division-ds 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -5
- package/division-ds-0.3.0.tgz +0 -0
- package/package.json +1 -1
- package/public/docs/components/accordion.md +2 -0
- package/public/docs/components/ai-label.md +2 -0
- package/public/docs/components/alert-dialog.md +2 -0
- package/public/docs/components/alert.md +2 -0
- package/public/docs/components/approval-request.md +2 -0
- package/public/docs/components/auth-form.md +2 -0
- package/public/docs/components/avatar-group.md +2 -0
- package/public/docs/components/avatar.md +2 -0
- package/public/docs/components/badge.md +2 -0
- package/public/docs/components/breadcrumbs.md +2 -0
- package/public/docs/components/button.md +2 -0
- package/public/docs/components/card.md +2 -0
- package/public/docs/components/carousel.md +2 -0
- package/public/docs/components/cart.md +2 -0
- package/public/docs/components/chart-panel.md +2 -0
- package/public/docs/components/chat-message.md +3 -0
- package/public/docs/components/chat-thread.md +2 -0
- package/public/docs/components/checkbox.md +2 -0
- package/public/docs/components/checkout-form.md +2 -0
- package/public/docs/components/command-palette.md +6 -1
- package/public/docs/components/data-table.md +2 -0
- package/public/docs/components/date-picker.md +166 -0
- package/public/docs/components/date-presets.md +111 -0
- package/public/docs/components/date-range-picker.md +135 -0
- package/public/docs/components/description-list.md +2 -0
- package/public/docs/components/dialog.md +2 -0
- package/public/docs/components/divider.md +2 -0
- package/public/docs/components/dropdown-menu.md +2 -0
- package/public/docs/components/empty-state.md +2 -0
- package/public/docs/components/footer.md +2 -0
- package/public/docs/components/form-field.md +4 -1
- package/public/docs/components/icon-button.md +2 -0
- package/public/docs/components/input.md +2 -0
- package/public/docs/components/kanban-board.md +2 -0
- package/public/docs/components/kbd.md +2 -0
- package/public/docs/components/link.md +2 -0
- package/public/docs/components/list-item.md +3 -0
- package/public/docs/components/loading-animation.md +2 -0
- package/public/docs/components/multi-select.md +2 -0
- package/public/docs/components/navbar.md +2 -0
- package/public/docs/components/newsletter-form.md +2 -0
- package/public/docs/components/page-header.md +2 -0
- package/public/docs/components/pagination.md +2 -0
- package/public/docs/components/product-card.md +3 -0
- package/public/docs/components/progress.md +3 -1
- package/public/docs/components/prompt-input.md +2 -0
- package/public/docs/components/quantity-stepper.md +2 -0
- package/public/docs/components/radio.md +38 -1
- package/public/docs/components/rating.md +2 -0
- package/public/docs/components/score-ring.md +2 -0
- package/public/docs/components/search.md +2 -0
- package/public/docs/components/section-heading.md +2 -0
- package/public/docs/components/segmented-control.md +2 -0
- package/public/docs/components/select.md +3 -1
- package/public/docs/components/sheet.md +2 -0
- package/public/docs/components/sidebar.md +2 -0
- package/public/docs/components/skeleton.md +2 -0
- package/public/docs/components/slider.md +3 -1
- package/public/docs/components/sparkline.md +2 -0
- package/public/docs/components/spinner.md +4 -2
- package/public/docs/components/stat.md +2 -0
- package/public/docs/components/status-tracker.md +2 -0
- package/public/docs/components/stepper.md +2 -0
- package/public/docs/components/switch.md +4 -2
- package/public/docs/components/tabs.md +2 -0
- package/public/docs/components/tag.md +2 -0
- package/public/docs/components/textarea.md +2 -0
- package/public/docs/components/time-field.md +127 -0
- package/public/docs/components/timeline.md +2 -0
- package/public/docs/components/toast.md +2 -0
- package/public/docs/components/tool-call.md +2 -0
- package/public/docs/components/tooltip.md +2 -0
- package/public/manifest/components.json +947 -72
- package/public/manifest/tokens.json +36 -5
- package/scripts/division-ds.mjs +5 -5
- package/scripts/lib/agent-docs.mjs +49 -6
- package/scripts/lib/ai-copy.mjs +15 -1
- package/scripts/lib/check-text.mjs +13 -0
- package/scripts/lib/mcp-server.mjs +2 -1
- package/scripts/lib/mcp-tools.mjs +25 -12
- package/scripts/lib/props-validator.mjs +2 -1
- package/scripts/lib/search-score.mjs +24 -0
- package/scripts/lib/token-discipline.mjs +10 -3
- package/skills/division-ds/SKILL.md +2 -2
- package/skills/division-ds/commands/add.md +1 -1
- package/skills/division-ds/commands/build.md +1 -1
- package/skills/division-ds/commands/fix.md +1 -1
- package/skills/division-ds/commands/review.md +2 -2
- package/skills/division-ds/topics/ai.md +2 -1
- package/skills/division-ds/topics/forms.md +3 -0
- package/skills/division-ds/topics/layout.md +3 -1
- package/division-ds-0.2.0.tgz +0 -0
|
@@ -1537,7 +1537,7 @@
|
|
|
1537
1537
|
"name": "tone",
|
|
1538
1538
|
"type": "'signal' | 'ok' | 'warning' | 'hostile'",
|
|
1539
1539
|
"default": "'signal'",
|
|
1540
|
-
"description": "The fill colour. signal paints accent.signal.
|
|
1540
|
+
"description": "The fill colour. signal paints accent.signal.indicator to match Slider. On the track in light theme that’s a 2.15:1 contrast ratio, below the 3:1 a bar needs when it’s the only sign of progress. So set showValue there."
|
|
1541
1541
|
},
|
|
1542
1542
|
{
|
|
1543
1543
|
"name": "className",
|
|
@@ -1738,7 +1738,7 @@
|
|
|
1738
1738
|
}
|
|
1739
1739
|
],
|
|
1740
1740
|
"dos": [
|
|
1741
|
-
"Name the group
|
|
1741
|
+
"Name the group: in a form, a fieldset legend that the RadioGroup points at with aria-labelledby; elsewhere, aria-label.",
|
|
1742
1742
|
"Offer a default when one option really is the norm.",
|
|
1743
1743
|
"Keep the set short. Past about seven options, use a Select."
|
|
1744
1744
|
],
|
|
@@ -1747,6 +1747,13 @@
|
|
|
1747
1747
|
"Don't put a radio outside a RadioGroup. Both the roving focus and the value come from the group.",
|
|
1748
1748
|
"Don't make choosing an option perform the action. Put a button after the group."
|
|
1749
1749
|
],
|
|
1750
|
+
"pitfalls": [
|
|
1751
|
+
{
|
|
1752
|
+
"wrong": "<FormField label=\"Difficulty\" error={error}>\n <RadioGroup>\n <Radio value=\"easy\" />\n </RadioGroup>\n</FormField>",
|
|
1753
|
+
"right": "<fieldset aria-describedby={error ? 'difficulty-error' : undefined}>\n <legend id=\"difficulty-label\" className=\"font-mono text-[11px] font-semibold uppercase tracking-[0.12em] text-[var(--color-text-primary)]\">\n Difficulty\n </legend>\n <RadioGroup aria-labelledby=\"difficulty-label\" aria-required=\"true\" value={value} onValueChange={setValue} className=\"mt-2\">\n {['easy', 'moderate', 'hard'].map(option => (\n <div key={option} className=\"flex items-center gap-2\">\n <Radio id={`difficulty-${option}`} value={option} invalid={Boolean(error)} />\n <label htmlFor={`difficulty-${option}`} className=\"font-body text-sm\">{option}</label>\n </div>\n ))}\n </RadioGroup>\n {error ? (\n <p id=\"difficulty-error\" className=\"mt-1.5 font-body text-sm text-[var(--color-accent-hostile-text)]\">{error}</p>\n ) : null}\n</fieldset>",
|
|
1754
|
+
"why": "FormField clones one control and gives it an id and a label; a group of radios has neither. The fieldset and legend name the group, the label styles match FormField, and the error is linked through aria-describedby. Give ErrorSummary the id of the first Radio so its link lands in the group."
|
|
1755
|
+
}
|
|
1756
|
+
],
|
|
1750
1757
|
"anatomy": [
|
|
1751
1758
|
{
|
|
1752
1759
|
"part": "RadioGroup",
|
|
@@ -2114,7 +2121,7 @@
|
|
|
2114
2121
|
},
|
|
2115
2122
|
{
|
|
2116
2123
|
"part": "Item",
|
|
2117
|
-
"description": "Highlighted rows use signal.
|
|
2124
|
+
"description": "Highlighted rows use accent.signal.indicator with accent.signal.indicator-ink. That’s the fill-selection grammar, the system’s rule for how a selection looks."
|
|
2118
2125
|
},
|
|
2119
2126
|
{
|
|
2120
2127
|
"part": "ItemIndicator",
|
|
@@ -2446,7 +2453,7 @@
|
|
|
2446
2453
|
},
|
|
2447
2454
|
{
|
|
2448
2455
|
"part": "Range",
|
|
2449
|
-
"description": "The filled span, in signal.
|
|
2456
|
+
"description": "The filled span, in accent.signal.indicator."
|
|
2450
2457
|
},
|
|
2451
2458
|
{
|
|
2452
2459
|
"part": "Thumb",
|
|
@@ -2669,7 +2676,7 @@
|
|
|
2669
2676
|
{
|
|
2670
2677
|
"name": "spinnerVariants",
|
|
2671
2678
|
"kind": "const",
|
|
2672
|
-
"code": "export const spinnerVariants = cva(\n // The arc takes `currentColor`, so a caller can recolour it with one text utility: Button does\n // exactly that, so the arc matches whatever ink the button label is set in.\n 'inline-block shrink-0 text-[var(--color-accent-signal-
|
|
2679
|
+
"code": "export const spinnerVariants = cva(\n // The arc takes `currentColor`, so a caller can recolour it with one text utility: Button does\n // exactly that, so the arc matches whatever ink the button label is set in.\n 'inline-block shrink-0 text-[var(--color-accent-signal-indicator)]',\n {\n variants: {\n size: { sm: 'w-3.5 h-3.5', md: 'w-5 h-5', lg: 'w-6 h-6' },\n },\n defaultVariants: { size: 'md' },\n }\n)",
|
|
2673
2680
|
"from": "src/components/atoms/spinner/Spinner"
|
|
2674
2681
|
}
|
|
2675
2682
|
],
|
|
@@ -2692,7 +2699,7 @@
|
|
|
2692
2699
|
},
|
|
2693
2700
|
{
|
|
2694
2701
|
"part": "Ring (ring)",
|
|
2695
|
-
"description": "An SVG (Scalable Vector Graphics) track at 20% of currentColor, which is the surrounding text colour, plus an arc in currentColor. That's accent.signal.
|
|
2702
|
+
"description": "An SVG (Scalable Vector Graphics) track at 20% of currentColor, which is the surrounding text colour, plus an arc in currentColor. That's accent.signal.indicator by default."
|
|
2696
2703
|
},
|
|
2697
2704
|
{
|
|
2698
2705
|
"part": "Blocks (conveyor)",
|
|
@@ -2843,11 +2850,11 @@
|
|
|
2843
2850
|
},
|
|
2844
2851
|
{
|
|
2845
2852
|
"part": "Thumb",
|
|
2846
|
-
"description": "A 16px (pixel) square, 3px from the track edge in both states, travelling 22px. Its position is the state signal. It's text.primary when off and accent.signal.
|
|
2853
|
+
"description": "A 16px (pixel) square, 3px from the track edge in both states, travelling 22px. Its position is the state signal. It's text.primary when off and accent.signal.indicator when on. Held down, it stretches 4px away from the edge it rests on: to the right when off, to the left when on, so it never leaves the track. Flipped, it speeds up across the track, gets a little longer in flight and a little shorter against the far edge, then goes back to its own shape. One give, no bounce."
|
|
2847
2854
|
},
|
|
2848
2855
|
{
|
|
2849
2856
|
"part": "Track fill",
|
|
2850
|
-
"description": "The control fill, on and off. When it's on, only the border turns to signal.
|
|
2857
|
+
"description": "The control fill, on and off. When it's on, only the border turns to accent.signal.indicator. The track doesn't fill with the accent, so the thumb is the one thing that changes colour during a flip."
|
|
2851
2858
|
}
|
|
2852
2859
|
],
|
|
2853
2860
|
"examples": [
|
|
@@ -4227,109 +4234,752 @@
|
|
|
4227
4234
|
"description": "Small buttons under an assistant message. They aren't shown on a user message."
|
|
4228
4235
|
},
|
|
4229
4236
|
{
|
|
4230
|
-
"name": "className",
|
|
4237
|
+
"name": "className",
|
|
4238
|
+
"type": "string",
|
|
4239
|
+
"description": "Goes on the article."
|
|
4240
|
+
},
|
|
4241
|
+
{
|
|
4242
|
+
"name": "onSubmit (ResponseFeedback)",
|
|
4243
|
+
"type": "(vote: 'helpful' | 'not-helpful') => void | Promise<void>",
|
|
4244
|
+
"description": "Required. Runs on a thumbs up or down. Return a promise to show \"Submitting feedback\" until it settles; a rejection puts the buttons back."
|
|
4245
|
+
},
|
|
4246
|
+
{
|
|
4247
|
+
"name": "onDetail (ResponseFeedback)",
|
|
4248
|
+
"type": "(text: string) => void",
|
|
4249
|
+
"description": "Offers an optional, dismissable \"what was wrong\" box after a Not helpful vote. Leave it out for no such step."
|
|
4250
|
+
},
|
|
4251
|
+
{
|
|
4252
|
+
"name": "className (ResponseFeedback)",
|
|
4253
|
+
"type": "string",
|
|
4254
|
+
"description": "Goes on the group."
|
|
4255
|
+
}
|
|
4256
|
+
],
|
|
4257
|
+
"api": [
|
|
4258
|
+
{
|
|
4259
|
+
"name": "ChatMessageRole",
|
|
4260
|
+
"kind": "type",
|
|
4261
|
+
"code": "export type ChatMessageRole = 'user' | 'assistant' | 'system'",
|
|
4262
|
+
"from": "src/components/molecules/chat-message/ChatMessage"
|
|
4263
|
+
},
|
|
4264
|
+
{
|
|
4265
|
+
"name": "FeedbackVote",
|
|
4266
|
+
"kind": "type",
|
|
4267
|
+
"code": "export type FeedbackVote = 'helpful' | 'not-helpful'",
|
|
4268
|
+
"from": "src/components/molecules/chat-message/ResponseFeedback"
|
|
4269
|
+
}
|
|
4270
|
+
],
|
|
4271
|
+
"keyboard": [
|
|
4272
|
+
{
|
|
4273
|
+
"keys": [
|
|
4274
|
+
"Tab"
|
|
4275
|
+
],
|
|
4276
|
+
"does": "Moves to the controls inside the message: a ToolCall's details, an approval's buttons, the actions."
|
|
4277
|
+
}
|
|
4278
|
+
],
|
|
4279
|
+
"dos": [
|
|
4280
|
+
"Keep streaming true until the last piece of text has arrived, then set it to false once.",
|
|
4281
|
+
"Put tool calls and approvals in the assistant message where they happened, in order with its text.",
|
|
4282
|
+
"Use a system line for events in the conversation itself: stopped, retried, context cleared.",
|
|
4283
|
+
"Give every message an author, including a system line (\"Status\"). It names the article.",
|
|
4284
|
+
"Put ResponseFeedback in the actions of a generated reply once it has finished streaming, so a vote rates the whole reply."
|
|
4285
|
+
],
|
|
4286
|
+
"donts": [
|
|
4287
|
+
"Don't animate the text in yourself. useStreamedText or your stream supplies it, and the thread handles announcing it.",
|
|
4288
|
+
"Don't put actions on the person's own message. Editing a sent message is a different flow.",
|
|
4289
|
+
"Don't colour the assistant's text. The bubble, the alignment and the author line already tell the roles apart."
|
|
4290
|
+
],
|
|
4291
|
+
"pitfalls": [
|
|
4292
|
+
{
|
|
4293
|
+
"wrong": "<ChatMessage role=\"assistant\" author=\"Assistant\">{partial}<span className=\"animate-pulse\">▍</span></ChatMessage>",
|
|
4294
|
+
"right": "<ChatMessage role=\"assistant\" author=\"Assistant\" streaming={!done}>{partial}</ChatMessage>",
|
|
4295
|
+
"why": "streaming sets aria-busy, draws a caret that doesn't blink, and tells the thread to announce the text once, when it's finished. A hand-made blinking caret flashes for the whole stream."
|
|
4296
|
+
}
|
|
4297
|
+
],
|
|
4298
|
+
"anatomy": [
|
|
4299
|
+
{
|
|
4300
|
+
"part": "Article",
|
|
4301
|
+
"description": "Named by the author line, so a screen reader hears who's speaking first. Has aria-busy while streaming."
|
|
4302
|
+
},
|
|
4303
|
+
{
|
|
4304
|
+
"part": "Author line",
|
|
4305
|
+
"description": "The author as a label in monospaced type, then the time in a <time dateTime> element."
|
|
4306
|
+
},
|
|
4307
|
+
{
|
|
4308
|
+
"part": "Bubble (user)",
|
|
4309
|
+
"description": "The person's words on surface.sunken, aligned right, at most 85% of the width."
|
|
4310
|
+
},
|
|
4311
|
+
{
|
|
4312
|
+
"part": "Body (assistant)",
|
|
4313
|
+
"description": "Full width, with no bubble: text, paragraphs, and ToolCall and ApprovalRequest blocks stacked in a column."
|
|
4314
|
+
},
|
|
4315
|
+
{
|
|
4316
|
+
"part": "Caret",
|
|
4317
|
+
"description": "A solid block in the signal colour after the last paragraph while streaming, drawn with the CSS ::after rule. It never blinks."
|
|
4318
|
+
},
|
|
4319
|
+
{
|
|
4320
|
+
"part": "Actions",
|
|
4321
|
+
"description": "Small buttons under an assistant message: Copy, Retry, and ResponseFeedback (thumbs up and down)."
|
|
4322
|
+
},
|
|
4323
|
+
{
|
|
4324
|
+
"part": "System line",
|
|
4325
|
+
"description": "A centred label in monospaced type between two thin lines: \"Assistant stopped\". Its author is there for screen readers only."
|
|
4326
|
+
}
|
|
4327
|
+
],
|
|
4328
|
+
"examples": [
|
|
4329
|
+
{
|
|
4330
|
+
"caption": "The three roles",
|
|
4331
|
+
"source": "<div className=\"flex w-full max-w-xl flex-col gap-6\">\n <ChatMessage role=\"user\" author=\"You\" time=\"2026-10-15T09:40:00+03:00\" timeLabel=\"09:40\">\n Which replicas are running low at Depot 4?\n </ChatMessage>\n <ChatMessage\n role=\"assistant\"\n author=\"Assistant\"\n time=\"2026-10-15T09:40:00+03:00\"\n timeLabel=\"09:40\"\n actions={\n <>\n <Button size=\"xs\" variant=\"ghost\" iconStart={<Copy />}>\n Copy\n </Button>\n <Button size=\"xs\" variant=\"ghost\" iconStart={<RotateCcw />}>\n Retry\n </Button>\n </>\n }\n >\n Two are under their reorder point: the K-41 field radio (6 left, reorder at 10) and the trail\n pack (3 left, reorder at 8). Everything else has at least two weeks of cover.\n </ChatMessage>\n <ChatMessage role=\"system\" author=\"Status\">\n Assistant stopped\n </ChatMessage>\n</div>"
|
|
4332
|
+
},
|
|
4333
|
+
{
|
|
4334
|
+
"caption": "While the reply is still streaming in: aria-busy, an ARIA (Accessible Rich Internet Applications) attribute that tells screen readers the message isn't finished, and a cursor that doesn't blink",
|
|
4335
|
+
"source": "<div className=\"flex w-full max-w-xl flex-col gap-6\">\n <ChatMessage role=\"assistant\" author=\"Assistant\" streaming>\n Depot 4 holds 1,240 replicas across 38 lines. The busiest\n </ChatMessage>\n</div>"
|
|
4336
|
+
},
|
|
4337
|
+
{
|
|
4338
|
+
"caption": "Feedback on a reply: thumbs up or down, one vote, and an optional detail step after Not helpful",
|
|
4339
|
+
"source": "const pretendSend = () => new Promise<void>(resolve => setTimeout(resolve, 800))\n\n<div className=\"flex w-full max-w-xl flex-col gap-6\">\n <ChatMessage\n role=\"assistant\"\n author=\"Assistant\"\n actions={<ResponseFeedback onSubmit={pretendSend} onDetail={() => {}} />}\n >\n Depot 4 holds 1,240 replicas. Eleven are below their reorder point.\n </ChatMessage>\n</div>"
|
|
4340
|
+
}
|
|
4341
|
+
]
|
|
4342
|
+
},
|
|
4343
|
+
{
|
|
4344
|
+
"name": "DatePicker",
|
|
4345
|
+
"title": "Date picker",
|
|
4346
|
+
"tier": "molecules",
|
|
4347
|
+
"slug": "date-picker",
|
|
4348
|
+
"summary": "One date, typed or picked. The field has a segment for the day, the month and the year, in the order your language writes them: type the digits and it moves on by itself, or use the arrow keys. The button inside it opens a calendar. The value is a plain 'YYYY-MM-DD' string with no time zone, so it means the same day for everyone. Calendar and DateField are exported too, for building your own.",
|
|
4349
|
+
"useWhen": "One date: a delivery day, a deadline, a birthday.",
|
|
4350
|
+
"notFor": "A range: DateRangePicker. A time: TimeField.",
|
|
4351
|
+
"source": "src/components/molecules/date-picker/DatePicker.tsx",
|
|
4352
|
+
"docs": "/docs/components/date-picker.md",
|
|
4353
|
+
"imports": [
|
|
4354
|
+
{
|
|
4355
|
+
"names": [
|
|
4356
|
+
"Calendar"
|
|
4357
|
+
],
|
|
4358
|
+
"from": "src/components/molecules/date-picker/Calendar"
|
|
4359
|
+
},
|
|
4360
|
+
{
|
|
4361
|
+
"names": [
|
|
4362
|
+
"DateField"
|
|
4363
|
+
],
|
|
4364
|
+
"from": "src/components/molecules/date-picker/DateField"
|
|
4365
|
+
},
|
|
4366
|
+
{
|
|
4367
|
+
"names": [
|
|
4368
|
+
"DatePicker"
|
|
4369
|
+
],
|
|
4370
|
+
"from": "src/components/molecules/date-picker/DatePicker"
|
|
4371
|
+
}
|
|
4372
|
+
],
|
|
4373
|
+
"props": [
|
|
4374
|
+
{
|
|
4375
|
+
"name": "label",
|
|
4376
|
+
"type": "string",
|
|
4377
|
+
"description": "Required. Names the field. Inside a FormField, FormField sets it from its own label."
|
|
4378
|
+
},
|
|
4379
|
+
{
|
|
4380
|
+
"name": "value",
|
|
4381
|
+
"type": "string ('YYYY-MM-DD' | '')",
|
|
4382
|
+
"description": "Controlled value (your page holds it)."
|
|
4383
|
+
},
|
|
4384
|
+
{
|
|
4385
|
+
"name": "defaultValue",
|
|
4386
|
+
"type": "string",
|
|
4387
|
+
"default": "''",
|
|
4388
|
+
"description": "Starting value when the picker holds the value itself."
|
|
4389
|
+
},
|
|
4390
|
+
{
|
|
4391
|
+
"name": "onValueChange",
|
|
4392
|
+
"type": "(value: string) => void",
|
|
4393
|
+
"description": "Fires with a whole, real date, or '' when the field is emptied. A half-typed date does not fire."
|
|
4394
|
+
},
|
|
4395
|
+
{
|
|
4396
|
+
"name": "min",
|
|
4397
|
+
"type": "string",
|
|
4398
|
+
"description": "Earliest date, 'YYYY-MM-DD'. Earlier days are struck through; typing one marks the field invalid."
|
|
4399
|
+
},
|
|
4400
|
+
{
|
|
4401
|
+
"name": "max",
|
|
4402
|
+
"type": "string",
|
|
4403
|
+
"description": "Latest date, 'YYYY-MM-DD'."
|
|
4404
|
+
},
|
|
4405
|
+
{
|
|
4406
|
+
"name": "isDateDisabled",
|
|
4407
|
+
"type": "(date: string) => boolean",
|
|
4408
|
+
"description": "Days that cannot be picked, such as weekends or holidays."
|
|
4409
|
+
},
|
|
4410
|
+
{
|
|
4411
|
+
"name": "locale",
|
|
4412
|
+
"type": "string",
|
|
4413
|
+
"description": "A language tag such as 'en-GB' or 'de'. Sets the segment order, the separator, the month and day names and the first day of the week. Defaults to the browser's."
|
|
4414
|
+
},
|
|
4415
|
+
{
|
|
4416
|
+
"name": "weekStartsOn",
|
|
4417
|
+
"type": "number",
|
|
4418
|
+
"description": "0 Sunday to 6 Saturday. Defaults to the locale's."
|
|
4419
|
+
},
|
|
4420
|
+
{
|
|
4421
|
+
"name": "showToday",
|
|
4422
|
+
"type": "boolean",
|
|
4423
|
+
"default": "true",
|
|
4424
|
+
"description": "Shows the Today button under the calendar when today can be picked."
|
|
4425
|
+
},
|
|
4426
|
+
{
|
|
4427
|
+
"name": "disabled",
|
|
4428
|
+
"type": "boolean",
|
|
4429
|
+
"default": "false",
|
|
4430
|
+
"description": "Disables the field and the calendar button."
|
|
4431
|
+
},
|
|
4432
|
+
{
|
|
4433
|
+
"name": "name",
|
|
4434
|
+
"type": "string",
|
|
4435
|
+
"description": "Submits the 'YYYY-MM-DD' value with a form, through a hidden input."
|
|
4436
|
+
},
|
|
4437
|
+
{
|
|
4438
|
+
"name": "invalid",
|
|
4439
|
+
"type": "boolean",
|
|
4440
|
+
"description": "Marks the field invalid. FormField sets it when there is an error."
|
|
4441
|
+
},
|
|
4442
|
+
{
|
|
4443
|
+
"name": "required",
|
|
4444
|
+
"type": "boolean",
|
|
4445
|
+
"description": "Marks the field required. FormField sets it."
|
|
4446
|
+
},
|
|
4447
|
+
{
|
|
4448
|
+
"name": "id",
|
|
4449
|
+
"type": "string",
|
|
4450
|
+
"description": "The field's id, so a FormField's error text can point at it. FormField sets it."
|
|
4451
|
+
},
|
|
4452
|
+
{
|
|
4453
|
+
"name": "aria-describedby",
|
|
4454
|
+
"type": "string",
|
|
4455
|
+
"description": "The ids of the help and error text. FormField sets it."
|
|
4456
|
+
},
|
|
4457
|
+
{
|
|
4458
|
+
"name": "className",
|
|
4459
|
+
"type": "string",
|
|
4460
|
+
"description": "Combined with the field's classes."
|
|
4461
|
+
},
|
|
4462
|
+
{
|
|
4463
|
+
"name": "ref",
|
|
4464
|
+
"type": "Ref<HTMLDivElement>",
|
|
4465
|
+
"description": "The field's group element."
|
|
4466
|
+
},
|
|
4467
|
+
{
|
|
4468
|
+
"name": "trailing (DateField)",
|
|
4469
|
+
"type": "ReactNode",
|
|
4470
|
+
"description": "Something inside the field after the segments. DatePicker puts its calendar button here."
|
|
4471
|
+
},
|
|
4472
|
+
{
|
|
4473
|
+
"name": "bare (DateField)",
|
|
4474
|
+
"type": "boolean",
|
|
4475
|
+
"default": "false",
|
|
4476
|
+
"description": "No border, fill or ring of its own, for two dates inside one border (DateRangePicker draws them)."
|
|
4477
|
+
},
|
|
4478
|
+
{
|
|
4479
|
+
"name": "onSelect (Calendar)",
|
|
4480
|
+
"type": "(date: string) => void",
|
|
4481
|
+
"description": "A day was picked with a click, Enter or Space."
|
|
4482
|
+
},
|
|
4483
|
+
{
|
|
4484
|
+
"name": "value (Calendar)",
|
|
4485
|
+
"type": "string | null",
|
|
4486
|
+
"description": "The picked day. Ignored when dayState is given."
|
|
4487
|
+
},
|
|
4488
|
+
{
|
|
4489
|
+
"name": "month (Calendar)",
|
|
4490
|
+
"type": "string",
|
|
4491
|
+
"description": "Any day in the first month shown. Controlled with onMonthChange."
|
|
4492
|
+
},
|
|
4493
|
+
{
|
|
4494
|
+
"name": "defaultMonth (Calendar)",
|
|
4495
|
+
"type": "string",
|
|
4496
|
+
"description": "The first month shown when the calendar holds it itself. Defaults to the value's month, or today's."
|
|
4497
|
+
},
|
|
4498
|
+
{
|
|
4499
|
+
"name": "onMonthChange (Calendar)",
|
|
4500
|
+
"type": "(month: string) => void",
|
|
4501
|
+
"description": "Fires with the new first month's 1st day."
|
|
4502
|
+
},
|
|
4503
|
+
{
|
|
4504
|
+
"name": "dayState (Calendar)",
|
|
4505
|
+
"type": "(date: string) => 'single' | 'start' | 'end' | 'start-end' | 'middle' | undefined",
|
|
4506
|
+
"description": "Draws each day yourself, for a range or any other selection."
|
|
4507
|
+
},
|
|
4508
|
+
{
|
|
4509
|
+
"name": "onDayEnter (Calendar)",
|
|
4510
|
+
"type": "(date: string) => void",
|
|
4511
|
+
"description": "The keyboard or the pointer moved onto a day. A range uses it to preview the band."
|
|
4512
|
+
},
|
|
4513
|
+
{
|
|
4514
|
+
"name": "numberOfMonths (Calendar)",
|
|
4515
|
+
"type": "1 | 2",
|
|
4516
|
+
"default": "1",
|
|
4517
|
+
"description": "Months side by side, stacked on narrow screens."
|
|
4518
|
+
},
|
|
4519
|
+
{
|
|
4520
|
+
"name": "autoFocus (Calendar)",
|
|
4521
|
+
"type": "boolean",
|
|
4522
|
+
"default": "false",
|
|
4523
|
+
"description": "Moves focus to the picked day, or today, when the calendar appears."
|
|
4524
|
+
}
|
|
4525
|
+
],
|
|
4526
|
+
"api": [
|
|
4527
|
+
{
|
|
4528
|
+
"name": "DayState",
|
|
4529
|
+
"kind": "type",
|
|
4530
|
+
"code": "/** How a day is drawn. `single` is one picked day; the rest belong to a range. */\nexport type DayState = 'single' | 'start' | 'end' | 'start-end' | 'middle'",
|
|
4531
|
+
"from": "src/components/molecules/date-picker/Calendar"
|
|
4532
|
+
}
|
|
4533
|
+
],
|
|
4534
|
+
"keyboard": [
|
|
4535
|
+
{
|
|
4536
|
+
"keys": [
|
|
4537
|
+
"0–9"
|
|
4538
|
+
],
|
|
4539
|
+
"does": "Types into the focused segment and moves on once it is full."
|
|
4540
|
+
},
|
|
4541
|
+
{
|
|
4542
|
+
"keys": [
|
|
4543
|
+
"↑",
|
|
4544
|
+
"↓"
|
|
4545
|
+
],
|
|
4546
|
+
"does": "In the field: one more or one less in the segment. In the calendar: a week earlier or later."
|
|
4547
|
+
},
|
|
4548
|
+
{
|
|
4549
|
+
"keys": [
|
|
4550
|
+
"←",
|
|
4551
|
+
"→"
|
|
4552
|
+
],
|
|
4553
|
+
"does": "In the field: the previous or next segment. In the calendar: the day before or after."
|
|
4554
|
+
},
|
|
4555
|
+
{
|
|
4556
|
+
"keys": [
|
|
4557
|
+
"Backspace"
|
|
4558
|
+
],
|
|
4559
|
+
"does": "Clears the segment, or moves back when it is already empty."
|
|
4560
|
+
},
|
|
4561
|
+
{
|
|
4562
|
+
"keys": [
|
|
4563
|
+
"Page Up",
|
|
4564
|
+
"Page Down"
|
|
4565
|
+
],
|
|
4566
|
+
"does": "The same day a month earlier or later. With Shift, a year."
|
|
4567
|
+
},
|
|
4568
|
+
{
|
|
4569
|
+
"keys": [
|
|
4570
|
+
"Home",
|
|
4571
|
+
"End"
|
|
4572
|
+
],
|
|
4573
|
+
"does": "The first or last day of the week."
|
|
4574
|
+
},
|
|
4575
|
+
{
|
|
4576
|
+
"keys": [
|
|
4577
|
+
"Enter",
|
|
4578
|
+
"Space"
|
|
4579
|
+
],
|
|
4580
|
+
"does": "Picks the focused day and closes the calendar."
|
|
4581
|
+
},
|
|
4582
|
+
{
|
|
4583
|
+
"keys": [
|
|
4584
|
+
"Esc"
|
|
4585
|
+
],
|
|
4586
|
+
"does": "Closes the calendar without a change."
|
|
4587
|
+
}
|
|
4588
|
+
],
|
|
4589
|
+
"dos": [
|
|
4590
|
+
"Store and send the 'YYYY-MM-DD' value as it is. It has no time zone, so it can't shift by a day.",
|
|
4591
|
+
"Set min and max to the real limits, so days nobody can book are struck through rather than refused after the fact.",
|
|
4592
|
+
"Wrap it in a FormField for a visible label, help text and errors."
|
|
4593
|
+
],
|
|
4594
|
+
"donts": [
|
|
4595
|
+
"Don't convert the value with new Date('2026-11-14'): that reads it as midnight UTC and can show the day before in the Americas.",
|
|
4596
|
+
"Don't hide unavailable days. Struck through and announced, they explain themselves.",
|
|
4597
|
+
"Don't use it for a date of birth without setting max to today."
|
|
4598
|
+
],
|
|
4599
|
+
"anatomy": [
|
|
4600
|
+
{
|
|
4601
|
+
"part": "Field (DateField)",
|
|
4602
|
+
"description": "A group named by the label, holding three spinbuttons (Day, Month, Year). Each says its value or \"Empty\". A date that does not exist (31 February) or falls outside min and max marks the field invalid."
|
|
4603
|
+
},
|
|
4604
|
+
{
|
|
4605
|
+
"part": "Calendar button",
|
|
4606
|
+
"description": "A ghost IconButton inside the field. Its name includes the picked date: \"Choose date, Saturday, 14 November 2026\"."
|
|
4607
|
+
},
|
|
4608
|
+
{
|
|
4609
|
+
"part": "Calendar",
|
|
4610
|
+
"description": "A grid with one tab stop. Each day is a button named with the full date. The picked day is a solid accent square with a cut corner; today has aria-current and a short bar under its number. Days that can't be picked stay visible, struck through and announced as unavailable."
|
|
4611
|
+
},
|
|
4612
|
+
{
|
|
4613
|
+
"part": "Today",
|
|
4614
|
+
"description": "A secondary Button under the calendar, shown only when today can be picked."
|
|
4615
|
+
}
|
|
4616
|
+
],
|
|
4617
|
+
"examples": [
|
|
4618
|
+
{
|
|
4619
|
+
"caption": "Default",
|
|
4620
|
+
"source": "<div className=\"w-full max-w-xs\">\n <DatePicker label=\"Delivery date\" />\n</div>"
|
|
4621
|
+
},
|
|
4622
|
+
{
|
|
4623
|
+
"caption": "In a FormField, with help text",
|
|
4624
|
+
"source": "<div className=\"w-full max-w-xs\">\n <FormField label=\"Trip date\" help=\"Type it, or open the calendar.\">\n <DatePicker label=\"Trip date\" />\n </FormField>\n</div>"
|
|
4625
|
+
},
|
|
4626
|
+
{
|
|
4627
|
+
"caption": "Controlled: the page holds the value",
|
|
4628
|
+
"source": "function Controlled() {\n const [date, setDate] = useState('2026-11-14')\n return (\n <div className=\"flex w-full max-w-xs flex-col gap-2\">\n <DatePicker label=\"Dispatch date\" value={date} onValueChange={setDate} />\n <span className=\"font-mono text-xs text-[var(--color-text-secondary)]\">value: {date ? `'${date}'` : \"''\"}</span>\n </div>\n )\n}\n\n<Controlled />"
|
|
4629
|
+
},
|
|
4630
|
+
{
|
|
4631
|
+
"caption": "Limits: weekdays only, within the next two months",
|
|
4632
|
+
"source": "const weekend = (date: string) => [0, 6].includes(new Date(`${date}T12:00:00Z`).getUTCDay())\n\n<div className=\"w-full max-w-xs\">\n <DatePicker label=\"Collection day\" min=\"2026-11-02\" max=\"2026-12-31\" defaultValue=\"2026-11-16\" isDateDisabled={weekend} />\n</div>"
|
|
4633
|
+
},
|
|
4634
|
+
{
|
|
4635
|
+
"caption": "US order and a Sunday start, from the locale",
|
|
4636
|
+
"source": "<div className=\"w-full max-w-xs\">\n <DatePicker label=\"Ship date\" locale=\"en-US\" defaultValue=\"2026-11-14\" />\n</div>"
|
|
4637
|
+
},
|
|
4638
|
+
{
|
|
4639
|
+
"caption": "The calendar on its own",
|
|
4640
|
+
"source": "function InlineCalendar() {\n const [date, setDate] = useState<string | null>(null)\n return (\n <div className=\"flex flex-col gap-2\">\n <Calendar value={date} onSelect={setDate} />\n <span className=\"font-mono text-xs text-[var(--color-text-secondary)]\">{date ? formatLong(date) : 'No day picked'}</span>\n </div>\n )\n}\n\n<InlineCalendar />"
|
|
4641
|
+
}
|
|
4642
|
+
]
|
|
4643
|
+
},
|
|
4644
|
+
{
|
|
4645
|
+
"name": "DatePresets",
|
|
4646
|
+
"title": "Date presets",
|
|
4647
|
+
"tier": "molecules",
|
|
4648
|
+
"slug": "date-presets",
|
|
4649
|
+
"summary": "Named periods such as Last 7 days, one click each. The defaults: Today, Yesterday, Last 7 days, Last 30 days, This month, Last month, This year, or your own. An add-on: put it in a DateRangePicker's aside and it reads and sets the picker's range by itself, then closes it. On its own it is a list you give a value and an onSelect. Installs DateRangePicker and DatePicker with it.",
|
|
4650
|
+
"useWhen": "Reports and logs, where people want the usual periods.",
|
|
4651
|
+
"notFor": "Exact dates: DateRangePicker alone.",
|
|
4652
|
+
"source": "src/components/molecules/date-presets/DatePresets.tsx",
|
|
4653
|
+
"docs": "/docs/components/date-presets.md",
|
|
4654
|
+
"imports": [
|
|
4655
|
+
{
|
|
4656
|
+
"names": [
|
|
4657
|
+
"DatePresets",
|
|
4658
|
+
"defaultPresets"
|
|
4659
|
+
],
|
|
4660
|
+
"from": "src/components/molecules/date-presets/DatePresets"
|
|
4661
|
+
}
|
|
4662
|
+
],
|
|
4663
|
+
"props": [
|
|
4664
|
+
{
|
|
4665
|
+
"name": "presets",
|
|
4666
|
+
"type": "DatePreset[]",
|
|
4667
|
+
"default": "defaultPresets()",
|
|
4668
|
+
"description": "Each { label, range }. Make your own, or start from defaultPresets(today)."
|
|
4669
|
+
},
|
|
4670
|
+
{
|
|
4671
|
+
"name": "value",
|
|
4672
|
+
"type": "{ start: string; end: string }",
|
|
4673
|
+
"description": "The current range. Inside a DateRangePicker it comes from the picker."
|
|
4674
|
+
},
|
|
4675
|
+
{
|
|
4676
|
+
"name": "onSelect",
|
|
4677
|
+
"type": "(range: DateRange) => void",
|
|
4678
|
+
"description": "A preset was chosen. Inside a DateRangePicker the picker also takes it and closes."
|
|
4679
|
+
},
|
|
4680
|
+
{
|
|
4681
|
+
"name": "label",
|
|
4682
|
+
"type": "string",
|
|
4683
|
+
"default": "'Presets'",
|
|
4684
|
+
"description": "The list's accessible name."
|
|
4685
|
+
},
|
|
4686
|
+
{
|
|
4687
|
+
"name": "className",
|
|
4688
|
+
"type": "string",
|
|
4689
|
+
"description": "Combined with the list's classes."
|
|
4690
|
+
},
|
|
4691
|
+
{
|
|
4692
|
+
"name": "ref",
|
|
4693
|
+
"type": "Ref<HTMLDivElement>",
|
|
4694
|
+
"description": "The list element."
|
|
4695
|
+
},
|
|
4696
|
+
{
|
|
4697
|
+
"name": "defaultPresets()",
|
|
4698
|
+
"type": "(today?: string) => DatePreset[]",
|
|
4699
|
+
"description": "The seven usual periods counted back from today ('YYYY-MM-DD'; defaults to the reader's today). Every one includes today."
|
|
4700
|
+
}
|
|
4701
|
+
],
|
|
4702
|
+
"api": [
|
|
4703
|
+
{
|
|
4704
|
+
"name": "DatePreset",
|
|
4705
|
+
"kind": "type",
|
|
4706
|
+
"code": "export type DatePreset = { label: string; range: DateRange }",
|
|
4707
|
+
"from": "src/components/molecules/date-presets/DatePresets"
|
|
4708
|
+
},
|
|
4709
|
+
{
|
|
4710
|
+
"name": "defaultPresets",
|
|
4711
|
+
"kind": "function",
|
|
4712
|
+
"code": "/** The usual periods, counted back from `today` (default: the reader's today). Each includes today. */\nexport function defaultPresets(today: IsoDate = todayIso()): DatePreset[]",
|
|
4713
|
+
"from": "src/components/molecules/date-presets/DatePresets"
|
|
4714
|
+
}
|
|
4715
|
+
],
|
|
4716
|
+
"keyboard": [
|
|
4717
|
+
{
|
|
4718
|
+
"keys": [
|
|
4719
|
+
"Tab"
|
|
4720
|
+
],
|
|
4721
|
+
"does": "Moves through the presets."
|
|
4722
|
+
},
|
|
4723
|
+
{
|
|
4724
|
+
"keys": [
|
|
4725
|
+
"Enter",
|
|
4726
|
+
"Space"
|
|
4727
|
+
],
|
|
4728
|
+
"does": "Chooses the focused preset."
|
|
4729
|
+
}
|
|
4730
|
+
],
|
|
4731
|
+
"dos": [
|
|
4732
|
+
"Keep the list short, seven or fewer.",
|
|
4733
|
+
"Name periods the way your users say them: \"This quarter\" if they plan in quarters."
|
|
4734
|
+
],
|
|
4735
|
+
"donts": [
|
|
4736
|
+
"Don't offer a preset nobody can pick, such as a future period when max is today."
|
|
4737
|
+
],
|
|
4738
|
+
"anatomy": [
|
|
4739
|
+
{
|
|
4740
|
+
"part": "List",
|
|
4741
|
+
"description": "A group named \"Presets\". Each period is a button; the one matching the current range is pressed (aria-pressed) and filled."
|
|
4742
|
+
}
|
|
4743
|
+
],
|
|
4744
|
+
"examples": [
|
|
4745
|
+
{
|
|
4746
|
+
"caption": "Inside a DateRangePicker: no wiring",
|
|
4747
|
+
"source": "<div className=\"w-full max-w-sm\">\n <DateRangePicker label=\"Activity\" aside={<DatePresets />} />\n</div>"
|
|
4748
|
+
},
|
|
4749
|
+
{
|
|
4750
|
+
"caption": "On its own",
|
|
4751
|
+
"source": "function OnItsOwn() {\n const [range, setRange] = useState<DateRange>(defaultPresets()[2].range)\n return (\n <div className=\"flex flex-col gap-3\">\n <DatePresets value={range} onSelect={setRange} />\n <span className=\"font-mono text-xs text-[var(--color-text-secondary)]\">\n {range.start} to {range.end}\n </span>\n </div>\n )\n}\n\n<OnItsOwn />"
|
|
4752
|
+
},
|
|
4753
|
+
{
|
|
4754
|
+
"caption": "Your own periods",
|
|
4755
|
+
"source": "<div className=\"w-full max-w-sm\">\n <DateRangePicker\n label=\"Season\"\n aside={\n <DatePresets\n label=\"Seasons\"\n presets={[\n { label: 'Winter 2026', range: { start: '2026-01-01', end: '2026-03-31' } },\n { label: 'Spring 2026', range: { start: '2026-04-01', end: '2026-06-30' } },\n { label: 'Summer 2026', range: { start: '2026-07-01', end: '2026-09-30' } },\n ]}\n />\n }\n />\n</div>"
|
|
4756
|
+
}
|
|
4757
|
+
]
|
|
4758
|
+
},
|
|
4759
|
+
{
|
|
4760
|
+
"name": "DateRangePicker",
|
|
4761
|
+
"title": "Date range picker",
|
|
4762
|
+
"tier": "molecules",
|
|
4763
|
+
"slug": "date-range-picker",
|
|
4764
|
+
"summary": "A start and an end date in one field, an add-on to DatePicker. Type both, or open two months side by side: the first day you pick is the start, the band follows you to the second, which sets the end and closes the calendar. Put DatePresets in `aside` for one-click periods like Last 7 days. Installs DatePicker with it.",
|
|
4765
|
+
"useWhen": "A booking, a report window, a leave request.",
|
|
4766
|
+
"notFor": "One day: DatePicker.",
|
|
4767
|
+
"source": "src/components/molecules/date-range-picker/DateRangePicker.tsx",
|
|
4768
|
+
"docs": "/docs/components/date-range-picker.md",
|
|
4769
|
+
"imports": [
|
|
4770
|
+
{
|
|
4771
|
+
"names": [
|
|
4772
|
+
"DateRangePicker",
|
|
4773
|
+
"EMPTY_RANGE",
|
|
4774
|
+
"useDateRangePicker"
|
|
4775
|
+
],
|
|
4776
|
+
"from": "src/components/molecules/date-range-picker/DateRangePicker"
|
|
4777
|
+
}
|
|
4778
|
+
],
|
|
4779
|
+
"props": [
|
|
4780
|
+
{
|
|
4781
|
+
"name": "label",
|
|
4782
|
+
"type": "string",
|
|
4783
|
+
"description": "Required. Names the field. Inside a FormField, FormField sets it."
|
|
4784
|
+
},
|
|
4785
|
+
{
|
|
4786
|
+
"name": "value",
|
|
4787
|
+
"type": "{ start: string; end: string }",
|
|
4788
|
+
"description": "Controlled range. Each end is 'YYYY-MM-DD' or ''."
|
|
4789
|
+
},
|
|
4790
|
+
{
|
|
4791
|
+
"name": "defaultValue",
|
|
4792
|
+
"type": "{ start: string; end: string }",
|
|
4793
|
+
"default": "{ start: '', end: '' }",
|
|
4794
|
+
"description": "Starting range when the picker holds it itself."
|
|
4795
|
+
},
|
|
4796
|
+
{
|
|
4797
|
+
"name": "onValueChange",
|
|
4798
|
+
"type": "(range: DateRange) => void",
|
|
4799
|
+
"description": "Fires when either end changes. Days picked in the calendar always arrive in order."
|
|
4800
|
+
},
|
|
4801
|
+
{
|
|
4802
|
+
"name": "min",
|
|
4803
|
+
"type": "string",
|
|
4804
|
+
"description": "Earliest date, 'YYYY-MM-DD'."
|
|
4805
|
+
},
|
|
4806
|
+
{
|
|
4807
|
+
"name": "max",
|
|
4808
|
+
"type": "string",
|
|
4809
|
+
"description": "Latest date, 'YYYY-MM-DD'."
|
|
4810
|
+
},
|
|
4811
|
+
{
|
|
4812
|
+
"name": "isDateDisabled",
|
|
4813
|
+
"type": "(date: string) => boolean",
|
|
4814
|
+
"description": "Days that cannot be picked."
|
|
4815
|
+
},
|
|
4816
|
+
{
|
|
4817
|
+
"name": "locale",
|
|
4818
|
+
"type": "string",
|
|
4819
|
+
"description": "Segment order, names and first day of the week. Defaults to the browser's."
|
|
4820
|
+
},
|
|
4821
|
+
{
|
|
4822
|
+
"name": "weekStartsOn",
|
|
4823
|
+
"type": "number",
|
|
4824
|
+
"description": "0 Sunday to 6 Saturday. Defaults to the locale's."
|
|
4825
|
+
},
|
|
4826
|
+
{
|
|
4827
|
+
"name": "aside",
|
|
4828
|
+
"type": "ReactNode",
|
|
4829
|
+
"description": "Beside the months, in the popover. DatePresets reads and sets the range by itself here."
|
|
4830
|
+
},
|
|
4831
|
+
{
|
|
4832
|
+
"name": "partLabels",
|
|
4833
|
+
"type": "[string, string]",
|
|
4834
|
+
"default": "['Start date', 'End date']",
|
|
4835
|
+
"description": "The names of the two dates."
|
|
4836
|
+
},
|
|
4837
|
+
{
|
|
4838
|
+
"name": "disabled",
|
|
4839
|
+
"type": "boolean",
|
|
4840
|
+
"default": "false",
|
|
4841
|
+
"description": "Disables both dates and the button."
|
|
4842
|
+
},
|
|
4843
|
+
{
|
|
4844
|
+
"name": "invalid",
|
|
4845
|
+
"type": "boolean",
|
|
4846
|
+
"description": "Marks the field invalid. FormField sets it."
|
|
4847
|
+
},
|
|
4848
|
+
{
|
|
4849
|
+
"name": "required",
|
|
4850
|
+
"type": "boolean",
|
|
4851
|
+
"description": "Marks both dates required. FormField sets it."
|
|
4852
|
+
},
|
|
4853
|
+
{
|
|
4854
|
+
"name": "name",
|
|
4855
|
+
"type": "string",
|
|
4856
|
+
"description": "Submits name-start and name-end with a form."
|
|
4857
|
+
},
|
|
4858
|
+
{
|
|
4859
|
+
"name": "id",
|
|
4860
|
+
"type": "string",
|
|
4861
|
+
"description": "The field's id. FormField sets it."
|
|
4862
|
+
},
|
|
4863
|
+
{
|
|
4864
|
+
"name": "aria-describedby",
|
|
4231
4865
|
"type": "string",
|
|
4232
|
-
"description": "
|
|
4866
|
+
"description": "The ids of the help and error text. FormField sets it."
|
|
4233
4867
|
},
|
|
4234
4868
|
{
|
|
4235
|
-
"name": "
|
|
4236
|
-
"type": "
|
|
4237
|
-
"description": "
|
|
4869
|
+
"name": "className",
|
|
4870
|
+
"type": "string",
|
|
4871
|
+
"description": "Combined with the field's classes."
|
|
4238
4872
|
},
|
|
4239
4873
|
{
|
|
4240
|
-
"name": "
|
|
4241
|
-
"type": "
|
|
4242
|
-
"description": "
|
|
4874
|
+
"name": "ref",
|
|
4875
|
+
"type": "Ref<HTMLDivElement>",
|
|
4876
|
+
"description": "The field's group element."
|
|
4243
4877
|
},
|
|
4244
4878
|
{
|
|
4245
|
-
"name": "
|
|
4246
|
-
"type": "
|
|
4247
|
-
"description": "
|
|
4879
|
+
"name": "useDateRangePicker()",
|
|
4880
|
+
"type": "() => { value: DateRange; select: (range: DateRange) => void } | null",
|
|
4881
|
+
"description": "Inside the popover: the range, and a way to set it and close. For your own aside content."
|
|
4248
4882
|
}
|
|
4249
4883
|
],
|
|
4250
4884
|
"api": [
|
|
4251
4885
|
{
|
|
4252
|
-
"name": "
|
|
4886
|
+
"name": "DateRange",
|
|
4253
4887
|
"kind": "type",
|
|
4254
|
-
"code": "
|
|
4255
|
-
"from": "src/components/molecules/
|
|
4888
|
+
"code": "/** A start and an end, each 'YYYY-MM-DD' or '' while not chosen. */\nexport type DateRange = { start: IsoDate | ''; end: IsoDate | '' }",
|
|
4889
|
+
"from": "src/components/molecules/date-range-picker/DateRangePicker"
|
|
4256
4890
|
},
|
|
4257
4891
|
{
|
|
4258
|
-
"name": "
|
|
4259
|
-
"kind": "
|
|
4260
|
-
"code": "export
|
|
4261
|
-
"from": "src/components/molecules/
|
|
4892
|
+
"name": "EMPTY_RANGE",
|
|
4893
|
+
"kind": "const",
|
|
4894
|
+
"code": "export const EMPTY_RANGE: DateRange = { start: '', end: '' }",
|
|
4895
|
+
"from": "src/components/molecules/date-range-picker/DateRangePicker"
|
|
4896
|
+
},
|
|
4897
|
+
{
|
|
4898
|
+
"name": "useDateRangePicker",
|
|
4899
|
+
"kind": "const",
|
|
4900
|
+
"code": "/** The open picker's range, and a way to set it and close. DatePresets reads it, so a preset in\n * `aside` needs no wiring. null outside a DateRangePicker. */\nexport const useDateRangePicker = () => useContext(Context)",
|
|
4901
|
+
"from": "src/components/molecules/date-range-picker/DateRangePicker"
|
|
4262
4902
|
}
|
|
4263
4903
|
],
|
|
4264
4904
|
"keyboard": [
|
|
4265
4905
|
{
|
|
4266
4906
|
"keys": [
|
|
4267
|
-
"
|
|
4907
|
+
"0–9",
|
|
4908
|
+
"↑",
|
|
4909
|
+
"↓"
|
|
4268
4910
|
],
|
|
4269
|
-
"does": "
|
|
4911
|
+
"does": "Types or steps the focused segment of either date."
|
|
4912
|
+
},
|
|
4913
|
+
{
|
|
4914
|
+
"keys": [
|
|
4915
|
+
"←",
|
|
4916
|
+
"→"
|
|
4917
|
+
],
|
|
4918
|
+
"does": "In the field: the next segment, across both dates. In the calendar: the day before or after, moving the band."
|
|
4919
|
+
},
|
|
4920
|
+
{
|
|
4921
|
+
"keys": [
|
|
4922
|
+
"Page Up",
|
|
4923
|
+
"Page Down"
|
|
4924
|
+
],
|
|
4925
|
+
"does": "A month earlier or later. With Shift, a year."
|
|
4926
|
+
},
|
|
4927
|
+
{
|
|
4928
|
+
"keys": [
|
|
4929
|
+
"Enter",
|
|
4930
|
+
"Space"
|
|
4931
|
+
],
|
|
4932
|
+
"does": "Picks the start, then the end, which closes the calendar."
|
|
4933
|
+
},
|
|
4934
|
+
{
|
|
4935
|
+
"keys": [
|
|
4936
|
+
"Esc"
|
|
4937
|
+
],
|
|
4938
|
+
"does": "Closes the calendar. A start picked without an end stays as the start."
|
|
4270
4939
|
}
|
|
4271
4940
|
],
|
|
4272
4941
|
"dos": [
|
|
4273
|
-
"
|
|
4274
|
-
"
|
|
4275
|
-
"Use a system line for events in the conversation itself: stopped, retried, context cleared.",
|
|
4276
|
-
"Give every message an author, including a system line (\"Status\"). It names the article.",
|
|
4277
|
-
"Put ResponseFeedback in the actions of a generated reply once it has finished streaming, so a vote rates the whole reply."
|
|
4942
|
+
"Add DatePresets in aside when people mostly want the usual periods.",
|
|
4943
|
+
"Validate the length yourself if a range has a limit (a 30-day report), and say so in help text."
|
|
4278
4944
|
],
|
|
4279
4945
|
"donts": [
|
|
4280
|
-
"Don't
|
|
4281
|
-
"Don't
|
|
4282
|
-
"Don't colour the assistant's text. The bubble, the alignment and the author line already tell the roles apart."
|
|
4283
|
-
],
|
|
4284
|
-
"pitfalls": [
|
|
4285
|
-
{
|
|
4286
|
-
"wrong": "<ChatMessage role=\"assistant\" author=\"Assistant\">{partial}<span className=\"animate-pulse\">▍</span></ChatMessage>",
|
|
4287
|
-
"right": "<ChatMessage role=\"assistant\" author=\"Assistant\" streaming={!done}>{partial}</ChatMessage>",
|
|
4288
|
-
"why": "streaming sets aria-busy, draws a caret that doesn't blink, and tells the thread to announce the text once, when it's finished. A hand-made blinking caret flashes for the whole stream."
|
|
4289
|
-
}
|
|
4946
|
+
"Don't use two separate DatePickers for a start and an end: nobody sees the band.",
|
|
4947
|
+
"Don't reorder a typed range for the user; the field marks it invalid so they can see what they typed."
|
|
4290
4948
|
],
|
|
4291
4949
|
"anatomy": [
|
|
4292
4950
|
{
|
|
4293
|
-
"part": "
|
|
4294
|
-
"description": "
|
|
4295
|
-
},
|
|
4296
|
-
{
|
|
4297
|
-
"part": "Author line",
|
|
4298
|
-
"description": "The author as a label in monospaced type, then the time in a <time dateTime> element."
|
|
4299
|
-
},
|
|
4300
|
-
{
|
|
4301
|
-
"part": "Bubble (user)",
|
|
4302
|
-
"description": "The person's words on surface.sunken, aligned right, at most 85% of the width."
|
|
4303
|
-
},
|
|
4304
|
-
{
|
|
4305
|
-
"part": "Body (assistant)",
|
|
4306
|
-
"description": "Full width, with no bubble: text, paragraphs, and ToolCall and ApprovalRequest blocks stacked in a column."
|
|
4951
|
+
"part": "Field",
|
|
4952
|
+
"description": "A group named by the label, holding two segmented dates (Start date, End date) and the calendar button. A typed end before the start marks it invalid."
|
|
4307
4953
|
},
|
|
4308
4954
|
{
|
|
4309
|
-
"part": "
|
|
4310
|
-
"description": "
|
|
4955
|
+
"part": "Calendar",
|
|
4956
|
+
"description": "Two months, stacked on narrow screens. The ends are solid accent squares, the days between a light accent band."
|
|
4311
4957
|
},
|
|
4312
4958
|
{
|
|
4313
|
-
"part": "
|
|
4314
|
-
"description": "
|
|
4959
|
+
"part": "Hint",
|
|
4960
|
+
"description": "\"Pick the first day.\" or \"Pick the last day.\", under the months, announced when it changes."
|
|
4315
4961
|
},
|
|
4316
4962
|
{
|
|
4317
|
-
"part": "
|
|
4318
|
-
"description": "
|
|
4963
|
+
"part": "Aside",
|
|
4964
|
+
"description": "An optional column beside the months, for DatePresets."
|
|
4319
4965
|
}
|
|
4320
4966
|
],
|
|
4321
4967
|
"examples": [
|
|
4322
4968
|
{
|
|
4323
|
-
"caption": "
|
|
4324
|
-
"source": "<div className=\"
|
|
4969
|
+
"caption": "Default",
|
|
4970
|
+
"source": "<div className=\"w-full max-w-sm\">\n <DateRangePicker label=\"Stay\" />\n</div>"
|
|
4325
4971
|
},
|
|
4326
4972
|
{
|
|
4327
|
-
"caption": "
|
|
4328
|
-
"source": "<div className=\"
|
|
4973
|
+
"caption": "With DatePresets beside the months",
|
|
4974
|
+
"source": "<div className=\"w-full max-w-sm\">\n <FormField label=\"Report period\" help=\"Pick a preset, or two days.\">\n <DateRangePicker label=\"Report period\" aside={<DatePresets />} />\n </FormField>\n</div>"
|
|
4329
4975
|
},
|
|
4330
4976
|
{
|
|
4331
|
-
"caption": "
|
|
4332
|
-
"source": "
|
|
4977
|
+
"caption": "Controlled: the page holds the range",
|
|
4978
|
+
"source": "function Controlled() {\n const [range, setRange] = useState<DateRange>({ start: '2026-11-09', end: '2026-11-13' })\n return (\n <div className=\"flex w-full max-w-sm flex-col gap-2\">\n <DateRangePicker label=\"Leave\" value={range} onValueChange={setRange} />\n <span className=\"font-mono text-xs text-[var(--color-text-secondary)]\">\n start: {range.start || '—'}, end: {range.end || '—'}\n </span>\n </div>\n )\n}\n\n<Controlled />"
|
|
4979
|
+
},
|
|
4980
|
+
{
|
|
4981
|
+
"caption": "Limits: November and December only",
|
|
4982
|
+
"source": "<div className=\"w-full max-w-sm\">\n <DateRangePicker label=\"Rental\" min=\"2026-11-01\" max=\"2026-12-30\" defaultValue={{ start: '2026-11-20', end: '2026-11-23' }} />\n</div>"
|
|
4333
4983
|
}
|
|
4334
4984
|
]
|
|
4335
4985
|
},
|
|
@@ -4917,7 +5567,7 @@
|
|
|
4917
5567
|
{
|
|
4918
5568
|
"name": "children",
|
|
4919
5569
|
"type": "ReactElement",
|
|
4920
|
-
"description": "Exactly one control: Input, Textarea, Select or QuantityStepper. A label set on a Select or QuantityStepper child is replaced by the FormField label."
|
|
5570
|
+
"description": "Exactly one control: Input, Textarea, Select or QuantityStepper. A label set on a Select or QuantityStepper child is replaced by the FormField label. An id you give the control is kept (point an ErrorSummary entry at it); without one, FormField makes one up."
|
|
4921
5571
|
},
|
|
4922
5572
|
{
|
|
4923
5573
|
"name": "className",
|
|
@@ -7278,6 +7928,225 @@
|
|
|
7278
7928
|
}
|
|
7279
7929
|
]
|
|
7280
7930
|
},
|
|
7931
|
+
{
|
|
7932
|
+
"name": "TimeField",
|
|
7933
|
+
"title": "Time field",
|
|
7934
|
+
"tier": "molecules",
|
|
7935
|
+
"slug": "time-field",
|
|
7936
|
+
"summary": "A time of day, an add-on to the date pickers. Hours and minutes are segments you type into or step with the arrow keys, like DateField; the clock button opens a list of times every step minutes. With a 12-hour clock there is an AM/PM segment. The value is 'HH:MM' on a 24-hour clock whatever is shown. Put it next to a DatePicker for a date and a time.",
|
|
7937
|
+
"useWhen": "A pickup slot, a meeting start, a shift.",
|
|
7938
|
+
"notFor": "A duration: Input with a unit.",
|
|
7939
|
+
"source": "src/components/molecules/time-field/TimeField.tsx",
|
|
7940
|
+
"docs": "/docs/components/time-field.md",
|
|
7941
|
+
"imports": [
|
|
7942
|
+
{
|
|
7943
|
+
"names": [
|
|
7944
|
+
"TimeField",
|
|
7945
|
+
"hourCycleFor"
|
|
7946
|
+
],
|
|
7947
|
+
"from": "src/components/molecules/time-field/TimeField"
|
|
7948
|
+
}
|
|
7949
|
+
],
|
|
7950
|
+
"props": [
|
|
7951
|
+
{
|
|
7952
|
+
"name": "label",
|
|
7953
|
+
"type": "string",
|
|
7954
|
+
"description": "Required. Names the field. Inside a FormField, FormField sets it."
|
|
7955
|
+
},
|
|
7956
|
+
{
|
|
7957
|
+
"name": "value",
|
|
7958
|
+
"type": "string ('HH:MM' | '')",
|
|
7959
|
+
"description": "Controlled value, 24-hour."
|
|
7960
|
+
},
|
|
7961
|
+
{
|
|
7962
|
+
"name": "defaultValue",
|
|
7963
|
+
"type": "string",
|
|
7964
|
+
"default": "''",
|
|
7965
|
+
"description": "Starting value when the field holds it itself."
|
|
7966
|
+
},
|
|
7967
|
+
{
|
|
7968
|
+
"name": "onValueChange",
|
|
7969
|
+
"type": "(value: string) => void",
|
|
7970
|
+
"description": "Fires with a whole time, or '' when emptied."
|
|
7971
|
+
},
|
|
7972
|
+
{
|
|
7973
|
+
"name": "hourCycle",
|
|
7974
|
+
"type": "12 | 24",
|
|
7975
|
+
"description": "12 adds an AM/PM segment. The value stays 24-hour. Defaults to the locale's clock."
|
|
7976
|
+
},
|
|
7977
|
+
{
|
|
7978
|
+
"name": "step",
|
|
7979
|
+
"type": "number",
|
|
7980
|
+
"default": "30",
|
|
7981
|
+
"description": "Minutes between the times in the list."
|
|
7982
|
+
},
|
|
7983
|
+
{
|
|
7984
|
+
"name": "min",
|
|
7985
|
+
"type": "string",
|
|
7986
|
+
"description": "Earliest time, 'HH:MM'. Earlier times are left out of the list; typing one marks the field invalid."
|
|
7987
|
+
},
|
|
7988
|
+
{
|
|
7989
|
+
"name": "max",
|
|
7990
|
+
"type": "string",
|
|
7991
|
+
"description": "Latest time, 'HH:MM'."
|
|
7992
|
+
},
|
|
7993
|
+
{
|
|
7994
|
+
"name": "showSlots",
|
|
7995
|
+
"type": "boolean",
|
|
7996
|
+
"default": "true",
|
|
7997
|
+
"description": "Shows the clock button and its list."
|
|
7998
|
+
},
|
|
7999
|
+
{
|
|
8000
|
+
"name": "locale",
|
|
8001
|
+
"type": "string",
|
|
8002
|
+
"description": "Decides the default clock. Defaults to the browser's."
|
|
8003
|
+
},
|
|
8004
|
+
{
|
|
8005
|
+
"name": "disabled",
|
|
8006
|
+
"type": "boolean",
|
|
8007
|
+
"default": "false",
|
|
8008
|
+
"description": "Disables the field and the button."
|
|
8009
|
+
},
|
|
8010
|
+
{
|
|
8011
|
+
"name": "invalid",
|
|
8012
|
+
"type": "boolean",
|
|
8013
|
+
"description": "Marks the field invalid. FormField sets it."
|
|
8014
|
+
},
|
|
8015
|
+
{
|
|
8016
|
+
"name": "required",
|
|
8017
|
+
"type": "boolean",
|
|
8018
|
+
"description": "Marks the field required. FormField sets it."
|
|
8019
|
+
},
|
|
8020
|
+
{
|
|
8021
|
+
"name": "name",
|
|
8022
|
+
"type": "string",
|
|
8023
|
+
"description": "Submits the 'HH:MM' value with a form."
|
|
8024
|
+
},
|
|
8025
|
+
{
|
|
8026
|
+
"name": "id",
|
|
8027
|
+
"type": "string",
|
|
8028
|
+
"description": "The field's id. FormField sets it."
|
|
8029
|
+
},
|
|
8030
|
+
{
|
|
8031
|
+
"name": "aria-describedby",
|
|
8032
|
+
"type": "string",
|
|
8033
|
+
"description": "The ids of the help and error text. FormField sets it."
|
|
8034
|
+
},
|
|
8035
|
+
{
|
|
8036
|
+
"name": "className",
|
|
8037
|
+
"type": "string",
|
|
8038
|
+
"description": "Combined with the field's classes."
|
|
8039
|
+
},
|
|
8040
|
+
{
|
|
8041
|
+
"name": "ref",
|
|
8042
|
+
"type": "Ref<HTMLDivElement>",
|
|
8043
|
+
"description": "The field's group element."
|
|
8044
|
+
},
|
|
8045
|
+
{
|
|
8046
|
+
"name": "hourCycleFor()",
|
|
8047
|
+
"type": "(locale?: string) => 12 | 24",
|
|
8048
|
+
"description": "The locale's own clock."
|
|
8049
|
+
}
|
|
8050
|
+
],
|
|
8051
|
+
"api": [
|
|
8052
|
+
{
|
|
8053
|
+
"name": "TimeValue",
|
|
8054
|
+
"kind": "type",
|
|
8055
|
+
"code": "/** 'HH:MM', 24-hour, or '' for no time. */\nexport type TimeValue = string",
|
|
8056
|
+
"from": "src/components/molecules/time-field/TimeField"
|
|
8057
|
+
},
|
|
8058
|
+
{
|
|
8059
|
+
"name": "hourCycleFor",
|
|
8060
|
+
"kind": "function",
|
|
8061
|
+
"code": "/** 12 or 24, from the locale's own clock. */\nexport function hourCycleFor(locale?: string): 12 | 24",
|
|
8062
|
+
"from": "src/components/molecules/time-field/TimeField"
|
|
8063
|
+
}
|
|
8064
|
+
],
|
|
8065
|
+
"keyboard": [
|
|
8066
|
+
{
|
|
8067
|
+
"keys": [
|
|
8068
|
+
"0–9"
|
|
8069
|
+
],
|
|
8070
|
+
"does": "Types the hour or minute and moves on once it is full."
|
|
8071
|
+
},
|
|
8072
|
+
{
|
|
8073
|
+
"keys": [
|
|
8074
|
+
"A",
|
|
8075
|
+
"P"
|
|
8076
|
+
],
|
|
8077
|
+
"does": "On the AM/PM segment, sets AM or PM."
|
|
8078
|
+
},
|
|
8079
|
+
{
|
|
8080
|
+
"keys": [
|
|
8081
|
+
"↑",
|
|
8082
|
+
"↓"
|
|
8083
|
+
],
|
|
8084
|
+
"does": "In the field: one more or one less. In the list: the next or previous time."
|
|
8085
|
+
},
|
|
8086
|
+
{
|
|
8087
|
+
"keys": [
|
|
8088
|
+
"←",
|
|
8089
|
+
"→"
|
|
8090
|
+
],
|
|
8091
|
+
"does": "The previous or next segment."
|
|
8092
|
+
},
|
|
8093
|
+
{
|
|
8094
|
+
"keys": [
|
|
8095
|
+
"Page Up",
|
|
8096
|
+
"Page Down"
|
|
8097
|
+
],
|
|
8098
|
+
"does": "In the list: six times earlier or later."
|
|
8099
|
+
},
|
|
8100
|
+
{
|
|
8101
|
+
"keys": [
|
|
8102
|
+
"Enter",
|
|
8103
|
+
"Space"
|
|
8104
|
+
],
|
|
8105
|
+
"does": "In the list: picks the time and closes it."
|
|
8106
|
+
},
|
|
8107
|
+
{
|
|
8108
|
+
"keys": [
|
|
8109
|
+
"Esc"
|
|
8110
|
+
],
|
|
8111
|
+
"does": "Closes the list without a change."
|
|
8112
|
+
}
|
|
8113
|
+
],
|
|
8114
|
+
"dos": [
|
|
8115
|
+
"Set step to the real booking grid, such as 15 for 15-minute slots.",
|
|
8116
|
+
"Store the value with its date and the time zone it means, separately."
|
|
8117
|
+
],
|
|
8118
|
+
"donts": [
|
|
8119
|
+
"Don't parse 'HH:MM' with new Date(): keep it a string until you combine it with a date and a zone."
|
|
8120
|
+
],
|
|
8121
|
+
"anatomy": [
|
|
8122
|
+
{
|
|
8123
|
+
"part": "Field",
|
|
8124
|
+
"description": "A group named by the label: Hour, Minute and, on a 12-hour clock, AM or PM, each a spinbutton."
|
|
8125
|
+
},
|
|
8126
|
+
{
|
|
8127
|
+
"part": "Clock button",
|
|
8128
|
+
"description": "A ghost IconButton. Its name includes the time: \"Choose time, 14:30\"."
|
|
8129
|
+
},
|
|
8130
|
+
{
|
|
8131
|
+
"part": "Time list",
|
|
8132
|
+
"description": "A listbox of times between min and max, every step minutes. It opens on the picked time, or the next slot after now."
|
|
8133
|
+
}
|
|
8134
|
+
],
|
|
8135
|
+
"examples": [
|
|
8136
|
+
{
|
|
8137
|
+
"caption": "Default, 24-hour",
|
|
8138
|
+
"source": "<div className=\"w-36\">\n <TimeField label=\"Start time\" hourCycle={24} />\n</div>"
|
|
8139
|
+
},
|
|
8140
|
+
{
|
|
8141
|
+
"caption": "12-hour, with AM and PM",
|
|
8142
|
+
"source": "<div className=\"w-40\">\n <TimeField label=\"Call time\" hourCycle={12} defaultValue=\"14:30\" />\n</div>"
|
|
8143
|
+
},
|
|
8144
|
+
{
|
|
8145
|
+
"caption": "With a DatePicker: a date and a time",
|
|
8146
|
+
"source": "function DateAndTime() {\n const [date, setDate] = useState('2026-11-14')\n const [time, setTime] = useState('09:30')\n return (\n <div className=\"flex w-full max-w-md flex-col gap-3\">\n <div className=\"grid gap-3 sm:grid-cols-[1fr_9rem]\">\n <FormField label=\"Pickup date\">\n <DatePicker label=\"Pickup date\" value={date} onValueChange={setDate} />\n </FormField>\n <FormField label=\"Pickup time\">\n <TimeField label=\"Pickup time\" value={time} onValueChange={setTime} step={15} min=\"08:00\" max=\"18:00\" />\n </FormField>\n </div>\n <span className=\"font-mono text-xs text-[var(--color-text-secondary)]\">\n {date && time ? `${date}T${time}` : 'Pick a date and a time'}\n </span>\n </div>\n )\n}\n\n<DateAndTime />"
|
|
8147
|
+
}
|
|
8148
|
+
]
|
|
8149
|
+
},
|
|
7281
8150
|
{
|
|
7282
8151
|
"name": "Timeline",
|
|
7283
8152
|
"title": "Timeline",
|
|
@@ -8960,7 +9829,7 @@
|
|
|
8960
9829
|
{
|
|
8961
9830
|
"name": "commands",
|
|
8962
9831
|
"type": "Command[]",
|
|
8963
|
-
"description": "Required. Each has id, label, group, keywords, shortcut, icon and onSelect."
|
|
9832
|
+
"description": "Required. Each has id, label, description (a quieter second line), group, keywords, shortcut, icon and onSelect."
|
|
8964
9833
|
},
|
|
8965
9834
|
{
|
|
8966
9835
|
"name": "open",
|
|
@@ -9008,6 +9877,12 @@
|
|
|
9008
9877
|
"default": "'No matching commands'",
|
|
9009
9878
|
"description": "Shown when nothing matches the search."
|
|
9010
9879
|
},
|
|
9880
|
+
{
|
|
9881
|
+
"name": "filter",
|
|
9882
|
+
"type": "(commands: readonly Command[], query: string) => Command[]",
|
|
9883
|
+
"default": "filterCommands",
|
|
9884
|
+
"description": "Your own matching and ranking. Gets every command and the query, returns the ones to show in order; groups follow that order. The docs site search uses it to rank with the same scorer as the MCP server."
|
|
9885
|
+
},
|
|
9011
9886
|
{
|
|
9012
9887
|
"name": "ref",
|
|
9013
9888
|
"type": "Ref<HTMLInputElement>",
|
|
@@ -9018,7 +9893,7 @@
|
|
|
9018
9893
|
{
|
|
9019
9894
|
"name": "Command",
|
|
9020
9895
|
"kind": "type",
|
|
9021
|
-
"code": "export type Command = {\n id: string\n label: string\n /** Commands with the same group are drawn together under its heading. */\n group?: string\n /** Extra words a search matches on. */\n keywords?: string[]\n /** A hint shown on the option, e.g. \"N\". Display only: the palette does not bind it. */\n shortcut?: string\n /** Drawn aria-hidden; the label carries the meaning. */\n icon?: ReactNode\n onSelect: () => void\n}",
|
|
9896
|
+
"code": "export type Command = {\n id: string\n label: string\n /** A second, quieter line under the label, e.g. what a search result is for. */\n description?: string\n /** Commands with the same group are drawn together under its heading. */\n group?: string\n /** Extra words a search matches on. */\n keywords?: string[]\n /** A hint shown on the option, e.g. \"N\". Display only: the palette does not bind it. */\n shortcut?: string\n /** Drawn aria-hidden; the label carries the meaning. */\n icon?: ReactNode\n onSelect: () => void\n}",
|
|
9022
9897
|
"from": "src/components/organisms/command-palette/CommandPalette"
|
|
9023
9898
|
},
|
|
9024
9899
|
{
|