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
This commit is contained in:
Danila Poyarkov 2026-07-18 09:41:32 +03:00
parent f1af81962c
commit 5d9645fead
6 changed files with 19 additions and 11 deletions

View file

@ -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',

View file

@ -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 })"
>
<SelectScrollUpButton class="flex items-center justify-center py-0.5 text-muted">
<icon-lucide-chevron-up class="size-3.5" />
</SelectScrollUpButton>
<SelectViewport :class="styles.viewport({ class: ui?.viewport })">
<SelectItem
v-for="opt in options"
@ -59,6 +64,9 @@ const styles = tv(theme)()
<SelectItemText>{{ opt.label }}</SelectItemText>
</SelectItem>
</SelectViewport>
<SelectScrollDownButton class="flex items-center justify-center py-0.5 text-muted">
<icon-lucide-chevron-down class="size-3.5" />
</SelectScrollDownButton>
</SelectContent>
</SelectPortal>
</SelectRoot>

View file

@ -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,

View file

@ -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: {

View file

@ -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: {

View file

@ -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: '' },