Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
81f4c7a
feat: scroll helper components
aaroniker Jan 26, 2026
1166468
feat: scroll settings
aaroniker Jan 26, 2026
a7fade7
feat: list scrolling
aaroniker Jan 26, 2026
ab07c94
feat: animated chevron
aaroniker Jan 29, 2026
bc77e15
feat: reasoning icon
aaroniker Jan 29, 2026
e3312f1
feat: transition select, dropdown
aaroniker Jan 29, 2026
d6beccf
feat: animate accordion, user message
aaroniker Jan 29, 2026
f2ca48f
feat: cycle label
aaroniker Jan 29, 2026
f39ff9c
feat: multiple transitions
aaroniker Jan 29, 2026
32d29ec
feat: transitions, review, dialog
aaroniker Jan 29, 2026
9a526d9
feat: prompt & progress icon
aaroniker Jan 29, 2026
50f10ed
feat: button transition
aaroniker Jan 29, 2026
ce89c2d
feat: popover & list
aaroniker Jan 29, 2026
dfc98ab
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 29, 2026
b788d52
format
aaroniker Jan 29, 2026
758f24f
Merge branch 'dev' into desktop-quick-polishment
thdxr Jan 29, 2026
5a88b7a
fix: lint
aaroniker Jan 29, 2026
9fb9549
Merge branch 'desktop-quick-polishment' of https://github.com/anomaly…
aaroniker Jan 29, 2026
7a946df
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 29, 2026
ab0ddd1
chore: update nix node_modules hashes
actions-user Jan 29, 2026
0060873
ci: upgrade bun cache to stickydisk for faster ci builds
thdxr Jan 30, 2026
83e59b9
sync
thdxr Jan 30, 2026
4b2d00e
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
019ba44
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
321cdab
fix: address potential issues in transitions PR (#11220)
Copilot Jan 30, 2026
e522a9a
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
e1e356c
release: v1.1.45
Jan 30, 2026
00637c0
fix: rm ai sdk middleware that was preventing <think> blocks from bei…
rekram1-node Jan 30, 2026
2081da3
feat: styles
aaroniker Jan 30, 2026
a9c29ae
Merge branch 'desktop-quick-polishment' of https://github.com/anomaly…
aaroniker Jan 30, 2026
10058a5
fix: lint
aaroniker Jan 30, 2026
d02b534
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
f3866ab
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
052ba91
fix: small warning
aaroniker Jan 30, 2026
f3612cd
fix: github ci
aaroniker Jan 30, 2026
33f6b9e
feat: prompt style fix
aaroniker Jan 30, 2026
ab9d872
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
590b8d6
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
f85d487
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
5dc26a0
Merge branch 'dev' into desktop-quick-polishment
aaroniker Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/app/src/components/dialog-select-model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const ModelList: Component<{

export function ModelSelectorPopover<T extends ValidComponent = "div">(props: {
provider?: string
children?: JSX.Element
children?: JSX.Element | ((open: boolean) => JSX.Element)
triggerAs?: T
triggerProps?: ComponentProps<T>
}) {
Expand Down Expand Up @@ -182,12 +182,13 @@ export function ModelSelectorPopover<T extends ValidComponent = "div">(props: {
as={props.triggerAs ?? "div"}
{...(props.triggerProps as any)}
>
{props.children}
{typeof props.children === "function" ? props.children(store.open) : props.children}
</Kobalte.Trigger>
<Kobalte.Portal>
<Kobalte.Content
class="w-72 h-80 flex flex-col rounded-md border border-border-base bg-surface-raised-stronger-non-alpha shadow-md z-50 outline-none overflow-hidden"
data-component="model-popover-content"
ref={(el) => setStore("content", el)}
class="w-72 h-80 flex flex-col p-2 rounded-md border border-border-base bg-surface-raised-stronger-non-alpha shadow-md z-50 outline-none overflow-hidden"
onEscapeKeyDown={(event) => {
setStore("dismiss", "escape")
setStore("open", false)
Expand Down
148 changes: 93 additions & 55 deletions packages/app/src/components/prompt-input.tsx

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/app/src/components/session-context-usage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
}

const circle = () => (
<div class="p-1">
<ProgressCircle size={16} strokeWidth={2} percentage={context()?.percentage ?? 0} />
<div class="text-icon-base">
<ProgressCircle size={18} percentage={context()?.percentage ?? 0} />
</div>
)

Expand Down Expand Up @@ -101,7 +101,7 @@ export function SessionContextUsage(props: SessionContextUsageProps) {
<Button
type="button"
variant="ghost"
class="size-6"
class="size-7 text-icon-base"
onClick={openContext}
aria-label={language.t("context.usage.view")}
>
Expand Down
42 changes: 24 additions & 18 deletions packages/app/src/components/settings-general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { usePlatform } from "@/context/platform"
import { useSettings, monoFontFamily } from "@/context/settings"
import { playSound, SOUND_OPTIONS } from "@/utils/sound"
import { Link } from "./link"
import { ScrollFade } from "@opencode-ai/ui/scroll-fade"

let demoSoundState = {
cleanup: undefined as (() => void) | undefined,
Expand Down Expand Up @@ -60,24 +61,24 @@ export const SettingsGeneral: Component = () => {
const actions =
platform.update && platform.restart
? [
{
label: language.t("toast.update.action.installRestart"),
onClick: async () => {
await platform.update!()
await platform.restart!()
},
{
label: language.t("toast.update.action.installRestart"),
onClick: async () => {
await platform.update!()
await platform.restart!()
},
{
label: language.t("toast.update.action.notYet"),
onClick: "dismiss" as const,
},
]
},
{
label: language.t("toast.update.action.notYet"),
onClick: "dismiss" as const,
},
]
: [
{
label: language.t("toast.update.action.notYet"),
onClick: "dismiss" as const,
},
]
{
label: language.t("toast.update.action.notYet"),
onClick: "dismiss" as const,
},
]

showToast({
persistent: true,
Expand Down Expand Up @@ -130,7 +131,12 @@ export const SettingsGeneral: Component = () => {
const soundOptions = [...SOUND_OPTIONS]

return (
<div class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10">
<ScrollFade
direction="vertical"
fadeStartSize={0}
fadeEndSize={16}
class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10"
>
<div class="sticky top-0 z-10 bg-[linear-gradient(to_bottom,var(--surface-raised-stronger-non-alpha)_calc(100%_-_24px),transparent)]">
<div class="flex flex-col gap-1 pt-6 pb-8">
<h2 class="text-16-medium text-text-strong">{language.t("settings.tab.general")}</h2>
Expand Down Expand Up @@ -394,7 +400,7 @@ export const SettingsGeneral: Component = () => {
</div>
</div>
</div>
</div>
</ScrollFade>
)
}

Expand Down
10 changes: 8 additions & 2 deletions packages/app/src/components/settings-keybinds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import fuzzysort from "fuzzysort"
import { formatKeybind, parseKeybind, useCommand } from "@/context/command"
import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
import { ScrollFade } from "@opencode-ai/ui/scroll-fade"

const IS_MAC = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform)
const PALETTE_ID = "command.palette"
Expand Down Expand Up @@ -352,7 +353,12 @@ export const SettingsKeybinds: Component = () => {
})

return (
<div class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10">
<ScrollFade
direction="vertical"
fadeStartSize={0}
fadeEndSize={16}
class="flex flex-col h-full overflow-y-auto no-scrollbar px-4 pb-10 sm:px-10 sm:pb-10"
>
<div class="sticky top-0 z-10 bg-[linear-gradient(to_bottom,var(--surface-raised-stronger-non-alpha)_calc(100%_-_24px),transparent)]">
<div class="flex flex-col gap-4 pt-6 pb-6 max-w-[720px]">
<div class="flex items-center justify-between gap-4">
Expand Down Expand Up @@ -429,6 +435,6 @@ export const SettingsKeybinds: Component = () => {
</div>
</Show>
</div>
</div>
</ScrollFade>
)
}
1 change: 1 addition & 0 deletions packages/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ pub fn run() {
.decorations(false);

let window = window_builder.build().expect("Failed to create window");
let _ = window.show();

#[cfg(windows)]
let _ = window.create_overlay_titlebar();
Expand Down
179 changes: 94 additions & 85 deletions packages/ui/src/components/accordion.css
Original file line number Diff line number Diff line change
@@ -1,98 +1,107 @@
[data-component="accordion"] {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
align-self: stretch;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
align-self: stretch;

[data-slot="accordion-item"] {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
overflow: clip;
[data-slot="accordion-item"] {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
align-self: stretch;
overflow: clip;

[data-slot="accordion-header"] {
width: 100%;
display: flex;
align-items: center;
margin: 0;
padding: 0;
[data-slot="accordion-header"] {
width: 100%;
display: flex;
align-items: center;
margin: 0;
padding: 0;

[data-slot="accordion-trigger"] {
width: 100%;
display: flex;
height: 32px;
padding: 8px 12px;
justify-content: space-between;
align-items: center;
align-self: stretch;
cursor: default;
user-select: none;
[data-slot="accordion-trigger"] {
width: 100%;
display: flex;
height: 32px;
padding: 8px 12px;
justify-content: space-between;
align-items: center;
align-self: stretch;
cursor: default;
user-select: none;

background-color: var(--surface-base);
border: 1px solid var(--border-weak-base);
border-radius: var(--radius-md);
overflow: clip;
color: var(--text-strong);
transition: background-color 0.15s ease;
background-color: var(--surface-base);
border: 1px solid var(--border-weak-base);
border-radius: var(--radius-md);
overflow: clip;
color: var(--text-strong);
transition-property: background-color, border-color;
transition-duration: var(--transition-duration);
transition-timing-function: var(--transition-easing);

/* text-12-regular */
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
/* text-12-regular */
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);

&:hover {
background-color: var(--surface-base);
}
&:focus-visible {
outline: none;
}
&[data-disabled] {
cursor: not-allowed;
}
}
}
&:hover {
background-color: var(--surface-base);
}
&:focus-visible {
outline: none;
}
&[data-disabled] {
cursor: not-allowed;
}
}
}

&[data-expanded] {
[data-slot="accordion-trigger"] {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
[data-slot="accordion-arrow"] {
flex-shrink: 0;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-weak);
}

[data-slot="accordion-content"] {
border: 1px solid var(--border-weak-base);
border-top: none;
border-bottom-left-radius: var(--radius-md);
border-bottom-right-radius: var(--radius-md);
}
}
[data-slot="accordion-content"] {
display: grid;
grid-template-rows: 0fr;
transition-property: grid-template-rows, opacity;
transition-duration: var(--transition-duration);
transition-timing-function: var(--transition-easing);
width: 100%;

[data-slot="accordion-content"] {
overflow: hidden;
width: 100%;
}
}
}
> * {
overflow: hidden;
}
}

@keyframes slideDown {
from {
height: 0;
}
to {
height: var(--kb-accordion-content-height);
}
}
[data-slot="accordion-content"][data-expanded] {
grid-template-rows: 1fr;
}

[data-slot="accordion-content"][data-closed] {
grid-template-rows: 0fr;
}

&[data-expanded] [data-slot="accordion-trigger"] {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}

@keyframes slideUp {
from {
height: var(--kb-accordion-content-height);
}
to {
height: 0;
}
&[data-expanded] [data-slot="accordion-content"] {
border: 1px solid var(--border-weak-base);
border-top: none;
border-bottom-left-radius: var(--radius-md);
border-bottom-right-radius: var(--radius-md);
height: auto;
}
}
}
Loading
Loading