summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop/src/components
diff options
context:
space:
mode:
authorAaron Iker <[email protected]>2025-12-22 12:41:38 +0100
committerGitHub <[email protected]>2025-12-22 05:41:38 -0600
commit5fd873a35a19de2f9e89c420158d5697746d2983 (patch)
tree583ef90753cbe5ddba07bc6a23112dc326fcc0e7 /packages/desktop/src/components
parenta9fbd786b3262a659620298b8071671452b497f1 (diff)
downloadopencode-5fd873a35a19de2f9e89c420158d5697746d2983.tar.gz
opencode-5fd873a35a19de2f9e89c420158d5697746d2983.zip
feat: polish dialog & list styles for the desktop app, add fixed logos from models.dev (#5925)
Diffstat (limited to 'packages/desktop/src/components')
-rw-r--r--packages/desktop/src/components/dialog-connect-provider.tsx36
-rw-r--r--packages/desktop/src/components/dialog-manage-models.tsx21
-rw-r--r--packages/desktop/src/components/dialog-select-file.tsx11
-rw-r--r--packages/desktop/src/components/dialog-select-model-unpaid.tsx31
-rw-r--r--packages/desktop/src/components/dialog-select-model.tsx3
-rw-r--r--packages/desktop/src/components/dialog-select-provider.tsx14
6 files changed, 52 insertions, 64 deletions
diff --git a/packages/desktop/src/components/dialog-connect-provider.tsx b/packages/desktop/src/components/dialog-connect-provider.tsx
index 0d6737815..789a5d3b7 100644
--- a/packages/desktop/src/components/dialog-connect-provider.tsx
+++ b/packages/desktop/src/components/dialog-connect-provider.tsx
@@ -1,24 +1,24 @@
-import { createMemo, Match, onCleanup, onMount, Switch } from "solid-js"
-import { createStore, produce } from "solid-js/store"
+import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2/client"
+import { Button } from "@opencode-ai/ui/button"
import { useDialog } from "@opencode-ai/ui/context/dialog"
-import { useGlobalSync } from "@/context/global-sync"
-import { useGlobalSDK } from "@/context/global-sdk"
-import { usePlatform } from "@/context/platform"
-import { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2/client"
import { Dialog } from "@opencode-ai/ui/dialog"
-import { List, ListRef } from "@opencode-ai/ui/list"
-import { Button } from "@opencode-ai/ui/button"
+import { Icon } from "@opencode-ai/ui/icon"
import { IconButton } from "@opencode-ai/ui/icon-button"
-import { TextField } from "@opencode-ai/ui/text-field"
+import type { IconName } from "@opencode-ai/ui/icons/provider"
+import { List, type ListRef } from "@opencode-ai/ui/list"
+import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
import { Spinner } from "@opencode-ai/ui/spinner"
-import { Icon } from "@opencode-ai/ui/icon"
+import { TextField } from "@opencode-ai/ui/text-field"
import { showToast } from "@opencode-ai/ui/toast"
-import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
-import { IconName } from "@opencode-ai/ui/icons/provider"
import { iife } from "@opencode-ai/util/iife"
+import { createMemo, Match, onCleanup, onMount, Switch } from "solid-js"
+import { createStore, produce } from "solid-js/store"
import { Link } from "@/components/link"
-import { DialogSelectProvider } from "./dialog-select-provider"
+import { useGlobalSDK } from "@/context/global-sdk"
+import { useGlobalSync } from "@/context/global-sync"
+import { usePlatform } from "@/context/platform"
import { DialogSelectModel } from "./dialog-select-model"
+import { DialogSelectProvider } from "./dialog-select-provider"
export function DialogConnectProvider(props: { provider: string }) {
const dialog = useDialog()
@@ -154,7 +154,9 @@ export function DialogConnectProvider(props: { provider: string }) {
<div class="text-14-regular text-text-base">Select login method for {provider().name}.</div>
<div class="">
<List
- ref={(ref) => (listRef = ref)}
+ ref={(ref) => {
+ listRef = ref
+ }}
items={methods}
key={(m) => m?.label}
onSelect={async (method, index) => {
@@ -163,7 +165,7 @@ export function DialogConnectProvider(props: { provider: string }) {
}}
>
{(i) => (
- <div class="w-full flex items-center gap-x-4">
+ <div class="w-full flex items-center gap-x-2">
<div class="w-4 h-2 rounded-[1px] bg-input-base shadow-xs-border-base flex items-center justify-center">
<div class="w-2.5 h-0.5 bg-icon-strong-base hidden" data-slot="list-item-extra-icon" />
</div>
@@ -175,7 +177,7 @@ export function DialogConnectProvider(props: { provider: string }) {
</Match>
<Match when={store.state === "pending"}>
<div class="text-14-regular text-text-base">
- <div class="flex items-center gap-x-4">
+ <div class="flex items-center gap-x-2">
<Spinner />
<span>Authorization in progress...</span>
</div>
@@ -183,7 +185,7 @@ export function DialogConnectProvider(props: { provider: string }) {
</Match>
<Match when={store.state === "error"}>
<div class="text-14-regular text-text-base">
- <div class="flex items-center gap-x-4">
+ <div class="flex items-center gap-x-2">
<Icon name="circle-ban-sign" class="text-icon-critical-base" />
<span>Authorization failed: {store.error}</span>
</div>
diff --git a/packages/desktop/src/components/dialog-manage-models.tsx b/packages/desktop/src/components/dialog-manage-models.tsx
index 5765a8e1a..66d125288 100644
--- a/packages/desktop/src/components/dialog-manage-models.tsx
+++ b/packages/desktop/src/components/dialog-manage-models.tsx
@@ -1,16 +1,15 @@
-import { Component } from "solid-js"
-import { useLocal } from "@/context/local"
-import { popularProviders } from "@/hooks/use-providers"
import { Dialog } from "@opencode-ai/ui/dialog"
import { List } from "@opencode-ai/ui/list"
import { Switch } from "@opencode-ai/ui/switch"
+import type { Component } from "solid-js"
+import { useLocal } from "@/context/local"
+import { popularProviders } from "@/hooks/use-providers"
export const DialogManageModels: Component = () => {
const local = useLocal()
return (
<Dialog title="Manage models" description="Customize which models appear in the model selector.">
<List
- class="px-2.5"
search={{ placeholder: "Search models", autofocus: true }}
emptyMessage="No model results"
key={(x) => `${x?.provider?.id}:${x?.id}`}
@@ -27,16 +26,24 @@ export const DialogManageModels: Component = () => {
}}
onSelect={(x) => {
if (!x) return
- const visible = local.model.visible({ modelID: x.id, providerID: x.provider.id })
+ const visible = local.model.visible({
+ modelID: x.id,
+ providerID: x.provider.id,
+ })
local.model.setVisibility({ modelID: x.id, providerID: x.provider.id }, !visible)
}}
>
{(i) => (
- <div class="w-full flex items-center justify-between gap-x-2.5">
+ <div class="w-full flex items-center justify-between gap-x-3">
<span>{i.name}</span>
<div onClick={(e) => e.stopPropagation()}>
<Switch
- checked={!!local.model.visible({ modelID: i.id, providerID: i.provider.id })}
+ checked={
+ !!local.model.visible({
+ modelID: i.id,
+ providerID: i.provider.id,
+ })
+ }
onChange={(checked) => {
local.model.setVisibility({ modelID: i.id, providerID: i.provider.id }, checked)
}}
diff --git a/packages/desktop/src/components/dialog-select-file.tsx b/packages/desktop/src/components/dialog-select-file.tsx
index 61c518719..b27afdc8b 100644
--- a/packages/desktop/src/components/dialog-select-file.tsx
+++ b/packages/desktop/src/components/dialog-select-file.tsx
@@ -1,12 +1,12 @@
-import { useLocal } from "@/context/local"
+import { useDialog } from "@opencode-ai/ui/context/dialog"
import { Dialog } from "@opencode-ai/ui/dialog"
-import { List } from "@opencode-ai/ui/list"
import { FileIcon } from "@opencode-ai/ui/file-icon"
+import { List } from "@opencode-ai/ui/list"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
-import { useLayout } from "@/context/layout"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
import { useParams } from "@solidjs/router"
import { createMemo } from "solid-js"
+import { useLayout } from "@/context/layout"
+import { useLocal } from "@/context/local"
export function DialogSelectFile() {
const layout = useLayout()
@@ -18,7 +18,6 @@ export function DialogSelectFile() {
return (
<Dialog title="Select file">
<List
- class="px-2.5"
search={{ placeholder: "Search files", autofocus: true }}
emptyMessage="No files found"
items={local.file.searchFiles}
@@ -32,7 +31,7 @@ export function DialogSelectFile() {
>
{(i) => (
<div class="w-full flex items-center justify-between rounded-md">
- <div class="flex items-center gap-x-2 grow min-w-0">
+ <div class="flex items-center gap-x-3 grow min-w-0">
<FileIcon node={{ path: i, type: "file" }} class="shrink-0 size-4" />
<div class="flex items-center text-14-regular">
<span class="text-text-weak whitespace-nowrap overflow-hidden overflow-ellipsis truncate min-w-0">
diff --git a/packages/desktop/src/components/dialog-select-model-unpaid.tsx b/packages/desktop/src/components/dialog-select-model-unpaid.tsx
index 77e493d3c..24ec8092d 100644
--- a/packages/desktop/src/components/dialog-select-model-unpaid.tsx
+++ b/packages/desktop/src/components/dialog-select-model-unpaid.tsx
@@ -1,15 +1,15 @@
-import { Component, onCleanup, onMount, Show } from "solid-js"
-import { useLocal } from "@/context/local"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
-import { popularProviders, useProviders } from "@/hooks/use-providers"
import { Button } from "@opencode-ai/ui/button"
-import { Tag } from "@opencode-ai/ui/tag"
+import { useDialog } from "@opencode-ai/ui/context/dialog"
import { Dialog } from "@opencode-ai/ui/dialog"
-import { List, ListRef } from "@opencode-ai/ui/list"
+import type { IconName } from "@opencode-ai/ui/icons/provider"
+import { List, type ListRef } from "@opencode-ai/ui/list"
import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
-import { IconName } from "@opencode-ai/ui/icons/provider"
-import { DialogSelectProvider } from "./dialog-select-provider"
+import { Tag } from "@opencode-ai/ui/tag"
+import { type Component, onCleanup, onMount, Show } from "solid-js"
+import { useLocal } from "@/context/local"
+import { popularProviders, useProviders } from "@/hooks/use-providers"
import { DialogConnectProvider } from "./dialog-connect-provider"
+import { DialogSelectProvider } from "./dialog-select-provider"
export const DialogSelectModelUnpaid: Component = () => {
const local = useLocal()
@@ -64,7 +64,7 @@ export const DialogSelectModelUnpaid: Component = () => {
<div class="px-2 text-14-medium text-text-base">Add more models from popular providers</div>
<div class="w-full">
<List
- class="w-full"
+ class="w-full px-0"
key={(x) => x?.id}
items={providers.popular}
activeIcon="plus-small"
@@ -79,17 +79,8 @@ export const DialogSelectModelUnpaid: Component = () => {
}}
>
{(i) => (
- <div class="w-full flex items-center gap-x-4">
- <ProviderIcon
- data-slot="list-item-extra-icon"
- id={i.id as IconName}
- // TODO: clean this up after we update icon in models.dev
- classList={{
- "text-icon-weak-base": true,
- "size-4 mx-0.5": i.id === "opencode",
- "size-5": i.id !== "opencode",
- }}
- />
+ <div class="w-full flex items-center gap-x-3">
+ <ProviderIcon data-slot="list-item-extra-icon" id={i.id as IconName} />
<span>{i.name}</span>
<Show when={i.id === "opencode"}>
<Tag>Recommended</Tag>
diff --git a/packages/desktop/src/components/dialog-select-model.tsx b/packages/desktop/src/components/dialog-select-model.tsx
index 622ab15fb..54783386a 100644
--- a/packages/desktop/src/components/dialog-select-model.tsx
+++ b/packages/desktop/src/components/dialog-select-model.tsx
@@ -35,7 +35,6 @@ export const DialogSelectModel: Component<{ provider?: string }> = (props) => {
}
>
<List
- class="px-2.5"
search={{ placeholder: "Search models", autofocus: true }}
emptyMessage="No model results"
key={(x) => `${x.provider.id}:${x.id}`}
@@ -61,7 +60,7 @@ export const DialogSelectModel: Component<{ provider?: string }> = (props) => {
}}
>
{(i) => (
- <div class="w-full flex items-center gap-x-2.5">
+ <div class="w-full flex items-center gap-x-3">
<span>{i.name}</span>
<Show when={i.provider.id === "opencode" && (!i.cost || i.cost?.input === 0)}>
<Tag>Free</Tag>
diff --git a/packages/desktop/src/components/dialog-select-provider.tsx b/packages/desktop/src/components/dialog-select-provider.tsx
index 52fac7073..5bbde5d41 100644
--- a/packages/desktop/src/components/dialog-select-provider.tsx
+++ b/packages/desktop/src/components/dialog-select-provider.tsx
@@ -15,7 +15,6 @@ export const DialogSelectProvider: Component = () => {
return (
<Dialog title="Connect provider">
<List
- class="px-2.5"
search={{ placeholder: "Search providers", autofocus: true }}
activeIcon="plus-small"
key={(x) => x?.id}
@@ -38,17 +37,8 @@ export const DialogSelectProvider: Component = () => {
}}
>
{(i) => (
- <div class="px-1.25 w-full flex items-center gap-x-4">
- <ProviderIcon
- data-slot="list-item-extra-icon"
- id={i.id as IconName}
- // TODO: clean this up after we update icon in models.dev
- classList={{
- "text-icon-weak-base": true,
- "size-4 mx-0.5": i.id === "opencode",
- "size-5": i.id !== "opencode",
- }}
- />
+ <div class="px-1.25 w-full flex items-center gap-x-3">
+ <ProviderIcon data-slot="list-item-extra-icon" id={i.id as IconName} />
<span>{i.name}</span>
<Show when={i.id === "opencode"}>
<Tag>Recommended</Tag>