@loworbitstudio/visor 1.30.0 → 1.31.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-03T23:23:41.691Z",
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",
@@ -1814,6 +1924,7 @@
1814
1924
  "--font-size-xs",
1815
1925
  "--font-weight-medium",
1816
1926
  "--font-weight-semibold",
1927
+ "--label-box-height",
1817
1928
  "--motion-duration-150",
1818
1929
  "--motion-easing-default",
1819
1930
  "--opacity-40",
@@ -3461,6 +3572,36 @@
3461
3572
  "default": true,
3462
3573
  "description": "When true, interaction with outside elements is blocked (Dialog root)"
3463
3574
  },
3575
+ {
3576
+ "name": "presentation",
3577
+ "type": "'dialog' | 'sheet' | 'responsive'",
3578
+ "default": "dialog",
3579
+ "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"
3580
+ },
3581
+ {
3582
+ "name": "breakpoint",
3583
+ "type": "number | string",
3584
+ "default": "640",
3585
+ "description": "Viewport width where responsive switches from sheet to dialog. A number is px; a string is any CSS length (Dialog root)"
3586
+ },
3587
+ {
3588
+ "name": "container",
3589
+ "type": "HTMLElement | null",
3590
+ "default": "undefined",
3591
+ "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"
3592
+ },
3593
+ {
3594
+ "name": "showHandle",
3595
+ "type": "boolean",
3596
+ "default": false,
3597
+ "description": "Show a drag handle on the sheet presentation; dragging down dismisses (DialogContent)"
3598
+ },
3599
+ {
3600
+ "name": "back",
3601
+ "type": "React.ReactNode",
3602
+ "default": "undefined",
3603
+ "description": "Leading back action rendered before the title, beside the close button (DialogHeader). See DialogBack."
3604
+ },
3464
3605
  {
3465
3606
  "name": "className",
3466
3607
  "type": "string",
@@ -3491,6 +3632,10 @@
3491
3632
  "name": "DialogHeader",
3492
3633
  "description": "Container for title and description at the top."
3493
3634
  },
3635
+ {
3636
+ "name": "DialogBack",
3637
+ "description": "Leading back action for DialogHeader's back slot (labelled \"Back\" by default)."
3638
+ },
3494
3639
  {
3495
3640
  "name": "DialogFooter",
3496
3641
  "description": "Right-aligned action row with a hairline top border, for dialog buttons."
@@ -3523,6 +3668,8 @@
3523
3668
  "tokens_used": [
3524
3669
  "--border-focus",
3525
3670
  "--border-subtle",
3671
+ "--dialog-keyboard-inset",
3672
+ "--dialog-viewport-height",
3526
3673
  "--focus-ring-offset",
3527
3674
  "--focus-ring-width",
3528
3675
  "--font-size-2xl",
@@ -3537,7 +3684,9 @@
3537
3684
  "--motion-easing-default",
3538
3685
  "--motion-easing-enter",
3539
3686
  "--motion-easing-exit",
3687
+ "--opacity-40",
3540
3688
  "--overlay-bg",
3689
+ "--radius-full",
3541
3690
  "--radius-lg",
3542
3691
  "--radius-sm",
3543
3692
  "--radius-xl",
@@ -4074,7 +4223,12 @@
4074
4223
  "intent": [
4075
4224
  "first-use",
4076
4225
  "zero-results",
4077
- "no-access"
4226
+ "no-access",
4227
+ "error"
4228
+ ],
4229
+ "fill": [
4230
+ true,
4231
+ false
4078
4232
  ]
4079
4233
  },
4080
4234
  "props": [
@@ -4129,8 +4283,14 @@
4129
4283
  },
4130
4284
  {
4131
4285
  "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"
4286
+ "type": "'first-use' | 'zero-results' | 'no-access' | 'error'",
4287
+ "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"
4288
+ },
4289
+ {
4290
+ "name": "fill",
4291
+ "type": "boolean",
4292
+ "default": "false",
4293
+ "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
4294
  },
4135
4295
  {
4136
4296
  "name": "headingAs",
@@ -4148,11 +4308,13 @@
4148
4308
  "--control-drop-edge-width",
4149
4309
  "--control-edge-color",
4150
4310
  "--control-edge-width",
4311
+ "--destructive",
4151
4312
  "--empty-state-actions-gap",
4152
4313
  "--empty-state-bg",
4153
4314
  "--empty-state-border",
4154
4315
  "--empty-state-description-color",
4155
4316
  "--empty-state-description-font-size",
4317
+ "--empty-state-error-color",
4156
4318
  "--empty-state-gap",
4157
4319
  "--empty-state-heading-color",
4158
4320
  "--empty-state-heading-font-family",
@@ -4211,6 +4373,7 @@
4211
4373
  "Passive informational notices or warnings (use Alert)",
4212
4374
  "Site-wide or page-level announcements (use Banner)",
4213
4375
  "Empty states where no data exists yet (use EmptyState)",
4376
+ "A whole region or screen whose load failed and should read like an empty state (use EmptyState intent=\"error\")",
4214
4377
  "Ephemeral transient notifications (use Toast)"
4215
4378
  ],
4216
4379
  "props": [
@@ -5410,7 +5573,13 @@
5410
5573
  {
5411
5574
  "name": "editLabel",
5412
5575
  "type": "string",
5413
- "description": "Accessible name of the pencil. Defaults to \"Edit {label}\"."
5576
+ "description": "Accessible name of the pencil, or the lead of the text button's name when `pencil` is false. Defaults to \"Edit {label}\"."
5577
+ },
5578
+ {
5579
+ "name": "pencil",
5580
+ "type": "boolean",
5581
+ "default": "true",
5582
+ "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
5583
  },
5415
5584
  {
5416
5585
  "name": "as",
@@ -5441,11 +5610,13 @@
5441
5610
  "--control-state-edge-width",
5442
5611
  "--focus-ring-offset",
5443
5612
  "--focus-ring-width",
5613
+ "--inline-edit-underline-style",
5444
5614
  "--motion-duration-150",
5445
5615
  "--motion-easing-default",
5446
5616
  "--radius-sm",
5447
5617
  "--spacing-1",
5448
5618
  "--spacing-2",
5619
+ "--stroke-width-thin",
5449
5620
  "--text-primary",
5450
5621
  "--text-secondary",
5451
5622
  "--text-tertiary"
@@ -5512,6 +5683,7 @@
5512
5683
  "--input-border",
5513
5684
  "--input-height-lg",
5514
5685
  "--input-height-md",
5686
+ "--input-nudge",
5515
5687
  "--input-padding-lg",
5516
5688
  "--input-padding-md",
5517
5689
  "--input-padding-sm",
@@ -7098,7 +7270,8 @@
7098
7270
  "when_to_use": [
7099
7271
  "Selecting exactly one option from a small set (2-6 choices)",
7100
7272
  "Mutually exclusive choices where all options should be visible",
7101
- "Form fields like gender, plan selection, or priority level"
7273
+ "Form fields like gender, plan selection, or priority level",
7274
+ "variant=\"card\" when each option needs an icon and a sentence (visibility levels, plan tiers), including options shown disabled"
7102
7275
  ],
7103
7276
  "when_not_to_use": [
7104
7277
  "Multiple selections allowed (use Checkbox group)",
@@ -7106,6 +7279,12 @@
7106
7279
  "Binary on/off toggle (use Switch or Checkbox)"
7107
7280
  ],
7108
7281
  "props": [
7282
+ {
7283
+ "name": "variant",
7284
+ "type": "'default' | 'card'",
7285
+ "default": "default",
7286
+ "description": "default draws a dot beside a label; card draws each item as a card with icon, title and description."
7287
+ },
7109
7288
  {
7110
7289
  "name": "value",
7111
7290
  "type": "string",
@@ -7133,7 +7312,7 @@
7133
7312
  "sub_components": [
7134
7313
  {
7135
7314
  "name": "RadioGroupItem",
7136
- "description": "An individual radio button with a filled circle indicator when selected."
7315
+ "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
7316
  }
7138
7317
  ],
7139
7318
  "dependencies": [
@@ -7142,16 +7321,49 @@
7142
7321
  ],
7143
7322
  "tokens_used": [
7144
7323
  "--border-default",
7324
+ "--border-error",
7145
7325
  "--border-focus",
7146
7326
  "--border-strong",
7327
+ "--control-edge-color",
7328
+ "--control-edge-style",
7329
+ "--control-edge-width",
7330
+ "--control-state-edge-width",
7331
+ "--destructive",
7147
7332
  "--focus-ring-width",
7333
+ "--font-size-sm",
7334
+ "--font-size-xs",
7335
+ "--font-weight-semibold",
7148
7336
  "--interactive-primary-bg",
7149
7337
  "--interactive-primary-text",
7338
+ "--line-height-snug",
7339
+ "--line-height-tight",
7150
7340
  "--motion-duration-150",
7151
7341
  "--motion-easing-default",
7342
+ "--opacity-60",
7152
7343
  "--primary",
7153
7344
  "--radio-border",
7154
- "--spacing-2"
7345
+ "--radio-card-bg",
7346
+ "--radio-card-border",
7347
+ "--radio-card-hover-bg",
7348
+ "--radio-card-icon-size",
7349
+ "--radio-card-mark-bg",
7350
+ "--radio-card-mark-text",
7351
+ "--radio-card-radius",
7352
+ "--radio-card-selected-bg",
7353
+ "--radio-card-selected-border",
7354
+ "--radio-edgeless-bg",
7355
+ "--radius-full",
7356
+ "--radius-lg",
7357
+ "--spacing-1",
7358
+ "--spacing-2",
7359
+ "--spacing-3",
7360
+ "--spacing-4",
7361
+ "--stroke-width-thin",
7362
+ "--surface-card",
7363
+ "--surface-interactive-hover",
7364
+ "--surface-muted",
7365
+ "--text-primary",
7366
+ "--text-secondary"
7155
7367
  ],
7156
7368
  "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
7369
  },
@@ -7185,7 +7397,7 @@
7185
7397
  },
7186
7398
  "save-status": {
7187
7399
  "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.",
7400
+ "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
7401
  "when_to_use": [
7190
7402
  "Showing where an autosaved value stands, beside the section or field it saves",
7191
7403
  "Any editor with no Save button, driven by the useAutosave hook",
@@ -7200,14 +7412,15 @@
7200
7412
  "status": {
7201
7413
  "saved": "Saved — muted, the resting state.",
7202
7414
  "saving": "Saving — a write is in flight.",
7203
- "unsaved": "Unsaved — a change is waiting for the debounce.",
7415
+ "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.",
7416
+ "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
7417
  "refused": "Couldn't save — validation refused the value or the write failed; shows a retry mark when onRetry is passed."
7205
7418
  }
7206
7419
  },
7207
7420
  "props": [
7208
7421
  {
7209
7422
  "name": "status",
7210
- "type": "'saved' | 'saving' | 'unsaved' | 'refused'",
7423
+ "type": "'saved' | 'saving' | 'syncing' | 'unsaved' | 'refused'",
7211
7424
  "description": "Where the value stands — pass useAutosave(...).status."
7212
7425
  },
7213
7426
  {
@@ -7217,8 +7430,14 @@
7217
7430
  },
7218
7431
  {
7219
7432
  "name": "labels",
7220
- "type": "Partial<Record<'saved' | 'saving' | 'unsaved' | 'refused', string>>",
7221
- "description": "Override any of the four labels, e.g. to translate them."
7433
+ "type": "Partial<Record<'saved' | 'saving' | 'syncing' | 'unsaved' | 'refused', string>>",
7434
+ "description": "Override any of the five labels, e.g. to translate them."
7435
+ },
7436
+ {
7437
+ "name": "unsavedAs",
7438
+ "type": "'text' | 'dot'",
7439
+ "default": "\"text\"",
7440
+ "description": "How unsaved is drawn. dot draws a dot alone, keeping the label as visually hidden text so it is still announced."
7222
7441
  },
7223
7442
  {
7224
7443
  "name": "retryLabel",
@@ -7241,9 +7460,12 @@
7241
7460
  "--font-size-xs",
7242
7461
  "--motion-duration-150",
7243
7462
  "--motion-easing-default",
7463
+ "--radius-full",
7244
7464
  "--radius-sm",
7465
+ "--save-status-dot-size",
7245
7466
  "--save-status-font-family",
7246
7467
  "--save-status-letter-spacing",
7468
+ "--save-status-syncing-color",
7247
7469
  "--save-status-text-transform",
7248
7470
  "--save-status-width",
7249
7471
  "--spacing-1",
@@ -7828,6 +8050,7 @@
7828
8050
  "--font-size-base",
7829
8051
  "--font-size-sm",
7830
8052
  "--font-size-xs",
8053
+ "--label-box-height",
7831
8054
  "--motion-duration-150",
7832
8055
  "--motion-easing-default",
7833
8056
  "--radius-lg",
@@ -8026,6 +8249,12 @@
8026
8249
  ]
8027
8250
  },
8028
8251
  "props": [
8252
+ {
8253
+ "name": "container",
8254
+ "type": "HTMLElement | null",
8255
+ "default": "undefined",
8256
+ "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"
8257
+ },
8029
8258
  {
8030
8259
  "name": "side",
8031
8260
  "type": "'top' | 'right' | 'bottom' | 'left'",
@@ -9855,6 +10084,7 @@
9855
10084
  "--font-weight-medium",
9856
10085
  "--hairline",
9857
10086
  "--hairline-width",
10087
+ "--label-box-height",
9858
10088
  "--motion-duration-150",
9859
10089
  "--motion-duration-normal",
9860
10090
  "--motion-easing-default",
@@ -10219,6 +10449,127 @@
10219
10449
  ],
10220
10450
  "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
10451
  },
10452
+ "time-picker": {
10453
+ "category": "form",
10454
+ "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.",
10455
+ "when_to_use": [
10456
+ "A wall-clock time of day in a form (doors open, start time, reminder time)",
10457
+ "Times where only a few minute values make sense (15- or 30-minute steps)",
10458
+ "Fields that must show AM/PM or 24-hour regardless of the browser's locale"
10459
+ ],
10460
+ "when_not_to_use": [
10461
+ "A date and a time together (use DatePicker beside a TimePicker, or a dedicated datetime picker)",
10462
+ "Durations or elapsed time (use NumberInput)",
10463
+ "Time zones; values are venue-local wall-clock times with no zone",
10464
+ "A native time input is acceptable and the browser locale is the right one"
10465
+ ],
10466
+ "props": [
10467
+ {
10468
+ "name": "value",
10469
+ "type": "string | undefined",
10470
+ "description": "Selected time as 24-hour \"HH:MM\""
10471
+ },
10472
+ {
10473
+ "name": "defaultValue",
10474
+ "type": "string",
10475
+ "description": "Initial \"HH:MM\" when uncontrolled"
10476
+ },
10477
+ {
10478
+ "name": "onChange",
10479
+ "type": "(value: string | undefined) => void",
10480
+ "description": "Called with 24-hour \"HH:MM\", or undefined when the field is cleared"
10481
+ },
10482
+ {
10483
+ "name": "hourCycle",
10484
+ "type": "12 | 24",
10485
+ "default": "from locale",
10486
+ "description": "12 shows \"4:30 PM\" and adds an AM/PM column; 24 shows \"16:30\""
10487
+ },
10488
+ {
10489
+ "name": "locale",
10490
+ "type": "string",
10491
+ "default": "document language",
10492
+ "description": "BCP 47 locale that decides the default hour cycle"
10493
+ },
10494
+ {
10495
+ "name": "minuteStep",
10496
+ "type": "number",
10497
+ "default": "1",
10498
+ "description": "Minutes between popover choices; typed times snap to the nearest step"
10499
+ },
10500
+ {
10501
+ "name": "placeholder",
10502
+ "type": "string"
10503
+ },
10504
+ {
10505
+ "name": "disabled",
10506
+ "type": "boolean",
10507
+ "default": "false"
10508
+ },
10509
+ {
10510
+ "name": "open",
10511
+ "type": "boolean",
10512
+ "description": "Controlled popover state"
10513
+ },
10514
+ {
10515
+ "name": "onOpenChange",
10516
+ "type": "(open: boolean) => void"
10517
+ },
10518
+ {
10519
+ "name": "container",
10520
+ "type": "HTMLElement | null",
10521
+ "description": "Element the popover portals into (defaults to document.body)"
10522
+ },
10523
+ {
10524
+ "name": "triggerLabel",
10525
+ "type": "string",
10526
+ "default": "\"Choose time\"",
10527
+ "description": "Accessible name of the clock button"
10528
+ }
10529
+ ],
10530
+ "dependencies": [
10531
+ "@radix-ui/react-popover",
10532
+ "@phosphor-icons/react"
10533
+ ],
10534
+ "tokens_used": [
10535
+ "--border-default",
10536
+ "--border-error",
10537
+ "--border-focus",
10538
+ "--border-strong",
10539
+ "--control-edge-color",
10540
+ "--control-edge-style",
10541
+ "--control-edge-width",
10542
+ "--control-state-edge-width",
10543
+ "--field-control-bg",
10544
+ "--field-menu-bg",
10545
+ "--focus-ring-width",
10546
+ "--font-body",
10547
+ "--font-size-sm",
10548
+ "--hairline-strong",
10549
+ "--hairline-width",
10550
+ "--input-bg",
10551
+ "--input-border",
10552
+ "--input-placeholder-color",
10553
+ "--interactive-primary-text",
10554
+ "--motion-duration-150",
10555
+ "--motion-easing-default",
10556
+ "--primary",
10557
+ "--radius-lg",
10558
+ "--radius-md",
10559
+ "--radius-sm",
10560
+ "--shadow-md",
10561
+ "--spacing-1",
10562
+ "--spacing-3",
10563
+ "--stroke-width-thin",
10564
+ "--surface-card",
10565
+ "--surface-interactive-default",
10566
+ "--surface-popover",
10567
+ "--surface-subtle",
10568
+ "--text-primary",
10569
+ "--text-secondary"
10570
+ ],
10571
+ "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"
10572
+ },
10222
10573
  "timeline": {
10223
10574
  "category": "data-display",
10224
10575
  "description": "A vertical timeline with status-based styling, optional icons, timestamps, and connector lines.",
@@ -10628,6 +10979,7 @@
10628
10979
  "--font-weight-medium",
10629
10980
  "--interactive-primary-bg",
10630
10981
  "--interactive-primary-text",
10982
+ "--label-box-height",
10631
10983
  "--motion-duration-150",
10632
10984
  "--motion-duration-200",
10633
10985
  "--motion-easing-default",
@@ -12187,11 +12539,13 @@
12187
12539
  },
12188
12540
  "month-calendar": {
12189
12541
  "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.",
12542
+ "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
12543
  "components_used": [],
12192
12544
  "when_to_use": [
12193
12545
  "Admin or booking surfaces that show events-in-a-month (the most common scheduling view)",
12194
12546
  "Color-coding recurring series or resource lanes via the per-chip series tint",
12547
+ "Stays, trips and availability that span several days, drawn as one bar and coloured per event",
12548
+ "A day sheet opening under the selected week",
12195
12549
  "Status-at-a-glance calendars where each event needs a success / warning / danger / info dot"
12196
12550
  ],
12197
12551
  "when_not_to_use": [
@@ -13102,6 +13456,7 @@
13102
13456
  ],
13103
13457
  "data-display": [
13104
13458
  "accordion",
13459
+ "action-row",
13105
13460
  "avatar",
13106
13461
  "badge",
13107
13462
  "bento-grid",
@@ -13208,6 +13563,7 @@
13208
13563
  "switch",
13209
13564
  "tag-input",
13210
13565
  "textarea",
13566
+ "time-picker",
13211
13567
  "tin-input",
13212
13568
  "toggle-group"
13213
13569
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loworbitstudio/visor",
3
- "version": "1.30.0",
3
+ "version": "1.31.0",
4
4
  "description": "CLI for the Visor design system — add components, hooks, and utilities to your project.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "@aws-sdk/client-s3": "^3.1021.0",
48
48
  "@babel/parser": "^7.26.0",
49
- "@loworbitstudio/visor-theme-engine": "^0.24.0",
49
+ "@loworbitstudio/visor-theme-engine": "^0.25.0",
50
50
  "commander": "^13.1.0",
51
51
  "diff": "^8.0.4",
52
52
  "picocolors": "^1.1.1",