diff --git a/packages/app/src/components/dialog-select-model.tsx b/packages/app/src/components/dialog-select-model.tsx index cdb299c79..8288a8255 100644 --- a/packages/app/src/components/dialog-select-model.tsx +++ b/packages/app/src/components/dialog-select-model.tsx @@ -4,6 +4,7 @@ import { useLocal } from "@/context/local" import { useDialog } from "@opencode-ai/ui/context/dialog" import { popularProviders } from "@/hooks/use-providers" import { Button } from "@opencode-ai/ui/button" +import { IconButton } from "@opencode-ai/ui/icon-button" import { Tag } from "@opencode-ai/ui/tag" import { Dialog } from "@opencode-ai/ui/dialog" import { List } from "@opencode-ai/ui/list" @@ -15,6 +16,7 @@ const ModelList: Component<{ provider?: string class?: string onSelect: () => void + action?: JSX.Element }> = (props) => { const local = useLocal() const language = useLanguage() @@ -29,7 +31,7 @@ const ModelList: Component<{ return ( `${x.provider.id}:${x.id}`} items={models} @@ -71,6 +73,12 @@ export const ModelSelectorPopover: Component<{ children: JSX.Element }> = (props) => { const [open, setOpen] = createSignal(false) + const dialog = useDialog() + + const handleManage = () => { + setOpen(false) + dialog.show(() => ) + } const language = useLanguage() return ( @@ -79,7 +87,22 @@ export const ModelSelectorPopover: Component<{ {language.t("dialog.model.select.title")} - setOpen(false)} class="p-1" /> + setOpen(false)} + class="p-1" + action={ + + } + /> diff --git a/packages/ui/src/components/list.css b/packages/ui/src/components/list.css index ee9be422c..95641bb20 100644 --- a/packages/ui/src/components/list.css +++ b/packages/ui/src/components/list.css @@ -23,14 +23,46 @@ overflow: hidden; padding: 0 12px; - [data-slot="list-search"] { + [data-slot="list-search-wrapper"] { display: flex; flex-shrink: 0; + align-items: center; + gap: 8px; + align-self: stretch; + margin-bottom: 4px; + padding-right: 4px; + + > [data-component="icon-button"] { + width: 24px; + height: 24px; + flex-shrink: 0; + background-color: transparent; + opacity: 0.5; + transition: opacity 0.15s ease; + + &:hover:not(:disabled), + &:focus:not(:disabled), + &:active:not(:disabled) { + background-color: transparent; + opacity: 0.7; + } + + &:hover:not(:disabled) [data-slot="icon-svg"] { + color: var(--icon-hover); + } + + &:active:not(:disabled) [data-slot="icon-svg"] { + color: var(--icon-active); + } + } + } + + [data-slot="list-search"] { + display: flex; + flex: 1; padding: 8px; align-items: center; gap: 12px; - align-self: stretch; - margin-bottom: 4px; border-radius: var(--radius-md); background: var(--surface-base); diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx index 066363502..fc9fa5405 100644 --- a/packages/ui/src/components/list.tsx +++ b/packages/ui/src/components/list.tsx @@ -11,6 +11,7 @@ export interface ListSearchProps { autofocus?: boolean hideIcon?: boolean class?: string + action?: JSX.Element } export interface ListProps extends FilteredListProps { @@ -60,6 +61,7 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void }) const { filter, grouped, flat, active, setActive, onKeyDown, onInput } = useFilteredList(props) const searchProps = () => (typeof props.search === "object" ? props.search : {}) + const searchAction = () => searchProps().action const moved = (event: MouseEvent) => event.movementX !== 0 || event.movementY !== 0 @@ -198,29 +200,32 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void }) return (
-
-
- - +
+
+
+ + + + +
+ + setInternalFilter("")} /> -
- - setInternalFilter("")} /> - + {searchAction()}