@human-synthesis/norns-ui 0.1.0 → 0.2.1

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.
@@ -0,0 +1,4188 @@
1
+ {
2
+ "library": "@human-synthesis/norns-ui",
3
+ "version": "0.2.0",
4
+ "counts": {
5
+ "components": 78,
6
+ "motion": 5,
7
+ "behaviors": 9,
8
+ "tokens": 99
9
+ },
10
+ "components": [
11
+ {
12
+ "name": "Accordion",
13
+ "category": "layout",
14
+ "import": "@human-synthesis/norns-ui/components/Accordion.n",
15
+ "bindability": [
16
+ "custom-only"
17
+ ],
18
+ "props": [
19
+ {
20
+ "name": "items",
21
+ "type": "AccordionItem[]",
22
+ "required": false
23
+ },
24
+ {
25
+ "name": "multiple",
26
+ "type": "boolean",
27
+ "required": false
28
+ },
29
+ {
30
+ "name": "value",
31
+ "type": "string | string[]",
32
+ "required": false
33
+ },
34
+ {
35
+ "name": "class",
36
+ "type": "string",
37
+ "required": false
38
+ }
39
+ ]
40
+ },
41
+ {
42
+ "name": "Audio",
43
+ "category": "media",
44
+ "import": "@human-synthesis/norns-ui/components/Audio.n",
45
+ "bindability": [
46
+ "custom-only"
47
+ ],
48
+ "props": [
49
+ {
50
+ "name": "src",
51
+ "type": "string",
52
+ "required": false
53
+ },
54
+ {
55
+ "name": "sources",
56
+ "type": "AudioSource[]",
57
+ "required": false
58
+ },
59
+ {
60
+ "name": "controls",
61
+ "type": "boolean",
62
+ "required": false
63
+ },
64
+ {
65
+ "name": "autoplay",
66
+ "type": "boolean",
67
+ "required": false
68
+ },
69
+ {
70
+ "name": "loop",
71
+ "type": "boolean",
72
+ "required": false
73
+ },
74
+ {
75
+ "name": "muted",
76
+ "type": "boolean",
77
+ "required": false
78
+ },
79
+ {
80
+ "name": "preload",
81
+ "type": "'none' | 'metadata' | 'auto'",
82
+ "required": false
83
+ },
84
+ {
85
+ "name": "fallback",
86
+ "type": "string",
87
+ "required": false
88
+ },
89
+ {
90
+ "name": "class",
91
+ "type": "string",
92
+ "required": false
93
+ }
94
+ ]
95
+ },
96
+ {
97
+ "name": "Autocomplete",
98
+ "category": "form",
99
+ "import": "@human-synthesis/norns-ui/components/Autocomplete.n",
100
+ "bindability": [
101
+ "custom-only"
102
+ ],
103
+ "props": [
104
+ {
105
+ "name": "items",
106
+ "type": "ComboboxItem[]",
107
+ "required": false
108
+ },
109
+ {
110
+ "name": "value",
111
+ "type": "string",
112
+ "required": false
113
+ },
114
+ {
115
+ "name": "open",
116
+ "type": "boolean",
117
+ "required": false
118
+ },
119
+ {
120
+ "name": "placeholder",
121
+ "type": "string",
122
+ "required": false
123
+ },
124
+ {
125
+ "name": "disabled",
126
+ "type": "boolean",
127
+ "required": false
128
+ },
129
+ {
130
+ "name": "name",
131
+ "type": "string",
132
+ "required": false
133
+ },
134
+ {
135
+ "name": "id",
136
+ "type": "string",
137
+ "required": false
138
+ },
139
+ {
140
+ "name": "error",
141
+ "type": "boolean",
142
+ "required": false
143
+ }
144
+ ]
145
+ },
146
+ {
147
+ "name": "Avatar",
148
+ "category": "media",
149
+ "import": "@human-synthesis/norns-ui/components/Avatar.n",
150
+ "bindability": [
151
+ "custom-only"
152
+ ],
153
+ "props": [
154
+ {
155
+ "name": "src",
156
+ "type": "string",
157
+ "required": false
158
+ },
159
+ {
160
+ "name": "name",
161
+ "type": "string",
162
+ "required": false,
163
+ "doc": "Display name; first + last initial used as fallback when `src` is missing."
164
+ },
165
+ {
166
+ "name": "size",
167
+ "type": "AvatarSize",
168
+ "required": false
169
+ },
170
+ {
171
+ "name": "class",
172
+ "type": "string",
173
+ "required": false
174
+ }
175
+ ]
176
+ },
177
+ {
178
+ "name": "AvatarGroup",
179
+ "category": "media",
180
+ "import": "@human-synthesis/norns-ui/components/AvatarGroup.n",
181
+ "bindability": [
182
+ "custom-only"
183
+ ],
184
+ "props": [
185
+ {
186
+ "name": "items",
187
+ "type": "AvatarGroupItem[]",
188
+ "required": false
189
+ },
190
+ {
191
+ "name": "max",
192
+ "type": "number",
193
+ "required": false
194
+ },
195
+ {
196
+ "name": "size",
197
+ "type": "AvatarSize",
198
+ "required": false
199
+ },
200
+ {
201
+ "name": "label",
202
+ "type": "string",
203
+ "required": false
204
+ },
205
+ {
206
+ "name": "class",
207
+ "type": "string",
208
+ "required": false
209
+ }
210
+ ]
211
+ },
212
+ {
213
+ "name": "Badge",
214
+ "category": "feedback",
215
+ "import": "@human-synthesis/norns-ui/components/Badge.n",
216
+ "bindability": [
217
+ "spec-bindable"
218
+ ],
219
+ "props": [
220
+ {
221
+ "name": "variant",
222
+ "type": "BadgeVariant",
223
+ "required": false
224
+ },
225
+ {
226
+ "name": "size",
227
+ "type": "BadgeSize",
228
+ "required": false
229
+ },
230
+ {
231
+ "name": "children",
232
+ "type": "Snippet",
233
+ "required": false
234
+ },
235
+ {
236
+ "name": "class",
237
+ "type": "string",
238
+ "required": false
239
+ }
240
+ ],
241
+ "bindings": {
242
+ "variant": "literal",
243
+ "size": "literal",
244
+ "class": "literal"
245
+ },
246
+ "example": {
247
+ "badge": null,
248
+ "variant": "success"
249
+ }
250
+ },
251
+ {
252
+ "name": "Banner",
253
+ "category": "feedback",
254
+ "import": "@human-synthesis/norns-ui/components/Banner.n",
255
+ "bindability": [
256
+ "spec-bindable"
257
+ ],
258
+ "props": [
259
+ {
260
+ "name": "variant",
261
+ "type": "BannerVariant",
262
+ "required": false
263
+ },
264
+ {
265
+ "name": "icon",
266
+ "type": "string",
267
+ "required": false,
268
+ "doc": "Iconify icon name (e.g. `\"lucide:alert-triangle\"`)."
269
+ },
270
+ {
271
+ "name": "actions",
272
+ "type": "Snippet",
273
+ "required": false
274
+ },
275
+ {
276
+ "name": "children",
277
+ "type": "Snippet",
278
+ "required": false
279
+ },
280
+ {
281
+ "name": "class",
282
+ "type": "string",
283
+ "required": false
284
+ }
285
+ ],
286
+ "bindings": {
287
+ "variant": "literal",
288
+ "icon": "literal",
289
+ "class": "literal"
290
+ },
291
+ "example": {
292
+ "banner": null,
293
+ "variant": "info"
294
+ }
295
+ },
296
+ {
297
+ "name": "Breadcrumbs",
298
+ "category": "navigation",
299
+ "import": "@human-synthesis/norns-ui/components/Breadcrumbs.n",
300
+ "bindability": [
301
+ "custom-only"
302
+ ],
303
+ "props": [
304
+ {
305
+ "name": "items",
306
+ "type": "BreadcrumbItem[]",
307
+ "required": false
308
+ },
309
+ {
310
+ "name": "separator",
311
+ "type": "string",
312
+ "required": false
313
+ },
314
+ {
315
+ "name": "class",
316
+ "type": "string",
317
+ "required": false
318
+ }
319
+ ]
320
+ },
321
+ {
322
+ "name": "Btn",
323
+ "category": "action",
324
+ "import": "@human-synthesis/norns-ui/components/Btn.n",
325
+ "bindability": [
326
+ "spec-bindable"
327
+ ],
328
+ "props": [
329
+ {
330
+ "name": "variant",
331
+ "type": "BtnVariant",
332
+ "required": false
333
+ },
334
+ {
335
+ "name": "size",
336
+ "type": "BtnSize",
337
+ "required": false
338
+ },
339
+ {
340
+ "name": "loading",
341
+ "type": "boolean",
342
+ "required": false
343
+ },
344
+ {
345
+ "name": "disabled",
346
+ "type": "boolean",
347
+ "required": false
348
+ },
349
+ {
350
+ "name": "type",
351
+ "type": "'button' | 'submit' | 'reset'",
352
+ "required": false
353
+ },
354
+ {
355
+ "name": "icon",
356
+ "type": "string",
357
+ "required": false
358
+ },
359
+ {
360
+ "name": "href",
361
+ "type": "string",
362
+ "required": false,
363
+ "doc": "When set, renders as an `<a>` styled like the button."
364
+ },
365
+ {
366
+ "name": "target",
367
+ "type": "string",
368
+ "required": false
369
+ },
370
+ {
371
+ "name": "rel",
372
+ "type": "string",
373
+ "required": false
374
+ },
375
+ {
376
+ "name": "class",
377
+ "type": "string",
378
+ "required": false
379
+ },
380
+ {
381
+ "name": "children",
382
+ "type": "Snippet",
383
+ "required": false
384
+ },
385
+ {
386
+ "name": "leading",
387
+ "type": "Snippet",
388
+ "required": false
389
+ },
390
+ {
391
+ "name": "trailing",
392
+ "type": "Snippet",
393
+ "required": false
394
+ }
395
+ ],
396
+ "bindings": {
397
+ "variant": "literal",
398
+ "size": "literal",
399
+ "type": "literal",
400
+ "icon": "literal",
401
+ "href": "literal",
402
+ "disabled": "literal",
403
+ "class": "literal"
404
+ },
405
+ "example": {
406
+ "btn": null,
407
+ "variant": "primary",
408
+ "type": "submit"
409
+ }
410
+ },
411
+ {
412
+ "name": "ButtonGroup",
413
+ "category": "action",
414
+ "import": "@human-synthesis/norns-ui/components/ButtonGroup.n",
415
+ "bindability": [
416
+ "custom-only"
417
+ ],
418
+ "props": [
419
+ {
420
+ "name": "orientation",
421
+ "type": "'horizontal' | 'vertical'",
422
+ "required": false
423
+ },
424
+ {
425
+ "name": "children",
426
+ "type": "Snippet",
427
+ "required": false
428
+ },
429
+ {
430
+ "name": "class",
431
+ "type": "string",
432
+ "required": false
433
+ }
434
+ ]
435
+ },
436
+ {
437
+ "name": "Calendar",
438
+ "category": "data",
439
+ "import": "@human-synthesis/norns-ui/components/Calendar.n",
440
+ "bindability": [
441
+ "spec-bindable"
442
+ ],
443
+ "props": [
444
+ {
445
+ "name": "value",
446
+ "type": "string",
447
+ "required": false,
448
+ "doc": "ISO YYYY-MM-DD. Bindable."
449
+ },
450
+ {
451
+ "name": "rangeValue",
452
+ "type": "CalendarDateRange",
453
+ "required": false,
454
+ "doc": "Range mode. Bindable. Use instead of `value` when `range` is true."
455
+ },
456
+ {
457
+ "name": "range",
458
+ "type": "boolean",
459
+ "required": false
460
+ },
461
+ {
462
+ "name": "min",
463
+ "type": "string",
464
+ "required": false,
465
+ "doc": "ISO YYYY-MM-DD inclusive."
466
+ },
467
+ {
468
+ "name": "max",
469
+ "type": "string",
470
+ "required": false
471
+ },
472
+ {
473
+ "name": "label",
474
+ "type": "string",
475
+ "required": false
476
+ },
477
+ {
478
+ "name": "onchange",
479
+ "type": "(next: string | CalendarDateRange) => void",
480
+ "required": false
481
+ },
482
+ {
483
+ "name": "class",
484
+ "type": "string",
485
+ "required": false
486
+ }
487
+ ],
488
+ "bindings": {
489
+ "value": "literal",
490
+ "range": "literal",
491
+ "min": "literal",
492
+ "max": "literal",
493
+ "label": "literal",
494
+ "class": "literal"
495
+ },
496
+ "example": {
497
+ "calendar": null,
498
+ "value": "2026-01-15"
499
+ }
500
+ },
501
+ {
502
+ "name": "Card",
503
+ "category": "layout",
504
+ "import": "@human-synthesis/norns-ui/components/Card.n",
505
+ "bindability": [
506
+ "spec-bindable"
507
+ ],
508
+ "props": [
509
+ {
510
+ "name": "padded",
511
+ "type": "boolean",
512
+ "required": false,
513
+ "doc": "Wrap body in `.card-body` (default true). Set false for full-bleed content."
514
+ },
515
+ {
516
+ "name": "interactive",
517
+ "type": "boolean",
518
+ "required": false,
519
+ "doc": "Apply `.card-interactive` hover/focus treatment. Implicit if `href` is set."
520
+ },
521
+ {
522
+ "name": "href",
523
+ "type": "string",
524
+ "required": false,
525
+ "doc": "Renders as `<a>` instead of `<div>` when set."
526
+ },
527
+ {
528
+ "name": "target",
529
+ "type": "string",
530
+ "required": false
531
+ },
532
+ {
533
+ "name": "rel",
534
+ "type": "string",
535
+ "required": false
536
+ },
537
+ {
538
+ "name": "header",
539
+ "type": "Snippet",
540
+ "required": false
541
+ },
542
+ {
543
+ "name": "footer",
544
+ "type": "Snippet",
545
+ "required": false
546
+ },
547
+ {
548
+ "name": "children",
549
+ "type": "Snippet",
550
+ "required": false
551
+ },
552
+ {
553
+ "name": "class",
554
+ "type": "string",
555
+ "required": false
556
+ }
557
+ ],
558
+ "bindings": {
559
+ "padded": "literal",
560
+ "interactive": "literal",
561
+ "href": "literal",
562
+ "class": "literal"
563
+ },
564
+ "example": {
565
+ "card": null,
566
+ "padded": true
567
+ }
568
+ },
569
+ {
570
+ "name": "Carousel",
571
+ "category": "layout",
572
+ "import": "@human-synthesis/norns-ui/components/Carousel.n",
573
+ "bindability": [
574
+ "custom-only"
575
+ ],
576
+ "props": [
577
+ {
578
+ "name": "slides",
579
+ "type": "CarouselSlide[]",
580
+ "required": false
581
+ },
582
+ {
583
+ "name": "index",
584
+ "type": "number",
585
+ "required": false
586
+ },
587
+ {
588
+ "name": "autoplay",
589
+ "type": "boolean",
590
+ "required": false
591
+ },
592
+ {
593
+ "name": "interval",
594
+ "type": "number",
595
+ "required": false,
596
+ "doc": "Autoplay interval in milliseconds. Default 5000."
597
+ },
598
+ {
599
+ "name": "aspect",
600
+ "type": "'video' | 'square' | 'wide' | 'none'",
601
+ "required": false,
602
+ "doc": "Default aspect ratio applied if no explicit `class=\"aspect-...\"` is passed."
603
+ },
604
+ {
605
+ "name": "children",
606
+ "type": "Snippet<[CarouselSlide, number]>",
607
+ "required": false,
608
+ "doc": "Custom slide renderer; receives `(slide, i)` and runs only for slides without `src`."
609
+ },
610
+ {
611
+ "name": "class",
612
+ "type": "string",
613
+ "required": false
614
+ }
615
+ ]
616
+ },
617
+ {
618
+ "name": "Chart",
619
+ "category": "data",
620
+ "import": "@human-synthesis/norns-ui/components/Chart.n",
621
+ "bindability": [
622
+ "spec-bindable"
623
+ ],
624
+ "props": [
625
+ {
626
+ "name": "data",
627
+ "type": "Record<string, unknown>[]",
628
+ "required": false,
629
+ "doc": "Rows to plot — typically a generated Query result."
630
+ },
631
+ {
632
+ "name": "type",
633
+ "type": "ChartType",
634
+ "required": false
635
+ },
636
+ {
637
+ "name": "x",
638
+ "type": "string",
639
+ "required": false,
640
+ "doc": "Field for the x axis / labels. Defaults to the first string field."
641
+ },
642
+ {
643
+ "name": "y",
644
+ "type": "string",
645
+ "required": false,
646
+ "doc": "Field for the y axis values. Defaults to the first numeric field."
647
+ },
648
+ {
649
+ "name": "label",
650
+ "type": "string",
651
+ "required": false,
652
+ "doc": "Accessible label for the rendered svg."
653
+ },
654
+ {
655
+ "name": "labels",
656
+ "type": "boolean",
657
+ "required": false,
658
+ "doc": "Show per-point x labels under the plot."
659
+ },
660
+ {
661
+ "name": "class",
662
+ "type": "string",
663
+ "required": false
664
+ }
665
+ ],
666
+ "bindings": {
667
+ "data": "query",
668
+ "type": "literal",
669
+ "x": "literal",
670
+ "y": "literal",
671
+ "label": "literal",
672
+ "labels": "literal",
673
+ "class": "literal"
674
+ },
675
+ "example": {
676
+ "chart": "deals.Query.amounts",
677
+ "type": "bar",
678
+ "x": "title",
679
+ "y": "amount"
680
+ }
681
+ },
682
+ {
683
+ "name": "ChatThread",
684
+ "category": "realtime",
685
+ "import": "@human-synthesis/norns-ui/components/ChatThread.n",
686
+ "bindability": [
687
+ "spec-bindable",
688
+ "snippet-extensible"
689
+ ],
690
+ "props": [
691
+ {
692
+ "name": "roomChannel",
693
+ "type": "string",
694
+ "required": false,
695
+ "doc": "Room name — a generated Page binds a `room: true` Worker here."
696
+ },
697
+ {
698
+ "name": "send",
699
+ "type": "string",
700
+ "required": false,
701
+ "doc": "Message type sent by the composer (default 'chat')."
702
+ },
703
+ {
704
+ "name": "receive",
705
+ "type": "string",
706
+ "required": false,
707
+ "doc": "Message type appended to the thread (defaults to `send`)."
708
+ },
709
+ {
710
+ "name": "placeholder",
711
+ "type": "string",
712
+ "required": false
713
+ },
714
+ {
715
+ "name": "sendLabel",
716
+ "type": "string",
717
+ "required": false
718
+ },
719
+ {
720
+ "name": "emptyMessage",
721
+ "type": "string",
722
+ "required": false
723
+ },
724
+ {
725
+ "name": "message",
726
+ "type": "Snippet<[ChatMessage]>",
727
+ "required": false,
728
+ "doc": "Message renderer snippet — replaces the default from/text row."
729
+ },
730
+ {
731
+ "name": "class",
732
+ "type": "string",
733
+ "required": false
734
+ }
735
+ ],
736
+ "bindings": {
737
+ "roomChannel": "room",
738
+ "send": "literal",
739
+ "receive": "literal",
740
+ "placeholder": "literal",
741
+ "sendLabel": "literal",
742
+ "emptyMessage": "literal",
743
+ "message": "snippet",
744
+ "class": "literal"
745
+ },
746
+ "example": {
747
+ "chatThread": {
748
+ "room": "games.Worker.matchRoom",
749
+ "sends": [
750
+ "chat"
751
+ ],
752
+ "receives": [
753
+ "chat"
754
+ ]
755
+ }
756
+ },
757
+ "snippetSlots": {
758
+ "message": [
759
+ "message"
760
+ ]
761
+ }
762
+ },
763
+ {
764
+ "name": "Checkbox",
765
+ "category": "form",
766
+ "import": "@human-synthesis/norns-ui/components/Checkbox.n",
767
+ "bindability": [
768
+ "spec-bindable"
769
+ ],
770
+ "props": [
771
+ {
772
+ "name": "checked",
773
+ "type": "boolean",
774
+ "required": false
775
+ },
776
+ {
777
+ "name": "error",
778
+ "type": "boolean",
779
+ "required": false
780
+ },
781
+ {
782
+ "name": "class",
783
+ "type": "string",
784
+ "required": false
785
+ }
786
+ ],
787
+ "bindings": {
788
+ "name": "literal",
789
+ "checked": "literal",
790
+ "required": "literal",
791
+ "disabled": "literal",
792
+ "error": "literal",
793
+ "class": "literal"
794
+ },
795
+ "example": {
796
+ "checkbox": null,
797
+ "name": "done",
798
+ "checked": true
799
+ }
800
+ },
801
+ {
802
+ "name": "Chip",
803
+ "category": "feedback",
804
+ "import": "@human-synthesis/norns-ui/components/Chip.n",
805
+ "bindability": [
806
+ "custom-only"
807
+ ],
808
+ "props": [
809
+ {
810
+ "name": "icon",
811
+ "type": "string",
812
+ "required": false
813
+ },
814
+ {
815
+ "name": "removable",
816
+ "type": "boolean",
817
+ "required": false
818
+ },
819
+ {
820
+ "name": "onremove",
821
+ "type": "(event: MouseEvent) => void",
822
+ "required": false
823
+ },
824
+ {
825
+ "name": "children",
826
+ "type": "Snippet",
827
+ "required": false
828
+ },
829
+ {
830
+ "name": "class",
831
+ "type": "string",
832
+ "required": false
833
+ }
834
+ ]
835
+ },
836
+ {
837
+ "name": "Collapsible",
838
+ "category": "layout",
839
+ "import": "@human-synthesis/norns-ui/components/Collapsible.n",
840
+ "bindability": [
841
+ "custom-only"
842
+ ],
843
+ "props": [
844
+ {
845
+ "name": "open",
846
+ "type": "boolean",
847
+ "required": false
848
+ },
849
+ {
850
+ "name": "title",
851
+ "type": "string",
852
+ "required": false
853
+ },
854
+ {
855
+ "name": "trigger",
856
+ "type": "Snippet",
857
+ "required": false
858
+ },
859
+ {
860
+ "name": "children",
861
+ "type": "Snippet",
862
+ "required": false
863
+ },
864
+ {
865
+ "name": "onopenchange",
866
+ "type": "(open: boolean) => void",
867
+ "required": false
868
+ },
869
+ {
870
+ "name": "class",
871
+ "type": "string",
872
+ "required": false
873
+ }
874
+ ]
875
+ },
876
+ {
877
+ "name": "ColorPicker",
878
+ "category": "form",
879
+ "import": "@human-synthesis/norns-ui/components/ColorPicker.n",
880
+ "bindability": [
881
+ "custom-only"
882
+ ],
883
+ "props": [
884
+ {
885
+ "name": "value",
886
+ "type": "string",
887
+ "required": false,
888
+ "doc": "Hex value with leading `#`. Bindable."
889
+ },
890
+ {
891
+ "name": "disabled",
892
+ "type": "boolean",
893
+ "required": false
894
+ },
895
+ {
896
+ "name": "hideCopy",
897
+ "type": "boolean",
898
+ "required": false,
899
+ "doc": "Hide the clipboard-copy button."
900
+ },
901
+ {
902
+ "name": "name",
903
+ "type": "string",
904
+ "required": false
905
+ },
906
+ {
907
+ "name": "id",
908
+ "type": "string",
909
+ "required": false
910
+ },
911
+ {
912
+ "name": "class",
913
+ "type": "string",
914
+ "required": false
915
+ }
916
+ ]
917
+ },
918
+ {
919
+ "name": "ContextMenu",
920
+ "category": "navigation",
921
+ "import": "@human-synthesis/norns-ui/components/ContextMenu.n",
922
+ "bindability": [
923
+ "custom-only"
924
+ ],
925
+ "props": [
926
+ {
927
+ "name": "items",
928
+ "type": "ContextMenuItem[]",
929
+ "required": false
930
+ },
931
+ {
932
+ "name": "trigger",
933
+ "type": "Snippet",
934
+ "required": false
935
+ },
936
+ {
937
+ "name": "triggerClass",
938
+ "type": "string",
939
+ "required": false
940
+ }
941
+ ]
942
+ },
943
+ {
944
+ "name": "CopyButton",
945
+ "category": "action",
946
+ "import": "@human-synthesis/norns-ui/components/CopyButton.n",
947
+ "bindability": [
948
+ "custom-only"
949
+ ],
950
+ "props": [
951
+ {
952
+ "name": "value",
953
+ "type": "string | number",
954
+ "required": false
955
+ },
956
+ {
957
+ "name": "variant",
958
+ "type": "'primary' | 'secondary' | 'ghost' | 'danger' | 'link'",
959
+ "required": false
960
+ },
961
+ {
962
+ "name": "size",
963
+ "type": "'sm' | 'md' | 'lg'",
964
+ "required": false
965
+ },
966
+ {
967
+ "name": "icon",
968
+ "type": "string",
969
+ "required": false
970
+ },
971
+ {
972
+ "name": "disabled",
973
+ "type": "boolean",
974
+ "required": false
975
+ },
976
+ {
977
+ "name": "label",
978
+ "type": "string",
979
+ "required": false
980
+ },
981
+ {
982
+ "name": "oncopy",
983
+ "type": "(value: string | number) => void",
984
+ "required": false
985
+ },
986
+ {
987
+ "name": "children",
988
+ "type": "Snippet",
989
+ "required": false
990
+ },
991
+ {
992
+ "name": "class",
993
+ "type": "string",
994
+ "required": false
995
+ }
996
+ ]
997
+ },
998
+ {
999
+ "name": "DataTable",
1000
+ "category": "data",
1001
+ "import": "@human-synthesis/norns-ui/components/DataTable.n",
1002
+ "bindability": [
1003
+ "spec-bindable",
1004
+ "snippet-extensible"
1005
+ ],
1006
+ "props": [
1007
+ {
1008
+ "name": "columns",
1009
+ "type": "DataTableColumn[]",
1010
+ "required": false
1011
+ },
1012
+ {
1013
+ "name": "rows",
1014
+ "type": "Record<string, unknown>[]",
1015
+ "required": false
1016
+ },
1017
+ {
1018
+ "name": "striped",
1019
+ "type": "boolean",
1020
+ "required": false
1021
+ },
1022
+ {
1023
+ "name": "dense",
1024
+ "type": "boolean",
1025
+ "required": false
1026
+ },
1027
+ {
1028
+ "name": "stickyHeader",
1029
+ "type": "boolean",
1030
+ "required": false
1031
+ },
1032
+ {
1033
+ "name": "emptyMessage",
1034
+ "type": "string",
1035
+ "required": false
1036
+ },
1037
+ {
1038
+ "name": "sortKey",
1039
+ "type": "string",
1040
+ "required": false,
1041
+ "doc": "Currently-sorted column key. Bindable."
1042
+ },
1043
+ {
1044
+ "name": "sortDir",
1045
+ "type": "'asc' | 'desc'",
1046
+ "required": false
1047
+ },
1048
+ {
1049
+ "name": "onrowclick",
1050
+ "type": "(row: Record<string, unknown>, index: number) => void",
1051
+ "required": false
1052
+ },
1053
+ {
1054
+ "name": "cell",
1055
+ "type": "Snippet<[Record<string, unknown>, string, unknown]>",
1056
+ "required": false,
1057
+ "doc": "Cell renderer snippet — receives (row, columnKey, value)."
1058
+ },
1059
+ {
1060
+ "name": "empty",
1061
+ "type": "Snippet",
1062
+ "required": false,
1063
+ "doc": "Rendered instead of emptyMessage when there are no rows."
1064
+ },
1065
+ {
1066
+ "name": "class",
1067
+ "type": "string",
1068
+ "required": false
1069
+ }
1070
+ ],
1071
+ "bindings": {
1072
+ "data": "query",
1073
+ "columns": "literal",
1074
+ "striped": "literal",
1075
+ "dense": "literal",
1076
+ "stickyHeader": "literal",
1077
+ "emptyMessage": "literal",
1078
+ "sortKey": "literal",
1079
+ "sortDir": "literal",
1080
+ "cell": "snippet",
1081
+ "empty": "snippet",
1082
+ "class": "literal"
1083
+ },
1084
+ "example": {
1085
+ "dataTable": "crm.Query.listDeals",
1086
+ "columns": "name,amount"
1087
+ },
1088
+ "snippetSlots": {
1089
+ "cell": [
1090
+ "row",
1091
+ "column",
1092
+ "value"
1093
+ ],
1094
+ "empty": []
1095
+ }
1096
+ },
1097
+ {
1098
+ "name": "DatePicker",
1099
+ "category": "form",
1100
+ "import": "@human-synthesis/norns-ui/components/DatePicker.n",
1101
+ "bindability": [
1102
+ "spec-bindable"
1103
+ ],
1104
+ "props": [
1105
+ {
1106
+ "name": "value",
1107
+ "type": "string",
1108
+ "required": false,
1109
+ "doc": "ISO date string (YYYY-MM-DD). Bindable."
1110
+ },
1111
+ {
1112
+ "name": "open",
1113
+ "type": "boolean",
1114
+ "required": false,
1115
+ "doc": "Whether the popover is open. Bindable."
1116
+ },
1117
+ {
1118
+ "name": "min",
1119
+ "type": "string",
1120
+ "required": false
1121
+ },
1122
+ {
1123
+ "name": "max",
1124
+ "type": "string",
1125
+ "required": false
1126
+ },
1127
+ {
1128
+ "name": "placeholder",
1129
+ "type": "string",
1130
+ "required": false
1131
+ },
1132
+ {
1133
+ "name": "disabled",
1134
+ "type": "boolean",
1135
+ "required": false
1136
+ },
1137
+ {
1138
+ "name": "closeOnSelect",
1139
+ "type": "boolean",
1140
+ "required": false,
1141
+ "doc": "Close the popover automatically once a date is picked (default true)."
1142
+ },
1143
+ {
1144
+ "name": "label",
1145
+ "type": "string",
1146
+ "required": false,
1147
+ "doc": "aria-label override; defaults to \"Pick a date\"."
1148
+ },
1149
+ {
1150
+ "name": "name",
1151
+ "type": "string",
1152
+ "required": false
1153
+ },
1154
+ {
1155
+ "name": "id",
1156
+ "type": "string",
1157
+ "required": false
1158
+ },
1159
+ {
1160
+ "name": "error",
1161
+ "type": "boolean",
1162
+ "required": false
1163
+ },
1164
+ {
1165
+ "name": "class",
1166
+ "type": "string",
1167
+ "required": false
1168
+ }
1169
+ ],
1170
+ "bindings": {
1171
+ "name": "literal",
1172
+ "value": "literal",
1173
+ "min": "literal",
1174
+ "max": "literal",
1175
+ "placeholder": "literal",
1176
+ "label": "literal",
1177
+ "disabled": "literal",
1178
+ "error": "literal",
1179
+ "id": "literal",
1180
+ "class": "literal"
1181
+ },
1182
+ "example": {
1183
+ "datePicker": null,
1184
+ "name": "due",
1185
+ "placeholder": "Pick a date"
1186
+ }
1187
+ },
1188
+ {
1189
+ "name": "DateRangePicker",
1190
+ "category": "form",
1191
+ "import": "@human-synthesis/norns-ui/components/DateRangePicker.n",
1192
+ "bindability": [
1193
+ "custom-only"
1194
+ ],
1195
+ "props": [
1196
+ {
1197
+ "name": "value",
1198
+ "type": "DateRange",
1199
+ "required": false
1200
+ },
1201
+ {
1202
+ "name": "open",
1203
+ "type": "boolean",
1204
+ "required": false,
1205
+ "doc": "Whether the popover is open. Bindable."
1206
+ },
1207
+ {
1208
+ "name": "min",
1209
+ "type": "string",
1210
+ "required": false
1211
+ },
1212
+ {
1213
+ "name": "max",
1214
+ "type": "string",
1215
+ "required": false
1216
+ },
1217
+ {
1218
+ "name": "placeholder",
1219
+ "type": "string",
1220
+ "required": false
1221
+ },
1222
+ {
1223
+ "name": "disabled",
1224
+ "type": "boolean",
1225
+ "required": false
1226
+ },
1227
+ {
1228
+ "name": "class",
1229
+ "type": "string",
1230
+ "required": false
1231
+ }
1232
+ ]
1233
+ },
1234
+ {
1235
+ "name": "Dialog",
1236
+ "category": "overlay",
1237
+ "import": "@human-synthesis/norns-ui/components/Dialog.n",
1238
+ "bindability": [
1239
+ "custom-only"
1240
+ ],
1241
+ "props": [
1242
+ {
1243
+ "name": "open",
1244
+ "type": "boolean",
1245
+ "required": false
1246
+ },
1247
+ {
1248
+ "name": "title",
1249
+ "type": "string",
1250
+ "required": false
1251
+ },
1252
+ {
1253
+ "name": "description",
1254
+ "type": "string",
1255
+ "required": false
1256
+ },
1257
+ {
1258
+ "name": "hideClose",
1259
+ "type": "boolean",
1260
+ "required": false
1261
+ },
1262
+ {
1263
+ "name": "dismissable",
1264
+ "type": "boolean",
1265
+ "required": false,
1266
+ "doc": "Close on overlay click and Escape. Default true."
1267
+ },
1268
+ {
1269
+ "name": "ariaLabel",
1270
+ "type": "string",
1271
+ "required": false,
1272
+ "doc": "Used as `aria-label` on the dialog when no `title` is provided."
1273
+ },
1274
+ {
1275
+ "name": "trigger",
1276
+ "type": "Snippet",
1277
+ "required": false
1278
+ },
1279
+ {
1280
+ "name": "actions",
1281
+ "type": "Snippet",
1282
+ "required": false
1283
+ },
1284
+ {
1285
+ "name": "children",
1286
+ "type": "Snippet",
1287
+ "required": false
1288
+ },
1289
+ {
1290
+ "name": "triggerClass",
1291
+ "type": "string",
1292
+ "required": false
1293
+ },
1294
+ {
1295
+ "name": "overlayClass",
1296
+ "type": "string",
1297
+ "required": false
1298
+ },
1299
+ {
1300
+ "name": "class",
1301
+ "type": "string",
1302
+ "required": false
1303
+ }
1304
+ ]
1305
+ },
1306
+ {
1307
+ "name": "Dropdown",
1308
+ "category": "navigation",
1309
+ "import": "@human-synthesis/norns-ui/components/Dropdown.n",
1310
+ "bindability": [
1311
+ "custom-only"
1312
+ ],
1313
+ "props": [
1314
+ {
1315
+ "name": "open",
1316
+ "type": "boolean",
1317
+ "required": false
1318
+ },
1319
+ {
1320
+ "name": "side",
1321
+ "type": "'top' | 'right' | 'bottom' | 'left'",
1322
+ "required": false
1323
+ },
1324
+ {
1325
+ "name": "align",
1326
+ "type": "'start' | 'center' | 'end'",
1327
+ "required": false
1328
+ },
1329
+ {
1330
+ "name": "sideOffset",
1331
+ "type": "number",
1332
+ "required": false
1333
+ },
1334
+ {
1335
+ "name": "items",
1336
+ "type": "DropdownItem[]",
1337
+ "required": false
1338
+ },
1339
+ {
1340
+ "name": "trigger",
1341
+ "type": "Snippet",
1342
+ "required": false
1343
+ },
1344
+ {
1345
+ "name": "children",
1346
+ "type": "Snippet",
1347
+ "required": false
1348
+ },
1349
+ {
1350
+ "name": "triggerClass",
1351
+ "type": "string",
1352
+ "required": false
1353
+ },
1354
+ {
1355
+ "name": "class",
1356
+ "type": "string",
1357
+ "required": false
1358
+ }
1359
+ ]
1360
+ },
1361
+ {
1362
+ "name": "Feed",
1363
+ "category": "realtime",
1364
+ "import": "@human-synthesis/norns-ui/components/Feed.n",
1365
+ "bindability": [
1366
+ "spec-bindable",
1367
+ "snippet-extensible"
1368
+ ],
1369
+ "props": [
1370
+ {
1371
+ "name": "streamSource",
1372
+ "type": "string",
1373
+ "required": false,
1374
+ "doc": "SSE endpoint URL — frames append as entries."
1375
+ },
1376
+ {
1377
+ "name": "roomChannel",
1378
+ "type": "string",
1379
+ "required": false,
1380
+ "doc": "Room name — received frames append as entries."
1381
+ },
1382
+ {
1383
+ "name": "receive",
1384
+ "type": "string",
1385
+ "required": false,
1386
+ "doc": "Room message type to append ('*' for all, the default)."
1387
+ },
1388
+ {
1389
+ "name": "max",
1390
+ "type": "number | string",
1391
+ "required": false,
1392
+ "doc": "Newest entries kept (default 100)."
1393
+ },
1394
+ {
1395
+ "name": "emptyMessage",
1396
+ "type": "string",
1397
+ "required": false
1398
+ },
1399
+ {
1400
+ "name": "item",
1401
+ "type": "Snippet<[unknown]>",
1402
+ "required": false,
1403
+ "doc": "Entry renderer snippet — replaces the default text/JSON line."
1404
+ },
1405
+ {
1406
+ "name": "class",
1407
+ "type": "string",
1408
+ "required": false
1409
+ }
1410
+ ],
1411
+ "bindings": {
1412
+ "streamSource": "stream",
1413
+ "roomChannel": "room",
1414
+ "receive": "literal",
1415
+ "max": "literal",
1416
+ "emptyMessage": "literal",
1417
+ "item": "snippet",
1418
+ "class": "literal"
1419
+ },
1420
+ "example": {
1421
+ "feed": {
1422
+ "stream": "ops.Endpoint.events"
1423
+ }
1424
+ },
1425
+ "snippetSlots": {
1426
+ "item": [
1427
+ "item"
1428
+ ]
1429
+ }
1430
+ },
1431
+ {
1432
+ "name": "Field",
1433
+ "category": "form",
1434
+ "import": "@human-synthesis/norns-ui/components/Field.n",
1435
+ "bindability": [
1436
+ "spec-bindable"
1437
+ ],
1438
+ "props": [
1439
+ {
1440
+ "name": "label",
1441
+ "type": "string",
1442
+ "required": false,
1443
+ "doc": "Label text rendered above the control. Used as id-derivation fallback if no `id`/`name` is given."
1444
+ },
1445
+ {
1446
+ "name": "help",
1447
+ "type": "string",
1448
+ "required": false,
1449
+ "doc": "Helper text shown below the control when there's no error."
1450
+ },
1451
+ {
1452
+ "name": "error",
1453
+ "type": "string",
1454
+ "required": false
1455
+ },
1456
+ {
1457
+ "name": "name",
1458
+ "type": "string",
1459
+ "required": false
1460
+ },
1461
+ {
1462
+ "name": "required",
1463
+ "type": "boolean",
1464
+ "required": false,
1465
+ "doc": "Adds a red asterisk after the label. Cosmetic; pair with `required` on the actual input."
1466
+ },
1467
+ {
1468
+ "name": "id",
1469
+ "type": "string",
1470
+ "required": false,
1471
+ "doc": "Explicit id for the control. Otherwise: `name`, then slugified `label`, then undefined."
1472
+ },
1473
+ {
1474
+ "name": "class",
1475
+ "type": "string",
1476
+ "required": false,
1477
+ "doc": "Optional class merged into the field wrapper."
1478
+ },
1479
+ {
1480
+ "name": "children",
1481
+ "type": "Snippet",
1482
+ "required": false,
1483
+ "doc": "Snippet that renders the actual control. Children should call `<Input />`, `<Textarea />`, etc."
1484
+ }
1485
+ ],
1486
+ "bindings": {
1487
+ "label": "literal",
1488
+ "help": "literal",
1489
+ "error": "literal",
1490
+ "name": "literal",
1491
+ "required": "literal",
1492
+ "id": "literal",
1493
+ "class": "literal"
1494
+ },
1495
+ "example": {
1496
+ "field": null,
1497
+ "label": "Email",
1498
+ "name": "email"
1499
+ }
1500
+ },
1501
+ {
1502
+ "name": "FieldGroup",
1503
+ "category": "form",
1504
+ "import": "@human-synthesis/norns-ui/components/FieldGroup.n",
1505
+ "bindability": [
1506
+ "custom-only"
1507
+ ],
1508
+ "props": [
1509
+ {
1510
+ "name": "legend",
1511
+ "type": "string",
1512
+ "required": false,
1513
+ "doc": "Optional legend text rendered as the fieldset's `<legend>`."
1514
+ },
1515
+ {
1516
+ "name": "class",
1517
+ "type": "string",
1518
+ "required": false
1519
+ },
1520
+ {
1521
+ "name": "children",
1522
+ "type": "Snippet",
1523
+ "required": false
1524
+ }
1525
+ ]
1526
+ },
1527
+ {
1528
+ "name": "Form",
1529
+ "category": "form",
1530
+ "import": "@human-synthesis/norns-ui/components/Form.n",
1531
+ "bindability": [
1532
+ "spec-bindable"
1533
+ ],
1534
+ "props": [
1535
+ {
1536
+ "name": "method",
1537
+ "type": "'GET' | 'POST'",
1538
+ "required": false
1539
+ },
1540
+ {
1541
+ "name": "action",
1542
+ "type": "string",
1543
+ "required": false
1544
+ },
1545
+ {
1546
+ "name": "enctype",
1547
+ "type": "'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain'",
1548
+ "required": false
1549
+ },
1550
+ {
1551
+ "name": "form",
1552
+ "type": "FormActionResult",
1553
+ "required": false
1554
+ },
1555
+ {
1556
+ "name": "class",
1557
+ "type": "string",
1558
+ "required": false
1559
+ },
1560
+ {
1561
+ "name": "children",
1562
+ "type": "Snippet",
1563
+ "required": false
1564
+ }
1565
+ ],
1566
+ "bindings": {
1567
+ "action": "action",
1568
+ "method": "literal",
1569
+ "enctype": "literal",
1570
+ "class": "literal"
1571
+ },
1572
+ "example": {
1573
+ "form": "crm.Action.createDeal",
1574
+ "method": "POST"
1575
+ }
1576
+ },
1577
+ {
1578
+ "name": "GradientText",
1579
+ "category": "typography",
1580
+ "import": "@human-synthesis/norns-ui/components/GradientText.n",
1581
+ "bindability": [
1582
+ "custom-only"
1583
+ ],
1584
+ "props": [
1585
+ {
1586
+ "name": "from",
1587
+ "type": "string",
1588
+ "required": false,
1589
+ "doc": "Start color. Default `var(--color-primary-500)`. Accepts any CSS color."
1590
+ },
1591
+ {
1592
+ "name": "to",
1593
+ "type": "string",
1594
+ "required": false,
1595
+ "doc": "End color. Default `var(--color-info-500)`."
1596
+ },
1597
+ {
1598
+ "name": "via",
1599
+ "type": "string",
1600
+ "required": false,
1601
+ "doc": "Optional middle stop."
1602
+ },
1603
+ {
1604
+ "name": "animate",
1605
+ "type": "boolean",
1606
+ "required": false,
1607
+ "doc": "Animate the gradient via background-position keyframes. Default true."
1608
+ },
1609
+ {
1610
+ "name": "angle",
1611
+ "type": "number",
1612
+ "required": false,
1613
+ "doc": "Gradient angle in degrees. Default 90."
1614
+ },
1615
+ {
1616
+ "name": "children",
1617
+ "type": "Snippet",
1618
+ "required": false
1619
+ },
1620
+ {
1621
+ "name": "class",
1622
+ "type": "string",
1623
+ "required": false
1624
+ }
1625
+ ]
1626
+ },
1627
+ {
1628
+ "name": "Header",
1629
+ "category": "navigation",
1630
+ "import": "@human-synthesis/norns-ui/components/Header.n",
1631
+ "bindability": [
1632
+ "custom-only"
1633
+ ],
1634
+ "props": [
1635
+ {
1636
+ "name": "sticky",
1637
+ "type": "boolean",
1638
+ "required": false
1639
+ },
1640
+ {
1641
+ "name": "brand",
1642
+ "type": "Snippet",
1643
+ "required": false
1644
+ },
1645
+ {
1646
+ "name": "nav",
1647
+ "type": "Snippet",
1648
+ "required": false
1649
+ },
1650
+ {
1651
+ "name": "actions",
1652
+ "type": "Snippet",
1653
+ "required": false
1654
+ },
1655
+ {
1656
+ "name": "class",
1657
+ "type": "string",
1658
+ "required": false
1659
+ }
1660
+ ]
1661
+ },
1662
+ {
1663
+ "name": "HeroBanner",
1664
+ "category": "layout",
1665
+ "import": "@human-synthesis/norns-ui/components/HeroBanner.n",
1666
+ "bindability": [
1667
+ "custom-only"
1668
+ ],
1669
+ "props": [
1670
+ {
1671
+ "name": "title",
1672
+ "type": "string",
1673
+ "required": true
1674
+ },
1675
+ {
1676
+ "name": "description",
1677
+ "type": "string",
1678
+ "required": false
1679
+ },
1680
+ {
1681
+ "name": "image",
1682
+ "type": "string",
1683
+ "required": false,
1684
+ "doc": "Background/decorative image src; rendered with reduced opacity behind the content."
1685
+ },
1686
+ {
1687
+ "name": "align",
1688
+ "type": "'left' | 'center'",
1689
+ "required": false
1690
+ },
1691
+ {
1692
+ "name": "gradient",
1693
+ "type": "boolean",
1694
+ "required": false,
1695
+ "doc": "Apply animated `GradientText` to the title. Default false."
1696
+ },
1697
+ {
1698
+ "name": "actions",
1699
+ "type": "Snippet",
1700
+ "required": false
1701
+ },
1702
+ {
1703
+ "name": "children",
1704
+ "type": "Snippet",
1705
+ "required": false
1706
+ },
1707
+ {
1708
+ "name": "class",
1709
+ "type": "string",
1710
+ "required": false
1711
+ }
1712
+ ]
1713
+ },
1714
+ {
1715
+ "name": "HierarchicalMenu",
1716
+ "category": "navigation",
1717
+ "import": "@human-synthesis/norns-ui/components/HierarchicalMenu.n",
1718
+ "bindability": [
1719
+ "custom-only"
1720
+ ],
1721
+ "props": [
1722
+ {
1723
+ "name": "items",
1724
+ "type": "HierarchicalMenuItem[]",
1725
+ "required": false
1726
+ },
1727
+ {
1728
+ "name": "label",
1729
+ "type": "string",
1730
+ "required": false,
1731
+ "doc": "aria-label for the <nav> wrapper."
1732
+ },
1733
+ {
1734
+ "name": "onSelect",
1735
+ "type": "(item: HierarchicalMenuItem) => void",
1736
+ "required": false
1737
+ },
1738
+ {
1739
+ "name": "class",
1740
+ "type": "string",
1741
+ "required": false
1742
+ }
1743
+ ]
1744
+ },
1745
+ {
1746
+ "name": "Icon",
1747
+ "category": "media",
1748
+ "import": "@human-synthesis/norns-ui/components/Icon.n",
1749
+ "bindability": [
1750
+ "custom-only"
1751
+ ],
1752
+ "props": [
1753
+ {
1754
+ "name": "name",
1755
+ "type": "string",
1756
+ "required": true
1757
+ },
1758
+ {
1759
+ "name": "size",
1760
+ "type": "string",
1761
+ "required": false
1762
+ },
1763
+ {
1764
+ "name": "flip",
1765
+ "type": "'horizontal' | 'vertical' | 'horizontal,vertical'",
1766
+ "required": false
1767
+ },
1768
+ {
1769
+ "name": "rotate",
1770
+ "type": "90 | 180 | 270 | string",
1771
+ "required": false
1772
+ },
1773
+ {
1774
+ "name": "class",
1775
+ "type": "string",
1776
+ "required": false
1777
+ }
1778
+ ]
1779
+ },
1780
+ {
1781
+ "name": "Image",
1782
+ "category": "media",
1783
+ "import": "@human-synthesis/norns-ui/components/Image.n",
1784
+ "bindability": [
1785
+ "custom-only"
1786
+ ],
1787
+ "props": [
1788
+ {
1789
+ "name": "src",
1790
+ "type": "string",
1791
+ "required": true
1792
+ },
1793
+ {
1794
+ "name": "alt",
1795
+ "type": "string",
1796
+ "required": false
1797
+ },
1798
+ {
1799
+ "name": "loading",
1800
+ "type": "'lazy' | 'eager'",
1801
+ "required": false
1802
+ },
1803
+ {
1804
+ "name": "fit",
1805
+ "type": "'cover' | 'contain' | 'fill' | 'none' | 'scale-down'",
1806
+ "required": false
1807
+ },
1808
+ {
1809
+ "name": "rounded",
1810
+ "type": "boolean | 'sm' | 'md' | 'lg' | 'full'",
1811
+ "required": false
1812
+ },
1813
+ {
1814
+ "name": "width",
1815
+ "type": "number | string",
1816
+ "required": false
1817
+ },
1818
+ {
1819
+ "name": "height",
1820
+ "type": "number | string",
1821
+ "required": false
1822
+ },
1823
+ {
1824
+ "name": "class",
1825
+ "type": "string",
1826
+ "required": false
1827
+ }
1828
+ ]
1829
+ },
1830
+ {
1831
+ "name": "Input",
1832
+ "category": "form",
1833
+ "import": "@human-synthesis/norns-ui/components/Input.n",
1834
+ "bindability": [
1835
+ "spec-bindable"
1836
+ ],
1837
+ "props": [
1838
+ {
1839
+ "name": "value",
1840
+ "type": "string | number",
1841
+ "required": false
1842
+ },
1843
+ {
1844
+ "name": "type",
1845
+ "type": "InputType",
1846
+ "required": false
1847
+ },
1848
+ {
1849
+ "name": "size",
1850
+ "type": "InputSize",
1851
+ "required": false
1852
+ },
1853
+ {
1854
+ "name": "error",
1855
+ "type": "boolean",
1856
+ "required": false,
1857
+ "doc": "Force the error styling regardless of the parent Field's error state."
1858
+ },
1859
+ {
1860
+ "name": "class",
1861
+ "type": "string",
1862
+ "required": false
1863
+ }
1864
+ ],
1865
+ "bindings": {
1866
+ "name": "literal",
1867
+ "type": "literal",
1868
+ "value": "literal",
1869
+ "placeholder": "literal",
1870
+ "required": "literal",
1871
+ "size": "literal",
1872
+ "class": "literal"
1873
+ },
1874
+ "example": {
1875
+ "input": null,
1876
+ "name": "email",
1877
+ "type": "email",
1878
+ "placeholder": "you@example.com"
1879
+ }
1880
+ },
1881
+ {
1882
+ "name": "Kanban",
1883
+ "category": "data",
1884
+ "import": "@human-synthesis/norns-ui/components/Kanban.n",
1885
+ "bindability": [
1886
+ "spec-bindable",
1887
+ "snippet-extensible"
1888
+ ],
1889
+ "props": [
1890
+ {
1891
+ "name": "data",
1892
+ "type": "Record<string, KanbanCard[]>",
1893
+ "required": false,
1894
+ "doc": "Cards grouped by column key — typically a grouped Query result."
1895
+ },
1896
+ {
1897
+ "name": "columns",
1898
+ "type": "string | Array<string | { key: string; label?: string }>",
1899
+ "required": false,
1900
+ "doc": "Column order/labels: comma-separated keys, key list, or {key,label} list."
1901
+ },
1902
+ {
1903
+ "name": "title",
1904
+ "type": "string",
1905
+ "required": false,
1906
+ "doc": "Card field used as the card title. Defaults to the first string field."
1907
+ },
1908
+ {
1909
+ "name": "subtitle",
1910
+ "type": "string",
1911
+ "required": false,
1912
+ "doc": "Card field rendered under the title when present."
1913
+ },
1914
+ {
1915
+ "name": "onMove",
1916
+ "type": "(card: KanbanCard, to: string, from: string) => unknown",
1917
+ "required": false,
1918
+ "doc": "Called after a drag between columns; binding an Action enables dragging."
1919
+ },
1920
+ {
1921
+ "name": "oncardclick",
1922
+ "type": "(card: KanbanCard) => void",
1923
+ "required": false
1924
+ },
1925
+ {
1926
+ "name": "emptyMessage",
1927
+ "type": "string",
1928
+ "required": false
1929
+ },
1930
+ {
1931
+ "name": "card",
1932
+ "type": "Snippet<[KanbanCard]>",
1933
+ "required": false,
1934
+ "doc": "Card renderer snippet — replaces the default title/subtitle block."
1935
+ },
1936
+ {
1937
+ "name": "empty",
1938
+ "type": "Snippet",
1939
+ "required": false,
1940
+ "doc": "Rendered instead of emptyMessage in an empty column."
1941
+ },
1942
+ {
1943
+ "name": "class",
1944
+ "type": "string",
1945
+ "required": false
1946
+ }
1947
+ ],
1948
+ "bindings": {
1949
+ "data": "query",
1950
+ "onMove": "action",
1951
+ "columns": "literal",
1952
+ "title": "literal",
1953
+ "subtitle": "literal",
1954
+ "emptyMessage": "literal",
1955
+ "card": "snippet",
1956
+ "empty": "snippet",
1957
+ "class": "literal"
1958
+ },
1959
+ "example": {
1960
+ "kanban": "deals.Query.pipeline",
1961
+ "onMove": "deals.Action.win",
1962
+ "title": "title"
1963
+ },
1964
+ "snippetSlots": {
1965
+ "card": [
1966
+ "card"
1967
+ ],
1968
+ "empty": []
1969
+ }
1970
+ },
1971
+ {
1972
+ "name": "Listbox",
1973
+ "category": "form",
1974
+ "import": "@human-synthesis/norns-ui/components/Listbox.n",
1975
+ "bindability": [
1976
+ "custom-only"
1977
+ ],
1978
+ "props": [
1979
+ {
1980
+ "name": "items",
1981
+ "type": "ListboxItem[]",
1982
+ "required": false
1983
+ },
1984
+ {
1985
+ "name": "value",
1986
+ "type": "unknown",
1987
+ "required": false,
1988
+ "doc": "Selected value (array when `multiple`). Bindable."
1989
+ },
1990
+ {
1991
+ "name": "multiple",
1992
+ "type": "boolean",
1993
+ "required": false
1994
+ },
1995
+ {
1996
+ "name": "disabled",
1997
+ "type": "boolean",
1998
+ "required": false
1999
+ },
2000
+ {
2001
+ "name": "emptyMessage",
2002
+ "type": "string",
2003
+ "required": false
2004
+ },
2005
+ {
2006
+ "name": "onchange",
2007
+ "type": "(value: unknown) => void",
2008
+ "required": false
2009
+ },
2010
+ {
2011
+ "name": "class",
2012
+ "type": "string",
2013
+ "required": false
2014
+ }
2015
+ ]
2016
+ },
2017
+ {
2018
+ "name": "LiveLog",
2019
+ "category": "realtime",
2020
+ "import": "@human-synthesis/norns-ui/components/LiveLog.n",
2021
+ "bindability": [
2022
+ "spec-bindable"
2023
+ ],
2024
+ "props": [
2025
+ {
2026
+ "name": "streamSource",
2027
+ "type": "string",
2028
+ "required": false,
2029
+ "doc": "SSE endpoint URL — each frame becomes a log line."
2030
+ },
2031
+ {
2032
+ "name": "roomChannel",
2033
+ "type": "string",
2034
+ "required": false,
2035
+ "doc": "Room name — received frames become log lines."
2036
+ },
2037
+ {
2038
+ "name": "receive",
2039
+ "type": "string",
2040
+ "required": false,
2041
+ "doc": "Room message type to log ('*' for all, the default)."
2042
+ },
2043
+ {
2044
+ "name": "maxLines",
2045
+ "type": "number | string",
2046
+ "required": false,
2047
+ "doc": "Newest lines kept (default 200)."
2048
+ },
2049
+ {
2050
+ "name": "class",
2051
+ "type": "string",
2052
+ "required": false
2053
+ }
2054
+ ],
2055
+ "bindings": {
2056
+ "streamSource": "stream",
2057
+ "roomChannel": "room",
2058
+ "receive": "literal",
2059
+ "maxLines": "literal",
2060
+ "class": "literal"
2061
+ },
2062
+ "example": {
2063
+ "liveLog": {
2064
+ "stream": "ops.Endpoint.logs"
2065
+ },
2066
+ "maxLines": 200
2067
+ }
2068
+ },
2069
+ {
2070
+ "name": "MegaMenu",
2071
+ "category": "navigation",
2072
+ "import": "@human-synthesis/norns-ui/components/MegaMenu.n",
2073
+ "bindability": [
2074
+ "custom-only"
2075
+ ],
2076
+ "props": [
2077
+ {
2078
+ "name": "sections",
2079
+ "type": "MegaMenuSection[]",
2080
+ "required": false
2081
+ },
2082
+ {
2083
+ "name": "label",
2084
+ "type": "string",
2085
+ "required": false,
2086
+ "doc": "aria-label for the <nav> wrapper."
2087
+ },
2088
+ {
2089
+ "name": "class",
2090
+ "type": "string",
2091
+ "required": false
2092
+ }
2093
+ ]
2094
+ },
2095
+ {
2096
+ "name": "MultiSelect",
2097
+ "category": "form",
2098
+ "import": "@human-synthesis/norns-ui/components/MultiSelect.n",
2099
+ "bindability": [
2100
+ "custom-only"
2101
+ ],
2102
+ "props": [
2103
+ {
2104
+ "name": "items",
2105
+ "type": "ComboboxItem[]",
2106
+ "required": false
2107
+ },
2108
+ {
2109
+ "name": "value",
2110
+ "type": "string[]",
2111
+ "required": false
2112
+ },
2113
+ {
2114
+ "name": "open",
2115
+ "type": "boolean",
2116
+ "required": false
2117
+ },
2118
+ {
2119
+ "name": "placeholder",
2120
+ "type": "string",
2121
+ "required": false
2122
+ },
2123
+ {
2124
+ "name": "disabled",
2125
+ "type": "boolean",
2126
+ "required": false
2127
+ },
2128
+ {
2129
+ "name": "name",
2130
+ "type": "string",
2131
+ "required": false
2132
+ },
2133
+ {
2134
+ "name": "id",
2135
+ "type": "string",
2136
+ "required": false
2137
+ },
2138
+ {
2139
+ "name": "error",
2140
+ "type": "boolean",
2141
+ "required": false
2142
+ }
2143
+ ]
2144
+ },
2145
+ {
2146
+ "name": "NumberInput",
2147
+ "category": "form",
2148
+ "import": "@human-synthesis/norns-ui/components/NumberInput.n",
2149
+ "bindability": [
2150
+ "custom-only"
2151
+ ],
2152
+ "props": [
2153
+ {
2154
+ "name": "value",
2155
+ "type": "number",
2156
+ "required": false
2157
+ },
2158
+ {
2159
+ "name": "min",
2160
+ "type": "number",
2161
+ "required": false
2162
+ },
2163
+ {
2164
+ "name": "max",
2165
+ "type": "number",
2166
+ "required": false
2167
+ },
2168
+ {
2169
+ "name": "stepSize",
2170
+ "type": "number",
2171
+ "required": false
2172
+ },
2173
+ {
2174
+ "name": "disabled",
2175
+ "type": "boolean",
2176
+ "required": false
2177
+ },
2178
+ {
2179
+ "name": "readonly",
2180
+ "type": "boolean",
2181
+ "required": false
2182
+ },
2183
+ {
2184
+ "name": "name",
2185
+ "type": "string",
2186
+ "required": false
2187
+ },
2188
+ {
2189
+ "name": "id",
2190
+ "type": "string",
2191
+ "required": false
2192
+ },
2193
+ {
2194
+ "name": "error",
2195
+ "type": "boolean",
2196
+ "required": false
2197
+ },
2198
+ {
2199
+ "name": "class",
2200
+ "type": "string",
2201
+ "required": false
2202
+ }
2203
+ ]
2204
+ },
2205
+ {
2206
+ "name": "OtpField",
2207
+ "category": "form",
2208
+ "import": "@human-synthesis/norns-ui/components/OtpField.n",
2209
+ "bindability": [
2210
+ "custom-only"
2211
+ ],
2212
+ "props": [
2213
+ {
2214
+ "name": "value",
2215
+ "type": "string",
2216
+ "required": false
2217
+ },
2218
+ {
2219
+ "name": "length",
2220
+ "type": "number",
2221
+ "required": false
2222
+ },
2223
+ {
2224
+ "name": "mask",
2225
+ "type": "boolean",
2226
+ "required": false
2227
+ },
2228
+ {
2229
+ "name": "label",
2230
+ "type": "string",
2231
+ "required": false
2232
+ },
2233
+ {
2234
+ "name": "oncomplete",
2235
+ "type": "(value: string) => void",
2236
+ "required": false
2237
+ },
2238
+ {
2239
+ "name": "class",
2240
+ "type": "string",
2241
+ "required": false
2242
+ }
2243
+ ]
2244
+ },
2245
+ {
2246
+ "name": "Pagination",
2247
+ "category": "data",
2248
+ "import": "@human-synthesis/norns-ui/components/Pagination.n",
2249
+ "bindability": [
2250
+ "spec-bindable"
2251
+ ],
2252
+ "props": [
2253
+ {
2254
+ "name": "page",
2255
+ "type": "number",
2256
+ "required": false
2257
+ },
2258
+ {
2259
+ "name": "total",
2260
+ "type": "number",
2261
+ "required": false
2262
+ },
2263
+ {
2264
+ "name": "pageSize",
2265
+ "type": "number",
2266
+ "required": false
2267
+ },
2268
+ {
2269
+ "name": "siblingCount",
2270
+ "type": "number",
2271
+ "required": false,
2272
+ "doc": "How many pages to show on each side of the current. Default 1."
2273
+ },
2274
+ {
2275
+ "name": "class",
2276
+ "type": "string",
2277
+ "required": false
2278
+ }
2279
+ ],
2280
+ "bindings": {
2281
+ "page": "literal",
2282
+ "total": "literal",
2283
+ "pageSize": "literal",
2284
+ "siblingCount": "literal",
2285
+ "class": "literal"
2286
+ },
2287
+ "example": {
2288
+ "pagination": null,
2289
+ "total": 120,
2290
+ "pageSize": 20
2291
+ }
2292
+ },
2293
+ {
2294
+ "name": "Popover",
2295
+ "category": "overlay",
2296
+ "import": "@human-synthesis/norns-ui/components/Popover.n",
2297
+ "bindability": [
2298
+ "custom-only"
2299
+ ],
2300
+ "props": [
2301
+ {
2302
+ "name": "open",
2303
+ "type": "boolean",
2304
+ "required": false
2305
+ },
2306
+ {
2307
+ "name": "side",
2308
+ "type": "PopoverSide",
2309
+ "required": false
2310
+ },
2311
+ {
2312
+ "name": "align",
2313
+ "type": "PopoverAlign",
2314
+ "required": false
2315
+ },
2316
+ {
2317
+ "name": "sideOffset",
2318
+ "type": "number",
2319
+ "required": false
2320
+ },
2321
+ {
2322
+ "name": "trigger",
2323
+ "type": "Snippet",
2324
+ "required": false
2325
+ },
2326
+ {
2327
+ "name": "children",
2328
+ "type": "Snippet",
2329
+ "required": false
2330
+ },
2331
+ {
2332
+ "name": "triggerClass",
2333
+ "type": "string",
2334
+ "required": false
2335
+ },
2336
+ {
2337
+ "name": "class",
2338
+ "type": "string",
2339
+ "required": false
2340
+ }
2341
+ ]
2342
+ },
2343
+ {
2344
+ "name": "PresenceAvatars",
2345
+ "category": "realtime",
2346
+ "import": "@human-synthesis/norns-ui/components/PresenceAvatars.n",
2347
+ "bindability": [
2348
+ "spec-bindable"
2349
+ ],
2350
+ "props": [
2351
+ {
2352
+ "name": "roomChannel",
2353
+ "type": "string",
2354
+ "required": false,
2355
+ "doc": "Room name — client count comes from the Room's presence broadcasts."
2356
+ },
2357
+ {
2358
+ "name": "max",
2359
+ "type": "number | string",
2360
+ "required": false,
2361
+ "doc": "Avatars shown before the +N overflow (default 5)."
2362
+ },
2363
+ {
2364
+ "name": "size",
2365
+ "type": "'xs' | 'sm' | 'md' | 'lg'",
2366
+ "required": false
2367
+ },
2368
+ {
2369
+ "name": "label",
2370
+ "type": "string",
2371
+ "required": false,
2372
+ "doc": "Suffix after the count (default 'online')."
2373
+ },
2374
+ {
2375
+ "name": "showCount",
2376
+ "type": "boolean",
2377
+ "required": false,
2378
+ "doc": "Show the numeric count next to the avatars (default true)."
2379
+ },
2380
+ {
2381
+ "name": "class",
2382
+ "type": "string",
2383
+ "required": false
2384
+ }
2385
+ ],
2386
+ "bindings": {
2387
+ "roomChannel": "room",
2388
+ "max": "literal",
2389
+ "size": "literal",
2390
+ "label": "literal",
2391
+ "showCount": "literal",
2392
+ "class": "literal"
2393
+ },
2394
+ "example": {
2395
+ "presenceAvatars": {
2396
+ "room": "games.Worker.matchRoom"
2397
+ },
2398
+ "max": 5
2399
+ }
2400
+ },
2401
+ {
2402
+ "name": "Progress",
2403
+ "category": "feedback",
2404
+ "import": "@human-synthesis/norns-ui/components/Progress.n",
2405
+ "bindability": [
2406
+ "custom-only"
2407
+ ],
2408
+ "props": [
2409
+ {
2410
+ "name": "value",
2411
+ "type": "number",
2412
+ "required": false
2413
+ },
2414
+ {
2415
+ "name": "max",
2416
+ "type": "number",
2417
+ "required": false
2418
+ },
2419
+ {
2420
+ "name": "variant",
2421
+ "type": "ProgressVariant",
2422
+ "required": false
2423
+ },
2424
+ {
2425
+ "name": "indeterminate",
2426
+ "type": "boolean",
2427
+ "required": false
2428
+ },
2429
+ {
2430
+ "name": "class",
2431
+ "type": "string",
2432
+ "required": false
2433
+ }
2434
+ ]
2435
+ },
2436
+ {
2437
+ "name": "ProgressCircular",
2438
+ "category": "feedback",
2439
+ "import": "@human-synthesis/norns-ui/components/ProgressCircular.n",
2440
+ "bindability": [
2441
+ "custom-only"
2442
+ ],
2443
+ "props": [
2444
+ {
2445
+ "name": "value",
2446
+ "type": "number",
2447
+ "required": false
2448
+ },
2449
+ {
2450
+ "name": "max",
2451
+ "type": "number",
2452
+ "required": false
2453
+ },
2454
+ {
2455
+ "name": "size",
2456
+ "type": "ProgressCircularSize",
2457
+ "required": false
2458
+ },
2459
+ {
2460
+ "name": "indeterminate",
2461
+ "type": "boolean",
2462
+ "required": false
2463
+ },
2464
+ {
2465
+ "name": "class",
2466
+ "type": "string",
2467
+ "required": false
2468
+ }
2469
+ ]
2470
+ },
2471
+ {
2472
+ "name": "Radio",
2473
+ "category": "form",
2474
+ "import": "@human-synthesis/norns-ui/components/Radio.n",
2475
+ "bindability": [
2476
+ "custom-only"
2477
+ ],
2478
+ "props": [
2479
+ {
2480
+ "name": "group",
2481
+ "type": "string",
2482
+ "required": false,
2483
+ "doc": "Two-way bound shared group value — pass `bind:group={selected}` from parent."
2484
+ },
2485
+ {
2486
+ "name": "value",
2487
+ "type": "string",
2488
+ "required": false
2489
+ },
2490
+ {
2491
+ "name": "error",
2492
+ "type": "boolean",
2493
+ "required": false
2494
+ },
2495
+ {
2496
+ "name": "class",
2497
+ "type": "string",
2498
+ "required": false
2499
+ }
2500
+ ]
2501
+ },
2502
+ {
2503
+ "name": "RippleButton",
2504
+ "category": "action",
2505
+ "import": "@human-synthesis/norns-ui/components/RippleButton.n",
2506
+ "bindability": [
2507
+ "custom-only"
2508
+ ],
2509
+ "props": [
2510
+ {
2511
+ "name": "variant",
2512
+ "type": "'primary' | 'secondary' | 'ghost' | 'danger' | 'link'",
2513
+ "required": false
2514
+ },
2515
+ {
2516
+ "name": "size",
2517
+ "type": "'sm' | 'md' | 'lg'",
2518
+ "required": false
2519
+ },
2520
+ {
2521
+ "name": "type",
2522
+ "type": "'button' | 'submit' | 'reset'",
2523
+ "required": false
2524
+ },
2525
+ {
2526
+ "name": "disabled",
2527
+ "type": "boolean",
2528
+ "required": false
2529
+ },
2530
+ {
2531
+ "name": "onclick",
2532
+ "type": "(event: MouseEvent) => void",
2533
+ "required": false
2534
+ },
2535
+ {
2536
+ "name": "icon",
2537
+ "type": "string",
2538
+ "required": false
2539
+ },
2540
+ {
2541
+ "name": "children",
2542
+ "type": "Snippet",
2543
+ "required": false
2544
+ },
2545
+ {
2546
+ "name": "class",
2547
+ "type": "string",
2548
+ "required": false
2549
+ }
2550
+ ]
2551
+ },
2552
+ {
2553
+ "name": "ScrollArea",
2554
+ "category": "layout",
2555
+ "import": "@human-synthesis/norns-ui/components/ScrollArea.n",
2556
+ "bindability": [
2557
+ "custom-only"
2558
+ ],
2559
+ "props": [
2560
+ {
2561
+ "name": "horizontal",
2562
+ "type": "boolean",
2563
+ "required": false,
2564
+ "doc": "Allow horizontal scrolling instead of just vertical."
2565
+ },
2566
+ {
2567
+ "name": "children",
2568
+ "type": "Snippet",
2569
+ "required": false
2570
+ },
2571
+ {
2572
+ "name": "class",
2573
+ "type": "string",
2574
+ "required": false
2575
+ }
2576
+ ]
2577
+ },
2578
+ {
2579
+ "name": "Select",
2580
+ "category": "form",
2581
+ "import": "@human-synthesis/norns-ui/components/Select.n",
2582
+ "bindability": [
2583
+ "spec-bindable"
2584
+ ],
2585
+ "props": [
2586
+ {
2587
+ "name": "value",
2588
+ "type": "string | number | string[]",
2589
+ "required": false
2590
+ },
2591
+ {
2592
+ "name": "error",
2593
+ "type": "boolean",
2594
+ "required": false
2595
+ },
2596
+ {
2597
+ "name": "class",
2598
+ "type": "string",
2599
+ "required": false
2600
+ },
2601
+ {
2602
+ "name": "children",
2603
+ "type": "Snippet",
2604
+ "required": false,
2605
+ "doc": "`<option>` children. Pass via Pug body."
2606
+ }
2607
+ ],
2608
+ "bindings": {
2609
+ "name": "literal",
2610
+ "value": "literal",
2611
+ "required": "literal",
2612
+ "class": "literal"
2613
+ },
2614
+ "example": {
2615
+ "select": null,
2616
+ "name": "stage"
2617
+ }
2618
+ },
2619
+ {
2620
+ "name": "Separator",
2621
+ "category": "layout",
2622
+ "import": "@human-synthesis/norns-ui/components/Separator.n",
2623
+ "bindability": [
2624
+ "custom-only"
2625
+ ],
2626
+ "props": [
2627
+ {
2628
+ "name": "orientation",
2629
+ "type": "'horizontal' | 'vertical'",
2630
+ "required": false
2631
+ },
2632
+ {
2633
+ "name": "class",
2634
+ "type": "string",
2635
+ "required": false
2636
+ }
2637
+ ]
2638
+ },
2639
+ {
2640
+ "name": "Sheet",
2641
+ "category": "overlay",
2642
+ "import": "@human-synthesis/norns-ui/components/Sheet.n",
2643
+ "bindability": [
2644
+ "custom-only"
2645
+ ],
2646
+ "props": [
2647
+ {
2648
+ "name": "open",
2649
+ "type": "boolean",
2650
+ "required": false
2651
+ },
2652
+ {
2653
+ "name": "side",
2654
+ "type": "SheetSide",
2655
+ "required": false,
2656
+ "doc": "`'left'` was previously the default for the now-removed `<Drawer>`."
2657
+ },
2658
+ {
2659
+ "name": "title",
2660
+ "type": "string",
2661
+ "required": false
2662
+ },
2663
+ {
2664
+ "name": "description",
2665
+ "type": "string",
2666
+ "required": false
2667
+ },
2668
+ {
2669
+ "name": "hideClose",
2670
+ "type": "boolean",
2671
+ "required": false
2672
+ },
2673
+ {
2674
+ "name": "dismissable",
2675
+ "type": "boolean",
2676
+ "required": false
2677
+ },
2678
+ {
2679
+ "name": "ariaLabel",
2680
+ "type": "string",
2681
+ "required": false
2682
+ },
2683
+ {
2684
+ "name": "trigger",
2685
+ "type": "Snippet",
2686
+ "required": false
2687
+ },
2688
+ {
2689
+ "name": "actions",
2690
+ "type": "Snippet",
2691
+ "required": false
2692
+ },
2693
+ {
2694
+ "name": "children",
2695
+ "type": "Snippet",
2696
+ "required": false
2697
+ },
2698
+ {
2699
+ "name": "triggerClass",
2700
+ "type": "string",
2701
+ "required": false
2702
+ },
2703
+ {
2704
+ "name": "overlayClass",
2705
+ "type": "string",
2706
+ "required": false
2707
+ },
2708
+ {
2709
+ "name": "class",
2710
+ "type": "string",
2711
+ "required": false
2712
+ }
2713
+ ]
2714
+ },
2715
+ {
2716
+ "name": "ShinyButton",
2717
+ "category": "action",
2718
+ "import": "@human-synthesis/norns-ui/components/ShinyButton.n",
2719
+ "bindability": [
2720
+ "custom-only"
2721
+ ],
2722
+ "props": [
2723
+ {
2724
+ "name": "variant",
2725
+ "type": "'primary' | 'secondary' | 'ghost' | 'danger' | 'link'",
2726
+ "required": false
2727
+ },
2728
+ {
2729
+ "name": "size",
2730
+ "type": "'sm' | 'md' | 'lg'",
2731
+ "required": false
2732
+ },
2733
+ {
2734
+ "name": "type",
2735
+ "type": "'button' | 'submit' | 'reset'",
2736
+ "required": false
2737
+ },
2738
+ {
2739
+ "name": "disabled",
2740
+ "type": "boolean",
2741
+ "required": false
2742
+ },
2743
+ {
2744
+ "name": "onclick",
2745
+ "type": "(event: MouseEvent) => void",
2746
+ "required": false
2747
+ },
2748
+ {
2749
+ "name": "icon",
2750
+ "type": "string",
2751
+ "required": false
2752
+ },
2753
+ {
2754
+ "name": "children",
2755
+ "type": "Snippet",
2756
+ "required": false
2757
+ },
2758
+ {
2759
+ "name": "class",
2760
+ "type": "string",
2761
+ "required": false
2762
+ }
2763
+ ]
2764
+ },
2765
+ {
2766
+ "name": "Skeleton",
2767
+ "category": "feedback",
2768
+ "import": "@human-synthesis/norns-ui/components/Skeleton.n",
2769
+ "bindability": [
2770
+ "custom-only"
2771
+ ],
2772
+ "props": [
2773
+ {
2774
+ "name": "variant",
2775
+ "type": "SkeletonVariant",
2776
+ "required": false
2777
+ },
2778
+ {
2779
+ "name": "width",
2780
+ "type": "number | string",
2781
+ "required": false
2782
+ },
2783
+ {
2784
+ "name": "height",
2785
+ "type": "number | string",
2786
+ "required": false
2787
+ },
2788
+ {
2789
+ "name": "class",
2790
+ "type": "string",
2791
+ "required": false
2792
+ }
2793
+ ]
2794
+ },
2795
+ {
2796
+ "name": "Spinner",
2797
+ "category": "feedback",
2798
+ "import": "@human-synthesis/norns-ui/components/Spinner.n",
2799
+ "bindability": [
2800
+ "custom-only"
2801
+ ],
2802
+ "props": [
2803
+ {
2804
+ "name": "size",
2805
+ "type": "string",
2806
+ "required": false,
2807
+ "doc": "Tailwind size utility for the spinner glyph."
2808
+ },
2809
+ {
2810
+ "name": "label",
2811
+ "type": "string",
2812
+ "required": false,
2813
+ "doc": "Accessible label announced to screen readers."
2814
+ },
2815
+ {
2816
+ "name": "class",
2817
+ "type": "string",
2818
+ "required": false
2819
+ }
2820
+ ]
2821
+ },
2822
+ {
2823
+ "name": "Stepper",
2824
+ "category": "navigation",
2825
+ "import": "@human-synthesis/norns-ui/components/Stepper.n",
2826
+ "bindability": [
2827
+ "custom-only"
2828
+ ],
2829
+ "props": [
2830
+ {
2831
+ "name": "steps",
2832
+ "type": "StepperStep[]",
2833
+ "required": false
2834
+ },
2835
+ {
2836
+ "name": "current",
2837
+ "type": "number",
2838
+ "required": false,
2839
+ "doc": "Index of the active step. Steps before are auto-marked complete unless overridden."
2840
+ },
2841
+ {
2842
+ "name": "orientation",
2843
+ "type": "'horizontal' | 'vertical'",
2844
+ "required": false
2845
+ },
2846
+ {
2847
+ "name": "class",
2848
+ "type": "string",
2849
+ "required": false
2850
+ }
2851
+ ]
2852
+ },
2853
+ {
2854
+ "name": "StreamText",
2855
+ "category": "realtime",
2856
+ "import": "@human-synthesis/norns-ui/components/StreamText.n",
2857
+ "bindability": [
2858
+ "spec-bindable"
2859
+ ],
2860
+ "props": [
2861
+ {
2862
+ "name": "streamSource",
2863
+ "type": "string",
2864
+ "required": false,
2865
+ "doc": "SSE endpoint URL — a generated Page binds a `stream:` Endpoint here."
2866
+ },
2867
+ {
2868
+ "name": "input",
2869
+ "type": "unknown",
2870
+ "required": false,
2871
+ "doc": "JSON-able request body; the stream opens with POST when set."
2872
+ },
2873
+ {
2874
+ "name": "autostart",
2875
+ "type": "boolean",
2876
+ "required": false,
2877
+ "doc": "Open the stream on mount (default true)."
2878
+ },
2879
+ {
2880
+ "name": "onframe",
2881
+ "type": "(frame: unknown) => void",
2882
+ "required": false,
2883
+ "doc": "Called with each parsed frame as it arrives."
2884
+ },
2885
+ {
2886
+ "name": "ondone",
2887
+ "type": "(text: string) => void",
2888
+ "required": false,
2889
+ "doc": "Called with the full accumulated text when the stream ends."
2890
+ },
2891
+ {
2892
+ "name": "class",
2893
+ "type": "string",
2894
+ "required": false
2895
+ }
2896
+ ],
2897
+ "bindings": {
2898
+ "streamSource": "stream",
2899
+ "autostart": "literal",
2900
+ "class": "literal"
2901
+ },
2902
+ "example": {
2903
+ "streamText": {
2904
+ "stream": "games.Endpoint.chat"
2905
+ }
2906
+ }
2907
+ },
2908
+ {
2909
+ "name": "Surface",
2910
+ "category": "layout",
2911
+ "import": "@human-synthesis/norns-ui/components/Surface.n",
2912
+ "bindability": [
2913
+ "custom-only"
2914
+ ],
2915
+ "props": [
2916
+ {
2917
+ "name": "tone",
2918
+ "type": "'glass'",
2919
+ "required": false
2920
+ },
2921
+ {
2922
+ "name": "children",
2923
+ "type": "Snippet",
2924
+ "required": false
2925
+ },
2926
+ {
2927
+ "name": "class",
2928
+ "type": "string",
2929
+ "required": false
2930
+ }
2931
+ ]
2932
+ },
2933
+ {
2934
+ "name": "Switch",
2935
+ "category": "form",
2936
+ "import": "@human-synthesis/norns-ui/components/Switch.n",
2937
+ "bindability": [
2938
+ "spec-bindable"
2939
+ ],
2940
+ "props": [
2941
+ {
2942
+ "name": "checked",
2943
+ "type": "boolean",
2944
+ "required": false
2945
+ },
2946
+ {
2947
+ "name": "error",
2948
+ "type": "boolean",
2949
+ "required": false
2950
+ },
2951
+ {
2952
+ "name": "class",
2953
+ "type": "string",
2954
+ "required": false
2955
+ }
2956
+ ],
2957
+ "bindings": {
2958
+ "name": "literal",
2959
+ "checked": "literal",
2960
+ "required": "literal",
2961
+ "disabled": "literal",
2962
+ "error": "literal",
2963
+ "class": "literal"
2964
+ },
2965
+ "example": {
2966
+ "switch": null,
2967
+ "name": "active"
2968
+ }
2969
+ },
2970
+ {
2971
+ "name": "Table",
2972
+ "category": "data",
2973
+ "import": "@human-synthesis/norns-ui/components/Table.n",
2974
+ "bindability": [
2975
+ "spec-bindable",
2976
+ "snippet-extensible"
2977
+ ],
2978
+ "props": [
2979
+ {
2980
+ "name": "data",
2981
+ "type": "Record<string, unknown>[]",
2982
+ "required": false,
2983
+ "doc": "Rows to render — typically a generated Query result bound by a Page spec."
2984
+ },
2985
+ {
2986
+ "name": "columns",
2987
+ "type": "string | Array<string | TableColumn>",
2988
+ "required": false
2989
+ },
2990
+ {
2991
+ "name": "pageSize",
2992
+ "type": "number | string",
2993
+ "required": false,
2994
+ "doc": "Client-side page size. 0 disables pagination. Accepts numeric strings."
2995
+ },
2996
+ {
2997
+ "name": "striped",
2998
+ "type": "boolean",
2999
+ "required": false
3000
+ },
3001
+ {
3002
+ "name": "dense",
3003
+ "type": "boolean",
3004
+ "required": false
3005
+ },
3006
+ {
3007
+ "name": "stickyHeader",
3008
+ "type": "boolean",
3009
+ "required": false
3010
+ },
3011
+ {
3012
+ "name": "emptyMessage",
3013
+ "type": "string",
3014
+ "required": false
3015
+ },
3016
+ {
3017
+ "name": "onrowclick",
3018
+ "type": "(row: Record<string, unknown>, index: number) => void",
3019
+ "required": false
3020
+ },
3021
+ {
3022
+ "name": "cell",
3023
+ "type": "Snippet<[Record<string, unknown>, string, unknown]>",
3024
+ "required": false,
3025
+ "doc": "Cell renderer snippet — receives (row, columnKey, value)."
3026
+ },
3027
+ {
3028
+ "name": "empty",
3029
+ "type": "Snippet",
3030
+ "required": false,
3031
+ "doc": "Rendered instead of emptyMessage when there are no rows."
3032
+ },
3033
+ {
3034
+ "name": "class",
3035
+ "type": "string",
3036
+ "required": false
3037
+ }
3038
+ ],
3039
+ "bindings": {
3040
+ "data": "query",
3041
+ "columns": "literal",
3042
+ "pageSize": "literal",
3043
+ "striped": "literal",
3044
+ "dense": "literal",
3045
+ "stickyHeader": "literal",
3046
+ "emptyMessage": "literal",
3047
+ "cell": "snippet",
3048
+ "empty": "snippet",
3049
+ "class": "literal"
3050
+ },
3051
+ "example": {
3052
+ "table": "crm.Query.listDeals",
3053
+ "columns": "name,amount,status",
3054
+ "pageSize": 10
3055
+ },
3056
+ "snippetSlots": {
3057
+ "cell": [
3058
+ "row",
3059
+ "column",
3060
+ "value"
3061
+ ],
3062
+ "empty": []
3063
+ }
3064
+ },
3065
+ {
3066
+ "name": "Tabs",
3067
+ "category": "navigation",
3068
+ "import": "@human-synthesis/norns-ui/components/Tabs.n",
3069
+ "bindability": [
3070
+ "custom-only"
3071
+ ],
3072
+ "props": [
3073
+ {
3074
+ "name": "value",
3075
+ "type": "string",
3076
+ "required": false
3077
+ },
3078
+ {
3079
+ "name": "items",
3080
+ "type": "TabsItem[]",
3081
+ "required": false
3082
+ },
3083
+ {
3084
+ "name": "label",
3085
+ "type": "string",
3086
+ "required": false,
3087
+ "doc": "ARIA label for the tablist. Default 'Tabs'."
3088
+ },
3089
+ {
3090
+ "name": "class",
3091
+ "type": "string",
3092
+ "required": false
3093
+ }
3094
+ ]
3095
+ },
3096
+ {
3097
+ "name": "TagsInput",
3098
+ "category": "form",
3099
+ "import": "@human-synthesis/norns-ui/components/TagsInput.n",
3100
+ "bindability": [
3101
+ "custom-only"
3102
+ ],
3103
+ "props": [
3104
+ {
3105
+ "name": "value",
3106
+ "type": "string[]",
3107
+ "required": false
3108
+ },
3109
+ {
3110
+ "name": "max",
3111
+ "type": "number",
3112
+ "required": false
3113
+ },
3114
+ {
3115
+ "name": "placeholder",
3116
+ "type": "string",
3117
+ "required": false
3118
+ },
3119
+ {
3120
+ "name": "commitOnBlur",
3121
+ "type": "boolean",
3122
+ "required": false
3123
+ },
3124
+ {
3125
+ "name": "separators",
3126
+ "type": "string[]",
3127
+ "required": false
3128
+ },
3129
+ {
3130
+ "name": "disabled",
3131
+ "type": "boolean",
3132
+ "required": false
3133
+ },
3134
+ {
3135
+ "name": "name",
3136
+ "type": "string",
3137
+ "required": false
3138
+ },
3139
+ {
3140
+ "name": "id",
3141
+ "type": "string",
3142
+ "required": false
3143
+ },
3144
+ {
3145
+ "name": "error",
3146
+ "type": "boolean",
3147
+ "required": false
3148
+ },
3149
+ {
3150
+ "name": "class",
3151
+ "type": "string",
3152
+ "required": false
3153
+ }
3154
+ ]
3155
+ },
3156
+ {
3157
+ "name": "Textarea",
3158
+ "category": "form",
3159
+ "import": "@human-synthesis/norns-ui/components/Textarea.n",
3160
+ "bindability": [
3161
+ "spec-bindable"
3162
+ ],
3163
+ "props": [
3164
+ {
3165
+ "name": "value",
3166
+ "type": "string",
3167
+ "required": false
3168
+ },
3169
+ {
3170
+ "name": "rows",
3171
+ "type": "number",
3172
+ "required": false
3173
+ },
3174
+ {
3175
+ "name": "error",
3176
+ "type": "boolean",
3177
+ "required": false
3178
+ },
3179
+ {
3180
+ "name": "class",
3181
+ "type": "string",
3182
+ "required": false
3183
+ }
3184
+ ],
3185
+ "bindings": {
3186
+ "name": "literal",
3187
+ "value": "literal",
3188
+ "placeholder": "literal",
3189
+ "rows": "literal",
3190
+ "required": "literal",
3191
+ "disabled": "literal",
3192
+ "error": "literal",
3193
+ "class": "literal"
3194
+ },
3195
+ "example": {
3196
+ "textarea": null,
3197
+ "name": "notes",
3198
+ "rows": 4
3199
+ }
3200
+ },
3201
+ {
3202
+ "name": "ThemeToggler",
3203
+ "category": "action",
3204
+ "import": "@human-synthesis/norns-ui/components/ThemeToggler.n",
3205
+ "bindability": [
3206
+ "custom-only"
3207
+ ],
3208
+ "props": [
3209
+ {
3210
+ "name": "variant",
3211
+ "type": "'primary' | 'secondary' | 'ghost' | 'danger' | 'link'",
3212
+ "required": false
3213
+ },
3214
+ {
3215
+ "name": "size",
3216
+ "type": "'sm' | 'md' | 'lg'",
3217
+ "required": false
3218
+ },
3219
+ {
3220
+ "name": "showLabel",
3221
+ "type": "boolean",
3222
+ "required": false
3223
+ },
3224
+ {
3225
+ "name": "labelLight",
3226
+ "type": "string",
3227
+ "required": false
3228
+ },
3229
+ {
3230
+ "name": "labelDark",
3231
+ "type": "string",
3232
+ "required": false
3233
+ },
3234
+ {
3235
+ "name": "lightIcon",
3236
+ "type": "string",
3237
+ "required": false
3238
+ },
3239
+ {
3240
+ "name": "darkIcon",
3241
+ "type": "string",
3242
+ "required": false
3243
+ },
3244
+ {
3245
+ "name": "storageKey",
3246
+ "type": "string",
3247
+ "required": false,
3248
+ "doc": "localStorage key. Default `'norns-theme'`."
3249
+ },
3250
+ {
3251
+ "name": "class",
3252
+ "type": "string",
3253
+ "required": false
3254
+ }
3255
+ ]
3256
+ },
3257
+ {
3258
+ "name": "TimePicker",
3259
+ "category": "form",
3260
+ "import": "@human-synthesis/norns-ui/components/TimePicker.n",
3261
+ "bindability": [
3262
+ "custom-only"
3263
+ ],
3264
+ "props": [
3265
+ {
3266
+ "name": "value",
3267
+ "type": "string",
3268
+ "required": false,
3269
+ "doc": "Time string `HH:MM` (24h regardless of display `hourCycle`). Bindable."
3270
+ },
3271
+ {
3272
+ "name": "open",
3273
+ "type": "boolean",
3274
+ "required": false
3275
+ },
3276
+ {
3277
+ "name": "minuteStep",
3278
+ "type": "number",
3279
+ "required": false,
3280
+ "doc": "Minute increment in the picker (5, 10, 15, 30). Default 5."
3281
+ },
3282
+ {
3283
+ "name": "hourCycle",
3284
+ "type": "12 | 24",
3285
+ "required": false
3286
+ },
3287
+ {
3288
+ "name": "placeholder",
3289
+ "type": "string",
3290
+ "required": false
3291
+ },
3292
+ {
3293
+ "name": "disabled",
3294
+ "type": "boolean",
3295
+ "required": false
3296
+ },
3297
+ {
3298
+ "name": "label",
3299
+ "type": "string",
3300
+ "required": false
3301
+ },
3302
+ {
3303
+ "name": "name",
3304
+ "type": "string",
3305
+ "required": false
3306
+ },
3307
+ {
3308
+ "name": "id",
3309
+ "type": "string",
3310
+ "required": false
3311
+ },
3312
+ {
3313
+ "name": "error",
3314
+ "type": "boolean",
3315
+ "required": false
3316
+ },
3317
+ {
3318
+ "name": "class",
3319
+ "type": "string",
3320
+ "required": false
3321
+ }
3322
+ ]
3323
+ },
3324
+ {
3325
+ "name": "Timeline",
3326
+ "category": "data",
3327
+ "import": "@human-synthesis/norns-ui/components/Timeline.n",
3328
+ "bindability": [
3329
+ "spec-bindable"
3330
+ ],
3331
+ "props": [
3332
+ {
3333
+ "name": "items",
3334
+ "type": "TimelineItem[]",
3335
+ "required": false
3336
+ },
3337
+ {
3338
+ "name": "data",
3339
+ "type": "TimelineItem[]",
3340
+ "required": false,
3341
+ "doc": "Alias for `items` — the prop a generated Page binds a Query result to."
3342
+ },
3343
+ {
3344
+ "name": "class",
3345
+ "type": "string",
3346
+ "required": false
3347
+ }
3348
+ ],
3349
+ "bindings": {
3350
+ "data": "query",
3351
+ "class": "literal"
3352
+ },
3353
+ "example": {
3354
+ "timeline": "crm.Query.history"
3355
+ }
3356
+ },
3357
+ {
3358
+ "name": "ToastProvider",
3359
+ "category": "feedback",
3360
+ "import": "@human-synthesis/norns-ui/components/ToastProvider.n",
3361
+ "bindability": [
3362
+ "custom-only"
3363
+ ],
3364
+ "props": [
3365
+ {
3366
+ "name": "class",
3367
+ "type": "string",
3368
+ "required": false
3369
+ }
3370
+ ]
3371
+ },
3372
+ {
3373
+ "name": "ToggleButton",
3374
+ "category": "form",
3375
+ "import": "@human-synthesis/norns-ui/components/ToggleButton.n",
3376
+ "bindability": [
3377
+ "custom-only"
3378
+ ],
3379
+ "props": [
3380
+ {
3381
+ "name": "pressed",
3382
+ "type": "boolean",
3383
+ "required": false
3384
+ },
3385
+ {
3386
+ "name": "disabled",
3387
+ "type": "boolean",
3388
+ "required": false
3389
+ },
3390
+ {
3391
+ "name": "icon",
3392
+ "type": "string",
3393
+ "required": false
3394
+ },
3395
+ {
3396
+ "name": "variant",
3397
+ "type": "'primary' | 'secondary' | 'ghost' | 'danger' | 'link'",
3398
+ "required": false,
3399
+ "doc": "Any `.btn-*` variant. The toggle visual state is controlled by `data-pressed`."
3400
+ },
3401
+ {
3402
+ "name": "size",
3403
+ "type": "'sm' | 'md' | 'lg'",
3404
+ "required": false
3405
+ },
3406
+ {
3407
+ "name": "onpressedchange",
3408
+ "type": "(pressed: boolean) => void",
3409
+ "required": false
3410
+ },
3411
+ {
3412
+ "name": "children",
3413
+ "type": "Snippet",
3414
+ "required": false
3415
+ },
3416
+ {
3417
+ "name": "class",
3418
+ "type": "string",
3419
+ "required": false
3420
+ }
3421
+ ]
3422
+ },
3423
+ {
3424
+ "name": "ToggleButtonGroup",
3425
+ "category": "form",
3426
+ "import": "@human-synthesis/norns-ui/components/ToggleButtonGroup.n",
3427
+ "bindability": [
3428
+ "custom-only"
3429
+ ],
3430
+ "props": [
3431
+ {
3432
+ "name": "items",
3433
+ "type": "ToggleGroupItem[]",
3434
+ "required": false
3435
+ },
3436
+ {
3437
+ "name": "value",
3438
+ "type": "string | string[] | undefined",
3439
+ "required": false
3440
+ },
3441
+ {
3442
+ "name": "multiple",
3443
+ "type": "boolean",
3444
+ "required": false
3445
+ },
3446
+ {
3447
+ "name": "disabled",
3448
+ "type": "boolean",
3449
+ "required": false
3450
+ },
3451
+ {
3452
+ "name": "label",
3453
+ "type": "string",
3454
+ "required": false
3455
+ },
3456
+ {
3457
+ "name": "class",
3458
+ "type": "string",
3459
+ "required": false
3460
+ }
3461
+ ]
3462
+ },
3463
+ {
3464
+ "name": "Toolbar",
3465
+ "category": "navigation",
3466
+ "import": "@human-synthesis/norns-ui/components/Toolbar.n",
3467
+ "bindability": [
3468
+ "custom-only"
3469
+ ],
3470
+ "props": [
3471
+ {
3472
+ "name": "orientation",
3473
+ "type": "'horizontal' | 'vertical'",
3474
+ "required": false
3475
+ },
3476
+ {
3477
+ "name": "label",
3478
+ "type": "string",
3479
+ "required": false,
3480
+ "doc": "Accessible label, used as aria-label."
3481
+ },
3482
+ {
3483
+ "name": "children",
3484
+ "type": "Snippet",
3485
+ "required": false
3486
+ },
3487
+ {
3488
+ "name": "class",
3489
+ "type": "string",
3490
+ "required": false
3491
+ }
3492
+ ]
3493
+ },
3494
+ {
3495
+ "name": "Tooltip",
3496
+ "category": "overlay",
3497
+ "import": "@human-synthesis/norns-ui/components/Tooltip.n",
3498
+ "bindability": [
3499
+ "custom-only"
3500
+ ],
3501
+ "props": [
3502
+ {
3503
+ "name": "content",
3504
+ "type": "string",
3505
+ "required": false
3506
+ },
3507
+ {
3508
+ "name": "side",
3509
+ "type": "'top' | 'right' | 'bottom' | 'left'",
3510
+ "required": false
3511
+ },
3512
+ {
3513
+ "name": "align",
3514
+ "type": "'start' | 'center' | 'end'",
3515
+ "required": false
3516
+ },
3517
+ {
3518
+ "name": "sideOffset",
3519
+ "type": "number",
3520
+ "required": false
3521
+ },
3522
+ {
3523
+ "name": "delay",
3524
+ "type": "number",
3525
+ "required": false
3526
+ },
3527
+ {
3528
+ "name": "rich",
3529
+ "type": "boolean",
3530
+ "required": false,
3531
+ "doc": "Wider, surface-elevated styling for tooltips with markup/multiline content."
3532
+ },
3533
+ {
3534
+ "name": "trigger",
3535
+ "type": "Snippet",
3536
+ "required": false
3537
+ },
3538
+ {
3539
+ "name": "children",
3540
+ "type": "Snippet",
3541
+ "required": false
3542
+ },
3543
+ {
3544
+ "name": "triggerClass",
3545
+ "type": "string",
3546
+ "required": false
3547
+ },
3548
+ {
3549
+ "name": "class",
3550
+ "type": "string",
3551
+ "required": false
3552
+ }
3553
+ ]
3554
+ },
3555
+ {
3556
+ "name": "Tree",
3557
+ "category": "data",
3558
+ "import": "@human-synthesis/norns-ui/components/Tree.n",
3559
+ "bindability": [
3560
+ "spec-bindable"
3561
+ ],
3562
+ "props": [
3563
+ {
3564
+ "name": "items",
3565
+ "type": "TreeNode[]",
3566
+ "required": false
3567
+ },
3568
+ {
3569
+ "name": "data",
3570
+ "type": "TreeNode[]",
3571
+ "required": false,
3572
+ "doc": "Alias for `items` — the prop a generated Page binds a Query result to."
3573
+ },
3574
+ {
3575
+ "name": "expanded",
3576
+ "type": "(string | number)[]",
3577
+ "required": false,
3578
+ "doc": "Array of node ids that are expanded. Bindable."
3579
+ },
3580
+ {
3581
+ "name": "selected",
3582
+ "type": "string | number",
3583
+ "required": false,
3584
+ "doc": "Currently-selected node id. Bindable."
3585
+ },
3586
+ {
3587
+ "name": "class",
3588
+ "type": "string",
3589
+ "required": false
3590
+ }
3591
+ ],
3592
+ "bindings": {
3593
+ "data": "query",
3594
+ "class": "literal"
3595
+ },
3596
+ "example": {
3597
+ "tree": "crm.Query.folders"
3598
+ }
3599
+ },
3600
+ {
3601
+ "name": "Uploader",
3602
+ "category": "form",
3603
+ "import": "@human-synthesis/norns-ui/components/Uploader.n",
3604
+ "bindability": [
3605
+ "spec-bindable"
3606
+ ],
3607
+ "props": [
3608
+ {
3609
+ "name": "files",
3610
+ "type": "File[]",
3611
+ "required": false
3612
+ },
3613
+ {
3614
+ "name": "multiple",
3615
+ "type": "boolean",
3616
+ "required": false
3617
+ },
3618
+ {
3619
+ "name": "accept",
3620
+ "type": "string",
3621
+ "required": false
3622
+ },
3623
+ {
3624
+ "name": "disabled",
3625
+ "type": "boolean",
3626
+ "required": false
3627
+ },
3628
+ {
3629
+ "name": "placeholder",
3630
+ "type": "string",
3631
+ "required": false
3632
+ },
3633
+ {
3634
+ "name": "helper",
3635
+ "type": "string",
3636
+ "required": false
3637
+ },
3638
+ {
3639
+ "name": "onchange",
3640
+ "type": "(files: File[]) => void",
3641
+ "required": false
3642
+ },
3643
+ {
3644
+ "name": "class",
3645
+ "type": "string",
3646
+ "required": false
3647
+ }
3648
+ ],
3649
+ "bindings": {
3650
+ "multiple": "literal",
3651
+ "accept": "literal",
3652
+ "disabled": "literal",
3653
+ "placeholder": "literal",
3654
+ "helper": "literal",
3655
+ "class": "literal"
3656
+ },
3657
+ "example": {
3658
+ "uploader": null,
3659
+ "accept": "image/*",
3660
+ "multiple": true
3661
+ }
3662
+ },
3663
+ {
3664
+ "name": "Video",
3665
+ "category": "media",
3666
+ "import": "@human-synthesis/norns-ui/components/Video.n",
3667
+ "bindability": [
3668
+ "custom-only"
3669
+ ],
3670
+ "props": [
3671
+ {
3672
+ "name": "src",
3673
+ "type": "string",
3674
+ "required": false
3675
+ },
3676
+ {
3677
+ "name": "sources",
3678
+ "type": "VideoSource[]",
3679
+ "required": false
3680
+ },
3681
+ {
3682
+ "name": "controls",
3683
+ "type": "boolean",
3684
+ "required": false
3685
+ },
3686
+ {
3687
+ "name": "autoplay",
3688
+ "type": "boolean",
3689
+ "required": false
3690
+ },
3691
+ {
3692
+ "name": "loop",
3693
+ "type": "boolean",
3694
+ "required": false
3695
+ },
3696
+ {
3697
+ "name": "muted",
3698
+ "type": "boolean",
3699
+ "required": false
3700
+ },
3701
+ {
3702
+ "name": "playsinline",
3703
+ "type": "boolean",
3704
+ "required": false
3705
+ },
3706
+ {
3707
+ "name": "preload",
3708
+ "type": "'none' | 'metadata' | 'auto'",
3709
+ "required": false
3710
+ },
3711
+ {
3712
+ "name": "poster",
3713
+ "type": "string",
3714
+ "required": false
3715
+ },
3716
+ {
3717
+ "name": "fallback",
3718
+ "type": "string",
3719
+ "required": false
3720
+ },
3721
+ {
3722
+ "name": "class",
3723
+ "type": "string",
3724
+ "required": false
3725
+ }
3726
+ ]
3727
+ },
3728
+ {
3729
+ "name": "Window",
3730
+ "category": "overlay",
3731
+ "import": "@human-synthesis/norns-ui/components/Window.n",
3732
+ "bindability": [
3733
+ "custom-only"
3734
+ ],
3735
+ "props": [
3736
+ {
3737
+ "name": "title",
3738
+ "type": "string",
3739
+ "required": false
3740
+ },
3741
+ {
3742
+ "name": "hideHeader",
3743
+ "type": "boolean",
3744
+ "required": false
3745
+ },
3746
+ {
3747
+ "name": "onClose",
3748
+ "type": "(event: MouseEvent) => void",
3749
+ "required": false,
3750
+ "doc": "Renders the header close button when supplied."
3751
+ },
3752
+ {
3753
+ "name": "onHeaderDoubleClick",
3754
+ "type": "(event: MouseEvent) => void",
3755
+ "required": false
3756
+ },
3757
+ {
3758
+ "name": "actions",
3759
+ "type": "Snippet",
3760
+ "required": false,
3761
+ "doc": "Extra header actions, rendered before the close button."
3762
+ },
3763
+ {
3764
+ "name": "children",
3765
+ "type": "Snippet",
3766
+ "required": false
3767
+ },
3768
+ {
3769
+ "name": "class",
3770
+ "type": "string",
3771
+ "required": false
3772
+ },
3773
+ {
3774
+ "name": "bodyClass",
3775
+ "type": "string",
3776
+ "required": false
3777
+ }
3778
+ ]
3779
+ }
3780
+ ],
3781
+ "motion": [
3782
+ {
3783
+ "name": "AnimatedNumber",
3784
+ "category": "motion",
3785
+ "import": "@human-synthesis/norns-ui/motion/AnimatedNumber.n",
3786
+ "bindability": [
3787
+ "custom-only"
3788
+ ],
3789
+ "props": [
3790
+ {
3791
+ "name": "value",
3792
+ "type": "number",
3793
+ "required": true
3794
+ },
3795
+ {
3796
+ "name": "from",
3797
+ "type": "number",
3798
+ "required": false
3799
+ },
3800
+ {
3801
+ "name": "duration",
3802
+ "type": "number",
3803
+ "required": false,
3804
+ "doc": "Duration in seconds."
3805
+ },
3806
+ {
3807
+ "name": "decimals",
3808
+ "type": "number",
3809
+ "required": false
3810
+ },
3811
+ {
3812
+ "name": "format",
3813
+ "type": "(n: number) => string",
3814
+ "required": false,
3815
+ "doc": "Custom number-to-string formatter."
3816
+ },
3817
+ {
3818
+ "name": "class",
3819
+ "type": "string",
3820
+ "required": false
3821
+ }
3822
+ ]
3823
+ },
3824
+ {
3825
+ "name": "GradientBackground",
3826
+ "category": "motion",
3827
+ "import": "@human-synthesis/norns-ui/motion/GradientBackground.n",
3828
+ "bindability": [
3829
+ "custom-only"
3830
+ ],
3831
+ "props": [
3832
+ {
3833
+ "name": "colors",
3834
+ "type": "string[]",
3835
+ "required": false
3836
+ },
3837
+ {
3838
+ "name": "duration",
3839
+ "type": "number",
3840
+ "required": false,
3841
+ "doc": "Loop duration in seconds. Default 18."
3842
+ },
3843
+ {
3844
+ "name": "angle",
3845
+ "type": "number",
3846
+ "required": false,
3847
+ "doc": "Gradient angle. Default 130."
3848
+ },
3849
+ {
3850
+ "name": "children",
3851
+ "type": "Snippet",
3852
+ "required": false
3853
+ },
3854
+ {
3855
+ "name": "class",
3856
+ "type": "string",
3857
+ "required": false
3858
+ }
3859
+ ]
3860
+ },
3861
+ {
3862
+ "name": "LiquidButton",
3863
+ "category": "motion",
3864
+ "import": "@human-synthesis/norns-ui/motion/LiquidButton.n",
3865
+ "bindability": [
3866
+ "custom-only"
3867
+ ],
3868
+ "props": [
3869
+ {
3870
+ "name": "variant",
3871
+ "type": "'primary' | 'secondary' | 'ghost' | 'danger' | 'link'",
3872
+ "required": false
3873
+ },
3874
+ {
3875
+ "name": "size",
3876
+ "type": "'sm' | 'md' | 'lg'",
3877
+ "required": false
3878
+ },
3879
+ {
3880
+ "name": "type",
3881
+ "type": "'button' | 'submit' | 'reset'",
3882
+ "required": false
3883
+ },
3884
+ {
3885
+ "name": "disabled",
3886
+ "type": "boolean",
3887
+ "required": false
3888
+ },
3889
+ {
3890
+ "name": "onclick",
3891
+ "type": "(event: MouseEvent) => void",
3892
+ "required": false
3893
+ },
3894
+ {
3895
+ "name": "icon",
3896
+ "type": "string",
3897
+ "required": false
3898
+ },
3899
+ {
3900
+ "name": "children",
3901
+ "type": "Snippet",
3902
+ "required": false
3903
+ },
3904
+ {
3905
+ "name": "class",
3906
+ "type": "string",
3907
+ "required": false
3908
+ }
3909
+ ]
3910
+ },
3911
+ {
3912
+ "name": "Reveal",
3913
+ "category": "motion",
3914
+ "import": "@human-synthesis/norns-ui/motion/Reveal.n",
3915
+ "bindability": [
3916
+ "custom-only"
3917
+ ],
3918
+ "props": [
3919
+ {
3920
+ "name": "direction",
3921
+ "type": "'up' | 'down' | 'left' | 'right'",
3922
+ "required": false
3923
+ },
3924
+ {
3925
+ "name": "distance",
3926
+ "type": "number",
3927
+ "required": false,
3928
+ "doc": "Travel distance in pixels. Default 12."
3929
+ },
3930
+ {
3931
+ "name": "duration",
3932
+ "type": "number",
3933
+ "required": false,
3934
+ "doc": "Animation duration in seconds. Default 0.5."
3935
+ },
3936
+ {
3937
+ "name": "delay",
3938
+ "type": "number",
3939
+ "required": false,
3940
+ "doc": "Delay before animating, seconds. Default 0."
3941
+ },
3942
+ {
3943
+ "name": "once",
3944
+ "type": "boolean",
3945
+ "required": false,
3946
+ "doc": "Re-trigger on every entry (false) or just the first time (true). Default true."
3947
+ },
3948
+ {
3949
+ "name": "threshold",
3950
+ "type": "number",
3951
+ "required": false,
3952
+ "doc": "IntersectionObserver threshold (0–1). Default 0.15."
3953
+ },
3954
+ {
3955
+ "name": "children",
3956
+ "type": "Snippet",
3957
+ "required": false
3958
+ },
3959
+ {
3960
+ "name": "class",
3961
+ "type": "string",
3962
+ "required": false
3963
+ }
3964
+ ]
3965
+ },
3966
+ {
3967
+ "name": "Sparkles",
3968
+ "category": "motion",
3969
+ "import": "@human-synthesis/norns-ui/motion/Sparkles.n",
3970
+ "bindability": [
3971
+ "custom-only"
3972
+ ],
3973
+ "props": [
3974
+ {
3975
+ "name": "density",
3976
+ "type": "number",
3977
+ "required": false
3978
+ },
3979
+ {
3980
+ "name": "colors",
3981
+ "type": "string[]",
3982
+ "required": false
3983
+ },
3984
+ {
3985
+ "name": "minSize",
3986
+ "type": "number",
3987
+ "required": false
3988
+ },
3989
+ {
3990
+ "name": "maxSize",
3991
+ "type": "number",
3992
+ "required": false
3993
+ },
3994
+ {
3995
+ "name": "children",
3996
+ "type": "Snippet",
3997
+ "required": false
3998
+ },
3999
+ {
4000
+ "name": "class",
4001
+ "type": "string",
4002
+ "required": false
4003
+ }
4004
+ ]
4005
+ }
4006
+ ],
4007
+ "behaviors": [
4008
+ {
4009
+ "name": "portal",
4010
+ "description": "Render the node into document.body so overlays escape stacking contexts.",
4011
+ "import": "@human-synthesis/norns-ui/behaviors"
4012
+ },
4013
+ {
4014
+ "name": "clickOutside",
4015
+ "description": "Invoke a callback when a pointer event lands outside the node.",
4016
+ "import": "@human-synthesis/norns-ui/behaviors"
4017
+ },
4018
+ {
4019
+ "name": "escape",
4020
+ "description": "Invoke a callback on Escape keydown while the node is mounted.",
4021
+ "import": "@human-synthesis/norns-ui/behaviors"
4022
+ },
4023
+ {
4024
+ "name": "focusTrap",
4025
+ "description": "Keep Tab focus cycling inside the node (dialogs, sheets).",
4026
+ "import": "@human-synthesis/norns-ui/behaviors"
4027
+ },
4028
+ {
4029
+ "name": "scrollLock",
4030
+ "description": "Lock body scroll while mounted (reference-counted acquire/release).",
4031
+ "import": "@human-synthesis/norns-ui/behaviors"
4032
+ },
4033
+ {
4034
+ "name": "useFloating",
4035
+ "description": "Anchor-position a floating element against a reference (@floating-ui).",
4036
+ "import": "@human-synthesis/norns-ui/behaviors"
4037
+ },
4038
+ {
4039
+ "name": "positionAt",
4040
+ "description": "One-shot floating position calculation for a coordinate anchor.",
4041
+ "import": "@human-synthesis/norns-ui/behaviors"
4042
+ },
4043
+ {
4044
+ "name": "rovingTabindex",
4045
+ "description": "Arrow-key roving focus for composite widgets (menus, listboxes).",
4046
+ "import": "@human-synthesis/norns-ui/behaviors"
4047
+ },
4048
+ {
4049
+ "name": "optimisticOverlay",
4050
+ "description": "Client-side id → value overlay that shadows server truth until reload (instant drag-drop, toggles).",
4051
+ "import": "@human-synthesis/norns-ui/behaviors"
4052
+ }
4053
+ ],
4054
+ "tokens": {
4055
+ "source": "@human-synthesis/norns-ui/styles/tokens",
4056
+ "vars": {
4057
+ "--color-primary-50": "oklch(97.7% 0.014 308.3)",
4058
+ "--color-primary-100": "oklch(94.6% 0.033 307.2)",
4059
+ "--color-primary-200": "oklch(90.2% 0.063 306.7)",
4060
+ "--color-primary-300": "oklch(81.1% 0.111 293.6)",
4061
+ "--color-primary-400": "oklch(70.2% 0.183 293.5)",
4062
+ "--color-primary-500": "oklch(60.6% 0.25 292.7)",
4063
+ "--color-primary-600": "oklch(54.1% 0.281 293)",
4064
+ "--color-primary-700": "oklch(49.1% 0.27 292.6)",
4065
+ "--color-primary-800": "oklch(43.2% 0.232 292.8)",
4066
+ "--color-primary-900": "oklch(38% 0.189 293.7)",
4067
+ "--color-primary-950": "oklch(28.3% 0.141 291.1)",
4068
+ "--color-success-50": "oklch(98.2% 0.018 155.8)",
4069
+ "--color-success-100": "oklch(96.2% 0.044 156.7)",
4070
+ "--color-success-200": "oklch(92.5% 0.084 155.9)",
4071
+ "--color-success-300": "oklch(87.1% 0.15 154.4)",
4072
+ "--color-success-400": "oklch(79.2% 0.209 151.7)",
4073
+ "--color-success-500": "oklch(72.3% 0.219 149.6)",
4074
+ "--color-success-600": "oklch(62.7% 0.194 149.2)",
4075
+ "--color-success-700": "oklch(52.7% 0.155 150.1)",
4076
+ "--color-success-800": "oklch(44.8% 0.119 151.3)",
4077
+ "--color-success-900": "oklch(39.3% 0.095 152.5)",
4078
+ "--color-success-950": "oklch(26.6% 0.065 152.9)",
4079
+ "--color-warning-50": "oklch(98.7% 0.022 95.3)",
4080
+ "--color-warning-100": "oklch(96.2% 0.06 95.6)",
4081
+ "--color-warning-200": "oklch(92.4% 0.12 95.7)",
4082
+ "--color-warning-300": "oklch(87.9% 0.169 91.6)",
4083
+ "--color-warning-400": "oklch(82.8% 0.189 84.4)",
4084
+ "--color-warning-500": "oklch(76.9% 0.188 70.1)",
4085
+ "--color-warning-600": "oklch(66.6% 0.179 58.3)",
4086
+ "--color-warning-700": "oklch(55.5% 0.163 48.9)",
4087
+ "--color-warning-800": "oklch(47.3% 0.137 46.2)",
4088
+ "--color-warning-900": "oklch(41.4% 0.112 45.9)",
4089
+ "--color-warning-950": "oklch(27.9% 0.077 45.6)",
4090
+ "--color-danger-50": "oklch(97.1% 0.013 17.4)",
4091
+ "--color-danger-100": "oklch(93.6% 0.032 17.7)",
4092
+ "--color-danger-200": "oklch(88.5% 0.062 18.3)",
4093
+ "--color-danger-300": "oklch(80.8% 0.114 19.6)",
4094
+ "--color-danger-400": "oklch(70.4% 0.191 22.2)",
4095
+ "--color-danger-500": "oklch(63.7% 0.237 25.3)",
4096
+ "--color-danger-600": "oklch(57.7% 0.245 27.3)",
4097
+ "--color-danger-700": "oklch(50.5% 0.213 27.5)",
4098
+ "--color-danger-800": "oklch(44.4% 0.177 26.9)",
4099
+ "--color-danger-900": "oklch(39.6% 0.141 25.7)",
4100
+ "--color-danger-950": "oklch(25.8% 0.092 26)",
4101
+ "--color-info-50": "oklch(97.7% 0.013 236.6)",
4102
+ "--color-info-100": "oklch(95.1% 0.026 236.8)",
4103
+ "--color-info-200": "oklch(90.1% 0.058 230.9)",
4104
+ "--color-info-300": "oklch(82.8% 0.111 230.3)",
4105
+ "--color-info-400": "oklch(74.6% 0.16 232.7)",
4106
+ "--color-info-500": "oklch(68.5% 0.169 237.3)",
4107
+ "--color-info-600": "oklch(58.8% 0.158 241.5)",
4108
+ "--color-info-700": "oklch(50% 0.134 242.7)",
4109
+ "--color-info-800": "oklch(44.3% 0.11 240.8)",
4110
+ "--color-info-900": "oklch(39.1% 0.09 240.9)",
4111
+ "--color-info-950": "oklch(29.3% 0.066 243.2)",
4112
+ "--color-fg": "oklch(20.4% 0 0)",
4113
+ "--color-fg-muted": "oklch(43.9% 0 0)",
4114
+ "--color-fg-subtle": "oklch(56.6% 0 0)",
4115
+ "--color-fg-on-primary": "white",
4116
+ "--color-bg": "white",
4117
+ "--color-bg-muted": "oklch(96.7% 0 0)",
4118
+ "--color-bg-subtle": "oklch(98.5% 0 0)",
4119
+ "--color-bg-elevated": "white",
4120
+ "--color-bg-inverse": "oklch(20.4% 0 0)",
4121
+ "--color-border": "oklch(92.2% 0 0)",
4122
+ "--color-border-strong": "oklch(86.9% 0 0)",
4123
+ "--color-ring": "var(--color-primary-500)",
4124
+ "--color-success-bg": "var(--color-success-50)",
4125
+ "--color-success-fg": "var(--color-success-900)",
4126
+ "--color-success-border": "var(--color-success-200)",
4127
+ "--color-warning-bg": "var(--color-warning-50)",
4128
+ "--color-warning-fg": "var(--color-warning-900)",
4129
+ "--color-warning-border": "var(--color-warning-200)",
4130
+ "--color-danger-bg": "var(--color-danger-50)",
4131
+ "--color-danger-fg": "var(--color-danger-900)",
4132
+ "--color-danger-border": "var(--color-danger-200)",
4133
+ "--color-info-bg": "var(--color-info-50)",
4134
+ "--color-info-fg": "var(--color-info-900)",
4135
+ "--color-info-border": "var(--color-info-200)",
4136
+ "--font-sans": "'Outfit Variable', 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n\t\t'Helvetica Neue', Arial, sans-serif",
4137
+ "--font-mono": "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono',\n\t\t'Courier New', monospace",
4138
+ "--ui-radius-sm": "0.25rem",
4139
+ "--ui-radius": "0.5rem",
4140
+ "--ui-radius-lg": "0.75rem",
4141
+ "--ui-radius-full": "9999px",
4142
+ "--ui-h-sm": "1.75rem",
4143
+ "--ui-h-md": "2.25rem",
4144
+ "--ui-h-lg": "2.75rem",
4145
+ "--ui-icon-btn-sm": "1.5rem",
4146
+ "--ui-icon-btn-md": "1.75rem",
4147
+ "--ui-icon-btn-lg": "2.25rem",
4148
+ "--ui-motion-fast": "150ms",
4149
+ "--ui-motion-med": "200ms",
4150
+ "--ui-motion-slow": "300ms",
4151
+ "--ui-motion-ease": "cubic-bezier(0.2, 0, 0, 1)",
4152
+ "--ui-elev-1": "0 1px 2px oklch(0% 0 0 / 0.06), 0 1px 3px oklch(0% 0 0 / 0.04)",
4153
+ "--ui-elev-2": "0 4px 12px -2px oklch(0% 0 0 / 0.08), 0 2px 4px -1px oklch(0% 0 0 / 0.04)",
4154
+ "--ui-elev-3": "0 16px 32px -8px oklch(0% 0 0 / 0.18), 0 4px 8px -4px oklch(0% 0 0 / 0.06)",
4155
+ "--ui-focus-ring": "0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-ring)"
4156
+ },
4157
+ "dark": {
4158
+ "--color-fg": "oklch(98.5% 0 0)",
4159
+ "--color-fg-muted": "oklch(70.8% 0 0)",
4160
+ "--color-fg-subtle": "oklch(56.6% 0 0)",
4161
+ "--color-fg-on-primary": "white",
4162
+ "--color-bg": "oklch(14.5% 0 0)",
4163
+ "--color-bg-muted": "oklch(20.4% 0 0)",
4164
+ "--color-bg-subtle": "oklch(17.5% 0 0)",
4165
+ "--color-bg-elevated": "oklch(23.5% 0 0)",
4166
+ "--color-bg-inverse": "oklch(98.5% 0 0)",
4167
+ "--color-border": "oklch(27.5% 0 0)",
4168
+ "--color-border-strong": "oklch(37.1% 0 0)",
4169
+ "--color-ring": "var(--color-primary-400)",
4170
+ "--ui-elev-1": "0 1px 2px oklch(0% 0 0 / 0.4)",
4171
+ "--ui-elev-2": "0 4px 12px -2px oklch(0% 0 0 / 0.5), 0 2px 4px -1px oklch(0% 0 0 / 0.3)",
4172
+ "--ui-elev-3": "0 16px 32px -8px oklch(0% 0 0 / 0.6), 0 4px 8px -4px oklch(0% 0 0 / 0.4)",
4173
+ "--ui-focus-ring": "0 0 0 2px var(--color-bg-elevated), 0 0 0 4px var(--color-ring)",
4174
+ "--color-success-bg": "oklch(28% 0.05 152)",
4175
+ "--color-success-fg": "var(--color-success-200)",
4176
+ "--color-success-border": "oklch(38% 0.08 151)",
4177
+ "--color-warning-bg": "oklch(28% 0.05 65)",
4178
+ "--color-warning-fg": "var(--color-warning-200)",
4179
+ "--color-warning-border": "oklch(38% 0.08 60)",
4180
+ "--color-danger-bg": "oklch(28% 0.07 27)",
4181
+ "--color-danger-fg": "var(--color-danger-200)",
4182
+ "--color-danger-border": "oklch(38% 0.11 27)",
4183
+ "--color-info-bg": "oklch(28% 0.05 240)",
4184
+ "--color-info-fg": "var(--color-info-200)",
4185
+ "--color-info-border": "oklch(38% 0.08 240)"
4186
+ }
4187
+ }
4188
+ }