@kb.ui/react 0.10.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -708
- package/dist/components/Accordion/Accordion.d.ts +33 -0
- package/dist/components/Avatar/Avatar.d.ts +19 -0
- package/dist/components/Code/Code.d.ts +26 -3
- package/dist/components/Code/tokenize.d.ts +5 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +10 -0
- package/dist/components/Collection/Collection.d.ts +99 -0
- package/dist/components/Collection/useCollection.d.ts +66 -0
- package/dist/components/CollectionList/CollectionList.d.ts +12 -0
- package/dist/components/CollectionRow/CollectionRow.d.ts +17 -0
- package/dist/components/Combobox/Combobox.d.ts +14 -2
- package/dist/components/CopyableText/CopyableText.d.ts +38 -0
- package/dist/components/CopyableText/content.d.ts +14 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +20 -0
- package/dist/components/Dialog/Dialog.d.ts +3 -1
- package/dist/components/Disclosure/Disclosure.d.ts +21 -0
- package/dist/components/EmptyState/EmptyState.d.ts +30 -0
- package/dist/components/Grid/Grid.d.ts +17 -6
- package/dist/components/Image/Image.d.ts +20 -0
- package/dist/components/Link/Link.d.ts +15 -2
- package/dist/components/Popover/Popover.d.ts +55 -0
- package/dist/components/Skeleton/Skeleton.d.ts +32 -0
- package/dist/components/Spinner/Spinner.d.ts +26 -0
- package/dist/components/Table/Table.d.ts +65 -0
- package/dist/components/Tabs/Tabs.d.ts +69 -0
- package/dist/components/Tabs/index.d.ts +1 -0
- package/dist/components/Thumbnail/Thumbnail.d.ts +14 -0
- package/dist/components/Toast/Toast.d.ts +72 -0
- package/dist/index.d.ts +29 -4
- package/dist/index.js +3510 -1232
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utils/CollapsiblePanel.d.ts +10 -0
- package/dist/utils/useClipboard.d.ts +28 -0
- package/docs/components/Accordion.md +66 -0
- package/docs/components/Avatar.md +80 -0
- package/docs/components/Badge.md +37 -0
- package/docs/components/Button.md +46 -0
- package/docs/components/Callout.md +41 -0
- package/docs/components/Card.md +41 -0
- package/docs/components/Checkbox.md +60 -0
- package/docs/components/Code.md +77 -0
- package/docs/components/CodeBlock.md +77 -0
- package/docs/components/Collection.md +183 -0
- package/docs/components/CollectionList.md +44 -0
- package/docs/components/CollectionRow.md +62 -0
- package/docs/components/Combobox.md +88 -0
- package/docs/components/Container.md +41 -0
- package/docs/components/CopyableText.md +93 -0
- package/docs/components/DescriptionList.md +61 -0
- package/docs/components/Dialog.md +84 -0
- package/docs/components/Disclosure.md +53 -0
- package/docs/components/EmptyState.md +50 -0
- package/docs/components/ErrorSummary.md +46 -0
- package/docs/components/Fieldset.md +42 -0
- package/docs/components/FileInput.md +74 -0
- package/docs/components/FormActions.md +45 -0
- package/docs/components/Grid.md +66 -0
- package/docs/components/Heading.md +40 -0
- package/docs/components/Image.md +62 -0
- package/docs/components/Inline.md +42 -0
- package/docs/components/Input.md +82 -0
- package/docs/components/Link.md +52 -0
- package/docs/components/Menu.md +44 -0
- package/docs/components/MultiSelect.md +59 -0
- package/docs/components/NumberField.md +65 -0
- package/docs/components/Panel.md +145 -0
- package/docs/components/Popover.md +89 -0
- package/docs/components/Progress.md +37 -0
- package/docs/components/RadioGroup.md +69 -0
- package/docs/components/ScrollArea.md +40 -0
- package/docs/components/Select.md +71 -0
- package/docs/components/Separator.md +40 -0
- package/docs/components/Skeleton.md +46 -0
- package/docs/components/Spinner.md +40 -0
- package/docs/components/Split.md +47 -0
- package/docs/components/Stat.md +34 -0
- package/docs/components/Status.md +47 -0
- package/docs/components/Switch.md +73 -0
- package/docs/components/Table.md +105 -0
- package/docs/components/Tabs.md +89 -0
- package/docs/components/Text.md +36 -0
- package/docs/components/Textarea.md +47 -0
- package/docs/components/Thumbnail.md +66 -0
- package/docs/components/Toast.md +130 -0
- package/docs/components/Toolbar.md +39 -0
- package/docs/components/Tooltip.md +42 -0
- package/package.json +3 -2
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Tabs
|
|
2
|
+
|
|
3
|
+
Switch between peer panels within one page. Use links for navigation to another URL and RadioGroup for a single form choice.
|
|
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-tabs--docs)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Tabs } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
export function Example() {
|
|
14
|
+
return (
|
|
15
|
+
<Tabs defaultValue="summary">
|
|
16
|
+
<Tabs.List aria-label="Project sections">
|
|
17
|
+
<Tabs.Tab value="summary">Summary</Tabs.Tab>
|
|
18
|
+
<Tabs.Tab value="activity" badge="3">Activity</Tabs.Tab>
|
|
19
|
+
</Tabs.List>
|
|
20
|
+
<Tabs.Panel value="summary">Project summary</Tabs.Panel>
|
|
21
|
+
<Tabs.Panel value="activity">Recent activity</Tabs.Panel>
|
|
22
|
+
</Tabs>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## More examples
|
|
28
|
+
|
|
29
|
+
- [Section headers](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--default): Select a release panel with arrow keys or a pointer.
|
|
30
|
+
- [Compact time windows](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--pill): Small pill tabs with a disabled option.
|
|
31
|
+
- [Vertical settings](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--vertical): Up/Down navigation beside settings content.
|
|
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
|
+
|
|
34
|
+
- [Nested panels](https://kbui.kcb.pro/storybook/?path=/story/components-tabs--nested): Each Tabs root owns its orientation, density and variant.
|
|
35
|
+
|
|
36
|
+
## Reference
|
|
37
|
+
|
|
38
|
+
| Part | Responsibility |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `Tabs` | Selection owner, orientation, appearance and shared class names |
|
|
41
|
+
| `Tabs.List` | Named tab list with roving keyboard focus; inserts an indicator by default |
|
|
42
|
+
| `Tabs.Tab` | Named trigger with a unique value matching its panel |
|
|
43
|
+
| `Tabs.Indicator` | Optional explicit active indicator inside the list |
|
|
44
|
+
| `Tabs.Panel` | Content associated with a matching trigger |
|
|
45
|
+
|
|
46
|
+
| Tabs prop | Type | Default | Purpose |
|
|
47
|
+
| --- | --- | --- | --- |
|
|
48
|
+
| `value` | `string \| number \| null` | — | Controlled selection; null selects no panel |
|
|
49
|
+
| `defaultValue` | `string \| number \| null` | First enabled tab | Initial uncontrolled selection; null selects none |
|
|
50
|
+
| `onValueChange` | `(value, details) => void` | — | Selection request with Base UI reason, event and cancel method |
|
|
51
|
+
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout and keyboard axis |
|
|
52
|
+
| `variant` | `"line" \| "pill"` | `"line"` | Underline or raised active surface |
|
|
53
|
+
| `size` | `"sm" \| "md"` | `"md"` | Trigger density |
|
|
54
|
+
| `className` | `string` | — | Root class |
|
|
55
|
+
| `classNames` | `ClassNames<TabsClassKey>` | — | root, list, tab, tabIcon, tabLabel, tabBadge, indicator, panel |
|
|
56
|
+
|
|
57
|
+
| Part prop | Type | Default | Purpose |
|
|
58
|
+
| --- | --- | --- | --- |
|
|
59
|
+
| `Tabs.List.activateOnFocus` | `boolean` | `true` | Select with arrow-key focus; false requires Enter/Space |
|
|
60
|
+
| `Tabs.List.loopFocus` | `boolean` | `true` | Wrap focus at list ends |
|
|
61
|
+
| `Tabs.List.showIndicator` | `boolean` | `true` | Insert automatic indicator; false leaves authored indicators intact |
|
|
62
|
+
| `Tabs.Tab.value` | `string \| number` | Required | Stable unique selection key |
|
|
63
|
+
| `Tabs.Tab.disabled` | `boolean` | `false` | Prevent selection; remain discoverable with arrow keys |
|
|
64
|
+
| `Tabs.Tab.icon` | `ReactNode` | — | Decorative leading icon |
|
|
65
|
+
| `Tabs.Tab.badge` | `ReactNode` | — | Trailing count/status included in accessible name |
|
|
66
|
+
| `Tabs.Panel.value` | `string \| number` | Required | Matching trigger value |
|
|
67
|
+
| `Tabs.Panel.keepMounted` | `boolean` | `false` | Retain hidden DOM and local draft state |
|
|
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.
|
|
70
|
+
|
|
71
|
+
## Selection and focus
|
|
72
|
+
|
|
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
|
+
|
|
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
|
+
|
|
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
|
+
|
|
79
|
+
## Styling and accessibility
|
|
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.
|
|
82
|
+
|
|
83
|
+
For right-to-left interfaces, combine HTML `dir="rtl"` with Base UI `DirectionProvider direction="rtl"` so keyboard direction matches layout.
|
|
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/).
|
|
86
|
+
|
|
87
|
+
## Related components
|
|
88
|
+
|
|
89
|
+
Use [RadioGroup](RadioGroup.md) for a form choice and [Toolbar](Toolbar.md) for grouped actions.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Text
|
|
2
|
+
|
|
3
|
+
Body paragraphs, inline text and block grouping.
|
|
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-text--docs)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Text } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
export function Example() {
|
|
14
|
+
return <Text>Review the project details before saving changes.</Text>;
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## More examples
|
|
19
|
+
|
|
20
|
+
- [Body and supporting copy](https://kbui.kcb.pro/storybook/?path=/story/components-text--sizes-and-tones): Compare text emphasis and measure.
|
|
21
|
+
- [Inline text](https://kbui.kcb.pro/storybook/?path=/story/components-text--inline): Preserve surrounding document structure.
|
|
22
|
+
|
|
23
|
+
## Reference
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Default | Notes |
|
|
26
|
+
| ------------------ | ---------------------- | --------- | ----------------------------------------------------- |
|
|
27
|
+
| `as` | `p` \| `span` \| `div` | `p` | Use span inside paragraphs; div for block children |
|
|
28
|
+
| `size` | `sm` \| `md` \| `lg` | `md` | Existing small/body roles (13px, 15px), then 1.125rem |
|
|
29
|
+
| `tone` | `default` \| `muted` | `default` | Primary ink or readable secondary ink |
|
|
30
|
+
| `className`, `ref` | Native element props | unset | Ref type follows chosen element |
|
|
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.
|
|
33
|
+
|
|
34
|
+
## Related components
|
|
35
|
+
|
|
36
|
+
Use [Heading](Heading.md) for hierarchy, [Link](Link.md) for navigation, and [Code](Code.md) for literal code.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Textarea
|
|
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.
|
|
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-textarea--docs)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Textarea } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
export function Example() {
|
|
14
|
+
return (
|
|
15
|
+
<Textarea
|
|
16
|
+
label="Review notes"
|
|
17
|
+
name="notes"
|
|
18
|
+
rows={5}
|
|
19
|
+
description="Explain what needs attention."
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## More examples
|
|
26
|
+
|
|
27
|
+
- [Validation feedback](https://kbui.kcb.pro/storybook/?path=/story/components-textarea--with-error): Associate an error with multiline input.
|
|
28
|
+
- [User resizing](https://kbui.kcb.pro/storybook/?path=/story/components-textarea--resize-modes): Compare allowed resize directions.
|
|
29
|
+
|
|
30
|
+
## Reference
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Notes |
|
|
33
|
+
| ---------------- | -------------------------------------------------------------- | ------------ | ---------------------------------------------------------- |
|
|
34
|
+
| `label` | `string` | required | Visible field label and accessible name |
|
|
35
|
+
| `visuallyHidden` | `boolean` | `false` | Hides the label visually while keeping its accessible name |
|
|
36
|
+
| `description` | `string` | unset | Supporting help text below the control |
|
|
37
|
+
| `error` | `string` | unset | Validation message; marks the control invalid |
|
|
38
|
+
| `rows` | `number` | `4` | Initial visible line count on the native textarea |
|
|
39
|
+
| `resize` | `"vertical" \| "none" \| "both"` | `"vertical"` | Controls user drag-resizing axis |
|
|
40
|
+
| `onValueChange` | `(value: string) => void` | unset | Called with the next string value on change |
|
|
41
|
+
| `classNames` | `ClassNames<"label" \| "control" \| "description" \| "error">` | unset | Classes for inner parts |
|
|
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`.
|
|
44
|
+
|
|
45
|
+
## Related components
|
|
46
|
+
|
|
47
|
+
Use [Input](Input.md) for a single-line value and [Fieldset](Fieldset.md) to group related answers.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Thumbnail
|
|
2
|
+
|
|
3
|
+
Pair stable image frames with visible titles and metadata for products, studies and attachments. Compose figures into responsive collections with Grid.
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Grid, Link, Thumbnail } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
export function Example() {
|
|
14
|
+
return (
|
|
15
|
+
<Grid as="ul" minItemWidth="sm" gap="lg">
|
|
16
|
+
<li>
|
|
17
|
+
<Thumbnail
|
|
18
|
+
src="/products/studio-coat.jpg"
|
|
19
|
+
alt="Sand wool coat with broad lapels"
|
|
20
|
+
ratio="portrait"
|
|
21
|
+
fit="contain"
|
|
22
|
+
caption={<Link href="/products/studio-coat">The studio coat</Link>}
|
|
23
|
+
description="Sand · Wool blend"
|
|
24
|
+
imageProps={{ loading: "lazy", width: 900, height: 1200 }}
|
|
25
|
+
/>
|
|
26
|
+
</li>
|
|
27
|
+
<li>
|
|
28
|
+
<Thumbnail
|
|
29
|
+
alt=""
|
|
30
|
+
ratio="portrait"
|
|
31
|
+
fallback="PDF"
|
|
32
|
+
caption={<Link href="/brand-guide.pdf">Brand guide.pdf</Link>}
|
|
33
|
+
description="PDF · 2.4 MB"
|
|
34
|
+
/>
|
|
35
|
+
</li>
|
|
36
|
+
</Grid>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## More examples
|
|
42
|
+
|
|
43
|
+
- [Products](https://kbui.kcb.pro/storybook/?path=/story/components-thumbnail--products): Responsive product cards and absent photography.
|
|
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.
|
|
46
|
+
|
|
47
|
+
## Reference
|
|
48
|
+
|
|
49
|
+
| Prop | Type | Default | Notes |
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
|
+
| `alt` | `string` | required | Meaningful visual alternative; empty when decorative |
|
|
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 |
|
|
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 |
|
|
57
|
+
| `classNames` | keyed classes | unset | `root`, `media`, `caption`, `title`, `description` |
|
|
58
|
+
| `ref` | `Ref<HTMLElement>` | unset | Native figure; remaining figure props apply here |
|
|
59
|
+
|
|
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
|
+
|
|
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.
|
|
63
|
+
|
|
64
|
+
## Related components
|
|
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.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Toast
|
|
2
|
+
|
|
3
|
+
Use Toast for temporary feedback about background work. One provider owns the message list, timers and focus. Keep essential results available in the page or a notification history.
|
|
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-toast--docs)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Button, Toast, useToastManager } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
function SaveButton() {
|
|
14
|
+
const { add } = useToastManager();
|
|
15
|
+
return (
|
|
16
|
+
<Button onClick={() => add({ title: "Changes saved", description: "Your project is up to date.", type: "success" })}>
|
|
17
|
+
Save changes
|
|
18
|
+
</Button>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function Example() {
|
|
23
|
+
return (
|
|
24
|
+
<Toast.Provider timeout={5000} limit={3}>
|
|
25
|
+
<SaveButton />
|
|
26
|
+
<Toast.Viewport aria-label="Notifications" />
|
|
27
|
+
</Toast.Provider>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Mount one `Toast.Viewport` inside each provider. Fixed placements portal to `document.body`; `placement="inline"` renders in normal layout without a portal. Choose a logical corner with `top-start`, `top-end`, `bottom-start` or `bottom-end`. For a nested theme, pass a mounted themed element or ref through `container`; otherwise the document theme applies. The provider and hook are scoped, so nested providers maintain independent messages.
|
|
33
|
+
|
|
34
|
+
## Queue and timing
|
|
35
|
+
|
|
36
|
+
Messages display newest first. `limit` defaults to `3`; older overflow messages remain mounted, hidden and inert. Dismissing a newer message reveals an older message if it has not expired. Timers continue for overflow messages. This is a temporary notification stack, not a FIFO delivery queue or durable history.
|
|
37
|
+
|
|
38
|
+
`timeout` defaults to `5000` milliseconds; a per-message timeout overrides the provider. Set `timeout: 0` to keep a message until dismissed. Hover, keyboard focus in the viewport and window blur pause timers; leaving resumes the remaining duration. New messages added while paused also wait. Unmounting the provider clears its timers and subscriptions.
|
|
39
|
+
|
|
40
|
+
Use `timeout: 0` for essential information or time-sensitive actions. Supply an application preference to disable or adjust time limits where the task requires it; hover/focus pause alone does not meet every requirement of [WCAG 2.2.1 Timing Adjustable, Level A](https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html).
|
|
41
|
+
|
|
42
|
+
F6 moves focus into the viewport without notifications interrupting the current task. Tab reaches messages and actions. Escape dismisses the focused message. Dismissal keeps focus within remaining messages or returns it to the previous working control when the last message closes. Close buttons provide a pointer and keyboard alternative to swipe dismissal.
|
|
43
|
+
|
|
44
|
+
## More examples
|
|
45
|
+
|
|
46
|
+
- [Overflow and dismissal](https://kbui.kcb.pro/storybook/?path=/story/components-toast--queue): Hide older messages and reveal persistent messages as capacity returns.
|
|
47
|
+
- [Undo action](https://kbui.kcb.pro/storybook/?path=/story/components-toast--with-action): Update an existing notification after an action.
|
|
48
|
+
- [Timed dismissal](https://kbui.kcb.pro/storybook/?path=/story/components-toast--timed): Enter notifications with F6, dismiss with Escape and return to work.
|
|
49
|
+
- [Promise states](https://kbui.kcb.pro/storybook/?path=/story/components-toast--promise-state): Keep message identity through loading and success.
|
|
50
|
+
- [Custom composition](https://kbui.kcb.pro/storybook/?path=/story/components-toast--custom-composition): Render typed message data and a real navigation link.
|
|
51
|
+
- [Positioned urgent message](https://kbui.kcb.pro/storybook/?path=/story/components-toast--positioned): Use a portaled corner viewport and a high-priority announcement.
|
|
52
|
+
- [Long content](https://kbui.kcb.pro/storybook/?path=/story/components-toast--long-content): Check wrapping, actions and dismissal at narrow widths.
|
|
53
|
+
|
|
54
|
+
## Reference
|
|
55
|
+
|
|
56
|
+
### Toast.Provider
|
|
57
|
+
|
|
58
|
+
| Prop | Type | Default | Notes |
|
|
59
|
+
| --- | --- | --- | --- |
|
|
60
|
+
| `children` | `ReactNode` | unset | Application content and one viewport |
|
|
61
|
+
| `timeout` | `number` | `5000` | Milliseconds before dismissal; `0` disables automatic dismissal |
|
|
62
|
+
| `limit` | `number` | `3` | Maximum visible active messages; use a positive integer |
|
|
63
|
+
| `toastManager` | `ToastManager` | unset | Optional external manager created once per application or request |
|
|
64
|
+
|
|
65
|
+
### Toast.Viewport
|
|
66
|
+
|
|
67
|
+
| Prop | Type | Default | Notes |
|
|
68
|
+
| --- | --- | --- | --- |
|
|
69
|
+
| `placement` | `ToastPlacement` | `bottom-end` | Four logical corners or `inline` |
|
|
70
|
+
| `container` | `HTMLElement` or ref | `document.body` | Portal host for fixed placements; unused for inline |
|
|
71
|
+
| `aria-label` | `string` | `Notifications` | Localize and distinguish the notification region |
|
|
72
|
+
| `renderToast` | `(toast: ToastObject<Data>) => ReactNode` | complete Toast | Custom renderer; give each returned root `key={toast.id}` |
|
|
73
|
+
| `children` | `ReactNode` | managed messages | Explicit children replace automatic rendering |
|
|
74
|
+
| `className`, `ref`, DOM props | native div props | unset | Reach the viewport; Base UI `render` composition is supported |
|
|
75
|
+
|
|
76
|
+
### Toast and parts
|
|
77
|
+
|
|
78
|
+
| Prop or part | Type | Default | Notes |
|
|
79
|
+
| --- | --- | --- | --- |
|
|
80
|
+
| `toast` | `ToastObject<Data>` | required | Message from the matching provider |
|
|
81
|
+
| `tone` | `neutral`, `info`, `success`, `warning`, `danger` | from type | `error` maps to danger; loading maps to info; other types fall back to neutral |
|
|
82
|
+
| `closeLabel` | `string` | `Dismiss notification` | Localized name for default close control |
|
|
83
|
+
| `classNames` | content, title, description, action, close | unset | Extra classes for default slots |
|
|
84
|
+
| `children` | `ReactNode` | complete message | Overrides default content and close control |
|
|
85
|
+
| `swipeDirection` | Base UI swipe directions | down and right | Configure or disable with an empty array |
|
|
86
|
+
| `Toast.Content` | content wrapper | div | Groups message content |
|
|
87
|
+
| `Toast.Title` | heading | message title | Supplies the root accessible name |
|
|
88
|
+
| `Toast.Description` | paragraph | message description | Supplies the root accessible description |
|
|
89
|
+
| `Toast.Action` | button | message actionProps | Does not close automatically; explicitly call close or update |
|
|
90
|
+
| `Toast.Close` | button | caller children | Dismisses its message; supply visible text or an accessible name |
|
|
91
|
+
| `className`, `ref`, DOM props | part element props | unset | Every part supports a plain class string, ref and Base UI render composition |
|
|
92
|
+
|
|
93
|
+
Custom children own their own slot classes and close control. For a link action, use `render={<a href="…" />}`, `nativeButton={false}` and `role="link"`. Default parts render title, description and action only when the message supplies them. Description-only messages, including shorthand promise text, become the title so the default dialog stays named. Give every message meaningful title text; an icon or color cannot replace it. Keep `title` and `description` on the message even when custom parts render them, because urgent announcements use the stored message content.
|
|
94
|
+
|
|
95
|
+
### Managers and messages
|
|
96
|
+
|
|
97
|
+
`useToastManager<Data>()` returns reactive `toasts`, `add`, `update`, `close` and `promise` from the nearest provider. `createToastManager<Data>()` supplies the same methods outside React; pass it to `toastManager`. Create a stable instance per application or server request. Calls made before provider subscription or after unmount are not buffered. Do not share a module-level manager between server requests.
|
|
98
|
+
|
|
99
|
+
| Method or option | Type | Behavior |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| `add(options)` | `ToastAddOptions<Data>` | Returns string ID; adding the same ID updates in place and refreshes its timer |
|
|
102
|
+
| `update(id, options)` | `ToastUpdateOptions<Data>` or updater | Changes existing content; an explicit timeout restarts timing |
|
|
103
|
+
| `close(id?)` | optional string ID | Closes one message or all messages; callbacks fire once |
|
|
104
|
+
| `promise(value, options)` | promise and loading/success/error options | Persistent loading message becomes success/error using same ID; resolves or rejects with original result |
|
|
105
|
+
| `title`, `description` | `ReactNode` | Stored message and announcement text |
|
|
106
|
+
| `type` | `string` | Visual type; use words in content to explain status |
|
|
107
|
+
| `priority` | `low` or `high` | Low is polite; high uses a separate urgent alert announcement |
|
|
108
|
+
| `timeout` | `number` | Per-message duration; `0` disables automatic dismissal |
|
|
109
|
+
| `id` | `string` | Optional stable key for upsert |
|
|
110
|
+
| `actionProps` | native button props | Includes action text, handler, disabled state and accessible name |
|
|
111
|
+
| `onClose`, `onRemove` | `() => void` | Close intent and final removal after exit transition |
|
|
112
|
+
| `data` | caller-defined object | Typed custom data for renderToast |
|
|
113
|
+
|
|
114
|
+
Promise options accept `loading`, `success` and `error` as text or update options; success/error also accept functions of the result/error. Handle rejected returned promises in application code. `ToastObject`, `ToastManager`, `ToastAddOptions`, `ToastUpdateOptions`, `ToastPromiseOptions`, component prop types, `ToastTone` and `ToastPlacement` are public exports.
|
|
115
|
+
|
|
116
|
+
Base UI owns interaction and lifecycle semantics; see its [Toast reference](https://base-ui.com/react/components/toast). CSS-only consumers must implement queueing, announcements, timing and focus themselves. Component tokens use the `--kb-toast-*` namespace; importing a standalone `toast.css` also requires tokens and reset.
|
|
117
|
+
|
|
118
|
+
## Motion
|
|
119
|
+
|
|
120
|
+
Messages enter with a short slide and soft scale settle; dismissal fades and collapses the space before removal. Stack spacing opens as a new message enters, and swipe dismissal continues in the gesture direction. Reduced motion removes transitions and geometric movement.
|
|
121
|
+
|
|
122
|
+
Tune `--kb-toast-motion-duration`, `--kb-toast-exit-duration`, `--kb-toast-motion-easing`, `--kb-toast-enter-offset` and `--kb-toast-enter-scale` to match the application. Keep exits brief so notifications do not obstruct work.
|
|
123
|
+
|
|
124
|
+
## Accessibility evidence and limits
|
|
125
|
+
|
|
126
|
+
Component tests cover lifecycle, announcements in the DOM, provider isolation, callbacks and portal composition. Browser stories exercise keyboard/focus, live-region structure, queue visibility, actions and real timing in both themes and motion preferences. These checks do not prove spoken delivery. Test relevant initial/update/urgent messages with supported screen readers and confirm no duplicate announcements. Manual screen-reader interoperability remains unverified; follow the [shared accessibility procedure](../../../../docs/guides/accessibility.md).
|
|
127
|
+
|
|
128
|
+
## Related components
|
|
129
|
+
|
|
130
|
+
Use [Status](Status.md) for state beside its content, [Callout](Callout.md) for an inline message with fuller context, and [Dialog](Dialog.md) when a decision must interrupt work.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Toolbar
|
|
2
|
+
|
|
3
|
+
Group related actions, such as editing or filtering controls. Give the row an accessible name so people know what its controls affect.
|
|
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-toolbar--docs)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Toolbar } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
export function Example() {
|
|
14
|
+
return (
|
|
15
|
+
<Toolbar aria-label="Document actions">
|
|
16
|
+
<Toolbar.Button onClick={() => window.print()}>Print</Toolbar.Button>
|
|
17
|
+
</Toolbar>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## More examples
|
|
23
|
+
|
|
24
|
+
- [Coordinated actions](https://kbui.kcb.pro/storybook/?path=/story/components-toolbar--default): Try the toolbar’s single Tab entry and arrow-key navigation.
|
|
25
|
+
|
|
26
|
+
## Reference
|
|
27
|
+
|
|
28
|
+
| Part | Props and responsibility |
|
|
29
|
+
| ------------------- | ------------------------------------------------------------------------------- |
|
|
30
|
+
| `Toolbar` | Root; name with aria-label; Base UI orientation controls the keyboard direction |
|
|
31
|
+
| `Toolbar.Group` | Groups related controls inside the toolbar |
|
|
32
|
+
| `Toolbar.Button` | Action; variant accepts Button variants and defaults to ghost |
|
|
33
|
+
| `Toolbar.Separator` | Visual division between groups |
|
|
34
|
+
|
|
35
|
+
Tab enters the toolbar once; arrow keys move between its controls. Give icon-only actions their own accessible names. Use Checkbox or RadioGroup when a control represents a persistent choice rather than an action.
|
|
36
|
+
|
|
37
|
+
## Related components
|
|
38
|
+
|
|
39
|
+
Use [Inline](Inline.md) for independent controls that should each retain their normal Tab stop, and [Menu](Menu.md) for a compact action list.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Tooltip
|
|
2
|
+
|
|
3
|
+
Add a brief, optional hint to an already named control. Put essential instructions in visible text or a field description instead.
|
|
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-tooltip--docs)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@kb.ui/react/styles.css";
|
|
11
|
+
import { Button, Tooltip } from "@kb.ui/react";
|
|
12
|
+
|
|
13
|
+
export function Example() {
|
|
14
|
+
return (
|
|
15
|
+
<Tooltip content="Print using your browser’s print dialog.">
|
|
16
|
+
<Button onClick={() => window.print()}>Print page</Button>
|
|
17
|
+
</Tooltip>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## More examples
|
|
23
|
+
|
|
24
|
+
- [An optional description](https://kbui.kcb.pro/storybook/?path=/story/components-tooltip--on-hover): Try pointer and keyboard access to a named trigger.
|
|
25
|
+
- [A themed hint](https://kbui.kcb.pro/storybook/?path=/story/components-tooltip--nested-theme): Keep a portaled hint within its intended theme.
|
|
26
|
+
|
|
27
|
+
## Reference
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Default | Notes |
|
|
30
|
+
| ----------- | ---------------- | ------------- | ---------------------------------------------------------- |
|
|
31
|
+
| `children` | `ReactElement` | required | Focusable trigger that accepts Base UI props and a ref |
|
|
32
|
+
| `content` | `ReactNode` | required | Short, non-interactive hint shown on hover or focus |
|
|
33
|
+
| `side` | positioner side | `top` | Preferred side; placement can adjust near viewport edges |
|
|
34
|
+
| `delay` | `number` | `400` | Hover delay in milliseconds |
|
|
35
|
+
| `container` | portal container | document body | Use a themed host when the popup belongs to a nested theme |
|
|
36
|
+
| `className` | `string` | unset | Class on the popup |
|
|
37
|
+
|
|
38
|
+
Give icon-only triggers their own aria-label. The tooltip is a description, not a replacement for the control's name. Do not put links, buttons, or required instructions in the popup.
|
|
39
|
+
|
|
40
|
+
## Related components
|
|
41
|
+
|
|
42
|
+
Use [Input](Input.md) descriptions for essential field instructions and [Callout](Callout.md) for a persistent message.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb.ui/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"directory": "packages/react"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
|
-
"dist"
|
|
12
|
+
"dist",
|
|
13
|
+
"docs"
|
|
13
14
|
],
|
|
14
15
|
"sideEffects": [
|
|
15
16
|
"*.css"
|