@momoi-labs/kiso 0.10.0 → 0.12.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.
- package/kiso/docs/components/README.md +7 -0
- package/kiso/docs/components/accent-selector.md +136 -0
- package/kiso/docs/components/card.md +11 -5
- package/kiso/docs/components/drawer.md +1 -1
- package/kiso/docs/components/form-actions.md +145 -0
- package/kiso/docs/components/form-field.md +3 -0
- package/kiso/docs/components/form.md +102 -0
- package/kiso/docs/components/modal-dialog.md +1 -1
- package/kiso/docs/components/step-bar.md +57 -0
- package/kiso/docs/components/step-list.md +86 -0
- package/kiso/docs/components/theme-selector.md +4 -2
- package/kiso/docs/components/time-range-control.md +6 -0
- package/kiso/docs/evolution.md +2 -1
- package/kiso/docs/patterns/crud.md +15 -2
- package/kiso/docs/patterns/settings.md +21 -2
- package/kiso/docs/tokens.md +100 -9
- package/kiso/ui.css +244 -39
- package/package.json +1 -1
- package/tokens/build/tokens.css +179 -16
- package/tokens/build/tokens.d.ts +184 -23
- package/tokens/build/tokens.json +160 -12
- package/tokens/build/tokens.scss +161 -13
|
@@ -12,6 +12,8 @@ behavioral reference where one exists.
|
|
|
12
12
|
- [Card](card.md): Groups related content and actions with visual separation.
|
|
13
13
|
- [Checkbox](checkbox.md): Toggles an option in a list or selects multiple values.
|
|
14
14
|
- [ChipInput](chip-input.md): Collects several structured values in one field, each with its own options.
|
|
15
|
+
- [Form](form.md): Composes fields and explicit submission actions in a native form.
|
|
16
|
+
- [FormActions](form-actions.md): Groups form actions and optional feedback, with inline or sticky placement.
|
|
15
17
|
- [FormField](form-field.md): Composes Label, a form control, HelperText, and ValidationMessage with consistent ID and ARIA wiring.
|
|
16
18
|
- [HelperText](helper-text.md): Provides persistent, non-error context for a form control.
|
|
17
19
|
- [IconButton](icon-button.md): Triggers a compact icon-only action with a required accessible name.
|
|
@@ -24,6 +26,7 @@ behavioral reference where one exists.
|
|
|
24
26
|
- [Switch](switch.md): Changes one immediately applied boolean setting.
|
|
25
27
|
- [Textarea](textarea.md): Collects multi-line free-form text.
|
|
26
28
|
- [ThemeSelector](theme-selector.md): Chooses between following the system colour scheme, forcing light, or forcing dark.
|
|
29
|
+
- [AccentSelector](accent-selector.md): Chooses which accent the interface uses: violet, terracotta, teal, cobalt, or nocturne.
|
|
27
30
|
- [Tooltip](tooltip.md): Adds nonessential pointer or keyboard context as progressive enhancement.
|
|
28
31
|
- [ValidationMessage](validation-message.md): Explains a field-level validation error and how to fix it.
|
|
29
32
|
|
|
@@ -43,6 +46,8 @@ behavioral reference where one exists.
|
|
|
43
46
|
- [Search](search.md): Filters visible content such as a list or table.
|
|
44
47
|
- [Sparkline](sparkline.md): Draws the shape of one metric series at cell size.
|
|
45
48
|
- [Stat](stat.md): Presents a named metric with optional change and context.
|
|
49
|
+
- [StepBar](step-bar.md): Summarises a run as one segment per step, coloured by state.
|
|
50
|
+
- [StepList](step-list.md): Lists a run's steps with a state, a label, a timing, and an output.
|
|
46
51
|
- [Table / DataTable](table.md): Presents structured records with optional sorting, selection, filtering, and pagination.
|
|
47
52
|
|
|
48
53
|
## Navigation and structure
|
|
@@ -72,6 +77,8 @@ behavioral reference where one exists.
|
|
|
72
77
|
|
|
73
78
|
## Required compositions
|
|
74
79
|
|
|
80
|
+
- [Form](form.md) with explicit submission includes fields and [FormActions](form-actions.md).
|
|
81
|
+
|
|
75
82
|
- [FormField](form-field.md) composes [Label](label.md) + [Input](input.md) (or another form control) + [HelperText](helper-text.md) + [ValidationMessage](validation-message.md).
|
|
76
83
|
- [ApplicationShell](app-shell.md) composes [Sidebar](sidebar.md) + [Navigation](navigation.md) + [Header](header.md) + page content, or a top-bar-only frame with brand in [Header](header.md).
|
|
77
84
|
- [Header](header.md) composes [Link](link.md) + [IconButton](icon-button.md) + optional [DropdownMenu](dropdown-menu.md).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# AccentSelector
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
AccentSelector chooses which accent the interface uses: violet, terracotta,
|
|
6
|
+
teal, cobalt, or nocturne. It is the only sanctioned control for that choice. The theme
|
|
7
|
+
(light, dark, system) is a separate axis with its own control,
|
|
8
|
+
[ThemeSelector](theme-selector.md); the two compose.
|
|
9
|
+
|
|
10
|
+
## The five values
|
|
11
|
+
|
|
12
|
+
| Value | Meaning | `data-accent` on `<html>` |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| `violet` (default) | The violet ink and fill on the warm neutrals. | Either no attribute or `data-accent="violet"`. |
|
|
15
|
+
| `terracotta` | Same roles, hue turned to terracotta. Neutrals unchanged. | `data-accent="terracotta"` |
|
|
16
|
+
| `teal` | Same roles, hue turned to teal. Neutrals unchanged. | `data-accent="teal"` |
|
|
17
|
+
| `cobalt` | Same roles, hue turned to cobalt. Neutrals unchanged. | `data-accent="cobalt"` |
|
|
18
|
+
| `nocturne` | The marketing site's palette: cool slate neutrals under the violet ink. | `data-accent="nocturne"` |
|
|
19
|
+
|
|
20
|
+
The attribute may also sit on a container, in which case only that subtree
|
|
21
|
+
takes the accent. A nested `data-accent="violet"` resets to the default. See
|
|
22
|
+
[Accents](../tokens.md#accents) for what the accent does and does not change.
|
|
23
|
+
|
|
24
|
+
An application that offers fewer accents passes the subset it supports; the
|
|
25
|
+
control does not have to show all five.
|
|
26
|
+
|
|
27
|
+
## Persistence
|
|
28
|
+
|
|
29
|
+
- An explicit choice persists under the key `kiso-accent`, with the value
|
|
30
|
+
`violet`, `terracotta`, `teal`, `cobalt`, or `nocturne`.
|
|
31
|
+
- Read the stored value in a blocking inline script in `<head>`, before first
|
|
32
|
+
paint, and apply it as `data-accent`. Anything later flashes.
|
|
33
|
+
- Storage may be unavailable. Wrap reads and writes so a failure degrades to
|
|
34
|
+
`violet` rather than throwing.
|
|
35
|
+
- An application with a fixed accent does not render the control at all; it
|
|
36
|
+
sets the attribute once, in the document.
|
|
37
|
+
|
|
38
|
+
## Anatomy
|
|
39
|
+
|
|
40
|
+
1. **Row label**: the word "Accent", on the left.
|
|
41
|
+
2. **Pills**: one per value, on the right, as a group. Each pill is a dot in
|
|
42
|
+
that accent's `primary` fill followed by the accent's name.
|
|
43
|
+
3. **Preview**: below the row, one panel that shows the *selected* accent
|
|
44
|
+
applied: a sidebar strip with a current-item marker, a heading, a link, a
|
|
45
|
+
primary and a secondary button, and a selected row.
|
|
46
|
+
|
|
47
|
+
| Value | Pill | Accessible name |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| `violet` | violet dot, "Violet" | "Violet" |
|
|
50
|
+
| `terracotta` | terracotta dot, "Terracotta" | "Terracotta" |
|
|
51
|
+
| `teal` | teal dot, "Teal" | "Teal" |
|
|
52
|
+
| `cobalt` | cobalt dot, "Cobalt" | "Cobalt" |
|
|
53
|
+
| `nocturne` | nocturne dot, "Nocturne" | "Nocturne" |
|
|
54
|
+
|
|
55
|
+
The pill names the accent, so no hover is needed to tell which is which. The
|
|
56
|
+
preview answers the choice: it is decorative and hidden from assistive
|
|
57
|
+
technology, because the names already carry the meaning. Each pill and the
|
|
58
|
+
preview carry their own `data-accent`, so their colours resolve under that
|
|
59
|
+
accent with no inline values.
|
|
60
|
+
|
|
61
|
+
The preview may be omitted where the row is inline chrome, such as a header
|
|
62
|
+
toolbar. In a settings card it is always present.
|
|
63
|
+
|
|
64
|
+
## Layout
|
|
65
|
+
|
|
66
|
+
A configuration row directly below the Theme row in the same card, with the
|
|
67
|
+
preview spanning the row's width beneath it. See
|
|
68
|
+
[Settings](../patterns/settings.md#theme).
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
Theme [ ▣ ][ ☀ ][ ☾ ]
|
|
72
|
+
Accent (● Violet)(● Terracotta)(● Teal)(● Cobalt)(● Nocturne)
|
|
73
|
+
┌──┬──────────────────────────────────┐
|
|
74
|
+
│ │ ▬▬▬▬▬▬ │
|
|
75
|
+
│▬ │ ▬▬▬ │
|
|
76
|
+
│ │ [primary] [secondary] │
|
|
77
|
+
│ │ ░░░░░░░░░░░░░░░░ selected │
|
|
78
|
+
└──┴──────────────────────────────────┘
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Narrower than 360px (a sidebar footer), the label stacks over the pills and
|
|
82
|
+
the pills form a two-column grid, so no name wraps mid-word.
|
|
83
|
+
|
|
84
|
+
## Tokens
|
|
85
|
+
|
|
86
|
+
Pill: height `--size-control-xs`, radius `--radius-full`, border
|
|
87
|
+
`--color-border`, fill `--color-card`, text `--color-muted-foreground` at
|
|
88
|
+
`--type-size-label`, dot `--spacing-md` square in `--color-primary`.
|
|
89
|
+
|
|
90
|
+
Selected pill: border `--color-primary`, fill `--color-accent-surface`, text
|
|
91
|
+
`--color-foreground` at `--type-weight-medium`. The pill is outlined and
|
|
92
|
+
tinted, not filled with `--color-primary`: the fill is already on the dot,
|
|
93
|
+
and a solid pill would compete with the page's actual primary action.
|
|
94
|
+
|
|
95
|
+
Preview: 120px tall, border `--color-border`, radius `--radius-lg`, canvas
|
|
96
|
+
`--color-background`, strip `--color-sidebar`, marker and link `--color-link`,
|
|
97
|
+
buttons `--color-primary` and `--color-card` with `--color-border-strong`,
|
|
98
|
+
row `--color-selected`. Transitions on `--motion-duration-fast` /
|
|
99
|
+
`--motion-easing-standard`.
|
|
100
|
+
|
|
101
|
+
## States
|
|
102
|
+
|
|
103
|
+
| State | Behavior |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| default | The offered options, exactly one selected; the preview shows it. |
|
|
106
|
+
| hover | Unselected pill takes `--color-accent-surface` and `--color-foreground`. |
|
|
107
|
+
| focus | Visible ring using `--color-ring`. Never remove it. |
|
|
108
|
+
| selected | Outlined and tinted pill as above, plus the accessible selected state. The preview repaints at once. |
|
|
109
|
+
| disabled | Not a state. The accent is always changeable where the control is shown. |
|
|
110
|
+
|
|
111
|
+
There is no loading state. The change is local and instant; do not wait on a
|
|
112
|
+
server round-trip to repaint, and do not show a Toast for it.
|
|
113
|
+
|
|
114
|
+
## Accessibility
|
|
115
|
+
|
|
116
|
+
- A group of mutually exclusive options with exactly one selected, each named
|
|
117
|
+
by its visible text.
|
|
118
|
+
- The preview is `aria-hidden`; it repeats what the pill already says.
|
|
119
|
+
- Announce the selection, not the resulting colours.
|
|
120
|
+
- Every accent passes the same [AA gate](../tokens.md#aa-gate) as the default,
|
|
121
|
+
so the control does not need to warn about contrast.
|
|
122
|
+
|
|
123
|
+
## When NOT to use
|
|
124
|
+
|
|
125
|
+
- A free colour picker. Kiso has five accents; a product colour that is not
|
|
126
|
+
one of them is a token proposal, not an option.
|
|
127
|
+
- A way to mark status or severity. Red, amber, and green are not accents for
|
|
128
|
+
that reason: a primary button in the danger hue reads as destructive.
|
|
129
|
+
- Per-user branding inside a single product. One accent per product, or per
|
|
130
|
+
product area, chosen by the product.
|
|
131
|
+
|
|
132
|
+
## Related
|
|
133
|
+
|
|
134
|
+
- [tokens](../tokens.md#accents): what an accent changes and how it is built.
|
|
135
|
+
- [ThemeSelector](theme-selector.md): the other appearance row.
|
|
136
|
+
- [Settings](../patterns/settings.md#theme): where the row lives.
|
|
@@ -69,7 +69,7 @@ it is a section with a heading, not a Card.
|
|
|
69
69
|
This is the shared panel contract. Card, [Table](table.md) wrapper,
|
|
70
70
|
[ModalDialog](modal-dialog.md), [Drawer](drawer.md),
|
|
71
71
|
[CommandPalette](command-palette.md), and code or log blocks are **panels**:
|
|
72
|
-
square (`--radius-surface`) with corner marks. Popover, DropdownMenu, Toast,
|
|
72
|
+
square (`--radius-surface`) with corner marks by default. Popover, DropdownMenu, Toast,
|
|
73
73
|
Alert, and Tooltip are transient chrome, not panels: they keep a small radius
|
|
74
74
|
and carry no marks.
|
|
75
75
|
|
|
@@ -91,11 +91,11 @@ accidental.
|
|
|
91
91
|
|
|
92
92
|
The gap is the mark. Close it and this is just a thicker border.
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
Applications can change panel borders, radii, mark shapes, and mark sizes
|
|
95
|
+
with the [appearance attributes](../tokens.md#appearance-attributes).
|
|
96
|
+
Without these attributes, panels keep the square frame and tick marks.
|
|
97
97
|
|
|
98
|
-
Draw
|
|
98
|
+
Draw default ticks on one pseudo-element inset by `calc(-1 * (var(--corner-mark-tick) +
|
|
99
99
|
var(--corner-mark-gap)))`, so no markup and no images are needed. If the panel
|
|
100
100
|
scrolls, move `overflow` to an inner element — the marks sit just outside the
|
|
101
101
|
frame and a scrolling wrapper clips them away.
|
|
@@ -188,3 +188,9 @@ No Radix Card primitive. Structure follows shadcn
|
|
|
188
188
|
|
|
189
189
|
Ignore shadcn's invitation to hard-code spacing utilities. Card spacing
|
|
190
190
|
consumes `--spacing-md`, `--spacing-lg`, or `--spacing-xl` only.
|
|
191
|
+
|
|
192
|
+
## Form submission
|
|
193
|
+
|
|
194
|
+
Use [FormActions](form-actions.md) for form submission controls and feedback.
|
|
195
|
+
It can replace CardFooter at the bottom of a form inside a Card. Do not nest
|
|
196
|
+
the two footers. CardFooter remains a general content-and-actions container.
|
|
@@ -27,7 +27,7 @@ Drawer Root
|
|
|
27
27
|
|
|
28
28
|
Content uses `--color-elevated-surface`, `--color-foreground`,
|
|
29
29
|
`--color-border`, `--spacing-lg` padding, `--radius-surface`, and
|
|
30
|
-
`--shadow-lg`. The scrim uses `--color-overlay`. Panels are square (`--radius-surface`) and carry corner marks. See
|
|
30
|
+
`--shadow-lg`. The scrim uses `--color-overlay`. Panels are square (`--radius-surface`) and carry corner marks by default. See
|
|
31
31
|
[Card](card.md#corner-marks) for the shared panel contract.
|
|
32
32
|
Entry/exit uses `--motion-duration-normal` and `--motion-easing-standard`, with
|
|
33
33
|
no travel under reduced motion.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# FormActions
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
FormActions gives an explicit-submit form one place for its primary action,
|
|
6
|
+
secondary actions, and optional feedback. It works for sign-in, creation,
|
|
7
|
+
editing, and applying choices. It does not assume that submission saves a record.
|
|
8
|
+
|
|
9
|
+
## Anatomy
|
|
10
|
+
|
|
11
|
+
1. An action region after the form content.
|
|
12
|
+
2. An optional visible message in a persistent status region.
|
|
13
|
+
3. An action group with one primary Button and any secondary actions.
|
|
14
|
+
|
|
15
|
+
The message comes before the buttons in DOM order. Buttons align to the end
|
|
16
|
+
of the region. The layout wraps when the available width cannot hold both
|
|
17
|
+
message and actions. Labels and messages can wrap without horizontal scrolling.
|
|
18
|
+
|
|
19
|
+
## React API
|
|
20
|
+
|
|
21
|
+
| Prop | Default | Meaning |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `children` | None | Consumer-provided Buttons or navigation Links. |
|
|
24
|
+
| `message` | None | React content rendered inside the status region. |
|
|
25
|
+
| `tone` | `neutral` | `neutral`, `warning`, or `danger` presentation. |
|
|
26
|
+
| `sticky` | `false` | Stick to the bottom of the nearest scrolling ancestor, within the form. |
|
|
27
|
+
| Native div props | None | Includes `className`, `style`, `ref`, and ARIA attributes. |
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
<FormActions
|
|
31
|
+
sticky
|
|
32
|
+
tone={error ? "danger" : dirty ? "warning" : "neutral"}
|
|
33
|
+
message={error || (dirty ? "Unsaved changes." : undefined)}
|
|
34
|
+
>
|
|
35
|
+
{dirty && <Button type="button" onClick={discard}>Discard changes</Button>}
|
|
36
|
+
<Button type="submit" variant="primary" disabled={saving || !dirty}>
|
|
37
|
+
{saving ? "Saving..." : "Save changes"}
|
|
38
|
+
</Button>
|
|
39
|
+
</FormActions>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Loading indicators and `aria-busy` belong on the submitting Button. The
|
|
43
|
+
consumer prevents duplicate submission and decides whether cancellation is safe.
|
|
44
|
+
No buttons, labels, dirty tracking, or network behavior are built in.
|
|
45
|
+
|
|
46
|
+
## Tones and messages
|
|
47
|
+
|
|
48
|
+
| Situation | Presentation |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Initial or create | Neutral; no message required. |
|
|
51
|
+
| Unsaved edits | Warning with a message identifying the unsaved changes. |
|
|
52
|
+
| Submitting | A short progress message and loading submit Button. |
|
|
53
|
+
| Submission failed | Danger with a recovery message; preserve entries. |
|
|
54
|
+
| Saved | Neutral confirmation when the form stays open; clear dirty state. |
|
|
55
|
+
|
|
56
|
+
Tone does not encode business state. A product decides what "saved, awaiting
|
|
57
|
+
application" means and supplies suitable copy. FormActions does not model
|
|
58
|
+
machines, deployments, or synchronization. Use text to communicate meaning;
|
|
59
|
+
color alone is insufficient. An icon and bold lead are optional.
|
|
60
|
+
|
|
61
|
+
A new record can show Cancel and Create without a message. Discard appears
|
|
62
|
+
only when there are edits to discard. Avoid an always-visible "Saved" caption
|
|
63
|
+
that remains unchanged after editing.
|
|
64
|
+
|
|
65
|
+
## Placement and scrolling
|
|
66
|
+
|
|
67
|
+
For page scrolling, put FormActions last inside Form and pass `sticky`.
|
|
68
|
+
Its bottom offset defaults to zero. When the page has outer padding, set
|
|
69
|
+
`inset-block-end` to the same spacing token so the floating actions respect
|
|
70
|
+
that inset. Cover the space below the floating bar with the page background,
|
|
71
|
+
including the container border, so scrolling fields do not show through the
|
|
72
|
+
outer padding. An offset alone does not create that visual separation.
|
|
73
|
+
When page scrolling moves a marked Card behind sticky actions, keep the top
|
|
74
|
+
marks on the Card and move both bottom corner marks to the sticky action edge.
|
|
75
|
+
Draw them above the inset cover so each corner retains its horizontal and
|
|
76
|
+
vertical tick. Do not leave
|
|
77
|
+
a second pair attached to the scrolling Card bottom.
|
|
78
|
+
For example, use `var(--spacing-xl)` for a page padded by
|
|
79
|
+
`--spacing-xl`, and match any responsive padding changes. The form must remain
|
|
80
|
+
in document flow: an ancestor with scrolling overflow changes the sticky
|
|
81
|
+
container.
|
|
82
|
+
|
|
83
|
+
For a bounded panel, put Form inside a height-constrained `form-scroll` region.
|
|
84
|
+
That region owns overflow and has no padding. Put padding on `form-body`
|
|
85
|
+
instead. Actions then span the container width without negative margins.
|
|
86
|
+
Form fills at least the panel height and pushes actions to its bottom.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
<TabsContent value="general" className="form-scroll" style={{ height: "28rem" }}>
|
|
90
|
+
<Form onSubmit={save}>
|
|
91
|
+
<div className="form-body">{/* FormFields */}</div>
|
|
92
|
+
<FormActions sticky>{/* Buttons */}</FormActions>
|
|
93
|
+
</Form>
|
|
94
|
+
</TabsContent>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Keep an outer Card's corner marks outside the scrolling region. Do not nest
|
|
98
|
+
FormActions inside CardFooter or DialogFooter; it provides its own border and
|
|
99
|
+
padding. CardFooter stays a general visual container without form status.
|
|
100
|
+
|
|
101
|
+
If an existing scroller must retain padding, the consumer must account for it:
|
|
102
|
+
set `style={{ insetBlockEnd: "calc(-1 * var(--spacing-lg))" }}` when the
|
|
103
|
+
scroller's bottom padding is `--spacing-lg`. Align the form with the horizontal
|
|
104
|
+
edges separately. Use lengths such as `0px` when supplying values to CSS math.
|
|
105
|
+
Prefer the unpadded composition above for new screens.
|
|
106
|
+
|
|
107
|
+
The background layers semantic tint over an opaque card surface. Scrolled
|
|
108
|
+
content must not show through the message or buttons. The bar stops at the
|
|
109
|
+
form's end; it is not fixed to the viewport across unrelated content.
|
|
110
|
+
|
|
111
|
+
## Accessibility
|
|
112
|
+
|
|
113
|
+
Only the message region has `role="status"` and `aria-atomic="true"`. Keep it
|
|
114
|
+
mounted when empty so updates can be announced. Do not put these attributes
|
|
115
|
+
on the entire action region, and do not put interactive controls in `message`.
|
|
116
|
+
|
|
117
|
+
Buttons retain their native semantics and tab order. The primary Button has
|
|
118
|
+
`type="submit"`; secondary Buttons have `type="button"`. Use a Link for an
|
|
119
|
+
actual navigation destination. Avoid duplicate announcements from an inline
|
|
120
|
+
message and a Toast for the same event.
|
|
121
|
+
|
|
122
|
+
Field validation stays beside its field. Keep form-level failures visible
|
|
123
|
+
until the person edits or retries. Verify sticky actions at narrow widths,
|
|
124
|
+
zoom, and keyboard focus. Shared scroll spacing reserves room for typical
|
|
125
|
+
wrapped actions; consumers must increase that space for unusually tall bars.
|
|
126
|
+
|
|
127
|
+
## Tokens
|
|
128
|
+
|
|
129
|
+
Spacing uses `--spacing-sm`, `--spacing-md`, and `--spacing-lg`. Scroll spacing
|
|
130
|
+
uses `--spacing-4xl`. Text uses `--type-size-label` and
|
|
131
|
+
`--type-weight-semibold`. The base uses `--color-card`,
|
|
132
|
+
`--color-card-foreground`, and `--color-border`. Warning uses
|
|
133
|
+
`--color-warning-surface` and `--color-warning-border`; danger uses
|
|
134
|
+
`--color-danger-surface` and `--color-danger-border`.
|
|
135
|
+
|
|
136
|
+
## When not to use
|
|
137
|
+
|
|
138
|
+
Do not add submission actions to immediate preferences or automatic filters.
|
|
139
|
+
Do not use this component for page-wide record actions unrelated to the form,
|
|
140
|
+
a generic Card footer, or a toolbar for selecting table rows.
|
|
141
|
+
|
|
142
|
+
## Radix/shadcn mapping
|
|
143
|
+
|
|
144
|
+
FormActions is a Kiso composition of native grouping, a status region, and
|
|
145
|
+
Buttons. It does not add a keyboard interaction model or a Radix dependency.
|
|
@@ -7,6 +7,9 @@ identification, entry, guidance, and field-level feedback so their visual and
|
|
|
7
7
|
accessible relationships remain intact. FormField is not a primitive and does
|
|
8
8
|
not replace the semantics of its children.
|
|
9
9
|
|
|
10
|
+
Use [Form](form.md) and [FormActions](form-actions.md) for the whole form and
|
|
11
|
+
its submission actions. FormField remains responsible for one control.
|
|
12
|
+
|
|
10
13
|
## Anatomy
|
|
11
14
|
|
|
12
15
|
The canonical composition is:
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Form
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Form composes fields and their submission actions in a native HTML form.
|
|
6
|
+
Every form with explicit submission includes [FormActions](form-actions.md).
|
|
7
|
+
The action can sign in, create, save, search, or apply a choice.
|
|
8
|
+
|
|
9
|
+
Immediate preferences and automatic filters do not need a submit action.
|
|
10
|
+
Use the existing Switch and search patterns for those interactions.
|
|
11
|
+
|
|
12
|
+
## Anatomy
|
|
13
|
+
|
|
14
|
+
1. A native `form`, optionally named by a heading with `aria-labelledby`.
|
|
15
|
+
2. A content region containing FormFields, sections, or fieldsets.
|
|
16
|
+
3. FormActions after the content, with one primary submit Button and any
|
|
17
|
+
secondary actions the task needs.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<Form onSubmit={handleSubmit} aria-labelledby="project-title">
|
|
21
|
+
<div className="form-body">
|
|
22
|
+
<h2 id="project-title">Create project</h2>
|
|
23
|
+
<FormField label="Project name" name="name" required />
|
|
24
|
+
</div>
|
|
25
|
+
<FormActions>
|
|
26
|
+
<Button type="submit" variant="primary">Create project</Button>
|
|
27
|
+
</FormActions>
|
|
28
|
+
</Form>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The `form-body` CSS class provides content padding and field spacing. It can
|
|
32
|
+
be applied to a div or fieldset. Products can instead compose content from
|
|
33
|
+
Cards and existing layout utilities. Form adds no padding around its actions.
|
|
34
|
+
Do not wrap FormActions in a padded content region or another footer.
|
|
35
|
+
|
|
36
|
+
## React API
|
|
37
|
+
|
|
38
|
+
Form accepts native form props, including `action`, `method`, `onSubmit`,
|
|
39
|
+
`id`, `ref`, and ARIA attributes. It forwards them to the form element and
|
|
40
|
+
merges `className` with `form`.
|
|
41
|
+
|
|
42
|
+
Form does not create buttons, enforce its children at runtime, intercept
|
|
43
|
+
submission, select a validation library, or track values and dirty state.
|
|
44
|
+
The application owns those behaviors. Explicit-submit forms must follow the
|
|
45
|
+
composition contract even though the React component accepts arbitrary content.
|
|
46
|
+
|
|
47
|
+
## Layouts
|
|
48
|
+
|
|
49
|
+
- Short forms keep FormActions in normal flow.
|
|
50
|
+
- Long forms use sticky FormActions on a page or inside a scrolling panel.
|
|
51
|
+
- A form in a bounded panel fills at least the panel height, so actions also
|
|
52
|
+
reach the panel bottom when content is short.
|
|
53
|
+
- A form can contain multiple Cards. A Card is not required for Form.
|
|
54
|
+
- In Dialog, compose DialogHeader and a Form containing its fields and
|
|
55
|
+
FormActions. Use `form-scroll` on the form when the dialog constrains its
|
|
56
|
+
height. Keep the dialog's existing focus and dismissal behavior.
|
|
57
|
+
|
|
58
|
+
See [FormActions](form-actions.md) for scroll ownership, padded containers,
|
|
59
|
+
responsive actions, and status announcements.
|
|
60
|
+
|
|
61
|
+
## States and ownership
|
|
62
|
+
|
|
63
|
+
| State | Application behavior |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| Initial | Provide fields and an explicit submit action; a status message is optional. |
|
|
66
|
+
| Dirty | Compare current values with the last saved values. Show feedback and Discard when useful. |
|
|
67
|
+
| Invalid | Preserve entries, show field errors, and focus the first invalid field. |
|
|
68
|
+
| Submitting | Show loading on the submit Button and prevent duplicate requests. |
|
|
69
|
+
| Failed | Keep entries and show a recoverable message. Use field errors for field failures. |
|
|
70
|
+
| Saved | Update the saved baseline and clear dirty state. Confirm inline or navigate as appropriate. |
|
|
71
|
+
|
|
72
|
+
Discard restores the saved baseline. Native reset restores initial defaults,
|
|
73
|
+
which may differ after a successful save. Cancel leaves the task; it does not
|
|
74
|
+
necessarily mean Discard. The application handles navigation and any warning
|
|
75
|
+
needed before losing material edits.
|
|
76
|
+
|
|
77
|
+
## Accessibility
|
|
78
|
+
|
|
79
|
+
Preserve native submit and validation behavior. Use `type="submit"` on the
|
|
80
|
+
primary Button and `type="button"` on other buttons. Never nest forms.
|
|
81
|
+
Group related controls with fieldset and legend when they share a question.
|
|
82
|
+
FormField continues to own label, help, and field-error associations.
|
|
83
|
+
|
|
84
|
+
DOM order is content followed by actions. Sticky placement must not obscure
|
|
85
|
+
focused controls or their errors; verify keyboard use and zoom in the actual
|
|
86
|
+
scroll container. Do not announce the whole form as a live region.
|
|
87
|
+
|
|
88
|
+
## Tokens
|
|
89
|
+
|
|
90
|
+
`form-body` uses `--spacing-lg` padding and `--spacing-xl` gaps. Form delegates
|
|
91
|
+
surfaces and borders to its container, and action styling to FormActions.
|
|
92
|
+
|
|
93
|
+
## Related contracts
|
|
94
|
+
|
|
95
|
+
- [FormField](form-field.md) for one labeled control.
|
|
96
|
+
- [FormActions](form-actions.md) for submission controls and feedback.
|
|
97
|
+
- [CRUD](../patterns/crud.md) and [Settings](../patterns/settings.md) for flows.
|
|
98
|
+
|
|
99
|
+
## Radix/shadcn mapping
|
|
100
|
+
|
|
101
|
+
Form uses native HTML semantics. It introduces no Radix primitive or form-state
|
|
102
|
+
library dependency.
|
|
@@ -26,7 +26,7 @@ Dialog Root
|
|
|
26
26
|
Content uses `--color-elevated-surface`, `--color-foreground`,
|
|
27
27
|
`--color-border`, `--radius-surface`, `--spacing-lg` padding, and
|
|
28
28
|
`--shadow-lg`. A Dialog is a panel: it carries corner marks. The scrim uses
|
|
29
|
-
`--color-overlay`. Panels are square (`--radius-surface`) and carry corner marks. See
|
|
29
|
+
`--color-overlay`. Panels are square (`--radius-surface`) and carry corner marks by default. See
|
|
30
30
|
[Card](card.md#corner-marks) for the shared panel contract.
|
|
31
31
|
Overlay transitions use `--motion-duration-normal` and
|
|
32
32
|
`--motion-easing-standard`.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# StepBar
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
StepBar summarises a run in one row: one segment per step, coloured by the
|
|
6
|
+
step's state. It answers "how far" and "where it stopped" at a glance, in the
|
|
7
|
+
places a [StepList](step-list.md) does not fit: a summary tab, a table cell,
|
|
8
|
+
a Toast. [Progress](meter.md) shows a continuous ratio; StepBar shows discrete
|
|
9
|
+
steps, so a failure is visible as a red segment in its place.
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
StepBar (role="img", named)
|
|
15
|
+
└── segment (repeated, one per step)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The bar is the whole component. The product places the count ("4 of 11"),
|
|
19
|
+
the current step's label, or the last output line beside it in its own
|
|
20
|
+
markup; StepBar does not render text.
|
|
21
|
+
|
|
22
|
+
## States
|
|
23
|
+
|
|
24
|
+
Segments take the same five states as StepList: pending in
|
|
25
|
+
`--color-secondary`, running and done in `--color-success`, skipped hatched in
|
|
26
|
+
`--color-success`, failed in `--color-danger`. A running segment may show a
|
|
27
|
+
partial fill from `progress` (0 to 1); without it, running fills fully.
|
|
28
|
+
|
|
29
|
+
## Sizes
|
|
30
|
+
|
|
31
|
+
One height, `--spacing-xs`. Width comes from the container. In a table cell,
|
|
32
|
+
give the cell a fixed width and keep the bar to one line beside the Badge;
|
|
33
|
+
do not add the ticker there. Hide the bar when the machine is not running and
|
|
34
|
+
has not failed; the Badge alone says "Stopped".
|
|
35
|
+
|
|
36
|
+
## Accessibility
|
|
37
|
+
|
|
38
|
+
`role="img"` with a name that says the count and the current step, such as
|
|
39
|
+
"Create: step 4 of 11, running System packages" or
|
|
40
|
+
"Create: failed at step 4 of 11, System packages". The segments are
|
|
41
|
+
decorative. Nothing depends on colour alone.
|
|
42
|
+
|
|
43
|
+
## Tokens and implementation
|
|
44
|
+
|
|
45
|
+
Segments use `--radius-xs` and a `--spacing-2xs` gap. The hatch for a skipped
|
|
46
|
+
segment reuses the existing hatch tokens. No Radix primitive.
|
|
47
|
+
|
|
48
|
+
## When to use
|
|
49
|
+
|
|
50
|
+
- A machine's summary tab or card while an action runs or after it fails.
|
|
51
|
+
- A machines table, one line per row, next to the status Badge.
|
|
52
|
+
- A progress Toast for a run started from another screen.
|
|
53
|
+
|
|
54
|
+
## When NOT to use
|
|
55
|
+
|
|
56
|
+
- The run's own page. Use StepList there; the bar would repeat it.
|
|
57
|
+
- A continuous measurement. Use Meter or Progress.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# StepList
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
StepList shows the steps of a run a machine walks through, one row per step,
|
|
6
|
+
with a state, a label, and a timing. While the run goes it is the progress;
|
|
7
|
+
afterwards it is the account of what happened. The reader does not walk the
|
|
8
|
+
steps; the machine does, and the reader reads how it went.
|
|
9
|
+
|
|
10
|
+
It is not the [Pagination](pagination.md) step indicator. That one shows a
|
|
11
|
+
person's position in a flow they drive. StepList has a state per step, a
|
|
12
|
+
timing, and an output the reader may open.
|
|
13
|
+
|
|
14
|
+
## Anatomy
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
StepList (ordered list, labelled)
|
|
18
|
+
└── Step (repeated)
|
|
19
|
+
├── rail: connector and mark, with a text alternative
|
|
20
|
+
├── label
|
|
21
|
+
├── meta (mono, muted)
|
|
22
|
+
└── detail (optional slot, below the row)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The rail is one vertical line through every mark. Each mark is a dot; the
|
|
26
|
+
connector above it takes the colour of the step's state, so the line fills as
|
|
27
|
+
the run advances and the list is itself the progress. Nothing else measures
|
|
28
|
+
completion: do not add a Progress track above a StepList.
|
|
29
|
+
|
|
30
|
+
Each row is a button when the list has `onSelect`; the product then shows the
|
|
31
|
+
selected step's output beside the list, usually in the second [Pane](split.md)
|
|
32
|
+
of a Split with a [LogView](log-view.md) filling it. On a narrow viewport,
|
|
33
|
+
where the Split cannot fit, pass the output as the selected step's `detail`
|
|
34
|
+
and it renders under the row.
|
|
35
|
+
|
|
36
|
+
## States
|
|
37
|
+
|
|
38
|
+
| State | Mark | Default meta |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| pending | empty dot, muted row | none; the product passes "Not run" after a failure |
|
|
41
|
+
| running | dot ringed in `--color-success`, pulsing, bold label | "Running" |
|
|
42
|
+
| done | filled `--color-success` dot | none; the product passes the duration |
|
|
43
|
+
| skipped | hollow `--color-success` dot, muted label | "Not needed" |
|
|
44
|
+
| failed | filled `--color-danger` dot, bold label in `--color-danger` | none; the product passes the duration |
|
|
45
|
+
|
|
46
|
+
The running step is `aria-current="step"`. Five states, not a status badge's
|
|
47
|
+
tones: running is alive, so it is the success colour; neutral is what is not
|
|
48
|
+
happening; danger is what stopped the run.
|
|
49
|
+
|
|
50
|
+
The product owns which step is selected. Follow the running step by default,
|
|
51
|
+
keep a step the reader chose, and offer a way back to the current one.
|
|
52
|
+
|
|
53
|
+
## Accessibility
|
|
54
|
+
|
|
55
|
+
An `ol` with an accessible name, one `li` per step. Each mark carries its
|
|
56
|
+
state as text (`role="img"` with the state as its name), so colour is never
|
|
57
|
+
the only signal. Rows that select are native buttons with `aria-pressed`;
|
|
58
|
+
rows that do not are plain text. The connector is decorative and hidden.
|
|
59
|
+
Under reduced motion the running mark does not pulse.
|
|
60
|
+
|
|
61
|
+
### Keyboard
|
|
62
|
+
|
|
63
|
+
No custom keymap. Tab reaches each selectable row; Enter or Space selects it.
|
|
64
|
+
|
|
65
|
+
## Tokens and implementation
|
|
66
|
+
|
|
67
|
+
Rail and marks use `--color-border-strong`, `--color-success`,
|
|
68
|
+
`--color-success-surface`, and `--color-danger`. Labels use
|
|
69
|
+
`--type-size-label`; the running and failed labels use
|
|
70
|
+
`--type-weight-semibold`. Meta uses `--font-mono`, `--type-size-label`, and
|
|
71
|
+
`--color-muted-foreground`. Rows are spaced with `--spacing-sm`; the rail
|
|
72
|
+
column is `--spacing-xl` wide, room for the running mark's glow. Focus uses `--color-focus`. No Radix
|
|
73
|
+
primitive is involved.
|
|
74
|
+
|
|
75
|
+
## When to use
|
|
76
|
+
|
|
77
|
+
- A lifecycle action on a machine: create, update, or a bootstrap with a
|
|
78
|
+
known list of stages.
|
|
79
|
+
- An image build or a collection whose phases are known before it starts.
|
|
80
|
+
|
|
81
|
+
## When NOT to use
|
|
82
|
+
|
|
83
|
+
- A flow the person walks through. Use Pagination's step indicator.
|
|
84
|
+
- A plan that is not known before it runs. Append rows as they happen, and
|
|
85
|
+
pair the list with an indeterminate Progress rather than a [StepBar](step-bar.md).
|
|
86
|
+
- A single indeterminate wait. Use Spinner.
|
|
@@ -104,11 +104,13 @@ server round-trip to repaint, and do not show a Toast for it.
|
|
|
104
104
|
which is the default and the most common choice.
|
|
105
105
|
- A theme entry buried inside a DropdownMenu as the only access point. A menu
|
|
106
106
|
may mirror the control, but the setting lives in a settings row.
|
|
107
|
-
- Any control that offers colour options beyond these three. Kiso has
|
|
108
|
-
themes.
|
|
107
|
+
- Any control that offers colour scheme options beyond these three. Kiso has
|
|
108
|
+
two themes. The accent is a separate axis with its own control,
|
|
109
|
+
[AccentSelector](accent-selector.md).
|
|
109
110
|
|
|
110
111
|
## Related
|
|
111
112
|
|
|
112
113
|
- [tokens](../tokens.md) — how `light-dark()` and `color-scheme` resolve.
|
|
113
114
|
- [Settings](../patterns/settings.md#theme) — where the row lives.
|
|
115
|
+
- [AccentSelector](accent-selector.md) — the other appearance row.
|
|
114
116
|
- [Switch](switch.md) — for actual booleans.
|
|
@@ -40,3 +40,9 @@ both full timestamps; visible dates appear when the interval crosses a day. Touc
|
|
|
40
40
|
Use existing Button, Input, and Popover tokens. Use `--spacing-xs` between
|
|
41
41
|
presets and `--spacing-md` between regions. The trigger wraps long ranges;
|
|
42
42
|
the popover fits the viewport. No new calendar, timezone, or date dependency.
|
|
43
|
+
|
|
44
|
+
## Custom range form
|
|
45
|
+
|
|
46
|
+
The custom range editor composes [Form](form.md) with
|
|
47
|
+
[FormActions](form-actions.md). Apply range is the explicit submit action;
|
|
48
|
+
validation stays next to the range fields. Presets still apply immediately.
|