Procházet zdrojové kódy

tui: simplify theme selection API by renaming setSelectedTheme to set

Dax Raad před 3 měsíci
rodič
revize
3823d8d50e

+ 8 - 7
packages/opencode/src/cli/cmd/tui/component/dialog-theme-list.tsx

@@ -12,15 +12,16 @@ export function DialogThemeList() {
   const dialog = useDialog()
   let confirmed = false
   let ref: DialogSelectRef<keyof typeof THEMES>
-  const initial = theme.selectedTheme
+  const initial = theme.selected
 
   onMount(() => {
     // highlight the first theme in the list when we open it for UX
-    theme.setSelectedTheme(Object.keys(THEMES)[0] as keyof typeof THEMES)
+    theme.set(Object.keys(THEMES)[0] as keyof typeof THEMES)
   })
+
   onCleanup(() => {
     // if we close the dialog without confirming, reset back to the initial theme
-    if (!confirmed) theme.setSelectedTheme(initial)
+    if (!confirmed) theme.set(initial)
   })
 
   return (
@@ -28,10 +29,10 @@ export function DialogThemeList() {
       title="Themes"
       options={options}
       onMove={(opt) => {
-        theme.setSelectedTheme(opt.value)
+        theme.set(opt.value)
       }}
       onSelect={(opt) => {
-        theme.setSelectedTheme(opt.value)
+        theme.set(opt.value)
         confirmed = true
         dialog.clear()
       }}
@@ -40,12 +41,12 @@ export function DialogThemeList() {
       }}
       onFilter={(query) => {
         if (query.length === 0) {
-          theme.setSelectedTheme(initial)
+          theme.set(initial)
           return
         }
 
         const first = ref.filtered[0]
-        if (first) theme.setSelectedTheme(first.value)
+        if (first) theme.set(first.value)
       }}
     />
   )

+ 3 - 2
packages/opencode/src/cli/cmd/tui/context/theme.tsx

@@ -642,10 +642,11 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
           return values()[prop]
         },
       }),
-      get selectedTheme() {
+      get selected() {
         return kv.data.theme
       },
-      setSelectedTheme(theme: string) {
+      set(theme: string) {
+        if (!THEMES[theme]) return
         setTheme(theme)
         kv.set("theme", theme)
       },

+ 22 - 8
packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

@@ -59,7 +59,8 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
       props.options,
       filter((x) => x.disabled !== true),
       take(props.limit ?? Infinity),
-      (x) => (!needle ? x : fuzzysort.go(needle, x, { keys: ["title", "category"] }).map((x) => x.obj)),
+      (x) =>
+        !needle ? x : fuzzysort.go(needle, x, { keys: ["title", "category"] }).map((x) => x.obj),
     )
     return result
   })
@@ -128,8 +129,10 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
     if (evt.name === "pagedown") move(10)
     if (evt.name === "return") {
       const option = selected()
-      if (option.onSelect) option.onSelect(dialog)
-      props.onSelect?.(option)
+      if (option) {
+        if (option.onSelect) option.onSelect(dialog)
+        props.onSelect?.(option)
+      }
     }
 
     for (const item of props.keybind ?? []) {
@@ -206,11 +209,15 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
                         props.onSelect?.(option)
                       }}
                       onMouseOver={() => {
-                        const index = filtered().findIndex((x) => isDeepEqual(x.value, option.value))
+                        const index = filtered().findIndex((x) =>
+                          isDeepEqual(x.value, option.value),
+                        )
                         if (index === -1) return
                         moveTo(index)
                       }}
-                      backgroundColor={active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
+                      backgroundColor={
+                        active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)
+                      }
                       paddingLeft={1}
                       paddingRight={1}
                       gap={1}
@@ -218,7 +225,9 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
                       <Option
                         title={option.title}
                         footer={option.footer}
-                        description={option.description !== category ? option.description : undefined}
+                        description={
+                          option.description !== category ? option.description : undefined
+                        }
                         active={active()}
                         current={isDeepEqual(option.value, props.current)}
                       />
@@ -234,7 +243,9 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
         <For each={props.keybind ?? []}>
           {(item) => (
             <text>
-              <span style={{ fg: theme.text, attributes: TextAttributes.BOLD }}>{Keybind.toString(item.keybind)}</span>
+              <span style={{ fg: theme.text, attributes: TextAttributes.BOLD }}>
+                {Keybind.toString(item.keybind)}
+              </span>
               <span style={{ fg: theme.textMuted }}> {item.title}</span>
             </text>
           )}
@@ -263,7 +274,10 @@ function Option(props: {
         wrapMode="none"
       >
         {Locale.truncate(props.title, 62)}
-        <span style={{ fg: props.active ? theme.background : theme.textMuted }}> {props.description}</span>
+        <span style={{ fg: props.active ? theme.background : theme.textMuted }}>
+          {" "}
+          {props.description}
+        </span>
       </text>
       <Show when={props.footer}>
         <box flexShrink={0}>