Design-Language/02-component-recipes.md
Component Recipes — Crawler Dashboard Design Language
wzxhzdk:26 Purpose: copy-paste-ready HTML / JSX skeletons for every pattern in 01-design-language.md. Use these before authoring any new component. If a recipe matches your need, use it.
wzxhzdk:27
wzxhzdk:28 Convention: examples are framework-agnostic HTML using class names from tokens.css. To use in React, replace class with className and convert attributes to camelCase. State props are noted in comments.
Recipe index
- Setting card (read mode)
- Setting card (edit mode, inline)
- Toggle row
- Toggle → conditional fields
- Number stepper with unit
- Repeating row (Start URLs / Exclusion Rules)
- Read-only with copy / Masked secret
- Day-picker pills
- Create-entity modal
- Destructive typed-confirm
- Status pill
- KPI tile row
- Empty state — data / gated / edit-empty
- Page header with tabs
- Three-section left nav
- Persistent CTA top bar
- Toolbar above table
- Data table
- Info banner inline
- Suggestion card
- Grouped warnings (Data Analysis)
- Run-control cluster (workspace top-right)
- Run-state pill (list row)
- Re-crawl confirm dialog (scoped, not typed)
1. Setting card (read mode)
wzxhzdk:0
Notes: - Icon tile = 32px square, light grey fill, 8px radius, dark monochrome glyph. - The right-side "value" is muted text — never bold, never colored. - The Edit button is the only interactive element.
2. Setting card (edit mode, inline)
wzxhzdk:1
Rules: - Save is disabled (greyed) until the form is dirty; becomes solid blue when dirty. - Cancel is always available; reverts state and collapses card back to read mode. - No "delete" button inside the edit body — use the danger zone (Recipe 10) for destructive operations.
3. Toggle row
wzxhzdk:2
Rules: - Always pair the switch with a textual label ("Enabled" / "Disabled") — never rely on track color alone.
4. Toggle → conditional fields
wzxhzdk:3
Rules: - Three levels of progressive disclosure max. Don't nest deeper. - Fieldset legend repeats the dropdown selection so user remembers their choice.
5. Number stepper with unit
wzxhzdk:4
Rule: when a number has a unit, surround the input with natural-language framing ("when it has crawled X URLs"). It's more readable than a labelled input alone.
6. Repeating row
wzxhzdk:5
Rules:
- Add button is ghost-style with a + glyph, always below the rows.
- Trash is a 40px icon button (icon-only with aria-label).
- Removing the last row is allowed; the empty state appears below the add button.
7. Read-only with copy / Masked secret
wzxhzdk:6
8. Day-picker pills
wzxhzdk:7
9. Create-entity modal
wzxhzdk:8
10. Destructive typed-confirm
wzxhzdk:9
Rules: - The scope statement (what is not affected) is mandatory. - The button stays disabled until the user types "DELETE" exactly. - No second "Cancel" button needed — closing the dialog (X or Escape) is the cancel.
11. Status pill
wzxhzdk:10
12. KPI tile row
wzxhzdk:11
13. Empty states
Variant: data (table empty)
wzxhzdk:12
Variant: gated (requires-prereq)
wzxhzdk:13
Variant: edit-empty (inside an edit-mode card)
wzxhzdk:14
14. Page header with tabs
wzxhzdk:15
15. Three-section left nav
wzxhzdk:16
16. Persistent CTA top bar
wzxhzdk:17
17. Toolbar above table
wzxhzdk:18
18. Data table
wzxhzdk:19
19. Info banner inline
wzxhzdk:20
Use for: safety rails on consequential actions, prerequisite reminders, scope clarifications.
20. Suggestion card
wzxhzdk:21
21. Grouped warnings (Data Analysis post-run)
wzxhzdk:22
22. Run-control cluster
The persistent top-right control of the focused workspace. State-aware: button label and overflow menu both change based on the crawler's current run state. This is our value-add over Algolia's single static CTA.
wzxhzdk:23
Stateful labels:
| State | Primary button | Overflow items |
|---|---|---|
idle |
Crawl now (filled) |
Edit configuration · Re-crawl from scratch · Settings |
running |
Pause (ghost) |
Stop crawl · View live log · Settings |
paused |
Resume (filled) |
Stop crawl · Edit configuration · Re-crawl from scratch |
stopped |
Crawl now (filled) |
Re-crawl from scratch · Edit configuration · Settings |
failed |
Retry (filled) |
View error log · Edit configuration · Settings |
Implementation notes:
- The button visually morphs (label + icon) between states, never a layout shift.
- Overflow menu is keyboard-navigable: ↑/↓ between items, Escape to close, Enter to activate.
- Menu items that lead to destructive actions (Stop crawl, Re-crawl from scratch) get the --danger modifier on hover state.
- Re-crawl from scratch always opens Recipe 24 — never fires immediately.
23. Run-state pill (list row)
Used in the crawler list table to show the current state of each crawler at a glance. Different from the static "last status" pills (Recipe 11): this one is live and it animates only the dot, never the layout.
wzxhzdk:24
Rules:
- Only Running gets the live-dot pulse. All other states are static.
- Pulse is opacity-only; never use scale, glow, or color shifts.
- The pill is paired with a 3-dot overflow menu in the row to expose actions (Pause / Resume / Stop / Open / Delete).
24. Re-crawl confirm dialog
A scoped confirmation — less heavy than the typed-confirm (Recipe 10) because the action is destructive of records only, not the asset itself. Records get re-built on the next crawl. The crawler config, schedule, and index name all survive.
wzxhzdk:25
Why not typed-confirm? Re-crawl is recoverable — the next crawl rebuilds the records. Typed-confirm (Recipe 10) is reserved for irreversible actions (Delete crawler). Reserving it for true irreversibility is what makes it credible.
How to extend this file
When you encounter a pattern in the dashboard not covered here:
- Take a screenshot, save it under
dashboard_screenshots/with a numbered name. - Add a finding to
00-findings.mddescribing what's new. - Add a recipe to this file with the copy-paste skeleton.
- If the pattern requires a new token, add it to
tokens.cssand reference it in01-design-language.md§1.
The pack stays portable as long as all four files travel together: 00-findings.md, 01-design-language.md, 02-component-recipes.md, tokens.css.