Skip to content

epic(ui): buttons in the Querya UI kit: one control scale, our own button family, no shadcn buttons #1331

Description

@ZhuchkaTriplesix

Goal

Every button in Querya looks, sizes and behaves the same, comes from our own UI kit, and does not depend on shadcn_flutter. We are moving off that library; buttons are the largest part left (≈ 290 shadcn button calls, 17 QueryaActionButton, 26 QueryaIconButton, ~70 raw IconButtons, 84 InkWells, 7 home-made button classes).

Standards first, components second, migration third, guards last.

Why (findings of the button review)

  • Six button "systems" with no common scale: shadcn normal (~36 px) and small (~28 px, scaled font and icon), QueryaIconButton 28 / 32, QueryaToolbarButton, seven private button classes (20–30 px), bare InkWell / IconButton.
  • Mixed heights in one toolbar: QueryaActionButton is normal, QueryaActionMenu is small — the ERD toolbar and the SQL editor's Execute split button show both side by side.
  • Icon inside a button is not tied to its size: QueryaActionButton always draws 18 px, small buttons carry 13 / 14 / 15 / 16 px icons by hand.
  • The same action looks different per dialog: Cancel is GhostButton 21×, OutlineButton 11×; Close is primary 5×, outline 6×, ghost 3×; Create is small 3×, normal 3×.
  • Copies: _ActionButton exists twice (Mongo collections / databases), plus _SmallActionButton, _TreeIconButton (20×20 hit area), _ToolbarButton, TableEditModeButton; the show-password eye button is pasted into four forms.
  • Hit areas and rounding: 15 InkWells with a square ripple, radii 3 / 4 / 6 / 8 / 16 / 20, a 16 px close icon as a button, no tooltip, disabled only by colour.
  • Tooltips: 6 use kQueryaTooltipWait, 6 literals, the rest the default (instant).

Plan (one issue each, in this order)

  1. docs(ui): the Querya button and control standard (sizes, variants, states, rules) before any code #1332 the standard (sizes, variants, states, layout and dialog-footer rules, mapping): agreed before any code
  2. feat(ui): control metrics and tokens shared by buttons, dropdowns, search fields and tab strips #1333 control metrics and tokens: one height per size for buttons, icon buttons, dropdowns, search fields, tab strips
  3. feat(ui): QueryaButton: primary / secondary / ghost / destructive on Flutter primitives, no shadcn #1334 QueryaButton: primary / secondary / ghost / destructive on Flutter primitives, no shadcn
  4. feat(ui): QueryaSplitButton, QueryaMenuButton and QueryaDialogActions #1335 QueryaSplitButton, QueryaMenuButton, QueryaDialogActions: the compositions that went wrong
  5. dev(ui): UI kit gallery: every control, variant, size and state in every theme #1336 UI kit gallery (debug): everything side by side, in every theme
  6. refactor(ui): migrate toolbars, panels and the self-made buttons to QueryaButton #1337 migration of toolbars and panels, removal of the private button copies
  7. refactor(ui): migrate dialogs and forms to QueryaButton and QueryaDialogActions #1338 migration of dialogs and forms to one footer
  8. chore(ui): remove the remaining shadcn buttons and add guard tests for the button standard #1339 removal of the remaining shadcn buttons + guard tests
  9. test(ui): widget and layout tests for the button family and for one height per row #1340 widget and layout tests (one height per row, states, theme switch)

Issues 5 and 9 can run beside 3-4; 6 and 7 can run in parallel after 4.

Rules that hold for all of them

  1. One control scale (sm 28 / md 32 / lg 36) shared by buttons, icon buttons, dropdown triggers, search fields and tab strips: a row has one height.
  2. Own widgets on Flutter primitives; no shadcn_flutter button type is imported outside the kit during and after the migration.
  3. Colours only from context.workbench / QueryaSemanticPalette; motion only from QueryaMotion; sizes only from the kit's tokens and uiScale.
  4. A guard test accompanies every replaced widget family, as for dialogs, dropdowns and spinners.

Done when

  • docs/ui-kit.md and the Obsidian UI standard hold the button standard and the migration table.
  • No shadcn button, raw IconButton / TextButton / ElevatedButton, or private button class remains outside the kit (guard tests green).
  • The kit gallery shows every variant × size × state in every built-in theme, and the layout tests keep one height per row.

Activity

  1. added
    epicEpic / umbrella issue
    frontendTheme parser epic label: frontend
    uiUser interface components and widgets
    uxUser experience, keyboard shortcuts and interactions
    on Oct 10, 2026
  2. ZhuchkaTriplesix commented on Oct 10, 2026

    @ZhuchkaTriplesix
    MemberAuthor

    Related accessibility requirement: #1370 ensures that the standardized QueryaIconButton / QueryaToolbarButton includes a visible 2px keyboard focus ring and proper Semantics(toggled: isActive).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicEpic / umbrella issuefrontendTheme parser epic label: frontenduiUser interface components and widgetsuxUser experience, keyboard shortcuts and interactions

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions