From 5d9645fead73c16ce0d78650955452870a2d4d97 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sat, 18 Jul 2026 09:41:32 +0300 Subject: [PATCH] feat(ui): section header bands and dropdown polish - Section headers become full 32px bands (title + trailing actions vertically centered) instead of an 11px line crammed against fields, giving each section a clear structural band like Figma - Select dropdowns adopt the floating-surface elevation (12px radius, no border, deep shadow), 24px flush items, and scroll up/down buttons for long lists (blend modes) - Font-settings gear trigger drops its hardcoded dark bg+border for the ghost icon-button recipe - Segmented-control active state uses neutral hover fill instead of the blue-grey selection color --- src/components/FontSettings/FontSettingsPopover.vue | 2 +- src/components/ui/AppSelect.vue | 8 ++++++++ src/theme/app-select.ts | 2 +- src/theme/panel/section.ts | 6 +++--- src/theme/segmented-control.ts | 2 +- src/theme/select.ts | 10 +++++----- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/components/FontSettings/FontSettingsPopover.vue b/src/components/FontSettings/FontSettingsPopover.vue index 29190139e..6f5d71e4f 100644 --- a/src/components/FontSettings/FontSettingsPopover.vue +++ b/src/components/FontSettings/FontSettingsPopover.vue @@ -16,7 +16,7 @@ const cls = usePopoverUI({ content: 'isolate z-[51] w-80 p-3' }) const trigger = useButtonUI({ tone: 'ghost', size: 'iconSm', - ui: { base: 'shrink-0 border border-border bg-input' } + ui: { base: 'shrink-0' } }) const secondaryButton = useButtonUI({ tone: 'ghost', diff --git a/src/components/ui/AppSelect.vue b/src/components/ui/AppSelect.vue index fe0e2a160..538f36808 100644 --- a/src/components/ui/AppSelect.vue +++ b/src/components/ui/AppSelect.vue @@ -7,6 +7,8 @@ import { SelectItemText, SelectPortal, SelectRoot, + SelectScrollDownButton, + SelectScrollUpButton, SelectTrigger, SelectValue, SelectViewport @@ -46,6 +48,9 @@ const styles = tv(theme)() :side-offset="2" :class="styles.content({ class: ui?.content })" > + + + {{ opt.label }} + + + diff --git a/src/theme/app-select.ts b/src/theme/app-select.ts index 659072411..c2dbeeed3 100644 --- a/src/theme/app-select.ts +++ b/src/theme/app-select.ts @@ -7,7 +7,7 @@ const appSelectTheme = { value: [selectTheme.slots.value, 'min-w-0 flex-1 truncate text-left'], content: [selectTheme.slots.content, 'max-h-56'], viewport: [selectTheme.slots.viewport, 'p-0.5'], - item: [selectTheme.slots.item, 'rounded py-1.5 pr-2 pl-6 text-[11px]'], + item: [selectTheme.slots.item, 'py-0 pr-2 pl-6 text-[11px]'], indicator: 'absolute left-1.5 inline-flex items-center justify-center' }, variants: selectTheme.variants, diff --git a/src/theme/panel/section.ts b/src/theme/panel/section.ts index 7ce53e5bd..7513a4dee 100644 --- a/src/theme/panel/section.ts +++ b/src/theme/panel/section.ts @@ -1,11 +1,11 @@ const panelSectionTheme = { slots: { - root: 'border-b border-border px-3 py-2 text-surface data-[disabled]:opacity-60', - header: 'mb-1.5 grid min-w-0 items-center gap-1.5', + root: 'border-b border-border px-3 pb-3 text-surface data-[disabled]:opacity-60', + header: 'grid h-8 min-w-0 items-center gap-1.5', title: 'min-w-0 cursor-pointer truncate border-0 bg-transparent p-0 text-left text-[11px] leading-none font-semibold text-surface', actions: - 'flex h-6 w-[26px] shrink-0 items-center justify-end gap-0.5 [&_[data-slot=icon-button]]:size-6 [&_[data-slot=icon-button]]:rounded', + 'flex h-7 w-[26px] shrink-0 items-center justify-end gap-0.5 [&_[data-slot=icon-button]]:size-6 [&_[data-slot=icon-button]]:rounded', body: 'min-w-0 data-[state=closed]:hidden' }, variants: { diff --git a/src/theme/segmented-control.ts b/src/theme/segmented-control.ts index 195ce5314..118642281 100644 --- a/src/theme/segmented-control.ts +++ b/src/theme/segmented-control.ts @@ -3,7 +3,7 @@ import { panelFieldBase } from './panel/field' const segmentedControlTheme = { slots: { root: [panelFieldBase, 'inline-flex items-center gap-0.5 p-0.5'], - item: 'flex h-[22px] min-w-0 flex-1 cursor-pointer items-center justify-center gap-1 rounded-sm text-muted outline-none hover:bg-hover hover:text-surface focus-visible:ring-1 focus-visible:ring-panel-focus data-[state=on]:bg-panel-selected-muted data-[state=on]:text-surface data-[state=on]:hover:bg-panel-selected-muted disabled:cursor-not-allowed disabled:opacity-50' + item: 'flex h-[22px] min-w-0 flex-1 cursor-pointer items-center justify-center gap-1 rounded-sm text-muted outline-none hover:bg-hover hover:text-surface focus-visible:ring-1 focus-visible:ring-panel-focus data-[state=on]:bg-hover data-[state=on]:text-surface data-[state=on]:hover:bg-hover disabled:cursor-not-allowed disabled:opacity-50' }, variants: { size: { diff --git a/src/theme/select.ts b/src/theme/select.ts index 2ed87eabd..04d3c6184 100644 --- a/src/theme/select.ts +++ b/src/theme/select.ts @@ -5,18 +5,18 @@ export default { trigger: [panelFieldBase, 'flex items-center justify-between text-[11px]'], value: 'min-w-0 flex-1 truncate text-left', content: - 'z-[110] min-w-[var(--reka-select-trigger-width)] overflow-hidden border border-border bg-panel text-[11px]', + 'z-[110] min-w-[var(--reka-select-trigger-width)] overflow-hidden rounded-xl bg-panel text-[11px] shadow-[0_8px_30px_rgb(0_0_0/0.4)]', viewport: '', - item: 'relative flex cursor-pointer items-center text-surface outline-none select-none data-[disabled]:pointer-events-none data-[highlighted]:bg-hover data-[disabled]:opacity-50' + item: 'relative flex h-6 cursor-pointer items-center text-surface outline-none select-none data-[disabled]:pointer-events-none data-[highlighted]:bg-hover data-[disabled]:opacity-50' }, variants: { radius: { md: { content: 'rounded-md' }, - lg: { content: 'rounded-lg' } + lg: { content: 'rounded-xl' } }, elevation: { - lg: { content: 'shadow-lg' }, - xl: { content: 'shadow-xl' } + lg: { content: 'shadow-[0_8px_30px_rgb(0_0_0/0.4)]' }, + xl: { content: 'shadow-[0_8px_30px_rgb(0_0_0/0.4)]' } }, padding: { none: { content: '' },