mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-09-01 17:10:24 +08:00
feat: add all Draw.io themes to settings panel (#835)
* feat: add all Draw.io themes to settings panel Add all available Draw.io themes (kennedy, atlas, dark, min, sketch, simple) to the settings panel dropdown. Previously only min and sketch were available as a toggle button. Changes: - Replace the Draw.io style toggle button with a dropdown selector - Expand theme type from "min" | "sketch" to include all 6 themes - Update localStorage validation to accept all themes - Update handler from toggle to direct theme selection Closes #499 * fix: localize theme labels, tighten DrawioTheme typing, sync dark param - Move DRAWIO_THEMES + DrawioTheme to lib/drawio-themes.ts; reuse in page.tsx, chat-panel.tsx and settings-dialog.tsx instead of `string` - Localize theme dropdown labels (Dark/Minimal/Sketch/Simple) in en/zh/ja/zh-Hant; keep proper-noun themes (Kennedy/Atlas) as-is - Drop trailing colon from drawioStyleDescription and remove dead switchTo/minimal/sketch keys in all 4 dictionaries - Auto-sync drawio dark URL param when ui="dark" is selected - Add aria-label to drawio-style SelectTrigger * fix: use kennedy as default theme and label it "Default" --------- Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
|||||||
ResizablePanelGroup,
|
ResizablePanelGroup,
|
||||||
} from "@/components/ui/resizable"
|
} from "@/components/ui/resizable"
|
||||||
import { useDiagram } from "@/contexts/diagram-context"
|
import { useDiagram } from "@/contexts/diagram-context"
|
||||||
|
import { type DrawioTheme, isDrawioTheme } from "@/lib/drawio-themes"
|
||||||
import { i18n, type Locale } from "@/lib/i18n/config"
|
import { i18n, type Locale } from "@/lib/i18n/config"
|
||||||
import { isIndexedDBUsable } from "@/lib/session-storage"
|
import { isIndexedDBUsable } from "@/lib/session-storage"
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ export default function Home() {
|
|||||||
const currentLang = (pathname.split("/")[1] || i18n.defaultLocale) as Locale
|
const currentLang = (pathname.split("/")[1] || i18n.defaultLocale) as Locale
|
||||||
const [isMobile, setIsMobile] = useState(false)
|
const [isMobile, setIsMobile] = useState(false)
|
||||||
const [isChatVisible, setIsChatVisible] = useState(true)
|
const [isChatVisible, setIsChatVisible] = useState(true)
|
||||||
const [drawioUi, setDrawioUi] = useState<"min" | "sketch">("min")
|
const [drawioUi, setDrawioUi] = useState<DrawioTheme>("kennedy")
|
||||||
const [darkMode, setDarkMode] = useState(false)
|
const [darkMode, setDarkMode] = useState(false)
|
||||||
const [isLoaded, setIsLoaded] = useState(false)
|
const [isLoaded, setIsLoaded] = useState(false)
|
||||||
const [isDrawioReady, setIsDrawioReady] = useState(false)
|
const [isDrawioReady, setIsDrawioReady] = useState(false)
|
||||||
@@ -56,7 +57,7 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const savedUi = localStorage.getItem("drawio-theme")
|
const savedUi = localStorage.getItem("drawio-theme")
|
||||||
if (savedUi === "min" || savedUi === "sketch") {
|
if (isDrawioTheme(savedUi)) {
|
||||||
setDrawioUi(savedUi)
|
setDrawioUi(savedUi)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,10 +114,9 @@ export default function Home() {
|
|||||||
resetDrawioReady()
|
resetDrawioReady()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDrawioUiChange = () => {
|
const handleDrawioUiChange = (theme: DrawioTheme) => {
|
||||||
const newUi = drawioUi === "min" ? "sketch" : "min"
|
localStorage.setItem("drawio-theme", theme)
|
||||||
localStorage.setItem("drawio-theme", newUi)
|
setDrawioUi(theme)
|
||||||
setDrawioUi(newUi)
|
|
||||||
setIsDrawioReady(false)
|
setIsDrawioReady(false)
|
||||||
resetDrawioReady()
|
resetDrawioReady()
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,8 @@ export default function Home() {
|
|||||||
saveAndExit: false,
|
saveAndExit: false,
|
||||||
noSaveBtn: true,
|
noSaveBtn: true,
|
||||||
noExitBtn: true,
|
noExitBtn: true,
|
||||||
dark: darkMode,
|
dark:
|
||||||
|
darkMode || drawioUi === "dark",
|
||||||
lang: currentLang,
|
lang: currentLang,
|
||||||
// Enable offline mode in Electron to disable external service calls
|
// Enable offline mode in Electron to disable external service calls
|
||||||
...(isElectron && {
|
...(isElectron && {
|
||||||
@@ -264,7 +265,7 @@ export default function Home() {
|
|||||||
isVisible={isChatVisible}
|
isVisible={isChatVisible}
|
||||||
onToggleVisibility={toggleChatPanel}
|
onToggleVisibility={toggleChatPanel}
|
||||||
drawioUi={drawioUi}
|
drawioUi={drawioUi}
|
||||||
onToggleDrawioUi={handleDrawioUiChange}
|
onDrawioUiChange={handleDrawioUiChange}
|
||||||
darkMode={darkMode}
|
darkMode={darkMode}
|
||||||
onToggleDarkMode={handleDarkModeChange}
|
onToggleDarkMode={handleDarkModeChange}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import { useSessionManager } from "@/hooks/use-session-manager"
|
|||||||
import { useValidateDiagram } from "@/hooks/use-validate-diagram"
|
import { useValidateDiagram } from "@/hooks/use-validate-diagram"
|
||||||
import { getApiEndpoint } from "@/lib/base-path"
|
import { getApiEndpoint } from "@/lib/base-path"
|
||||||
import { findCachedResponse } from "@/lib/cached-responses"
|
import { findCachedResponse } from "@/lib/cached-responses"
|
||||||
|
import type { DrawioTheme } from "@/lib/drawio-themes"
|
||||||
import { formatMessage } from "@/lib/i18n/utils"
|
import { formatMessage } from "@/lib/i18n/utils"
|
||||||
import { isPdfFile, isTextFile } from "@/lib/pdf-utils"
|
import { isPdfFile, isTextFile } from "@/lib/pdf-utils"
|
||||||
import { sanitizeMessages } from "@/lib/session-storage"
|
import { sanitizeMessages } from "@/lib/session-storage"
|
||||||
@@ -68,8 +69,8 @@ interface ChatMessage {
|
|||||||
interface ChatPanelProps {
|
interface ChatPanelProps {
|
||||||
isVisible: boolean
|
isVisible: boolean
|
||||||
onToggleVisibility: () => void
|
onToggleVisibility: () => void
|
||||||
drawioUi: "min" | "sketch"
|
drawioUi: DrawioTheme
|
||||||
onToggleDrawioUi: () => void
|
onDrawioUiChange: (theme: DrawioTheme) => void
|
||||||
darkMode: boolean
|
darkMode: boolean
|
||||||
onToggleDarkMode: () => void
|
onToggleDarkMode: () => void
|
||||||
isMobile?: boolean
|
isMobile?: boolean
|
||||||
@@ -110,7 +111,7 @@ export default function ChatPanel({
|
|||||||
isVisible,
|
isVisible,
|
||||||
onToggleVisibility,
|
onToggleVisibility,
|
||||||
drawioUi,
|
drawioUi,
|
||||||
onToggleDrawioUi,
|
onDrawioUiChange,
|
||||||
darkMode,
|
darkMode,
|
||||||
onToggleDarkMode,
|
onToggleDarkMode,
|
||||||
isMobile = false,
|
isMobile = false,
|
||||||
@@ -1442,7 +1443,7 @@ export default function ChatPanel({
|
|||||||
open={showSettingsDialog}
|
open={showSettingsDialog}
|
||||||
onOpenChange={setShowSettingsDialog}
|
onOpenChange={setShowSettingsDialog}
|
||||||
drawioUi={drawioUi}
|
drawioUi={drawioUi}
|
||||||
onToggleDrawioUi={onToggleDrawioUi}
|
onDrawioUiChange={onDrawioUiChange}
|
||||||
darkMode={darkMode}
|
darkMode={darkMode}
|
||||||
onToggleDarkMode={onToggleDarkMode}
|
onToggleDarkMode={onToggleDarkMode}
|
||||||
minimalStyle={minimalStyle}
|
minimalStyle={minimalStyle}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { Switch } from "@/components/ui/switch"
|
|||||||
import { Textarea } from "@/components/ui/textarea"
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
import { useDictionary } from "@/hooks/use-dictionary"
|
import { useDictionary } from "@/hooks/use-dictionary"
|
||||||
import { getApiEndpoint } from "@/lib/base-path"
|
import { getApiEndpoint } from "@/lib/base-path"
|
||||||
|
import type { DrawioTheme } from "@/lib/drawio-themes"
|
||||||
import { i18n, type Locale } from "@/lib/i18n/config"
|
import { i18n, type Locale } from "@/lib/i18n/config"
|
||||||
import { STORAGE_KEYS } from "@/lib/storage"
|
import { STORAGE_KEYS } from "@/lib/storage"
|
||||||
|
|
||||||
@@ -63,8 +64,8 @@ const LANGUAGE_LABELS: Record<Locale, string> = {
|
|||||||
interface SettingsDialogProps {
|
interface SettingsDialogProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
onOpenChange: (open: boolean) => void
|
onOpenChange: (open: boolean) => void
|
||||||
drawioUi: "min" | "sketch"
|
drawioUi: DrawioTheme
|
||||||
onToggleDrawioUi: () => void
|
onDrawioUiChange: (theme: DrawioTheme) => void
|
||||||
darkMode: boolean
|
darkMode: boolean
|
||||||
onToggleDarkMode: () => void
|
onToggleDarkMode: () => void
|
||||||
minimalStyle?: boolean
|
minimalStyle?: boolean
|
||||||
@@ -90,7 +91,7 @@ function SettingsContent({
|
|||||||
open,
|
open,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
drawioUi,
|
drawioUi,
|
||||||
onToggleDrawioUi,
|
onDrawioUiChange,
|
||||||
darkMode,
|
darkMode,
|
||||||
onToggleDarkMode,
|
onToggleDarkMode,
|
||||||
minimalStyle = false,
|
minimalStyle = false,
|
||||||
@@ -432,23 +433,40 @@ function SettingsContent({
|
|||||||
{/* Draw.io Style */}
|
{/* Draw.io Style */}
|
||||||
<SettingItem
|
<SettingItem
|
||||||
label={dict.settings.drawioStyle}
|
label={dict.settings.drawioStyle}
|
||||||
description={`${dict.settings.drawioStyleDescription} ${
|
description={dict.settings.drawioStyleDescription}
|
||||||
drawioUi === "min"
|
|
||||||
? dict.settings.minimal
|
|
||||||
: dict.settings.sketch
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<Button
|
<Select
|
||||||
id="drawio-ui"
|
value={drawioUi}
|
||||||
variant="outline"
|
onValueChange={(v) =>
|
||||||
onClick={onToggleDrawioUi}
|
onDrawioUiChange(v as DrawioTheme)
|
||||||
className="h-9 w-[120px] rounded-xl border-border-subtle hover:bg-interactive-hover font-normal"
|
}
|
||||||
>
|
>
|
||||||
{dict.settings.switchTo}{" "}
|
<SelectTrigger
|
||||||
{drawioUi === "min"
|
id="drawio-ui-select"
|
||||||
? dict.settings.sketch
|
aria-label={dict.settings.drawioStyle}
|
||||||
: dict.settings.minimal}
|
className="w-[120px] h-9 rounded-xl"
|
||||||
</Button>
|
>
|
||||||
|
<SelectValue />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="kennedy">
|
||||||
|
{dict.settings.themeDefault}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="atlas">Atlas</SelectItem>
|
||||||
|
<SelectItem value="dark">
|
||||||
|
{dict.settings.themeDark}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="min">
|
||||||
|
{dict.settings.themeMinimal}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="sketch">
|
||||||
|
{dict.settings.themeSketch}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="simple">
|
||||||
|
{dict.settings.themeSimple}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
{/* Diagram Style */}
|
{/* Diagram Style */}
|
||||||
|
|||||||
17
lib/drawio-themes.ts
Normal file
17
lib/drawio-themes.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export const DRAWIO_THEMES = [
|
||||||
|
"kennedy",
|
||||||
|
"atlas",
|
||||||
|
"dark",
|
||||||
|
"min",
|
||||||
|
"sketch",
|
||||||
|
"simple",
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export type DrawioTheme = (typeof DRAWIO_THEMES)[number]
|
||||||
|
|
||||||
|
export function isDrawioTheme(value: unknown): value is DrawioTheme {
|
||||||
|
return (
|
||||||
|
typeof value === "string" &&
|
||||||
|
(DRAWIO_THEMES as readonly string[]).includes(value)
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -102,10 +102,12 @@
|
|||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
"themeDescription": "Dark/Light mode for interface and DrawIO canvas.",
|
"themeDescription": "Dark/Light mode for interface and DrawIO canvas.",
|
||||||
"drawioStyle": "DrawIO Style",
|
"drawioStyle": "DrawIO Style",
|
||||||
"drawioStyleDescription": "Canvas style:",
|
"drawioStyleDescription": "Canvas style",
|
||||||
"switchTo": "Switch to",
|
"themeDefault": "Default",
|
||||||
"minimal": "Minimal",
|
"themeDark": "Dark",
|
||||||
"sketch": "Sketch",
|
"themeMinimal": "Minimal",
|
||||||
|
"themeSketch": "Sketch",
|
||||||
|
"themeSimple": "Simple",
|
||||||
"diagramStyle": "Diagram Style",
|
"diagramStyle": "Diagram Style",
|
||||||
"diagramStyleDescription": "Toggle between minimal and styled diagram output.",
|
"diagramStyleDescription": "Toggle between minimal and styled diagram output.",
|
||||||
"sendShortcut": "Send Shortcut",
|
"sendShortcut": "Send Shortcut",
|
||||||
|
|||||||
@@ -102,10 +102,12 @@
|
|||||||
"theme": "テーマ",
|
"theme": "テーマ",
|
||||||
"themeDescription": "インターフェースと DrawIO キャンバスのダーク/ライトモード。",
|
"themeDescription": "インターフェースと DrawIO キャンバスのダーク/ライトモード。",
|
||||||
"drawioStyle": "DrawIO スタイル",
|
"drawioStyle": "DrawIO スタイル",
|
||||||
"drawioStyleDescription": "キャンバススタイル:",
|
"drawioStyleDescription": "キャンバススタイル",
|
||||||
"switchTo": "切り替え",
|
"themeDefault": "デフォルト",
|
||||||
"minimal": "ミニマル",
|
"themeDark": "ダーク",
|
||||||
"sketch": "スケッチ",
|
"themeMinimal": "ミニマル",
|
||||||
|
"themeSketch": "スケッチ",
|
||||||
|
"themeSimple": "シンプル",
|
||||||
"diagramStyle": "ダイアグラムスタイル",
|
"diagramStyle": "ダイアグラムスタイル",
|
||||||
"diagramStyleDescription": "ミニマルとスタイル付きの出力を切り替えます。",
|
"diagramStyleDescription": "ミニマルとスタイル付きの出力を切り替えます。",
|
||||||
"sendShortcut": "送信ショートカット",
|
"sendShortcut": "送信ショートカット",
|
||||||
|
|||||||
@@ -102,10 +102,12 @@
|
|||||||
"theme": "主題",
|
"theme": "主題",
|
||||||
"themeDescription": "介面和 DrawIO 畫布的深色/淺色模式。",
|
"themeDescription": "介面和 DrawIO 畫布的深色/淺色模式。",
|
||||||
"drawioStyle": "DrawIO 樣式",
|
"drawioStyle": "DrawIO 樣式",
|
||||||
"drawioStyleDescription": "畫布樣式:",
|
"drawioStyleDescription": "畫布樣式",
|
||||||
"switchTo": "切換到",
|
"themeDefault": "預設",
|
||||||
"minimal": "簡約",
|
"themeDark": "深色",
|
||||||
"sketch": "草圖",
|
"themeMinimal": "簡約",
|
||||||
|
"themeSketch": "草圖",
|
||||||
|
"themeSimple": "簡單",
|
||||||
"diagramStyle": "圖表樣式",
|
"diagramStyle": "圖表樣式",
|
||||||
"diagramStyleDescription": "切換簡約與精緻圖表輸出模式。",
|
"diagramStyleDescription": "切換簡約與精緻圖表輸出模式。",
|
||||||
"sendShortcut": "傳送快捷鍵",
|
"sendShortcut": "傳送快捷鍵",
|
||||||
|
|||||||
@@ -102,10 +102,12 @@
|
|||||||
"theme": "主题",
|
"theme": "主题",
|
||||||
"themeDescription": "界面和 DrawIO 画布的深色/浅色模式。",
|
"themeDescription": "界面和 DrawIO 画布的深色/浅色模式。",
|
||||||
"drawioStyle": "DrawIO 样式",
|
"drawioStyle": "DrawIO 样式",
|
||||||
"drawioStyleDescription": "画布样式:",
|
"drawioStyleDescription": "画布样式",
|
||||||
"switchTo": "切换到",
|
"themeDefault": "默认",
|
||||||
"minimal": "简约",
|
"themeDark": "深色",
|
||||||
"sketch": "草图",
|
"themeMinimal": "简约",
|
||||||
|
"themeSketch": "草图",
|
||||||
|
"themeSimple": "简单",
|
||||||
"diagramStyle": "图表样式",
|
"diagramStyle": "图表样式",
|
||||||
"diagramStyleDescription": "切换简约与精致图表输出模式。",
|
"diagramStyleDescription": "切换简约与精致图表输出模式。",
|
||||||
"sendShortcut": "发送快捷键",
|
"sendShortcut": "发送快捷键",
|
||||||
|
|||||||
Reference in New Issue
Block a user