@molecule/app-ui-react 1.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/LICENSE +115 -0
- package/README.md +2786 -0
- package/dist/components/Accordion.d.ts +12 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +80 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Alert.d.ts +26 -0
- package/dist/components/Alert.d.ts.map +1 -0
- package/dist/components/Alert.js +53 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AuthGuard.d.ts +66 -0
- package/dist/components/AuthGuard.d.ts.map +1 -0
- package/dist/components/AuthGuard.js +42 -0
- package/dist/components/AuthGuard.js.map +1 -0
- package/dist/components/Avatar.d.ts +12 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar.js +25 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/Badge.d.ts +12 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +18 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Button.d.ts +12 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +19 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Card.d.ts +34 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Card.js +71 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/Checkbox.d.ts +12 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +41 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/Dropdown.d.ts +38 -0
- package/dist/components/Dropdown.d.ts.map +1 -0
- package/dist/components/Dropdown.js +352 -0
- package/dist/components/Dropdown.js.map +1 -0
- package/dist/components/EmptyState.d.ts +15 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +20 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/FloatingInput.d.ts +22 -0
- package/dist/components/FloatingInput.d.ts.map +1 -0
- package/dist/components/FloatingInput.js +38 -0
- package/dist/components/FloatingInput.js.map +1 -0
- package/dist/components/Form.d.ts +22 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Form.js +81 -0
- package/dist/components/Form.js.map +1 -0
- package/dist/components/Icon.d.ts +48 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +46 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/Input.d.ts +12 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +25 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/LanguagePicker.d.ts +60 -0
- package/dist/components/LanguagePicker.d.ts.map +1 -0
- package/dist/components/LanguagePicker.js +45 -0
- package/dist/components/LanguagePicker.js.map +1 -0
- package/dist/components/Layout.d.ts +24 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/Layout.js +104 -0
- package/dist/components/Layout.js.map +1 -0
- package/dist/components/Modal.d.ts +32 -0
- package/dist/components/Modal.d.ts.map +1 -0
- package/dist/components/Modal.js +235 -0
- package/dist/components/Modal.js.map +1 -0
- package/dist/components/PageHeader.d.ts +15 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PageHeader.js +20 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PageShell.d.ts +15 -0
- package/dist/components/PageShell.d.ts.map +1 -0
- package/dist/components/PageShell.js +20 -0
- package/dist/components/PageShell.js.map +1 -0
- package/dist/components/Pagination.d.ts +12 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +78 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/PanelClose.d.ts +40 -0
- package/dist/components/PanelClose.d.ts.map +1 -0
- package/dist/components/PanelClose.js +32 -0
- package/dist/components/PanelClose.js.map +1 -0
- package/dist/components/Progress.d.ts +45 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +21 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/RadioGroup.d.ts +12 -0
- package/dist/components/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup.js +34 -0
- package/dist/components/RadioGroup.js.map +1 -0
- package/dist/components/Select.d.ts +12 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Select.js +57 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/Separator.d.ts +25 -0
- package/dist/components/Separator.d.ts.map +1 -0
- package/dist/components/Separator.js +18 -0
- package/dist/components/Separator.js.map +1 -0
- package/dist/components/SidebarUserCard.d.ts +60 -0
- package/dist/components/SidebarUserCard.d.ts.map +1 -0
- package/dist/components/SidebarUserCard.js +45 -0
- package/dist/components/SidebarUserCard.js.map +1 -0
- package/dist/components/Skeleton.d.ts +26 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +45 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Spinner.d.ts +17 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +32 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/Switch.d.ts +12 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +52 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/Table.d.ts +12 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Table.js +53 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs.d.ts +12 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs.js +72 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Textarea.d.ts +12 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +66 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/ThemeToggle.d.ts +43 -0
- package/dist/components/ThemeToggle.d.ts.map +1 -0
- package/dist/components/ThemeToggle.js +30 -0
- package/dist/components/ThemeToggle.js.map +1 -0
- package/dist/components/Toast.d.ts +61 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +159 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Tooltip.d.ts +21 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +245 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/UserMenu.d.ts +59 -0
- package/dist/components/UserMenu.d.ts.map +1 -0
- package/dist/components/UserMenu.js +34 -0
- package/dist/components/UserMenu.js.map +1 -0
- package/dist/components/UserMenuPopover.d.ts +139 -0
- package/dist/components/UserMenuPopover.d.ts.map +1 -0
- package/dist/components/UserMenuPopover.js +173 -0
- package/dist/components/UserMenuPopover.js.map +1 -0
- package/dist/components/index.d.ts +43 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +43 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities/index.d.ts +8 -0
- package/dist/utilities/index.d.ts.map +1 -0
- package/dist/utilities/index.js +8 -0
- package/dist/utilities/index.js.map +1 -0
- package/dist/utilities/initials.d.ts +13 -0
- package/dist/utilities/initials.d.ts.map +1 -0
- package/dist/utilities/initials.js +23 -0
- package/dist/utilities/initials.js.map +1 -0
- package/dist/utilities/renderIcon.d.ts +21 -0
- package/dist/utilities/renderIcon.d.ts.map +1 -0
- package/dist/utilities/renderIcon.js +40 -0
- package/dist/utilities/renderIcon.js.map +1 -0
- package/dist/utilities.d.ts +12 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +14 -0
- package/dist/utilities.js.map +1 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,2786 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
3
|
+
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
|
+
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
|
+
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
+
Generated: 2026-08-04T00:41:31.054Z
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# @molecule/app-ui-react
|
|
10
|
+
|
|
11
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
+
|
|
15
|
+
React UI components for molecule.dev.
|
|
16
|
+
|
|
17
|
+
Provides React implementations of the `@molecule/app-ui` component
|
|
18
|
+
interfaces using the UIClassMap abstraction from `@molecule/app-ui`.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { setClassMap } from '@molecule/app-ui'
|
|
24
|
+
import { classMap } from '@molecule/app-ui-tailwind'
|
|
25
|
+
import { Button, Modal, Icon, EmptyState } from '@molecule/app-ui-react'
|
|
26
|
+
import { useState } from 'react'
|
|
27
|
+
|
|
28
|
+
// Once at startup, before first render — components throw without it:
|
|
29
|
+
setClassMap(classMap)
|
|
30
|
+
|
|
31
|
+
function ConfirmDelete({ onConfirm }: { onConfirm: () => void }) {
|
|
32
|
+
const [open, setOpen] = useState(false)
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<Button color="error" onClick={() => setOpen(true)}>
|
|
36
|
+
<Icon name="trash" size={16} /> Delete
|
|
37
|
+
</Button>
|
|
38
|
+
<Modal
|
|
39
|
+
open={open}
|
|
40
|
+
onClose={() => setOpen(false)}
|
|
41
|
+
title="Delete item?"
|
|
42
|
+
data-mol-id="confirm-delete"
|
|
43
|
+
>
|
|
44
|
+
<EmptyState title="This cannot be undone" />
|
|
45
|
+
<Button color="error" onClick={onConfirm}>
|
|
46
|
+
Confirm
|
|
47
|
+
</Button>
|
|
48
|
+
</Modal>
|
|
49
|
+
</>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Type
|
|
55
|
+
|
|
56
|
+
`framework`
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install @molecule/app-ui-react @molecule/app-i18n @molecule/app-icons @molecule/app-react @molecule/app-ui react react-dom react-router
|
|
62
|
+
npm install -D @types/react @types/react-dom
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API
|
|
66
|
+
|
|
67
|
+
### Interfaces
|
|
68
|
+
|
|
69
|
+
#### `AccordionItem`
|
|
70
|
+
|
|
71
|
+
A single item in an Accordion component.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface AccordionItem<T = string> {
|
|
75
|
+
/**
|
|
76
|
+
* Item value/id.
|
|
77
|
+
*/
|
|
78
|
+
value: T
|
|
79
|
+
/**
|
|
80
|
+
* Item header/trigger.
|
|
81
|
+
*/
|
|
82
|
+
header: Children
|
|
83
|
+
/**
|
|
84
|
+
* Item content.
|
|
85
|
+
*/
|
|
86
|
+
content: Children
|
|
87
|
+
/**
|
|
88
|
+
* Whether the item is disabled.
|
|
89
|
+
*/
|
|
90
|
+
disabled?: boolean
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### `AccordionProps`
|
|
95
|
+
|
|
96
|
+
Props for the Accordion component.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
interface AccordionProps<T = string> extends BaseProps {
|
|
100
|
+
/**
|
|
101
|
+
* Accordion items.
|
|
102
|
+
*/
|
|
103
|
+
items: AccordionItem<T>[]
|
|
104
|
+
/**
|
|
105
|
+
* Expanded item(s).
|
|
106
|
+
*/
|
|
107
|
+
value?: T | T[]
|
|
108
|
+
/**
|
|
109
|
+
* Default expanded item(s).
|
|
110
|
+
*/
|
|
111
|
+
defaultValue?: T | T[]
|
|
112
|
+
/**
|
|
113
|
+
* Change handler.
|
|
114
|
+
*/
|
|
115
|
+
onChange?: (value: T | T[]) => void
|
|
116
|
+
/**
|
|
117
|
+
* Whether multiple items can be expanded.
|
|
118
|
+
*/
|
|
119
|
+
multiple?: boolean
|
|
120
|
+
/**
|
|
121
|
+
* Whether items can be collapsed.
|
|
122
|
+
*/
|
|
123
|
+
collapsible?: boolean
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### `AlertProps`
|
|
128
|
+
|
|
129
|
+
Props for the Alert component.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
interface AlertProps extends HTMLElementProps {
|
|
133
|
+
/**
|
|
134
|
+
* Alert content.
|
|
135
|
+
*/
|
|
136
|
+
children?: Children
|
|
137
|
+
/**
|
|
138
|
+
* Alert title.
|
|
139
|
+
*/
|
|
140
|
+
title?: string
|
|
141
|
+
/**
|
|
142
|
+
* Alert status/type.
|
|
143
|
+
*/
|
|
144
|
+
status?: ColorVariant
|
|
145
|
+
/**
|
|
146
|
+
* Alert variant.
|
|
147
|
+
*/
|
|
148
|
+
variant?: 'solid' | 'subtle' | 'outline' | 'left-accent'
|
|
149
|
+
/**
|
|
150
|
+
* Whether the alert is dismissible.
|
|
151
|
+
*/
|
|
152
|
+
dismissible?: boolean
|
|
153
|
+
/**
|
|
154
|
+
* Called when dismissed.
|
|
155
|
+
*/
|
|
156
|
+
onDismiss?: () => void
|
|
157
|
+
/**
|
|
158
|
+
* Icon to display.
|
|
159
|
+
*/
|
|
160
|
+
icon?: Children
|
|
161
|
+
/**
|
|
162
|
+
* Accessible label for the dismiss button.
|
|
163
|
+
* @default 'Dismiss'
|
|
164
|
+
*/
|
|
165
|
+
dismissLabel?: string
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### `AuthGuardProps`
|
|
170
|
+
|
|
171
|
+
Props for {@link AuthGuard}.
|
|
172
|
+
|
|
173
|
+
All props are optional — the default behavior (loading tag → redirect
|
|
174
|
+
to `/login` → `<Outlet />`) matches the bare-bones guard apps were
|
|
175
|
+
shipping locally. The props let apps customize per-call without
|
|
176
|
+
forking the component.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
interface AuthGuardProps {
|
|
180
|
+
/**
|
|
181
|
+
* Element rendered while `useAuth().state.initialized` is `false`.
|
|
182
|
+
* Overrides the default `<div data-mol-id="auth-guard-loading">…</div>`
|
|
183
|
+
* loading tag — pass a full-page spinner or any other UI you want
|
|
184
|
+
* during the auth bootstrap window.
|
|
185
|
+
*/
|
|
186
|
+
loadingFallback?: ReactNode
|
|
187
|
+
/**
|
|
188
|
+
* i18n key used for the default loading-tag text. Defaults to
|
|
189
|
+
* `'common.loading'`. Ignored when `loadingFallback` is set.
|
|
190
|
+
*/
|
|
191
|
+
loadingKey?: string
|
|
192
|
+
/**
|
|
193
|
+
* Fallback text if the i18n key is missing. Defaults to `'Loading...'`
|
|
194
|
+
* (the project-canonical ASCII glyph — Phase C of the locale
|
|
195
|
+
* canonicalization plan). Ignored when `loadingFallback` is set.
|
|
196
|
+
*/
|
|
197
|
+
loadingDefault?: string
|
|
198
|
+
/**
|
|
199
|
+
* Path to redirect to when the user is not authenticated. Defaults to
|
|
200
|
+
* `'/login'`. The current `useLocation()` is preserved as `state.from`
|
|
201
|
+
* for post-login restoration.
|
|
202
|
+
*/
|
|
203
|
+
loginPath?: string
|
|
204
|
+
/**
|
|
205
|
+
* Callback invoked when `isAuthenticated` transitions to `true` (or is
|
|
206
|
+
* already `true` on first render). Useful for one-shot per-app
|
|
207
|
+
* bootstrap effects (e.g. seeding fixture data). The caller is
|
|
208
|
+
* responsible for idempotency if the auth state can flip back and
|
|
209
|
+
* forth — this fires on every transition.
|
|
210
|
+
*/
|
|
211
|
+
onAuthenticated?: () => void
|
|
212
|
+
/**
|
|
213
|
+
* Children to render when authenticated. Defaults to `<Outlet />`,
|
|
214
|
+
* which is the React Router pattern this guard is designed for.
|
|
215
|
+
*/
|
|
216
|
+
children?: ReactNode
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `AvatarProps`
|
|
221
|
+
|
|
222
|
+
Props for the Avatar component.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
interface AvatarProps extends HTMLElementProps {
|
|
226
|
+
/**
|
|
227
|
+
* Image source URL.
|
|
228
|
+
*/
|
|
229
|
+
src?: string
|
|
230
|
+
/**
|
|
231
|
+
* Alt text for the image.
|
|
232
|
+
*/
|
|
233
|
+
alt?: string
|
|
234
|
+
/**
|
|
235
|
+
* Name for fallback initials.
|
|
236
|
+
*/
|
|
237
|
+
name?: string
|
|
238
|
+
/**
|
|
239
|
+
* Avatar size.
|
|
240
|
+
*/
|
|
241
|
+
size?: Size | number
|
|
242
|
+
/**
|
|
243
|
+
* Whether the avatar is rounded.
|
|
244
|
+
*/
|
|
245
|
+
rounded?: boolean
|
|
246
|
+
/**
|
|
247
|
+
* Fallback element when no image.
|
|
248
|
+
*/
|
|
249
|
+
fallback?: Children
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### `BadgeProps`
|
|
254
|
+
|
|
255
|
+
Props for the Badge component (status labels, counts, tags).
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
interface BadgeProps extends HTMLElementProps {
|
|
259
|
+
/**
|
|
260
|
+
* Badge content.
|
|
261
|
+
*/
|
|
262
|
+
children?: Children
|
|
263
|
+
/**
|
|
264
|
+
* Badge color.
|
|
265
|
+
*/
|
|
266
|
+
color?: ColorVariant
|
|
267
|
+
/**
|
|
268
|
+
* Badge variant.
|
|
269
|
+
*/
|
|
270
|
+
variant?: 'solid' | 'outline' | 'subtle'
|
|
271
|
+
/**
|
|
272
|
+
* Badge size.
|
|
273
|
+
*/
|
|
274
|
+
size?: Size
|
|
275
|
+
/**
|
|
276
|
+
* Whether the badge is rounded.
|
|
277
|
+
*/
|
|
278
|
+
rounded?: boolean
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### `BaseProps`
|
|
283
|
+
|
|
284
|
+
Base props shared by all components.
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
interface BaseProps {
|
|
288
|
+
/**
|
|
289
|
+
* Additional CSS class name(s).
|
|
290
|
+
*/
|
|
291
|
+
className?: string
|
|
292
|
+
/**
|
|
293
|
+
* Inline styles.
|
|
294
|
+
*/
|
|
295
|
+
style?: CSSProperties
|
|
296
|
+
/**
|
|
297
|
+
* Test ID for automated testing.
|
|
298
|
+
*/
|
|
299
|
+
testId?: string
|
|
300
|
+
/**
|
|
301
|
+
* Automation ID for AI agents and E2E tests. Maps to the `data-mol-id`
|
|
302
|
+
* HTML attribute. Use `molId()` from `./automation.js` to generate
|
|
303
|
+
* semantic IDs. (Tooling only — screen readers do not expose `data-*`
|
|
304
|
+
* attributes; accessible names come from labels/`aria-*`.)
|
|
305
|
+
*/
|
|
306
|
+
automationId?: string
|
|
307
|
+
/**
|
|
308
|
+
* Whether the component is disabled.
|
|
309
|
+
*/
|
|
310
|
+
disabled?: boolean
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
#### `ButtonElementProps`
|
|
315
|
+
|
|
316
|
+
Base props for button elements.
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
interface ButtonElementProps extends HTMLElementProps {
|
|
320
|
+
type?: 'button' | 'submit' | 'reset'
|
|
321
|
+
name?: string
|
|
322
|
+
value?: string
|
|
323
|
+
form?: string
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### `ButtonProps`
|
|
328
|
+
|
|
329
|
+
Props for the Button component.
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
interface ButtonProps extends ButtonElementProps {
|
|
333
|
+
/**
|
|
334
|
+
* Button content.
|
|
335
|
+
*/
|
|
336
|
+
children?: Children
|
|
337
|
+
/**
|
|
338
|
+
* Visual variant.
|
|
339
|
+
*/
|
|
340
|
+
variant?: ButtonVariant
|
|
341
|
+
/**
|
|
342
|
+
* Color scheme.
|
|
343
|
+
*/
|
|
344
|
+
color?: ColorVariant
|
|
345
|
+
/**
|
|
346
|
+
* Button size.
|
|
347
|
+
*/
|
|
348
|
+
size?: ButtonSize
|
|
349
|
+
/**
|
|
350
|
+
* Whether the button is in a loading state.
|
|
351
|
+
*/
|
|
352
|
+
loading?: boolean
|
|
353
|
+
/**
|
|
354
|
+
* Loading text to display.
|
|
355
|
+
*/
|
|
356
|
+
loadingText?: string
|
|
357
|
+
/**
|
|
358
|
+
* Whether the button takes full width.
|
|
359
|
+
*/
|
|
360
|
+
fullWidth?: boolean
|
|
361
|
+
/**
|
|
362
|
+
* Icon to display before the label.
|
|
363
|
+
*/
|
|
364
|
+
leftIcon?: Children
|
|
365
|
+
/**
|
|
366
|
+
* Icon to display after the label.
|
|
367
|
+
*/
|
|
368
|
+
rightIcon?: Children
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
#### `CardProps`
|
|
373
|
+
|
|
374
|
+
Props for the Card container component (elevated, outlined, or filled surface).
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
interface CardProps extends HTMLElementProps {
|
|
378
|
+
/**
|
|
379
|
+
* Card content.
|
|
380
|
+
*/
|
|
381
|
+
children?: Children
|
|
382
|
+
/**
|
|
383
|
+
* Card variant.
|
|
384
|
+
*/
|
|
385
|
+
variant?: 'elevated' | 'outlined' | 'filled'
|
|
386
|
+
/**
|
|
387
|
+
* Whether the card is interactive (clickable).
|
|
388
|
+
*/
|
|
389
|
+
interactive?: boolean
|
|
390
|
+
/**
|
|
391
|
+
* Padding size.
|
|
392
|
+
*/
|
|
393
|
+
padding?: Size | 'none'
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
#### `CheckboxProps`
|
|
398
|
+
|
|
399
|
+
Props for the Checkbox component.
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
interface CheckboxProps extends InputElementProps {
|
|
403
|
+
/**
|
|
404
|
+
* Checkbox label.
|
|
405
|
+
*/
|
|
406
|
+
label?: Children
|
|
407
|
+
/**
|
|
408
|
+
* Whether the checkbox is checked.
|
|
409
|
+
*/
|
|
410
|
+
checked?: boolean
|
|
411
|
+
/**
|
|
412
|
+
* Whether the checkbox is in an indeterminate state.
|
|
413
|
+
*/
|
|
414
|
+
indeterminate?: boolean
|
|
415
|
+
/**
|
|
416
|
+
* Checkbox size.
|
|
417
|
+
*/
|
|
418
|
+
size?: Size
|
|
419
|
+
/**
|
|
420
|
+
* Error message.
|
|
421
|
+
*/
|
|
422
|
+
error?: string
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### `ContainerProps`
|
|
427
|
+
|
|
428
|
+
Props for the Container layout component.
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
interface ContainerProps extends HTMLElementProps {
|
|
432
|
+
/**
|
|
433
|
+
* Container content.
|
|
434
|
+
*/
|
|
435
|
+
children?: Children
|
|
436
|
+
/**
|
|
437
|
+
* Maximum width.
|
|
438
|
+
*/
|
|
439
|
+
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full' | string
|
|
440
|
+
/**
|
|
441
|
+
* Whether to center the container.
|
|
442
|
+
*/
|
|
443
|
+
centered?: boolean
|
|
444
|
+
/**
|
|
445
|
+
* Horizontal padding.
|
|
446
|
+
*/
|
|
447
|
+
paddingX?: Size | string
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### `CSSProperties`
|
|
452
|
+
|
|
453
|
+
Framework-agnostic CSS properties.
|
|
454
|
+
Mirrors React.CSSProperties but without React dependency.
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
interface CSSProperties {
|
|
458
|
+
[key: string]: string | number | undefined
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### `FlexProps`
|
|
463
|
+
|
|
464
|
+
Flex container props.
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
interface FlexProps extends HTMLElementProps {
|
|
468
|
+
/**
|
|
469
|
+
* Flex content.
|
|
470
|
+
*/
|
|
471
|
+
children?: Children
|
|
472
|
+
/**
|
|
473
|
+
* Flex direction.
|
|
474
|
+
*/
|
|
475
|
+
direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse'
|
|
476
|
+
/**
|
|
477
|
+
* Justify content.
|
|
478
|
+
*/
|
|
479
|
+
justify?: 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly'
|
|
480
|
+
/**
|
|
481
|
+
* Align items.
|
|
482
|
+
*/
|
|
483
|
+
align?: 'start' | 'end' | 'center' | 'baseline' | 'stretch'
|
|
484
|
+
/**
|
|
485
|
+
* Flex wrap.
|
|
486
|
+
*/
|
|
487
|
+
wrap?: 'wrap' | 'nowrap' | 'wrap-reverse'
|
|
488
|
+
/**
|
|
489
|
+
* Gap between items.
|
|
490
|
+
*/
|
|
491
|
+
gap?: Size | string | number
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### `FormElementProps`
|
|
496
|
+
|
|
497
|
+
Base props for form elements.
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
interface FormElementProps extends HTMLElementProps {
|
|
501
|
+
action?: string
|
|
502
|
+
method?: 'get' | 'post'
|
|
503
|
+
encType?: string
|
|
504
|
+
target?: string
|
|
505
|
+
noValidate?: boolean
|
|
506
|
+
autoComplete?: 'on' | 'off'
|
|
507
|
+
onSubmit?: FormEventHandler
|
|
508
|
+
onReset?: FormEventHandler
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
#### `FormFieldProps`
|
|
513
|
+
|
|
514
|
+
Form field wrapper props.
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
interface FormFieldProps extends HTMLElementProps {
|
|
518
|
+
/**
|
|
519
|
+
* Field content.
|
|
520
|
+
*/
|
|
521
|
+
children?: Children
|
|
522
|
+
/**
|
|
523
|
+
* Field label.
|
|
524
|
+
*/
|
|
525
|
+
label?: string
|
|
526
|
+
/**
|
|
527
|
+
* Field name.
|
|
528
|
+
*/
|
|
529
|
+
name?: string
|
|
530
|
+
/**
|
|
531
|
+
* Error message.
|
|
532
|
+
*/
|
|
533
|
+
error?: string
|
|
534
|
+
/**
|
|
535
|
+
* Hint/help text.
|
|
536
|
+
*/
|
|
537
|
+
hint?: string
|
|
538
|
+
/**
|
|
539
|
+
* Whether the field is required.
|
|
540
|
+
*/
|
|
541
|
+
required?: boolean
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
#### `FormProps`
|
|
546
|
+
|
|
547
|
+
Props for the Form component (wraps inputs with submission handling and validation).
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
interface FormProps extends FormElementProps {
|
|
551
|
+
/**
|
|
552
|
+
* Form content.
|
|
553
|
+
*/
|
|
554
|
+
children?: Children
|
|
555
|
+
/**
|
|
556
|
+
* Submit handler with form data.
|
|
557
|
+
*/
|
|
558
|
+
onFormSubmit?: (data: Record<string, unknown>) => void | Promise<void>
|
|
559
|
+
/**
|
|
560
|
+
* Whether the form is submitting.
|
|
561
|
+
*/
|
|
562
|
+
submitting?: boolean
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
#### `GridProps`
|
|
567
|
+
|
|
568
|
+
Grid container props.
|
|
569
|
+
|
|
570
|
+
```typescript
|
|
571
|
+
interface GridProps extends HTMLElementProps {
|
|
572
|
+
/**
|
|
573
|
+
* Grid content.
|
|
574
|
+
*/
|
|
575
|
+
children?: Children
|
|
576
|
+
/**
|
|
577
|
+
* Number of columns.
|
|
578
|
+
*/
|
|
579
|
+
columns?: number | string
|
|
580
|
+
/**
|
|
581
|
+
* Number of rows.
|
|
582
|
+
*/
|
|
583
|
+
rows?: number | string
|
|
584
|
+
/**
|
|
585
|
+
* Gap between items.
|
|
586
|
+
*/
|
|
587
|
+
gap?: Size | string | number
|
|
588
|
+
/**
|
|
589
|
+
* Column gap.
|
|
590
|
+
*/
|
|
591
|
+
columnGap?: Size | string | number
|
|
592
|
+
/**
|
|
593
|
+
* Row gap.
|
|
594
|
+
*/
|
|
595
|
+
rowGap?: Size | string | number
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
#### `HTMLElementProps`
|
|
600
|
+
|
|
601
|
+
Base props for HTML elements.
|
|
602
|
+
Framework bindings should extend this with framework-specific attributes.
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
interface HTMLElementProps extends BaseProps {
|
|
606
|
+
id?: string
|
|
607
|
+
title?: string
|
|
608
|
+
tabIndex?: number
|
|
609
|
+
role?: string
|
|
610
|
+
'aria-label'?: string
|
|
611
|
+
'aria-labelledby'?: string
|
|
612
|
+
'aria-describedby'?: string
|
|
613
|
+
'aria-hidden'?: boolean
|
|
614
|
+
'aria-disabled'?: boolean
|
|
615
|
+
'aria-expanded'?: boolean
|
|
616
|
+
'aria-selected'?: boolean
|
|
617
|
+
'aria-checked'?: boolean | 'mixed'
|
|
618
|
+
'aria-pressed'?: boolean | 'mixed'
|
|
619
|
+
'aria-invalid'?: boolean
|
|
620
|
+
'aria-required'?: boolean
|
|
621
|
+
'aria-readonly'?: boolean
|
|
622
|
+
'aria-busy'?: boolean
|
|
623
|
+
'aria-live'?: 'off' | 'polite' | 'assertive'
|
|
624
|
+
onClick?: MouseEventHandler
|
|
625
|
+
onDoubleClick?: MouseEventHandler
|
|
626
|
+
onMouseEnter?: MouseEventHandler
|
|
627
|
+
onMouseLeave?: MouseEventHandler
|
|
628
|
+
onFocus?: FocusEventHandler
|
|
629
|
+
onBlur?: FocusEventHandler
|
|
630
|
+
onKeyDown?: KeyboardEventHandler
|
|
631
|
+
onKeyUp?: KeyboardEventHandler
|
|
632
|
+
onKeyPress?: KeyboardEventHandler
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
#### `IconProps`
|
|
637
|
+
|
|
638
|
+
Props for {@link Icon}.
|
|
639
|
+
|
|
640
|
+
Extends `SVGProps<SVGSVGElement>` so callers can pass any SVG / HTML
|
|
641
|
+
attribute the underlying `<svg>` accepts, including `data-mol-id`,
|
|
642
|
+
`aria-*`, `role`, event handlers, `style`, etc. — without the
|
|
643
|
+
component needing to enumerate them.
|
|
644
|
+
|
|
645
|
+
```typescript
|
|
646
|
+
interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'width' | 'height' | 'viewBox' | 'fill'> {
|
|
647
|
+
/**
|
|
648
|
+
* Name of the glyph to look up in the bonded icon set. Typed as
|
|
649
|
+
* {@link IconName} so a typo fails the type-check instead of throwing at
|
|
650
|
+
* render time; sets with extra glyphs augment `CustomIconNames` in
|
|
651
|
+
* `@molecule/app-icons` to widen it.
|
|
652
|
+
*/
|
|
653
|
+
name: IconName
|
|
654
|
+
/** Width and height of the rendered SVG in pixels. Defaults to 20. */
|
|
655
|
+
size?: number
|
|
656
|
+
/** Class name forwarded to the root `<svg>`. */
|
|
657
|
+
className?: string
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
#### `InputElementProps`
|
|
662
|
+
|
|
663
|
+
Base props for input elements.
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
interface InputElementProps extends HTMLElementProps {
|
|
667
|
+
name?: string
|
|
668
|
+
value?: string | number | readonly string[]
|
|
669
|
+
defaultValue?: string | number | readonly string[]
|
|
670
|
+
placeholder?: string
|
|
671
|
+
required?: boolean
|
|
672
|
+
readOnly?: boolean
|
|
673
|
+
autoFocus?: boolean
|
|
674
|
+
autoComplete?: string
|
|
675
|
+
maxLength?: number
|
|
676
|
+
minLength?: number
|
|
677
|
+
pattern?: string
|
|
678
|
+
onChange?: ChangeEventHandler
|
|
679
|
+
onInput?: FormEventHandler
|
|
680
|
+
}
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
#### `InputProps`
|
|
684
|
+
|
|
685
|
+
Props for the Input component (text field, email, password, etc.).
|
|
686
|
+
|
|
687
|
+
```typescript
|
|
688
|
+
interface InputProps extends InputElementProps {
|
|
689
|
+
/**
|
|
690
|
+
* Input type.
|
|
691
|
+
*/
|
|
692
|
+
type?: InputType
|
|
693
|
+
/**
|
|
694
|
+
* Input size.
|
|
695
|
+
*/
|
|
696
|
+
size?: Size
|
|
697
|
+
/**
|
|
698
|
+
* Horizontal text alignment inside the input (see
|
|
699
|
+
* {@link InputClassOptions.align}). Defaults to the bond's own style.
|
|
700
|
+
*/
|
|
701
|
+
align?: 'left' | 'center'
|
|
702
|
+
/**
|
|
703
|
+
* Label text.
|
|
704
|
+
*/
|
|
705
|
+
label?: string
|
|
706
|
+
/**
|
|
707
|
+
* Error message.
|
|
708
|
+
*/
|
|
709
|
+
error?: string
|
|
710
|
+
/**
|
|
711
|
+
* Hint/help text.
|
|
712
|
+
*/
|
|
713
|
+
hint?: string
|
|
714
|
+
/**
|
|
715
|
+
* Element to display on the left.
|
|
716
|
+
*/
|
|
717
|
+
leftElement?: Children
|
|
718
|
+
/**
|
|
719
|
+
* Element to display on the right.
|
|
720
|
+
*/
|
|
721
|
+
rightElement?: Children
|
|
722
|
+
/**
|
|
723
|
+
* Whether to show a clear button.
|
|
724
|
+
*/
|
|
725
|
+
clearable?: boolean
|
|
726
|
+
/**
|
|
727
|
+
* Called when the clear button is clicked.
|
|
728
|
+
*/
|
|
729
|
+
onClear?: () => void
|
|
730
|
+
/**
|
|
731
|
+
* Accessible label for the clear button.
|
|
732
|
+
* @default 'Clear'
|
|
733
|
+
*/
|
|
734
|
+
clearLabel?: string
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
#### `LanguagePickerProps`
|
|
739
|
+
|
|
740
|
+
Props for {@link LanguagePicker}.
|
|
741
|
+
|
|
742
|
+
Extends standard `<button>` attributes so callers can pass any extra
|
|
743
|
+
`data-*`, `aria-*`, event handler, or `style` prop without forking the
|
|
744
|
+
component. The named props let apps customize the trigger label, icon,
|
|
745
|
+
size, and modal heading without spreading attribute concerns.
|
|
746
|
+
|
|
747
|
+
```typescript
|
|
748
|
+
interface LanguagePickerProps extends Omit<
|
|
749
|
+
ButtonHTMLAttributes<HTMLButtonElement>,
|
|
750
|
+
'aria-label' | 'onClick' | 'type' | 'children'
|
|
751
|
+
> {
|
|
752
|
+
/** i18n key for the trigger button label / aria-label. Defaults to `'footer.language'`. */
|
|
753
|
+
labelKey?: string
|
|
754
|
+
/** Fallback label if the i18n key is missing. Defaults to `'Language'`. */
|
|
755
|
+
labelDefault?: string
|
|
756
|
+
/** i18n key for the modal title. Defaults to `'languagePicker.modalTitle'`. */
|
|
757
|
+
modalTitleKey?: string
|
|
758
|
+
/** Fallback modal title if the i18n key is missing. Defaults to `'Choose language'`. */
|
|
759
|
+
modalTitleDefault?: string
|
|
760
|
+
/** Icon glyph to render before the current locale name. Defaults to `'globe'`. */
|
|
761
|
+
icon?: IconName
|
|
762
|
+
/** Pixel size for the rendered icon. Defaults to `16`. */
|
|
763
|
+
iconSize?: number
|
|
764
|
+
/**
|
|
765
|
+
* What to render inside the trigger button.
|
|
766
|
+
*
|
|
767
|
+
* - `'name'` — globe icon + current locale's native name (e.g. `🌐 English`).
|
|
768
|
+
* This is the default; matches the molecule-dev footer pattern.
|
|
769
|
+
* - `'code'` — globe icon + lowercase locale code (e.g. `🌐 en`). Useful in
|
|
770
|
+
* tight chrome where the long native name (e.g. "Bahasa Indonesia") would wrap.
|
|
771
|
+
* - `'icon'` — globe icon only. Useful in icon-bar headers.
|
|
772
|
+
*/
|
|
773
|
+
display?: 'name' | 'code' | 'icon'
|
|
774
|
+
/** Optional className appended to the trigger button. */
|
|
775
|
+
className?: string
|
|
776
|
+
/** Optional render override: receives `{ open }` and replaces the default trigger. */
|
|
777
|
+
renderTrigger?: (open: () => void) => ReactNode
|
|
778
|
+
}
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
#### `ModalProps`
|
|
782
|
+
|
|
783
|
+
Props for the Modal/Dialog component.
|
|
784
|
+
|
|
785
|
+
```typescript
|
|
786
|
+
interface ModalProps extends HTMLElementProps {
|
|
787
|
+
/**
|
|
788
|
+
* Whether the modal is open.
|
|
789
|
+
*/
|
|
790
|
+
open: boolean
|
|
791
|
+
/**
|
|
792
|
+
* Called when the modal should close.
|
|
793
|
+
*/
|
|
794
|
+
onClose: () => void
|
|
795
|
+
/**
|
|
796
|
+
* Modal title.
|
|
797
|
+
*/
|
|
798
|
+
title?: string
|
|
799
|
+
/**
|
|
800
|
+
* Modal content.
|
|
801
|
+
*/
|
|
802
|
+
children?: Children
|
|
803
|
+
/**
|
|
804
|
+
* Modal size.
|
|
805
|
+
*/
|
|
806
|
+
size?: ModalSize
|
|
807
|
+
/**
|
|
808
|
+
* Whether to show a close button.
|
|
809
|
+
*/
|
|
810
|
+
showCloseButton?: boolean
|
|
811
|
+
/**
|
|
812
|
+
* Whether clicking the overlay closes the modal.
|
|
813
|
+
*/
|
|
814
|
+
closeOnOverlayClick?: boolean
|
|
815
|
+
/**
|
|
816
|
+
* Whether pressing Escape closes the modal.
|
|
817
|
+
*/
|
|
818
|
+
closeOnEscape?: boolean
|
|
819
|
+
/**
|
|
820
|
+
* Footer content (typically action buttons).
|
|
821
|
+
*/
|
|
822
|
+
footer?: Children
|
|
823
|
+
/**
|
|
824
|
+
* Whether the modal is centered vertically.
|
|
825
|
+
*/
|
|
826
|
+
centered?: boolean
|
|
827
|
+
/**
|
|
828
|
+
* Whether to prevent body scroll when open.
|
|
829
|
+
*/
|
|
830
|
+
preventScroll?: boolean
|
|
831
|
+
/**
|
|
832
|
+
* Accessible label for the close button.
|
|
833
|
+
* @default 'Close'
|
|
834
|
+
*/
|
|
835
|
+
closeLabel?: string
|
|
836
|
+
}
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
#### `PaginationProps`
|
|
840
|
+
|
|
841
|
+
Props for the Pagination component (page navigation with current page, total, page size, and change callbacks).
|
|
842
|
+
|
|
843
|
+
```typescript
|
|
844
|
+
interface PaginationProps extends BaseProps {
|
|
845
|
+
/**
|
|
846
|
+
* Current page (1-indexed).
|
|
847
|
+
*/
|
|
848
|
+
page: number
|
|
849
|
+
/**
|
|
850
|
+
* Total number of pages.
|
|
851
|
+
*/
|
|
852
|
+
totalPages: number
|
|
853
|
+
/**
|
|
854
|
+
* Page change handler.
|
|
855
|
+
*/
|
|
856
|
+
onChange: (page: number) => void
|
|
857
|
+
/**
|
|
858
|
+
* Number of sibling pages to show.
|
|
859
|
+
*/
|
|
860
|
+
siblings?: number
|
|
861
|
+
/**
|
|
862
|
+
* Number of boundary pages to show.
|
|
863
|
+
*/
|
|
864
|
+
boundaries?: number
|
|
865
|
+
/**
|
|
866
|
+
* Pagination size.
|
|
867
|
+
*/
|
|
868
|
+
size?: Size
|
|
869
|
+
/**
|
|
870
|
+
* Whether to show first/last buttons.
|
|
871
|
+
*/
|
|
872
|
+
showFirstLast?: boolean
|
|
873
|
+
/**
|
|
874
|
+
* Whether to show previous/next buttons.
|
|
875
|
+
*/
|
|
876
|
+
showPrevNext?: boolean
|
|
877
|
+
/**
|
|
878
|
+
* Accessible labels for pagination controls.
|
|
879
|
+
*/
|
|
880
|
+
labels?: {
|
|
881
|
+
nav?: string
|
|
882
|
+
first?: string
|
|
883
|
+
previous?: string
|
|
884
|
+
next?: string
|
|
885
|
+
last?: string
|
|
886
|
+
goToPage?: (page: number) => string
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
#### `PanelCloseProviderProps`
|
|
892
|
+
|
|
893
|
+
Props for {@link PanelCloseProvider}.
|
|
894
|
+
|
|
895
|
+
```typescript
|
|
896
|
+
interface PanelCloseProviderProps {
|
|
897
|
+
/** Callback that dismisses the enclosing drawer/modal. */
|
|
898
|
+
close: () => void
|
|
899
|
+
/** Panel content that may call {@link usePanelClose}. */
|
|
900
|
+
children: ReactNode
|
|
901
|
+
}
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
#### `ProgressProps`
|
|
905
|
+
|
|
906
|
+
Props for the Progress component.
|
|
907
|
+
|
|
908
|
+
```typescript
|
|
909
|
+
interface ProgressProps extends BaseProps {
|
|
910
|
+
/**
|
|
911
|
+
* Progress value (0-100).
|
|
912
|
+
*/
|
|
913
|
+
value: number
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Maximum value.
|
|
917
|
+
*/
|
|
918
|
+
max?: number
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* Progress size.
|
|
922
|
+
*/
|
|
923
|
+
size?: Size
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Progress color.
|
|
927
|
+
*/
|
|
928
|
+
color?: ColorVariant
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Whether to show the value label.
|
|
932
|
+
*/
|
|
933
|
+
showValue?: boolean
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Accessible label.
|
|
937
|
+
*/
|
|
938
|
+
label?: string
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Whether the progress is indeterminate.
|
|
942
|
+
*/
|
|
943
|
+
indeterminate?: boolean
|
|
944
|
+
}
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
#### `RadioGroupProps`
|
|
948
|
+
|
|
949
|
+
Props for the RadioGroup component.
|
|
950
|
+
|
|
951
|
+
```typescript
|
|
952
|
+
interface RadioGroupProps<T = string> extends BaseProps {
|
|
953
|
+
/**
|
|
954
|
+
* Radio options.
|
|
955
|
+
*/
|
|
956
|
+
options: RadioOption<T>[]
|
|
957
|
+
/**
|
|
958
|
+
* Current value.
|
|
959
|
+
*/
|
|
960
|
+
value?: T
|
|
961
|
+
/**
|
|
962
|
+
* Change handler.
|
|
963
|
+
*/
|
|
964
|
+
onChange?: (value: T) => void
|
|
965
|
+
/**
|
|
966
|
+
* Radio size.
|
|
967
|
+
*/
|
|
968
|
+
size?: Size
|
|
969
|
+
/**
|
|
970
|
+
* Group label.
|
|
971
|
+
*/
|
|
972
|
+
label?: string
|
|
973
|
+
/**
|
|
974
|
+
* Shared `name` attribute for the group's radio inputs (used for native
|
|
975
|
+
* form submission). When omitted, a unique per-instance name is generated
|
|
976
|
+
* so separate groups never merge — the visible `label` is deliberately
|
|
977
|
+
* NOT used as the name, because two groups with the same label (e.g. two
|
|
978
|
+
* "Size" pickers) would otherwise form ONE native radio group and
|
|
979
|
+
* deselect each other.
|
|
980
|
+
*/
|
|
981
|
+
name?: string
|
|
982
|
+
/**
|
|
983
|
+
* Layout direction.
|
|
984
|
+
*/
|
|
985
|
+
direction?: 'horizontal' | 'vertical'
|
|
986
|
+
/**
|
|
987
|
+
* Error message.
|
|
988
|
+
*/
|
|
989
|
+
error?: string
|
|
990
|
+
}
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
#### `RadioOption`
|
|
994
|
+
|
|
995
|
+
A single option in a RadioGroup.
|
|
996
|
+
|
|
997
|
+
```typescript
|
|
998
|
+
interface RadioOption<T = string> {
|
|
999
|
+
/**
|
|
1000
|
+
* Option value.
|
|
1001
|
+
*/
|
|
1002
|
+
value: T
|
|
1003
|
+
/**
|
|
1004
|
+
* Display label.
|
|
1005
|
+
*/
|
|
1006
|
+
label: Children
|
|
1007
|
+
/**
|
|
1008
|
+
* Whether the option is disabled.
|
|
1009
|
+
*/
|
|
1010
|
+
disabled?: boolean
|
|
1011
|
+
}
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
#### `SelectElementProps`
|
|
1015
|
+
|
|
1016
|
+
Base props for select elements.
|
|
1017
|
+
|
|
1018
|
+
```typescript
|
|
1019
|
+
interface SelectElementProps extends HTMLElementProps {
|
|
1020
|
+
name?: string
|
|
1021
|
+
required?: boolean
|
|
1022
|
+
autoFocus?: boolean
|
|
1023
|
+
multiple?: boolean
|
|
1024
|
+
onChange?: ChangeEventHandler
|
|
1025
|
+
}
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
#### `SelectOption`
|
|
1029
|
+
|
|
1030
|
+
A single option in a Select dropdown.
|
|
1031
|
+
|
|
1032
|
+
```typescript
|
|
1033
|
+
interface SelectOption<T = string> {
|
|
1034
|
+
/**
|
|
1035
|
+
* Option value.
|
|
1036
|
+
*/
|
|
1037
|
+
value: T
|
|
1038
|
+
/**
|
|
1039
|
+
* Display label.
|
|
1040
|
+
*/
|
|
1041
|
+
label: string
|
|
1042
|
+
/**
|
|
1043
|
+
* Whether the option is disabled.
|
|
1044
|
+
*/
|
|
1045
|
+
disabled?: boolean
|
|
1046
|
+
/**
|
|
1047
|
+
* Option group (for grouped selects).
|
|
1048
|
+
*/
|
|
1049
|
+
group?: string
|
|
1050
|
+
}
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
#### `SelectProps`
|
|
1054
|
+
|
|
1055
|
+
Props for the Select dropdown component (single or multi-select).
|
|
1056
|
+
|
|
1057
|
+
```typescript
|
|
1058
|
+
interface SelectProps<T = string> extends SelectElementProps {
|
|
1059
|
+
/**
|
|
1060
|
+
* Select options.
|
|
1061
|
+
*/
|
|
1062
|
+
options: SelectOption<T>[]
|
|
1063
|
+
/**
|
|
1064
|
+
* Current value.
|
|
1065
|
+
*/
|
|
1066
|
+
value?: T
|
|
1067
|
+
/**
|
|
1068
|
+
* Change handler (with typed value).
|
|
1069
|
+
*/
|
|
1070
|
+
onValueChange?: (value: T) => void
|
|
1071
|
+
/**
|
|
1072
|
+
* Select size.
|
|
1073
|
+
*/
|
|
1074
|
+
size?: Size
|
|
1075
|
+
/**
|
|
1076
|
+
* Label text.
|
|
1077
|
+
*/
|
|
1078
|
+
label?: string
|
|
1079
|
+
/**
|
|
1080
|
+
* Placeholder text.
|
|
1081
|
+
*/
|
|
1082
|
+
placeholder?: string
|
|
1083
|
+
/**
|
|
1084
|
+
* Error message.
|
|
1085
|
+
*/
|
|
1086
|
+
error?: string
|
|
1087
|
+
/**
|
|
1088
|
+
* Hint/help text.
|
|
1089
|
+
*/
|
|
1090
|
+
hint?: string
|
|
1091
|
+
/**
|
|
1092
|
+
* Whether to allow clearing the selection.
|
|
1093
|
+
*/
|
|
1094
|
+
clearable?: boolean
|
|
1095
|
+
}
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
#### `SeparatorProps`
|
|
1099
|
+
|
|
1100
|
+
Props for the Separator component.
|
|
1101
|
+
|
|
1102
|
+
```typescript
|
|
1103
|
+
interface SeparatorProps extends BaseProps {
|
|
1104
|
+
/**
|
|
1105
|
+
* Orientation of the separator.
|
|
1106
|
+
*/
|
|
1107
|
+
orientation?: 'horizontal' | 'vertical'
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Decorative separators are purely visual.
|
|
1111
|
+
*/
|
|
1112
|
+
decorative?: boolean
|
|
1113
|
+
}
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
#### `SidebarUserCardProps`
|
|
1117
|
+
|
|
1118
|
+
Props for the {@link SidebarUserCard} component.
|
|
1119
|
+
|
|
1120
|
+
Extends standard `<button>` attributes so callers can pass extra
|
|
1121
|
+
`data-*`, `aria-*`, `style`, or event handler props onto the trigger
|
|
1122
|
+
button without forking. The named props below cover the common
|
|
1123
|
+
customization points.
|
|
1124
|
+
|
|
1125
|
+
```typescript
|
|
1126
|
+
interface SidebarUserCardProps extends Omit<
|
|
1127
|
+
ButtonHTMLAttributes<HTMLButtonElement>,
|
|
1128
|
+
'aria-label' | 'onClick' | 'children'
|
|
1129
|
+
> {
|
|
1130
|
+
/**
|
|
1131
|
+
* Panel content shown inside the drawer/modal (typically the app's
|
|
1132
|
+
* `SettingsPanel`). It can dismiss the drawer by calling
|
|
1133
|
+
* `usePanelClose()` — no `onClose` prop-threading required.
|
|
1134
|
+
*/
|
|
1135
|
+
children: ReactNode
|
|
1136
|
+
/**
|
|
1137
|
+
* Display name override. When omitted, falls back to
|
|
1138
|
+
* `useAuth().user?.name`, then `email`, then a guest label.
|
|
1139
|
+
*/
|
|
1140
|
+
name?: string
|
|
1141
|
+
/**
|
|
1142
|
+
* Secondary line under the name (role, plan, status, etc.).
|
|
1143
|
+
* Apps typically pass something like `t('sidebar.memberStatus', {}, { defaultValue: 'Premium Member' })`.
|
|
1144
|
+
* When omitted and the auth user has an email, the email is shown instead.
|
|
1145
|
+
*/
|
|
1146
|
+
secondaryLine?: string
|
|
1147
|
+
/** Optional avatar image URL — overrides `useAuth().user?.avatarUrl`. */
|
|
1148
|
+
avatarUrl?: string
|
|
1149
|
+
/** i18n key for the trigger button's aria-label. Default: `'sidebarUserCard.open'`. */
|
|
1150
|
+
ariaLabelKey?: string
|
|
1151
|
+
/** Fallback aria-label if the i18n key is missing. Default: `'Open account menu'`. */
|
|
1152
|
+
ariaLabelDefault?: string
|
|
1153
|
+
/**
|
|
1154
|
+
* `data-mol-id` for the trigger button. Defaults to
|
|
1155
|
+
* `'sidebar-user-card'`. Pass a different value (e.g. `'user-menu'`)
|
|
1156
|
+
* to disambiguate or align with an app's existing e2e selectors.
|
|
1157
|
+
*/
|
|
1158
|
+
dataMolId?: string
|
|
1159
|
+
}
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
#### `SkeletonProps`
|
|
1163
|
+
|
|
1164
|
+
Props for the Skeleton loading placeholder component.
|
|
1165
|
+
|
|
1166
|
+
```typescript
|
|
1167
|
+
interface SkeletonProps extends BaseProps {
|
|
1168
|
+
/**
|
|
1169
|
+
* Skeleton width.
|
|
1170
|
+
*/
|
|
1171
|
+
width?: string | number
|
|
1172
|
+
/**
|
|
1173
|
+
* Skeleton height.
|
|
1174
|
+
*/
|
|
1175
|
+
height?: string | number
|
|
1176
|
+
/**
|
|
1177
|
+
* Whether the skeleton is circular.
|
|
1178
|
+
*/
|
|
1179
|
+
circle?: boolean
|
|
1180
|
+
/**
|
|
1181
|
+
* Border radius.
|
|
1182
|
+
*/
|
|
1183
|
+
borderRadius?: string | number
|
|
1184
|
+
/**
|
|
1185
|
+
* Animation type.
|
|
1186
|
+
*/
|
|
1187
|
+
animation?: 'pulse' | 'wave' | 'none'
|
|
1188
|
+
}
|
|
1189
|
+
```
|
|
1190
|
+
|
|
1191
|
+
#### `SpacerProps`
|
|
1192
|
+
|
|
1193
|
+
Props for the Spacer layout component (adds whitespace between elements).
|
|
1194
|
+
|
|
1195
|
+
```typescript
|
|
1196
|
+
interface SpacerProps extends BaseProps {
|
|
1197
|
+
/**
|
|
1198
|
+
* Space size.
|
|
1199
|
+
*/
|
|
1200
|
+
size?: Size | string | number
|
|
1201
|
+
/**
|
|
1202
|
+
* Whether the spacer is horizontal.
|
|
1203
|
+
*/
|
|
1204
|
+
horizontal?: boolean
|
|
1205
|
+
}
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
#### `SpinnerProps`
|
|
1209
|
+
|
|
1210
|
+
Props for the Spinner/loading indicator component.
|
|
1211
|
+
|
|
1212
|
+
```typescript
|
|
1213
|
+
interface SpinnerProps extends BaseProps {
|
|
1214
|
+
/**
|
|
1215
|
+
* Spinner size.
|
|
1216
|
+
*/
|
|
1217
|
+
size?: Size
|
|
1218
|
+
/**
|
|
1219
|
+
* Spinner color.
|
|
1220
|
+
*/
|
|
1221
|
+
color?: ColorVariant | string
|
|
1222
|
+
/**
|
|
1223
|
+
* Loading label (for accessibility).
|
|
1224
|
+
*/
|
|
1225
|
+
label?: string
|
|
1226
|
+
/**
|
|
1227
|
+
* Spinner thickness.
|
|
1228
|
+
*/
|
|
1229
|
+
thickness?: number
|
|
1230
|
+
}
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
#### `SwitchProps`
|
|
1234
|
+
|
|
1235
|
+
Props for the Switch/Toggle component.
|
|
1236
|
+
|
|
1237
|
+
```typescript
|
|
1238
|
+
interface SwitchProps extends InputElementProps {
|
|
1239
|
+
/**
|
|
1240
|
+
* Switch label.
|
|
1241
|
+
*/
|
|
1242
|
+
label?: Children
|
|
1243
|
+
/**
|
|
1244
|
+
* Whether the switch is on.
|
|
1245
|
+
*/
|
|
1246
|
+
checked?: boolean
|
|
1247
|
+
/**
|
|
1248
|
+
* Switch size.
|
|
1249
|
+
*/
|
|
1250
|
+
size?: Size
|
|
1251
|
+
/**
|
|
1252
|
+
* Color when on.
|
|
1253
|
+
*/
|
|
1254
|
+
color?: ColorVariant
|
|
1255
|
+
}
|
|
1256
|
+
```
|
|
1257
|
+
|
|
1258
|
+
#### `TabItem`
|
|
1259
|
+
|
|
1260
|
+
A single tab in a Tabs component.
|
|
1261
|
+
|
|
1262
|
+
```typescript
|
|
1263
|
+
interface TabItem<T = string> {
|
|
1264
|
+
/**
|
|
1265
|
+
* Tab value/id.
|
|
1266
|
+
*/
|
|
1267
|
+
value: T
|
|
1268
|
+
/**
|
|
1269
|
+
* Tab label.
|
|
1270
|
+
*/
|
|
1271
|
+
label: Children
|
|
1272
|
+
/**
|
|
1273
|
+
* Tab content.
|
|
1274
|
+
*/
|
|
1275
|
+
content?: Children
|
|
1276
|
+
/**
|
|
1277
|
+
* Whether the tab is disabled.
|
|
1278
|
+
*/
|
|
1279
|
+
disabled?: boolean
|
|
1280
|
+
/**
|
|
1281
|
+
* Icon to display.
|
|
1282
|
+
*/
|
|
1283
|
+
icon?: Children
|
|
1284
|
+
}
|
|
1285
|
+
```
|
|
1286
|
+
|
|
1287
|
+
#### `TableColumn`
|
|
1288
|
+
|
|
1289
|
+
Table column definition.
|
|
1290
|
+
|
|
1291
|
+
```typescript
|
|
1292
|
+
interface TableColumn<T> {
|
|
1293
|
+
/**
|
|
1294
|
+
* Column key (data property).
|
|
1295
|
+
*/
|
|
1296
|
+
key: keyof T | string
|
|
1297
|
+
/**
|
|
1298
|
+
* Column header.
|
|
1299
|
+
*/
|
|
1300
|
+
header: Children
|
|
1301
|
+
/**
|
|
1302
|
+
* Custom cell renderer.
|
|
1303
|
+
*/
|
|
1304
|
+
render?: (value: unknown, row: T, index: number) => Children
|
|
1305
|
+
/**
|
|
1306
|
+
* Column width.
|
|
1307
|
+
*/
|
|
1308
|
+
width?: string | number
|
|
1309
|
+
/**
|
|
1310
|
+
* Whether the column is sortable.
|
|
1311
|
+
*/
|
|
1312
|
+
sortable?: boolean
|
|
1313
|
+
/**
|
|
1314
|
+
* Text alignment.
|
|
1315
|
+
*/
|
|
1316
|
+
align?: 'left' | 'center' | 'right'
|
|
1317
|
+
}
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
#### `TableProps`
|
|
1321
|
+
|
|
1322
|
+
Props for the Table component.
|
|
1323
|
+
|
|
1324
|
+
```typescript
|
|
1325
|
+
interface TableProps<T> extends HTMLElementProps {
|
|
1326
|
+
/**
|
|
1327
|
+
* Table data.
|
|
1328
|
+
*/
|
|
1329
|
+
data: T[]
|
|
1330
|
+
/**
|
|
1331
|
+
* Column definitions.
|
|
1332
|
+
*/
|
|
1333
|
+
columns: TableColumn<T>[]
|
|
1334
|
+
/**
|
|
1335
|
+
* Row key extractor.
|
|
1336
|
+
*/
|
|
1337
|
+
rowKey?: keyof T | ((row: T) => string | number)
|
|
1338
|
+
/**
|
|
1339
|
+
* Whether to show borders.
|
|
1340
|
+
*/
|
|
1341
|
+
bordered?: boolean
|
|
1342
|
+
/**
|
|
1343
|
+
* Whether rows are striped.
|
|
1344
|
+
*/
|
|
1345
|
+
striped?: boolean
|
|
1346
|
+
/**
|
|
1347
|
+
* Whether rows are hoverable.
|
|
1348
|
+
*/
|
|
1349
|
+
hoverable?: boolean
|
|
1350
|
+
/**
|
|
1351
|
+
* Table size.
|
|
1352
|
+
*/
|
|
1353
|
+
size?: Size
|
|
1354
|
+
/**
|
|
1355
|
+
* Empty state content.
|
|
1356
|
+
*/
|
|
1357
|
+
emptyContent?: Children
|
|
1358
|
+
/**
|
|
1359
|
+
* Loading state.
|
|
1360
|
+
*/
|
|
1361
|
+
loading?: boolean
|
|
1362
|
+
/**
|
|
1363
|
+
* Sort configuration.
|
|
1364
|
+
*/
|
|
1365
|
+
sort?: {
|
|
1366
|
+
key: string
|
|
1367
|
+
direction: 'asc' | 'desc'
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Sort change handler.
|
|
1371
|
+
*/
|
|
1372
|
+
onSort?: (key: string, direction: 'asc' | 'desc') => void
|
|
1373
|
+
/**
|
|
1374
|
+
* Row click handler.
|
|
1375
|
+
*/
|
|
1376
|
+
onRowClick?: (row: T, index: number) => void
|
|
1377
|
+
}
|
|
1378
|
+
```
|
|
1379
|
+
|
|
1380
|
+
#### `TabsProps`
|
|
1381
|
+
|
|
1382
|
+
Props for the Tabs component (switchable tabbed content panels).
|
|
1383
|
+
|
|
1384
|
+
```typescript
|
|
1385
|
+
interface TabsProps<T = string> extends BaseProps {
|
|
1386
|
+
/**
|
|
1387
|
+
* Tab items.
|
|
1388
|
+
*/
|
|
1389
|
+
items: TabItem<T>[]
|
|
1390
|
+
/**
|
|
1391
|
+
* Current active tab.
|
|
1392
|
+
*/
|
|
1393
|
+
value?: T
|
|
1394
|
+
/**
|
|
1395
|
+
* Default active tab.
|
|
1396
|
+
*/
|
|
1397
|
+
defaultValue?: T
|
|
1398
|
+
/**
|
|
1399
|
+
* Change handler.
|
|
1400
|
+
*/
|
|
1401
|
+
onChange?: (value: T) => void
|
|
1402
|
+
/**
|
|
1403
|
+
* Tab variant.
|
|
1404
|
+
*/
|
|
1405
|
+
variant?: 'line' | 'enclosed' | 'soft-rounded' | 'solid-rounded'
|
|
1406
|
+
/**
|
|
1407
|
+
* Tab size.
|
|
1408
|
+
*/
|
|
1409
|
+
size?: Size
|
|
1410
|
+
/**
|
|
1411
|
+
* Whether tabs are fitted (take full width).
|
|
1412
|
+
*/
|
|
1413
|
+
fitted?: boolean
|
|
1414
|
+
}
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
#### `TextareaElementProps`
|
|
1418
|
+
|
|
1419
|
+
Base props for textarea elements.
|
|
1420
|
+
|
|
1421
|
+
```typescript
|
|
1422
|
+
interface TextareaElementProps extends HTMLElementProps {
|
|
1423
|
+
name?: string
|
|
1424
|
+
value?: string
|
|
1425
|
+
defaultValue?: string
|
|
1426
|
+
placeholder?: string
|
|
1427
|
+
required?: boolean
|
|
1428
|
+
readOnly?: boolean
|
|
1429
|
+
autoFocus?: boolean
|
|
1430
|
+
rows?: number
|
|
1431
|
+
cols?: number
|
|
1432
|
+
maxLength?: number
|
|
1433
|
+
minLength?: number
|
|
1434
|
+
wrap?: 'hard' | 'soft' | 'off'
|
|
1435
|
+
onChange?: ChangeEventHandler
|
|
1436
|
+
onInput?: FormEventHandler
|
|
1437
|
+
}
|
|
1438
|
+
```
|
|
1439
|
+
|
|
1440
|
+
#### `TextareaProps`
|
|
1441
|
+
|
|
1442
|
+
Props for the Textarea component.
|
|
1443
|
+
|
|
1444
|
+
```typescript
|
|
1445
|
+
interface TextareaProps extends TextareaElementProps {
|
|
1446
|
+
/**
|
|
1447
|
+
* Text size tier (see {@link TextareaClassOptions.size}) — pass the same
|
|
1448
|
+
* `size` as a neighboring Input for identical font sizes.
|
|
1449
|
+
*/
|
|
1450
|
+
size?: Size
|
|
1451
|
+
/**
|
|
1452
|
+
* Label text.
|
|
1453
|
+
*/
|
|
1454
|
+
label?: string
|
|
1455
|
+
/**
|
|
1456
|
+
* Error message.
|
|
1457
|
+
*/
|
|
1458
|
+
error?: string
|
|
1459
|
+
/**
|
|
1460
|
+
* Hint/help text.
|
|
1461
|
+
*/
|
|
1462
|
+
hint?: string
|
|
1463
|
+
/**
|
|
1464
|
+
* Whether the textarea auto-resizes.
|
|
1465
|
+
*/
|
|
1466
|
+
autoResize?: boolean
|
|
1467
|
+
/**
|
|
1468
|
+
* Minimum number of rows.
|
|
1469
|
+
*/
|
|
1470
|
+
minRows?: number
|
|
1471
|
+
/**
|
|
1472
|
+
* Maximum number of rows.
|
|
1473
|
+
*/
|
|
1474
|
+
maxRows?: number
|
|
1475
|
+
}
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1478
|
+
#### `ThemeToggleProps`
|
|
1479
|
+
|
|
1480
|
+
Props for {@link ThemeToggle}.
|
|
1481
|
+
|
|
1482
|
+
Extends standard `<button>` attributes so callers can pass any extra
|
|
1483
|
+
`data-*`, `aria-*`, event handler, or `style` prop without forking the
|
|
1484
|
+
component. The handful of explicitly named props below let apps swap
|
|
1485
|
+
the icon glyphs, label, or size without spreading attribute concerns.
|
|
1486
|
+
|
|
1487
|
+
```typescript
|
|
1488
|
+
interface ThemeToggleProps extends Omit<
|
|
1489
|
+
ButtonHTMLAttributes<HTMLButtonElement>,
|
|
1490
|
+
'aria-label' | 'aria-pressed' | 'onClick' | 'type'
|
|
1491
|
+
> {
|
|
1492
|
+
/** i18n key for the `aria-label`. Defaults to `'theme.toggle'`. */
|
|
1493
|
+
ariaLabelKey?: string
|
|
1494
|
+
/** Fallback `aria-label` if the i18n key is missing. Defaults to `'Toggle theme'`. */
|
|
1495
|
+
ariaLabelDefault?: string
|
|
1496
|
+
/** Icon name to render in dark mode. Defaults to `'moon'`. */
|
|
1497
|
+
darkIcon?: IconName
|
|
1498
|
+
/** Icon name to render in light mode. Defaults to `'sun'`. */
|
|
1499
|
+
lightIcon?: IconName
|
|
1500
|
+
/** Pixel size for the rendered icon. Defaults to `20`. */
|
|
1501
|
+
iconSize?: number
|
|
1502
|
+
}
|
|
1503
|
+
```
|
|
1504
|
+
|
|
1505
|
+
#### `ToastProps`
|
|
1506
|
+
|
|
1507
|
+
Props for the Toast/notification component.
|
|
1508
|
+
|
|
1509
|
+
```typescript
|
|
1510
|
+
interface ToastProps extends HTMLElementProps {
|
|
1511
|
+
/**
|
|
1512
|
+
* Toast content.
|
|
1513
|
+
*/
|
|
1514
|
+
children?: Children
|
|
1515
|
+
/**
|
|
1516
|
+
* Toast title.
|
|
1517
|
+
*/
|
|
1518
|
+
title?: string
|
|
1519
|
+
/**
|
|
1520
|
+
* Toast description.
|
|
1521
|
+
*/
|
|
1522
|
+
description?: string
|
|
1523
|
+
/**
|
|
1524
|
+
* Toast status/type.
|
|
1525
|
+
*/
|
|
1526
|
+
status?: ColorVariant
|
|
1527
|
+
/**
|
|
1528
|
+
* Duration in milliseconds (0 for persistent).
|
|
1529
|
+
*/
|
|
1530
|
+
duration?: number
|
|
1531
|
+
/**
|
|
1532
|
+
* Whether the toast is dismissible.
|
|
1533
|
+
*/
|
|
1534
|
+
dismissible?: boolean
|
|
1535
|
+
/**
|
|
1536
|
+
* Called when dismissed.
|
|
1537
|
+
*/
|
|
1538
|
+
onDismiss?: () => void
|
|
1539
|
+
/**
|
|
1540
|
+
* Toast position.
|
|
1541
|
+
*/
|
|
1542
|
+
position?: 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'
|
|
1543
|
+
/**
|
|
1544
|
+
* Accessible label for the close button.
|
|
1545
|
+
* @default 'Close'
|
|
1546
|
+
*/
|
|
1547
|
+
closeLabel?: string
|
|
1548
|
+
}
|
|
1549
|
+
```
|
|
1550
|
+
|
|
1551
|
+
#### `TooltipProps`
|
|
1552
|
+
|
|
1553
|
+
Props for the Tooltip component (hover/focus popover with informational text).
|
|
1554
|
+
|
|
1555
|
+
```typescript
|
|
1556
|
+
interface TooltipProps extends HTMLElementProps {
|
|
1557
|
+
/**
|
|
1558
|
+
* Tooltip content.
|
|
1559
|
+
*/
|
|
1560
|
+
content: Children
|
|
1561
|
+
/**
|
|
1562
|
+
* Element that triggers the tooltip.
|
|
1563
|
+
*/
|
|
1564
|
+
children: Children
|
|
1565
|
+
/**
|
|
1566
|
+
* Tooltip placement.
|
|
1567
|
+
*/
|
|
1568
|
+
placement?: TooltipPlacement
|
|
1569
|
+
/**
|
|
1570
|
+
* Delay before showing (ms).
|
|
1571
|
+
*/
|
|
1572
|
+
delay?: number
|
|
1573
|
+
/**
|
|
1574
|
+
* Whether the tooltip has an arrow.
|
|
1575
|
+
*/
|
|
1576
|
+
hasArrow?: boolean
|
|
1577
|
+
}
|
|
1578
|
+
```
|
|
1579
|
+
|
|
1580
|
+
#### `UserMenuPopoverPanelProps`
|
|
1581
|
+
|
|
1582
|
+
Props for {@link UserMenuPopoverPanel}.
|
|
1583
|
+
|
|
1584
|
+
```typescript
|
|
1585
|
+
interface UserMenuPopoverPanelProps {
|
|
1586
|
+
/**
|
|
1587
|
+
* Panel body — typically a set of `<Link>` nav items and a
|
|
1588
|
+
* `<UserMenuPopoverSignOut />`. Rendered inside a `<nav>` below the
|
|
1589
|
+
* built-in identity header.
|
|
1590
|
+
*/
|
|
1591
|
+
children: ReactNode
|
|
1592
|
+
/** Extra className composed onto the absolute-positioned panel. */
|
|
1593
|
+
className?: string
|
|
1594
|
+
/** i18n key for the panel's aria-label. Default: `'userMenu.panelLabel'`. */
|
|
1595
|
+
ariaLabelKey?: string
|
|
1596
|
+
/** Fallback aria-label if the i18n key is missing. Default: `'Account menu'`. */
|
|
1597
|
+
ariaLabelDefault?: string
|
|
1598
|
+
/** `data-mol-id` for the panel. Default: `'user-menu-panel'`. */
|
|
1599
|
+
dataMolId?: string
|
|
1600
|
+
}
|
|
1601
|
+
```
|
|
1602
|
+
|
|
1603
|
+
#### `UserMenuPopoverProps`
|
|
1604
|
+
|
|
1605
|
+
Props for {@link UserMenuPopover}.
|
|
1606
|
+
|
|
1607
|
+
```typescript
|
|
1608
|
+
interface UserMenuPopoverProps {
|
|
1609
|
+
/**
|
|
1610
|
+
* The trigger and panel — typically `<UserMenuPopoverTrigger />` and
|
|
1611
|
+
* `<UserMenuPopoverPanel>`.
|
|
1612
|
+
*/
|
|
1613
|
+
children: ReactNode
|
|
1614
|
+
/**
|
|
1615
|
+
* Label shown when there is no authenticated user. Defaults to the
|
|
1616
|
+
* `userMenuPopover.guest` translation (English fallback `"Account"`).
|
|
1617
|
+
*/
|
|
1618
|
+
guestName?: string
|
|
1619
|
+
/** Extra className composed onto the relative-positioned container. */
|
|
1620
|
+
className?: string
|
|
1621
|
+
}
|
|
1622
|
+
```
|
|
1623
|
+
|
|
1624
|
+
#### `UserMenuPopoverSignOutProps`
|
|
1625
|
+
|
|
1626
|
+
Props for {@link UserMenuPopoverSignOut}.
|
|
1627
|
+
|
|
1628
|
+
```typescript
|
|
1629
|
+
interface UserMenuPopoverSignOutProps {
|
|
1630
|
+
/** i18n key for the button label. Default: `'userMenu.signOut'`. */
|
|
1631
|
+
labelKey?: string
|
|
1632
|
+
/** Fallback label if the i18n key is missing. Default: `'Sign out'`. */
|
|
1633
|
+
labelDefault?: string
|
|
1634
|
+
/** `data-mol-id` for the button. Default: `'user-menu-sign-out'`. */
|
|
1635
|
+
dataMolId?: string
|
|
1636
|
+
/** Extra className composed onto the button. */
|
|
1637
|
+
className?: string
|
|
1638
|
+
}
|
|
1639
|
+
```
|
|
1640
|
+
|
|
1641
|
+
#### `UserMenuPopoverTriggerProps`
|
|
1642
|
+
|
|
1643
|
+
Props for {@link UserMenuPopoverTrigger}.
|
|
1644
|
+
|
|
1645
|
+
```typescript
|
|
1646
|
+
interface UserMenuPopoverTriggerProps {
|
|
1647
|
+
/** i18n key for the trigger's aria-label. Default: `'userMenu.open'`. */
|
|
1648
|
+
ariaLabelKey?: string
|
|
1649
|
+
/** Fallback aria-label if the i18n key is missing. Default: `'Open user menu'`. */
|
|
1650
|
+
ariaLabelDefault?: string
|
|
1651
|
+
/** `data-mol-id` for the trigger button. Default: `'user-menu'`. */
|
|
1652
|
+
dataMolId?: string
|
|
1653
|
+
/** Extra className composed onto the trigger button. */
|
|
1654
|
+
className?: string
|
|
1655
|
+
}
|
|
1656
|
+
```
|
|
1657
|
+
|
|
1658
|
+
#### `UserMenuProps`
|
|
1659
|
+
|
|
1660
|
+
Props for {@link UserMenu}.
|
|
1661
|
+
|
|
1662
|
+
The inner trigger is a Molecule `<Button>` whose own prop set
|
|
1663
|
+
conflicts with raw `ButtonHTMLAttributes` (color, value, size enums),
|
|
1664
|
+
so this component exposes a curated set of customization points
|
|
1665
|
+
instead of extending HTML attributes. For one-off extra attributes,
|
|
1666
|
+
pass them via `dataMolId` / `className` / `style` props.
|
|
1667
|
+
|
|
1668
|
+
```typescript
|
|
1669
|
+
interface UserMenuProps {
|
|
1670
|
+
/**
|
|
1671
|
+
* Panel content shown inside the drawer/modal (typically the app's
|
|
1672
|
+
* `SettingsPanel`). It can dismiss the drawer by calling
|
|
1673
|
+
* `usePanelClose()` — no `onClose` prop-threading required.
|
|
1674
|
+
*/
|
|
1675
|
+
children: ReactNode
|
|
1676
|
+
/**
|
|
1677
|
+
* i18n key for the trigger button's aria-label. Defaults to
|
|
1678
|
+
* `'userMenu.open'`. Apps whose existing locales use a different key
|
|
1679
|
+
* (e.g. `'userMenu.openButton'`) can override.
|
|
1680
|
+
*/
|
|
1681
|
+
ariaLabelKey?: string
|
|
1682
|
+
/** Fallback aria-label if the i18n key is missing. Defaults to `"Open user menu"`. */
|
|
1683
|
+
ariaLabelDefault?: string
|
|
1684
|
+
/** Icon name for the trigger button. Defaults to `'user'`. */
|
|
1685
|
+
triggerIcon?: IconName
|
|
1686
|
+
/** Pixel size for the trigger icon. Defaults to 20. */
|
|
1687
|
+
triggerIconSize?: number
|
|
1688
|
+
/**
|
|
1689
|
+
* `data-mol-id` for the trigger button. Defaults to `'user-menu'`.
|
|
1690
|
+
* Pass an explicit value to disambiguate when the same page mounts
|
|
1691
|
+
* more than one UserMenu.
|
|
1692
|
+
*/
|
|
1693
|
+
dataMolId?: string
|
|
1694
|
+
/** Extra className composed onto the trigger button. */
|
|
1695
|
+
className?: string
|
|
1696
|
+
/** Whether the trigger button is disabled. */
|
|
1697
|
+
disabled?: boolean
|
|
1698
|
+
/**
|
|
1699
|
+
* Override the trigger button's click handler. When provided, called
|
|
1700
|
+
* instead of opening the panel — hosts use this to intercept the click
|
|
1701
|
+
* (e.g. to open an auth modal for guest users).
|
|
1702
|
+
*/
|
|
1703
|
+
onClick?: () => void
|
|
1704
|
+
}
|
|
1705
|
+
```
|
|
1706
|
+
|
|
1707
|
+
### Types
|
|
1708
|
+
|
|
1709
|
+
#### `ButtonVariant`
|
|
1710
|
+
|
|
1711
|
+
Button visual variant styles.
|
|
1712
|
+
|
|
1713
|
+
```typescript
|
|
1714
|
+
type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link'
|
|
1715
|
+
```
|
|
1716
|
+
|
|
1717
|
+
#### `ChangeEventHandler`
|
|
1718
|
+
|
|
1719
|
+
Framework-agnostic change event handler.
|
|
1720
|
+
|
|
1721
|
+
```typescript
|
|
1722
|
+
type ChangeEventHandler = EventHandler<Event>
|
|
1723
|
+
```
|
|
1724
|
+
|
|
1725
|
+
#### `Children`
|
|
1726
|
+
|
|
1727
|
+
Framework-agnostic child content.
|
|
1728
|
+
Use `unknown` to allow any framework's node type (ReactNode, VNode, etc.).
|
|
1729
|
+
|
|
1730
|
+
```typescript
|
|
1731
|
+
type Children = unknown
|
|
1732
|
+
```
|
|
1733
|
+
|
|
1734
|
+
#### `ColorVariant`
|
|
1735
|
+
|
|
1736
|
+
Semantic color variants used across components for status indication.
|
|
1737
|
+
|
|
1738
|
+
```typescript
|
|
1739
|
+
type ColorVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'
|
|
1740
|
+
```
|
|
1741
|
+
|
|
1742
|
+
#### `EventHandler`
|
|
1743
|
+
|
|
1744
|
+
Framework-agnostic event handler.
|
|
1745
|
+
|
|
1746
|
+
```typescript
|
|
1747
|
+
type EventHandler<E = Event> = (event: E) => void
|
|
1748
|
+
```
|
|
1749
|
+
|
|
1750
|
+
#### `FocusEventHandler`
|
|
1751
|
+
|
|
1752
|
+
Framework-agnostic focus event handler.
|
|
1753
|
+
|
|
1754
|
+
```typescript
|
|
1755
|
+
type FocusEventHandler = EventHandler<FocusEvent>
|
|
1756
|
+
```
|
|
1757
|
+
|
|
1758
|
+
#### `FormEventHandler`
|
|
1759
|
+
|
|
1760
|
+
Framework-agnostic form event handler.
|
|
1761
|
+
|
|
1762
|
+
```typescript
|
|
1763
|
+
type FormEventHandler = EventHandler<Event>
|
|
1764
|
+
```
|
|
1765
|
+
|
|
1766
|
+
#### `InputType`
|
|
1767
|
+
|
|
1768
|
+
Allowed HTML input type attribute values for the Input component.
|
|
1769
|
+
|
|
1770
|
+
```typescript
|
|
1771
|
+
type InputType =
|
|
1772
|
+
| 'text'
|
|
1773
|
+
| 'email'
|
|
1774
|
+
| 'password'
|
|
1775
|
+
| 'number'
|
|
1776
|
+
| 'tel'
|
|
1777
|
+
| 'url'
|
|
1778
|
+
| 'search'
|
|
1779
|
+
| 'date'
|
|
1780
|
+
| 'time'
|
|
1781
|
+
| 'datetime-local'
|
|
1782
|
+
```
|
|
1783
|
+
|
|
1784
|
+
#### `KeyboardEventHandler`
|
|
1785
|
+
|
|
1786
|
+
Framework-agnostic keyboard event handler.
|
|
1787
|
+
|
|
1788
|
+
```typescript
|
|
1789
|
+
type KeyboardEventHandler = EventHandler<KeyboardEvent>
|
|
1790
|
+
```
|
|
1791
|
+
|
|
1792
|
+
#### `ModalSize`
|
|
1793
|
+
|
|
1794
|
+
Modal size variants including full-screen.
|
|
1795
|
+
|
|
1796
|
+
```typescript
|
|
1797
|
+
type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'
|
|
1798
|
+
```
|
|
1799
|
+
|
|
1800
|
+
#### `MouseEventHandler`
|
|
1801
|
+
|
|
1802
|
+
Framework-agnostic mouse event handler.
|
|
1803
|
+
|
|
1804
|
+
```typescript
|
|
1805
|
+
type MouseEventHandler = EventHandler<MouseEvent>
|
|
1806
|
+
```
|
|
1807
|
+
|
|
1808
|
+
#### `Size`
|
|
1809
|
+
|
|
1810
|
+
Standard size scale used across all molecule UI components (buttons, inputs, badges, etc.).
|
|
1811
|
+
|
|
1812
|
+
```typescript
|
|
1813
|
+
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
|
1814
|
+
```
|
|
1815
|
+
|
|
1816
|
+
#### `TooltipPlacement`
|
|
1817
|
+
|
|
1818
|
+
Position where a tooltip renders relative to its trigger element (top, bottom, left, right, and corner variants).
|
|
1819
|
+
|
|
1820
|
+
```typescript
|
|
1821
|
+
type TooltipPlacement =
|
|
1822
|
+
'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end'
|
|
1823
|
+
```
|
|
1824
|
+
|
|
1825
|
+
### Functions
|
|
1826
|
+
|
|
1827
|
+
#### `AuthGuard(props)`
|
|
1828
|
+
|
|
1829
|
+
Route-element guard for authenticated sections of a React Router tree.
|
|
1830
|
+
|
|
1831
|
+
- While `useAuth().state.initialized` is `false`, renders the
|
|
1832
|
+
`loadingFallback` (or the default `<div data-mol-id="auth-guard-loading">{t('common.loading')}</div>`).
|
|
1833
|
+
- If the user is not authenticated, redirects to `loginPath` carrying
|
|
1834
|
+
the attempted location in `state.from` for post-login restoration.
|
|
1835
|
+
- Otherwise renders `children` (or `<Outlet />` if none).
|
|
1836
|
+
|
|
1837
|
+
The default loading tag carries `data-mol-id="auth-guard-loading"`
|
|
1838
|
+
so AI agents and e2e tests can target it reliably. When the caller
|
|
1839
|
+
passes a custom `loadingFallback`, it's the caller's responsibility
|
|
1840
|
+
to include any data-mol-id they need.
|
|
1841
|
+
|
|
1842
|
+
```typescript
|
|
1843
|
+
function AuthGuard({
|
|
1844
|
+
loadingFallback,
|
|
1845
|
+
loadingKey = 'common.loading',
|
|
1846
|
+
loadingDefault = 'Loading...',
|
|
1847
|
+
loginPath = '/login',
|
|
1848
|
+
onAuthenticated,
|
|
1849
|
+
children,
|
|
1850
|
+
}?: AuthGuardProps): ReactNode
|
|
1851
|
+
```
|
|
1852
|
+
|
|
1853
|
+
- `props` — {@link AuthGuardProps}
|
|
1854
|
+
|
|
1855
|
+
#### `cn(inputs)`
|
|
1856
|
+
|
|
1857
|
+
Merge class name strings, filtering out falsy values (undefined, null, false).
|
|
1858
|
+
|
|
1859
|
+
```typescript
|
|
1860
|
+
function cn(inputs?: (string | false | null | undefined)[]): string
|
|
1861
|
+
```
|
|
1862
|
+
|
|
1863
|
+
- `inputs` — Class name strings or falsy values to be filtered out.
|
|
1864
|
+
|
|
1865
|
+
**Returns:** A single space-separated class string.
|
|
1866
|
+
|
|
1867
|
+
#### `Icon(props)`
|
|
1868
|
+
|
|
1869
|
+
Renders an SVG glyph looked up by `name` from the bonded
|
|
1870
|
+
`@molecule/app-icons` set.
|
|
1871
|
+
|
|
1872
|
+
Handles two icon-data shapes returned by the bond:
|
|
1873
|
+
|
|
1874
|
+
1. Pre-rendered SVG markup (`icon.svg`) — injected via
|
|
1875
|
+
`dangerouslySetInnerHTML`. The bond is the trust boundary; only
|
|
1876
|
+
bond a set that controls its own SVG strings.
|
|
1877
|
+
2. Structured paths (`icon.paths`) — rendered as discrete `<path>`
|
|
1878
|
+
children, with optional stroke styling forwarded from the icon set.
|
|
1879
|
+
|
|
1880
|
+
Any extra HTML/SVG attribute (e.g. `data-mol-id`, `aria-label`,
|
|
1881
|
+
`role="img"`, `onClick`) is forwarded to the root `<svg>` via spread.
|
|
1882
|
+
|
|
1883
|
+
Decorative by default: when the caller passes no `aria-label` /
|
|
1884
|
+
`aria-labelledby` / `role`, the SVG is rendered `aria-hidden` +
|
|
1885
|
+
`focusable="false"` so screen readers skip it (an unnamed inline SVG is
|
|
1886
|
+
announced as a stray "image" by some combos). Passing any of those props
|
|
1887
|
+
opts the icon into the accessibility tree.
|
|
1888
|
+
|
|
1889
|
+
```typescript
|
|
1890
|
+
function Icon({ name, size = 20, className, ...rest }: IconProps): React.JSX.Element
|
|
1891
|
+
```
|
|
1892
|
+
|
|
1893
|
+
- `props` — {@link IconProps}
|
|
1894
|
+
|
|
1895
|
+
**Returns:** An `<svg>` element rendering the named glyph.
|
|
1896
|
+
|
|
1897
|
+
#### `LanguagePicker(props)`
|
|
1898
|
+
|
|
1899
|
+
Globe-icon button that opens a modal grid of every locale registered
|
|
1900
|
+
with the bonded i18n provider. Clicking a locale calls `setLocale`
|
|
1901
|
+
and closes the modal.
|
|
1902
|
+
|
|
1903
|
+
Reads `locale`, `setLocale`, and `locales` from {@link useTranslation},
|
|
1904
|
+
so the list of choices stays in sync with whatever set the
|
|
1905
|
+
`setupI18nDefault` (or any other i18n setup) registered. No hardcoded
|
|
1906
|
+
language list — adding a locale to the i18n bond adds it to the picker.
|
|
1907
|
+
|
|
1908
|
+
Molecule-convention defaults baked in:
|
|
1909
|
+
|
|
1910
|
+
- `data-mol-id="language-picker-trigger"` on the trigger button
|
|
1911
|
+
- `data-mol-id="language-picker-modal"` on the modal dialog
|
|
1912
|
+
- `data-mol-id="language-picker-option-<code>"` on each locale button
|
|
1913
|
+
- `data-active` on the currently-selected locale button
|
|
1914
|
+
- `aria-label` from the `footer.language` i18n key (default `"Language"`)
|
|
1915
|
+
|
|
1916
|
+
```typescript
|
|
1917
|
+
function LanguagePicker({
|
|
1918
|
+
labelKey = 'footer.language',
|
|
1919
|
+
labelDefault = 'Language',
|
|
1920
|
+
modalTitleKey = 'languagePicker.modalTitle',
|
|
1921
|
+
modalTitleDefault = 'Choose language',
|
|
1922
|
+
icon = 'globe',
|
|
1923
|
+
iconSize = 16,
|
|
1924
|
+
display = 'name',
|
|
1925
|
+
className,
|
|
1926
|
+
renderTrigger,
|
|
1927
|
+
...rest
|
|
1928
|
+
}?: LanguagePickerProps): JSX.Element
|
|
1929
|
+
```
|
|
1930
|
+
|
|
1931
|
+
- `props` — {@link LanguagePickerProps}
|
|
1932
|
+
|
|
1933
|
+
#### `PanelCloseProvider(props)`
|
|
1934
|
+
|
|
1935
|
+
Provides the panel-close callback to descendants. Rendered internally
|
|
1936
|
+
by `UserMenu` and `SidebarUserCard` around their `children`; apps do
|
|
1937
|
+
not normally render this directly.
|
|
1938
|
+
|
|
1939
|
+
```typescript
|
|
1940
|
+
function PanelCloseProvider({ close, children }: PanelCloseProviderProps): JSX.Element
|
|
1941
|
+
```
|
|
1942
|
+
|
|
1943
|
+
- `props` — The close callback and the panel content.
|
|
1944
|
+
|
|
1945
|
+
**Returns:** The children wrapped in the close-context provider.
|
|
1946
|
+
|
|
1947
|
+
#### `SidebarUserCard(props)`
|
|
1948
|
+
|
|
1949
|
+
Sidebar-resident user-account card: avatar + name + status line, opens
|
|
1950
|
+
the app's settings drawer on click.
|
|
1951
|
+
|
|
1952
|
+
Drop-in replacement for `<UserMenu />` when the trigger lives inside a
|
|
1953
|
+
vertical sidebar (e.g. as the `userMenu` slot of `<SidebarLayout>`).
|
|
1954
|
+
Reads name/email/avatar from `useAuth()` by default; pass explicit
|
|
1955
|
+
`name` / `secondaryLine` / `avatarUrl` props to override.
|
|
1956
|
+
|
|
1957
|
+
Ships with `data-mol-id="sidebar-user-card"` on the trigger button
|
|
1958
|
+
by default for AI-agent / e2e selection. Callers can override by
|
|
1959
|
+
passing `data-mol-id` as an extra prop.
|
|
1960
|
+
|
|
1961
|
+
```typescript
|
|
1962
|
+
function SidebarUserCard({
|
|
1963
|
+
children,
|
|
1964
|
+
name,
|
|
1965
|
+
secondaryLine,
|
|
1966
|
+
avatarUrl,
|
|
1967
|
+
ariaLabelKey = 'sidebarUserCard.open',
|
|
1968
|
+
ariaLabelDefault = 'Open account menu',
|
|
1969
|
+
dataMolId = 'sidebar-user-card',
|
|
1970
|
+
className,
|
|
1971
|
+
...rest
|
|
1972
|
+
}: SidebarUserCardProps): JSX.Element
|
|
1973
|
+
```
|
|
1974
|
+
|
|
1975
|
+
#### `ThemeToggle(props)`
|
|
1976
|
+
|
|
1977
|
+
Button that flips the wired theme bond between light and dark.
|
|
1978
|
+
|
|
1979
|
+
Reads `mode` and `toggleTheme` from `useTheme()` and shows the
|
|
1980
|
+
configured dark/light icon accordingly. Ships with molecule
|
|
1981
|
+
conventions out of the box:
|
|
1982
|
+
|
|
1983
|
+
- `data-mol-id="theme-toggle"` for AI-agent / e2e selection
|
|
1984
|
+
- `data-mode={mode}` so tests can assert current state via DOM
|
|
1985
|
+
- `aria-pressed={mode === 'dark'}` for screen-reader state
|
|
1986
|
+
- `aria-label` from the `theme.toggle` i18n key (default `"Toggle theme"`)
|
|
1987
|
+
|
|
1988
|
+
Every per-app variant the fleet was carrying — extra `data-*` attrs,
|
|
1989
|
+
additional `aria-*` flags, custom event handlers — is now absorbed
|
|
1990
|
+
via the spread of unknown props. Apps that need different icons or
|
|
1991
|
+
label text use the named props.
|
|
1992
|
+
|
|
1993
|
+
```typescript
|
|
1994
|
+
function ThemeToggle({
|
|
1995
|
+
ariaLabelKey = 'theme.toggle',
|
|
1996
|
+
ariaLabelDefault = 'Toggle theme',
|
|
1997
|
+
darkIcon = 'moon',
|
|
1998
|
+
lightIcon = 'sun',
|
|
1999
|
+
iconSize = 20,
|
|
2000
|
+
className,
|
|
2001
|
+
...rest
|
|
2002
|
+
}?: ThemeToggleProps): JSX.Element
|
|
2003
|
+
```
|
|
2004
|
+
|
|
2005
|
+
- `props` — {@link ThemeToggleProps}
|
|
2006
|
+
|
|
2007
|
+
#### `ToastProvider(props)`
|
|
2008
|
+
|
|
2009
|
+
Provider component that manages global toast state.
|
|
2010
|
+
|
|
2011
|
+
```typescript
|
|
2012
|
+
function ToastProvider({
|
|
2013
|
+
children,
|
|
2014
|
+
position = 'bottom-right',
|
|
2015
|
+
}: ToastProviderProps): React.JSX.Element
|
|
2016
|
+
```
|
|
2017
|
+
|
|
2018
|
+
- `props` — The component props.
|
|
2019
|
+
- `props.children` — The child elements to render within the provider.
|
|
2020
|
+
- `props.position` — The default position for toasts.
|
|
2021
|
+
|
|
2022
|
+
**Returns:** The rendered provider with toast container.
|
|
2023
|
+
|
|
2024
|
+
#### `usePanelClose()`
|
|
2025
|
+
|
|
2026
|
+
Returns the callback that dismisses the drawer the current panel is
|
|
2027
|
+
mounted in. Safe to call anywhere — returns a no-op when no enclosing
|
|
2028
|
+
`UserMenu` / `SidebarUserCard` provides one (e.g. a `SettingsPanel`
|
|
2029
|
+
rendered as a standalone page).
|
|
2030
|
+
|
|
2031
|
+
```typescript
|
|
2032
|
+
function usePanelClose(): () => void
|
|
2033
|
+
```
|
|
2034
|
+
|
|
2035
|
+
**Returns:** A function that closes the enclosing drawer, or a no-op.
|
|
2036
|
+
|
|
2037
|
+
#### `UserMenu(props)`
|
|
2038
|
+
|
|
2039
|
+
Avatar-style trigger that opens the app's settings panel in a drawer.
|
|
2040
|
+
|
|
2041
|
+
The panel content is passed as `children` so apps can mount their own
|
|
2042
|
+
`SettingsPanel` (which diverges per app) inside the shared drawer
|
|
2043
|
+
chrome. Panel content dismisses the drawer via `usePanelClose()`.
|
|
2044
|
+
|
|
2045
|
+
Ships with `data-mol-id="user-menu"` on the trigger button by
|
|
2046
|
+
default for AI-agent / e2e selection.
|
|
2047
|
+
|
|
2048
|
+
```typescript
|
|
2049
|
+
function UserMenu({
|
|
2050
|
+
children,
|
|
2051
|
+
ariaLabelKey = 'userMenu.open',
|
|
2052
|
+
ariaLabelDefault = 'Open user menu',
|
|
2053
|
+
triggerIcon = 'user',
|
|
2054
|
+
triggerIconSize = 20,
|
|
2055
|
+
dataMolId = 'user-menu',
|
|
2056
|
+
className,
|
|
2057
|
+
disabled,
|
|
2058
|
+
onClick,
|
|
2059
|
+
}: UserMenuProps): JSX.Element
|
|
2060
|
+
```
|
|
2061
|
+
|
|
2062
|
+
#### `UserMenuPopover(props)`
|
|
2063
|
+
|
|
2064
|
+
Container for the inline popover account menu. Owns the open state and
|
|
2065
|
+
the auto-dismiss behaviour (route change, `popstate`, outside click,
|
|
2066
|
+
`Escape`), and provides the resolved account identity to its
|
|
2067
|
+
sub-components via context.
|
|
2068
|
+
|
|
2069
|
+
```typescript
|
|
2070
|
+
function UserMenuPopover({
|
|
2071
|
+
children,
|
|
2072
|
+
guestName,
|
|
2073
|
+
className,
|
|
2074
|
+
}: UserMenuPopoverProps): React.JSX.Element
|
|
2075
|
+
```
|
|
2076
|
+
|
|
2077
|
+
- `props` — The popover children, optional guest label, and className.
|
|
2078
|
+
|
|
2079
|
+
**Returns:** The relative-positioned popover container.
|
|
2080
|
+
|
|
2081
|
+
#### `UserMenuPopoverPanel(props)`
|
|
2082
|
+
|
|
2083
|
+
The popover panel: an absolutely-positioned card with a built-in
|
|
2084
|
+
identity header (name + email) and a `<nav>` wrapping the caller's nav
|
|
2085
|
+
items. Renders nothing while the popover is closed.
|
|
2086
|
+
|
|
2087
|
+
Provides only the structural concerns (absolute positioning above the
|
|
2088
|
+
trigger, `rounded-xl` border frame, the header/nav layout). Cosmetic
|
|
2089
|
+
choices — width, background, padding, shadow — are per-app: pass them
|
|
2090
|
+
via `className`. `cn()` concatenates (it does not tailwind-merge), so
|
|
2091
|
+
the panel never bakes a width/background the caller would have to
|
|
2092
|
+
fight.
|
|
2093
|
+
|
|
2094
|
+
```typescript
|
|
2095
|
+
function UserMenuPopoverPanel({
|
|
2096
|
+
children,
|
|
2097
|
+
className,
|
|
2098
|
+
ariaLabelKey = 'userMenu.panelLabel',
|
|
2099
|
+
ariaLabelDefault = 'Account menu',
|
|
2100
|
+
dataMolId = 'user-menu-panel',
|
|
2101
|
+
}: UserMenuPopoverPanelProps): React.JSX.Element | null
|
|
2102
|
+
```
|
|
2103
|
+
|
|
2104
|
+
- `props` — The nav children, className, and aria-label overrides.
|
|
2105
|
+
|
|
2106
|
+
**Returns:** The popover panel, or `null` when closed.
|
|
2107
|
+
|
|
2108
|
+
#### `UserMenuPopoverSignOut(props)`
|
|
2109
|
+
|
|
2110
|
+
The sign-out nav item — closes the popover and calls `auth.logout()`.
|
|
2111
|
+
Drop it in as the last child of `<UserMenuPopoverPanel>`.
|
|
2112
|
+
|
|
2113
|
+
```typescript
|
|
2114
|
+
function UserMenuPopoverSignOut({
|
|
2115
|
+
labelKey = 'userMenu.signOut',
|
|
2116
|
+
labelDefault = 'Sign out',
|
|
2117
|
+
dataMolId = 'user-menu-sign-out',
|
|
2118
|
+
className,
|
|
2119
|
+
}: UserMenuPopoverSignOutProps): React.JSX.Element
|
|
2120
|
+
```
|
|
2121
|
+
|
|
2122
|
+
- `props` — Label overrides, `data-mol-id`, and className.
|
|
2123
|
+
|
|
2124
|
+
**Returns:** The sign-out button.
|
|
2125
|
+
|
|
2126
|
+
#### `UserMenuPopoverTrigger(props)`
|
|
2127
|
+
|
|
2128
|
+
The trigger button: an initials avatar plus the account name and email,
|
|
2129
|
+
styled as a full-width sidebar card. Toggles the popover panel.
|
|
2130
|
+
|
|
2131
|
+
```typescript
|
|
2132
|
+
function UserMenuPopoverTrigger({
|
|
2133
|
+
ariaLabelKey = 'userMenu.open',
|
|
2134
|
+
ariaLabelDefault = 'Open user menu',
|
|
2135
|
+
dataMolId = 'user-menu',
|
|
2136
|
+
className,
|
|
2137
|
+
}: UserMenuPopoverTriggerProps): React.JSX.Element
|
|
2138
|
+
```
|
|
2139
|
+
|
|
2140
|
+
- `props` — aria-label overrides, `data-mol-id`, and className.
|
|
2141
|
+
|
|
2142
|
+
**Returns:** The popover trigger button.
|
|
2143
|
+
|
|
2144
|
+
#### `useToast()`
|
|
2145
|
+
|
|
2146
|
+
Hook to access the toast context for adding and removing toasts.
|
|
2147
|
+
|
|
2148
|
+
```typescript
|
|
2149
|
+
function useToast(): ToastContextValue
|
|
2150
|
+
```
|
|
2151
|
+
|
|
2152
|
+
**Returns:** The toast context value with toast management methods.
|
|
2153
|
+
|
|
2154
|
+
#### `useUserMenuPopoverClose()`
|
|
2155
|
+
|
|
2156
|
+
Returns a callback that closes the enclosing `UserMenuPopover`. Useful
|
|
2157
|
+
for nav-item `onClick` handlers that should dismiss the popover even
|
|
2158
|
+
when they don't change the route. Returns a no-op when called outside
|
|
2159
|
+
a `UserMenuPopover`.
|
|
2160
|
+
|
|
2161
|
+
```typescript
|
|
2162
|
+
function useUserMenuPopoverClose(): () => void
|
|
2163
|
+
```
|
|
2164
|
+
|
|
2165
|
+
**Returns:** A function that closes the popover.
|
|
2166
|
+
|
|
2167
|
+
### Constants
|
|
2168
|
+
|
|
2169
|
+
#### `Accordion`
|
|
2170
|
+
|
|
2171
|
+
Accordion component.
|
|
2172
|
+
|
|
2173
|
+
```typescript
|
|
2174
|
+
const Accordion: React.ForwardRefExoticComponent<
|
|
2175
|
+
AccordionProps<string> & React.RefAttributes<HTMLDivElement>
|
|
2176
|
+
>
|
|
2177
|
+
```
|
|
2178
|
+
|
|
2179
|
+
#### `Alert`
|
|
2180
|
+
|
|
2181
|
+
Alert component.
|
|
2182
|
+
|
|
2183
|
+
`role="alert"` is assertive: it interrupts a screen reader immediately,
|
|
2184
|
+
which is correct ONLY for content that appears dynamically (a validation
|
|
2185
|
+
error after submit, a save failure). An Alert rendered statically with
|
|
2186
|
+
the rest of the page (an informational banner already in the initial
|
|
2187
|
+
render) has nothing to interrupt — announcing it assertively on mount is
|
|
2188
|
+
the same over-announcing trap the Toast role fix addresses. `live`
|
|
2189
|
+
(default `true`, matching the previous unconditional behavior so no
|
|
2190
|
+
existing dynamic-error usage silently goes quiet) makes this honest and
|
|
2191
|
+
caller-controlled: pass `live={false}` for a banner that is part of the
|
|
2192
|
+
page's normal content, and it announces politely (`role="status"`)
|
|
2193
|
+
instead of interrupting.
|
|
2194
|
+
|
|
2195
|
+
```typescript
|
|
2196
|
+
const Alert: React.ForwardRefExoticComponent<
|
|
2197
|
+
AlertProps & { live?: boolean } & React.RefAttributes<HTMLDivElement>
|
|
2198
|
+
>
|
|
2199
|
+
```
|
|
2200
|
+
|
|
2201
|
+
#### `Avatar`
|
|
2202
|
+
|
|
2203
|
+
Avatar component.
|
|
2204
|
+
|
|
2205
|
+
```typescript
|
|
2206
|
+
const Avatar: React.ForwardRefExoticComponent<AvatarProps & React.RefAttributes<HTMLDivElement>>
|
|
2207
|
+
```
|
|
2208
|
+
|
|
2209
|
+
#### `Badge`
|
|
2210
|
+
|
|
2211
|
+
Badge component.
|
|
2212
|
+
|
|
2213
|
+
```typescript
|
|
2214
|
+
const Badge: React.ForwardRefExoticComponent<BadgeProps & React.RefAttributes<HTMLSpanElement>>
|
|
2215
|
+
```
|
|
2216
|
+
|
|
2217
|
+
#### `Button`
|
|
2218
|
+
|
|
2219
|
+
Button component.
|
|
2220
|
+
|
|
2221
|
+
```typescript
|
|
2222
|
+
const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>
|
|
2223
|
+
```
|
|
2224
|
+
|
|
2225
|
+
#### `Card`
|
|
2226
|
+
|
|
2227
|
+
Card component.
|
|
2228
|
+
|
|
2229
|
+
```typescript
|
|
2230
|
+
const Card: React.ForwardRefExoticComponent<
|
|
2231
|
+
CardProps & { 'data-mol-id'?: string } & React.RefAttributes<HTMLDivElement>
|
|
2232
|
+
>
|
|
2233
|
+
```
|
|
2234
|
+
|
|
2235
|
+
#### `CardContent`
|
|
2236
|
+
|
|
2237
|
+
Card content component.
|
|
2238
|
+
|
|
2239
|
+
```typescript
|
|
2240
|
+
const CardContent: React.ForwardRefExoticComponent<
|
|
2241
|
+
React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>
|
|
2242
|
+
>
|
|
2243
|
+
```
|
|
2244
|
+
|
|
2245
|
+
#### `CardDescription`
|
|
2246
|
+
|
|
2247
|
+
Card description component.
|
|
2248
|
+
|
|
2249
|
+
```typescript
|
|
2250
|
+
const CardDescription: React.ForwardRefExoticComponent<
|
|
2251
|
+
React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>
|
|
2252
|
+
>
|
|
2253
|
+
```
|
|
2254
|
+
|
|
2255
|
+
#### `CardFooter`
|
|
2256
|
+
|
|
2257
|
+
Card footer component.
|
|
2258
|
+
|
|
2259
|
+
```typescript
|
|
2260
|
+
const CardFooter: React.ForwardRefExoticComponent<
|
|
2261
|
+
React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>
|
|
2262
|
+
>
|
|
2263
|
+
```
|
|
2264
|
+
|
|
2265
|
+
#### `CardHeader`
|
|
2266
|
+
|
|
2267
|
+
Card header component.
|
|
2268
|
+
|
|
2269
|
+
```typescript
|
|
2270
|
+
const CardHeader: React.ForwardRefExoticComponent<
|
|
2271
|
+
React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>
|
|
2272
|
+
>
|
|
2273
|
+
```
|
|
2274
|
+
|
|
2275
|
+
#### `CardTitle`
|
|
2276
|
+
|
|
2277
|
+
Card title component.
|
|
2278
|
+
|
|
2279
|
+
```typescript
|
|
2280
|
+
const CardTitle: React.ForwardRefExoticComponent<
|
|
2281
|
+
React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLHeadingElement>
|
|
2282
|
+
>
|
|
2283
|
+
```
|
|
2284
|
+
|
|
2285
|
+
#### `Checkbox`
|
|
2286
|
+
|
|
2287
|
+
Checkbox component.
|
|
2288
|
+
|
|
2289
|
+
```typescript
|
|
2290
|
+
const Checkbox: React.ForwardRefExoticComponent<
|
|
2291
|
+
CheckboxProps & React.RefAttributes<HTMLInputElement>
|
|
2292
|
+
>
|
|
2293
|
+
```
|
|
2294
|
+
|
|
2295
|
+
#### `Container`
|
|
2296
|
+
|
|
2297
|
+
Container component.
|
|
2298
|
+
|
|
2299
|
+
```typescript
|
|
2300
|
+
const Container: React.ForwardRefExoticComponent<
|
|
2301
|
+
ContainerProps & React.RefAttributes<HTMLDivElement>
|
|
2302
|
+
>
|
|
2303
|
+
```
|
|
2304
|
+
|
|
2305
|
+
#### `Dropdown`
|
|
2306
|
+
|
|
2307
|
+
Dropdown component.
|
|
2308
|
+
|
|
2309
|
+
Implements the WAI-ARIA APG menu-button pattern. The trigger is made a
|
|
2310
|
+
real, keyboard-operable control: if `trigger` is a single element (a
|
|
2311
|
+
`<button>`, an icon `<Button>`, …) it is cloned with `aria-haspopup`,
|
|
2312
|
+
`aria-expanded`, `aria-controls`, and the open/keyboard handlers merged
|
|
2313
|
+
onto it directly — no extra wrapper, no double focus stop. If `trigger`
|
|
2314
|
+
is not a single element (text, a fragment, multiple nodes), it is wrapped
|
|
2315
|
+
in a `role="button" tabIndex={0}` container instead so keyboard/AT users
|
|
2316
|
+
can still reach it. Enter/Space/ArrowDown open the menu and move focus to
|
|
2317
|
+
the first item (ArrowUp opens to the last item); once open, ArrowUp/Down/
|
|
2318
|
+
Home/End roving-navigate the `role="menuitem"` items, Escape closes and
|
|
2319
|
+
returns focus to the trigger, and Tab closes the menu in sync with focus
|
|
2320
|
+
leaving it (matching native menus, which do not trap Tab).
|
|
2321
|
+
|
|
2322
|
+
```typescript
|
|
2323
|
+
const Dropdown: React.ForwardRefExoticComponent<
|
|
2324
|
+
DropdownProps<string> & React.RefAttributes<HTMLDivElement>
|
|
2325
|
+
>
|
|
2326
|
+
```
|
|
2327
|
+
|
|
2328
|
+
#### `DropdownLabel`
|
|
2329
|
+
|
|
2330
|
+
Dropdown label for grouping items.
|
|
2331
|
+
|
|
2332
|
+
```typescript
|
|
2333
|
+
const DropdownLabel: React.ForwardRefExoticComponent<
|
|
2334
|
+
{ children: React.ReactNode; className?: string } & React.RefAttributes<HTMLDivElement>
|
|
2335
|
+
>
|
|
2336
|
+
```
|
|
2337
|
+
|
|
2338
|
+
#### `DropdownSeparator`
|
|
2339
|
+
|
|
2340
|
+
Dropdown separator for dividing groups.
|
|
2341
|
+
|
|
2342
|
+
```typescript
|
|
2343
|
+
const DropdownSeparator: React.ForwardRefExoticComponent<
|
|
2344
|
+
{ className?: string } & React.RefAttributes<HTMLDivElement>
|
|
2345
|
+
>
|
|
2346
|
+
```
|
|
2347
|
+
|
|
2348
|
+
#### `EmptyState`
|
|
2349
|
+
|
|
2350
|
+
EmptyState component.
|
|
2351
|
+
|
|
2352
|
+
Displays a centered placeholder with an optional icon, title, description,
|
|
2353
|
+
and a primary action when a list or section has no content.
|
|
2354
|
+
|
|
2355
|
+
```typescript
|
|
2356
|
+
const EmptyState: React.ForwardRefExoticComponent<
|
|
2357
|
+
EmptyStateProps & React.RefAttributes<HTMLDivElement>
|
|
2358
|
+
>
|
|
2359
|
+
```
|
|
2360
|
+
|
|
2361
|
+
#### `Flex`
|
|
2362
|
+
|
|
2363
|
+
Flex container component.
|
|
2364
|
+
|
|
2365
|
+
```typescript
|
|
2366
|
+
const Flex: React.ForwardRefExoticComponent<FlexProps & React.RefAttributes<HTMLDivElement>>
|
|
2367
|
+
```
|
|
2368
|
+
|
|
2369
|
+
#### `FloatingInput`
|
|
2370
|
+
|
|
2371
|
+
An input with a floating label.
|
|
2372
|
+
|
|
2373
|
+
Shows the placeholder text as a small uppercase label always visible at
|
|
2374
|
+
the top of the input. On focus the label turns primary-colored.
|
|
2375
|
+
|
|
2376
|
+
Works as both a controlled and an uncontrolled input: when `value` is
|
|
2377
|
+
omitted, the component tracks its own state seeded from `defaultValue`
|
|
2378
|
+
and still forwards every `onChange` event to the caller.
|
|
2379
|
+
|
|
2380
|
+
The floating text is a real `<label htmlFor>` (not a bare `<span>`), so
|
|
2381
|
+
it is the input's programmatic accessible name via label association —
|
|
2382
|
+
previously the accessible name came only from `placeholder` (stripped by
|
|
2383
|
+
some AT/browser combos once the field has a value), and clicking the
|
|
2384
|
+
floating text did nothing because it wasn't associated with anything.
|
|
2385
|
+
`id` falls back to `useId()` when the caller doesn't pass one, mirroring
|
|
2386
|
+
Input/Select/Textarea's id-collision fix.
|
|
2387
|
+
|
|
2388
|
+
```typescript
|
|
2389
|
+
const FloatingInput: ForwardRefExoticComponent<FloatingInputProps & RefAttributes<HTMLInputElement>>
|
|
2390
|
+
```
|
|
2391
|
+
|
|
2392
|
+
#### `Form`
|
|
2393
|
+
|
|
2394
|
+
Form component.
|
|
2395
|
+
|
|
2396
|
+
```typescript
|
|
2397
|
+
const Form: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<HTMLFormElement>>
|
|
2398
|
+
```
|
|
2399
|
+
|
|
2400
|
+
#### `FormField`
|
|
2401
|
+
|
|
2402
|
+
Form field wrapper component.
|
|
2403
|
+
|
|
2404
|
+
```typescript
|
|
2405
|
+
const FormField: React.ForwardRefExoticComponent<
|
|
2406
|
+
FormFieldProps & React.RefAttributes<HTMLDivElement>
|
|
2407
|
+
>
|
|
2408
|
+
```
|
|
2409
|
+
|
|
2410
|
+
#### `Grid`
|
|
2411
|
+
|
|
2412
|
+
Grid container component.
|
|
2413
|
+
|
|
2414
|
+
```typescript
|
|
2415
|
+
const Grid: React.ForwardRefExoticComponent<GridProps & React.RefAttributes<HTMLDivElement>>
|
|
2416
|
+
```
|
|
2417
|
+
|
|
2418
|
+
#### `Input`
|
|
2419
|
+
|
|
2420
|
+
Input component.
|
|
2421
|
+
|
|
2422
|
+
```typescript
|
|
2423
|
+
const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>
|
|
2424
|
+
```
|
|
2425
|
+
|
|
2426
|
+
#### `Label`
|
|
2427
|
+
|
|
2428
|
+
Label component.
|
|
2429
|
+
|
|
2430
|
+
```typescript
|
|
2431
|
+
const Label: React.ForwardRefExoticComponent<
|
|
2432
|
+
React.LabelHTMLAttributes<HTMLLabelElement> & {
|
|
2433
|
+
required?: boolean
|
|
2434
|
+
} & React.RefAttributes<HTMLLabelElement>
|
|
2435
|
+
>
|
|
2436
|
+
```
|
|
2437
|
+
|
|
2438
|
+
#### `Modal`
|
|
2439
|
+
|
|
2440
|
+
Modal component.
|
|
2441
|
+
|
|
2442
|
+
Renders into a `document.body` portal. Forwards any extra `data-*` or
|
|
2443
|
+
`aria-*` props on the rest spread to the inner dialog `<div>` (e.g.
|
|
2444
|
+
callers commonly pass `data-mol-id="some-modal"` for AI-agent / e2e
|
|
2445
|
+
selectors).
|
|
2446
|
+
|
|
2447
|
+
The internal close button always carries `data-mol-id="modal-close"`
|
|
2448
|
+
as the molecule-convention default for the one fixed interactive
|
|
2449
|
+
element inside the chrome.
|
|
2450
|
+
|
|
2451
|
+
Implements the WAI-ARIA APG dialog (modal) pattern: on open, focus moves
|
|
2452
|
+
to the first focusable element inside the dialog (or the dialog itself
|
|
2453
|
+
when it has none); Tab/Shift+Tab are trapped inside the dialog; on close,
|
|
2454
|
+
focus returns to whatever was focused before the dialog opened. Stacked
|
|
2455
|
+
dialogs (a confirm above a drawer) each register on a module-level stack —
|
|
2456
|
+
Escape and the Tab trap only act for the TOPMOST dialog, and the body
|
|
2457
|
+
scroll lock is reference-counted so closing one of several open dialogs
|
|
2458
|
+
never unlocks scroll behind the ones still open.
|
|
2459
|
+
|
|
2460
|
+
```typescript
|
|
2461
|
+
const Modal: React.ForwardRefExoticComponent<
|
|
2462
|
+
ModalProps & { 'data-mol-id'?: string } & React.RefAttributes<HTMLDivElement>
|
|
2463
|
+
>
|
|
2464
|
+
```
|
|
2465
|
+
|
|
2466
|
+
#### `PageHeader`
|
|
2467
|
+
|
|
2468
|
+
PageHeader component.
|
|
2469
|
+
|
|
2470
|
+
Renders a page title with optional breadcrumb trail, description, and
|
|
2471
|
+
action buttons for a consistent page heading area.
|
|
2472
|
+
|
|
2473
|
+
```typescript
|
|
2474
|
+
const PageHeader: React.ForwardRefExoticComponent<
|
|
2475
|
+
PageHeaderProps & React.RefAttributes<HTMLDivElement>
|
|
2476
|
+
>
|
|
2477
|
+
```
|
|
2478
|
+
|
|
2479
|
+
#### `PageShell`
|
|
2480
|
+
|
|
2481
|
+
PageShell component.
|
|
2482
|
+
|
|
2483
|
+
Provides the top-level layout for authenticated pages with an optional
|
|
2484
|
+
collapsible sidebar, a top bar, and a scrollable main content area.
|
|
2485
|
+
|
|
2486
|
+
```typescript
|
|
2487
|
+
const PageShell: React.ForwardRefExoticComponent<
|
|
2488
|
+
PageShellProps & React.RefAttributes<HTMLDivElement>
|
|
2489
|
+
>
|
|
2490
|
+
```
|
|
2491
|
+
|
|
2492
|
+
#### `Pagination`
|
|
2493
|
+
|
|
2494
|
+
Pagination component.
|
|
2495
|
+
|
|
2496
|
+
```typescript
|
|
2497
|
+
const Pagination: React.ForwardRefExoticComponent<
|
|
2498
|
+
PaginationProps & React.RefAttributes<HTMLElement>
|
|
2499
|
+
>
|
|
2500
|
+
```
|
|
2501
|
+
|
|
2502
|
+
#### `Progress`
|
|
2503
|
+
|
|
2504
|
+
Progress component.
|
|
2505
|
+
|
|
2506
|
+
```typescript
|
|
2507
|
+
const Progress: React.ForwardRefExoticComponent<ProgressProps & React.RefAttributes<HTMLDivElement>>
|
|
2508
|
+
```
|
|
2509
|
+
|
|
2510
|
+
#### `RadioGroup`
|
|
2511
|
+
|
|
2512
|
+
RadioGroup component.
|
|
2513
|
+
|
|
2514
|
+
```typescript
|
|
2515
|
+
const RadioGroup: React.ForwardRefExoticComponent<
|
|
2516
|
+
RadioGroupProps<string> & React.RefAttributes<HTMLDivElement>
|
|
2517
|
+
>
|
|
2518
|
+
```
|
|
2519
|
+
|
|
2520
|
+
#### `Select`
|
|
2521
|
+
|
|
2522
|
+
Select component.
|
|
2523
|
+
|
|
2524
|
+
```typescript
|
|
2525
|
+
const Select: React.ForwardRefExoticComponent<
|
|
2526
|
+
SelectProps<string> & React.RefAttributes<HTMLSelectElement>
|
|
2527
|
+
>
|
|
2528
|
+
```
|
|
2529
|
+
|
|
2530
|
+
#### `Separator`
|
|
2531
|
+
|
|
2532
|
+
Separator component.
|
|
2533
|
+
|
|
2534
|
+
```typescript
|
|
2535
|
+
const Separator: React.ForwardRefExoticComponent<
|
|
2536
|
+
SeparatorProps & React.RefAttributes<HTMLDivElement>
|
|
2537
|
+
>
|
|
2538
|
+
```
|
|
2539
|
+
|
|
2540
|
+
#### `Skeleton`
|
|
2541
|
+
|
|
2542
|
+
Skeleton component.
|
|
2543
|
+
|
|
2544
|
+
```typescript
|
|
2545
|
+
const Skeleton: React.ForwardRefExoticComponent<SkeletonProps & React.RefAttributes<HTMLDivElement>>
|
|
2546
|
+
```
|
|
2547
|
+
|
|
2548
|
+
#### `SkeletonCircle`
|
|
2549
|
+
|
|
2550
|
+
Skeleton circle (avatar placeholder).
|
|
2551
|
+
|
|
2552
|
+
```typescript
|
|
2553
|
+
const SkeletonCircle: React.ForwardRefExoticComponent<
|
|
2554
|
+
{ size?: number; className?: string } & React.RefAttributes<HTMLDivElement>
|
|
2555
|
+
>
|
|
2556
|
+
```
|
|
2557
|
+
|
|
2558
|
+
#### `SkeletonText`
|
|
2559
|
+
|
|
2560
|
+
Skeleton text line.
|
|
2561
|
+
|
|
2562
|
+
```typescript
|
|
2563
|
+
const SkeletonText: React.ForwardRefExoticComponent<
|
|
2564
|
+
{ lines?: number; className?: string } & React.RefAttributes<HTMLDivElement>
|
|
2565
|
+
>
|
|
2566
|
+
```
|
|
2567
|
+
|
|
2568
|
+
#### `Spacer`
|
|
2569
|
+
|
|
2570
|
+
Spacer component.
|
|
2571
|
+
|
|
2572
|
+
```typescript
|
|
2573
|
+
const Spacer: React.ForwardRefExoticComponent<SpacerProps & React.RefAttributes<HTMLDivElement>>
|
|
2574
|
+
```
|
|
2575
|
+
|
|
2576
|
+
#### `Spinner`
|
|
2577
|
+
|
|
2578
|
+
Spinner component.
|
|
2579
|
+
|
|
2580
|
+
Extracts data-* and aria-* props from the rest spread so callers can
|
|
2581
|
+
pass `data-mol-id`, custom `aria-*` overrides, etc. without forking.
|
|
2582
|
+
|
|
2583
|
+
```typescript
|
|
2584
|
+
const Spinner: React.ForwardRefExoticComponent<
|
|
2585
|
+
SpinnerProps & { 'data-mol-id'?: string } & React.RefAttributes<HTMLDivElement>
|
|
2586
|
+
>
|
|
2587
|
+
```
|
|
2588
|
+
|
|
2589
|
+
#### `Switch`
|
|
2590
|
+
|
|
2591
|
+
Switch component.
|
|
2592
|
+
|
|
2593
|
+
```typescript
|
|
2594
|
+
const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLButtonElement>>
|
|
2595
|
+
```
|
|
2596
|
+
|
|
2597
|
+
#### `Table`
|
|
2598
|
+
|
|
2599
|
+
Table component.
|
|
2600
|
+
|
|
2601
|
+
```typescript
|
|
2602
|
+
const Table: React.ForwardRefExoticComponent<
|
|
2603
|
+
TableProps<Record<string, unknown>> & React.RefAttributes<HTMLTableElement>
|
|
2604
|
+
>
|
|
2605
|
+
```
|
|
2606
|
+
|
|
2607
|
+
#### `Tabs`
|
|
2608
|
+
|
|
2609
|
+
Tabs component.
|
|
2610
|
+
|
|
2611
|
+
```typescript
|
|
2612
|
+
const Tabs: React.ForwardRefExoticComponent<TabsProps<string> & React.RefAttributes<HTMLDivElement>>
|
|
2613
|
+
```
|
|
2614
|
+
|
|
2615
|
+
#### `Textarea`
|
|
2616
|
+
|
|
2617
|
+
Textarea component.
|
|
2618
|
+
|
|
2619
|
+
```typescript
|
|
2620
|
+
const Textarea: React.ForwardRefExoticComponent<
|
|
2621
|
+
TextareaProps & React.RefAttributes<HTMLTextAreaElement>
|
|
2622
|
+
>
|
|
2623
|
+
```
|
|
2624
|
+
|
|
2625
|
+
#### `Toast`
|
|
2626
|
+
|
|
2627
|
+
Single Toast component.
|
|
2628
|
+
|
|
2629
|
+
The auto-dismiss countdown pauses on hover AND focus (WCAG 2.2.1) and
|
|
2630
|
+
resumes with whatever time was left — a slow reader or a keyboard/AT
|
|
2631
|
+
user interacting with the toast never has it disappear mid-read. The
|
|
2632
|
+
announced role follows `status`: `warning`/`error` get the assertive
|
|
2633
|
+
`role="alert"`; every other status (`info`, `success`, the default) gets
|
|
2634
|
+
the polite `role="status"` so routine confirmations don't interrupt a
|
|
2635
|
+
screen reader mid-sentence the way an assertive announcement does.
|
|
2636
|
+
|
|
2637
|
+
```typescript
|
|
2638
|
+
const Toast: React.ForwardRefExoticComponent<ToastProps & React.RefAttributes<HTMLDivElement>>
|
|
2639
|
+
```
|
|
2640
|
+
|
|
2641
|
+
#### `ToastContainer`
|
|
2642
|
+
|
|
2643
|
+
Container that positions toasts on screen via a portal.
|
|
2644
|
+
|
|
2645
|
+
```typescript
|
|
2646
|
+
const ToastContainer: React.ForwardRefExoticComponent<
|
|
2647
|
+
ToastContainerProps & React.RefAttributes<HTMLDivElement>
|
|
2648
|
+
>
|
|
2649
|
+
```
|
|
2650
|
+
|
|
2651
|
+
#### `Tooltip`
|
|
2652
|
+
|
|
2653
|
+
Tooltip component.
|
|
2654
|
+
|
|
2655
|
+
`children` must be a single valid React element (e.g. one `<button>` or
|
|
2656
|
+
one custom component that forwards `aria-describedby`) for the tooltip's
|
|
2657
|
+
content to be programmatically associated with it — this is what lets a
|
|
2658
|
+
screen reader announce the tooltip text for the actually-focused control.
|
|
2659
|
+
A non-element `children` (plain text, a fragment, multiple nodes) still
|
|
2660
|
+
shows the tooltip visually on hover/focus, but without that association.
|
|
2661
|
+
`hasArrow` renders a small themed pointer at the resolved `placement`
|
|
2662
|
+
edge.
|
|
2663
|
+
|
|
2664
|
+
```typescript
|
|
2665
|
+
const Tooltip: React.ForwardRefExoticComponent<TooltipProps & React.RefAttributes<HTMLDivElement>>
|
|
2666
|
+
```
|
|
2667
|
+
|
|
2668
|
+
## Injection Notes
|
|
2669
|
+
|
|
2670
|
+
### Requirements
|
|
2671
|
+
|
|
2672
|
+
Peer dependencies:
|
|
2673
|
+
|
|
2674
|
+
- `@molecule/app-i18n` ^1.0.0
|
|
2675
|
+
- `@molecule/app-icons` ^1.0.0
|
|
2676
|
+
- `@molecule/app-react` ^1.0.0
|
|
2677
|
+
- `@molecule/app-ui` ^1.0.0
|
|
2678
|
+
- `react` ^18.0.0 || ^19.0.0
|
|
2679
|
+
- `react-dom` ^18.0.0 || ^19.0.0
|
|
2680
|
+
- `react-router` ^7.0.0 || ^8.0.0
|
|
2681
|
+
|
|
2682
|
+
### Runtime Dependencies
|
|
2683
|
+
|
|
2684
|
+
- `@molecule/app-i18n`
|
|
2685
|
+
- `@molecule/app-icons`
|
|
2686
|
+
- `@molecule/app-react`
|
|
2687
|
+
- `@molecule/app-ui`
|
|
2688
|
+
- `react`
|
|
2689
|
+
- `react-dom`
|
|
2690
|
+
- `react-router`
|
|
2691
|
+
|
|
2692
|
+
Wiring prerequisites — get these right before debugging anything else:
|
|
2693
|
+
|
|
2694
|
+
- **A ClassMap bond must be set before first render.** Every component resolves styling via
|
|
2695
|
+
`getClassMap()` from `@molecule/app-ui`, which THROWS ("No UIClassMap has been set") until
|
|
2696
|
+
`setClassMap(...)` runs with a bond like `@molecule/app-ui-tailwind`. Scaffolded apps do
|
|
2697
|
+
this in `bonds/index.ts` — keep that import first in `main.tsx`.
|
|
2698
|
+
- **Some components require molecule providers from `@molecule/app-react`** and throw without
|
|
2699
|
+
them: `UserMenu`, `UserMenuPopover`, `LanguagePicker`, `SidebarUserCard`, `AuthGuard`, and
|
|
2700
|
+
`ThemeToggle` need `I18nProvider` (via `MoleculeProvider i18n={...}`); `ThemeToggle` also
|
|
2701
|
+
needs `ThemeProvider`; `AuthGuard` also needs `AuthProvider`. The primitive components
|
|
2702
|
+
(Button, Modal, Input, …) need only the ClassMap.
|
|
2703
|
+
- **Router-linked components** (`UserMenu`, `UserMenuPopover`, `SidebarUserCard`, `Dropdown`
|
|
2704
|
+
item `href`s, `AuthGuard` redirects) render react-router `<Link>`/navigation — they need a
|
|
2705
|
+
react-router context (`<BrowserRouter>`) and, in workspace dev setups, the Vite
|
|
2706
|
+
`resolve.dedupe: ['react', 'react-dom', 'react-router', 'react-router']` entry; a
|
|
2707
|
+
duplicate copy surfaces as "useHref may be used only in the context of a <Router>".
|
|
2708
|
+
- **`UserMenu` panel content is `children`** (rendered inside the popover, with
|
|
2709
|
+
`PanelClose`/`usePanelClose` available) — there is no `renderPanel` prop.
|
|
2710
|
+
- **`Icon` names are kebab-case `IconName`s from `@molecule/app-icons`** — an unknown name is
|
|
2711
|
+
a runtime error, not a blank. Extend via `CustomIconNames` augmentation, never raw SVG.
|
|
2712
|
+
- **Name collisions with feature packages** — several feature packages export a
|
|
2713
|
+
same-named component; import from the package whose props/behavior you want:
|
|
2714
|
+
- `EmptyState` — also `@molecule/app-empty-state-react` (adds an icon badge,
|
|
2715
|
+
per-brand `className`/`dataMolId`, and a companion `<CtaCard>`). THIS one is the
|
|
2716
|
+
primitive icon/title/description/action variant.
|
|
2717
|
+
- `PageHeader` — also `@molecule/app-page-chrome-react` (adds `subtitle`, `icon`,
|
|
2718
|
+
`meta`, `emphasis` + a `<HeroSection>`). THIS one takes
|
|
2719
|
+
`title`/`description`/`actions`/`breadcrumbs`.
|
|
2720
|
+
- `Pagination` — the low-level page-window control (no "showing X of Y" text, no
|
|
2721
|
+
page-size selector); for those use `<PaginationBar>` from
|
|
2722
|
+
`@molecule/app-pagination-bar-react`.
|
|
2723
|
+
|
|
2724
|
+
A11y contracts worth knowing before you debug "it doesn't look like it's
|
|
2725
|
+
doing anything" on these components:
|
|
2726
|
+
|
|
2727
|
+
- **`Modal`** implements the WAI-ARIA APG dialog pattern: opening moves
|
|
2728
|
+
focus to the first focusable element inside the dialog (or the dialog
|
|
2729
|
+
itself when it has none); Tab/Shift+Tab are trapped inside; closing
|
|
2730
|
+
restores focus to whatever opened it. Stacked dialogs (a confirm above a
|
|
2731
|
+
drawer) register on a module-level stack — Escape and the Tab trap only
|
|
2732
|
+
act for the TOPMOST dialog, and the body scroll lock is
|
|
2733
|
+
reference-counted, so closing one of several open dialogs never unlocks
|
|
2734
|
+
scroll behind the ones still open. `centered={false}` top-anchors the
|
|
2735
|
+
dialog instead of vertically centering it (an inline-style exception —
|
|
2736
|
+
`UIClassMap` has no `dialogWrapper({ centered })` resolver yet).
|
|
2737
|
+
- **`Dropdown`** implements the WAI-ARIA APG menu-button pattern: the
|
|
2738
|
+
`trigger` is made a real, keyboard-operable control (cloned with
|
|
2739
|
+
`aria-haspopup`/`aria-expanded`/`aria-controls` when it's a single
|
|
2740
|
+
element; wrapped in a `role="button" tabIndex={0}` container otherwise).
|
|
2741
|
+
Enter/Space/ArrowDown open the menu and focus the first item (ArrowUp
|
|
2742
|
+
opens to the last); once open, ArrowUp/Down/Home/End roving-navigate the
|
|
2743
|
+
`menuitem`s, Escape closes and returns focus to the trigger, and Tab
|
|
2744
|
+
closes the menu in sync with focus leaving it (native menus don't trap
|
|
2745
|
+
Tab). `width="trigger"` never renders literal `width: 'trigger'` CSS on
|
|
2746
|
+
the not-yet-measurable first-open frame — it renders unset instead.
|
|
2747
|
+
- **`Tooltip`** requires a single element as `children` for its content to
|
|
2748
|
+
be programmatically associated (`aria-describedby`, injected via
|
|
2749
|
+
`cloneElement`) with the actually-focused/hovered control — a non-element
|
|
2750
|
+
`children` still shows visually but without that association.
|
|
2751
|
+
`hasArrow` renders a small themed pointer at the resolved `placement`.
|
|
2752
|
+
- **`Toast`** pauses its auto-dismiss countdown on hover AND focus (WCAG
|
|
2753
|
+
2.2.1) and resumes with whatever time was left. The announced role
|
|
2754
|
+
follows `status`: `warning`/`error` get the assertive `role="alert"`;
|
|
2755
|
+
every other status gets the polite `role="status"` so a routine
|
|
2756
|
+
confirmation doesn't interrupt a screen reader mid-sentence.
|
|
2757
|
+
- **`Alert`** takes a `live` prop (default `true`, matching the previous
|
|
2758
|
+
unconditional behavior): `live={false}` switches it from the assertive
|
|
2759
|
+
`role="alert"` to the polite `role="status"` for a banner that's part of
|
|
2760
|
+
the page's normal (not dynamically-appearing) content.
|
|
2761
|
+
- **`UserMenuPopover*`**: `UserMenuPopoverPanel` is a disclosure region
|
|
2762
|
+
(`aria-expanded` + `aria-controls` on the trigger, no role on the panel
|
|
2763
|
+
itself), NOT `role="menu"` — it renders a header plus a `<nav>` of
|
|
2764
|
+
arbitrary links, which is invalid content for `role="menu"` (that role
|
|
2765
|
+
may contain ONLY `menuitem` descendants).
|
|
2766
|
+
- **`Switch`** dispatches a REAL native `change` Event through its hidden
|
|
2767
|
+
checkbox — `event.preventDefault()`, `event.currentTarget`, and
|
|
2768
|
+
`event.stopPropagation()` all behave like they do for any native input
|
|
2769
|
+
(previously the handler received a synthesized `{ target: { checked } }`
|
|
2770
|
+
object that crashed on any of those).
|
|
2771
|
+
- **`Tabs`** implements the WAI-ARIA APG tabs pattern: roving tabindex
|
|
2772
|
+
(only the active tab is in the Tab order) with ArrowLeft/ArrowRight/
|
|
2773
|
+
Home/End moving focus and selection.
|
|
2774
|
+
- **`FormField`** wires `aria-describedby` from its error paragraph onto
|
|
2775
|
+
the child input automatically (falling back to a `useId()`-derived id
|
|
2776
|
+
when no `name` prop is given) — don't duplicate the association by hand.
|
|
2777
|
+
- **`Progress`** clamps `aria-valuenow` into `[0, max]` to match the
|
|
2778
|
+
clamped visual bar, so out-of-range values never announce impossible
|
|
2779
|
+
percentages.
|
|
2780
|
+
- **`Textarea`** `autoResize` also works uncontrolled (`defaultValue` +
|
|
2781
|
+
user typing): it listens to `input` events rather than only reacting to
|
|
2782
|
+
the controlled `value` prop.
|
|
2783
|
+
|
|
2784
|
+
## Translations
|
|
2785
|
+
|
|
2786
|
+
Translation strings are provided by `@molecule/app-locales-ui`.
|