@kb.ui/react 0.10.4 → 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.
Files changed (109) hide show
  1. package/README.md +142 -707
  2. package/dist/components/Accordion/Accordion.d.ts +33 -0
  3. package/dist/components/Avatar/Avatar.d.ts +19 -0
  4. package/dist/components/Code/Code.d.ts +26 -3
  5. package/dist/components/Code/tokenize.d.ts +5 -0
  6. package/dist/components/CodeBlock/CodeBlock.d.ts +10 -0
  7. package/dist/components/Collection/Collection.d.ts +99 -0
  8. package/dist/components/Collection/useCollection.d.ts +66 -0
  9. package/dist/components/CollectionList/CollectionList.d.ts +12 -0
  10. package/dist/components/CollectionRow/CollectionRow.d.ts +17 -0
  11. package/dist/components/Combobox/Combobox.d.ts +14 -2
  12. package/dist/components/ConfirmAction/ConfirmAction.d.ts +42 -0
  13. package/dist/components/CopyableText/CopyableText.d.ts +38 -0
  14. package/dist/components/CopyableText/content.d.ts +14 -0
  15. package/dist/components/Dashboard/Dashboard.d.ts +17 -0
  16. package/dist/components/DescriptionList/DescriptionList.d.ts +20 -0
  17. package/dist/components/Dialog/Dialog.d.ts +3 -1
  18. package/dist/components/Disclosure/Disclosure.d.ts +21 -0
  19. package/dist/components/EmptyState/EmptyState.d.ts +30 -0
  20. package/dist/components/Form/Form.d.ts +19 -0
  21. package/dist/components/FormSection/FormSection.d.ts +26 -0
  22. package/dist/components/Gallery/Gallery.d.ts +26 -0
  23. package/dist/components/Grid/Grid.d.ts +17 -6
  24. package/dist/components/Image/Image.d.ts +20 -0
  25. package/dist/components/Link/Link.d.ts +15 -2
  26. package/dist/components/PageHeader/PageHeader.d.ts +27 -0
  27. package/dist/components/Panel/Panel.d.ts +3 -1
  28. package/dist/components/Popover/Popover.d.ts +55 -0
  29. package/dist/components/Settings/Settings.d.ts +11 -0
  30. package/dist/components/Skeleton/Skeleton.d.ts +34 -0
  31. package/dist/components/Spinner/Spinner.d.ts +26 -0
  32. package/dist/components/Stack/Stack.d.ts +15 -0
  33. package/dist/components/StatsRow/StatsRow.d.ts +33 -0
  34. package/dist/components/SupportingPane/SupportingPane.d.ts +15 -0
  35. package/dist/components/Table/Table.d.ts +65 -0
  36. package/dist/components/Tabs/Tabs.d.ts +69 -0
  37. package/dist/components/Tabs/index.d.ts +1 -0
  38. package/dist/components/Thumbnail/Thumbnail.d.ts +14 -0
  39. package/dist/components/Toast/Toast.d.ts +72 -0
  40. package/dist/index.d.ts +39 -4
  41. package/dist/index.js +3901 -1238
  42. package/dist/index.js.map +1 -1
  43. package/dist/styles.css +1 -1
  44. package/dist/utils/CollapsiblePanel.d.ts +10 -0
  45. package/dist/utils/useClipboard.d.ts +28 -0
  46. package/docs/components/Accordion.md +66 -0
  47. package/docs/components/Avatar.md +80 -0
  48. package/docs/components/Badge.md +37 -0
  49. package/docs/components/Button.md +46 -0
  50. package/docs/components/Callout.md +41 -0
  51. package/docs/components/Card.md +41 -0
  52. package/docs/components/Checkbox.md +60 -0
  53. package/docs/components/Code.md +77 -0
  54. package/docs/components/CodeBlock.md +77 -0
  55. package/docs/components/Collection.md +183 -0
  56. package/docs/components/CollectionList.md +44 -0
  57. package/docs/components/CollectionRow.md +62 -0
  58. package/docs/components/Combobox.md +88 -0
  59. package/docs/components/ConfirmAction.md +100 -0
  60. package/docs/components/Container.md +41 -0
  61. package/docs/components/CopyableText.md +93 -0
  62. package/docs/components/Dashboard.md +81 -0
  63. package/docs/components/DescriptionList.md +61 -0
  64. package/docs/components/Dialog.md +84 -0
  65. package/docs/components/Disclosure.md +53 -0
  66. package/docs/components/EmptyState.md +50 -0
  67. package/docs/components/ErrorSummary.md +48 -0
  68. package/docs/components/Fieldset.md +42 -0
  69. package/docs/components/FileInput.md +74 -0
  70. package/docs/components/Form.md +67 -0
  71. package/docs/components/FormActions.md +45 -0
  72. package/docs/components/FormSection.md +57 -0
  73. package/docs/components/Gallery.md +84 -0
  74. package/docs/components/Grid.md +66 -0
  75. package/docs/components/Heading.md +40 -0
  76. package/docs/components/Image.md +62 -0
  77. package/docs/components/Inline.md +42 -0
  78. package/docs/components/Input.md +82 -0
  79. package/docs/components/Link.md +52 -0
  80. package/docs/components/Menu.md +44 -0
  81. package/docs/components/MultiSelect.md +59 -0
  82. package/docs/components/NumberField.md +65 -0
  83. package/docs/components/PageHeader.md +68 -0
  84. package/docs/components/Panel.md +153 -0
  85. package/docs/components/Popover.md +89 -0
  86. package/docs/components/Progress.md +37 -0
  87. package/docs/components/RadioGroup.md +69 -0
  88. package/docs/components/ScrollArea.md +40 -0
  89. package/docs/components/Select.md +71 -0
  90. package/docs/components/Separator.md +40 -0
  91. package/docs/components/Settings.md +57 -0
  92. package/docs/components/Skeleton.md +86 -0
  93. package/docs/components/Spinner.md +45 -0
  94. package/docs/components/Split.md +47 -0
  95. package/docs/components/Stack.md +54 -0
  96. package/docs/components/Stat.md +34 -0
  97. package/docs/components/StatsRow.md +80 -0
  98. package/docs/components/Status.md +48 -0
  99. package/docs/components/SupportingPane.md +59 -0
  100. package/docs/components/Switch.md +73 -0
  101. package/docs/components/Table.md +105 -0
  102. package/docs/components/Tabs.md +89 -0
  103. package/docs/components/Text.md +36 -0
  104. package/docs/components/Textarea.md +47 -0
  105. package/docs/components/Thumbnail.md +66 -0
  106. package/docs/components/Toast.md +130 -0
  107. package/docs/components/Toolbar.md +39 -0
  108. package/docs/components/Tooltip.md +42 -0
  109. package/package.json +3 -2
@@ -0,0 +1,81 @@
1
+ # Dashboard
2
+
3
+ Use `Dashboard` for an overview page: a header, a row of headline metrics, then primary and secondary panels. Primary and secondary sit side by side, two thirds and one third, once the panels region is 60rem wide, and stack with primary first below that. `Dashboard` is also the page frame: it fills the width up to 80rem with 1, 1.5 or 2rem gutters, so it does not need a [`Container`](Container.md). For a main column with one supporting aside, such as an order summary, use [`Split`](Split.md).
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/layout-dashboard--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Card, Dashboard, Grid, PageHeader, Panel, Progress, Stat, Status } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <main>
16
+ <Dashboard
17
+ header={
18
+ <PageHeader
19
+ title="Sales dashboard"
20
+ description="Performance overview for your online store."
21
+ meta={<Status tone="success">Updated 5 minutes ago</Status>}
22
+ />
23
+ }
24
+ metrics={
25
+ <Grid as="ul" aria-label="Key metrics" minItemWidth="sm" gap="md">
26
+ <Card as="li">
27
+ <Stat label="Total revenue" value="$128,450" />
28
+ </Card>
29
+ <Card as="li">
30
+ <Stat label="Orders" value="2,184" />
31
+ </Card>
32
+ </Grid>
33
+ }
34
+ primary={
35
+ <Panel aria-labelledby="channels-title">
36
+ <Panel.Header>
37
+ <h2 id="channels-title">Revenue by channel</h2>
38
+ </Panel.Header>
39
+ <Panel.Body>Organic search brought in 36% of revenue.</Panel.Body>
40
+ </Panel>
41
+ }
42
+ secondary={
43
+ <Panel aria-labelledby="goals-title">
44
+ <Panel.Header>
45
+ <h2 id="goals-title">Monthly goals</h2>
46
+ </Panel.Header>
47
+ <Panel.Body>
48
+ <Progress label="Revenue" value={86} valueText="$128k of $150k" />
49
+ </Panel.Body>
50
+ </Panel>
51
+ }
52
+ />
53
+ </main>
54
+ );
55
+ }
56
+ ```
57
+
58
+ ## More examples
59
+
60
+ - [Sales overview](https://kbui.kcb.pro/storybook/?path=/story/layout-dashboard--sales-overview): A store dashboard with a date range, four metrics, channel revenue and top products beside monthly goals.
61
+ - [Metrics and primary](https://kbui.kcb.pro/storybook/?path=/story/layout-dashboard--metrics-and-primary): Without secondary panels, the primary region fills the page.
62
+
63
+ ## Reference
64
+
65
+ | Prop | Type | Default | Notes |
66
+ | --- | --- | --- | --- |
67
+ | `header` | `ReactNode` | unset | Page title, freshness and page actions; usually a `PageHeader` |
68
+ | `metrics` | `ReactNode` | unset | Row of headline metrics below the header |
69
+ | `primary` | `ReactNode` | unset | Main panels; two thirds of the row on wide pages |
70
+ | `secondary` | `ReactNode` | unset | Supporting panels; one third on wide pages, below primary on narrow ones |
71
+ | `classNames` | `{ header?, metrics?, panels?, primary?, secondary? }` | unset | Classes for the regions |
72
+
73
+ Other native `div` props and `ref` pass through. Regions render in the order above and only when they have content; with only one of primary or secondary, it fills the row. Each panel region stacks its children with the dashboard gap.
74
+
75
+ Gutters follow the width of the dashboard's parent: 1rem below 48rem, 1.5rem from 48rem and 2rem from 64rem. As a direct flex item, such as beside a sidebar, the parent is the whole row, so wrap `Dashboard` in its own block, such as `main`. Tokens: `--kb-dashboard-gap`, `--kb-dashboard-max-width`, `--kb-dashboard-gutter-sm`, `-md`, `-lg`, `--kb-dashboard-gutter-md-from`, `--kb-dashboard-gutter-lg-from` and `--kb-dashboard-collapse`.
76
+
77
+ Give the page one `h1`, usually `PageHeader`'s title, and name each panel with its `h2`. Label the metrics list, and show when the data was last updated, or that it is partial, as text in the header. Your app owns data loading, date ranges and refresh.
78
+
79
+ ## Related components
80
+
81
+ Use [`PageHeader`](PageHeader.md) for the header, [`Stat`](Stat.md) in a [`Grid`](Grid.md) for metrics and [`Panel`](Panel.md) for each panel.
@@ -0,0 +1,61 @@
1
+ # DescriptionList
2
+
3
+ Present named facts about one record with native description-list relationships. Use `Table` when readers need to compare the same fields across records.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-descriptionlist--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { DescriptionList, Link, Status } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <DescriptionList aria-label="Project details">
16
+ <DescriptionList.Item>
17
+ <DescriptionList.Term>Owner</DescriptionList.Term>
18
+ <DescriptionList.Detail><Link href="/people/ada">Ada Chen</Link></DescriptionList.Detail>
19
+ </DescriptionList.Item>
20
+ <DescriptionList.Item>
21
+ <DescriptionList.Term>Status</DescriptionList.Term>
22
+ <DescriptionList.Detail><Status tone="success">Ready for review</Status></DescriptionList.Detail>
23
+ </DescriptionList.Item>
24
+ <DescriptionList.Item>
25
+ <DescriptionList.Term>Open tasks</DescriptionList.Term>
26
+ <DescriptionList.Detail>{0}</DescriptionList.Detail>
27
+ </DescriptionList.Item>
28
+ </DescriptionList>
29
+ );
30
+ }
31
+ ```
32
+
33
+ ## More examples
34
+
35
+ - [Responsive](https://kbui.kcb.pro/storybook/?path=/story/components-descriptionlist--responsive): Stacks according to its parent width.
36
+ - [Nested details](https://kbui.kcb.pro/storybook/?path=/story/components-descriptionlist--nested): Independent density and layout inside another detail value.
37
+
38
+ ## Reference
39
+
40
+ | Part | Native element | Purpose |
41
+ |---|---|---|
42
+ | `DescriptionList` | `dl` | Root description list; native naming attributes, children, styles and ref pass through |
43
+ | `DescriptionList.Item` | `div` | Groups one Term with one or more Detail elements |
44
+ | `DescriptionList.Term` | `dt` | Meaningful label in reading order before its values |
45
+ | `DescriptionList.Detail` | `dd` | Text, numbers, links, status or richer content; repeated Details support multiple values |
46
+
47
+ | Prop | Default | Behavior |
48
+ |---|---|---|
49
+ | `layout` | `responsive` | `responsive` uses label/value columns, stacking below 32rem of available width; `horizontal` keeps columns; `stacked` always puts values below labels |
50
+ | `density` | `comfortable` | `comfortable` or `dense`; changes immediate Item spacing |
51
+ | `dividers` | true | Rules between immediate groups |
52
+
53
+ Every part accepts its native attributes, `className`, `style` and ref. Types are `DescriptionListProps`, `DescriptionListItemProps`, `DescriptionListTermProps` and `DescriptionListDetailProps`. Use a real `dt` before its `dd` values; the description list does not become a table or listbox. Group alternate names inside one Term when they share values. Native IDs and `aria-labelledby` remain available for richer relationships.
54
+
55
+ Values align to the same column across Items. Long labels, identifiers and composed `Status` text wrap, including chips with decorative icons; native links and controls retain their keyboard behavior. Use a deliberate stacked layout for narrow details, or override `--kb-descriptionlist-term-width` when the default 12rem label cap does not fit your labels. Other tokens control column/row gaps and comfortable/dense block padding. Nested lists keep their own layout and density.
56
+
57
+ Keep zero values visible. Write a meaningful unavailable value such as Not scheduled rather than silently omitting a required fact. Your app owns formatting, units, timezone, localization, loading, errors and announcements. Do not use term text as an input label; controls still need their own labels and relationships. A description list supplies native relationships, not interactive field validation.
58
+
59
+ ## Related components
60
+
61
+ Use [`Table`](Table.md) for comparing fields across records, [`CollectionRow`](CollectionRow.md) for summarizing records with actions, and [`Status`](Status.md) for an explicit state. See [Structured data](../../../../docs/guides/structured-data.md) for choosing and composing these patterns.
@@ -0,0 +1,84 @@
1
+ # Dialog
2
+
3
+ `Dialog` is composed from parts. Base UI handles focus trapping, closing on Escape and scroll locking.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-dialog--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Button, Dialog } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <Dialog>
16
+ <Dialog.Trigger render={<Button />}>View details</Dialog.Trigger>
17
+ <Dialog.Content
18
+ title="Project details"
19
+ description="Current project status."
20
+ >
21
+ <p>Three tasks remain.</p>
22
+ <Dialog.Actions>
23
+ <Dialog.Close render={<Button />}>Done</Dialog.Close>
24
+ </Dialog.Actions>
25
+ </Dialog.Content>
26
+ </Dialog>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ## More examples
32
+
33
+ - [A confirmation task](https://kbui.kcb.pro/storybook/?path=/story/components-dialog--confirm): Open and close a modal from its trigger.
34
+ - [Structured content](https://kbui.kcb.pro/storybook/?path=/story/components-dialog--sections): Inspect header, body, footer, and actions; opens a modal.
35
+ - [A custom layout](https://kbui.kcb.pro/storybook/?path=/story/components-dialog--custom-layout): Inspect composed titles and descriptions; opens a modal.
36
+
37
+ ## Reference
38
+
39
+ | Part | Purpose |
40
+ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
41
+ | `Dialog` | Root. Accepts `open`, `defaultOpen` and `onOpenChange` for controlled use. |
42
+ | `Dialog.Trigger` | Opens the dialog. Use `render={<Button />}` to style it as a button. |
43
+ | `Dialog.Content` | The dialog. `title` and `description` set its accessible name and description; `container` changes where it mounts. |
44
+ | `Content.layout` | `"center"` (default) or `"drawer"`; drawer slides from inline end, uses `--kb-dialog-width` and scrolls direct Body independently. |
45
+ | `Dialog.Title`, `Dialog.Description` | For custom layouts. Use these or the `Dialog.Content` props in a given dialog, not both, or it gets two titles. |
46
+ | `Dialog.Header`, `Dialog.Body`, `Dialog.Footer` | Optional structured sections; accept native `div` props and refs. Centered padding follows `--kb-dialog-{header,body,footer}-padding`; drawer sections use `--kb-dialog-padding`. |
47
+ | `Dialog.Actions` | Aligns buttons along the bottom right. |
48
+ | `Dialog.Close` | Closes the dialog. |
49
+
50
+ | Prop on root or Content | Type | Default | Notes |
51
+ | ------------------------ | ---------------- | ------------- | ----------------------------------------------------------------------------- |
52
+ | `open` on `Dialog` | `boolean` | uncontrolled | Current visibility when your app controls the dialog |
53
+ | `defaultOpen` on `Dialog` | `boolean` | `false` | Initial visibility; avoid starting open in a reading surface |
54
+ | `onOpenChange` on `Dialog` | Base UI callback | unset | Receives the next visibility and change details |
55
+ | `title` on Content | `ReactNode` | unset | Visible title and accessible name; use `Dialog.Title` for custom markup instead |
56
+ | `description` on Content | `ReactNode` | unset | Supporting description; use `Dialog.Description` for custom markup instead |
57
+ | `container` on Content | portal container | document body | Themed host for a nested dialog |
58
+
59
+ ```tsx
60
+ <Dialog>
61
+ <Dialog.Trigger render={<Button />}>Open</Dialog.Trigger>
62
+ <Dialog.Content title="Rename file">
63
+ <Input label="Name" />
64
+ <Dialog.Actions>
65
+ <Dialog.Close render={<Button variant="ghost" />}>Cancel</Dialog.Close>
66
+ <Button>Save</Button>
67
+ </Dialog.Actions>
68
+ </Dialog.Content>
69
+ </Dialog>
70
+ ```
71
+
72
+ ## Related components
73
+
74
+ Use [`ConfirmAction`](ConfirmAction.md) for a destructive action behind a confirmation, [`Menu`](Menu.md) for a short action list and [`Callout`](Callout.md) for a message that belongs in the page.
75
+
76
+
77
+ ## Drawer and confirmation patterns
78
+
79
+ The [overlay guide](../../../../docs/guides/forms-and-overlays.md#drawer-pattern) supplies complete drawer and asynchronous confirmation modules. Drawers use `Content layout="drawer"` with direct Header, Body and Footer sections. Header/actions remain visible while Body scrolls; the drawer follows logical direction and dynamic viewport height. Content title/description props automatically form a drawer Header. Focus a composed title initially for long content. Confirmations focus Cancel first, reject duplicate/pending dismissal, retain errors for retry and close only after success.
80
+
81
+ - [Drawer](https://kbui.kcb.pro/storybook/?path=/story/components-dialog--drawer)
82
+ - [Failure and retry](https://kbui.kcb.pro/storybook/?path=/story/components-dialog--confirmation-recovery)
83
+
84
+ Use [`Popover`](Popover.md) for non-modal anchored controls and [`Disclosure`](Disclosure.md) for supporting details inline.
@@ -0,0 +1,53 @@
1
+ # Disclosure
2
+
3
+ Reveal optional details or advanced controls inline. Base UI Collapsible owns the open state, trigger relationship and hidden panel behavior.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-disclosure--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Disclosure, Input } from "@kb.ui/react";
12
+
13
+ export function AdvancedSettings() {
14
+ return (
15
+ <Disclosure>
16
+ <Disclosure.Trigger>Advanced settings</Disclosure.Trigger>
17
+ <Disclosure.Panel keepMounted>
18
+ <Input label="Reply-to address" defaultValue="team@example.com" />
19
+ </Disclosure.Panel>
20
+ </Disclosure>
21
+ );
22
+ }
23
+ ```
24
+
25
+ ## More examples
26
+
27
+ - [Retained draft](https://kbui.kcb.pro/storybook/?path=/story/components-disclosure--retained-draft): preserve an uncontrolled field through collapse.
28
+ - [Controlled](https://kbui.kcb.pro/storybook/?path=/story/components-disclosure--controlled): caller-owned open state.
29
+ - [Disabled](https://kbui.kcb.pro/storybook/?path=/story/components-disclosure--disabled): unavailable details.
30
+
31
+ ## Reference
32
+
33
+ | Part / prop | Type | Default | Purpose |
34
+ |---|---|---|---|
35
+ | `Disclosure` | Base UI Collapsible root props | `div` | Groups trigger and panel; accepts native props and ref. |
36
+ | `open` / `defaultOpen` | `boolean` | `false` | Controlled or initial expansion. |
37
+ | `onOpenChange` | `(open, details) => void` | — | Requests a state change; `details.cancel()` rejects it. |
38
+ | `disabled` | `boolean` | `false` | Prevents user toggling. |
39
+ | `Disclosure.Trigger` | Base UI Collapsible trigger props | `button` | Native Enter/Space activation and expanded/controls relationships. |
40
+ | `Disclosure.Panel` | Base UI Collapsible panel props | `div` | Contains optional details and controls. |
41
+ | `Panel.keepMounted` | `boolean` | `false` | Retains DOM and uncontrolled draft state while closed. |
42
+ | `Panel.hiddenUntilFound` | `boolean` | `false` | Uses browser find-in-page reveal where supported; overrides `keepMounted`. |
43
+ | `className` / `render` / `ref` | Part-specific native props | — | Style, compose and reference each DOM part. Class names accept strings. |
44
+
45
+ Tab reaches the trigger; Enter and Space toggle it without moving focus into the panel. Collapsed controls leave the accessibility tree and Tab order. No arrow-key navigation or modal behavior is added. Put essential instructions and errors where they remain discoverable. Unmounted content loses uncontrolled state; use `keepMounted` or store values outside the panel. Browser find-in-page reveal depends on engine support and the caller accepting controlled state changes.
46
+
47
+ Style `--kb-disclosure-padding`, `-radius`, `-background`, `-color`, `-border` and `-trigger-height`. Preserve visible focus, hidden semantics and disabled state when overriding styles.
48
+
49
+ Panels expand and collapse through measured height transitions; reversing mid-transition follows the latest toggle. Content grows naturally once expanded. `--kb-disclosure-motion-duration` and `-motion-easing` control panel and caret motion; reduced motion disables transitions. `.kb-disclosure-panel-content` owns inner padding, keeping the outer `Panel` measurable without clipping collapsed padding. `Panel` props, `className`, render and ref still target the outer node.
50
+
51
+ ## Related components
52
+
53
+ Use [`Accordion`](Accordion.md) for related sections with headings, [`Panel`](Panel.md) for a structured work surface, or [`Popover`](Popover.md) for anchored supporting controls. [Overlay guidance](../../../../docs/guides/forms-and-overlays.md) covers choosing disclosure, popovers and modal patterns.
@@ -0,0 +1,50 @@
1
+ # EmptyState
2
+
3
+ Explain why a collection, search result, or section has no content to show, and provide the direct action that populates or recovers it.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-emptystate--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Button, EmptyState } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <EmptyState
16
+ eyebrow="Pipelines"
17
+ title="No release pipelines configured"
18
+ description="Create a pipeline to validate builds and publish signed packages."
19
+ actions={<Button size="sm">Create pipeline</Button>}
20
+ />
21
+ );
22
+ }
23
+ ```
24
+
25
+ ## More examples
26
+
27
+ - [Filtered zero results](https://kbui.kcb.pro/storybook/?path=/story/components-emptystate--filtered-zero-results): Give people a one-click way to clear active filters or widen their query.
28
+ - [Recoverable section failure](https://kbui.kcb.pro/storybook/?path=/story/components-emptystate--recoverable-failure): Explain when a section failed to load and pair the explanation with a retry action.
29
+ - [Surface variants](https://kbui.kcb.pro/storybook/?path=/story/components-emptystate--variants-and-sizes): Choose `surface`, `subtle`, or `plain` containers to match surrounding hierarchy.
30
+
31
+ ## Reference
32
+
33
+ | Prop | Type | Default | Notes |
34
+ | -------------- | -------------------------------------------- | --------- | -------------------------------------------------------------------------------------- |
35
+ | `title` | `ReactNode` | required | Heading text naming what is missing or unavailable |
36
+ | `description` | `ReactNode` | unset | Supporting guidance explaining how to populate or recover the view |
37
+ | `eyebrow` | `ReactNode` | unset | Short uppercase label above the title |
38
+ | `icon` | `ReactNode` | unset | Decorative emblem above the header; hidden from assistive technology |
39
+ | `actions` | `ReactNode` | unset | Primary and secondary buttons or links that resolve the empty state |
40
+ | `footer` | `ReactNode` | unset | Quiet footnote, error code, or secondary hint below actions |
41
+ | `headingLevel` | `2` / `3` / `4` | `3` | Semantic heading tag (`h2`–`h4`) matching the surrounding document outline |
42
+ | `variant` | `surface` / `subtle` / `plain` | `surface` | Raised bordered card, dashed recessed well, or borderless inline block |
43
+ | `size` | `sm` / `md` / `lg` | `md` | Scales padding, icon badge, and heading typography |
44
+ | `tone` | `neutral` / `info` / `warning` / `danger` | `neutral` | Accentuates the icon badge and border for informational or failure states |
45
+ | `live` | `boolean` | `false` | Adds `role="status"` when revealed dynamically after filtering or an async load error |
46
+ | `classNames` | keyed classes | unset | Style `icon`, `header`, `eyebrow`, `title`, `description`, `body`, `actions`, `footer` |
47
+
48
+ ## Related components
49
+
50
+ Use [`Skeleton`](Skeleton.md) while the collection is still loading, [`Callout`](Callout.md) for inline notices beside populated content, and [`Toast`](Toast.md) for transient action feedback.
@@ -0,0 +1,48 @@
1
+ # ErrorSummary
2
+
3
+ Place `ErrorSummary` at the top of a form when submission fails so people can see what went wrong and jump directly to each invalid field. When `items` is empty, nothing is rendered.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-errorsummary--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { ErrorSummary, Input } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <form noValidate>
16
+ <ErrorSummary
17
+ items={[{ href: "#email", label: "Enter an email address." }]}
18
+ />
19
+ <Input id="email" label="Email" error="Enter an email address." />
20
+ </form>
21
+ );
22
+ }
23
+ ```
24
+
25
+ This example shows a failed-submission state. The Form recovery story below demonstrates validation and moving focus to the summary after submission.
26
+
27
+ ## More examples
28
+
29
+ - [Recover after submission](https://kbui.kcb.pro/storybook/?path=/story/components-errorsummary--form-recovery): Run validation, focus the summary, and jump to invalid fields.
30
+
31
+ ## Reference
32
+
33
+ | Prop | Type | Default | Notes |
34
+ | -------------- | -------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------- |
35
+ | `items` | `readonly ErrorSummaryItem[]` | required | Ordered `{ id?, href, label }` entries linking to invalid fields |
36
+ | `title` | `ReactNode` | `"There is a problem"` | Heading text naming the alert region |
37
+ | `description` | `ReactNode` | unset | Optional recovery guidance above the error list |
38
+ | `headingLevel` | `2 \| 3 \| 4` | `2` | Heading rank for the summary title |
39
+ | `onItemSelect` | `(href: string, event: MouseEvent<HTMLAnchorElement>) => void` | unset | Called when a recovery link is clicked |
40
+ | `classNames` | `ClassNames<"title" \| "description" \| "list" \| "item" \| "link">` | unset | Classes for inner parts |
41
+
42
+ `ErrorSummary` renders an alert region with `tabIndex={-1}` so your submit handler can focus it when validation fails. Clicking an `#id` link focuses the matching control or the first enabled control inside a referenced group. Pair `ErrorSummary` with inline `error` props on each invalid field.
43
+
44
+ Error links keep their list markers. The list's `gap` controls spacing between items without added prose margins.
45
+
46
+ ## Related components
47
+
48
+ Keep inline errors on [`Input`](Input.md), [`Textarea`](Textarea.md), and other fields. Use [`FormActions`](FormActions.md) for the submit controls.
@@ -0,0 +1,42 @@
1
+ # Fieldset
2
+
3
+ Use `Fieldset` to group related controls into a named form section using native `fieldset` and `legend` semantics. Setting `disabled` disables descendant form controls natively.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-fieldset--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Fieldset, Input } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <Fieldset legend="Contact details" description="How we can reach you.">
16
+ <Input label="Email" type="email" name="email" />
17
+ </Fieldset>
18
+ );
19
+ }
20
+ ```
21
+
22
+ ## More examples
23
+
24
+ - [A group-level error](https://kbui.kcb.pro/storybook/?path=/story/components-fieldset--with-error): Explain a correction for a named group.
25
+ - [An unavailable group](https://kbui.kcb.pro/storybook/?path=/story/components-fieldset--disabled): Inspect disabled descendant controls.
26
+
27
+ ## Reference
28
+
29
+ | Prop | Type | Default | Notes |
30
+ | ---------------- | -------------------------------------------------------------- | -------- | ------------------------------------------------------ |
31
+ | `legend` | `ReactNode` | required | Section heading rendered inside the native `legend` |
32
+ | `visuallyHidden` | `boolean` | `false` | Hides the legend visually while keeping the group name |
33
+ | `description` | `ReactNode` | unset | Section help text linked through `aria-describedby` |
34
+ | `error` | `ReactNode` | unset | Group-level error linked through `aria-describedby` |
35
+ | `disabled` | `boolean` | `false` | Disables all descendant controls in the fieldset |
36
+ | `classNames` | `ClassNames<"legend" \| "description" \| "fields" \| "error">` | unset | Classes for inner parts |
37
+
38
+ Other native `fieldset` props and `ref` pass through to the `<fieldset>` element. Use `--kb-fieldset-gap`, `--kb-fieldset-fields-gap`, and `--kb-fieldset-legend-size` to tune spacing and legend typography.
39
+
40
+ ## Related components
41
+
42
+ Use [`Textarea`](Textarea.md) and [`Input`](Input.md) for answers, [`ErrorSummary`](ErrorSummary.md) for submission recovery, and [`FormActions`](FormActions.md) for the action row.
@@ -0,0 +1,74 @@
1
+ # FileInput
2
+
3
+ Use `FileInput` to choose files, review the selected list, and remove items. Your app decides which files to accept, keeps the `File` objects, and handles uploads. See [Retained file selection](https://github.com/KhallilB/kbui/blob/main/docs/guides/file-inputs.md) for examples, keyboard behavior, and styling. Available since v0.6.0.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-fileinput--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { FileInput, type FileInputItem } from "@kb.ui/react";
12
+ import { useState } from "react";
13
+
14
+ type Attachment = FileInputItem & { file: File };
15
+
16
+ export function Example() {
17
+ const [items, setItems] = useState<Attachment[]>([]);
18
+ return (
19
+ <FileInput
20
+ label="Attachments"
21
+ items={items}
22
+ onFiles={(files) =>
23
+ setItems((current) => [
24
+ ...current,
25
+ ...files.map((file) => ({
26
+ id: crypto.randomUUID(),
27
+ name: file.name,
28
+ file,
29
+ })),
30
+ ])
31
+ }
32
+ onRemove={(id) =>
33
+ setItems((current) => current.filter((item) => item.id !== id))
34
+ }
35
+ />
36
+ );
37
+ }
38
+ ```
39
+
40
+ The example retains each original `File` alongside its display metadata. Your app chooses acceptance rules and builds `FormData` for uploads; see [retained file selection](https://github.com/KhallilB/kbui/blob/main/docs/guides/file-inputs.md#choosing-and-removing-files).
41
+
42
+ ## More examples
43
+
44
+ - [Rejected selection feedback](https://kbui.kcb.pro/storybook/?path=/story/components-fileinput--rejected): Keep accepted items visible while explaining a rejection.
45
+ - [Image-picker hints](https://kbui.kcb.pro/storybook/?path=/story/components-fileinput--evidence): Compare image acceptance hints and helper text.
46
+ - [Item metadata](https://kbui.kcb.pro/storybook/?path=/story/components-fileinput--custom-content): Customize retained-file content without losing its identity.
47
+
48
+ ## Reference
49
+
50
+ | Prop | Type | Default | Notes |
51
+ | ---------------------------------------------------- | ------------------------------------ | ----------------------- | -------------------------------------------------------------------- |
52
+ | `label` | `string` | required | Visible field name and accessible picker context |
53
+ | `items` | `readonly FileInputItem[]` | required | Retained files with stable ids, names, and optional descriptions |
54
+ | `onFiles` | `(files: File[]) => void` | required | Check the selection and update retained files in your app |
55
+ | `onRemove` | `(id: string) => void` | required | Request removal; update items to confirm it |
56
+ | `accept` | `string` | unset | Native picker hint, such as image/*; does not validate files |
57
+ | `multiple` | `boolean` | `true` | Allow multiple selection; use a singular `chooseLabel` for single mode |
58
+ | `disabled`, `readOnly` | `boolean` | `false` | Prevent edits while keeping the retained list visible |
59
+ | `description`, `error` | `string` | unset | Help or actionable rejection text associated with the field |
60
+ | `visuallyHidden` | `boolean` | `false` | Hide the visual label while preserving its accessible name |
61
+ | `chooseLabel` | `string` | Choose files | Localized visible picker action |
62
+ | `emptyMessage` | `string` | No files added. | Localized empty-state text |
63
+ | `removeLabel` | `(item: FileInputItem) => string` | Remove + filename | Accessible remove action; keep the filename in the name |
64
+ | `removedMessage` | `(item: FileInputItem) => string` | filename + removed. | Announcement after removal is confirmed |
65
+ | `selectionMessage` | `(count: number) => string` | count + files selected. | Announcement after native selection |
66
+ | `renderItem` | `(item: FileInputItem) => ReactNode` | name + description | Custom item content; keep visible file identity |
67
+ | `inputRef`, `triggerRef` | element refs | unset | Hidden native `input` and visible picker access |
68
+ | `triggerClassName`, `listClassName`, `itemClassName` | `string` | unset | Classes for picker, retained list, and items |
69
+
70
+ Native `<div>` props, `ref` and `className` apply to the root. Root `aria-describedby` IDs follow the help and error IDs. Item button refs stay internal so removal can restore focus. Customize items through the item/content classes and `renderItem`; avoid changing individual item buttons. The `×` is decorative, and each removal button is named with the full filename.
71
+
72
+ ## Related components
73
+
74
+ Use [`Progress`](Progress.md) to show upload progress supplied by your app. File selection and uploading are separate steps.
@@ -0,0 +1,67 @@
1
+ # Form
2
+
3
+ Use `Form` for one task with one submit action, such as checkout, booking or sign-up. It renders a native `form` with three regions in reading order: an optional header, the fields, and an actions row. Fill the regions and the arrangement comes with them: a readable maximum width, even spacing between sections, and actions that fill the row on narrow screens. For pages of independently saved sections, use [`Settings`](Settings.md).
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/layout-form--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Button, Form, FormSection, Heading, Input } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <Form
16
+ aria-labelledby="booking-title"
17
+ onSubmit={(event) => event.preventDefault()}
18
+ header={
19
+ <Heading level={1} id="booking-title">
20
+ Book a room
21
+ </Heading>
22
+ }
23
+ actions={
24
+ <>
25
+ <Button type="submit">Confirm booking</Button>
26
+ <Button type="button" variant="ghost">
27
+ Back to rooms
28
+ </Button>
29
+ </>
30
+ }
31
+ >
32
+ <FormSection title="Dates">
33
+ <Input label="Check-in" type="date" name="checkIn" />
34
+ <Input label="Check-out" type="date" name="checkOut" />
35
+ </FormSection>
36
+ <FormSection title="Guest">
37
+ <Input label="Full name" name="name" autoComplete="name" />
38
+ </FormSection>
39
+ </Form>
40
+ );
41
+ }
42
+ ```
43
+
44
+ ## More examples
45
+
46
+ - [Hotel booking](https://kbui.kcb.pro/storybook/?path=/story/layout-form--hotel-booking): Dates, room type and extras in three sections, then one confirm action.
47
+ - [Sign up](https://kbui.kcb.pro/storybook/?path=/story/layout-form--sign-up): A short form at the narrow width, with plain fields and no sections.
48
+
49
+ ## Reference
50
+
51
+ | Prop | Type | Default | Notes |
52
+ | --- | --- | --- | --- |
53
+ | `header` | `ReactNode` | unset | Title and intro above the fields |
54
+ | `actions` | `ReactNode` | unset | Rendered in [`FormActions`](FormActions.md) with a divider; put the submit button first |
55
+ | `actionsAlign` | `"end" \| "start" \| "between"` | `"end"` | Alignment of the actions row at 30rem and wider |
56
+ | `width` | `"sm" \| "md" \| "full"` | `"md"` | Maximum inline size: 32rem, 40rem or none |
57
+ | `classNames` | `{ header?, body?, actions? }` | unset | Classes for the regions |
58
+
59
+ Other native form props and `ref` pass through. Children fill the body: [`FormSection`](FormSection.md) groups for longer tasks, or plain fields for short ones.
60
+
61
+ Below 30rem of row width, each button or link in the actions fills its own row in source order, so the submit button sits on top and every button is a full-width target. Tokens: `--kb-form-gap`, `--kb-form-width-sm` and `--kb-form-width-md`.
62
+
63
+ A form is a landmark only when it has a name; add `aria-label` or `aria-labelledby` when people should find it from the landmark list. Your app owns validation, [`ErrorSummary`](ErrorSummary.md) focus after a failed submit, pending state and success feedback.
64
+
65
+ ## Related components
66
+
67
+ Use [`Settings`](Settings.md) for independently saved sections, [`FormSection`](FormSection.md) to group fields and [`Container`](Container.md) for the page boundary around the form.
@@ -0,0 +1,45 @@
1
+ # FormActions
2
+
3
+ Use `FormActions` at the bottom of a form or section to align submit, reset, and secondary buttons with consistent wrapping and spacing. Buttons stay in natural Tab order without toolbar arrow-key navigation.
4
+
5
+ [All components](../../README.md#components) · [Usage](#usage) · [Examples](#more-examples) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-formactions--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Button, FormActions, Input } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <form onSubmit={(event) => event.preventDefault()}>
16
+ <Input label="Project name" name="project" />
17
+ <FormActions divider>
18
+ <Button type="submit">Save changes</Button>
19
+ <Button type="reset" variant="ghost">
20
+ Reset
21
+ </Button>
22
+ </FormActions>
23
+ </form>
24
+ );
25
+ }
26
+ ```
27
+
28
+ ## More examples
29
+
30
+ - [Separate the action row](https://kbui.kcb.pro/storybook/?path=/story/components-formactions--with-divider): Keep a boundary above the actions.
31
+ - [Primary and secondary groups](https://kbui.kcb.pro/storybook/?path=/story/components-formactions--split-alignment): Compare actions at opposite ends of the row.
32
+
33
+ ## Reference
34
+
35
+ | Prop | Type | Default | Notes |
36
+ | ---------- | ------------------------------- | ------- | -------------------------------------------------- |
37
+ | `align` | `"end" \| "start" \| "between"` | `"end"` | Horizontal button alignment |
38
+ | `divider` | `boolean` | `false` | Adds a top border and spacing above the action row |
39
+ | `children` | `ReactNode` | unset | Form buttons in reading and Tab order |
40
+
41
+ Other native `div` props and `ref` pass through. Use `--kb-formactions-gap` and `--kb-formactions-padding-top` to adjust spacing.
42
+
43
+ ## Related components
44
+
45
+ Use [`Fieldset`](Fieldset.md) for named groups and [`ErrorSummary`](ErrorSummary.md) for failed submission recovery. Use [`Toolbar`](Toolbar.md) when controls need arrow-key navigation.