@k8ordo/ui 1.0.0 → 2.0.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 +37 -12
- package/dist/components/ai/conversation/conversation.d.mts +8 -10
- package/dist/components/ai/conversation/conversation.mjs +1 -6
- package/dist/components/ai/conversation/index.d.mts +15 -1
- package/dist/components/ai/conversation/index.mjs +8 -1
- package/dist/components/ai/index.d.mts +5 -9
- package/dist/components/ai/index.mjs +4 -4
- package/dist/components/ai/message/index.d.mts +12 -1
- package/dist/components/ai/message/index.mjs +7 -1
- package/dist/components/ai/message/message.d.mts +3 -5
- package/dist/components/ai/message/message.mjs +1 -5
- package/dist/components/ai/prompt-input/index.d.mts +23 -1
- package/dist/components/ai/prompt-input/index.mjs +8 -1
- package/dist/components/ai/prompt-input/prompt-input.d.mts +4 -6
- package/dist/components/ai/prompt-input/prompt-input.mjs +1 -6
- package/dist/components/ai/suggestion/index.d.mts +13 -1
- package/dist/components/ai/suggestion/index.mjs +7 -1
- package/dist/components/ai/suggestion/suggestion.d.mts +3 -5
- package/dist/components/ai/suggestion/suggestion.mjs +1 -5
- package/dist/components/buttons/icon-button/icon-button.mjs +1 -1
- package/dist/components/form/checkbox/checkbox.d.mts +1 -0
- package/dist/components/form/checkbox/checkbox.mjs +3 -2
- package/dist/components/form/checkbox-group/index.d.mts +1 -0
- package/dist/components/form/file-field/file-field.d.mts +12 -15
- package/dist/components/form/file-field/file-field.mjs +1 -6
- package/dist/components/form/file-field/index.d.mts +17 -1
- package/dist/components/form/file-field/index.mjs +8 -1
- package/dist/components/form/radio/radio.d.mts +1 -0
- package/dist/components/form/radio/radio.mjs +3 -2
- package/dist/components/index.d.mts +15 -21
- package/dist/components/index.mjs +7 -7
- package/dist/components/navigation/anchor/anchor.mjs +1 -1
- package/dist/components/navigation/tabs/index.d.mts +19 -1
- package/dist/components/navigation/tabs/index.mjs +9 -1
- package/dist/components/navigation/tabs/tabs.d.mts +16 -18
- package/dist/components/navigation/tabs/tabs.mjs +1 -7
- package/dist/components/overlays/dialog/dialog.d.mts +12 -16
- package/dist/components/overlays/dialog/dialog.mjs +1 -6
- package/dist/components/overlays/dialog/index.d.mts +17 -1
- package/dist/components/overlays/dialog/index.mjs +8 -1
- package/dist/components/overlays/dropdown-menu/dropdown-menu.d.mts +20 -24
- package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +2 -11
- package/dist/components/overlays/dropdown-menu/index.d.mts +31 -1
- package/dist/components/overlays/dropdown-menu/index.mjs +12 -1
- package/dist/components/overlays/dropdown-menu/sub-menu.mjs +1 -1
- package/dist/components/overlays/list-box/index.d.mts +27 -1
- package/dist/components/overlays/list-box/index.mjs +9 -1
- package/dist/components/overlays/list-box/list-box.d.mts +20 -22
- package/dist/components/overlays/list-box/list-box.mjs +2 -8
- package/dist/components/overlays/popover/index.d.mts +24 -1
- package/dist/components/overlays/popover/index.mjs +8 -1
- package/dist/components/overlays/popover/popover.d.mts +18 -20
- package/dist/components/overlays/popover/popover.mjs +2 -7
- package/dist/components/overlays/tooltip/index.d.mts +21 -1
- package/dist/components/overlays/tooltip/index.mjs +8 -1
- package/dist/components/overlays/tooltip/tooltip.d.mts +18 -22
- package/dist/components/overlays/tooltip/tooltip.mjs +2 -7
- package/dist/hooks/index.d.mts +1 -4
- package/dist/hooks/index.mjs +2 -5
- package/dist/index.d.mts +13 -15
- package/dist/index.mjs +9 -12
- package/dist/integrations/_shared/renderers.mjs +7 -7
- package/dist/integrations/_shared/schemas.d.mts +1 -1
- package/dist/{hooks/focus-trap/index.d.mts → internal/focus-trap.d.mts} +1 -1
- package/dist/{hooks/focus-trap/index.mjs → internal/focus-trap.mjs} +1 -1
- package/dist/styles/index.css +0 -8
- package/docs/GUIDE.md +148 -133
- package/docs/llms.txt +11 -7
- package/docs/props.generated.json +18 -0
- package/docs/references/ai-chat.md +67 -67
- package/docs/references/color.md +108 -107
- package/docs/references/components.md +318 -310
- package/docs/references/generative-ui.md +51 -30
- package/docs/references/helpers.md +155 -52
- package/docs/references/hooks.md +61 -74
- package/docs/references/interaction-design.md +47 -47
- package/docs/references/spatial-design.md +83 -81
- package/docs/references/typography.md +68 -67
- package/package.json +32 -33
- package/dist/hooks/hash/index.d.mts +0 -4
- package/dist/hooks/hash/index.mjs +0 -25
- package/dist/hooks/local-storage/index.d.mts +0 -4
- package/dist/hooks/local-storage/index.mjs +0 -46
- package/dist/hooks/session-storage/index.d.mts +0 -4
- package/dist/hooks/session-storage/index.mjs +0 -46
|
@@ -1,35 +1,42 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Generative UI (json-render / OpenUI)
|
|
2
2
|
|
|
3
|
-
k8ordo
|
|
3
|
+
`@k8ordo/ui` ships official adapters that let an LLM generate UI out of
|
|
4
|
+
`@k8ordo/ui` components only. The generated UI is pinned to the design tokens,
|
|
5
|
+
so it cannot drift off-brand. Two frameworks are supported:
|
|
6
|
+
[json-render](https://json-render.dev) and [OpenUI](https://www.openui.com).
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
Both are optional peer dependencies — install only the one you use.
|
|
6
9
|
|
|
7
10
|
```bash
|
|
8
11
|
# json-render
|
|
9
12
|
pnpm add @json-render/core @json-render/react zod
|
|
10
13
|
# OpenUI
|
|
11
14
|
pnpm add @openuidev/react-lang zod
|
|
12
|
-
# OpenUI
|
|
15
|
+
# Add this too if you use OpenUI's server-safe prompt entry:
|
|
13
16
|
pnpm add @openuidev/lang-core
|
|
14
17
|
```
|
|
15
18
|
|
|
16
19
|
## json-render
|
|
17
20
|
|
|
18
|
-
catalog
|
|
21
|
+
The catalog (schemas and prompt) is separate from the registry (rendering), and
|
|
22
|
+
the catalog is **server-safe**.
|
|
19
23
|
|
|
20
|
-
### 1.
|
|
24
|
+
### 1. Generate the prompt on the server
|
|
21
25
|
|
|
22
26
|
```tsx
|
|
23
27
|
import { catalog, uiRules } from '@k8ordo/ui/json-render';
|
|
24
28
|
|
|
25
|
-
// customRules
|
|
26
|
-
//
|
|
29
|
+
// customRules injects the cross-cutting constraints an LLM most often breaks
|
|
30
|
+
// (cell count matching columns in Table, href format, text-only content in
|
|
31
|
+
// Tabs and Accordion).
|
|
27
32
|
const systemPrompt = catalog.prompt({ customRules: [...uiRules] });
|
|
28
33
|
```
|
|
29
34
|
|
|
30
|
-
### 2.
|
|
35
|
+
### 2. Render on the client
|
|
31
36
|
|
|
32
|
-
`JsonRenderUI`
|
|
37
|
+
`JsonRenderUI` already wires up `JSONUIProvider` + `Renderer` + registry
|
|
38
|
+
internally, so passing the spec is enough. Pass `onStateChange` when you need to
|
|
39
|
+
collect form values.
|
|
33
40
|
|
|
34
41
|
```tsx
|
|
35
42
|
'use client';
|
|
@@ -40,27 +47,33 @@ export function GenUi({ spec }: { spec: unknown }) {
|
|
|
40
47
|
}
|
|
41
48
|
```
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
For an advanced setup (your own `navigate`, `handlers`, or
|
|
51
|
+
`validationFunctions`), pass the low-level `registry` straight to
|
|
52
|
+
`@json-render/react`'s `JSONUIProvider` / `Renderer`.
|
|
44
53
|
|
|
45
|
-
### 3. LLM
|
|
54
|
+
### 3. Validate LLM output, then render or repair it
|
|
46
55
|
|
|
47
|
-
`validateGeneratedSpec`
|
|
56
|
+
`validateGeneratedSpec` applies mechanical fixes, validates the structure, then
|
|
57
|
+
validates props per component. On failure it returns a repair prompt you can
|
|
58
|
+
send straight back to the LLM. Use it instead of `catalog.validate()`, which
|
|
59
|
+
rejects valid specs in the current upstream version.
|
|
48
60
|
|
|
49
61
|
```tsx
|
|
50
62
|
import { validateGeneratedSpec } from '@k8ordo/ui/json-render';
|
|
51
63
|
|
|
52
64
|
const result = validateGeneratedSpec(JSON.parse(llmOutput));
|
|
53
65
|
if (result.ok) {
|
|
54
|
-
// result.fixes
|
|
66
|
+
// result.fixes lists what was auto-corrected
|
|
55
67
|
return <JsonRenderUI spec={result.spec} />;
|
|
56
68
|
}
|
|
57
|
-
//
|
|
69
|
+
// If it is broken, regenerate with the repair prompt
|
|
58
70
|
const retried = await llm(result.repairPrompt);
|
|
59
71
|
```
|
|
60
72
|
|
|
61
|
-
### 4.
|
|
73
|
+
### 4. Typed specs (optional)
|
|
62
74
|
|
|
63
|
-
`satisfies UISpec`
|
|
75
|
+
Writing `satisfies UISpec` turns a typo in a component name or prop into a
|
|
76
|
+
compile error, and removes the need for `as unknown as Spec`.
|
|
64
77
|
|
|
65
78
|
```tsx
|
|
66
79
|
import type { UISpec } from '@k8ordo/ui/json-render';
|
|
@@ -74,11 +87,13 @@ const spec = {
|
|
|
74
87
|
} satisfies UISpec;
|
|
75
88
|
```
|
|
76
89
|
|
|
77
|
-
`ComponentName`
|
|
90
|
+
`ComponentName` and `ComponentProps<K>` are exported as well, so you can pull
|
|
91
|
+
out the props type of a specific component.
|
|
78
92
|
|
|
79
93
|
## OpenUI
|
|
80
94
|
|
|
81
|
-
|
|
95
|
+
A model where children are expressed as typed subcomponents
|
|
96
|
+
(`z.array(Child.ref)`). Rendering is `'use client'`.
|
|
82
97
|
|
|
83
98
|
```tsx
|
|
84
99
|
'use client';
|
|
@@ -90,23 +105,29 @@ export function GenUi({ response }: { response: string }) {
|
|
|
90
105
|
}
|
|
91
106
|
```
|
|
92
107
|
|
|
93
|
-
|
|
108
|
+
The system prompt comes from a dedicated server-safe entry, mirroring
|
|
109
|
+
json-render's `catalog.prompt()`.
|
|
94
110
|
|
|
95
111
|
```tsx
|
|
96
112
|
import { prompt } from '@k8ordo/ui/openui/prompt';
|
|
97
113
|
|
|
98
|
-
const systemPrompt = prompt(); // React
|
|
114
|
+
const systemPrompt = prompt(); // No React dependency — callable from RSC or an API route
|
|
99
115
|
```
|
|
100
116
|
|
|
101
|
-
OpenUI
|
|
117
|
+
In OpenUI a `Stack` or `Grid` cannot sit directly inside another `Stack` or
|
|
118
|
+
`Grid` (self-referential schemas are unsupported). When you need nested layout,
|
|
119
|
+
put the `Stack` / `Grid` inside a `Card`. json-render is slot-based and nests
|
|
120
|
+
freely.
|
|
102
121
|
|
|
103
|
-
##
|
|
122
|
+
## Exports at a glance
|
|
104
123
|
|
|
105
|
-
|
|
|
124
|
+
| Export | Kind | Contents |
|
|
106
125
|
| --------------------------------- | -------------- | ------------------------------------------------------------------ |
|
|
107
|
-
| `@k8ordo/ui/json-render` |
|
|
108
|
-
| `@k8ordo/ui/json-render/registry` | `'use client'` | `JsonRenderUI
|
|
109
|
-
| `@k8ordo/ui/openui` | `'use client'` | `library
|
|
110
|
-
| `@k8ordo/ui/openui/prompt` |
|
|
111
|
-
|
|
112
|
-
>
|
|
126
|
+
| `@k8ordo/ui/json-render` | server-safe | `catalog`, `validateGeneratedSpec`, `uiRules`, types (`UISpec`, …) |
|
|
127
|
+
| `@k8ordo/ui/json-render/registry` | `'use client'` | `JsonRenderUI` (pre-wired), `registry` (low level) |
|
|
128
|
+
| `@k8ordo/ui/openui` | `'use client'` | `library` (rendering) |
|
|
129
|
+
| `@k8ordo/ui/openui/prompt` | server-safe | `prompt()` (prompt generation) |
|
|
130
|
+
|
|
131
|
+
> All of them assume you have loaded `@k8ordo/ui/styles.css` (or
|
|
132
|
+
> `@k8ordo/ui/tailwind.css` in a Tailwind CSS 4 project) and wrapped the tree in
|
|
133
|
+
> `UIProvider`.
|
|
@@ -1,120 +1,223 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Helpers and types
|
|
2
2
|
|
|
3
|
-
k8ordo
|
|
3
|
+
Utility functions and type definitions that `@k8ordo/ui` provides.
|
|
4
4
|
|
|
5
5
|
```tsx
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
chain,
|
|
8
|
+
cn,
|
|
9
|
+
createSafeContext,
|
|
10
|
+
mergeProps,
|
|
11
|
+
mergeRefs,
|
|
12
|
+
} from '@k8ordo/ui';
|
|
13
|
+
import type {
|
|
14
|
+
Status,
|
|
15
|
+
Direction,
|
|
16
|
+
Placement,
|
|
17
|
+
ModalSide,
|
|
18
|
+
DrawerSide,
|
|
19
|
+
Option,
|
|
20
|
+
} from '@k8ordo/ui';
|
|
8
21
|
```
|
|
9
22
|
|
|
10
|
-
|
|
23
|
+
The list below is the complete public helper API: `pnpm check:props` fails
|
|
24
|
+
when the headings under "Helper functions" and the exports of
|
|
25
|
+
`src/helpers/index.ts` disagree.
|
|
26
|
+
|
|
27
|
+
## Helper functions
|
|
28
|
+
|
|
29
|
+
### chain
|
|
30
|
+
|
|
31
|
+
Combines several callbacks into one that calls each in order with the same
|
|
32
|
+
arguments. `undefined` entries are skipped, so an optional user handler can be
|
|
33
|
+
passed straight in. The combined function returns nothing.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { chain } from '@k8ordo/ui';
|
|
37
|
+
|
|
38
|
+
const onClick = chain(props.onClick, () => {
|
|
39
|
+
setOpen(false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
<button onClick={onClick} />;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Signature:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const chain: <T extends (...args: never[]) => unknown>(
|
|
49
|
+
...callbacks: Array<T | undefined>
|
|
50
|
+
) => (...args: Parameters<T>) => void;
|
|
51
|
+
```
|
|
11
52
|
|
|
12
53
|
### cn
|
|
13
54
|
|
|
14
|
-
Tailwind
|
|
55
|
+
Merges Tailwind classes (clsx + tailwind-merge). Accepts strings, arrays,
|
|
56
|
+
objects, and falsy values, and resolves conflicting utilities with the last
|
|
57
|
+
one winning.
|
|
15
58
|
|
|
16
59
|
```tsx
|
|
17
60
|
import { cn } from '@k8ordo/ui';
|
|
18
61
|
|
|
19
62
|
cn('text-fg-base', isActive && 'bg-primary-bg', className);
|
|
20
|
-
//
|
|
63
|
+
cn('flex', undefined, { hidden: false, grow: true }); // → 'flex grow'
|
|
21
64
|
cn('px-4 py-2', 'px-6'); // → 'py-2 px-6'
|
|
22
65
|
```
|
|
23
66
|
|
|
24
|
-
|
|
67
|
+
Signature:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const cn: (...inputs: ClassValue[]) => string;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### createSafeContext
|
|
25
74
|
|
|
26
|
-
|
|
75
|
+
Creates a context whose hook throws with the given message when there is no
|
|
76
|
+
provider above it, instead of handing back `null`. Returns the context (to
|
|
77
|
+
render as a provider) and the hook as a tuple.
|
|
27
78
|
|
|
28
79
|
```tsx
|
|
29
|
-
import {
|
|
80
|
+
import { createSafeContext } from '@k8ordo/ui';
|
|
30
81
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```
|
|
82
|
+
const [TabsContext, useTabsContext] = createSafeContext<{
|
|
83
|
+
selectedId: string;
|
|
84
|
+
}>('Tabs.Tab must be used within <Tabs.Root>');
|
|
35
85
|
|
|
36
|
-
|
|
86
|
+
const Root = ({ children }) => (
|
|
87
|
+
<TabsContext value={{ selectedId }}>{children}</TabsContext>
|
|
88
|
+
);
|
|
37
89
|
|
|
38
|
-
|
|
90
|
+
const Tab = () => {
|
|
91
|
+
const { selectedId } = useTabsContext(); // throws outside <Root>
|
|
92
|
+
};
|
|
93
|
+
```
|
|
39
94
|
|
|
40
|
-
|
|
41
|
-
import { commalize } from '@k8ordo/ui';
|
|
95
|
+
Signature:
|
|
42
96
|
|
|
43
|
-
|
|
44
|
-
|
|
97
|
+
```ts
|
|
98
|
+
const createSafeContext: <T>(
|
|
99
|
+
errorMessage: string,
|
|
100
|
+
) => readonly [Context<T | null>, () => T];
|
|
45
101
|
```
|
|
46
102
|
|
|
47
|
-
###
|
|
103
|
+
### mergeProps
|
|
48
104
|
|
|
49
|
-
|
|
105
|
+
Merges two props objects the way a `render*` prop expects: `className` goes
|
|
106
|
+
through `cn`, `style` is shallow-merged, event handlers (`onClick`,
|
|
107
|
+
`onKeyDown`, …) are chained with `chain` so both run, and any other key is
|
|
108
|
+
overwritten by `override` unless its value is `undefined`.
|
|
50
109
|
|
|
51
110
|
```tsx
|
|
52
|
-
import {
|
|
111
|
+
import { mergeProps } from '@k8ordo/ui';
|
|
112
|
+
|
|
113
|
+
const merged = mergeProps(
|
|
114
|
+
{ className: 'p-2 text-fg-base', onClick: track },
|
|
115
|
+
{ className: 'text-fg-mute', onClick: open, id: 'menu' },
|
|
116
|
+
);
|
|
117
|
+
// merged.className → 'p-2 text-fg-mute'
|
|
118
|
+
// merged.onClick() → track(), then open()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Signature:
|
|
53
122
|
|
|
54
|
-
|
|
123
|
+
```ts
|
|
124
|
+
const mergeProps: <
|
|
125
|
+
A extends Record<string, unknown>,
|
|
126
|
+
B extends Record<string, unknown>,
|
|
127
|
+
>(
|
|
128
|
+
base: A,
|
|
129
|
+
override: B,
|
|
130
|
+
) => Omit<A, keyof B> & B;
|
|
55
131
|
```
|
|
56
132
|
|
|
57
|
-
###
|
|
133
|
+
### mergeRefs
|
|
58
134
|
|
|
59
|
-
|
|
135
|
+
Combines several refs into one callback ref, so a component can keep an
|
|
136
|
+
internal ref while forwarding the caller's. Object refs are assigned, function
|
|
137
|
+
refs are called, and `null` / `undefined` are skipped. The returned callback
|
|
138
|
+
returns a cleanup (React 19 ref cleanup) that resets object refs to `null` and
|
|
139
|
+
runs each function ref's own cleanup — or calls it with `null` when it did not
|
|
140
|
+
return one.
|
|
60
141
|
|
|
61
142
|
```tsx
|
|
62
|
-
import {
|
|
143
|
+
import { mergeRefs } from '@k8ordo/ui';
|
|
144
|
+
|
|
145
|
+
const Field = ({ ref, ...rest }: { ref?: Ref<HTMLInputElement> }) => {
|
|
146
|
+
const internalRef = useRef<HTMLInputElement>(null);
|
|
147
|
+
return <input ref={mergeRefs(internalRef, ref)} {...rest} />;
|
|
148
|
+
};
|
|
63
149
|
```
|
|
64
150
|
|
|
65
|
-
|
|
151
|
+
Signature:
|
|
66
152
|
|
|
67
|
-
|
|
153
|
+
```ts
|
|
154
|
+
const mergeRefs: <T>(
|
|
155
|
+
...refs: ReadonlyArray<Ref<T> | undefined>
|
|
156
|
+
) => RefCallback<T>;
|
|
157
|
+
```
|
|
68
158
|
|
|
69
|
-
|
|
70
|
-
import { isInternalRoute } from '@k8ordo/ui';
|
|
159
|
+
## Type definitions
|
|
71
160
|
|
|
72
|
-
|
|
73
|
-
|
|
161
|
+
### Status
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
type Status = 'success' | 'info' | 'warning' | 'error';
|
|
74
165
|
```
|
|
75
166
|
|
|
76
|
-
|
|
167
|
+
Used for the status of Alert, Badge, Toast, and similar components.
|
|
77
168
|
|
|
78
|
-
|
|
169
|
+
### Direction
|
|
79
170
|
|
|
80
171
|
```tsx
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const colors = findAllColors();
|
|
172
|
+
type Direction = 'up' | 'down' | 'right' | 'left';
|
|
84
173
|
```
|
|
85
174
|
|
|
86
|
-
|
|
175
|
+
Used to point ChevronIcon and similar icons.
|
|
87
176
|
|
|
88
|
-
|
|
177
|
+
### Placement
|
|
89
178
|
|
|
90
179
|
```tsx
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
180
|
+
type Placement =
|
|
181
|
+
| 'top'
|
|
182
|
+
| 'top-start'
|
|
183
|
+
| 'top-end'
|
|
184
|
+
| 'bottom'
|
|
185
|
+
| 'bottom-start'
|
|
186
|
+
| 'bottom-end'
|
|
187
|
+
| 'left'
|
|
188
|
+
| 'left-start'
|
|
189
|
+
| 'left-end'
|
|
190
|
+
| 'right'
|
|
191
|
+
| 'right-start'
|
|
192
|
+
| 'right-end';
|
|
94
193
|
```
|
|
95
194
|
|
|
96
|
-
|
|
195
|
+
Placement relative to an anchor element, for Popover, Tooltip, DropdownMenu,
|
|
196
|
+
and ListBox (the `placement` prop).
|
|
97
197
|
|
|
98
|
-
###
|
|
198
|
+
### ModalSide
|
|
99
199
|
|
|
100
200
|
```tsx
|
|
101
|
-
type
|
|
201
|
+
type ModalSide = 'center' | 'bottom' | 'left' | 'right';
|
|
102
202
|
```
|
|
103
203
|
|
|
104
|
-
|
|
204
|
+
Which viewport edge a Modal sticks to (the `side` prop). It is a different
|
|
205
|
+
idea from `Placement`, which is relative to an anchor, so the prop name differs
|
|
206
|
+
too.
|
|
105
207
|
|
|
106
|
-
###
|
|
208
|
+
### DrawerSide
|
|
107
209
|
|
|
108
210
|
```tsx
|
|
109
|
-
type
|
|
211
|
+
type DrawerSide = Extract<ModalSide, 'left' | 'right'>;
|
|
110
212
|
```
|
|
111
213
|
|
|
112
|
-
|
|
214
|
+
The subset of `ModalSide` a Drawer accepts: a drawer always slides in from an
|
|
215
|
+
edge, so `center` is excluded.
|
|
113
216
|
|
|
114
217
|
### Option
|
|
115
218
|
|
|
116
219
|
```tsx
|
|
117
|
-
type Option = { value: string; label: string }
|
|
220
|
+
type Option = Readonly<{ value: string; label: string }>;
|
|
118
221
|
```
|
|
119
222
|
|
|
120
|
-
Select, Autocomplete
|
|
223
|
+
Used for the choices in Radio, Select, Autocomplete, and similar components.
|