diff --git a/packages/desktop/src/components/prompt-input.tsx b/packages/desktop/src/components/prompt-input.tsx index cad1f209..74443d6a 100644 --- a/packages/desktop/src/components/prompt-input.tsx +++ b/packages/desktop/src/components/prompt-input.tsx @@ -543,6 +543,7 @@ export const PromptInput: Component = (props) => { disabled={!session.prompt.dirty() && !session.working()} icon={session.working() ? "stop" : "arrow-up"} variant="primary" + class="rounded-full" /> diff --git a/packages/desktop/src/context/local.tsx b/packages/desktop/src/context/local.tsx index cef6c555..9dacc710 100644 --- a/packages/desktop/src/context/local.tsx +++ b/packages/desktop/src/context/local.tsx @@ -5,6 +5,7 @@ import type { FileContent, FileNode, Model, Provider, File as FileStatus } from import { createSimpleContext } from "./helper" import { useSDK } from "./sdk" import { useSync } from "./sync" +import { makePersisted } from "@solid-primitives/storage" export type LocalFile = FileNode & Partial<{ @@ -456,11 +457,45 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ } })() + const layout = (() => { + const [store, setStore] = makePersisted( + createStore({ + sidebar: { + opened: true, + width: 240, + }, + }), + { + name: "layout", + }, + ) + + return { + sidebar: { + opened: createMemo(() => store.sidebar.opened), + open() { + setStore("sidebar", "opened", true) + }, + close() { + setStore("sidebar", "opened", false) + }, + toggle() { + setStore("sidebar", "opened", (x) => !x) + }, + width: createMemo(() => store.sidebar.width), + resize(width: number) { + setStore("sidebar", "width", width) + }, + }, + } + })() + const result = { model, agent, file, context, + layout, } return result }, diff --git a/packages/desktop/src/pages/layout.tsx b/packages/desktop/src/pages/layout.tsx index 85f55e8b..e1560acc 100644 --- a/packages/desktop/src/pages/layout.tsx +++ b/packages/desktop/src/pages/layout.tsx @@ -1,27 +1,42 @@ -import { Button, Tooltip, DiffChanges } from "@opencode-ai/ui" +import { Button, Tooltip, DiffChanges, IconButton } from "@opencode-ai/ui" import { createMemo, For, ParentProps, Show } from "solid-js" -import { getFilename } from "@/utils" import { DateTime } from "luxon" import { useSync } from "@/context/sync" import { A, useParams } from "@solidjs/router" +import { useLocal } from "@/context/local" export default function Layout(props: ParentProps) { const params = useParams() const sync = useSync() + const local = useLocal() return (
-
-
- {getFilename(sync.data.path.directory)} -
-
- -
+
+
+
+ + + +
+
+ + + + +
+ +
+ + + + +
{props.children}
diff --git a/packages/ui/src/components/button.css b/packages/ui/src/components/button.css index f5a08067..f76d7465 100644 --- a/packages/ui/src/components/button.css +++ b/packages/ui/src/components/button.css @@ -7,6 +7,7 @@ border-radius: 6px; text-decoration: none; user-select: none; + cursor: default; outline: none; &[data-variant="primary"] { @@ -93,11 +94,12 @@ gap: 8px; + /* text-12-medium */ font-family: var(--font-family-sans); - font-size: var(--font-size-base); + font-size: var(--font-size-small); font-style: normal; font-weight: var(--font-weight-medium); - line-height: var(--line-height-large); /* 171.429% */ + line-height: var(--line-height-large); /* 166.667% */ letter-spacing: var(--letter-spacing-normal); } diff --git a/packages/ui/src/components/icon-button.css b/packages/ui/src/components/icon-button.css index 6fe95fcc..a491074f 100644 --- a/packages/ui/src/components/icon-button.css +++ b/packages/ui/src/components/icon-button.css @@ -2,20 +2,11 @@ display: inline-flex; align-items: center; justify-content: center; - border-radius: 100%; + border-radius: 6px; text-decoration: none; user-select: none; aspect-ratio: 1; - - &:disabled { - background-color: var(--icon-strong-disabled); - color: var(--icon-invert-base); - cursor: not-allowed; - } - - &:focus { - outline: none; - } + flex-shrink: 0; &[data-variant="primary"] { background-color: var(--icon-strong-base); @@ -51,45 +42,62 @@ } &[data-variant="secondary"] { + border: transparent; background-color: var(--button-secondary-base); color: var(--text-strong); + box-shadow: var(--shadow-xs-border); &:hover:not(:disabled) { - background-color: var(--surface-hover); + background-color: var(--button-secondary-hover); } &:active:not(:disabled) { - background-color: var(--surface-active); + background-color: var(--button-secondary-base); } &:focus:not(:disabled) { - background-color: var(--surface-focus); + background-color: var(--button-secondary-base); + } + &:focus-visible:not(:active) { + background-color: var(--button-secondary-base); + box-shadow: var(--shadow-xs-border-focus); + } + &:focus-visible:active { + box-shadow: none; + } + + [data-slot="icon"] { + color: var(--icon-strong-base); } } &[data-variant="ghost"] { background-color: transparent; + /* color: var(--icon-base); */ [data-slot="icon"] { - color: var(--icon-weak-base); - - &:hover:not(:disabled) { - color: var(--icon-weak-hover); - } - &:active:not(:disabled) { - color: var(--icon-string-active); - } + color: var(--icon-base); } - /* color: var(--text-strong); */ - /**/ - /* &:hover:not(:disabled) { */ - /* background-color: var(--surface-hover); */ - /* } */ - /* &:active:not(:disabled) { */ - /* background-color: var(--surface-active); */ - /* } */ - /* &:focus:not(:disabled) { */ - /* background-color: var(--surface-focus); */ - /* } */ + &:hover:not(:disabled) { + background-color: var(--surface-base-hover); + + [data-slot="icon"] { + color: var(--icon-hover); + } + } + &:active:not(:disabled) { + [data-slot="icon"] { + color: var(--icon-active); + } + } + &:selected:not(:disabled) { + background-color: var(--surface-base-active); + [data-slot="icon"] { + color: var(--icon-selected); + } + } + &:focus:not(:disabled) { + background-color: var(--surface-focus); + } } &[data-size="normal"] { @@ -103,9 +111,14 @@ &[data-size="large"] { height: 32px; - padding: 0 8px 0 6px; + /* padding: 0 8px 0 6px; */ gap: 8px; + [data-slot="icon"] { + height: 16px; + width: 16px; + } + /* text-12-medium */ font-family: var(--font-family-sans); font-size: var(--font-size-small); @@ -114,4 +127,14 @@ line-height: var(--line-height-large); /* 166.667% */ letter-spacing: var(--letter-spacing-normal); } + + &:disabled { + background-color: var(--icon-strong-disabled); + color: var(--icon-invert-base); + cursor: not-allowed; + } + + &:focus { + outline: none; + } } diff --git a/packages/ui/src/components/icon-button.tsx b/packages/ui/src/components/icon-button.tsx index abc82609..fccdebd0 100644 --- a/packages/ui/src/components/icon-button.tsx +++ b/packages/ui/src/components/icon-button.tsx @@ -2,7 +2,7 @@ import { Button as Kobalte } from "@kobalte/core/button" import { type ComponentProps, splitProps } from "solid-js" import { Icon, IconProps } from "./icon" -export interface IconButtonProps { +export interface IconButtonProps extends ComponentProps { icon: IconProps["name"] size?: "normal" | "large" iconSize?: IconProps["size"] @@ -22,7 +22,11 @@ export function IconButton(props: ComponentProps<"button"> & IconButtonProps) { [split.class ?? ""]: !!split.class, }} > - + ) } diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx index 2e96b9d8..082bbea9 100644 --- a/packages/ui/src/components/icon.tsx +++ b/packages/ui/src/components/icon.tsx @@ -152,6 +152,8 @@ const newIcons = { "circle-ban-sign": ``, stop: ``, enter: ``, + "layout-left": ``, + "speech-bubble": ``, } export interface IconProps extends ComponentProps<"svg"> { diff --git a/packages/ui/src/components/tabs.css b/packages/ui/src/components/tabs.css index 1d786fb4..67f28928 100644 --- a/packages/ui/src/components/tabs.css +++ b/packages/ui/src/components/tabs.css @@ -7,7 +7,7 @@ overflow: clip; [data-slot="list"] { - height: 40px; + height: 48px; width: 100%; position: relative; display: flex; @@ -39,7 +39,7 @@ [data-slot="trigger"] { position: relative; height: 100%; - padding: 8px 24px; + padding: 14px 24px; display: flex; align-items: center; color: var(--text-base); diff --git a/packages/web/astro.config.mjs b/packages/web/astro.config.mjs index 24987ca3..d67bebe0 100644 --- a/packages/web/astro.config.mjs +++ b/packages/web/astro.config.mjs @@ -110,6 +110,7 @@ export default defineConfig({ ], redirects: { "/discord": "https://discord.gg/opencode", + "/desktop-feedback": "https://discord.gg/h5TNnkFVNy", }, })