@momoi-labs/kiso 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -0
  3. package/kiso/AGENTS.md +50 -0
  4. package/kiso/README.md +62 -0
  5. package/kiso/docs/accessibility.md +87 -0
  6. package/kiso/docs/brand.md +95 -0
  7. package/kiso/docs/components/README.md +58 -0
  8. package/kiso/docs/components/alert.md +158 -0
  9. package/kiso/docs/components/badge.md +135 -0
  10. package/kiso/docs/components/breadcrumb.md +66 -0
  11. package/kiso/docs/components/button.md +168 -0
  12. package/kiso/docs/components/card.md +154 -0
  13. package/kiso/docs/components/checkbox.md +91 -0
  14. package/kiso/docs/components/command-palette.md +165 -0
  15. package/kiso/docs/components/drawer.md +79 -0
  16. package/kiso/docs/components/dropdown-menu.md +178 -0
  17. package/kiso/docs/components/empty-state.md +142 -0
  18. package/kiso/docs/components/form-field.md +115 -0
  19. package/kiso/docs/components/header.md +79 -0
  20. package/kiso/docs/components/helper-text.md +86 -0
  21. package/kiso/docs/components/icon-button.md +161 -0
  22. package/kiso/docs/components/input.md +99 -0
  23. package/kiso/docs/components/label.md +88 -0
  24. package/kiso/docs/components/link.md +152 -0
  25. package/kiso/docs/components/modal-dialog.md +82 -0
  26. package/kiso/docs/components/navigation.md +68 -0
  27. package/kiso/docs/components/page-header.md +70 -0
  28. package/kiso/docs/components/pagination.md +129 -0
  29. package/kiso/docs/components/popover.md +74 -0
  30. package/kiso/docs/components/search.md +147 -0
  31. package/kiso/docs/components/select.md +105 -0
  32. package/kiso/docs/components/sidebar.md +74 -0
  33. package/kiso/docs/components/skeleton.md +140 -0
  34. package/kiso/docs/components/spinner.md +125 -0
  35. package/kiso/docs/components/switch.md +92 -0
  36. package/kiso/docs/components/table.md +255 -0
  37. package/kiso/docs/components/tabs.md +69 -0
  38. package/kiso/docs/components/textarea.md +91 -0
  39. package/kiso/docs/components/toast.md +80 -0
  40. package/kiso/docs/components/tooltip.md +162 -0
  41. package/kiso/docs/components/validation-message.md +96 -0
  42. package/kiso/docs/data-interfaces.md +309 -0
  43. package/kiso/docs/evolution.md +35 -0
  44. package/kiso/docs/patterns/README.md +40 -0
  45. package/kiso/docs/patterns/application-shell.md +106 -0
  46. package/kiso/docs/patterns/command-palette.md +142 -0
  47. package/kiso/docs/patterns/confirmations.md +158 -0
  48. package/kiso/docs/patterns/crud.md +139 -0
  49. package/kiso/docs/patterns/dashboard.md +102 -0
  50. package/kiso/docs/patterns/destructive-actions.md +137 -0
  51. package/kiso/docs/patterns/developer-oriented-interfaces.md +162 -0
  52. package/kiso/docs/patterns/empty-states.md +76 -0
  53. package/kiso/docs/patterns/errors.md +93 -0
  54. package/kiso/docs/patterns/filtering.md +147 -0
  55. package/kiso/docs/patterns/keyboard-shortcuts.md +155 -0
  56. package/kiso/docs/patterns/large-data-tables.md +182 -0
  57. package/kiso/docs/patterns/list-detail.md +118 -0
  58. package/kiso/docs/patterns/loading.md +80 -0
  59. package/kiso/docs/patterns/login-authentication.md +101 -0
  60. package/kiso/docs/patterns/onboarding.md +94 -0
  61. package/kiso/docs/patterns/pagination.md +121 -0
  62. package/kiso/docs/patterns/permission-denied.md +84 -0
  63. package/kiso/docs/patterns/search.md +150 -0
  64. package/kiso/docs/patterns/settings.md +100 -0
  65. package/kiso/docs/patterns/sorting.md +121 -0
  66. package/kiso/docs/principles.md +122 -0
  67. package/kiso/docs/tokens.md +95 -0
  68. package/kiso/docs/voice-and-tone.md +154 -0
  69. package/package.json +42 -0
  70. package/tokens/build/tokens.css +143 -0
  71. package/tokens/build/tokens.d.ts +160 -0
  72. package/tokens/build/tokens.json +88 -0
  73. package/tokens/build/tokens.scss +89 -0
@@ -0,0 +1,82 @@
1
+ # Modal / Dialog
2
+
3
+ A focused overlay for a task or decision that temporarily blocks the page.
4
+
5
+ ## Purpose
6
+
7
+ Modal/Dialog interrupts the current flow only when the person must complete,
8
+ confirm, or cancel a focused task before returning. It traps focus and makes
9
+ the page behind it inert. On small viewports, content that needs more room may
10
+ use [Drawer](drawer.md) instead.
11
+
12
+ ## Anatomy
13
+
14
+ ```
15
+ Dialog Root
16
+ ├── Trigger
17
+ ├── Overlay
18
+ └── Content
19
+ ├── Title (required)
20
+ ├── Description (required when the title is insufficient)
21
+ ├── body
22
+ ├── actions
23
+ └── Close control
24
+ ```
25
+
26
+ Content uses `--color-elevated-surface`, `--color-foreground`,
27
+ `--color-border`, `--radius-lg`, `--spacing-lg` padding, and `--shadow-md`.
28
+ Overlay transitions use `--motion-duration-normal` and
29
+ `--motion-easing-standard`.
30
+
31
+ ## Variants
32
+
33
+ Two behavioral variants: task Dialog (default) and Alert Dialog for a
34
+ confirmation that must prevent outside dismissal. Both keep the same labelled,
35
+ modal focus behavior; an in-page Alert is not a Dialog variant.
36
+
37
+ ## Sizes
38
+
39
+ One responsive size. Content uses a readable bounded width and becomes
40
+ viewport-limited when space is tight; use Drawer when the task needs a distinct
41
+ small-viewport presentation instead of adding `sm` / `lg` Dialog sizes.
42
+
43
+ ## States
44
+
45
+ | State | Behavior |
46
+ | --- | --- |
47
+ | closed (default) | Content is absent; trigger remains available. |
48
+ | hover | Trigger and child controls own hover. |
49
+ | focus | Opening moves focus inside; `--color-focus` remains visible on controls. |
50
+ | active/open | Page behind is inert; focus is trapped in Content. |
51
+ | disabled | A disabled trigger does not open; the Dialog itself is not disabled. |
52
+ | loading | Keep close/cancel available when safe, mark the task `aria-busy="true"`, and prevent duplicate submission. |
53
+ | error | Show recoverable error next to the affected action or field; keep the Dialog open. |
54
+
55
+ ## Accessibility
56
+
57
+ Use `role="dialog"`, `aria-modal="true"`, `aria-labelledby`, and when needed
58
+ `aria-describedby` (Radix supplies these from Title/Description). Opening moves
59
+ focus to the first meaningful element, not always the close icon. `Tab` and
60
+ `Shift+Tab` cycle inside; `Escape` closes unless a destructive operation cannot
61
+ safely be interrupted. Closing returns focus to the trigger or the next logical
62
+ control. Clicking the overlay may close only when losing work is impossible.
63
+
64
+ ## When to use
65
+
66
+ - A short focused task, confirmation, or decision that blocks page work.
67
+ - Content that needs explicit completion or cancellation.
68
+
69
+ ## When NOT to use
70
+
71
+ - Persistent information; use an in-page [Alert](alert.md).
72
+ - A transient confirmation; use [Toast](toast.md).
73
+ - Rich contextual content anchored to a control; use [Popover](popover.md).
74
+ - Long or navigation-heavy workflows; use a page, or Drawer when viewport
75
+ adaptation is the real need.
76
+
77
+ ## Radix/shadcn mapping
78
+
79
+ Maps to Radix Dialog / shadcn Dialog (`Root`, `Trigger`, `Portal`, `Overlay`,
80
+ `Content`, `Title`, `Description`, `Close`). Use Radix Alert Dialog only for
81
+ confirmations that require its stricter outside-dismiss behavior; it is not
82
+ Kiso's in-page Alert.
@@ -0,0 +1,68 @@
1
+ # Navigation
2
+
3
+ A semantic container for a coherent set of Links to major destinations.
4
+
5
+ ## Purpose
6
+
7
+ Navigation supplies landmark and grouping semantics without choosing a layout.
8
+ [Header](header.md) and [Sidebar](sidebar.md) are specific layout roles that
9
+ compose Navigation; Navigation itself is not a visual menu or overlay.
10
+
11
+ ## Anatomy
12
+
13
+ ```
14
+ Navigation
15
+ ├── accessible label
16
+ └── list
17
+ └── Link(s)
18
+ ```
19
+
20
+ Presentation inherits its host. Links use `--color-foreground`,
21
+ `--color-primary`, and `--color-focus`. Items use `--spacing-sm` block and
22
+ `--spacing-md` inline spacing plus the five property-qualified label typography
23
+ tokens.
24
+
25
+ ## Variants
26
+
27
+ No visual variants. Navigation is semantic structure and inherits horizontal,
28
+ vertical, or other presentation from its Header, Sidebar, footer, or section.
29
+
30
+ ## Sizes
31
+
32
+ No sizes of its own. The host controls layout and spacing; Links keep the sizes
33
+ defined by their component guidance.
34
+
35
+ ## States
36
+
37
+ | State | Behavior |
38
+ | --- | --- |
39
+ | default | Destinations are exposed as native Links. |
40
+ | hover | Link owns hover feedback. |
41
+ | focus | Focused Link shows `--color-focus`. |
42
+ | active | Current destination uses `aria-current="page"`. |
43
+ | disabled | Navigation is never disabled; omit unavailable destinations or follow Link guidance. |
44
+
45
+ ## Accessibility
46
+
47
+ Use `<nav aria-label="…">` and preferably a list of Links. Each navigation
48
+ landmark on the page needs a distinct label (“Primary”, “Breadcrumb”,
49
+ “Pagination”). Do not add menu roles: application navigation keeps native Link
50
+ semantics and `Tab` order. `Enter` follows a Link.
51
+
52
+ ## When to use
53
+
54
+ - To group destinations in Header, Sidebar, footer, or a local section.
55
+ - When assistive-technology users should be able to jump to the link set as a
56
+ landmark.
57
+
58
+ ## When NOT to use
59
+
60
+ - A group of commands or Buttons.
61
+ - Tabs that switch within-page panels.
62
+ - Breadcrumb or Pagination, which need their more specific labels and rules.
63
+
64
+ ## Radix/shadcn mapping
65
+
66
+ No primitive is needed: use native `<nav>` + list + Kiso Link. Radix Navigation
67
+ Menu / shadcn Navigation Menu is only a behavioral reference for genuinely
68
+ compound disclosure navigation, not the default implementation.
@@ -0,0 +1,70 @@
1
+ # PageHeader
2
+
3
+ Introduces one page with its title, supporting context, and primary actions.
4
+
5
+ ## Purpose
6
+
7
+ PageHeader gives every route a clear content heading and a predictable place
8
+ for page-scoped actions. It composes title + optional subtitle + action
9
+ [Buttons](button.md); it is distinct from the application [Header](header.md).
10
+
11
+ ## Anatomy
12
+
13
+ ```
14
+ PageHeader
15
+ ├── title (required h1)
16
+ ├── subtitle (optional)
17
+ └── actions (optional)
18
+ └── Button(s)
19
+ ```
20
+
21
+ Title uses `--type-role-heading-font-family`, `--type-role-heading-font-size`,
22
+ `--type-role-heading-font-weight`, `--type-role-heading-letter-spacing`, and
23
+ `--type-role-heading-line-height` with `--color-foreground`; subtitle uses the
24
+ five property-qualified body typography tokens and `--color-muted-foreground`.
25
+ Layout uses `--spacing-lg` between regions and `--spacing-sm` between title and
26
+ subtitle. Actions retain Button tokens and behavior.
27
+
28
+ ## Variants
29
+
30
+ No visual variants. Subtitle and actions are optional anatomy; their presence
31
+ does not create separate PageHeader variants.
32
+
33
+ ## Sizes
34
+
35
+ One size. The title keeps the page-heading type role; responsive wrapping is a
36
+ compact state, while child Buttons retain their own sizes.
37
+
38
+ ## States
39
+
40
+ | State | Behavior |
41
+ | --- | --- |
42
+ | default | Title leads; subtitle and actions support it. |
43
+ | hover | No container hover; Buttons own hover. |
44
+ | focus | Focus lands on actions, never on the layout container by default. |
45
+ | active | N/A for the container; child Buttons own active state. |
46
+ | disabled | PageHeader is never disabled; individual actions may be. |
47
+ | compact | On narrow viewports, actions wrap below text without changing reading or focus order. |
48
+
49
+ ## Accessibility
50
+
51
+ Use the page's single `<h1>` for the title. Keep DOM order title, subtitle,
52
+ then actions even when visual layout places actions beside the title. Button
53
+ labels must state their actions. Do not put navigation controls here merely to
54
+ fill space.
55
+
56
+ ## When to use
57
+
58
+ - At the start of a routed page or a primary workspace view.
59
+ - When page-specific actions need a consistent location.
60
+
61
+ ## When NOT to use
62
+
63
+ - For global product chrome; use Header.
64
+ - Inside every Card or nested section; use the correct heading level.
65
+ - When it would create a second `<h1>` on the page.
66
+
67
+ ## Radix/shadcn mapping
68
+
69
+ No Radix or shadcn PageHeader primitive. Compose semantic HTML and Kiso Button;
70
+ do not treat shadcn CardHeader as a page-level substitute.
@@ -0,0 +1,129 @@
1
+ # Pagination
2
+
3
+ Moves through explicit pages or indicates progress through a bounded sequence.
4
+
5
+ ## Purpose
6
+
7
+ Pagination exposes position and direct page navigation when page numbers help
8
+ the person reason about a dataset. It composes with Table/DataTable; it does
9
+ not replace filtering or Search. Its step indicator variant exposes position
10
+ in a sequential workflow without making progress itself.
11
+
12
+ ## Anatomy
13
+
14
+ ```
15
+ Pagination navigation
16
+ ├── Previous control
17
+ ├── page Link(s)
18
+ ├── ellipsis (optional, non-interactive)
19
+ ├── Next control
20
+ └── result summary (optional)
21
+ ```
22
+
23
+ Use Link for URL-addressable pages and Button only for a client-side dataset
24
+ whose URL intentionally does not change. Apply `--color-primary`,
25
+ `--color-foreground`, `--color-border`, `--color-disabled`, and
26
+ `--color-focus`, `--spacing-xs` between controls, `--spacing-sm` block and
27
+ inline control padding, and the five property-qualified label typography
28
+ tokens.
29
+
30
+ ## Variants
31
+
32
+ No visual variants. Pagination uses the numbered model shown above; optional
33
+ ellipsis and result summary are composition choices, not variants.
34
+
35
+ ## Sizes
36
+
37
+ One size. Page controls keep one consistent target and label treatment; use
38
+ semantic spacing rather than introducing `sm` or `lg` pagination.
39
+
40
+ ## States
41
+
42
+ | State | Behavior |
43
+ | --- | --- |
44
+ | default | Page destinations and previous/next are available. |
45
+ | hover | Interactive page control owns hover feedback. |
46
+ | focus | Focused control shows `--color-focus`. |
47
+ | active | Current page has `aria-current="page"`; activation loads the target page. |
48
+ | disabled | Previous/next at a boundary is unavailable and uses `--color-disabled`; page Links are never disabled. |
49
+ | loading | Keep position visible, mark the results region `aria-busy="true"`, and prevent duplicate requests without erasing controls. |
50
+
51
+ ## Accessibility
52
+
53
+ Use `<nav aria-label="Pagination">`. Give controls names such as “Go to page
54
+ 4”, “Previous page”, and “Next page”; the visible numeral alone is not enough.
55
+ Ellipses are not focusable. After a page change, move focus to the results
56
+ heading or announce the updated range in a polite live region. Native Link or
57
+ Button keyboard behavior applies.
58
+
59
+ ## Step indicator variant
60
+
61
+ Pagination supports a step indicator variant for a bounded, sequential flow,
62
+ as required by user story 17 in
63
+ [epic #3](https://github.com/momoi-labs/blueprint/issues/3). This variant reuses
64
+ Pagination's ordered navigation shape and tokens, but steps are workflow
65
+ states, not dataset pages. It does not add a separate multi-step pattern.
66
+
67
+ ### Semantics and anatomy
68
+
69
+ ```
70
+ Step indicator navigation
71
+ └── ordered list
72
+ └── step (one or more)
73
+ ├── position or status marker
74
+ ├── label
75
+ └── supporting text (optional)
76
+ ```
77
+
78
+ Keep every step visible so the person can understand their position and the
79
+ remaining work. Use concise task labels rather than page numbers alone. The
80
+ indicator communicates progress; Button controls such as “Back” and
81
+ “Continue” perform the workflow actions and remain outside it.
82
+
83
+ ### States
84
+
85
+ | State | Behavior |
86
+ | --- | --- |
87
+ | upcoming | Identifies work not yet reached. It is non-interactive unless the flow explicitly allows skipping ahead. |
88
+ | current | Identifies the active step with `aria-current="step"`; only one step is current. |
89
+ | completed | Identifies a successfully completed step. It may be interactive when revisiting completed work is safe. |
90
+ | error | Identifies a visited step that needs attention without relying on color alone. |
91
+ | disabled | An unavailable step remains legible but cannot be activated; prefer non-interactive text over a disabled Link. |
92
+
93
+ Do not infer completion from the current position: a person may return to a
94
+ completed step, and a visited step may contain an error. Pair icons and colors
95
+ with text or accessible names such as “Completed: Account details”.
96
+
97
+ ### Accessibility and keyboard behavior
98
+
99
+ Wrap the ordered list in `<nav aria-label="Form progress">` and expose the
100
+ current item with `aria-current="step"`. Include the step position in its
101
+ accessible name when it is useful, for example “Step 2 of 4: Permissions,
102
+ current step”. Decorative connectors and status icons are hidden from
103
+ assistive technology.
104
+
105
+ Render navigable steps as native Links when each step has a URL, or Buttons
106
+ when navigation is intentionally client-side. `Tab` moves through only those
107
+ interactive steps; `Enter` activates a Link, and `Enter` or `Space` activates
108
+ a Button. Non-interactive current, upcoming, and disabled steps do not enter
109
+ the tab order. Do not add arrow-key behavior unless the indicator is built
110
+ from another component whose documented semantics require it. After a step
111
+ change, move focus to the new step's heading and announce validation errors
112
+ before blocking “Continue”.
113
+
114
+ ## When to use
115
+
116
+ - A known dataset where people benefit from page position or direct jumps.
117
+ - Table/DataTable results that are expensive or impractical to load at once.
118
+ - A bounded multi-step flow where people benefit from seeing their progress.
119
+
120
+ ## When NOT to use
121
+
122
+ - An unbounded activity stream; use incremental loading.
123
+ - A small dataset that fits comfortably on one page.
124
+ - To hide missing Search or filtering.
125
+
126
+ ## Radix/shadcn mapping
127
+
128
+ No Radix Pagination primitive. Use shadcn Pagination as a structural reference
129
+ with native Links and Kiso tokens; do not copy utility colors or raw sizes.
@@ -0,0 +1,74 @@
1
+ # Popover
2
+
3
+ An anchored overlay for rich contextual content, including interactive
4
+ controls.
5
+
6
+ ## Purpose
7
+
8
+ Popover adds context or a small task beside its trigger without blocking the
9
+ whole page. Unlike [Tooltip](tooltip.md), it may contain Buttons, Links, or
10
+ inputs and can hold more than a short hint.
11
+
12
+ ## Anatomy
13
+
14
+ ```
15
+ Popover
16
+ ├── Trigger
17
+ └── Content
18
+ ├── heading/label (when needed)
19
+ ├── contextual content or controls
20
+ └── Arrow (optional)
21
+ ```
22
+
23
+ Content uses `--color-elevated-surface`, `--color-foreground`,
24
+ `--color-border`, `--radius-md`, `--spacing-md` padding, and `--shadow-md`.
25
+ Placement offset uses `--spacing-xs`, collision padding uses `--spacing-md`,
26
+ and motion uses `--motion-duration-fast` with `--motion-easing-standard`.
27
+
28
+ ## Variants
29
+
30
+ No visual variants. Side, alignment, collision flipping, and an optional Arrow
31
+ are placement/composition options, not separate Popover variants.
32
+
33
+ ## Sizes
34
+
35
+ One content-sized treatment with a readable maximum width. Do not add named
36
+ sizes; content that needs substantially more room belongs in Dialog or Drawer.
37
+
38
+ ## States
39
+
40
+ | State | Behavior |
41
+ | --- | --- |
42
+ | closed (default) | Content is absent and trigger has `aria-expanded="false"`. |
43
+ | hover | Trigger owns hover; hover alone does not open interactive content. |
44
+ | focus | Trigger/children show `--color-focus`; opening may move focus to content when the task requires it. |
45
+ | active/open | Trigger has `aria-expanded="true"`; Content flips or shifts on collision. |
46
+ | disabled | Disabled trigger does not open. |
47
+ | loading/error | Represent these inside Content with the relevant component; keep the Popover stable. |
48
+
49
+ ## Accessibility
50
+
51
+ The trigger is a Button or other appropriate control with `aria-expanded` and
52
+ an accessible name. `Enter`/`Space` opens; `Escape` closes and returns focus to
53
+ the trigger. `Tab` moves through interactive content and then onward; Popover
54
+ does not trap focus like a Dialog. Close on outside interaction only when doing
55
+ so cannot lose unsaved work. Supply a heading/label when Content needs one.
56
+
57
+ ## When to use
58
+
59
+ - Contextual details, filters, compact forms, or rich previews anchored to a
60
+ control.
61
+ - Content with interactive elements that cannot live in Tooltip.
62
+
63
+ ## When NOT to use
64
+
65
+ - A short, non-essential text hint; use Tooltip.
66
+ - A blocking decision or focus trap; use Modal/Dialog.
67
+ - A list of actions only; use DropdownMenu.
68
+ - Essential information that disappears without a clear way to reopen it.
69
+
70
+ ## Radix/shadcn mapping
71
+
72
+ Maps to Radix Popover / shadcn Popover (`Root`, `Trigger`, `Portal`, `Content`,
73
+ optional `Arrow`). Radix collision and focus behavior are the behavioral
74
+ reference; restyle with Kiso tokens.
@@ -0,0 +1,147 @@
1
+ # Search
2
+
3
+ A standalone field that filters or finds within a visible collection. It does
4
+ not navigate the app or run global commands.
5
+
6
+ ## Purpose
7
+
8
+ Search narrows what the person already has in view — rows in a
9
+ [Table / DataTable](table.md), items in a list, entries in a panel. The
10
+ collection owns the data; Search only supplies the query string (and optional
11
+ clear).
12
+
13
+ User stories #9 and #19.
14
+
15
+ ### Choose the right finder
16
+
17
+ | Need | Control | Why |
18
+ | --- | --- | --- |
19
+ | Filter visible / listed content | **Search** | Query stays scoped to this collection. |
20
+ | Global actions, jump-to, command runner | **[CommandPalette](command-palette.md)** | App-wide; keyboard-first command UI. |
21
+ | Single-line form value that happens to be a query stored as data | [Input](input.md) `type="search"` inside FormField | Persisted field, not live filtering chrome. |
22
+ | One value from a known set | [Select](select.md) | Not free-text filter. |
23
+
24
+ Search composes *with* lists and tables; it is **not** built into them
25
+ (user story #9).
26
+
27
+ ## Anatomy
28
+
29
+ ```
30
+ Search
31
+ ├── leading icon (optional; decorative magnifying glass)
32
+ ├── Input (type="search"; required)
33
+ ├── Clear (optional IconButton; visible when value non-empty)
34
+ └── Spinner (optional; while results are resolving)
35
+ ```
36
+
37
+ Label is usually visually hidden but programmatically present ("Filter
38
+ replicas", "Search queries") — either a `<label>` or `aria-label` on the
39
+ input. Do not rely on placeholder alone as the name.
40
+
41
+ HelperText / [ValidationMessage](validation-message.md) are uncommon for
42
+ live filters; if the query can be invalid (regex mode, etc.), wrap with
43
+ FormField patterns.
44
+
45
+ ## Variants
46
+
47
+ | Variant | Behavior |
48
+ | --- | --- |
49
+ | `instant` (default) | Filters as the person types (debounced). Good for client-side or fast indexes. |
50
+ | `submit` | Applies on Enter or an explicit "Search" Button. Good for expensive server queries. |
51
+
52
+ Appearance follows Input: `--color-surface`, `--color-border`,
53
+ `--color-foreground`, placeholder `--color-subtle-foreground`. Leading icon
54
+ `--color-muted-foreground`.
55
+
56
+ Do not add a "global" variant — that is CommandPalette.
57
+
58
+ ## Sizes
59
+
60
+ Align with [Input](input.md):
61
+
62
+ | Size | Use |
63
+ | --- | --- |
64
+ | `sm` | Table toolbars, dense chrome. |
65
+ | `md` (default) | Most collection filters. |
66
+ | `lg` | Rare; full-page find entry points. |
67
+
68
+ Width is a layout concern (toolbar flex): prefer filling the filter slot,
69
+ not a fixed pixel width.
70
+
71
+ ## States
72
+
73
+ | State | Behavior | Tokens / notes |
74
+ | --- | --- | --- |
75
+ | default | Empty or valued; ready to type. | Input default tokens. |
76
+ | hover | Quiet border emphasis; no layout shift. | |
77
+ | focus | Visible `--color-focus` ring on the input. | |
78
+ | active | Native caret / selection. | |
79
+ | disabled | Native `disabled`; not focusable. | `--color-disabled`. |
80
+ | loading | Value remains; show Spinner; `aria-busy` on the search region or input when results are in flight. Do not clear the query. | Distinct from disabled. |
81
+ | error | Rare. `aria-invalid` + [ValidationMessage](validation-message.md) only when the query syntax itself is invalid — not when there are zero hits. | Zero hits → collection [EmptyState](empty-state.md) `no-results`, not Search error. |
82
+
83
+ Clear control: [IconButton](icon-button.md) `ghost` `sm`, `aria-label`
84
+ "Clear search". After clear, keep focus in the input and refresh results.
85
+
86
+ ## Accessibility
87
+
88
+ - Accessible name always present (`label` / `aria-label` / `aria-labelledby`).
89
+ Placeholder is not the name.
90
+ - Use native `type="search"` so platform clear and semantics work where
91
+ available; if a custom Clear is used, keep it named and keyboard reachable.
92
+ - Debounced instant search should update results without trapping focus.
93
+ When results update, prefer updating the collection region; use a polite
94
+ status only when the change would otherwise be silent ("12 replicas").
95
+ - Do not move focus into the table on every keystroke.
96
+ - Submit variant: Enter submits; a visible Button must also exist if Enter
97
+ is not obvious in context.
98
+
99
+ ### Keyboard
100
+
101
+ | Key | Action |
102
+ | --- | --- |
103
+ | Printable keys | Edit the query. |
104
+ | `Enter` | `submit` variant: apply query. `instant`: may force an immediate apply (flush debounce); do not navigate away. |
105
+ | `Escape` | Optional: clear the query if non-empty, or leave unchanged — pick one per surface and keep it consistent. Does not open CommandPalette. |
106
+ | `Tab` / `Shift+Tab` | Move to Clear (if present) and the rest of the page. |
107
+
108
+ `⌘K` / `Ctrl+K` is **not** Search's shortcut — that belongs to
109
+ [CommandPalette](command-palette.md) unless the product explicitly documents
110
+ a different global binding.
111
+
112
+ ## When to use
113
+
114
+ - Filtering rows in a Table/DataTable toolbar.
115
+ - Filtering a list or catalog panel.
116
+ - Any "narrow what I see here" affordance (user stories #9, #19).
117
+
118
+ ## When NOT to use
119
+
120
+ - **Global jump / run command.** CommandPalette.
121
+ - **Contextual actions on one element.** [DropdownMenu](dropdown-menu.md).
122
+ - **Choosing one known option.** Select.
123
+ - **Storing a search string as form data** without live filtering — Input in
124
+ FormField may be enough; do not force Search chrome.
125
+ - **Replacing empty or error states.** EmptyState / Alert on the collection.
126
+
127
+ ## Tokens
128
+
129
+ Same semantic set as Input: `--color-surface`, `--color-foreground`,
130
+ `--color-subtle-foreground`, `--color-muted-foreground`, `--color-border`,
131
+ `--color-focus`, `--color-disabled`, `--spacing-sm` block and `--spacing-md`
132
+ inline padding, `--radius-md`, the five property-qualified body typography
133
+ tokens, `--motion-duration-fast`, and `--motion-easing-standard`.
134
+ Spinner and IconButton bring their own tokens. No raw hex/px.
135
+
136
+ ## Radix/shadcn mapping
137
+
138
+ No Radix Search primitive.
139
+
140
+ | Kiso | Reference |
141
+ | --- | --- |
142
+ | Field | Native `input type="search"` styled like shadcn [Input](https://ui.shadcn.com/docs/components/input) |
143
+ | Clear / icon chrome | Compose Kiso IconButton + decorative icon; shadcn Input with icon examples as layout reference only |
144
+ | In toolbars | shadcn Data Table toolbar filter input → restyle to Kiso tokens |
145
+
146
+ Do **not** map Search to shadcn [Command](https://ui.shadcn.com/docs/components/command)
147
+ or cmdk. That reference is [CommandPalette](command-palette.md).
@@ -0,0 +1,105 @@
1
+ # Select
2
+
3
+ ## Purpose
4
+
5
+ Select lets a person choose exactly one value from a predefined set. It hides
6
+ the option list until opened, so use it when showing every option at once would
7
+ create unnecessary noise.
8
+
9
+ ## Anatomy
10
+
11
+ 1. **Trigger** — displays the selected value or placeholder and opens the list.
12
+ 2. **Value** — current selection.
13
+ 3. **Icon** — indicates that the list can open; decorative when the trigger is
14
+ already named.
15
+ 4. **Content** — elevated option surface positioned relative to the trigger.
16
+ 5. **Viewport** — scrollable option container.
17
+ 6. **Item** — one selectable value, with optional selection indicator.
18
+ 7. **Group and group label (optional)** — organizes a long, meaningful set.
19
+ 8. **Scroll controls (optional)** — reveal overflow without replacing ordinary
20
+ scrolling.
21
+
22
+ ## Variants
23
+
24
+ - **Default** — flat list of mutually exclusive options.
25
+ - **Grouped** — labeled groups where categories help scanning.
26
+ - **Required** — placeholder is not a valid submitted value.
27
+ - **Disabled options** — exceptional choices that are visible but unavailable;
28
+ prefer omitting irrelevant options when their absence is not confusing.
29
+
30
+ Select is not Switch or Checkbox: Select chooses one value from many; Switch
31
+ changes one immediate on/off setting; Checkbox represents an independent
32
+ boolean or membership in a multi-select set.
33
+
34
+ ## Sizes
35
+
36
+ - **Small** — dense toolbars and compact forms.
37
+ - **Medium** — default.
38
+ - **Large** — rare, high-emphasis selection.
39
+
40
+ Trigger sizes align with Input sizes. Content width is at least sufficient for
41
+ its items and may match the trigger. Use spacing and size tokens, not raw values.
42
+
43
+ ## States
44
+
45
+ | State | Behavior |
46
+ | --- | --- |
47
+ | Default | Closed trigger shows selection or placeholder. |
48
+ | Hover | Trigger and enabled item show a quiet interactive emphasis. |
49
+ | Focus | Trigger or focused item has a visible `--color-focus` indicator. |
50
+ | Active/open | Trigger exposes `data-state="open"`; content is visible and the current keyboard item is distinct from the selected item. |
51
+ | Disabled | Trigger cannot open; disabled items cannot be selected. Uses `--color-disabled`. |
52
+ | Loading | Trigger remains stable, shows Spinner/status, and does not present stale options as ready. |
53
+ | Error | Trigger uses `aria-invalid="true"`, danger treatment, and linked ValidationMessage. |
54
+
55
+ Loading is not disabled. Loading says options are being resolved; disabled says
56
+ selection is unavailable. If loading prevents opening, announce why and retain
57
+ the current value.
58
+
59
+ ## Accessibility
60
+
61
+ - Associate the trigger with Label through `for`/`id` where the implementation
62
+ supports it, or an equivalent `aria-labelledby` relationship without
63
+ duplicating the accessible name.
64
+ - The Radix implementation supplies button/listbox semantics, active descendant
65
+ management, portalling, and typeahead. Preserve them.
66
+ - Link HelperText and ValidationMessage via `aria-describedby`; expose invalid,
67
+ required, disabled, and busy states programmatically.
68
+ - Keyboard: `Enter`, `Space`, or supported arrow keys open; arrows move through
69
+ options; typeahead searches; `Enter`/`Space` selects; `Escape` closes and
70
+ returns focus; `Home`/`End` move to bounds where supported.
71
+ - Focus returns to the trigger after selection or dismissal. Selection is not
72
+ committed merely by moving focus through items.
73
+
74
+ ## When to use
75
+
76
+ - For one choice from a known set where a collapsed list saves meaningful space.
77
+ - When options are short, comparable labels.
78
+ - When Radix Select's custom presentation is needed consistently across themes.
79
+
80
+ ## When NOT to use
81
+
82
+ - Do not use for multiple choices; use Checkbox controls or a dedicated
83
+ multi-select pattern.
84
+ - Do not use for one boolean setting; use Switch.
85
+ - Do not hide two or three important options when visible choices would be
86
+ faster to compare.
87
+ - Do not use as autocomplete for a very large or remote dataset without a
88
+ dedicated combobox/search pattern.
89
+
90
+ ## Tokens
91
+
92
+ Trigger uses the Input token mapping. Content uses `--color-elevated-surface`,
93
+ `--color-foreground`, `--color-border`, `--shadow-sm`, and `--radius-md`;
94
+ focused/selected items use `--color-accent` or `--color-primary` according to
95
+ hierarchy, focus uses `--color-focus`, and error uses `--color-danger`. List
96
+ padding uses `--spacing-xs`, item padding uses `--spacing-sm` block and
97
+ `--spacing-md` inline, and transitions use `--motion-duration-fast` with
98
+ `--motion-easing-standard`.
99
+
100
+ ## Radix/shadcn mapping
101
+
102
+ Maps to [Radix Select](https://www.radix-ui.com/primitives/docs/components/select)
103
+ and [shadcn/ui Select](https://ui.shadcn.com/docs/components/select). Keep the
104
+ Radix parts and behavior as the reference contract; shadcn supplies the common
105
+ composition and styling baseline.