@loworbitstudio/visor 1.30.0 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "0.4.0",
3
- "generated_at": "2026-10-03T18:10:41.404Z",
3
+ "generated_at": "2026-10-04T04:36:38.216Z",
4
4
  "components": {
5
5
  "accessibility-specimen": {
6
6
  "category": "specimen",
@@ -146,6 +146,115 @@
146
146
  ],
147
147
  "example": "<Accordion type=\"single\" collapsible>\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>Is it accessible?</AccordionTrigger>\n <AccordionContent>\n Yes. It adheres to the WAI-ARIA Accordion pattern.\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-2\">\n <AccordionTrigger>Is it animated?</AccordionTrigger>\n <AccordionContent>\n Yes. It uses CSS animations for smooth expand/collapse.\n </AccordionContent>\n </AccordionItem>\n</Accordion>\n"
148
148
  },
149
+ "action-row": {
150
+ "category": "data-display",
151
+ "description": "One tappable list row — a button or link with a leading icon, a title, an optional second line and a trailing value, badge or caret.",
152
+ "when_to_use": [
153
+ "A settings or detail list where each row opens something (a picker, a screen, a map, a billing page)",
154
+ "A row that reads a value on the right and a verb or caret (\"3 suggested · Review\", \"Address ›\")",
155
+ "A person or invitation row whose whole surface is the target",
156
+ "Any list that needs rest, hover, focus, selected, open and disabled states with a hairline between rows"
157
+ ],
158
+ "when_not_to_use": [
159
+ "A row that needs a Switch, Checkbox or second button inside it (the trailing slot is non-interactive; build a label row with the control as its own element)",
160
+ "A row that expands in place (use Accordion or Collapsible; ActionRow is the closed row)",
161
+ "A read-only label/value pair (use KeyValueList)",
162
+ "A token specimen (use SurfaceRow)"
163
+ ],
164
+ "props": [
165
+ {
166
+ "name": "children",
167
+ "type": "React.ReactNode",
168
+ "description": "The title. With asChild, the one element to render as (an <a href>), with the title inside it."
169
+ },
170
+ {
171
+ "name": "asChild",
172
+ "type": "boolean",
173
+ "default": "false",
174
+ "description": "Render as the single child element (a link, a router Link) instead of a <button>."
175
+ },
176
+ {
177
+ "name": "leading",
178
+ "type": "React.ReactNode",
179
+ "description": "Leading slot, an icon or avatar. Wrapped in an aria-hidden span; the title carries the name."
180
+ },
181
+ {
182
+ "name": "line",
183
+ "type": "React.ReactNode",
184
+ "description": "Optional second line under the title."
185
+ },
186
+ {
187
+ "name": "trailing",
188
+ "type": "React.ReactNode",
189
+ "description": "Trailing value, badge or caret. Non-interactive; a focusable element here fires a development warning."
190
+ },
191
+ {
192
+ "name": "selected",
193
+ "type": "boolean",
194
+ "default": "false",
195
+ "description": "The row is the current choice. Sets aria-current (\"true\", or the aria-current you pass) and aria-selected on option, tab, row, gridcell and treeitem roles."
196
+ },
197
+ {
198
+ "name": "open",
199
+ "type": "boolean",
200
+ "description": "The row has opened a picker or popover. Sets aria-expanded and data-state."
201
+ },
202
+ {
203
+ "name": "disabled",
204
+ "type": "boolean",
205
+ "default": "false",
206
+ "description": "Native disabled on a button; aria-disabled, tabIndex -1 and a blocked click under asChild."
207
+ }
208
+ ],
209
+ "sub_components": [
210
+ {
211
+ "name": "ActionRowList",
212
+ "description": "A list wrapper (ul, each row in an li) that draws a hairline between rows on --hairline-width."
213
+ }
214
+ ],
215
+ "dependencies": [
216
+ "@radix-ui/react-slot"
217
+ ],
218
+ "tokens_used": [
219
+ "--action-row-disabled-opacity",
220
+ "--action-row-gap",
221
+ "--action-row-hover-bg",
222
+ "--action-row-leading-color",
223
+ "--action-row-leading-size",
224
+ "--action-row-line-color",
225
+ "--action-row-min-height",
226
+ "--action-row-open-bg",
227
+ "--action-row-padding",
228
+ "--action-row-radius",
229
+ "--action-row-selected-bg",
230
+ "--action-row-selected-edge-color",
231
+ "--action-row-title-weight",
232
+ "--action-row-trailing-color",
233
+ "--border-default",
234
+ "--border-focus",
235
+ "--control-state-edge-width",
236
+ "--focus-ring-offset",
237
+ "--focus-ring-width",
238
+ "--font-size-base",
239
+ "--font-size-sm",
240
+ "--font-weight-medium",
241
+ "--hairline",
242
+ "--hairline-width",
243
+ "--line-height-snug",
244
+ "--motion-duration-150",
245
+ "--motion-easing-default",
246
+ "--opacity-50",
247
+ "--radius-md",
248
+ "--spacing-2",
249
+ "--spacing-3",
250
+ "--stroke-width-thin",
251
+ "--surface-interactive-active",
252
+ "--surface-interactive-hover",
253
+ "--text-primary",
254
+ "--text-secondary"
255
+ ],
256
+ "example": "<ActionRowList aria-label=\"Pass details\">\n <ActionRow leading={<MapPin />} line=\"Open in Maps\" trailing={<CaretRight />}>\n Address\n </ActionRow>\n <ActionRow leading={<Users />} trailing=\"2 riders\" selected>\n Riders\n </ActionRow>\n</ActionRowList>\n"
257
+ },
149
258
  "activity-feed": {
150
259
  "category": "admin",
151
260
  "description": "Admin compound for rendering a vertical list of timestamped events — dashboards, audit logs, and notification views.",
@@ -420,6 +529,7 @@
420
529
  "--interactive-primary-text",
421
530
  "--interactive-secondary-bg",
422
531
  "--interactive-secondary-text",
532
+ "--label-box-height",
423
533
  "--motion-duration-150",
424
534
  "--motion-easing-default",
425
535
  "--radius-full",
@@ -1110,24 +1220,29 @@
1110
1220
  "--border-focus",
1111
1221
  "--border-strong",
1112
1222
  "--button-dlg-font-size",
1223
+ "--button-dlg-font-weight",
1113
1224
  "--button-dlg-letter-spacing",
1114
1225
  "--button-dlg-radius",
1115
1226
  "--button-dlg-text-transform",
1227
+ "--button-font-weight",
1116
1228
  "--button-icon-ghost-color",
1117
1229
  "--button-icon-pad",
1118
1230
  "--button-icon-radius",
1119
1231
  "--button-icon-size",
1120
1232
  "--button-letter-spacing",
1121
1233
  "--button-lg-font-size",
1234
+ "--button-lg-font-weight",
1122
1235
  "--button-lg-letter-spacing",
1123
1236
  "--button-lg-radius",
1124
1237
  "--button-lg-text-transform",
1125
1238
  "--button-md-font-size",
1239
+ "--button-md-font-weight",
1126
1240
  "--button-md-letter-spacing",
1127
1241
  "--button-md-radius",
1128
1242
  "--button-md-text-transform",
1129
1243
  "--button-radius",
1130
1244
  "--button-sm-font-size",
1245
+ "--button-sm-font-weight",
1131
1246
  "--button-sm-letter-spacing",
1132
1247
  "--button-sm-radius",
1133
1248
  "--button-sm-text-transform",
@@ -1814,6 +1929,7 @@
1814
1929
  "--font-size-xs",
1815
1930
  "--font-weight-medium",
1816
1931
  "--font-weight-semibold",
1932
+ "--label-box-height",
1817
1933
  "--motion-duration-150",
1818
1934
  "--motion-easing-default",
1819
1935
  "--opacity-40",
@@ -3329,6 +3445,30 @@
3329
3445
  "name": "disabled",
3330
3446
  "type": "boolean",
3331
3447
  "default": "false"
3448
+ },
3449
+ {
3450
+ "name": "align",
3451
+ "type": "\"start\" | \"center\" | \"end\"",
3452
+ "default": "\"start\"",
3453
+ "description": "Popover alignment against the trigger. Use \"end\" under a full-width trigger so the calendar does not sit against the right edge."
3454
+ },
3455
+ {
3456
+ "name": "sideOffset",
3457
+ "type": "number",
3458
+ "default": "4",
3459
+ "description": "Gap in px between the trigger and the popover"
3460
+ },
3461
+ {
3462
+ "name": "collisionPadding",
3463
+ "type": "number",
3464
+ "default": "0",
3465
+ "description": "Viewport padding in px the popover keeps clear when it collides with an edge"
3466
+ },
3467
+ {
3468
+ "name": "defaultOpen",
3469
+ "type": "boolean",
3470
+ "default": "false",
3471
+ "description": "Whether the popover starts open (uncontrolled)"
3332
3472
  }
3333
3473
  ],
3334
3474
  "dependencies": [
@@ -3340,6 +3480,9 @@
3340
3480
  "--border-default",
3341
3481
  "--border-focus",
3342
3482
  "--border-strong",
3483
+ "--control-edge-color",
3484
+ "--control-edge-style",
3485
+ "--control-edge-width",
3343
3486
  "--field-menu-bg",
3344
3487
  "--focus-ring-offset",
3345
3488
  "--focus-ring-width",
@@ -3461,6 +3604,36 @@
3461
3604
  "default": true,
3462
3605
  "description": "When true, interaction with outside elements is blocked (Dialog root)"
3463
3606
  },
3607
+ {
3608
+ "name": "presentation",
3609
+ "type": "'dialog' | 'sheet' | 'responsive'",
3610
+ "default": "dialog",
3611
+ "description": "How the content is presented (Dialog root). dialog is a centred modal, sheet is a bottom sheet, responsive is a dialog from breakpoint up and a sheet below it. Same content, focus trap and Escape handling in each.\n"
3612
+ },
3613
+ {
3614
+ "name": "breakpoint",
3615
+ "type": "number | string",
3616
+ "default": "640",
3617
+ "description": "Viewport width where responsive switches from sheet to dialog. A number is px; a string is any CSS length (Dialog root)"
3618
+ },
3619
+ {
3620
+ "name": "container",
3621
+ "type": "HTMLElement | null",
3622
+ "default": "undefined",
3623
+ "description": "Element the overlay and content portal into, covering only that element (Dialog root). Not Radix modal mode: focus is trapped in the content, the container's other children are inert, and content outside the container stays interactive. Pass the element, not a ref.\n"
3624
+ },
3625
+ {
3626
+ "name": "showHandle",
3627
+ "type": "boolean",
3628
+ "default": false,
3629
+ "description": "Show a drag handle on the sheet presentation; dragging down dismisses (DialogContent)"
3630
+ },
3631
+ {
3632
+ "name": "back",
3633
+ "type": "React.ReactNode",
3634
+ "default": "undefined",
3635
+ "description": "Leading back action rendered before the title, beside the close button (DialogHeader). See DialogBack."
3636
+ },
3464
3637
  {
3465
3638
  "name": "className",
3466
3639
  "type": "string",
@@ -3491,6 +3664,10 @@
3491
3664
  "name": "DialogHeader",
3492
3665
  "description": "Container for title and description at the top."
3493
3666
  },
3667
+ {
3668
+ "name": "DialogBack",
3669
+ "description": "Leading back action for DialogHeader's back slot (labelled \"Back\" by default)."
3670
+ },
3494
3671
  {
3495
3672
  "name": "DialogFooter",
3496
3673
  "description": "Right-aligned action row with a hairline top border, for dialog buttons."
@@ -3523,6 +3700,8 @@
3523
3700
  "tokens_used": [
3524
3701
  "--border-focus",
3525
3702
  "--border-subtle",
3703
+ "--dialog-keyboard-inset",
3704
+ "--dialog-viewport-height",
3526
3705
  "--focus-ring-offset",
3527
3706
  "--focus-ring-width",
3528
3707
  "--font-size-2xl",
@@ -3537,7 +3716,9 @@
3537
3716
  "--motion-easing-default",
3538
3717
  "--motion-easing-enter",
3539
3718
  "--motion-easing-exit",
3719
+ "--opacity-40",
3540
3720
  "--overlay-bg",
3721
+ "--radius-full",
3541
3722
  "--radius-lg",
3542
3723
  "--radius-sm",
3543
3724
  "--radius-xl",
@@ -4074,7 +4255,12 @@
4074
4255
  "intent": [
4075
4256
  "first-use",
4076
4257
  "zero-results",
4077
- "no-access"
4258
+ "no-access",
4259
+ "error"
4260
+ ],
4261
+ "fill": [
4262
+ true,
4263
+ false
4078
4264
  ]
4079
4265
  },
4080
4266
  "props": [
@@ -4129,8 +4315,14 @@
4129
4315
  },
4130
4316
  {
4131
4317
  "name": "intent",
4132
- "type": "'first-use' | 'zero-results' | 'no-access'",
4133
- "description": "Semantic intent of the empty state (Borealis global state spec §5). first-use: no items exist yet; accent-tinted icon chip; encourage creation CTA. zero-results: filter/search returned nothing; accent-tinted chip; offer clear-filter. no-access: permission gate; neutral chip; typically no CTA (terminal state). Setting intent auto-activates iconWrap.\n"
4318
+ "type": "'first-use' | 'zero-results' | 'no-access' | 'error'",
4319
+ "description": "Semantic intent of the empty state (Borealis global state spec §5). first-use: no items exist yet; accent-tinted icon chip; encourage creation CTA. zero-results: filter/search returned nothing; accent-tinted chip; offer clear-filter. no-access: permission gate; neutral chip; typically no CTA (terminal state). error: a failed load; icon and heading in the destructive colour, role=\"alert\", and the icon stays unchipped unless iconWrap is set. Use ErrorPlacard for inline, in-card failures. Setting any other intent auto-activates iconWrap.\n"
4320
+ },
4321
+ {
4322
+ "name": "fill",
4323
+ "type": "boolean",
4324
+ "default": "false",
4325
+ "description": "Fills the container and centres the content vertically and horizontally. Use inside a flex or fixed-height parent so empty and error screens sit in the middle of the open space.\n"
4134
4326
  },
4135
4327
  {
4136
4328
  "name": "headingAs",
@@ -4148,11 +4340,13 @@
4148
4340
  "--control-drop-edge-width",
4149
4341
  "--control-edge-color",
4150
4342
  "--control-edge-width",
4343
+ "--destructive",
4151
4344
  "--empty-state-actions-gap",
4152
4345
  "--empty-state-bg",
4153
4346
  "--empty-state-border",
4154
4347
  "--empty-state-description-color",
4155
4348
  "--empty-state-description-font-size",
4349
+ "--empty-state-error-color",
4156
4350
  "--empty-state-gap",
4157
4351
  "--empty-state-heading-color",
4158
4352
  "--empty-state-heading-font-family",
@@ -4211,6 +4405,7 @@
4211
4405
  "Passive informational notices or warnings (use Alert)",
4212
4406
  "Site-wide or page-level announcements (use Banner)",
4213
4407
  "Empty states where no data exists yet (use EmptyState)",
4408
+ "A whole region or screen whose load failed and should read like an empty state (use EmptyState intent=\"error\")",
4214
4409
  "Ephemeral transient notifications (use Toast)"
4215
4410
  ],
4216
4411
  "props": [
@@ -5410,7 +5605,13 @@
5410
5605
  {
5411
5606
  "name": "editLabel",
5412
5607
  "type": "string",
5413
- "description": "Accessible name of the pencil. Defaults to \"Edit {label}\"."
5608
+ "description": "Accessible name of the pencil, or the lead of the text button's name when `pencil` is false. Defaults to \"Edit {label}\"."
5609
+ },
5610
+ {
5611
+ "name": "pencil",
5612
+ "type": "boolean",
5613
+ "default": "true",
5614
+ "description": "Draws the pencil after the text. With `false` the text is the control (VI-677) - a button named \"Edit {label}, {value}\" that opens on click, Enter or Space and takes focus back after Enter or Escape. It underlines on hover and shows the focus ring alone on focus, clear of the glyphs."
5414
5615
  },
5415
5616
  {
5416
5617
  "name": "as",
@@ -5441,11 +5642,13 @@
5441
5642
  "--control-state-edge-width",
5442
5643
  "--focus-ring-offset",
5443
5644
  "--focus-ring-width",
5645
+ "--inline-edit-underline-style",
5444
5646
  "--motion-duration-150",
5445
5647
  "--motion-easing-default",
5446
5648
  "--radius-sm",
5447
5649
  "--spacing-1",
5448
5650
  "--spacing-2",
5651
+ "--stroke-width-thin",
5449
5652
  "--text-primary",
5450
5653
  "--text-secondary",
5451
5654
  "--text-tertiary"
@@ -5485,6 +5688,16 @@
5485
5688
  "type": "React.ReactNode",
5486
5689
  "description": "Optional leading glyph rendered inside the field (e.g. a Phosphor icon). The input reserves enough left padding to clear it."
5487
5690
  },
5691
+ {
5692
+ "name": "prefix",
5693
+ "type": "React.ReactNode",
5694
+ "description": "Fixed text before the value, inside the same well (a currency symbol). Drawn in the secondary text colour, never part of the value or the selection, and the value never runs under it. Clicking it focuses the input; it is wired to the input with aria-describedby, so assistive tech reads it as a description, not as the value. Replaces the native `prefix` HTML attribute, which is not forwarded. When set, `className` lands on the wrapper that draws the well.\n"
5695
+ },
5696
+ {
5697
+ "name": "suffix",
5698
+ "type": "React.ReactNode",
5699
+ "description": "Fixed text after the value, inside the same well (`.epk.pro`, a unit). Same behaviour as `prefix`."
5700
+ },
5488
5701
  {
5489
5702
  "name": "passwordManagers",
5490
5703
  "type": "'ignore' | 'allow'",
@@ -5494,6 +5707,8 @@
5494
5707
  ],
5495
5708
  "dependencies": [],
5496
5709
  "tokens_used": [
5710
+ "--affix-inset",
5711
+ "--affix-pad-y",
5497
5712
  "--border-default",
5498
5713
  "--border-error",
5499
5714
  "--border-focus",
@@ -5501,17 +5716,28 @@
5501
5716
  "--control-edge-color",
5502
5717
  "--control-edge-style",
5503
5718
  "--control-edge-width",
5719
+ "--control-invalid-halo-width",
5720
+ "--control-invalid-ring-width",
5504
5721
  "--control-state-edge-width",
5505
5722
  "--field-control-bg",
5506
5723
  "--focus-ring-offset",
5507
5724
  "--focus-ring-width",
5725
+ "--font-ascent",
5726
+ "--font-descent",
5508
5727
  "--font-size-base",
5509
5728
  "--font-size-sm",
5729
+ "--input-affix-color",
5730
+ "--input-affix-gap",
5510
5731
  "--input-bg",
5511
5732
  "--input-bg-invalid",
5512
5733
  "--input-border",
5734
+ "--input-box",
5513
5735
  "--input-height-lg",
5514
5736
  "--input-height-md",
5737
+ "--input-md-height",
5738
+ "--input-md-padding",
5739
+ "--input-md-radius",
5740
+ "--input-nudge",
5515
5741
  "--input-padding-lg",
5516
5742
  "--input-padding-md",
5517
5743
  "--input-padding-sm",
@@ -5523,6 +5749,7 @@
5523
5749
  "--radius-md",
5524
5750
  "--radius-sm",
5525
5751
  "--spacing-1",
5752
+ "--spacing-2",
5526
5753
  "--spacing-3",
5527
5754
  "--spacing-3_5",
5528
5755
  "--spacing-4",
@@ -5535,7 +5762,7 @@
5535
5762
  "--text-primary",
5536
5763
  "--text-secondary"
5537
5764
  ],
5538
- "example": "<Input type=\"email\" placeholder=\"you@example.com\" />\n\n<Input type=\"password\" passwordManagers=\"allow\" aria-invalid=\"true\" />\n"
5765
+ "example": "<Input type=\"email\" placeholder=\"you@example.com\" />\n\n<Input suffix=\".epk.pro\" aria-label=\"Address\" />\n\n<Input prefix=\"€\" inputMode=\"decimal\" aria-label=\"Amount\" />\n\n<Input type=\"password\" passwordManagers=\"allow\" aria-invalid=\"true\" />\n"
5539
5766
  },
5540
5767
  "kbd": {
5541
5768
  "category": "admin",
@@ -6338,6 +6565,16 @@
6338
6565
  "type": "number",
6339
6566
  "default": "1",
6340
6567
  "description": "Increment/decrement step size."
6568
+ },
6569
+ {
6570
+ "name": "prefix",
6571
+ "type": "React.ReactNode",
6572
+ "description": "Fixed text before the value, inside the same well (a currency symbol). Same treatment as Input's prefix; replaces the native `prefix` attribute."
6573
+ },
6574
+ {
6575
+ "name": "suffix",
6576
+ "type": "React.ReactNode",
6577
+ "description": "Fixed text after the value, inside the same well (a unit such as `h` or `m`)."
6341
6578
  }
6342
6579
  ],
6343
6580
  "dependencies": [
@@ -6346,21 +6583,31 @@
6346
6583
  "tokens_used": [
6347
6584
  "--border-default",
6348
6585
  "--border-focus",
6586
+ "--control-edge-color",
6587
+ "--control-edge-style",
6588
+ "--control-edge-width",
6589
+ "--control-state-edge-width",
6349
6590
  "--focus-ring-offset",
6350
6591
  "--focus-ring-width",
6592
+ "--font-ascent",
6593
+ "--font-descent",
6351
6594
  "--font-size-sm",
6595
+ "--input-affix-color",
6596
+ "--input-affix-gap",
6597
+ "--input-nudge",
6352
6598
  "--motion-duration-150",
6353
6599
  "--motion-easing-default",
6354
6600
  "--number-input-bg",
6355
6601
  "--number-input-border",
6356
6602
  "--radius-md",
6603
+ "--spacing-2",
6357
6604
  "--surface-interactive-default",
6358
6605
  "--surface-interactive-hover",
6359
6606
  "--surface-muted",
6360
6607
  "--text-primary",
6361
6608
  "--text-secondary"
6362
6609
  ],
6363
- "example": "<NumberInput defaultValue={1} min={0} max={10} step={1} />\n"
6610
+ "example": "<NumberInput defaultValue={1} min={0} max={10} step={1} />\n\n<NumberInput prefix=\"$\" defaultValue={150} aria-label=\"Fee\" />\n\n<NumberInput suffix=\"h\" defaultValue={2} aria-label=\"Hours\" />\n"
6364
6611
  },
6365
6612
  "offline-banner": {
6366
6613
  "category": "feedback",
@@ -6518,23 +6765,52 @@
6518
6765
  "type": "boolean",
6519
6766
  "default": "false",
6520
6767
  "description": "Auto-focus the first cell on mount."
6768
+ },
6769
+ {
6770
+ "name": "invalid",
6771
+ "type": "boolean",
6772
+ "default": "false",
6773
+ "description": "Marks every cell aria-invalid and draws the invalid edge. The digits are kept so they can be corrected."
6774
+ },
6775
+ {
6776
+ "name": "errorMessage",
6777
+ "type": "ReactNode",
6778
+ "description": "Shown under the cells while invalid, in the error text colour, as a role=alert live region. The component draws the message, so do not render a second error line."
6779
+ },
6780
+ {
6781
+ "name": "trailing",
6782
+ "type": "ReactNode",
6783
+ "description": "Trailing content beside the cells, for a working indicator (Spinner) or a resend action."
6521
6784
  }
6522
6785
  ],
6523
6786
  "dependencies": [],
6524
6787
  "tokens_used": [
6525
6788
  "--border-default",
6789
+ "--border-error",
6526
6790
  "--border-focus",
6527
6791
  "--border-strong",
6792
+ "--control-edge-color",
6793
+ "--control-edge-style",
6794
+ "--control-edge-width",
6795
+ "--control-invalid-halo-width",
6796
+ "--control-invalid-ring-width",
6797
+ "--control-state-edge-width",
6798
+ "--focus-ring-offset",
6528
6799
  "--focus-ring-width",
6529
6800
  "--font-size-lg",
6801
+ "--font-size-sm",
6530
6802
  "--font-weight-medium",
6803
+ "--font-weight-normal",
6531
6804
  "--motion-duration-150",
6532
6805
  "--motion-easing-default",
6533
6806
  "--otp-bg",
6807
+ "--otp-bg-invalid",
6534
6808
  "--otp-border",
6535
6809
  "--radius-md",
6536
6810
  "--spacing-2",
6811
+ "--surface-error-subtle",
6537
6812
  "--surface-interactive-default",
6813
+ "--text-error",
6538
6814
  "--text-primary",
6539
6815
  "--text-secondary"
6540
6816
  ],
@@ -7098,7 +7374,8 @@
7098
7374
  "when_to_use": [
7099
7375
  "Selecting exactly one option from a small set (2-6 choices)",
7100
7376
  "Mutually exclusive choices where all options should be visible",
7101
- "Form fields like gender, plan selection, or priority level"
7377
+ "Form fields like gender, plan selection, or priority level",
7378
+ "variant=\"card\" when each option needs an icon and a sentence (visibility levels, plan tiers), including options shown disabled"
7102
7379
  ],
7103
7380
  "when_not_to_use": [
7104
7381
  "Multiple selections allowed (use Checkbox group)",
@@ -7106,6 +7383,12 @@
7106
7383
  "Binary on/off toggle (use Switch or Checkbox)"
7107
7384
  ],
7108
7385
  "props": [
7386
+ {
7387
+ "name": "variant",
7388
+ "type": "'default' | 'card'",
7389
+ "default": "default",
7390
+ "description": "default draws a dot beside a label; card draws each item as a card with icon, title and description."
7391
+ },
7109
7392
  {
7110
7393
  "name": "value",
7111
7394
  "type": "string",
@@ -7133,7 +7416,7 @@
7133
7416
  "sub_components": [
7134
7417
  {
7135
7418
  "name": "RadioGroupItem",
7136
- "description": "An individual radio button with a filled circle indicator when selected."
7419
+ "description": "An individual radio button with a filled circle indicator when selected. In the card variant it is a card with icon, title and description slots and a check mark."
7137
7420
  }
7138
7421
  ],
7139
7422
  "dependencies": [
@@ -7142,16 +7425,49 @@
7142
7425
  ],
7143
7426
  "tokens_used": [
7144
7427
  "--border-default",
7428
+ "--border-error",
7145
7429
  "--border-focus",
7146
7430
  "--border-strong",
7431
+ "--control-edge-color",
7432
+ "--control-edge-style",
7433
+ "--control-edge-width",
7434
+ "--control-state-edge-width",
7435
+ "--destructive",
7147
7436
  "--focus-ring-width",
7437
+ "--font-size-sm",
7438
+ "--font-size-xs",
7439
+ "--font-weight-semibold",
7148
7440
  "--interactive-primary-bg",
7149
7441
  "--interactive-primary-text",
7442
+ "--line-height-snug",
7443
+ "--line-height-tight",
7150
7444
  "--motion-duration-150",
7151
7445
  "--motion-easing-default",
7446
+ "--opacity-60",
7152
7447
  "--primary",
7153
7448
  "--radio-border",
7154
- "--spacing-2"
7449
+ "--radio-card-bg",
7450
+ "--radio-card-border",
7451
+ "--radio-card-hover-bg",
7452
+ "--radio-card-icon-size",
7453
+ "--radio-card-mark-bg",
7454
+ "--radio-card-mark-text",
7455
+ "--radio-card-radius",
7456
+ "--radio-card-selected-bg",
7457
+ "--radio-card-selected-border",
7458
+ "--radio-edgeless-bg",
7459
+ "--radius-full",
7460
+ "--radius-lg",
7461
+ "--spacing-1",
7462
+ "--spacing-2",
7463
+ "--spacing-3",
7464
+ "--spacing-4",
7465
+ "--stroke-width-thin",
7466
+ "--surface-card",
7467
+ "--surface-interactive-hover",
7468
+ "--surface-muted",
7469
+ "--text-primary",
7470
+ "--text-secondary"
7155
7471
  ],
7156
7472
  "example": "<RadioGroup defaultValue=\"medium\">\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\" }}>\n <RadioGroupItem value=\"small\" id=\"small\" />\n <Label htmlFor=\"small\">Small</Label>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\" }}>\n <RadioGroupItem value=\"medium\" id=\"medium\" />\n <Label htmlFor=\"medium\">Medium</Label>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\" }}>\n <RadioGroupItem value=\"large\" id=\"large\" />\n <Label htmlFor=\"large\">Large</Label>\n </div>\n</RadioGroup>\n"
7157
7473
  },
@@ -7185,7 +7501,7 @@
7185
7501
  },
7186
7502
  "save-status": {
7187
7503
  "category": "feedback",
7188
- "description": "Autosave readout — Saved / Saving / Unsaved / Couldn't save in a fixed-width slot that never reflows its row, with a retry mark after a failed save. aria-live polite; draws no edge.",
7504
+ "description": "Autosave readout — Saved / Saving / Syncing / Unsaved / Couldn't save in a fixed-width slot that never reflows its row, with a retry mark after a failed save. aria-live polite; draws no edge.",
7189
7505
  "when_to_use": [
7190
7506
  "Showing where an autosaved value stands, beside the section or field it saves",
7191
7507
  "Any editor with no Save button, driven by the useAutosave hook",
@@ -7200,14 +7516,15 @@
7200
7516
  "status": {
7201
7517
  "saved": "Saved — muted, the resting state.",
7202
7518
  "saving": "Saving — a write is in flight.",
7203
- "unsaved": "Unsaved — a change is waiting for the debounce.",
7519
+ "syncing": "Syncing — a first sync from an outside source is writing rows the user did not type. The consumer sets it; useAutosave never emits it.",
7520
+ "unsaved": "Unsaved — a change is waiting for the debounce. Draw it as a dot alone with unsavedAs=\"dot\"; the label stays as the dot's accessible name.",
7204
7521
  "refused": "Couldn't save — validation refused the value or the write failed; shows a retry mark when onRetry is passed."
7205
7522
  }
7206
7523
  },
7207
7524
  "props": [
7208
7525
  {
7209
7526
  "name": "status",
7210
- "type": "'saved' | 'saving' | 'unsaved' | 'refused'",
7527
+ "type": "'saved' | 'saving' | 'syncing' | 'unsaved' | 'refused'",
7211
7528
  "description": "Where the value stands — pass useAutosave(...).status."
7212
7529
  },
7213
7530
  {
@@ -7217,8 +7534,20 @@
7217
7534
  },
7218
7535
  {
7219
7536
  "name": "labels",
7220
- "type": "Partial<Record<'saved' | 'saving' | 'unsaved' | 'refused', string>>",
7221
- "description": "Override any of the four labels, e.g. to translate them."
7537
+ "type": "Partial<Record<'saved' | 'saving' | 'syncing' | 'unsaved' | 'refused', string>>",
7538
+ "description": "Override any of the five labels, e.g. to translate them."
7539
+ },
7540
+ {
7541
+ "name": "unsavedAs",
7542
+ "type": "'text' | 'dot'",
7543
+ "default": "\"text\"",
7544
+ "description": "How unsaved is drawn. dot draws a dot alone, keeping the label as visually hidden text so it is still announced."
7545
+ },
7546
+ {
7547
+ "name": "dot",
7548
+ "type": "boolean",
7549
+ "default": "false",
7550
+ "description": "Draws a status dot before the label in every state, in the state's ink. Its box is as wide as the larger of the two dot sizes, so the label never moves."
7222
7551
  },
7223
7552
  {
7224
7553
  "name": "retryLabel",
@@ -7241,10 +7570,15 @@
7241
7570
  "--font-size-xs",
7242
7571
  "--motion-duration-150",
7243
7572
  "--motion-easing-default",
7573
+ "--radius-full",
7244
7574
  "--radius-sm",
7575
+ "--save-status-dot-size",
7245
7576
  "--save-status-font-family",
7577
+ "--save-status-font-size",
7246
7578
  "--save-status-letter-spacing",
7579
+ "--save-status-syncing-color",
7247
7580
  "--save-status-text-transform",
7581
+ "--save-status-unsaved-dot-size",
7248
7582
  "--save-status-width",
7249
7583
  "--spacing-1",
7250
7584
  "--spacing-2",
@@ -7674,6 +8008,103 @@
7674
8008
  ],
7675
8009
  "example": "import Link from 'next/link'\nimport { UsersIcon, ShieldIcon, EnvelopeIcon } from '@phosphor-icons/react'\nimport { SectionNav, SectionNavItem } from '@/components/ui/section-nav/section-nav'\n\n<SectionNav aria-label=\"Organization sections\">\n <SectionNavItem asChild isActive icon={UsersIcon} label=\"Detail\">\n <Link href=\"/org/detail\" />\n </SectionNavItem>\n <SectionNavItem asChild icon={ShieldIcon} label=\"Roles\" count={4}>\n <Link href=\"/org/roles\" />\n </SectionNavItem>\n <SectionNavItem asChild icon={EnvelopeIcon} label=\"Invites\" count={2}>\n <Link href=\"/org/invites\" />\n </SectionNavItem>\n</SectionNav>\n"
7676
8010
  },
8011
+ "segmented-control": {
8012
+ "category": "form",
8013
+ "description": "A single-select pill group with a sliding active indicator, an options API and a fullWidth equal-segment layout. A thin wrapper over ToggleGroup that never goes empty.",
8014
+ "when_to_use": [
8015
+ "Switching a list or view filter between 2-5 mutually exclusive options (Unpaid / Paid / Any)",
8016
+ "A scope or range selector where exactly one option is always on",
8017
+ "Compact view-mode switches (day / week / month) that change the content below in place"
8018
+ ],
8019
+ "when_not_to_use": [
8020
+ "Navigation between pages or routes (use Tabs)",
8021
+ "Multi-select toolbar toggles (use ToggleGroup type=\"multiple\")",
8022
+ "A form answer that is submitted with the form (use Radio Group)",
8023
+ "A long list of options (use Select or Combobox)",
8024
+ "Binary on/off (use Switch)"
8025
+ ],
8026
+ "variants": {
8027
+ "size": [
8028
+ "xs",
8029
+ "sm",
8030
+ "md",
8031
+ "lg"
8032
+ ],
8033
+ "fullWidth": [
8034
+ true,
8035
+ false
8036
+ ]
8037
+ },
8038
+ "props": [
8039
+ {
8040
+ "name": "options",
8041
+ "type": "{ value: string; label: ReactNode; icon?: ReactNode; disabled?: boolean }[]",
8042
+ "description": "The segments, in order."
8043
+ },
8044
+ {
8045
+ "name": "value",
8046
+ "type": "string",
8047
+ "description": "Controlled value."
8048
+ },
8049
+ {
8050
+ "name": "defaultValue",
8051
+ "type": "string",
8052
+ "description": "Uncontrolled initial value. Falls back to the first enabled option."
8053
+ },
8054
+ {
8055
+ "name": "onValueChange",
8056
+ "type": "(value: string) => void",
8057
+ "description": "Fires with the new value. Never fires with an empty string."
8058
+ },
8059
+ {
8060
+ "name": "size",
8061
+ "type": "'xs' | 'sm' | 'md' | 'lg'",
8062
+ "default": "md"
8063
+ },
8064
+ {
8065
+ "name": "fullWidth",
8066
+ "type": "boolean",
8067
+ "default": false,
8068
+ "description": "Equal-width segments spanning the container."
8069
+ },
8070
+ {
8071
+ "name": "disabled",
8072
+ "type": "boolean",
8073
+ "default": false
8074
+ }
8075
+ ],
8076
+ "dependencies": [
8077
+ "class-variance-authority"
8078
+ ],
8079
+ "tokens_used": [
8080
+ "--border-default",
8081
+ "--border-focus",
8082
+ "--control-edge-color",
8083
+ "--control-edge-style",
8084
+ "--control-edge-width",
8085
+ "--control-state-edge-width",
8086
+ "--focus-ring-offset",
8087
+ "--focus-ring-width",
8088
+ "--font-weight-medium",
8089
+ "--interactive-primary-bg",
8090
+ "--interactive-primary-text",
8091
+ "--label-box-height",
8092
+ "--primary",
8093
+ "--radius-lg",
8094
+ "--radius-md",
8095
+ "--radius-xl",
8096
+ "--segmented-control-active-weight",
8097
+ "--segmented-control-inactive-text",
8098
+ "--segmented-control-indicator-bg",
8099
+ "--segmented-control-indicator-edge",
8100
+ "--segmented-control-indicator-text",
8101
+ "--segmented-control-radius",
8102
+ "--segmented-control-track-bg",
8103
+ "--surface-page",
8104
+ "--text-primary"
8105
+ ],
8106
+ "example": "<SegmentedControl\n aria-label=\"Payment status\"\n defaultValue=\"unpaid\"\n options={[\n { value: \"unpaid\", label: \"Unpaid\" },\n { value: \"paid\", label: \"Paid\" },\n { value: \"any\", label: \"Any\" },\n ]}\n/>\n"
8107
+ },
7677
8108
  "segmented-progress": {
7678
8109
  "category": "data-display",
7679
8110
  "description": "Discrete per-step progress meter — N equal pill segments in a row, each individually expressing done, current, or pending state. Designed for multi-step flows where individual step completion matters, not just an overall percentage.",
@@ -7821,6 +8252,8 @@
7821
8252
  "--control-edge-color",
7822
8253
  "--control-edge-style",
7823
8254
  "--control-edge-width",
8255
+ "--control-invalid-halo-width",
8256
+ "--control-invalid-ring-width",
7824
8257
  "--control-state-edge-width",
7825
8258
  "--field-control-bg",
7826
8259
  "--field-menu-bg",
@@ -7828,6 +8261,7 @@
7828
8261
  "--font-size-base",
7829
8262
  "--font-size-sm",
7830
8263
  "--font-size-xs",
8264
+ "--label-box-height",
7831
8265
  "--motion-duration-150",
7832
8266
  "--motion-easing-default",
7833
8267
  "--radius-lg",
@@ -7838,6 +8272,9 @@
7838
8272
  "--radix-select-trigger-width",
7839
8273
  "--select-bg",
7840
8274
  "--select-border",
8275
+ "--select-height",
8276
+ "--select-padding",
8277
+ "--select-radius",
7841
8278
  "--shadow-lg",
7842
8279
  "--spacing-1",
7843
8280
  "--spacing-2",
@@ -7882,16 +8319,25 @@
7882
8319
  "name": "decorative",
7883
8320
  "type": "boolean",
7884
8321
  "default": true,
7885
- "description": "When true, removes the separator from the accessibility tree"
8322
+ "description": "When true, removes the separator from the accessibility tree. Ignored when a label is set."
8323
+ },
8324
+ {
8325
+ "name": "label",
8326
+ "type": "ReactNode",
8327
+ "description": "Text centred on a horizontal rule, with the rule on both sides. A labelled separator is never decorative (role=\"separator\", named by the label). Ignored on a vertical separator."
7886
8328
  }
7887
8329
  ],
7888
8330
  "dependencies": [
7889
8331
  "@radix-ui/react-separator"
7890
8332
  ],
7891
8333
  "tokens_used": [
7892
- "--border-default"
8334
+ "--border-default",
8335
+ "--font-size-sm",
8336
+ "--separator-color",
8337
+ "--spacing-3",
8338
+ "--text-secondary"
7893
8339
  ],
7894
- "example": "<div>\n <h3>Section A</h3>\n <Separator />\n <h3>Section B</h3>\n</div>\n\n<div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span>Item 1</span>\n <Separator orientation=\"vertical\" />\n <span>Item 2</span>\n</div>\n"
8340
+ "example": "<div>\n <h3>Section A</h3>\n <Separator />\n <h3>Section B</h3>\n</div>\n\n<Separator label=\"or\" />\n\n<div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span>Item 1</span>\n <Separator orientation=\"vertical\" />\n <span>Item 2</span>\n</div>\n"
7895
8341
  },
7896
8342
  "session-timeout": {
7897
8343
  "category": "overlay",
@@ -8026,6 +8472,12 @@
8026
8472
  ]
8027
8473
  },
8028
8474
  "props": [
8475
+ {
8476
+ "name": "container",
8477
+ "type": "HTMLElement | null",
8478
+ "default": "undefined",
8479
+ "description": "Element the overlay and panel portal into, covering only that element (Sheet root). Not Radix modal mode: focus is trapped in the panel, the container's other children are inert, and content outside the container stays interactive. Pass the element, not a ref.\n"
8480
+ },
8029
8481
  {
8030
8482
  "name": "side",
8031
8483
  "type": "'top' | 'right' | 'bottom' | 'left'",
@@ -9855,6 +10307,7 @@
9855
10307
  "--font-weight-medium",
9856
10308
  "--hairline",
9857
10309
  "--hairline-width",
10310
+ "--label-box-height",
9858
10311
  "--motion-duration-150",
9859
10312
  "--motion-duration-normal",
9860
10313
  "--motion-easing-default",
@@ -9936,6 +10389,12 @@
9936
10389
  "type": "boolean",
9937
10390
  "default": "false",
9938
10391
  "description": "Disables the tag input."
10392
+ },
10393
+ {
10394
+ "name": "entryAs",
10395
+ "type": "'text' | 'slot'",
10396
+ "default": "\"text\"",
10397
+ "description": "Where the next tag is typed. text types after the last tag as bare text; slot types into a dashed slot the shape of a held tag, drawn on the shared drop edge so edges off turns it off."
9939
10398
  }
9940
10399
  ],
9941
10400
  "dependencies": [
@@ -9945,6 +10404,8 @@
9945
10404
  "--border-default",
9946
10405
  "--border-focus",
9947
10406
  "--border-strong",
10407
+ "--control-drop-edge-style",
10408
+ "--control-drop-edge-width",
9948
10409
  "--control-edge-color",
9949
10410
  "--control-edge-style",
9950
10411
  "--control-edge-width",
@@ -9962,6 +10423,18 @@
9962
10423
  "--surface-muted",
9963
10424
  "--tag-input-bg",
9964
10425
  "--tag-input-border",
10426
+ "--tag-input-min-height",
10427
+ "--tag-input-padding",
10428
+ "--tag-input-radius",
10429
+ "--tag-input-slot-height",
10430
+ "--tag-input-slot-min-width",
10431
+ "--tag-input-slot-padding-x",
10432
+ "--tag-input-slot-radius",
10433
+ "--tag-input-tag-font-size",
10434
+ "--tag-input-tag-font-weight",
10435
+ "--tag-input-tag-height",
10436
+ "--tag-input-tag-padding-x",
10437
+ "--tag-input-tag-radius",
9965
10438
  "--text-primary",
9966
10439
  "--text-secondary"
9967
10440
  ],
@@ -10124,6 +10597,8 @@
10124
10597
  "--control-edge-color",
10125
10598
  "--control-edge-style",
10126
10599
  "--control-edge-width",
10600
+ "--control-invalid-halo-width",
10601
+ "--control-invalid-ring-width",
10127
10602
  "--control-state-edge-width",
10128
10603
  "--focus-ring-width",
10129
10604
  "--font-size-base",
@@ -10140,7 +10615,9 @@
10140
10615
  "--text-primary",
10141
10616
  "--text-secondary",
10142
10617
  "--textarea-bg",
10143
- "--textarea-border"
10618
+ "--textarea-border",
10619
+ "--textarea-padding",
10620
+ "--textarea-radius"
10144
10621
  ],
10145
10622
  "example": "<Textarea placeholder=\"Write your message...\" rows={4} />\n\n<Textarea aria-invalid=\"true\" />\n"
10146
10623
  },
@@ -10219,6 +10696,127 @@
10219
10696
  ],
10220
10697
  "example": "import { ThemeSwitcher } from \"@/components/ui/theme-switcher/theme-switcher\"\nimport { SourceInspectorToggle } from \"@/components/devtools/source-inspector/source-inspector-toggle\"\n\n<ThemeSwitcher\n themes={[\n { id: \"default\", label: \"Default\", bodyClass: \"\" },\n { id: \"blackout\", label: \"Blackout\", bodyClass: \"blackout-theme\" },\n ]}\n extras={<SourceInspectorToggle />}\n/>\n"
10221
10698
  },
10699
+ "time-picker": {
10700
+ "category": "form",
10701
+ "description": "A time picker with a typeable field and a popover of hour and minute columns, shown in a 12- or 24-hour cycle with a configurable minute step.",
10702
+ "when_to_use": [
10703
+ "A wall-clock time of day in a form (doors open, start time, reminder time)",
10704
+ "Times where only a few minute values make sense (15- or 30-minute steps)",
10705
+ "Fields that must show AM/PM or 24-hour regardless of the browser's locale"
10706
+ ],
10707
+ "when_not_to_use": [
10708
+ "A date and a time together (use DatePicker beside a TimePicker, or a dedicated datetime picker)",
10709
+ "Durations or elapsed time (use NumberInput)",
10710
+ "Time zones; values are venue-local wall-clock times with no zone",
10711
+ "A native time input is acceptable and the browser locale is the right one"
10712
+ ],
10713
+ "props": [
10714
+ {
10715
+ "name": "value",
10716
+ "type": "string | undefined",
10717
+ "description": "Selected time as 24-hour \"HH:MM\""
10718
+ },
10719
+ {
10720
+ "name": "defaultValue",
10721
+ "type": "string",
10722
+ "description": "Initial \"HH:MM\" when uncontrolled"
10723
+ },
10724
+ {
10725
+ "name": "onChange",
10726
+ "type": "(value: string | undefined) => void",
10727
+ "description": "Called with 24-hour \"HH:MM\", or undefined when the field is cleared"
10728
+ },
10729
+ {
10730
+ "name": "hourCycle",
10731
+ "type": "12 | 24",
10732
+ "default": "from locale",
10733
+ "description": "12 shows \"4:30 PM\" and adds an AM/PM column; 24 shows \"16:30\""
10734
+ },
10735
+ {
10736
+ "name": "locale",
10737
+ "type": "string",
10738
+ "default": "document language",
10739
+ "description": "BCP 47 locale that decides the default hour cycle"
10740
+ },
10741
+ {
10742
+ "name": "minuteStep",
10743
+ "type": "number",
10744
+ "default": "1",
10745
+ "description": "Minutes between popover choices; typed times snap to the nearest step"
10746
+ },
10747
+ {
10748
+ "name": "placeholder",
10749
+ "type": "string"
10750
+ },
10751
+ {
10752
+ "name": "disabled",
10753
+ "type": "boolean",
10754
+ "default": "false"
10755
+ },
10756
+ {
10757
+ "name": "open",
10758
+ "type": "boolean",
10759
+ "description": "Controlled popover state"
10760
+ },
10761
+ {
10762
+ "name": "onOpenChange",
10763
+ "type": "(open: boolean) => void"
10764
+ },
10765
+ {
10766
+ "name": "container",
10767
+ "type": "HTMLElement | null",
10768
+ "description": "Element the popover portals into (defaults to document.body)"
10769
+ },
10770
+ {
10771
+ "name": "triggerLabel",
10772
+ "type": "string",
10773
+ "default": "\"Choose time\"",
10774
+ "description": "Accessible name of the clock button"
10775
+ }
10776
+ ],
10777
+ "dependencies": [
10778
+ "@radix-ui/react-popover",
10779
+ "@phosphor-icons/react"
10780
+ ],
10781
+ "tokens_used": [
10782
+ "--border-default",
10783
+ "--border-error",
10784
+ "--border-focus",
10785
+ "--border-strong",
10786
+ "--control-edge-color",
10787
+ "--control-edge-style",
10788
+ "--control-edge-width",
10789
+ "--control-state-edge-width",
10790
+ "--field-control-bg",
10791
+ "--field-menu-bg",
10792
+ "--focus-ring-width",
10793
+ "--font-body",
10794
+ "--font-size-sm",
10795
+ "--hairline-strong",
10796
+ "--hairline-width",
10797
+ "--input-bg",
10798
+ "--input-border",
10799
+ "--input-placeholder-color",
10800
+ "--interactive-primary-text",
10801
+ "--motion-duration-150",
10802
+ "--motion-easing-default",
10803
+ "--primary",
10804
+ "--radius-lg",
10805
+ "--radius-md",
10806
+ "--radius-sm",
10807
+ "--shadow-md",
10808
+ "--spacing-1",
10809
+ "--spacing-3",
10810
+ "--stroke-width-thin",
10811
+ "--surface-card",
10812
+ "--surface-interactive-default",
10813
+ "--surface-popover",
10814
+ "--surface-subtle",
10815
+ "--text-primary",
10816
+ "--text-secondary"
10817
+ ],
10818
+ "example": "<TimePicker value={opensAt} onChange={setOpensAt} aria-label=\"Doors open\" />\n\n<TimePicker\n hourCycle={24}\n minuteStep={15}\n value={start}\n onChange={setStart}\n aria-label=\"Set start\"\n/>\n"
10819
+ },
10222
10820
  "timeline": {
10223
10821
  "category": "data-display",
10224
10822
  "description": "A vertical timeline with status-based styling, optional icons, timestamps, and connector lines.",
@@ -10621,6 +11219,7 @@
10621
11219
  "tokens_used": [
10622
11220
  "--border-default",
10623
11221
  "--border-focus",
11222
+ "--focus-ring-offset",
10624
11223
  "--focus-ring-width",
10625
11224
  "--font-size-base",
10626
11225
  "--font-size-sm",
@@ -10628,6 +11227,7 @@
10628
11227
  "--font-weight-medium",
10629
11228
  "--interactive-primary-bg",
10630
11229
  "--interactive-primary-text",
11230
+ "--label-box-height",
10631
11231
  "--motion-duration-150",
10632
11232
  "--motion-duration-200",
10633
11233
  "--motion-easing-default",
@@ -12187,11 +12787,13 @@
12187
12787
  },
12188
12788
  "month-calendar": {
12189
12789
  "category": "data-display",
12190
- "description": "A theme-portable month event-grid (scheduler) block. Renders a 6×7 day-cell grid under a localized weekday header, with prev/next month navigation, a view-mode segmented control (Month / Week / Day), and per-cell event chips. Each chip carries a status-dot slot (success / warning / danger / info) and an optional series tint (1–5) keyed to the theme's chart ramp for color-coding a recurring series or resource lane. Days outside the displayed month are dimmed; optional today and selected-day highlighting. Fully token-driven — every color, spacing, stroke, radius, shadow, opacity, and motion value binds to a Visor token, so the grid adopts the active theme without modification.",
12790
+ "description": "A theme-portable month event-grid (scheduler) block. Renders a 6×7 day-cell grid under a localized weekday header, with prev/next month navigation, a view-mode segmented control (Month / Week / Day), and per-cell event chips. Each chip carries a status-dot slot (success / warning / danger / info) and an optional series tint (1–5) keyed to the theme's chart ramp for color-coding a recurring series or resource lane. Days outside the displayed month are dimmed; optional today and selected-day highlighting. Events with an `end` draw as one bar across the days they span, cut at week edges with a continued mark and stacked in lanes (with \"+N\" past `maxLanes`). `renderWeekDetail` opens a slot under the week that holds the selected day; `renderDayMark` puts a consumer mark in each day cell. Dates are plain YYYY-MM-DD calendar dates. The month is an ARIA grid with arrow-key day movement. Fully token-driven — every color, spacing, stroke, radius, shadow, opacity, and motion value binds to a Visor token, so the grid adopts the active theme without modification.",
12191
12791
  "components_used": [],
12192
12792
  "when_to_use": [
12193
12793
  "Admin or booking surfaces that show events-in-a-month (the most common scheduling view)",
12194
12794
  "Color-coding recurring series or resource lanes via the per-chip series tint",
12795
+ "Stays, trips and availability that span several days, drawn as one bar and coloured per event",
12796
+ "A day sheet opening under the selected week",
12195
12797
  "Status-at-a-glance calendars where each event needs a success / warning / danger / info dot"
12196
12798
  ],
12197
12799
  "when_not_to_use": [
@@ -13102,6 +13704,7 @@
13102
13704
  ],
13103
13705
  "data-display": [
13104
13706
  "accordion",
13707
+ "action-row",
13105
13708
  "avatar",
13106
13709
  "badge",
13107
13710
  "bento-grid",
@@ -13201,6 +13804,7 @@
13201
13804
  "phone-input",
13202
13805
  "radio-group",
13203
13806
  "search-input",
13807
+ "segmented-control",
13204
13808
  "select",
13205
13809
  "slider",
13206
13810
  "slider-control",
@@ -13208,6 +13812,7 @@
13208
13812
  "switch",
13209
13813
  "tag-input",
13210
13814
  "textarea",
13815
+ "time-picker",
13211
13816
  "tin-input",
13212
13817
  "toggle-group"
13213
13818
  ],