@handamade/psi-react 0.13.1 → 0.14.2

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 (85) hide show
  1. package/README.md +5 -2
  2. package/dist/AspectRatio/AspectRatio.d.ts +3 -1
  3. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  4. package/dist/Button/Button.d.ts +3 -1
  5. package/dist/Button/Button.d.ts.map +1 -1
  6. package/dist/Card/Card.d.ts +2 -0
  7. package/dist/Card/Card.d.ts.map +1 -1
  8. package/dist/DescriptionList/DescriptionItem.d.ts +19 -0
  9. package/dist/DescriptionList/DescriptionItem.d.ts.map +1 -0
  10. package/dist/DescriptionList/DescriptionList.d.ts +19 -0
  11. package/dist/DescriptionList/DescriptionList.d.ts.map +1 -0
  12. package/dist/Dialog/Dialog.d.ts +2 -0
  13. package/dist/Dialog/Dialog.d.ts.map +1 -1
  14. package/dist/Field/Field.d.ts +2 -0
  15. package/dist/Field/Field.d.ts.map +1 -1
  16. package/dist/IconButton/IconButton.d.ts +3 -1
  17. package/dist/IconButton/IconButton.d.ts.map +1 -1
  18. package/dist/Menu/Menu.d.ts +1 -0
  19. package/dist/Menu/Menu.d.ts.map +1 -1
  20. package/dist/Menu/MenuItem.d.ts +1 -0
  21. package/dist/Menu/MenuItem.d.ts.map +1 -1
  22. package/dist/Panel/Panel.d.ts +3 -1
  23. package/dist/Panel/Panel.d.ts.map +1 -1
  24. package/dist/Select/Select.d.ts +3 -1
  25. package/dist/Select/Select.d.ts.map +1 -1
  26. package/dist/Table/Table.d.ts +1 -0
  27. package/dist/Table/Table.d.ts.map +1 -1
  28. package/dist/Table/TableBody.d.ts +1 -0
  29. package/dist/Table/TableBody.d.ts.map +1 -1
  30. package/dist/Table/TableCell.d.ts +1 -0
  31. package/dist/Table/TableCell.d.ts.map +1 -1
  32. package/dist/Table/TableHead.d.ts +1 -0
  33. package/dist/Table/TableHead.d.ts.map +1 -1
  34. package/dist/Table/TableHeaderCell.d.ts +1 -0
  35. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  36. package/dist/Table/TableRow.d.ts +1 -0
  37. package/dist/Table/TableRow.d.ts.map +1 -1
  38. package/dist/Toolbar/Toolbar.d.ts +3 -1
  39. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  40. package/dist/icons/IconMoreHorizontal.d.ts +10 -0
  41. package/dist/icons/IconMoreHorizontal.d.ts.map +1 -0
  42. package/dist/icons/index.d.ts +1 -0
  43. package/dist/icons/index.d.ts.map +1 -1
  44. package/dist/index.d.ts +5 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +647 -605
  47. package/dist/manifest.json +207 -0
  48. package/dist/patterns.json +47 -10
  49. package/dist/styles.css +1 -1
  50. package/docs/AspectRatio.md +2 -0
  51. package/docs/Button.md +2 -0
  52. package/docs/Card.md +2 -0
  53. package/docs/Checkbox.md +1 -0
  54. package/docs/DescriptionItem.md +31 -0
  55. package/docs/DescriptionList.md +32 -0
  56. package/docs/Dialog.md +2 -0
  57. package/docs/Field.md +2 -0
  58. package/docs/IconButton.md +2 -0
  59. package/docs/Input.md +1 -0
  60. package/docs/Menu.md +2 -0
  61. package/docs/MenuItem.md +2 -0
  62. package/docs/MenuSeparator.md +1 -0
  63. package/docs/NavBar.md +1 -0
  64. package/docs/Pagination.md +1 -0
  65. package/docs/Panel.md +2 -0
  66. package/docs/Select.md +2 -0
  67. package/docs/Switch.md +1 -0
  68. package/docs/Tab.md +1 -0
  69. package/docs/TabList.md +1 -0
  70. package/docs/TabPanel.md +1 -0
  71. package/docs/Table.md +2 -0
  72. package/docs/TableBody.md +2 -0
  73. package/docs/TableCell.md +2 -0
  74. package/docs/TableHead.md +2 -0
  75. package/docs/TableHeaderCell.md +2 -0
  76. package/docs/TableRow.md +2 -0
  77. package/docs/Tabs.md +1 -0
  78. package/docs/Tag.md +1 -0
  79. package/docs/Toast.md +1 -0
  80. package/docs/ToastProvider.md +1 -0
  81. package/docs/ToastRegion.md +1 -0
  82. package/docs/Toolbar.md +2 -0
  83. package/docs/Tooltip.md +1 -0
  84. package/llms.txt +8 -3
  85. package/package.json +2 -2
@@ -0,0 +1,32 @@
1
+ <!-- Generated by emit-docs.ts — do not edit. -->
2
+ # DescriptionList
3
+
4
+ Key/value display (D70): a `<dl>` of term/value pairs, the body `detail-drawer` has always described and never had a component for. No `size` prop — this is type, and the type scale is already expressed by --psi-text-*. Consumers restyle via the token family, not a prop.
5
+
6
+ ## Props
7
+
8
+ | Prop | Type | Default | Required | Description |
9
+ |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | One DescriptionItem per field. |
11
+ | `layout` | `"stacked" \| "inline"` | stacked | no | `stacked` puts the term above its value; `inline` puts them in a two-column grid, which is what a detail drawer wants. |
12
+ | `gap` | `8 \| 12 \| 16` | 12 | no | Gap between pairs, in px. |
13
+ | `ref` | `Ref<HTMLDListElement>` | — | no | Forwarded ref to the root element. |
14
+ | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
15
+
16
+ ## Theming
17
+
18
+ Override `--psi-description-list-*` custom properties at any scope.
19
+
20
+
21
+
22
+ ## Rules
23
+
24
+ - One accent per visual group; everything else neutral or ghost.
25
+ - danger only for actions with real consequences.
26
+ - Sizes are px numbers (24|32|40|48), never S/M/L.
27
+ - Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
28
+ - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
29
+ - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
30
+ - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
31
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
32
+ - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Dialog.md CHANGED
@@ -7,6 +7,7 @@ Modal dialog on the native <dialog> top layer: focus trap, aria-modal and focus
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | Body content, between the title and footer slots. |
10
11
  | `open` | `boolean` | — | yes | Controlled open state; syncs to showModal()/close(). |
11
12
  | `onClose` | `(reason: "esc" \| "backdrop" \| "close-button") => void` | — | yes | Called on every dismissal attempt with its source; the consumer flips `open`. |
12
13
  | `title` | `ReactNode` | — | no | Heading; renders an <h2> wired to aria-labelledby. Without it, pass aria-label. |
@@ -41,4 +42,5 @@ Override `--psi-dialog-*` custom properties at any scope.
41
42
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
42
43
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
43
44
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
45
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
44
46
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Field.md CHANGED
@@ -7,6 +7,7 @@ Labeled form-row wrapper: label above, control, one message line below — descr
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | The control this field labels. |
10
11
  | `label` | `ReactNode` | — | no | Label content; renders a <label> (or <legend> in group mode). |
11
12
  | `description` | `ReactNode` | — | no | Helper line under the control; replaced by error when error is set. |
12
13
  | `error` | `ReactNode` | — | no | Error content; when truthy it replaces the description and switches the field (and a wrapped Input/Select) into error state. |
@@ -39,4 +40,5 @@ Override `--psi-field-*` custom properties at any scope.
39
40
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
40
41
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
41
42
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
43
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
42
44
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -7,6 +7,7 @@ Square icon-only button; same variant/size/href contract as Button. Give it an a
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | The icon element — an Icon* component. |
10
11
  | `aria-label` | `string` | — | yes | Accessible name for the icon-only control. Required: an IconButton has no text to name it, so omitting this ships an unnameable button (D60). If you also pass `aria-labelledby`, that wins per the accname algorithm. |
11
12
  | `variant` | `"accent" \| "neutral" \| "ghost" \| "danger"` | neutral | no | Visual variant. |
12
13
  | `size` | `24 \| 32 \| 40 \| 48` | 32 | no | Square size in px (24 \| 32 \| 40 \| 48). |
@@ -49,4 +50,5 @@ Override `--psi-button-*` custom properties at any scope; interactive states der
49
50
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
50
51
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
51
52
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
53
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
52
54
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Input.md CHANGED
@@ -37,4 +37,5 @@ Override `--psi-input-*` custom properties at any scope; interactive states deri
37
37
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
38
38
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
39
39
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
40
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
40
41
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Menu.md CHANGED
@@ -12,6 +12,7 @@ Action menu on the native Popover API top layer: the top layer and light dismiss
12
12
  | `trigger` | `ReactElement<Record<string, unknown>, string \| JSXElementConstructor<any>>` | — | yes | The trigger element. Must be a single React element that spreads unknown props onto a focusable node (a Psi `Button`, say): Menu clones it to add `aria-haspopup="menu"` and `aria-expanded`, so assistive tech associates the menu with the control users actually focus. |
13
13
  | `placement` | `"bottom-start" \| "bottom-end" \| "top-start" \| "top-end"` | bottom-start | no | Placement relative to the trigger. |
14
14
  | `aria-label` | `string` | — | no | Accessible name for the menu when there is no visible label. |
15
+ | `children` | `ReactNode` | — | yes | MenuItem and MenuSeparator children. |
15
16
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
16
17
  | `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the popover element. |
17
18
 
@@ -42,4 +43,5 @@ Override `--psi-menu-*` custom properties at any scope; interactive states deriv
42
43
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
43
44
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
44
45
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
46
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
45
47
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/MenuItem.md CHANGED
@@ -7,6 +7,7 @@ One action in a Menu. Renders a real <button> so activation, Enter and Space com
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | yes | Item label. |
10
11
  | `onSelect` | `() => void` | — | yes | Fires on activation; Menu then reports the dismissal via onClose("item-select") (D50). |
11
12
  | `variant` | `"neutral" \| "danger"` | neutral | no | danger is for destructive actions only (house rule). |
12
13
  | `disabled` | `boolean` | false | no | |
@@ -44,4 +45,5 @@ This component has no `--psi-menu-item-*` tokens — its styling binds scale tok
44
45
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
45
46
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
46
47
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
48
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
47
49
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -32,4 +32,5 @@ This component has no `--psi-menu-separator-*` tokens — its styling binds scal
32
32
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
33
33
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
34
34
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
35
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
35
36
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/NavBar.md CHANGED
@@ -28,4 +28,5 @@ Override `--psi-navbar-*` custom properties at any scope; interactive states der
28
28
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
29
29
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
30
30
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
31
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
31
32
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -29,4 +29,5 @@ This component has no `--psi-pagination-*` tokens — its styling binds scale to
29
29
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
30
30
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
31
31
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
32
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
32
33
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Panel.md CHANGED
@@ -7,6 +7,7 @@ Elevated surface panel (D51): secondary background, faint hairline, radius-12
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | Panel contents. |
10
11
  | `padding` | `16 \| 24` | 24 | no | Inner padding in px. |
11
12
  | `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the root element. |
12
13
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
@@ -34,4 +35,5 @@ Override `--psi-panel-*` custom properties at any scope.
34
35
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
35
36
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
36
37
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
38
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
37
39
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Select.md CHANGED
@@ -7,6 +7,7 @@ Styled native `<select>` with pixel-true heights (24–48) and an error state. I
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | The <option> elements. |
10
11
  | `size` | `24 \| 32 \| 40 \| 48` | 32 | no | Height in px (24 \| 32 \| 40 \| 48). Replaces the native `size` attribute (which sets the visible option-row count on a listbox-style `<select>`) with the design system's control height in pixels. |
11
12
  | `error` | `boolean` | false | no | Show error styling. Inside a Field, the Field's error also lights this. |
12
13
  | `ref` | `Ref<HTMLSelectElement>` | — | no | Forwarded ref to the underlying `<select>` element. |
@@ -36,4 +37,5 @@ Override `--psi-select-*` custom properties at any scope; interactive states der
36
37
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
37
38
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
38
39
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
40
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
39
41
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Switch.md CHANGED
@@ -33,4 +33,5 @@ Override `--psi-switch-*` custom properties at any scope.
33
33
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
34
34
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
35
35
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
36
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
36
37
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Tab.md CHANGED
@@ -36,4 +36,5 @@ This component has no `--psi-tab-*` tokens — its styling binds scale tokens on
36
36
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
37
37
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
38
38
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
39
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
39
40
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/TabList.md CHANGED
@@ -37,4 +37,5 @@ This component has no `--psi-tab-list-*` tokens — its styling binds scale toke
37
37
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
38
38
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
39
39
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
40
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
40
41
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/TabPanel.md CHANGED
@@ -35,4 +35,5 @@ This component has no `--psi-tab-panel-*` tokens — its styling binds scale tok
35
35
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
36
36
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
37
37
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
38
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
38
39
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Table.md CHANGED
@@ -15,6 +15,7 @@ Data table on native table semantics. Holds no state: sorting, selection and pag
15
15
  | `selectable` | `boolean` | false | no | Renders the row-selection checkbox column. |
16
16
  | `selected` | `ReadonlySet<string>` | new Set<string>() | no | Controlled selection, keyed by each `TableRow`'s `rowId`. |
17
17
  | `onSelectionChange` | `((selected: ReadonlySet<string>) => void)` | — | no | Called with the next selection. See `onSortChange` on why it is optional. |
18
+ | `children` | `ReactNode` | — | yes | TableHead and TableBody. |
18
19
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
19
20
  | `ref` | `Ref<HTMLTableElement>` | — | no | Forwarded ref to the underlying `<table>` element. |
20
21
 
@@ -33,4 +34,5 @@ Override `--psi-table-*` custom properties at any scope; interactive states deri
33
34
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
34
35
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
35
36
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
37
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
36
38
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/TableBody.md CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | yes | The body TableRows. |
10
11
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
11
12
 
12
13
  ## Theming
@@ -24,4 +25,5 @@ This component has no `--psi-table-body-*` tokens — its styling binds scale to
24
25
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
25
26
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
26
27
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
28
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
27
29
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/TableCell.md CHANGED
@@ -8,6 +8,7 @@
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
10
  | `numeric` | `boolean` | — | no | Right-aligns and renders tabular figures (D62). |
11
+ | `children` | `ReactNode` | — | no | Cell content. |
11
12
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
12
13
 
13
14
  ## Theming
@@ -25,4 +26,5 @@ This component has no `--psi-table-cell-*` tokens — its styling binds scale to
25
26
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
26
27
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
27
28
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
29
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
28
30
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/TableHead.md CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | yes | The header TableRow. |
10
11
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
11
12
 
12
13
  ## Theming
@@ -24,4 +25,5 @@ This component has no `--psi-table-head-*` tokens — its styling binds scale to
24
25
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
25
26
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
26
27
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
28
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
27
29
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -9,6 +9,7 @@
9
9
  |---|---|---|---|---|
10
10
  | `sortKey` | `string` | — | no | Sort key this column emits. Enables the sort control when the table is `sortable`. |
11
11
  | `numeric` | `boolean` | — | no | Right-aligns and renders tabular figures (D62). |
12
+ | `children` | `ReactNode` | — | no | Header label. |
12
13
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
13
14
 
14
15
  ## Theming
@@ -26,4 +27,5 @@ This component has no `--psi-table-header-cell-*` tokens — its styling binds s
26
27
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
27
28
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
28
29
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
30
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
29
31
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/TableRow.md CHANGED
@@ -9,6 +9,7 @@
9
9
  |---|---|---|---|---|
10
10
  | `rowId` | `string` | — | no | Stable identity for selection. Required for selectable tables (D62). |
11
11
  | `selectLabel` | `string` | — | no | Accessible name for this row's selection checkbox. |
12
+ | `children` | `ReactNode` | — | yes | The row's cells. |
12
13
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
13
14
 
14
15
  ## Theming
@@ -26,4 +27,5 @@ This component has no `--psi-table-row-*` tokens — its styling binds scale tok
26
27
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
27
28
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
28
29
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
30
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
29
31
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Tabs.md CHANGED
@@ -37,4 +37,5 @@ Override `--psi-tabs-*` custom properties at any scope; interactive states deriv
37
37
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
38
38
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
39
39
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
40
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
40
41
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Tag.md CHANGED
@@ -47,4 +47,5 @@ Override `--psi-tag-*` custom properties at any scope.
47
47
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
48
48
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
49
49
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
50
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
50
51
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Toast.md CHANGED
@@ -48,4 +48,5 @@ Override `--psi-toast-*` custom properties at any scope.
48
48
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
49
49
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
50
50
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
51
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
51
52
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -36,4 +36,5 @@ This component has no `--psi-toast-provider-*` tokens — its styling binds scal
36
36
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
37
37
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
38
38
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
39
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
39
40
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
@@ -36,4 +36,5 @@ This component has no `--psi-toast-region-*` tokens — its styling binds scale
36
36
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
37
37
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
38
38
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
39
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
39
40
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Toolbar.md CHANGED
@@ -7,6 +7,7 @@ Horizontal grouping row for filter/search controls (D52). Wraps on overflow; zer
7
7
 
8
8
  | Prop | Type | Default | Required | Description |
9
9
  |---|---|---|---|---|
10
+ | `children` | `ReactNode` | — | no | The controls. |
10
11
  | `gap` | `8 \| 12 \| 16` | 8 | no | Gap between controls in px. |
11
12
  | `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the root element. |
12
13
  | `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
@@ -34,4 +35,5 @@ This component has no `--psi-toolbar-*` tokens — its styling binds scale token
34
35
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
35
36
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
36
37
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
38
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
37
39
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/docs/Tooltip.md CHANGED
@@ -35,4 +35,5 @@ Override `--psi-tooltip-*` custom properties at any scope.
35
35
  - Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
36
36
  - --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
37
37
  - Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
38
+ - Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
38
39
  - Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # @handamade/psi-react
2
2
 
3
- 32 React 19 components consuming @handamade/psi-tokens. Zero runtime deps, CSS Modules, ref-as-prop.
3
+ 34 React 19 components consuming @handamade/psi-tokens. Zero runtime deps, CSS Modules, ref-as-prop.
4
4
 
5
5
  ## Machine-readable artifacts
6
6
  - dist/manifest.json: full component/prop inventory with types and defaults
@@ -27,6 +27,11 @@
27
27
  ## Panel
28
28
  - <Panel padding={16|24}>: the elevated surface panel (D51) — bg-secondary, faint hairline border, radius-12, space-24 padding (16 for compact). Binds the shared --psi-surface-* recipe Dialog's panel also uses; brands retune both by overriding --psi-surface-*. Not a Card: no media slot, no hover lift.
29
29
 
30
+ ## DescriptionList (2)
31
+ - `<DescriptionList layout="stacked|inline" gap={8|12|16}>` with one `<DescriptionItem term="Date">value</DescriptionItem>` per field (D70). Renders `<dl>`; each item is a `<div><dt/><dd/></div>` group, which is the HTML5 grouping element, so the term/value association survives.
32
+ - `stacked` (default) puts the term above its value; `inline` is a two-column grid and is what a detail drawer wants. This is the body of the `detail-drawer` pattern — do not hand-roll a `<dl>`.
33
+ - The term is a prop and the value is children, matching Field's `label` idiom. No `size` prop: this is type, so restyle through `--psi-description-list-*`.
34
+
30
35
  ## Toolbar
31
36
  - <Toolbar gap={8|12|16} aria-label="Filters">: horizontal wrapping row for filter/search controls (Input, Select, Tag, Button). Wraps on overflow (D52); with aria-label it announces as role=group. Deliberately not ARIA role=toolbar (no roving tabindex). Unblocks the filter-toolbar pattern — consult dist/patterns.json for the preset.
32
37
 
@@ -36,8 +41,8 @@
36
41
  ## AspectRatio
37
42
  - <AspectRatio ratio={16/10}>{children}</AspectRatio>: a frame div with CSS aspect-ratio set from the numeric ratio prop — wrap images/media to reserve layout space before load. Combine with the .psi-media-tint utility for the brand media-tint treatment.
38
43
 
39
- ## Icons (25)
40
- - Full icon set: IconPlus, IconMinus, IconCheck, IconClose, IconChevronDown, IconChevronRight, IconSearch, IconSettings, IconUser, IconEye, IconEyeOff, IconEdit, IconCopy, IconTrash, IconLoader, IconExternalLink, plus D36 additions — arrows IconArrowDown and IconArrowUpRight, and social glyphs IconLinkedIn, IconGitHub, IconX, IconInstagram — plus the D64 status glyphs IconInfo, IconAlertTriangle and IconAlertCircle.
44
+ ## Icons (26)
45
+ - Full icon set: IconPlus, IconMinus, IconCheck, IconClose, IconChevronDown, IconChevronRight, IconSearch, IconSettings, IconUser, IconEye, IconEyeOff, IconEdit, IconCopy, IconTrash, IconLoader, IconExternalLink, plus D36 additions — arrows IconArrowDown and IconArrowUpRight, and social glyphs IconLinkedIn, IconGitHub, IconX, IconInstagram — plus the D64 status glyphs IconInfo, IconAlertTriangle and IconAlertCircle, and the D70 IconMoreHorizontal — the ellipsis glyph for a row-actions trigger.
41
46
 
42
47
  ## Table family (6)
43
48
  - `<Table>` renders `<table>` and is **controlled-only** — it holds no state (D62). Sorting is `sort={{key, direction}}` + `onSortChange`; selection is `selected` (a `ReadonlySet<string>` keyed by each `<TableRow rowId>`) + `onSelectionChange`. `sortable` and `selectable` only enable the affordances. `size` is `32 | 40 | 48` px (default 40) and `stickyHeader` pins the header. It does no filtering, sorting or slicing of rows — the consumer does that.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handamade/psi-react",
3
- "version": "0.13.1",
3
+ "version": "0.14.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -46,7 +46,7 @@
46
46
  "tsx": "^4.22.4",
47
47
  "vite": "^6.0.0",
48
48
  "vitest": "^3.2.6",
49
- "@handamade/psi-tokens": "0.13.1"
49
+ "@handamade/psi-tokens": "0.14.2"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "vite build && tsc -p tsconfig.build.json && tsx scripts/emit-styles-dts.ts && tsx scripts/emit-manifest.ts && tsx scripts/emit-patterns.ts && tsx scripts/emit-docs.ts",