Skip to content

Design spec · Component appendix

Shared rules live in Shared core; platform differences in macOS / Windows. This page holds the per-control Do/Don’t; register a new control here before implementing it.

ComponentBased onResponsibility
Panelframework tool/Panel.vuemodule panel (frame + header bar + body)
SettingsSection / SettingsRow / SettingsField@/components/settingsgroup + row + field
EmptyState / LoadingState / ErrorState@/components/nativethree-state standards (icon 20 + copy + action)
FormRow@/components/nativelabel + control + inline validation
ListRow@/components/nativelist row: primary + secondary text + trailing control
SearchField@/components/nativemagnifier + clear + search-as-you-type
Segmented@/components/native2–7 exclusive options with ←/→ keyboard semantics

Toolbar / SidebarList / PopUp / ToggleRow / StatusBar / ProgressBar / AlertDialog are planned; implement per §2 when needed and backfill this table.

1.5 Known pitfalls (reka-ui 2.10 + shadcn-vue)

Section titled “1.5 Known pitfalls (reka-ui 2.10 + shadcn-vue)”
  • data-active: / data-inactive: variants are dead rules: reka’s TabsTrigger only emits data-state="active|inactive". Always style with data-[state=active]:.
  • TabsList horizontal height is pinned by the group variant: group-data-[orientation=horizontal]/tabs:h-9 cannot be overridden by a plain h-*; use an inline style.
  • Do not reinstate global transition suppression: transition-duration: 75ms !important is removed; motion uses tokens. The reka popper wrapper’s transition-duration: 0s exception must stay.
DoDon’t
One primary button per screen (default), the rest secondary / ghostseveral default buttons competing
ghost only for panel-header / toolbar actionsghost as the primary action
Two height steps (h-8 regular / h-7 compact), icon size-3.5 + mr-1mixing h-9 with other sizes (except a page-level primary action)
Destructive actions as destructive + Alert confirmationred for “cancel” or ordinary actions
Verb labels matching the outcome (Export → “Exported”)generic OK / Submit / Run
DoDon’t
FormRow provides label + hint + inline validationplaceholder only, no label
Fixed height + scroll on overflowauto-grow causing layout jumps
Right-aligned numeric input + tabular-numsleft-aligned, non-tabular numbers
Validate in place (text-xs text-destructive under the control)error only in a toast, or only after submit
Monospace for code / paths / keysmonospace for body text
Section titled “Select / segmented / checkbox / switch / search”
DoDon’t
2–5 exclusive → segmented; ≥6 → selecta row of switches for exclusive options
Fine-grained boolean → checkbox (title on the right)fine-grained boolean as a switch
Mini switch in grouped forms (size="sm")a large switch breaking row height
A switch shares the row with its title (SettingRow)justify-between pulling title and switch apart
Search field searches as you type + clear buttonsearch field with a “Search” button
Fixed select width (control column aligned)varying widths, ragged left edges
DoDon’t
Wrap every module in Panel; header bar + body p-4modules exposed on the page
Subgroups inside one container via divide-y + small title + spacingcard-in-card, box-in-box
Row: primary + secondary (text-xs gray) + trailing controlthree or more lines of explanation per row
Rows are keyboard-focusable (tabindex + role)mouse-only rows

Overlays (menu / dialog / toast / tooltip)

Section titled “Overlays (menu / dialog / toast / tooltip)”
DoDon’t
Radius 12 (8 on Windows), consistent shadow + 1px strokeinconsistent radii / shadows
Esc closes and restores focus to the triggerfocus lost on close
Menu items ≥24px tall, icons 16, dangerous item last and separatedcramped items, dangerous item next to normal ones
Tooltip for supplementary text only (icon buttons, truncated text)Tooltip carrying must-read info
Toast only for system-level failures / finished long tasksusing a toast for form validation
DoDon’t
divide-y rows, sticky header, right-aligned numbersboxed rows, centered numbers
EmptyState for no dataa blank table
Opaque background in scroll areas (no glass)material over tables
Horizontal scroll + sticky first column when widesqueezing columns until text wraps
DoDon’t
Empty: icon (20) + headline + description + actiona bare “No data”
<1s no loading; 1–10s skeleton; >10s progress + cancela spinner overlay for everything
Error bar: cause + next step + retry“Something went wrong” with no information
DoDon’t
Sizes 14/16/20, stroke 2a custom icon size per page
Icon buttons always have aria-label + tooltipbare icons with no hint
Shortcuts visible in menu items / hints (⌘K / Ctrl+K per platform)hidden shortcuts documented only

3.5 Design-walkthrough workflow (self-served screenshots)

Section titled “3.5 Design-walkthrough workflow (self-served screenshots)”

The web layer renders in a normal browser (the preview bridge emulates the Tauri API), so screenshots can be scripted:

终端窗口
npx vite # start the frontend (1420)
node scripts/design-shot.mjs \
--url "/tool/hello-table" --out /tmp/a.png \
--theme dark --font 14 [--platform win] \
[--eval "document.querySelector('button').click()"] # interact before shooting
  • Preview bridge src/dev/preview-bridge.ts: active only under import.meta.env.DEV and outside Tauri; implements the __TAURI_INTERNALS__ protocol + a localStorage plugin-store + framework command fixtures.
  • A plugin’s own business-command fixtures live in plugins/<id>/frontend/preview.ts (default export Record<commandName, returnValue>), merged automatically in dev preview; base ships none.
  • URL params: ?theme=light|dark, ?font=13|14|15, ?accent=<name>, ?platform=win.
  • Use it to check spec clauses per screen and verify overlays / focus / three states; native window shell and material still need real-machine confirmation.

Base ships only _template / hello-world / system, all already brought up to this spec. A fork’s own plugins follow the same checklist batch by batch, tracked by each fork (the framework does not need to know fork plugin names). After each batch: pnpm lint && pnpm build && pnpm test, then self-check against Shared core §7; Rust batches additionally run pnpm fmt:rs && pnpm lint:rs && pnpm test:rs.