1+ import { useT } from '@open-codesign/i18n' ;
12import { Download , Moon , Plus , Settings as SettingsIcon } from 'lucide-react' ;
23import { useEffect , useMemo , useState } from 'react' ;
34import { useCodesignStore } from '../store' ;
@@ -11,6 +12,7 @@ interface PaletteAction {
1112}
1213
1314export function CommandPalette ( ) {
15+ const t = useT ( ) ;
1416 const open = useCodesignStore ( ( s ) => s . commandPaletteOpen ) ;
1517 const close = useCodesignStore ( ( s ) => s . closeCommandPalette ) ;
1618 const openSettings = useCodesignStore ( ( s ) => s . openSettings ) ;
@@ -24,8 +26,8 @@ export function CommandPalette() {
2426 ( ) => [
2527 {
2628 id : 'new-design' ,
27- label : 'New Design' ,
28- hint : 'Clear chat and start fresh' ,
29+ label : t ( 'commands.items.newDesign' ) ,
30+ hint : t ( 'commands.hints.newDesign' ) ,
2931 icon : Plus ,
3032 run : ( ) => {
3133 useCodesignStore . setState ( {
@@ -35,44 +37,44 @@ export function CommandPalette() {
3537 iframeErrors : [ ] ,
3638 selectedElement : null ,
3739 } ) ;
38- pushToast ( { variant : 'info' , title : 'Workspace cleared' } ) ;
40+ pushToast ( { variant : 'info' , title : t ( 'commands. cleared') } ) ;
3941 } ,
4042 } ,
4143 {
4244 id : 'toggle-theme' ,
43- label : 'Toggle Theme' ,
44- hint : 'Switch between light and dark' ,
45+ label : t ( 'commands.items.toggleTheme' ) ,
46+ hint : t ( 'commands.hints.toggleTheme' ) ,
4547 icon : Moon ,
4648 run : toggleTheme ,
4749 } ,
4850 {
4951 id : 'open-settings' ,
50- label : 'Open Settings' ,
51- hint : 'Models, appearance, storage' ,
52+ label : t ( 'commands.items.openSettings' ) ,
53+ hint : t ( 'commands.hints.openSettings' ) ,
5254 icon : SettingsIcon ,
5355 run : openSettings ,
5456 } ,
5557 {
5658 id : 'export' ,
57- label : 'Export' ,
58- hint : 'PDF and PPTX coming soon' ,
59+ label : t ( 'commands.items.export' ) ,
60+ hint : t ( 'commands.hints.export' ) ,
5961 icon : Download ,
6062 run : ( ) =>
6163 pushToast ( {
6264 variant : 'info' ,
63- title : 'Export not available yet' ,
64- description : 'PDF and PPTX exporters land in v0.2. HTML export is in the toolbar.' ,
65+ title : t ( 'commands.exportUseToolbarTitle' ) ,
66+ description : t ( 'commands.exportUseToolbarBody' ) ,
6567 } ) ,
6668 } ,
6769 ] ,
68- [ openSettings , toggleTheme , pushToast ] ,
70+ [ openSettings , pushToast , t , toggleTheme ] ,
6971 ) ;
7072
7173 const filtered = useMemo ( ( ) => {
7274 const q = query . trim ( ) . toLowerCase ( ) ;
7375 if ( ! q ) return actions ;
7476 return actions . filter (
75- ( a ) => a . label . toLowerCase ( ) . includes ( q ) || a . hint . toLowerCase ( ) . includes ( q ) ,
77+ ( action ) => action . label . toLowerCase ( ) . includes ( q ) || action . hint . toLowerCase ( ) . includes ( q ) ,
7678 ) ;
7779 } , [ actions , query ] ) ;
7880
@@ -89,8 +91,8 @@ export function CommandPalette() {
8991
9092 if ( ! open ) return null ;
9193
92- function runAt ( i : number ) {
93- const action = filtered [ i ] ;
94+ function runAt ( index : number ) {
95+ const action = filtered [ index ] ;
9496 if ( ! action ) return ;
9597 action . run ( ) ;
9698 close ( ) ;
@@ -101,7 +103,7 @@ export function CommandPalette() {
101103 // biome-ignore lint/a11y/useSemanticElements: native <dialog> top-layer rendering interferes with our overlay stack
102104 role = "dialog"
103105 aria-modal = "true"
104- aria-label = "Command palette"
106+ aria-label = { t ( 'commands.title' ) }
105107 className = "fixed inset-0 z-50 flex items-start justify-center pt-24 px-6 bg-[var(--color-overlay)] animate-[overlay-in_120ms_ease-out]"
106108 onClick = { close }
107109 onKeyDown = { ( e ) => {
@@ -114,10 +116,10 @@ export function CommandPalette() {
114116 onKeyDown = { ( e ) => {
115117 if ( e . key === 'ArrowDown' ) {
116118 e . preventDefault ( ) ;
117- setCursor ( ( c ) => Math . min ( c + 1 , filtered . length - 1 ) ) ;
119+ setCursor ( ( current ) => Math . min ( current + 1 , filtered . length - 1 ) ) ;
118120 } else if ( e . key === 'ArrowUp' ) {
119121 e . preventDefault ( ) ;
120- setCursor ( ( c ) => Math . max ( c - 1 , 0 ) ) ;
122+ setCursor ( ( current ) => Math . max ( current - 1 , 0 ) ) ;
121123 } else if ( e . key === 'Enter' ) {
122124 e . preventDefault ( ) ;
123125 runAt ( cursor ) ;
@@ -136,24 +138,24 @@ export function CommandPalette() {
136138 setQuery ( e . target . value ) ;
137139 setCursor ( 0 ) ;
138140 } }
139- placeholder = "Type a command…"
141+ placeholder = { t ( 'commands.placeholder' ) }
140142 className = "w-full px-5 h-12 bg-transparent border-b border-[var(--color-border)] text-[var(--text-sm)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-muted)] focus:outline-none"
141143 />
142144 < ul className = "max-h-72 overflow-y-auto py-2" >
143145 { filtered . length === 0 ? (
144146 < li className = "px-5 py-3 text-[var(--text-sm)] text-[var(--color-text-muted)]" >
145- No matches.
147+ { t ( 'commands.noMatches' ) }
146148 </ li >
147149 ) : (
148- filtered . map ( ( a , i ) => {
149- const Icon = a . icon ;
150- const active = i === cursor ;
150+ filtered . map ( ( action , index ) => {
151+ const Icon = action . icon ;
152+ const active = index === cursor ;
151153 return (
152- < li key = { a . id } >
154+ < li key = { action . id } >
153155 < button
154156 type = "button"
155- onMouseEnter = { ( ) => setCursor ( i ) }
156- onClick = { ( ) => runAt ( i ) }
157+ onMouseEnter = { ( ) => setCursor ( index ) }
158+ onClick = { ( ) => runAt ( index ) }
157159 className = { `w-full flex items-center gap-3 px-5 py-2.5 text-left transition-colors ${
158160 active
159161 ? 'bg-[var(--color-surface-active)]'
@@ -163,10 +165,10 @@ export function CommandPalette() {
163165 < Icon className = "w-4 h-4 text-[var(--color-text-secondary)] shrink-0" />
164166 < span className = "flex-1 min-w-0" >
165167 < span className = "block text-[var(--text-sm)] text-[var(--color-text-primary)]" >
166- { a . label }
168+ { action . label }
167169 </ span >
168170 < span className = "block text-[var(--text-xs)] text-[var(--color-text-muted)]" >
169- { a . hint }
171+ { action . hint }
170172 </ span >
171173 </ span >
172174 </ button >
0 commit comments