@kb.ui/react 0.11.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.
Files changed (81) hide show
  1. package/README.md +79 -66
  2. package/dist/components/ConfirmAction/ConfirmAction.d.ts +42 -0
  3. package/dist/components/Dashboard/Dashboard.d.ts +17 -0
  4. package/dist/components/Form/Form.d.ts +19 -0
  5. package/dist/components/FormSection/FormSection.d.ts +26 -0
  6. package/dist/components/Gallery/Gallery.d.ts +26 -0
  7. package/dist/components/PageHeader/PageHeader.d.ts +27 -0
  8. package/dist/components/Panel/Panel.d.ts +3 -1
  9. package/dist/components/Settings/Settings.d.ts +11 -0
  10. package/dist/components/Skeleton/Skeleton.d.ts +8 -6
  11. package/dist/components/Stack/Stack.d.ts +15 -0
  12. package/dist/components/StatsRow/StatsRow.d.ts +33 -0
  13. package/dist/components/SupportingPane/SupportingPane.d.ts +15 -0
  14. package/dist/index.d.ts +10 -0
  15. package/dist/index.js +718 -333
  16. package/dist/index.js.map +1 -1
  17. package/dist/styles.css +1 -1
  18. package/docs/components/Accordion.md +9 -9
  19. package/docs/components/Avatar.md +4 -4
  20. package/docs/components/Badge.md +4 -4
  21. package/docs/components/Button.md +8 -8
  22. package/docs/components/Callout.md +3 -3
  23. package/docs/components/Card.md +4 -4
  24. package/docs/components/Checkbox.md +5 -5
  25. package/docs/components/Code.md +2 -2
  26. package/docs/components/CodeBlock.md +7 -7
  27. package/docs/components/Collection.md +5 -5
  28. package/docs/components/CollectionList.md +6 -6
  29. package/docs/components/CollectionRow.md +11 -11
  30. package/docs/components/Combobox.md +3 -3
  31. package/docs/components/ConfirmAction.md +100 -0
  32. package/docs/components/Container.md +2 -2
  33. package/docs/components/CopyableText.md +9 -9
  34. package/docs/components/Dashboard.md +81 -0
  35. package/docs/components/DescriptionList.md +3 -3
  36. package/docs/components/Dialog.md +7 -7
  37. package/docs/components/Disclosure.md +4 -4
  38. package/docs/components/EmptyState.md +1 -1
  39. package/docs/components/ErrorSummary.md +5 -3
  40. package/docs/components/Fieldset.md +6 -6
  41. package/docs/components/FileInput.md +5 -5
  42. package/docs/components/Form.md +67 -0
  43. package/docs/components/FormActions.md +3 -3
  44. package/docs/components/FormSection.md +57 -0
  45. package/docs/components/Gallery.md +84 -0
  46. package/docs/components/Grid.md +13 -13
  47. package/docs/components/Heading.md +3 -3
  48. package/docs/components/Image.md +3 -3
  49. package/docs/components/Inline.md +3 -3
  50. package/docs/components/Input.md +3 -3
  51. package/docs/components/Link.md +2 -2
  52. package/docs/components/Menu.md +5 -5
  53. package/docs/components/MultiSelect.md +2 -2
  54. package/docs/components/NumberField.md +5 -5
  55. package/docs/components/PageHeader.md +68 -0
  56. package/docs/components/Panel.md +11 -3
  57. package/docs/components/Popover.md +9 -9
  58. package/docs/components/Progress.md +1 -1
  59. package/docs/components/RadioGroup.md +3 -3
  60. package/docs/components/ScrollArea.md +1 -1
  61. package/docs/components/Select.md +2 -2
  62. package/docs/components/Separator.md +3 -3
  63. package/docs/components/Settings.md +57 -0
  64. package/docs/components/Skeleton.md +56 -16
  65. package/docs/components/Spinner.md +9 -4
  66. package/docs/components/Split.md +4 -4
  67. package/docs/components/Stack.md +54 -0
  68. package/docs/components/Stat.md +1 -1
  69. package/docs/components/StatsRow.md +80 -0
  70. package/docs/components/Status.md +7 -6
  71. package/docs/components/SupportingPane.md +59 -0
  72. package/docs/components/Switch.md +5 -5
  73. package/docs/components/Table.md +12 -12
  74. package/docs/components/Tabs.md +10 -10
  75. package/docs/components/Text.md +2 -2
  76. package/docs/components/Textarea.md +4 -4
  77. package/docs/components/Thumbnail.md +7 -7
  78. package/docs/components/Toast.md +9 -9
  79. package/docs/components/Toolbar.md +4 -4
  80. package/docs/components/Tooltip.md +3 -3
  81. package/package.json +1 -1
@@ -17,11 +17,16 @@ export function Example() {
17
17
 
18
18
  ## More examples
19
19
 
20
- - [Fancy variants and status pills](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--fancy-variants): Compare `ring`, `orbit`, `dots`, and `bars` indicators alongside elevated `pill` status framing.
21
- - [Visible status label](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--with-visible-label): Pair the animated arc with explicit text describing what is loading.
22
- - [Busy button submission](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--busy-button): Render a decorative spinner inside a disabled button during asynchronous submission.
20
+ - [Variants](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--variants): Compare the `ring`, `orbit`, `dots`, and `bars` indicators.
21
+ - [Pill](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--pill): Frame a spinner and its visible label as a compact status chip.
22
+ - [With label](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--with-label): Show the label next to the indicator so sighted users know what is loading.
23
+ - [Busy button](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--busy-button): Render a decorative spinner inside a disabled button during asynchronous submission.
23
24
  - [Sizes and tones](https://kbui.kcb.pro/storybook/?path=/story/components-spinner--sizes-and-tones): Match compact controls, inline status rows, or section-level waits.
24
25
 
26
+ ## Motion
27
+
28
+ The ring expands and contracts through a continuous sweep. Orbit combines two opposing sweeps around a breathing core; dots lift in sequence and bars run a staggered wave. Motion uses the existing `--kb-spinner-*` duration, easing, and stagger tokens. Reduced-motion preferences leave a static indicator and retain the status label.
29
+
25
30
  ## Reference
26
31
 
27
32
  | Prop | Type | Default | Notes |
@@ -37,4 +42,4 @@ export function Example() {
37
42
 
38
43
  ## Related components
39
44
 
40
- Use [Progress](Progress.md) when a numeric completion ratio exists, [Skeleton](Skeleton.md) to preserve layout geometry while loading content, and [Status](Status.md) for persistent state labels.
45
+ Use [`Progress`](Progress.md) when a numeric completion ratio exists, [`Skeleton`](Skeleton.md) to preserve layout geometry while loading content, and [`Status`](Status.md) for persistent state labels.
@@ -1,6 +1,6 @@
1
1
  # Split
2
2
 
3
- Two children form equal or weighted columns through layout-owned `.kb-split-track` wrappers. Below the available-width threshold, columns stack in source order. Layout uses CSS alone, including inside nested panels. Native props and matching ref pass through.
3
+ Use `Split` for two columns with equal or different widths. Each child sits in a `.kb-split-track` wrapper. When space is tight, the columns stack in source order. This uses CSS alone and also works inside nested panels. Native HTML props and the matching `ref` pass through.
4
4
 
5
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-split--docs)
6
6
 
@@ -36,12 +36,12 @@ export function Example() {
36
36
  | `as` | `div` `section` `article` | `div` |
37
37
  | `ratio` | `equal` (1:1) `wide-start` (2:1) `wide-end` (1:2) | `equal` |
38
38
  | `collapse` | `sm` (32rem) `md` (48rem) `lg` (64rem) | `md` |
39
- | `gap` | `none` `sm` `md` `lg`, same scale as Inline | `md` |
39
+ | `gap` | `none` `sm` `md` `lg`, same scale as `Inline` | `md` |
40
40
  | `align` | `start` `center` `end` `baseline` `stretch` | `stretch` |
41
41
  | `classNames` | `{ track?: string }`, applied to each column track | unset |
42
42
 
43
- Provide two children; empty conditional children add no track. Each track owns column sizing, so Text keeps its reading measure and nested token overrides stay local. Non-default generic native elements require an explicit `as`. Use Grid for variable child counts. See [Layout composition](https://github.com/KhallilB/kbui/blob/main/docs/guides/layout.md).
43
+ Provide two children, one per column. Empty conditional children add no track. The track controls column width, so `Text` keeps its line-length limit and nested token overrides affect only that nested layout. Set `as` explicitly when using an element other than the default. Use `Grid` when the number of children varies. See [Layout composition](https://github.com/KhallilB/kbui/blob/main/docs/guides/layout.md).
44
44
 
45
45
  ## Related components
46
46
 
47
- Use [Grid](Grid.md) for a variable number of children and [Container](Container.md) for the page boundary.
47
+ Use [`Grid`](Grid.md) for a variable number of children and [`Container`](Container.md) for the page boundary.
@@ -0,0 +1,54 @@
1
+ # Stack
2
+
3
+ Vertical flow with shared spacing: the block-axis counterpart to `Inline`. Children keep source and tab order; `Stack` adds no role, focus management or keyboard handling. Native props and matching ref pass through.
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-stack--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Button, Heading, Inline, Stack, Text } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <Stack as="section" aria-labelledby="billing-title">
16
+ <Heading level={2} size="md" id="billing-title">
17
+ Billing
18
+ </Heading>
19
+ <Text>Your plan renews on 1 December.</Text>
20
+ <Inline gap="sm">
21
+ <Button>Change plan</Button>
22
+ <Button variant="secondary">Download invoices</Button>
23
+ </Inline>
24
+ </Stack>
25
+ );
26
+ }
27
+ ```
28
+
29
+ ## More examples
30
+
31
+ - [Section rhythm](https://kbui.kcb.pro/storybook/?path=/story/layout-stack--sections): Nest sections with a wider outer gap.
32
+ - [Inline-axis alignment](https://kbui.kcb.pro/storybook/?path=/story/layout-stack--alignment): Compare stretched and content-width children.
33
+ - [Block-axis distribution](https://kbui.kcb.pro/storybook/?path=/story/layout-stack--justify): Push actions to the bottom of a fixed-height card.
34
+ - [Form fields](https://kbui.kcb.pro/storybook/?path=/story/layout-stack--form): Space fields and actions in a native form.
35
+ - [A native list](https://kbui.kcb.pro/storybook/?path=/story/layout-stack--list): Ordered steps without list chrome.
36
+
37
+ ## Reference
38
+
39
+ | Prop | Values | Default |
40
+ | --------- | ------------------------------------------------------------- | --------- |
41
+ | `as` | `div` `section` `article` `aside` `ul` `ol` `nav` `form` | `div` |
42
+ | `gap` | `none` `sm` (0.5rem) `md` (1rem) `lg` (1.5rem) | `md` |
43
+ | `align` | `start` `center` `end` `stretch` | `stretch` |
44
+ | `justify` | `start` `center` `end` `between` | `start` |
45
+
46
+ Non-default native elements require an explicit `as`; native props and refs follow that element. Explicit layout props own their data attributes even when caller attributes conflict.
47
+
48
+ `gap` owns vertical rhythm: `Stack` removes block margins from its direct children and its own browser margins, padding and list markers. `align="stretch"` fills the stack's width; `start`, `center` and `end` size children to their content. `justify` distributes children only when the stack is taller than its content, for example with `style={{ blockSize: "100%" }}` inside a fixed-height parent.
49
+
50
+ A named `section` exposes a region landmark; name it with `aria-labelledby`. With `ul` or `ol`, use `li` children. `Stack` removes list markers, so include `role="list"` when Safari must keep announcing the list; see [MDN’s list-style accessibility guidance](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/list-style#accessibility). Override `--kb-layout-gap-sm`, `-md` or `-lg` on a subtree to change the shared scale. See [Layout composition](https://github.com/KhallilB/kbui/blob/main/docs/guides/layout.md).
51
+
52
+ ## Related components
53
+
54
+ Use [`Inline`](Inline.md) for a wrapping row, [`Grid`](Grid.md) when items may share columns, and [`Split`](Split.md) for two columns that stack below a threshold.
@@ -31,4 +31,4 @@ export function Example() {
31
31
 
32
32
  ## Related components
33
33
 
34
- Use [Progress](Progress.md) when the number represents completion and [Status](Status.md) for changing state.
34
+ Use [`Progress`](Progress.md) when the number represents completion and [`Status`](Status.md) for changing state.
@@ -0,0 +1,80 @@
1
+ # StatsRow
2
+
3
+ Show a few comparable metrics in a row, such as the key figures at the top of a dashboard. The row fills its region and wraps into more rows when narrow.
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-statsrow--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Link, StatsRow } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <StatsRow aria-label="Store performance, September 2026">
16
+ <StatsRow.Item
17
+ label="Total revenue"
18
+ value="$48,250"
19
+ change="+12.8%"
20
+ trend="up"
21
+ tone="positive"
22
+ context="vs. previous month"
23
+ link={<Link href="/revenue">View revenue</Link>}
24
+ />
25
+ <StatsRow.Item
26
+ label="Orders"
27
+ value="625"
28
+ change="+8.7%"
29
+ trend="up"
30
+ tone="positive"
31
+ context="vs. previous month"
32
+ />
33
+ <StatsRow.Item
34
+ label="Refund requests"
35
+ value="38"
36
+ change="+12 requests"
37
+ trend="up"
38
+ tone="negative"
39
+ context="vs. previous month"
40
+ />
41
+ </StatsRow>
42
+ );
43
+ }
44
+ ```
45
+
46
+ Items share equal columns no narrower than `--kb-statsrow-item-min-width` (10rem) and fill the row. Below that width they wrap into more rows, so no screen size scrolls sideways. Labels, values, changes and links each share a track across a row, so a label that wraps to two lines keeps the values beside it aligned.
47
+
48
+ ## More examples
49
+
50
+ - [Outlined with links](https://kbui.kcb.pro/storybook/?path=/story/components-statsrow--outlined): Put each metric on a card surface and link to its detail screen.
51
+ - [Direction and tone](https://kbui.kcb.pro/storybook/?path=/story/components-statsrow--direction-and-tone): Set the direction glyph apart from whether the change is good news.
52
+ - [Compact wrap](https://kbui.kcb.pro/storybook/?path=/story/components-statsrow--wrap): See six metrics wrap at the widths of 390 and 768 pixel screens.
53
+
54
+ ## Reference
55
+
56
+ `StatsRow` renders a `ul`; other native `ul` props, including `aria-label` and `aria-labelledby`, pass through to it.
57
+
58
+ | Prop | Type | Default | Notes |
59
+ | ------------ | --------------------- | ------- | --------------------------------------------------------- |
60
+ | `appearance` | `plain` / `outlined` | `plain` | Plain metrics on the page, or each metric on a card surface |
61
+ | `children` | `StatsRow.Item` nodes | unset | One item per metric |
62
+
63
+ `StatsRow.Item` renders an `li` around a [`Stat`](Stat.md); other native `li` props pass through to it.
64
+
65
+ | Prop | Type | Default | Notes |
66
+ | ------------ | ----------------------------------- | --------- | --------------------------------------------------------------------------- |
67
+ | `label` | `ReactNode` | required | What the value measures; read first |
68
+ | `value` | `ReactNode` | required | The figure with its unit; tabular figures |
69
+ | `change` | `ReactNode` | unset | Change since the comparison period; its text states the direction, such as `+12.8%` |
70
+ | `trend` | `up` / `down` / `flat` | unset | Direction glyph before `change`; hidden from assistive technology; needs `change` |
71
+ | `tone` | `positive` / `negative` / `neutral` | `neutral` | Colors `change` by whether it is good news, apart from its direction; needs `change` |
72
+ | `context` | `ReactNode` | unset | Comparison period or freshness, such as `vs. previous month` |
73
+ | `link` | `ReactNode` | unset | `Link` to the detail behind the metric; aligned on the last row of the item |
74
+ | `classNames` | keyed classes | unset | Style `stat`, `label`, `value`, `trend`, `change`, `glyph`, `context`, `link` |
75
+
76
+ Keep units comparable across a row: one currency, the same precision and one comparison period. Write the direction into the change text; color and the glyph do not convey it on their own. Tone is color only, so when good or bad news is not obvious from the label, say it in the change or context text, such as `+12 requests, above target`.
77
+
78
+ ## Related components
79
+
80
+ Use [`Stat`](Stat.md) for a single figure, [`Progress`](Progress.md) when a metric measures completion toward a target, [`DescriptionList`](DescriptionList.md) for labelled record details that are not comparable figures, and [`Grid`](Grid.md) for collections of cards that are not metrics.
@@ -1,6 +1,6 @@
1
1
  # Status
2
2
 
3
- Use Status for a state such as running, blocked, or complete. Always include text so the meaning is clear without relying on color or an icon.
3
+ Use `Status` for a state such as running, blocked, or complete. Always include text so the meaning is clear without relying on color or an icon.
4
4
 
5
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-status--docs)
6
6
 
@@ -21,9 +21,10 @@ export function Example() {
21
21
 
22
22
  ## More examples
23
23
 
24
- - [Changing state](https://kbui.kcb.pro/storybook/?path=/story/components-status--live): Inspect the status announcement contract.
24
+ - [Changing state](https://kbui.kcb.pro/storybook/?path=/story/components-status--live): Check how status updates are announced.
25
25
  - [Supporting iconography](https://kbui.kcb.pro/storybook/?path=/story/components-status--with-icon): Keep meaning in text when an icon is present.
26
- - [A compact state label](https://kbui.kcb.pro/storybook/?path=/story/components-status--chip): Compare a contained appearance.
26
+ - [A compact state label](https://kbui.kcb.pro/storybook/?path=/story/components-status--chip): Compare a contained appearance; the icon leads the chip.
27
+ - [A chip without an icon](https://kbui.kcb.pro/storybook/?path=/story/components-status--chip-without-icon): The chip leads with a dot in the tone's color.
27
28
 
28
29
  ## Reference
29
30
 
@@ -38,10 +39,10 @@ export function Example() {
38
39
  | `children` | `ReactNode` | unset | State text such as Running or Blocked; keep it meaningful without color |
39
40
  | `tone` | `neutral` / `info` / `running` / `success` / `warning` / `blocked` | `neutral` | Reinforces the written state |
40
41
  | `appearance` | `plain` / `chip` | `plain` | Plain stays inline; chip adds separation with a tinted surface |
41
- | `icon` | `ReactNode` | unset | Optional decorative icon; the text still names the state |
42
- | `live` | `boolean` | `false` | Adds role=status for changing text; does not move focus |
42
+ | `icon` | `ReactNode` | unset | Decorative; the text still names the state. Replaces a chip's dot |
43
+ | `live` | `boolean` | `false` | Adds `role=status` for changing text; does not move focus |
43
44
  | `compact` | `boolean` | `false` | Tighter spacing and smaller text for dense layouts |
44
45
 
45
46
  ## Related components
46
47
 
47
- Use [Badge](Badge.md) for static metadata, [Progress](Progress.md) for completion, and [Callout](Callout.md) for a fuller message.
48
+ Use [`Badge`](Badge.md) for static metadata, [`Progress`](Progress.md) for completion, and [`Callout`](Callout.md) for a fuller message.
@@ -0,0 +1,59 @@
1
+ # SupportingPane
2
+
3
+ Use `SupportingPane` for a page with one main task and supporting context beside it, such as a cart with its order summary or a record list with an inspector. It renders a main region and a named `aside` landmark. From 48rem of page content width the aside sits beside main at a fixed width while main fills the rest; below that it moves under main. It also frames the page: full width up to 80rem, centred, with 1, 1.5 and 2rem gutters. For two equal columns inside a section, 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-supportingpane--docs)
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import "@kb.ui/react/styles.css";
11
+ import { Button, Card, Heading, PageHeader, SupportingPane, Text } from "@kb.ui/react";
12
+
13
+ export function Example() {
14
+ return (
15
+ <main>
16
+ <SupportingPane
17
+ asideLabelledBy="summary-title"
18
+ aside={
19
+ <Card as="div">
20
+ <Heading level={2} id="summary-title">
21
+ Order summary
22
+ </Heading>
23
+ <Text>Total $245.75</Text>
24
+ <Button>Continue to payment</Button>
25
+ </Card>
26
+ }
27
+ >
28
+ <PageHeader title="Your cart" description="Your sneakers are reserved for 15 minutes." />
29
+ <Text>2 items</Text>
30
+ </SupportingPane>
31
+ </main>
32
+ );
33
+ }
34
+ ```
35
+
36
+ ## More examples
37
+
38
+ - [Shoe cart](https://kbui.kcb.pro/storybook/?path=/story/layout-supportingpane--shoe-cart): Items, free-shipping progress and help in main; the order summary beside them, or below them on narrow screens.
39
+ - [Inspector](https://kbui.kcb.pro/storybook/?path=/story/layout-supportingpane--inspector): An order list with the selected order's details in the aside.
40
+
41
+ ## Reference
42
+
43
+ | Prop | Type | Default | Notes |
44
+ | --- | --- | --- | --- |
45
+ | `children` | `ReactNode` | unset | Main region content, starting with the page heading |
46
+ | `aside` | `ReactNode` | unset | Supporting content; omit it and main fills the page |
47
+ | `asideLabelledBy` | `string` | unset | Id of a visible heading inside the aside that names it |
48
+ | `asideLabel` | `string` | unset | Accessible name for the aside when it has no visible heading |
49
+ | `classNames` | `{ main?, aside? }` | unset | Classes for the regions |
50
+
51
+ Other native `div` props and `ref` pass through to the root. Main comes first in source order and the aside second at every width; nothing is reordered. Each region stacks its children with the pane's gap, so main content needs no extra wrapper.
52
+
53
+ Tokens: `--kb-supportingpane-max-width`, `--kb-supportingpane-gutter-sm`, `-md`, `-lg`, `--kb-supportingpane-gap` and `--kb-supportingpane-aside-width`. Gutters step at 48rem and 64rem of viewport width; the aside moves beside main at 48rem of the pane's own content width, so a pane inside a narrow parent stays stacked.
54
+
55
+ Place `SupportingPane` inside your page's `main` and start main content with the page's `h1`, such as a [`PageHeader`](PageHeader.md). Name the aside, preferably from its visible heading; the complementary landmark is allowed inside main. The aside does not stick or hide; your app owns any show and hide control and its focus.
56
+
57
+ ## Related components
58
+
59
+ Use [`PageHeader`](PageHeader.md) to open main, [`Card`](Card.md) to group the aside, and [`Split`](Split.md) for proportional columns inside a section.
@@ -1,6 +1,6 @@
1
1
  # Switch
2
2
 
3
- Use Switch for a preference that takes effect as soon as it changes. Pass `checked` and update it in `onCheckedChange`; your app handles saving and form reset. Switch uses a labelled native checkbox with `role="switch"`. Use Checkbox when people are selecting items instead.
3
+ Use `Switch` for a preference that takes effect as soon as it changes. Pass `checked` and update it in `onCheckedChange`; your app handles saving and form reset. `Switch` uses a labelled native checkbox with `role="switch"`. Use `Checkbox` when people are selecting items instead.
4
4
 
5
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-switch--docs)
6
6
 
@@ -40,13 +40,13 @@ export function Example() {
40
40
  | `tone` | `"accent" \| "neutral" \| "info" \| "success" \| "warning" \| "danger"` | `"accent"` | Checked-state track tone when `onTone` is unset |
41
41
  | `offTone` / `onTone` | `SwitchTone` | `"neutral"` / `tone` | Independent track tone for unchecked and checked sides |
42
42
  | `offColor` / `onColor` | `string` | | Custom CSS color for the unchecked or checked track |
43
- | `description` / `error` | `string` | | Associated helper/error text; error sets aria-invalid |
43
+ | `description` / `error` | `string` | | Associated helper/error text; error sets `aria-invalid` |
44
44
  | `disabled` / `readOnly` | `boolean` | `false` | Disabled blocks focus/changes; read-only keeps focus and form value while blocking edits |
45
45
  | `visuallyHidden` | `boolean` | `false` | Hide label visually, keep its accessible name |
46
46
  | `offIcon` / `onIcon` | `ReactNode` | | Decorative slots; do not place interactive content inside |
47
- | `name` / `value` / `form` / `required` | native input props | | Native form ownership, successful value and validation |
47
+ | `name` / `value` / `form` / `required` | native `input` props | | Native form ownership, successful value and validation |
48
48
  | `ref` | `Ref<HTMLInputElement>` | | Native checkbox, never an extra hidden control |
49
- | `className` / `controlClassName` | `string` | | Root/native input class |
49
+ | `className` / `controlClassName` | `string` | | Root/native `input` class |
50
50
  | `style` | `CSSProperties` | | Native input styles; CSS custom properties also reach visible track and thumb |
51
51
 
52
52
  ```tsx
@@ -70,4 +70,4 @@ Import `useState` from React and `Switch` from `@kb.ui/react`. Clicking or press
70
70
 
71
71
  ## Related components
72
72
 
73
- Use [Checkbox](Checkbox.md) for a choice submitted with other answers and [RadioGroup](RadioGroup.md) for one of several settings.
73
+ Use [`Checkbox`](Checkbox.md) for a choice submitted with other answers and [`RadioGroup`](RadioGroup.md) for one of several settings.
@@ -48,7 +48,7 @@ export function Example() {
48
48
  ## More examples
49
49
 
50
50
  - [Sorting and selection](https://kbui.kcb.pro/storybook/?path=/story/components-table--sorting-and-selection): Numeric and text ordering, stable selected IDs, mixed selection and excluded rows.
51
- - [Row actions](https://kbui.kcb.pro/storybook/?path=/story/components-table--sorting-and-selection): Named Buttons and Menu composition with focus return.
51
+ - [Row actions](https://kbui.kcb.pro/storybook/?path=/story/components-table--sorting-and-selection): Named Buttons and `Menu` composition with focus return.
52
52
  - [Dense and sticky](https://kbui.kcb.pro/storybook/?path=/story/components-table--dense-sticky): Bounded scrolling, sticky headers and a pinned first column.
53
53
 
54
54
  ## Reference
@@ -63,14 +63,14 @@ export function Example() {
63
63
  | `Table.ColumnHeader` | `th`, optional `button` | Defaults `scope="col"`; controlled sorting and logical alignment |
64
64
  | `Table.RowHeader` | `th` | Defaults `scope="row"`; supports grouped header scope override |
65
65
  | `Table.Cell` | `td` | Native data cell; supports `colSpan`, `rowSpan`, children and ref |
66
- | `Table.SelectionCheckbox` | Checkbox | Same required `label`, `checked`, `onCheckedChange`, optional `indeterminate`, `disabled`, `readOnly`, ref and slots as Checkbox |
67
- | `Table.RowActions` | `div` | Wrapping, end-aligned actions; compose named Buttons, links or Menu |
66
+ | `Table.SelectionCheckbox` | `Checkbox` | Same required `label`, `checked`, `onCheckedChange`, optional `indeterminate`, `disabled`, `readOnly`, ref and slots as `Checkbox` |
67
+ | `Table.RowActions` | `div` | Wrapping, end-aligned actions; compose named Buttons, links or `Menu` |
68
68
 
69
69
  | Prop | Applies to | Default | Behavior |
70
70
  |---|---|---|---|
71
- | `density` | Table | `comfortable` | `comfortable` or `dense`; controls cell spacing, preserves control targets |
72
- | `layout` | Table | `auto` | `auto` or `fixed`; with fixed layout supply widths through native `colgroup`/`col` or styles |
73
- | `stickyHeader` | Table | false | Pins the complete head, including grouped header rows, to the scroll boundary |
71
+ | `density` | `Table` | `comfortable` | `comfortable` or `dense`; controls cell spacing, preserves control targets |
72
+ | `layout` | `Table` | `auto` | `auto` or `fixed`; with fixed layout supply widths through native `colgroup`/`col` or styles |
73
+ | `stickyHeader` | `Table` | false | Pins the complete head, including grouped header rows, to the scroll boundary |
74
74
  | `align` | Cell, ColumnHeader, RowHeader | `start` | Logical `start`, `center`, `end`; works with `dir="rtl"` |
75
75
  | `sticky` | Cell, ColumnHeader, RowHeader | unset | Pins one `start` or `end` edge cell; match the same edge across rows |
76
76
  | `sortDirection` | ColumnHeader | `none` | `none`, `ascending`, `descending`; explicit direction owns `aria-sort`, otherwise native `aria-sort` passes through |
@@ -84,22 +84,22 @@ Every part accepts its native element attributes, `style`, `className` and ref.
84
84
 
85
85
  Sortable headings use the full cell as the button target. Unsorted headings show paired arrows; the applied order uses one arrow with stronger ink. Keep headings readable with native column widths and a bounded scroll container. Fixed-layout sortable headings wrap within their assigned columns. Reserve a compact checkbox column, align numeric headings with their values, and keep row action labels short while supplying record-specific accessible names. The sorting example places its title, instructions and selection count outside scrolling data, with visible text explaining unavailable selection.
86
86
 
87
- Sort a copy of your data or request server ordering. Keep the column and direction together; reset other headers to `none` so only one header announces an active sort. For server requests, handle stale responses in your app, keep applied order authoritative, set `sortDisabled` while pending, and announce progress through a status message outside an `aria-busy` body. Table does not mutate or fetch records. It does not implement multiple simultaneous sort keys.
87
+ Sort a copy of your data or request server ordering. Keep the column and direction together; reset other headers to `none` so only one header announces an active sort. For server requests, handle stale responses in your app, keep applied order authoritative, set `sortDisabled` while pending, and announce progress through a status message outside an `aria-busy` body. `Table` does not mutate or fetch records. It does not implement multiple simultaneous sort keys.
88
88
 
89
89
  Keep selection by stable ID rather than visible row index. Define whether select-all covers the current page, filtered results or all records; label that scope explicitly. Compute mixed/all state from eligible rows only, exclude disabled rows, and disable select-all when no rows are eligible. Decide how removed records and page changes affect selection. `Table.Row selected` provides styling; selection controls own the accessible state. Row actions have their own names and normal Tab order, and do not toggle selection implicitly.
90
90
 
91
91
  ### Layout and feedback
92
92
 
93
- Place the table inside `Table.ScrollContainer` for horizontal overflow or a bounded vertical viewport. Its region is keyboard focusable; `maxHeight` limits height. On focus, the React container reveals controls hidden beneath sticky headers or pinned edges without moving keyboard focus. Keep enough free viewport space for the action; a pinned column wider than the viewport cannot expose adjacent cells. Supply a readable minimum table width with `style` when columns should scroll rather than wrap. A table can also render directly when page scrolling is sufficient. To keep the table title fixed on both scroll axes, render a Heading outside ScrollContainer and name the table through `aria-labelledby`, as in Dense and sticky. Native Table.Caption remains part of the scrollable table. Column headings stay fixed vertically with stickyHeader and scroll horizontally with their data columns.
93
+ Place the table inside `Table.ScrollContainer` for horizontal overflow or a bounded vertical viewport. Its region is keyboard focusable; `maxHeight` limits height. On focus, the React container reveals controls hidden beneath sticky headers or pinned edges without moving keyboard focus. Keep enough free viewport space for the action; a pinned column wider than the viewport cannot expose adjacent cells. In auto layout, headings and cells keep whole words, so a table narrower than its longest words scrolls instead of breaking them; supply a minimum table width with `style` when columns need more room. Fixed layout breaks long words within its assigned columns. A table can also render directly when page scrolling is sufficient. To keep the table title fixed on both scroll axes, render a `Heading` outside `ScrollContainer` and name the table through `aria-labelledby`, as in Dense and sticky. Native `Table.Caption` remains part of the scrollable table. Column headings stay fixed vertically with `stickyHeader` and scroll horizontally with their data columns.
94
94
 
95
- Sticky edges support one cell on each edge. For several pinned columns, calculate non-overlapping offsets in your own styles; Table does not assign column offsets. Keep sufficient viewport space for unpinned cells. Header/body column widths must match. Set `dir="rtl"` on the application or ScrollContainer as well as the table when the scroll direction should follow RTL; the stories expose a direction control. Nested tables keep their own density and section surfaces. Native `colSpan`, `rowSpan`, `scope="colgroup"` and explicit `id`/`headers` relationships support grouped headers. Sticky and selected cell backgrounds stay opaque in both themes; restyled background tokens must remain opaque.
95
+ Sticky edges support one cell on each edge. For several pinned columns, calculate non-overlapping offsets in your own styles; `Table` does not assign column offsets. Keep sufficient viewport space for unpinned cells. Header/body column widths must match. Set `dir="rtl"` on the application or ScrollContainer as well as the table when the scroll direction should follow RTL; the stories expose a direction control. Nested tables keep their own density and section surfaces. Native `colSpan`, `rowSpan`, `scope="colgroup"` and explicit `id`/`headers` relationships support grouped headers. Sticky and selected cell backgrounds stay opaque in both themes; restyled background tokens must remain opaque.
96
96
 
97
- Render empty or error feedback in a row containing a `Table.Cell colSpan={columnCount}`; supply retry as a named Button if appropriate. Use a separate status for asynchronous updates. Table preserves semantic HTML and ordinary Tab navigation; arrow-key cell navigation, pagination, filtering, virtualization and record management remain app-owned. For very large sets, paginate in your app rather than assuming all rows are virtualized.
97
+ Render empty or error feedback in a row containing a `Table.Cell colSpan={columnCount}`; supply retry as a named `Button` if appropriate. Use a separate status for asynchronous updates. `Table` preserves semantic HTML and ordinary Tab navigation; arrow-key cell navigation, pagination, filtering, virtualization and record management remain app-owned. For very large sets, paginate in your app rather than assuming all rows are virtualized.
98
98
 
99
99
  Adjust `--kb-table-cell-padding-block`, `--kb-table-cell-padding-inline`, `--kb-table-dense-padding-block`, `--kb-table-background`, `--kb-table-header-background`, `--kb-table-selected-background`, `--kb-table-border`, `--kb-table-radius` and `--kb-table-sort-target` through normal CSS. Keep focus visible and dense action targets usable. See [accessibility verification](../../../../docs/guides/accessibility.md) for manual keyboard, screen-reader, zoom, spacing and contrast checks. Automated stories do not establish screen-reader interoperability or page conformance.
100
100
 
101
101
  ## Related components
102
102
 
103
- Use [DescriptionList](DescriptionList.md) for labeled facts about one record and [CollectionList](CollectionList.md) with [CollectionRow](CollectionRow.md) for records with variable details. The [Structured data guide](../../../../docs/guides/structured-data.md) compares these choices.
103
+ Use [`DescriptionList`](DescriptionList.md) for labeled facts about one record and [`CollectionList`](CollectionList.md) with [`CollectionRow`](CollectionRow.md) for records with variable details. The [Structured data guide](../../../../docs/guides/structured-data.md) compares these choices.
104
104
 
105
- Use [Checkbox](Checkbox.md) for independent selection, [Menu](Menu.md) for overflow actions, [Button](Button.md) for immediate actions, and [Status](Status.md) for meaningful asynchronous feedback. Use [Grid](Grid.md) for visual page layout rather than tabular relationships.
105
+ Use [`Checkbox`](Checkbox.md) for independent selection, [`Menu`](Menu.md) for overflow actions, [`Button`](Button.md) for immediate actions, and [`Status`](Status.md) for meaningful asynchronous feedback. Use [`Grid`](Grid.md) for visual page layout rather than tabular relationships.
@@ -1,6 +1,6 @@
1
1
  # Tabs
2
2
 
3
- Switch between peer panels within one page. Use links for navigation to another URL and RadioGroup for a single form choice.
3
+ Switch between peer panels within one page. Use links for navigation to another URL and `RadioGroup` for a single form choice.
4
4
 
5
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-tabs--docs)
6
6
 
@@ -31,7 +31,7 @@ export function Example() {
31
31
  - [Vertical settings](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--vertical): Up/Down navigation beside settings content.
32
32
  - [Retained settings draft](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--retained-draft): Manual activation retains an input while its panel is hidden.
33
33
 
34
- - [Nested panels](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--nested): Each Tabs root owns its orientation, density and variant.
34
+ - [Nested panels](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--nested): Each `Tabs` root owns its orientation, density and variant.
35
35
 
36
36
  ## Reference
37
37
 
@@ -43,7 +43,7 @@ export function Example() {
43
43
  | `Tabs.Indicator` | Optional explicit active indicator inside the list |
44
44
  | `Tabs.Panel` | Content associated with a matching trigger |
45
45
 
46
- | Tabs prop | Type | Default | Purpose |
46
+ | `Tabs` prop | Type | Default | Purpose |
47
47
  | --- | --- | --- | --- |
48
48
  | `value` | `string \| number \| null` | — | Controlled selection; null selects no panel |
49
49
  | `defaultValue` | `string \| number \| null` | First enabled tab | Initial uncontrolled selection; null selects none |
@@ -52,7 +52,7 @@ export function Example() {
52
52
  | `variant` | `"line" \| "pill"` | `"line"` | Underline or raised active surface |
53
53
  | `size` | `"sm" \| "md"` | `"md"` | Trigger density |
54
54
  | `className` | `string` | — | Root class |
55
- | `classNames` | `ClassNames<TabsClassKey>` | — | root, list, tab, tabIcon, tabLabel, tabBadge, indicator, panel |
55
+ | `classNames` | `ClassNames<TabsClassKey>` | — | root, list, tab, `tabIcon`, `tabLabel`, `tabBadge`, indicator, panel |
56
56
 
57
57
  | Part prop | Type | Default | Purpose |
58
58
  | --- | --- | --- | --- |
@@ -66,24 +66,24 @@ export function Example() {
66
66
  | `Tabs.Panel.value` | `string \| number` | Required | Matching trigger value |
67
67
  | `Tabs.Panel.keepMounted` | `boolean` | `false` | Retain hidden DOM and local draft state |
68
68
 
69
- All parts forward refs, native element props and Base UI composition props; `className` accepts a string. Keep triggers and panels inside their Tabs root. Put an explicit indicator directly inside Tabs.List, or set showIndicator to false when supplying a custom composition. Use unique values within each root and avoid interactive elements inside tab labels or badges.
69
+ All parts forward refs, native element props and Base UI composition props; `className` accepts a string. Keep triggers and panels inside their `Tabs` root. Put an explicit indicator directly inside `Tabs.List`, or set `showIndicator` to false when supplying a custom composition. Use unique values within each root and avoid interactive elements inside tab labels or badges.
70
70
 
71
71
  ## Selection and focus
72
72
 
73
73
  Base UI owns selection, tab/panel relationships and roving focus. Tab enters the selected trigger; Left/Right moves horizontal focus, Up/Down moves vertical focus, and Home/End reaches the first/last trigger. Disabled tabs can receive arrow-key focus but cannot be selected. Automatic activation selects enabled tabs while moving; manual activation requires Enter or Space. Controlled values change only when the parent updates them. A null value selects no tab.
74
74
 
75
- Uncontrolled roots recover to an enabled tab when the selected tab is removed or disabled, reporting the reason through onValueChange. Controlled recovery belongs to the parent. User selection can be cancelled through details.cancel(); automatic fallback cannot. Applications own fetching, loading feedback and content availability. Prefer manual activation for panels that require loading.
75
+ Uncontrolled roots recover to an enabled tab when the selected tab is removed or disabled, reporting the reason through `onValueChange`. Controlled recovery belongs to the parent. User selection can be cancelled through details.cancel(); automatic fallback cannot. Applications own fetching, loading feedback and content availability. Prefer manual activation for panels that require loading.
76
76
 
77
- Inactive panels unmount by default. keepMounted preserves their DOM and draft state while hiding them from reading and keyboard navigation; hidden components can still run effects. Default values must match a tab when selecting a particular initial panel.
77
+ Inactive panels unmount by default. `keepMounted` preserves their DOM and draft state while hiding them from reading and keyboard navigation; hidden components can still run effects. Default values must match a tab when selecting a particular initial panel.
78
78
 
79
79
  ## Styling and accessibility
80
80
 
81
- Each part receives its nearest root’s `data-variant`, `data-size` and `data-orientation`, so nested roots retain independent styling. Use the documented classes and component tokens: --kb-tabs-radius, --kb-tabs-list-padding, --kb-tabs-tab-height-sm, --kb-tabs-tab-height-md, --kb-tabs-indicator-thickness and --kb-tabs-panel-padding. The tab list scrolls horizontally when labels exceed available width. Vertical layouts need enough room for labels and content; applications can choose horizontal orientation at narrow widths.
81
+ Each part receives its nearest root’s `data-variant`, `data-size` and `data-orientation`, so nested roots retain independent styling. Use the documented classes and component tokens: `--kb-tabs-radius`, `--kb-tabs-list-padding`, `--kb-tabs-tab-height-sm`, `--kb-tabs-tab-height-md`, `--kb-tabs-indicator-thickness` and `--kb-tabs-panel-padding`. The tab list scrolls horizontally when labels exceed available width. Vertical tabs place the list beside the panel from 48rem of their own width; at narrower widths, the panel moves beneath the list.
82
82
 
83
83
  For right-to-left interfaces, combine HTML `dir="rtl"` with Base UI `DirectionProvider direction="rtl"` so keyboard direction matches layout.
84
84
 
85
- Name Tabs.List with aria-label or aria-labelledby. Keep tab labels descriptive and use associated panels for peer views. Verify selected versus focused states, hidden panel controls, long labels, both themes, forced colors and enlarged text. Browser automation covers tested keyboard and accessibility fixtures; manual screen-reader and browser-zoom checks remain pending. See [shared verification](../../../../docs/guides/accessibility.md) and the informative [WAI-ARIA tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).
85
+ Name `Tabs.List` with `aria-label` or `aria-labelledby`. Keep tab labels descriptive and use associated panels for peer views. Verify selected versus focused states, hidden panel controls, long labels, both themes, forced colors and enlarged text. Browser automation covers tested keyboard and accessibility fixtures; manual screen-reader and browser-zoom checks remain pending. See [shared verification](../../../../docs/guides/accessibility.md) and the informative [WAI-ARIA tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).
86
86
 
87
87
  ## Related components
88
88
 
89
- Use [RadioGroup](RadioGroup.md) for a form choice and [Toolbar](Toolbar.md) for grouped actions.
89
+ Use [`RadioGroup`](RadioGroup.md) for a form choice and [`Toolbar`](Toolbar.md) for grouped actions.
@@ -29,8 +29,8 @@ export function Example() {
29
29
  | `tone` | `default` \| `muted` | `default` | Primary ink or readable secondary ink |
30
30
  | `className`, `ref` | Native element props | unset | Ref type follows chosen element |
31
31
 
32
- Body line height is 1.6; block content is bounded to 65ch by `--kb-text-measure`. Text has no margin. Inline spans keep natural flow. Use native `strong` and `em` for meaningful emphasis. Do not nest paragraphs or place block children inside the default paragraph.
32
+ Body text has a line height of 1.6 and a 65ch line-length limit set by `--kb-text-measure`. `Text` adds no margin. Inline spans stay in the flow of the sentence. Use native `<strong>` and `<em>` for emphasis. Keep paragraphs and other block elements outside the default paragraph.
33
33
 
34
34
  ## Related components
35
35
 
36
- Use [Heading](Heading.md) for hierarchy, [Link](Link.md) for navigation, and [Code](Code.md) for literal code.
36
+ Use [`Heading`](Heading.md) for hierarchy, [`Link`](Link.md) for navigation, and [`Code`](Code.md) for literal code.
@@ -1,6 +1,6 @@
1
1
  # Textarea
2
2
 
3
- Use Textarea for multiline notes, summaries, or configuration payloads. It pairs a native textarea with a persistent label, optional help text, and validation feedback.
3
+ Use `Textarea` for multiline notes, summaries, or configuration payloads. It pairs a native `textarea` with a persistent label, optional help text, and validation feedback.
4
4
 
5
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-textarea--docs)
6
6
 
@@ -35,13 +35,13 @@ export function Example() {
35
35
  | `visuallyHidden` | `boolean` | `false` | Hides the label visually while keeping its accessible name |
36
36
  | `description` | `string` | unset | Supporting help text below the control |
37
37
  | `error` | `string` | unset | Validation message; marks the control invalid |
38
- | `rows` | `number` | `4` | Initial visible line count on the native textarea |
38
+ | `rows` | `number` | `4` | Initial visible line count on the native `textarea` |
39
39
  | `resize` | `"vertical" \| "none" \| "both"` | `"vertical"` | Controls user drag-resizing axis |
40
40
  | `onValueChange` | `(value: string) => void` | unset | Called with the next string value on change |
41
41
  | `classNames` | `ClassNames<"label" \| "control" \| "description" \| "error">` | unset | Classes for inner parts |
42
42
 
43
- Other native textarea props (`value`, `defaultValue`, `onChange`, `placeholder`, `disabled`, `readOnly`, `required`, `name`, `form`, `ref`) pass through to the `<textarea>` element. Adjust minimum height and padding with `--kb-textarea-min-height`, `--kb-textarea-padding-block`, and `--kb-textarea-padding-inline`.
43
+ Other native `textarea` props (`value`, `defaultValue`, `onChange`, `placeholder`, `disabled`, `readOnly`, `required`, `name`, `form`, `ref`) pass through to the `<textarea>` element. Adjust minimum height and padding with `--kb-textarea-min-height`, `--kb-textarea-padding-block`, and `--kb-textarea-padding-inline`.
44
44
 
45
45
  ## Related components
46
46
 
47
- Use [Input](Input.md) for a single-line value and [Fieldset](Fieldset.md) to group related answers.
47
+ Use [`Input`](Input.md) for a single-line value and [`Fieldset`](Fieldset.md) to group related answers.
@@ -1,6 +1,6 @@
1
1
  # Thumbnail
2
2
 
3
- Pair stable image frames with visible titles and metadata for products, studies and attachments. Compose figures into responsive collections with Grid.
3
+ Pair stable image frames with visible titles and metadata for products, studies and attachments. Compose figures into responsive collections with `Grid`.
4
4
 
5
5
  [All components](../../README.md#components) · [Usage](#usage) · [Reference](#reference) · [Live examples and accessibility](https://kbui.kcb.pro/storybook/?path=/docs/components-thumbnail--docs)
6
6
 
@@ -42,7 +42,7 @@ export function Example() {
42
42
 
43
43
  - [Products](https://kbui.kcb.pro/storybook/?path=/story/components-thumbnail--products): Responsive product cards and absent photography.
44
44
  - [Attachments](https://kbui.kcb.pro/storybook/?path=/story/components-thumbnail--attachments): Persistent filenames, formats and file sizes.
45
- - [Gallery](https://kbui.kcb.pro/storybook/?path=/story/components-thumbnail--gallery): Keyboard-operable Dialog inspection and focus return.
45
+ - [Gallery](https://kbui.kcb.pro/storybook/?path=/story/components-thumbnail--gallery): Keyboard-operable `Dialog` inspection and focus return.
46
46
 
47
47
  ## Reference
48
48
 
@@ -50,17 +50,17 @@ export function Example() {
50
50
  | --- | --- | --- | --- |
51
51
  | `alt` | `string` | required | Meaningful visual alternative; empty when decorative |
52
52
  | `src` | `string` | unset | Preview source |
53
- | `ratio`, `fit`, `position`, `fallback` | Image props | Image defaults | Framing and non-interactive fallback |
54
- | `caption` | `ReactNode` | unset | Visible figure title; may contain Link, Button or Dialog.Trigger |
53
+ | `ratio`, `fit`, `position`, `fallback` | `Image` props | `Image` defaults | Framing and non-interactive fallback |
54
+ | `caption` | `ReactNode` | unset | Visible figure title; may contain `Link`, `Button` or `Dialog.Trigger` |
55
55
  | `description` | `ReactNode` | unset | Persistent supporting text such as format and size |
56
- | `imageProps` | remaining Image props | unset | Responsive source/loading attributes, callbacks, frame ref, style and Image slots |
56
+ | `imageProps` | remaining `Image` props | unset | Responsive source/loading attributes, callbacks, frame ref, style and `Image` slots |
57
57
  | `classNames` | keyed classes | unset | `root`, `media`, `caption`, `title`, `description` |
58
58
  | `ref` | `Ref<HTMLElement>` | unset | Native figure; remaining figure props apply here |
59
59
 
60
60
  A caption names the figure through `aria-labelledby`; caller naming attributes take precedence. Description is visible metadata within `figcaption`. Without either, no caption element is rendered. Figure and image remain non-interactive; caption actions own their native keyboard behavior. The component never infers file type, size or download policy from the URL.
61
61
 
62
- Use `Grid as="ul"` with `li` children for a gallery in reading order. A named Dialog trigger in the caption supports enlarged inspection, Escape dismissal and focus return through Dialog. The gallery recipe provides no carousel, arrow-key selection, image editor or upload. See [media recipes](../../../../docs/guides/media-and-identity.md) for a complete implementation.
62
+ For a page of previews, put each `Thumbnail` in a [`Gallery`](Gallery.md) item. A named `Dialog` trigger in the caption supports enlarged inspection, Escape dismissal and focus return through `Dialog`. `Gallery` provides no carousel, arrow-key selection, image editor or upload. See [media recipes](../../../../docs/guides/media-and-identity.md#build-a-gallery-in-reading-order) for a complete implementation.
63
63
 
64
64
  ## Related components
65
65
 
66
- Use [Image](Image.md) for an image alone, [Avatar](Avatar.md) for people, [Grid](Grid.md) for layout, and [Dialog](Dialog.md) for focused media inspection.
66
+ Use [`Image`](Image.md) for an image alone, [`Avatar`](Avatar.md) for people, [`Grid`](Grid.md) for layout, and [`Dialog`](Dialog.md) for focused media inspection.