@human-synthesis/norns-ui 0.0.11 → 0.0.13
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/COMPONENTS.md +1417 -0
- package/README.md +5 -3
- package/package.json +8 -5
- package/src/index.js +1 -0
- package/src/types/Window.d.ts +22 -0
package/COMPONENTS.md
ADDED
|
@@ -0,0 +1,1417 @@
|
|
|
1
|
+
# norns-ui — component reference
|
|
2
|
+
|
|
3
|
+
Generated by `bun run docs:components` from `src/types/*.d.ts`. Do not edit by hand.
|
|
4
|
+
|
|
5
|
+
Every component under **components/** is auto-imported by name in `.n` files when the consumer wires `presetUI()` into `nornsAutoImport` (`Btn(variant="primary") Save`). Components under **motion/** are opt-in: `import { Reveal } from '@human-synthesis/norns-ui/motion'`. Snippet props (`children`, `header`, `trigger`, …) are filled with `+snippet('name')` blocks in Pug. Every component accepts `class` and merges it with `cn()`.
|
|
6
|
+
|
|
7
|
+
Live usage of every component: `norns-demo/src/routes/examples/ui/+page.n`.
|
|
8
|
+
|
|
9
|
+
## Components
|
|
10
|
+
|
|
11
|
+
[Accordion](#accordion) · [Audio](#audio) · [Autocomplete](#autocomplete) · [Avatar](#avatar) · [AvatarGroup](#avatargroup) · [Badge](#badge) · [Banner](#banner) · [Breadcrumbs](#breadcrumbs) · [Btn](#btn) · [ButtonGroup](#buttongroup) · [Calendar](#calendar) · [Card](#card) · [Carousel](#carousel) · [Checkbox](#checkbox) · [Chip](#chip) · [Collapsible](#collapsible) · [ColorPicker](#colorpicker) · [ContextMenu](#contextmenu) · [CopyButton](#copybutton) · [DataTable](#datatable) · [DatePicker](#datepicker) · [DateRangePicker](#daterangepicker) · [Dialog](#dialog) · [Dropdown](#dropdown) · [Field](#field) · [FieldGroup](#fieldgroup) · [Form](#form) · [GradientText](#gradienttext) · [Header](#header) · [HeroBanner](#herobanner) · [HierarchicalMenu](#hierarchicalmenu) · [Icon](#icon) · [Image](#image) · [Input](#input) · [MegaMenu](#megamenu) · [MultiSelect](#multiselect) · [NumberInput](#numberinput) · [OtpField](#otpfield) · [Pagination](#pagination) · [Popover](#popover) · [Progress](#progress) · [ProgressCircular](#progresscircular) · [Radio](#radio) · [RippleButton](#ripplebutton) · [ScrollArea](#scrollarea) · [Select](#select) · [Separator](#separator) · [Sheet](#sheet) · [ShinyButton](#shinybutton) · [Skeleton](#skeleton) · [Stepper](#stepper) · [Surface](#surface) · [Switch](#switch) · [Tabs](#tabs) · [TagsInput](#tagsinput) · [Textarea](#textarea) · [ThemeToggler](#themetoggler) · [Timeline](#timeline) · [TimePicker](#timepicker) · [ToastProvider](#toastprovider) · [ToggleButton](#togglebutton) · [ToggleButtonGroup](#togglebuttongroup) · [Toolbar](#toolbar) · [Tooltip](#tooltip) · [Tree](#tree) · [Uploader](#uploader) · [Video](#video) · [Window](#window)
|
|
12
|
+
|
|
13
|
+
### Accordion
|
|
14
|
+
|
|
15
|
+
`@human-synthesis/norns-ui/components/Accordion.n`
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
export type AccordionItem = {
|
|
19
|
+
value: string;
|
|
20
|
+
title: string;
|
|
21
|
+
content?: Snippet;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type AccordionProps = {
|
|
25
|
+
items?: AccordionItem[];
|
|
26
|
+
multiple?: boolean;
|
|
27
|
+
value?: string | string[];
|
|
28
|
+
class?: string;
|
|
29
|
+
};
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Audio
|
|
33
|
+
|
|
34
|
+
`@human-synthesis/norns-ui/components/Audio.n`
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
export type AudioSource = { src: string; type?: string };
|
|
38
|
+
|
|
39
|
+
export type AudioProps = {
|
|
40
|
+
src?: string;
|
|
41
|
+
sources?: AudioSource[];
|
|
42
|
+
controls?: boolean;
|
|
43
|
+
autoplay?: boolean;
|
|
44
|
+
loop?: boolean;
|
|
45
|
+
muted?: boolean;
|
|
46
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
47
|
+
fallback?: string;
|
|
48
|
+
class?: string;
|
|
49
|
+
};
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Autocomplete
|
|
53
|
+
|
|
54
|
+
`@human-synthesis/norns-ui/components/Autocomplete.n`
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
export type ComboboxItem = { value: string; label: string };
|
|
58
|
+
|
|
59
|
+
export type AutocompleteProps = {
|
|
60
|
+
items?: ComboboxItem[];
|
|
61
|
+
value?: string;
|
|
62
|
+
open?: boolean;
|
|
63
|
+
placeholder?: string;
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
name?: string;
|
|
66
|
+
id?: string;
|
|
67
|
+
error?: boolean;
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Avatar
|
|
72
|
+
|
|
73
|
+
`@human-synthesis/norns-ui/components/Avatar.n`
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
export type AvatarSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
77
|
+
|
|
78
|
+
export type AvatarProps = {
|
|
79
|
+
src?: string;
|
|
80
|
+
/** Display name; first + last initial used as fallback when `src` is missing. */
|
|
81
|
+
name?: string;
|
|
82
|
+
size?: AvatarSize;
|
|
83
|
+
class?: string;
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### AvatarGroup
|
|
88
|
+
|
|
89
|
+
`@human-synthesis/norns-ui/components/AvatarGroup.n`
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
export type AvatarGroupItem = { src?: string; name?: string };
|
|
93
|
+
|
|
94
|
+
export type AvatarGroupProps = {
|
|
95
|
+
items?: AvatarGroupItem[];
|
|
96
|
+
max?: number;
|
|
97
|
+
size?: AvatarSize;
|
|
98
|
+
label?: string;
|
|
99
|
+
class?: string;
|
|
100
|
+
};
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Badge
|
|
104
|
+
|
|
105
|
+
`@human-synthesis/norns-ui/components/Badge.n`
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
export type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
|
109
|
+
export type BadgeSize = 'sm' | 'md';
|
|
110
|
+
|
|
111
|
+
export type BadgeProps = {
|
|
112
|
+
variant?: BadgeVariant;
|
|
113
|
+
size?: BadgeSize;
|
|
114
|
+
children?: Snippet;
|
|
115
|
+
class?: string;
|
|
116
|
+
};
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Banner
|
|
120
|
+
|
|
121
|
+
`@human-synthesis/norns-ui/components/Banner.n`
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
export type BannerVariant = 'info' | 'success' | 'warning' | 'danger';
|
|
125
|
+
|
|
126
|
+
export type BannerProps = {
|
|
127
|
+
variant?: BannerVariant;
|
|
128
|
+
/** Iconify icon name (e.g. `"lucide:alert-triangle"`). */
|
|
129
|
+
icon?: string;
|
|
130
|
+
actions?: Snippet;
|
|
131
|
+
children?: Snippet;
|
|
132
|
+
class?: string;
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Breadcrumbs
|
|
137
|
+
|
|
138
|
+
`@human-synthesis/norns-ui/components/Breadcrumbs.n`
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
export type BreadcrumbItem = {
|
|
142
|
+
label: string;
|
|
143
|
+
href?: string;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export type BreadcrumbsProps = {
|
|
147
|
+
items?: BreadcrumbItem[];
|
|
148
|
+
separator?: string;
|
|
149
|
+
class?: string;
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Btn
|
|
154
|
+
|
|
155
|
+
`@human-synthesis/norns-ui/components/Btn.n`
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
/**
|
|
159
|
+
* Type shim for `Btn.n`. Hand-rolled until we have a proper
|
|
160
|
+
* `svelte-package` build over the Civet+Pug source.
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
export type BtnVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
165
|
+
export type BtnSize = 'sm' | 'md' | 'lg';
|
|
166
|
+
|
|
167
|
+
export type BtnProps = Omit<HTMLButtonAttributes, 'class' | 'children'> & {
|
|
168
|
+
variant?: BtnVariant;
|
|
169
|
+
size?: BtnSize;
|
|
170
|
+
loading?: boolean;
|
|
171
|
+
disabled?: boolean;
|
|
172
|
+
type?: 'button' | 'submit' | 'reset';
|
|
173
|
+
/**
|
|
174
|
+
* Convenience: Iconify icon name (e.g. `"lucide:save"`). Renders an
|
|
175
|
+
* `<Icon>` in the leading slot. If you also pass a `leading` snippet,
|
|
176
|
+
* the snippet wins.
|
|
177
|
+
*/
|
|
178
|
+
icon?: string;
|
|
179
|
+
/** When set, renders as an `<a>` styled like the button. */
|
|
180
|
+
href?: string;
|
|
181
|
+
target?: string;
|
|
182
|
+
rel?: string;
|
|
183
|
+
class?: string;
|
|
184
|
+
children?: Snippet;
|
|
185
|
+
leading?: Snippet;
|
|
186
|
+
trailing?: Snippet;
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### ButtonGroup
|
|
191
|
+
|
|
192
|
+
`@human-synthesis/norns-ui/components/ButtonGroup.n`
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
export type ButtonGroupProps = {
|
|
196
|
+
orientation?: 'horizontal' | 'vertical';
|
|
197
|
+
children?: Snippet;
|
|
198
|
+
class?: string;
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Calendar
|
|
203
|
+
|
|
204
|
+
`@human-synthesis/norns-ui/components/Calendar.n`
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
export type CalendarDateRange = { start: string; end: string };
|
|
208
|
+
|
|
209
|
+
export type CalendarProps = {
|
|
210
|
+
/** ISO YYYY-MM-DD. Bindable. */
|
|
211
|
+
value?: string;
|
|
212
|
+
/** Range mode. Bindable. Use instead of `value` when `range` is true. */
|
|
213
|
+
rangeValue?: CalendarDateRange;
|
|
214
|
+
range?: boolean;
|
|
215
|
+
/** ISO YYYY-MM-DD inclusive. */
|
|
216
|
+
min?: string;
|
|
217
|
+
max?: string;
|
|
218
|
+
label?: string;
|
|
219
|
+
onchange?: (next: string | CalendarDateRange) => void;
|
|
220
|
+
class?: string;
|
|
221
|
+
};
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Card
|
|
225
|
+
|
|
226
|
+
`@human-synthesis/norns-ui/components/Card.n`
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
export type CardProps = {
|
|
230
|
+
/** Wrap body in `.card-body` (default true). Set false for full-bleed content. */
|
|
231
|
+
padded?: boolean;
|
|
232
|
+
/** Apply `.card-interactive` hover/focus treatment. Implicit if `href` is set. */
|
|
233
|
+
interactive?: boolean;
|
|
234
|
+
/** Renders as `<a>` instead of `<div>` when set. */
|
|
235
|
+
href?: string;
|
|
236
|
+
target?: string;
|
|
237
|
+
rel?: string;
|
|
238
|
+
header?: Snippet;
|
|
239
|
+
footer?: Snippet;
|
|
240
|
+
children?: Snippet;
|
|
241
|
+
class?: string;
|
|
242
|
+
};
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Carousel
|
|
246
|
+
|
|
247
|
+
`@human-synthesis/norns-ui/components/Carousel.n`
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
export type CarouselSlide = {
|
|
251
|
+
src?: string;
|
|
252
|
+
alt?: string;
|
|
253
|
+
[key: string]: unknown;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export type CarouselProps = {
|
|
257
|
+
slides?: CarouselSlide[];
|
|
258
|
+
index?: number;
|
|
259
|
+
autoplay?: boolean;
|
|
260
|
+
/** Autoplay interval in milliseconds. Default 5000. */
|
|
261
|
+
interval?: number;
|
|
262
|
+
/** Default aspect ratio applied if no explicit `class="aspect-..."` is passed. */
|
|
263
|
+
aspect?: 'video' | 'square' | 'wide' | 'none';
|
|
264
|
+
/** Custom slide renderer; receives `(slide, i)` and runs only for slides without `src`. */
|
|
265
|
+
children?: Snippet<[CarouselSlide, number]>;
|
|
266
|
+
class?: string;
|
|
267
|
+
};
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Checkbox
|
|
271
|
+
|
|
272
|
+
`@human-synthesis/norns-ui/components/Checkbox.n`
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
export type CheckboxProps = Omit<HTMLInputAttributes, 'class' | 'type' | 'checked'> & {
|
|
276
|
+
checked?: boolean;
|
|
277
|
+
error?: boolean;
|
|
278
|
+
class?: string;
|
|
279
|
+
};
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Chip
|
|
283
|
+
|
|
284
|
+
`@human-synthesis/norns-ui/components/Chip.n`
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
export type ChipProps = {
|
|
288
|
+
icon?: string;
|
|
289
|
+
removable?: boolean;
|
|
290
|
+
onremove?: (event: MouseEvent) => void;
|
|
291
|
+
children?: Snippet;
|
|
292
|
+
class?: string;
|
|
293
|
+
};
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Collapsible
|
|
297
|
+
|
|
298
|
+
`@human-synthesis/norns-ui/components/Collapsible.n`
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
export type CollapsibleProps = {
|
|
302
|
+
open?: boolean;
|
|
303
|
+
title?: string;
|
|
304
|
+
trigger?: Snippet;
|
|
305
|
+
children?: Snippet;
|
|
306
|
+
onopenchange?: (open: boolean) => void;
|
|
307
|
+
class?: string;
|
|
308
|
+
};
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### ColorPicker
|
|
312
|
+
|
|
313
|
+
`@human-synthesis/norns-ui/components/ColorPicker.n`
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
export type ColorPickerProps = {
|
|
317
|
+
/** Hex value with leading `#`. Bindable. */
|
|
318
|
+
value?: string;
|
|
319
|
+
disabled?: boolean;
|
|
320
|
+
/** Hide the clipboard-copy button. */
|
|
321
|
+
hideCopy?: boolean;
|
|
322
|
+
name?: string;
|
|
323
|
+
id?: string;
|
|
324
|
+
class?: string;
|
|
325
|
+
};
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### ContextMenu
|
|
329
|
+
|
|
330
|
+
`@human-synthesis/norns-ui/components/ContextMenu.n`
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
export type ContextMenuItem = {
|
|
334
|
+
label?: string;
|
|
335
|
+
icon?: string;
|
|
336
|
+
separator?: boolean;
|
|
337
|
+
disabled?: boolean;
|
|
338
|
+
onSelect?: () => void;
|
|
339
|
+
/**
|
|
340
|
+
* NOTE: nested submenus are not supported in 0.0.6+ (the property is
|
|
341
|
+
* accepted but children are ignored). Re-introduce when the upstream
|
|
342
|
+
* design needs them.
|
|
343
|
+
*/
|
|
344
|
+
children?: ContextMenuItem[];
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export type ContextMenuProps = {
|
|
348
|
+
items?: ContextMenuItem[];
|
|
349
|
+
trigger?: Snippet;
|
|
350
|
+
triggerClass?: string;
|
|
351
|
+
};
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### CopyButton
|
|
355
|
+
|
|
356
|
+
`@human-synthesis/norns-ui/components/CopyButton.n`
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
export type CopyButtonProps = {
|
|
360
|
+
value?: string | number;
|
|
361
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
362
|
+
size?: 'sm' | 'md' | 'lg';
|
|
363
|
+
icon?: string;
|
|
364
|
+
disabled?: boolean;
|
|
365
|
+
label?: string;
|
|
366
|
+
oncopy?: (value: string | number) => void;
|
|
367
|
+
children?: Snippet;
|
|
368
|
+
class?: string;
|
|
369
|
+
};
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### DataTable
|
|
373
|
+
|
|
374
|
+
`@human-synthesis/norns-ui/components/DataTable.n`
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
export type DataTableColumn = {
|
|
378
|
+
key: string;
|
|
379
|
+
label?: string;
|
|
380
|
+
width?: string;
|
|
381
|
+
class?: string;
|
|
382
|
+
cellClass?: string;
|
|
383
|
+
sortable?: boolean;
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
export type DataTableProps = {
|
|
387
|
+
columns?: DataTableColumn[];
|
|
388
|
+
rows?: Record<string, unknown>[];
|
|
389
|
+
striped?: boolean;
|
|
390
|
+
dense?: boolean;
|
|
391
|
+
stickyHeader?: boolean;
|
|
392
|
+
emptyMessage?: string;
|
|
393
|
+
/** Currently-sorted column key. Bindable. */
|
|
394
|
+
sortKey?: string;
|
|
395
|
+
sortDir?: 'asc' | 'desc';
|
|
396
|
+
onrowclick?: (row: Record<string, unknown>, index: number) => void;
|
|
397
|
+
class?: string;
|
|
398
|
+
};
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### DatePicker
|
|
402
|
+
|
|
403
|
+
`@human-synthesis/norns-ui/components/DatePicker.n`
|
|
404
|
+
|
|
405
|
+
```ts
|
|
406
|
+
export type DatePickerProps = {
|
|
407
|
+
/** ISO date string (YYYY-MM-DD). Bindable. */
|
|
408
|
+
value?: string;
|
|
409
|
+
/** Whether the popover is open. Bindable. */
|
|
410
|
+
open?: boolean;
|
|
411
|
+
min?: string;
|
|
412
|
+
max?: string;
|
|
413
|
+
placeholder?: string;
|
|
414
|
+
disabled?: boolean;
|
|
415
|
+
/** Close the popover automatically once a date is picked (default true). */
|
|
416
|
+
closeOnSelect?: boolean;
|
|
417
|
+
/** aria-label override; defaults to "Pick a date". */
|
|
418
|
+
label?: string;
|
|
419
|
+
name?: string;
|
|
420
|
+
id?: string;
|
|
421
|
+
error?: boolean;
|
|
422
|
+
class?: string;
|
|
423
|
+
};
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### DateRangePicker
|
|
427
|
+
|
|
428
|
+
`@human-synthesis/norns-ui/components/DateRangePicker.n`
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
export type DateRange = { start: string; end: string };
|
|
432
|
+
|
|
433
|
+
export type DateRangePickerProps = {
|
|
434
|
+
value?: DateRange;
|
|
435
|
+
/** Whether the popover is open. Bindable. */
|
|
436
|
+
open?: boolean;
|
|
437
|
+
min?: string;
|
|
438
|
+
max?: string;
|
|
439
|
+
placeholder?: string;
|
|
440
|
+
disabled?: boolean;
|
|
441
|
+
class?: string;
|
|
442
|
+
};
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Dialog
|
|
446
|
+
|
|
447
|
+
`@human-synthesis/norns-ui/components/Dialog.n`
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
export type DialogProps = {
|
|
451
|
+
open?: boolean;
|
|
452
|
+
title?: string;
|
|
453
|
+
description?: string;
|
|
454
|
+
hideClose?: boolean;
|
|
455
|
+
/** Close on overlay click and Escape. Default true. */
|
|
456
|
+
dismissable?: boolean;
|
|
457
|
+
/** Used as `aria-label` on the dialog when no `title` is provided. */
|
|
458
|
+
ariaLabel?: string;
|
|
459
|
+
trigger?: Snippet;
|
|
460
|
+
actions?: Snippet;
|
|
461
|
+
children?: Snippet;
|
|
462
|
+
triggerClass?: string;
|
|
463
|
+
overlayClass?: string;
|
|
464
|
+
class?: string;
|
|
465
|
+
};
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Dropdown
|
|
469
|
+
|
|
470
|
+
`@human-synthesis/norns-ui/components/Dropdown.n`
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
export type DropdownItem = {
|
|
474
|
+
label?: string;
|
|
475
|
+
icon?: string;
|
|
476
|
+
separator?: boolean;
|
|
477
|
+
disabled?: boolean;
|
|
478
|
+
onSelect?: () => void;
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
export type DropdownProps = {
|
|
482
|
+
open?: boolean;
|
|
483
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
484
|
+
align?: 'start' | 'center' | 'end';
|
|
485
|
+
sideOffset?: number;
|
|
486
|
+
items?: DropdownItem[];
|
|
487
|
+
trigger?: Snippet;
|
|
488
|
+
children?: Snippet;
|
|
489
|
+
triggerClass?: string;
|
|
490
|
+
class?: string;
|
|
491
|
+
};
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Field
|
|
495
|
+
|
|
496
|
+
`@human-synthesis/norns-ui/components/Field.n`
|
|
497
|
+
|
|
498
|
+
```ts
|
|
499
|
+
export type FieldProps = {
|
|
500
|
+
/** Label text rendered above the control. Used as id-derivation fallback if no `id`/`name` is given. */
|
|
501
|
+
label?: string;
|
|
502
|
+
/** Helper text shown below the control when there's no error. */
|
|
503
|
+
help?: string;
|
|
504
|
+
/**
|
|
505
|
+
* Explicit error message. Overrides any auto-resolved error from the
|
|
506
|
+
* parent `<Form form={...}>` context. Switches the inner control to
|
|
507
|
+
* error styling.
|
|
508
|
+
*/
|
|
509
|
+
error?: string;
|
|
510
|
+
/**
|
|
511
|
+
* Field name — used to look up an auto-error from the parent `<Form>`
|
|
512
|
+
* context (matching `form.errors[*].path[0].key`) and as the default
|
|
513
|
+
* id for the inner control. When set, an inner `<Input>` doesn't need
|
|
514
|
+
* an explicit `name=` either if it inherits from this Field.
|
|
515
|
+
*/
|
|
516
|
+
name?: string;
|
|
517
|
+
/** Adds a red asterisk after the label. Cosmetic; pair with `required` on the actual input. */
|
|
518
|
+
required?: boolean;
|
|
519
|
+
/** Explicit id for the control. Otherwise: `name`, then slugified `label`, then undefined. */
|
|
520
|
+
id?: string;
|
|
521
|
+
/** Optional class merged into the field wrapper. */
|
|
522
|
+
class?: string;
|
|
523
|
+
/** Snippet that renders the actual control. Children should call `<Input />`, `<Textarea />`, etc. */
|
|
524
|
+
children?: Snippet;
|
|
525
|
+
};
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### FieldGroup
|
|
529
|
+
|
|
530
|
+
`@human-synthesis/norns-ui/components/FieldGroup.n`
|
|
531
|
+
|
|
532
|
+
```ts
|
|
533
|
+
export type FieldGroupProps = {
|
|
534
|
+
/** Optional legend text rendered as the fieldset's `<legend>`. */
|
|
535
|
+
legend?: string;
|
|
536
|
+
class?: string;
|
|
537
|
+
children?: Snippet;
|
|
538
|
+
};
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Form
|
|
542
|
+
|
|
543
|
+
`@human-synthesis/norns-ui/components/Form.n`
|
|
544
|
+
|
|
545
|
+
```ts
|
|
546
|
+
/**
|
|
547
|
+
* The shape returned by `fail(400, { errors, values })` from a SvelteKit
|
|
548
|
+
* action — what `+page.server.c`'s `page.actions` produces on validation
|
|
549
|
+
* failure (or a manually-constructed equivalent). `errors` is a valibot
|
|
550
|
+
* issue list; `values` is the raw form data echoed back for re-rendering.
|
|
551
|
+
*/
|
|
552
|
+
export type FormActionResult = {
|
|
553
|
+
errors?: Array<{ path?: Array<{ key?: string }>; message: string }>;
|
|
554
|
+
values?: Record<string, string>;
|
|
555
|
+
} | null | undefined;
|
|
556
|
+
|
|
557
|
+
export type FormProps = Omit<HTMLFormAttributes, 'class' | 'children'> & {
|
|
558
|
+
method?: 'GET' | 'POST';
|
|
559
|
+
action?: string;
|
|
560
|
+
enctype?: 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain';
|
|
561
|
+
/**
|
|
562
|
+
* Pass the page's `form` prop here. Form derives a `name → message` errors
|
|
563
|
+
* map and exposes it via context so descendant `<Field name="...">` looks
|
|
564
|
+
* up its own error automatically.
|
|
565
|
+
*/
|
|
566
|
+
form?: FormActionResult;
|
|
567
|
+
class?: string;
|
|
568
|
+
children?: Snippet;
|
|
569
|
+
};
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### GradientText
|
|
573
|
+
|
|
574
|
+
`@human-synthesis/norns-ui/components/GradientText.n`
|
|
575
|
+
|
|
576
|
+
```ts
|
|
577
|
+
export type GradientTextProps = {
|
|
578
|
+
/** Start color. Default `var(--color-primary-500)`. Accepts any CSS color. */
|
|
579
|
+
from?: string;
|
|
580
|
+
/** End color. Default `var(--color-info-500)`. */
|
|
581
|
+
to?: string;
|
|
582
|
+
/** Optional middle stop. */
|
|
583
|
+
via?: string;
|
|
584
|
+
/** Animate the gradient via background-position keyframes. Default true. */
|
|
585
|
+
animate?: boolean;
|
|
586
|
+
/** Gradient angle in degrees. Default 90. */
|
|
587
|
+
angle?: number;
|
|
588
|
+
children?: Snippet;
|
|
589
|
+
class?: string;
|
|
590
|
+
};
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Header
|
|
594
|
+
|
|
595
|
+
`@human-synthesis/norns-ui/components/Header.n`
|
|
596
|
+
|
|
597
|
+
```ts
|
|
598
|
+
export type HeaderProps = {
|
|
599
|
+
sticky?: boolean;
|
|
600
|
+
brand?: Snippet;
|
|
601
|
+
nav?: Snippet;
|
|
602
|
+
actions?: Snippet;
|
|
603
|
+
class?: string;
|
|
604
|
+
};
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### HeroBanner
|
|
608
|
+
|
|
609
|
+
`@human-synthesis/norns-ui/components/HeroBanner.n`
|
|
610
|
+
|
|
611
|
+
```ts
|
|
612
|
+
export type HeroBannerProps = {
|
|
613
|
+
title: string;
|
|
614
|
+
description?: string;
|
|
615
|
+
/** Background/decorative image src; rendered with reduced opacity behind the content. */
|
|
616
|
+
image?: string;
|
|
617
|
+
align?: 'left' | 'center';
|
|
618
|
+
/** Apply animated `GradientText` to the title. Default false. */
|
|
619
|
+
gradient?: boolean;
|
|
620
|
+
actions?: Snippet;
|
|
621
|
+
children?: Snippet;
|
|
622
|
+
class?: string;
|
|
623
|
+
};
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### HierarchicalMenu
|
|
627
|
+
|
|
628
|
+
`@human-synthesis/norns-ui/components/HierarchicalMenu.n`
|
|
629
|
+
|
|
630
|
+
```ts
|
|
631
|
+
export type HierarchicalMenuItem = {
|
|
632
|
+
label: string;
|
|
633
|
+
href?: string;
|
|
634
|
+
icon?: string;
|
|
635
|
+
description?: string;
|
|
636
|
+
children?: HierarchicalMenuItem[];
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
export type HierarchicalMenuProps = {
|
|
640
|
+
items?: HierarchicalMenuItem[];
|
|
641
|
+
/** aria-label for the <nav> wrapper. */
|
|
642
|
+
label?: string;
|
|
643
|
+
onSelect?: (item: HierarchicalMenuItem) => void;
|
|
644
|
+
class?: string;
|
|
645
|
+
};
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### Icon
|
|
649
|
+
|
|
650
|
+
`@human-synthesis/norns-ui/components/Icon.n`
|
|
651
|
+
|
|
652
|
+
```ts
|
|
653
|
+
export type IconProps = {
|
|
654
|
+
/**
|
|
655
|
+
* Iconify icon name in `<set>:<name>` form, e.g. `"lucide:check"` or
|
|
656
|
+
* `"mdi:home"`. The `@iconify-json/lucide` package ships with the library;
|
|
657
|
+
* other sets can be installed alongside (`@iconify-json/heroicons`, etc.).
|
|
658
|
+
*/
|
|
659
|
+
name: string;
|
|
660
|
+
/**
|
|
661
|
+
* Tailwind size utility for the icon, e.g. `"size-4"`, `"size-5"`. Default
|
|
662
|
+
* `"size-4"`. Pass any class string accepted by Tailwind.
|
|
663
|
+
*/
|
|
664
|
+
size?: string;
|
|
665
|
+
flip?: 'horizontal' | 'vertical' | 'horizontal,vertical';
|
|
666
|
+
rotate?: 90 | 180 | 270 | string;
|
|
667
|
+
class?: string;
|
|
668
|
+
};
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### Image
|
|
672
|
+
|
|
673
|
+
`@human-synthesis/norns-ui/components/Image.n`
|
|
674
|
+
|
|
675
|
+
```ts
|
|
676
|
+
export type ImageProps = {
|
|
677
|
+
src: string;
|
|
678
|
+
alt?: string;
|
|
679
|
+
loading?: 'lazy' | 'eager';
|
|
680
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
681
|
+
rounded?: boolean | 'sm' | 'md' | 'lg' | 'full';
|
|
682
|
+
width?: number | string;
|
|
683
|
+
height?: number | string;
|
|
684
|
+
class?: string;
|
|
685
|
+
};
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
### Input
|
|
689
|
+
|
|
690
|
+
`@human-synthesis/norns-ui/components/Input.n`
|
|
691
|
+
|
|
692
|
+
```ts
|
|
693
|
+
export type InputSize = 'sm' | 'md' | 'lg';
|
|
694
|
+
export type InputType =
|
|
695
|
+
| 'text'
|
|
696
|
+
| 'email'
|
|
697
|
+
| 'password'
|
|
698
|
+
| 'number'
|
|
699
|
+
| 'tel'
|
|
700
|
+
| 'url'
|
|
701
|
+
| 'search'
|
|
702
|
+
| 'date'
|
|
703
|
+
| 'time'
|
|
704
|
+
| 'datetime-local'
|
|
705
|
+
| 'month'
|
|
706
|
+
| 'week';
|
|
707
|
+
|
|
708
|
+
export type InputProps = Omit<HTMLInputAttributes, 'class' | 'type' | 'size' | 'value'> & {
|
|
709
|
+
value?: string | number;
|
|
710
|
+
type?: InputType;
|
|
711
|
+
size?: InputSize;
|
|
712
|
+
/** Force the error styling regardless of the parent Field's error state. */
|
|
713
|
+
error?: boolean;
|
|
714
|
+
class?: string;
|
|
715
|
+
};
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### MegaMenu
|
|
719
|
+
|
|
720
|
+
`@human-synthesis/norns-ui/components/MegaMenu.n`
|
|
721
|
+
|
|
722
|
+
```ts
|
|
723
|
+
export type MegaMenuItem = {
|
|
724
|
+
label: string;
|
|
725
|
+
href?: string;
|
|
726
|
+
icon?: string;
|
|
727
|
+
description?: string;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
export type MegaMenuColumn = {
|
|
731
|
+
title?: string;
|
|
732
|
+
items: MegaMenuItem[];
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
export type MegaMenuSection = {
|
|
736
|
+
label: string;
|
|
737
|
+
cols?: 2 | 3 | 4;
|
|
738
|
+
columns: MegaMenuColumn[];
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
export type MegaMenuProps = {
|
|
742
|
+
sections?: MegaMenuSection[];
|
|
743
|
+
/** aria-label for the <nav> wrapper. */
|
|
744
|
+
label?: string;
|
|
745
|
+
class?: string;
|
|
746
|
+
};
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### MultiSelect
|
|
750
|
+
|
|
751
|
+
`@human-synthesis/norns-ui/components/MultiSelect.n`
|
|
752
|
+
|
|
753
|
+
```ts
|
|
754
|
+
export type MultiSelectProps = {
|
|
755
|
+
items?: ComboboxItem[];
|
|
756
|
+
value?: string[];
|
|
757
|
+
open?: boolean;
|
|
758
|
+
placeholder?: string;
|
|
759
|
+
disabled?: boolean;
|
|
760
|
+
name?: string;
|
|
761
|
+
id?: string;
|
|
762
|
+
error?: boolean;
|
|
763
|
+
};
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### NumberInput
|
|
767
|
+
|
|
768
|
+
`@human-synthesis/norns-ui/components/NumberInput.n`
|
|
769
|
+
|
|
770
|
+
```ts
|
|
771
|
+
export type NumberInputProps = {
|
|
772
|
+
value?: number;
|
|
773
|
+
min?: number;
|
|
774
|
+
max?: number;
|
|
775
|
+
stepSize?: number;
|
|
776
|
+
disabled?: boolean;
|
|
777
|
+
readonly?: boolean;
|
|
778
|
+
name?: string;
|
|
779
|
+
id?: string;
|
|
780
|
+
error?: boolean;
|
|
781
|
+
class?: string;
|
|
782
|
+
};
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
### OtpField
|
|
786
|
+
|
|
787
|
+
`@human-synthesis/norns-ui/components/OtpField.n`
|
|
788
|
+
|
|
789
|
+
```ts
|
|
790
|
+
export type OtpFieldProps = {
|
|
791
|
+
value?: string;
|
|
792
|
+
length?: number;
|
|
793
|
+
mask?: boolean;
|
|
794
|
+
label?: string;
|
|
795
|
+
oncomplete?: (value: string) => void;
|
|
796
|
+
class?: string;
|
|
797
|
+
};
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
### Pagination
|
|
801
|
+
|
|
802
|
+
`@human-synthesis/norns-ui/components/Pagination.n`
|
|
803
|
+
|
|
804
|
+
```ts
|
|
805
|
+
export type PaginationProps = {
|
|
806
|
+
page?: number;
|
|
807
|
+
total?: number;
|
|
808
|
+
pageSize?: number;
|
|
809
|
+
/** How many pages to show on each side of the current. Default 1. */
|
|
810
|
+
siblingCount?: number;
|
|
811
|
+
class?: string;
|
|
812
|
+
};
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
### Popover
|
|
816
|
+
|
|
817
|
+
`@human-synthesis/norns-ui/components/Popover.n`
|
|
818
|
+
|
|
819
|
+
```ts
|
|
820
|
+
export type PopoverSide = 'top' | 'right' | 'bottom' | 'left';
|
|
821
|
+
export type PopoverAlign = 'start' | 'center' | 'end';
|
|
822
|
+
|
|
823
|
+
export type PopoverProps = {
|
|
824
|
+
open?: boolean;
|
|
825
|
+
side?: PopoverSide;
|
|
826
|
+
align?: PopoverAlign;
|
|
827
|
+
sideOffset?: number;
|
|
828
|
+
trigger?: Snippet;
|
|
829
|
+
children?: Snippet;
|
|
830
|
+
triggerClass?: string;
|
|
831
|
+
class?: string;
|
|
832
|
+
};
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
### Progress
|
|
836
|
+
|
|
837
|
+
`@human-synthesis/norns-ui/components/Progress.n`
|
|
838
|
+
|
|
839
|
+
```ts
|
|
840
|
+
export type ProgressVariant = 'primary' | 'success' | 'warning' | 'danger';
|
|
841
|
+
|
|
842
|
+
export type ProgressProps = {
|
|
843
|
+
value?: number;
|
|
844
|
+
max?: number;
|
|
845
|
+
variant?: ProgressVariant;
|
|
846
|
+
indeterminate?: boolean;
|
|
847
|
+
class?: string;
|
|
848
|
+
};
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
### ProgressCircular
|
|
852
|
+
|
|
853
|
+
`@human-synthesis/norns-ui/components/ProgressCircular.n`
|
|
854
|
+
|
|
855
|
+
```ts
|
|
856
|
+
export type ProgressCircularSize = 'sm' | 'md' | 'lg';
|
|
857
|
+
|
|
858
|
+
export type ProgressCircularProps = {
|
|
859
|
+
value?: number;
|
|
860
|
+
max?: number;
|
|
861
|
+
size?: ProgressCircularSize;
|
|
862
|
+
indeterminate?: boolean;
|
|
863
|
+
class?: string;
|
|
864
|
+
};
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
### Radio
|
|
868
|
+
|
|
869
|
+
`@human-synthesis/norns-ui/components/Radio.n`
|
|
870
|
+
|
|
871
|
+
```ts
|
|
872
|
+
export type RadioProps = Omit<HTMLInputAttributes, 'class' | 'type'> & {
|
|
873
|
+
/** Two-way bound shared group value — pass `bind:group={selected}` from parent. */
|
|
874
|
+
group?: string;
|
|
875
|
+
value?: string;
|
|
876
|
+
error?: boolean;
|
|
877
|
+
class?: string;
|
|
878
|
+
};
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### RippleButton
|
|
882
|
+
|
|
883
|
+
`@human-synthesis/norns-ui/components/RippleButton.n`
|
|
884
|
+
|
|
885
|
+
```ts
|
|
886
|
+
export type RippleButtonProps = {
|
|
887
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
888
|
+
size?: 'sm' | 'md' | 'lg';
|
|
889
|
+
type?: 'button' | 'submit' | 'reset';
|
|
890
|
+
disabled?: boolean;
|
|
891
|
+
onclick?: (event: MouseEvent) => void;
|
|
892
|
+
icon?: string;
|
|
893
|
+
children?: Snippet;
|
|
894
|
+
class?: string;
|
|
895
|
+
};
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### ScrollArea
|
|
899
|
+
|
|
900
|
+
`@human-synthesis/norns-ui/components/ScrollArea.n`
|
|
901
|
+
|
|
902
|
+
```ts
|
|
903
|
+
export type ScrollAreaProps = {
|
|
904
|
+
/** Allow horizontal scrolling instead of just vertical. */
|
|
905
|
+
horizontal?: boolean;
|
|
906
|
+
children?: Snippet;
|
|
907
|
+
class?: string;
|
|
908
|
+
};
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### Select
|
|
912
|
+
|
|
913
|
+
`@human-synthesis/norns-ui/components/Select.n`
|
|
914
|
+
|
|
915
|
+
```ts
|
|
916
|
+
export type SelectProps = Omit<HTMLSelectAttributes, 'class' | 'value' | 'children'> & {
|
|
917
|
+
value?: string | number | string[];
|
|
918
|
+
error?: boolean;
|
|
919
|
+
class?: string;
|
|
920
|
+
/** `<option>` children. Pass via Pug body. */
|
|
921
|
+
children?: Snippet;
|
|
922
|
+
};
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
### Separator
|
|
926
|
+
|
|
927
|
+
`@human-synthesis/norns-ui/components/Separator.n`
|
|
928
|
+
|
|
929
|
+
```ts
|
|
930
|
+
export type SeparatorProps = {
|
|
931
|
+
orientation?: 'horizontal' | 'vertical';
|
|
932
|
+
class?: string;
|
|
933
|
+
};
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
### Sheet
|
|
937
|
+
|
|
938
|
+
`@human-synthesis/norns-ui/components/Sheet.n`
|
|
939
|
+
|
|
940
|
+
```ts
|
|
941
|
+
export type SheetSide = 'top' | 'right' | 'bottom' | 'left';
|
|
942
|
+
|
|
943
|
+
export type SheetProps = {
|
|
944
|
+
open?: boolean;
|
|
945
|
+
/** `'left'` was previously the default for the now-removed `<Drawer>`. */
|
|
946
|
+
side?: SheetSide;
|
|
947
|
+
title?: string;
|
|
948
|
+
description?: string;
|
|
949
|
+
hideClose?: boolean;
|
|
950
|
+
dismissable?: boolean;
|
|
951
|
+
ariaLabel?: string;
|
|
952
|
+
trigger?: Snippet;
|
|
953
|
+
actions?: Snippet;
|
|
954
|
+
children?: Snippet;
|
|
955
|
+
triggerClass?: string;
|
|
956
|
+
overlayClass?: string;
|
|
957
|
+
class?: string;
|
|
958
|
+
};
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
### ShinyButton
|
|
962
|
+
|
|
963
|
+
`@human-synthesis/norns-ui/components/ShinyButton.n`
|
|
964
|
+
|
|
965
|
+
```ts
|
|
966
|
+
export type ShinyButtonProps = {
|
|
967
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
968
|
+
size?: 'sm' | 'md' | 'lg';
|
|
969
|
+
type?: 'button' | 'submit' | 'reset';
|
|
970
|
+
disabled?: boolean;
|
|
971
|
+
onclick?: (event: MouseEvent) => void;
|
|
972
|
+
icon?: string;
|
|
973
|
+
children?: Snippet;
|
|
974
|
+
class?: string;
|
|
975
|
+
};
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
### Skeleton
|
|
979
|
+
|
|
980
|
+
`@human-synthesis/norns-ui/components/Skeleton.n`
|
|
981
|
+
|
|
982
|
+
```ts
|
|
983
|
+
export type SkeletonVariant = 'rect' | 'text' | 'circle';
|
|
984
|
+
|
|
985
|
+
export type SkeletonProps = {
|
|
986
|
+
variant?: SkeletonVariant;
|
|
987
|
+
width?: number | string;
|
|
988
|
+
height?: number | string;
|
|
989
|
+
class?: string;
|
|
990
|
+
};
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
### Stepper
|
|
994
|
+
|
|
995
|
+
`@human-synthesis/norns-ui/components/Stepper.n`
|
|
996
|
+
|
|
997
|
+
```ts
|
|
998
|
+
export type StepperStep = {
|
|
999
|
+
id?: string;
|
|
1000
|
+
label: string;
|
|
1001
|
+
complete?: boolean;
|
|
1002
|
+
current?: boolean;
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
export type StepperProps = {
|
|
1006
|
+
steps?: StepperStep[];
|
|
1007
|
+
/** Index of the active step. Steps before are auto-marked complete unless overridden. */
|
|
1008
|
+
current?: number;
|
|
1009
|
+
orientation?: 'horizontal' | 'vertical';
|
|
1010
|
+
class?: string;
|
|
1011
|
+
};
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
### Surface
|
|
1015
|
+
|
|
1016
|
+
`@human-synthesis/norns-ui/components/Surface.n`
|
|
1017
|
+
|
|
1018
|
+
```ts
|
|
1019
|
+
export type SurfaceProps = {
|
|
1020
|
+
tone?: 'glass';
|
|
1021
|
+
children?: Snippet;
|
|
1022
|
+
class?: string;
|
|
1023
|
+
};
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
### Switch
|
|
1027
|
+
|
|
1028
|
+
`@human-synthesis/norns-ui/components/Switch.n`
|
|
1029
|
+
|
|
1030
|
+
```ts
|
|
1031
|
+
export type SwitchProps = Omit<HTMLInputAttributes, 'class' | 'type' | 'checked' | 'role'> & {
|
|
1032
|
+
checked?: boolean;
|
|
1033
|
+
error?: boolean;
|
|
1034
|
+
class?: string;
|
|
1035
|
+
};
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
### Tabs
|
|
1039
|
+
|
|
1040
|
+
`@human-synthesis/norns-ui/components/Tabs.n`
|
|
1041
|
+
|
|
1042
|
+
```ts
|
|
1043
|
+
export type TabsItem = {
|
|
1044
|
+
value: string;
|
|
1045
|
+
label: string;
|
|
1046
|
+
panel?: Snippet;
|
|
1047
|
+
disabled?: boolean;
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
export type TabsProps = {
|
|
1051
|
+
value?: string;
|
|
1052
|
+
items?: TabsItem[];
|
|
1053
|
+
/** ARIA label for the tablist. Default 'Tabs'. */
|
|
1054
|
+
label?: string;
|
|
1055
|
+
class?: string;
|
|
1056
|
+
};
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
### TagsInput
|
|
1060
|
+
|
|
1061
|
+
`@human-synthesis/norns-ui/components/TagsInput.n`
|
|
1062
|
+
|
|
1063
|
+
```ts
|
|
1064
|
+
export type TagsInputProps = {
|
|
1065
|
+
value?: string[];
|
|
1066
|
+
max?: number;
|
|
1067
|
+
placeholder?: string;
|
|
1068
|
+
commitOnBlur?: boolean;
|
|
1069
|
+
separators?: string[];
|
|
1070
|
+
disabled?: boolean;
|
|
1071
|
+
name?: string;
|
|
1072
|
+
id?: string;
|
|
1073
|
+
error?: boolean;
|
|
1074
|
+
class?: string;
|
|
1075
|
+
};
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
### Textarea
|
|
1079
|
+
|
|
1080
|
+
`@human-synthesis/norns-ui/components/Textarea.n`
|
|
1081
|
+
|
|
1082
|
+
```ts
|
|
1083
|
+
export type TextareaProps = Omit<HTMLTextareaAttributes, 'class' | 'value' | 'rows'> & {
|
|
1084
|
+
value?: string;
|
|
1085
|
+
rows?: number;
|
|
1086
|
+
error?: boolean;
|
|
1087
|
+
class?: string;
|
|
1088
|
+
};
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
### ThemeToggler
|
|
1092
|
+
|
|
1093
|
+
`@human-synthesis/norns-ui/components/ThemeToggler.n`
|
|
1094
|
+
|
|
1095
|
+
```ts
|
|
1096
|
+
export type ThemeTogglerProps = {
|
|
1097
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
1098
|
+
size?: 'sm' | 'md' | 'lg';
|
|
1099
|
+
showLabel?: boolean;
|
|
1100
|
+
labelLight?: string;
|
|
1101
|
+
labelDark?: string;
|
|
1102
|
+
lightIcon?: string;
|
|
1103
|
+
darkIcon?: string;
|
|
1104
|
+
/** localStorage key. Default `'norns-theme'`. */
|
|
1105
|
+
storageKey?: string;
|
|
1106
|
+
class?: string;
|
|
1107
|
+
};
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
### Timeline
|
|
1111
|
+
|
|
1112
|
+
`@human-synthesis/norns-ui/components/Timeline.n`
|
|
1113
|
+
|
|
1114
|
+
```ts
|
|
1115
|
+
export type TimelineItem = {
|
|
1116
|
+
time?: string;
|
|
1117
|
+
title?: string;
|
|
1118
|
+
description?: string;
|
|
1119
|
+
icon?: string;
|
|
1120
|
+
variant?: 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
export type TimelineProps = {
|
|
1124
|
+
items?: TimelineItem[];
|
|
1125
|
+
class?: string;
|
|
1126
|
+
};
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
### TimePicker
|
|
1130
|
+
|
|
1131
|
+
`@human-synthesis/norns-ui/components/TimePicker.n`
|
|
1132
|
+
|
|
1133
|
+
```ts
|
|
1134
|
+
export type TimePickerProps = {
|
|
1135
|
+
/** Time string `HH:MM` (24h regardless of display `hourCycle`). Bindable. */
|
|
1136
|
+
value?: string;
|
|
1137
|
+
open?: boolean;
|
|
1138
|
+
/** Minute increment in the picker (5, 10, 15, 30). Default 5. */
|
|
1139
|
+
minuteStep?: number;
|
|
1140
|
+
hourCycle?: 12 | 24;
|
|
1141
|
+
placeholder?: string;
|
|
1142
|
+
disabled?: boolean;
|
|
1143
|
+
label?: string;
|
|
1144
|
+
name?: string;
|
|
1145
|
+
id?: string;
|
|
1146
|
+
error?: boolean;
|
|
1147
|
+
class?: string;
|
|
1148
|
+
};
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
### ToastProvider
|
|
1152
|
+
|
|
1153
|
+
`@human-synthesis/norns-ui/components/ToastProvider.n`
|
|
1154
|
+
|
|
1155
|
+
```ts
|
|
1156
|
+
export type ToastVariant = 'info' | 'success' | 'warning' | 'error';
|
|
1157
|
+
|
|
1158
|
+
export type ToastProviderProps = {
|
|
1159
|
+
class?: string;
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
export type ToastOpts = {
|
|
1163
|
+
variant?: ToastVariant;
|
|
1164
|
+
duration?: number;
|
|
1165
|
+
};
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
### ToggleButton
|
|
1169
|
+
|
|
1170
|
+
`@human-synthesis/norns-ui/components/ToggleButton.n`
|
|
1171
|
+
|
|
1172
|
+
```ts
|
|
1173
|
+
export type ToggleButtonProps = {
|
|
1174
|
+
pressed?: boolean;
|
|
1175
|
+
disabled?: boolean;
|
|
1176
|
+
icon?: string;
|
|
1177
|
+
/** Any `.btn-*` variant. The toggle visual state is controlled by `data-pressed`. */
|
|
1178
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
1179
|
+
size?: 'sm' | 'md' | 'lg';
|
|
1180
|
+
onpressedchange?: (pressed: boolean) => void;
|
|
1181
|
+
children?: Snippet;
|
|
1182
|
+
class?: string;
|
|
1183
|
+
};
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
### ToggleButtonGroup
|
|
1187
|
+
|
|
1188
|
+
`@human-synthesis/norns-ui/components/ToggleButtonGroup.n`
|
|
1189
|
+
|
|
1190
|
+
```ts
|
|
1191
|
+
export type ToggleGroupItem = {
|
|
1192
|
+
value: string;
|
|
1193
|
+
label?: string;
|
|
1194
|
+
icon?: string;
|
|
1195
|
+
iconOnly?: boolean;
|
|
1196
|
+
disabled?: boolean;
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
export type ToggleButtonGroupProps = {
|
|
1200
|
+
items?: ToggleGroupItem[];
|
|
1201
|
+
value?: string | string[] | undefined;
|
|
1202
|
+
multiple?: boolean;
|
|
1203
|
+
disabled?: boolean;
|
|
1204
|
+
label?: string;
|
|
1205
|
+
class?: string;
|
|
1206
|
+
};
|
|
1207
|
+
```
|
|
1208
|
+
|
|
1209
|
+
### Toolbar
|
|
1210
|
+
|
|
1211
|
+
`@human-synthesis/norns-ui/components/Toolbar.n`
|
|
1212
|
+
|
|
1213
|
+
```ts
|
|
1214
|
+
export type ToolbarProps = {
|
|
1215
|
+
orientation?: 'horizontal' | 'vertical';
|
|
1216
|
+
/** Accessible label, used as aria-label. */
|
|
1217
|
+
label?: string;
|
|
1218
|
+
children?: Snippet;
|
|
1219
|
+
class?: string;
|
|
1220
|
+
};
|
|
1221
|
+
```
|
|
1222
|
+
|
|
1223
|
+
### Tooltip
|
|
1224
|
+
|
|
1225
|
+
`@human-synthesis/norns-ui/components/Tooltip.n`
|
|
1226
|
+
|
|
1227
|
+
```ts
|
|
1228
|
+
export type TooltipProps = {
|
|
1229
|
+
content?: string;
|
|
1230
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
1231
|
+
align?: 'start' | 'center' | 'end';
|
|
1232
|
+
sideOffset?: number;
|
|
1233
|
+
delay?: number;
|
|
1234
|
+
/** Wider, surface-elevated styling for tooltips with markup/multiline content. */
|
|
1235
|
+
rich?: boolean;
|
|
1236
|
+
trigger?: Snippet;
|
|
1237
|
+
children?: Snippet;
|
|
1238
|
+
triggerClass?: string;
|
|
1239
|
+
class?: string;
|
|
1240
|
+
};
|
|
1241
|
+
```
|
|
1242
|
+
|
|
1243
|
+
### Tree
|
|
1244
|
+
|
|
1245
|
+
`@human-synthesis/norns-ui/components/Tree.n`
|
|
1246
|
+
|
|
1247
|
+
```ts
|
|
1248
|
+
export type TreeNode = {
|
|
1249
|
+
id: string | number;
|
|
1250
|
+
label: string;
|
|
1251
|
+
icon?: string;
|
|
1252
|
+
children?: TreeNode[];
|
|
1253
|
+
};
|
|
1254
|
+
|
|
1255
|
+
export type TreeProps = {
|
|
1256
|
+
items?: TreeNode[];
|
|
1257
|
+
/** Array of node ids that are expanded. Bindable. */
|
|
1258
|
+
expanded?: (string | number)[];
|
|
1259
|
+
/** Currently-selected node id. Bindable. */
|
|
1260
|
+
selected?: string | number;
|
|
1261
|
+
class?: string;
|
|
1262
|
+
};
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
### Uploader
|
|
1266
|
+
|
|
1267
|
+
`@human-synthesis/norns-ui/components/Uploader.n`
|
|
1268
|
+
|
|
1269
|
+
```ts
|
|
1270
|
+
export type UploaderProps = {
|
|
1271
|
+
files?: File[];
|
|
1272
|
+
multiple?: boolean;
|
|
1273
|
+
accept?: string;
|
|
1274
|
+
disabled?: boolean;
|
|
1275
|
+
placeholder?: string;
|
|
1276
|
+
helper?: string;
|
|
1277
|
+
onchange?: (files: File[]) => void;
|
|
1278
|
+
class?: string;
|
|
1279
|
+
};
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### Video
|
|
1283
|
+
|
|
1284
|
+
`@human-synthesis/norns-ui/components/Video.n`
|
|
1285
|
+
|
|
1286
|
+
```ts
|
|
1287
|
+
export type VideoSource = { src: string; type?: string };
|
|
1288
|
+
|
|
1289
|
+
export type VideoProps = {
|
|
1290
|
+
src?: string;
|
|
1291
|
+
sources?: VideoSource[];
|
|
1292
|
+
controls?: boolean;
|
|
1293
|
+
autoplay?: boolean;
|
|
1294
|
+
loop?: boolean;
|
|
1295
|
+
muted?: boolean;
|
|
1296
|
+
playsinline?: boolean;
|
|
1297
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
1298
|
+
poster?: string;
|
|
1299
|
+
fallback?: string;
|
|
1300
|
+
class?: string;
|
|
1301
|
+
};
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
### Window
|
|
1305
|
+
|
|
1306
|
+
`@human-synthesis/norns-ui/components/Window.n`
|
|
1307
|
+
|
|
1308
|
+
```ts
|
|
1309
|
+
export type WindowProps = {
|
|
1310
|
+
/** Header title (truncated). */
|
|
1311
|
+
title?: string;
|
|
1312
|
+
/** Remove the whole header bar; keeps the rounded shell. */
|
|
1313
|
+
hideHeader?: boolean;
|
|
1314
|
+
/** When set, renders a `lucide:x` close button (marked `.nodrag`). */
|
|
1315
|
+
onClose?: () => void;
|
|
1316
|
+
/** Fires on double-click over the header bar (e.g. maximise). */
|
|
1317
|
+
onHeaderDoubleClick?: (event: MouseEvent) => void;
|
|
1318
|
+
/** Extra header controls, rendered before the close button. */
|
|
1319
|
+
actions?: Snippet;
|
|
1320
|
+
children?: Snippet;
|
|
1321
|
+
/** Classes for the outer shell — pass dimensions here (`w-[520px] h-[380px]`). */
|
|
1322
|
+
class?: string;
|
|
1323
|
+
/** Classes for the body section. */
|
|
1324
|
+
bodyClass?: string;
|
|
1325
|
+
};
|
|
1326
|
+
```
|
|
1327
|
+
|
|
1328
|
+
## Motion (opt-in)
|
|
1329
|
+
|
|
1330
|
+
[AnimatedNumber](#animatednumber) · [GradientBackground](#gradientbackground) · [LiquidButton](#liquidbutton) · [Reveal](#reveal) · [Sparkles](#sparkles)
|
|
1331
|
+
|
|
1332
|
+
### AnimatedNumber
|
|
1333
|
+
|
|
1334
|
+
`import { AnimatedNumber } from '@human-synthesis/norns-ui/motion'`
|
|
1335
|
+
|
|
1336
|
+
```ts
|
|
1337
|
+
export type AnimatedNumberProps = {
|
|
1338
|
+
value: number;
|
|
1339
|
+
from?: number;
|
|
1340
|
+
/** Duration in seconds. */
|
|
1341
|
+
duration?: number;
|
|
1342
|
+
decimals?: number;
|
|
1343
|
+
/** Custom number-to-string formatter. */
|
|
1344
|
+
format?: (n: number) => string;
|
|
1345
|
+
class?: string;
|
|
1346
|
+
};
|
|
1347
|
+
```
|
|
1348
|
+
|
|
1349
|
+
### GradientBackground
|
|
1350
|
+
|
|
1351
|
+
`import { GradientBackground } from '@human-synthesis/norns-ui/motion'`
|
|
1352
|
+
|
|
1353
|
+
```ts
|
|
1354
|
+
export type GradientBackgroundProps = {
|
|
1355
|
+
colors?: string[];
|
|
1356
|
+
/** Loop duration in seconds. Default 18. */
|
|
1357
|
+
duration?: number;
|
|
1358
|
+
/** Gradient angle. Default 130. */
|
|
1359
|
+
angle?: number;
|
|
1360
|
+
children?: Snippet;
|
|
1361
|
+
class?: string;
|
|
1362
|
+
};
|
|
1363
|
+
```
|
|
1364
|
+
|
|
1365
|
+
### LiquidButton
|
|
1366
|
+
|
|
1367
|
+
`import { LiquidButton } from '@human-synthesis/norns-ui/motion'`
|
|
1368
|
+
|
|
1369
|
+
```ts
|
|
1370
|
+
export type LiquidButtonProps = {
|
|
1371
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
1372
|
+
size?: 'sm' | 'md' | 'lg';
|
|
1373
|
+
type?: 'button' | 'submit' | 'reset';
|
|
1374
|
+
disabled?: boolean;
|
|
1375
|
+
onclick?: (event: MouseEvent) => void;
|
|
1376
|
+
icon?: string;
|
|
1377
|
+
children?: Snippet;
|
|
1378
|
+
class?: string;
|
|
1379
|
+
};
|
|
1380
|
+
```
|
|
1381
|
+
|
|
1382
|
+
### Reveal
|
|
1383
|
+
|
|
1384
|
+
`import { Reveal } from '@human-synthesis/norns-ui/motion'`
|
|
1385
|
+
|
|
1386
|
+
```ts
|
|
1387
|
+
export type RevealProps = {
|
|
1388
|
+
direction?: 'up' | 'down' | 'left' | 'right';
|
|
1389
|
+
/** Travel distance in pixels. Default 12. */
|
|
1390
|
+
distance?: number;
|
|
1391
|
+
/** Animation duration in seconds. Default 0.5. */
|
|
1392
|
+
duration?: number;
|
|
1393
|
+
/** Delay before animating, seconds. Default 0. */
|
|
1394
|
+
delay?: number;
|
|
1395
|
+
/** Re-trigger on every entry (false) or just the first time (true). Default true. */
|
|
1396
|
+
once?: boolean;
|
|
1397
|
+
/** IntersectionObserver threshold (0–1). Default 0.15. */
|
|
1398
|
+
threshold?: number;
|
|
1399
|
+
children?: Snippet;
|
|
1400
|
+
class?: string;
|
|
1401
|
+
};
|
|
1402
|
+
```
|
|
1403
|
+
|
|
1404
|
+
### Sparkles
|
|
1405
|
+
|
|
1406
|
+
`import { Sparkles } from '@human-synthesis/norns-ui/motion'`
|
|
1407
|
+
|
|
1408
|
+
```ts
|
|
1409
|
+
export type SparklesProps = {
|
|
1410
|
+
density?: number;
|
|
1411
|
+
colors?: string[];
|
|
1412
|
+
minSize?: number;
|
|
1413
|
+
maxSize?: number;
|
|
1414
|
+
children?: Snippet;
|
|
1415
|
+
class?: string;
|
|
1416
|
+
};
|
|
1417
|
+
```
|