Repository navigation
docs(ui): the Querya button and control standard (sizes, variants, states, rules) before any code #1332
Description
Part of #1331.
Why first
The review showed that the problem is not a missing widget but missing rules: three heights were chosen per call site. This issue fixes the rules in docs/ui-kit.md (and the Obsidian Единый UI-стандарт) so the components, the migration and the guard tests all implement the same thing. Nothing is built until this is agreed.
The standard (proposal, to confirm in review)
1. Control scale. One scale for every interactive control (buttons, icon buttons, dropdown triggers, search fields, tab strips, toggles), multiplied by uiScale:
| size | height | h-padding | label | icon | icon gap | use |
|---|---|---|---|---|---|---|
sm |
28 | 8 | 12 / w500 | 14 | 6 | trees, panel headers, data-grid and staging toolbars, inline row actions |
md |
32 | 12 | 13 / w500 | 16 | 6 | default: top toolbars, SQL editor, results, ERD, tab bars |
lg |
36 | 16 | 14 / w500 | 18 | 8 | dialogs, forms, onboarding, empty states |
Icon-only controls are square (width = height). One corner radius for controls: 6. Today's QueryaIconButtonDensity (28 / 32) and QueryaDropdownTokens (26 / 36) are folded into this scale.
2. Variants (what the button means, not how it is painted):
| variant | look | use |
|---|---|---|
primary |
accent fill, onAccent text |
the one main action of a surface; at most one per dialog / toolbar |
secondary (default) |
transparent, 1 px borderSubtle, foreground text |
every other action |
ghost |
no border, hover fill | cancel / dismiss, quiet toolbar actions, icon-only |
destructive |
destructive fill (primary tone) or red text (secondary / ghost tone) |
irreversible actions |
Selected / toggled (isActive) is a state of any variant: accent 14 % fill + 30 % accent border (as QueryaIconButton does today). No tinted-fill "tonal" variant: the two Mongo _ActionButton copies become secondary.
3. States. rest · hover (fill from muted 35 %, primary +12 % onAccent) · pressed (fill 50 %, no scale) · keyboard-focus (2 px accent ring, only for keyboard focus) · disabled (50 % foreground, basic cursor, no hover) · loading (spinner replaces the leading icon, or the label of an icon-only button; width is reserved so nothing jumps; not pressable) · selected. Colour fades use QueryaMotion.fast / enter and are instant under reduced motion.
4. Anatomy and behaviour. [leading icon] label [trailing: chevron | shortcut hint]. Label is one line with ellipsis, never wraps. Icon-only controls must have a tooltip (kQueryaTooltipWait); labelled controls may. Minimum hit area 28 × 28 even when the visible icon is smaller (an inline tree action keeps a 14 px icon in a 28 px target). A labelled button collapses to icon-only with its label as the tooltip on a narrow toolbar. Enter / Space activate; the control is focusable and has semantics (label, enabled, busy).
5. Layout rules.
- One row = one size. A toolbar never mixes
smandmdcontrols. - Gap between controls 8; inside a group (split button, segmented control) 0 with a shared border and radius only on the outer corners.
- A split button (action + menu) is one component, not two neighbours.
- Dialog footer: right-aligned, order secondary actions → cancel (ghost) → primary / destructive, gap 8, all
lg; a lone Close issecondary; Retry issecondary, orprimaryin an empty / error state; destructive confirmation pairs Cancel withdestructive, never two filled buttons. - Destructive actions sit last in a toolbar or inside its menu, never first.
6. What is not allowed. shadcn button types, Material IconButton / TextButton / ElevatedButton, InkWell / GestureDetector with a Text child used as a button, a literal height / radius / font size on a button, a literal tooltip delay, a hand-made spinner or eye icon.
7. Theme. Colours come from context.workbench and QueryaSemanticPalette; a custom VS Code theme recolours every button. Text on accent / destructive fills must pass the contrast check already in color_contrast.dart.
Deliverables
-
docs/ui-kit.md: Buttons and controls section with the tables above, the do / don't snippets and the shadcn → Querya mapping. - Obsidian note Единый UI-стандарт: the same, plus a rationale paragraph.
- The mapping table for the migration: shadcn
ButtonSize.small→smin panels andmdin toolbars,normal→lgin dialogs andmdin toolbars;OutlineButton→secondary,GhostButton→ghost,PrimaryButton→primary,DestructiveButton→destructive,QueryaActionButton→secondary md,QueryaActionMenutrigger → menu button. - The values above signed off (any change is made here, once).
Out of scope
Inputs, dropdown menus and tab strips keep their own components; they only adopt the scale's heights (see the metrics issue).
Activity
ZhuchkaTriplesix commentedon Oct 11, 2026
Done in #1403 (merged into
dev).