@robr0/design-system 0.8.0 → 0.9.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.
Files changed (95) hide show
  1. package/README.md +3 -3
  2. package/components/Accordion/Accordion.js +1 -0
  3. package/components/AgentPlan/AgentPlan.css +2 -2
  4. package/components/AgentPlan/AgentPlan.js +1 -0
  5. package/components/AgentStatus/AgentStatus.js +1 -0
  6. package/components/AiButton/AiButton.js +1 -0
  7. package/components/AlertDialog/AlertDialog.js +1 -0
  8. package/components/AnchorNav/AnchorNav.css +63 -0
  9. package/components/AnchorNav/AnchorNav.d.ts +33 -0
  10. package/components/AnchorNav/AnchorNav.js +82 -0
  11. package/components/AppLayout/AppLayout.js +1 -0
  12. package/components/AppSidebar/AppSidebar.js +1 -0
  13. package/components/Avatar/Avatar.js +1 -0
  14. package/components/Button/Button.js +1 -0
  15. package/components/Card/Card.js +1 -0
  16. package/components/Carousel/Carousel.js +1 -0
  17. package/components/ChatThread/ChatThread.js +1 -0
  18. package/components/Checkbox/Checkbox.js +1 -0
  19. package/components/CodeBlock/CodeBlock.js +1 -0
  20. package/components/CodeDiff/CodeDiff.css +175 -0
  21. package/components/CodeDiff/CodeDiff.d.ts +58 -0
  22. package/components/CodeDiff/CodeDiff.js +114 -0
  23. package/components/ColorPicker/ColorPicker.js +1 -0
  24. package/components/Combobox/Combobox.js +1 -0
  25. package/components/CommandPalette/CommandPalette.js +1 -0
  26. package/components/Composer/Composer.js +1 -0
  27. package/components/ContactCard/ContactCard.js +1 -0
  28. package/components/ContextMenu/ContextMenu.js +1 -0
  29. package/components/DataTable/DataTable.js +1 -0
  30. package/components/DateInput/DateInput.js +1 -0
  31. package/components/DatePicker/DatePicker.js +1 -0
  32. package/components/Dialog/Dialog.js +1 -0
  33. package/components/Drawer/Drawer.js +1 -0
  34. package/components/Dropdown/Dropdown.js +1 -0
  35. package/components/DropdownMenu/DropdownMenu.css +1 -1
  36. package/components/DropdownMenu/DropdownMenu.js +1 -0
  37. package/components/EventCalendar/EventCalendar.js +1 -0
  38. package/components/Field/Field.js +1 -0
  39. package/components/Field/FieldContext.js +1 -0
  40. package/components/FileInput/FileInput.js +1 -0
  41. package/components/Input/Input.js +1 -0
  42. package/components/InterruptCard/InterruptCard.css +11 -21
  43. package/components/InterruptCard/InterruptCard.d.ts +5 -6
  44. package/components/MessageCard/MessageCard.css +1 -2
  45. package/components/ModelPicker/ModelPicker.css +3 -1
  46. package/components/ModelPicker/ModelPicker.js +1 -0
  47. package/components/NavList/NavList.js +1 -0
  48. package/components/NotificationCenter/NotificationCenter.js +1 -0
  49. package/components/NumberInput/NumberInput.css +154 -0
  50. package/components/NumberInput/NumberInput.d.ts +44 -0
  51. package/components/NumberInput/NumberInput.js +147 -0
  52. package/components/Pagination/Pagination.js +1 -0
  53. package/components/PinInput/PinInput.css +92 -0
  54. package/components/PinInput/PinInput.d.ts +46 -0
  55. package/components/PinInput/PinInput.js +161 -0
  56. package/components/Popover/Popover.css +5 -6
  57. package/components/Popover/Popover.js +1 -0
  58. package/components/RadioButton/RadioButton.js +1 -0
  59. package/components/Reasoning/Reasoning.js +1 -0
  60. package/components/SegmentedControl/SegmentedControl.js +1 -0
  61. package/components/SelectionCard/SelectionCard.js +1 -0
  62. package/components/ShaderField/ShaderField.js +1 -0
  63. package/components/ShaderField/useShaderField.js +1 -0
  64. package/components/Slider/Slider.js +1 -0
  65. package/components/Sparkline/Sparkline.css +52 -0
  66. package/components/Sparkline/Sparkline.d.ts +49 -0
  67. package/components/Sparkline/Sparkline.js +86 -0
  68. package/components/Stepper/Stepper.css +207 -0
  69. package/components/Stepper/Stepper.d.ts +41 -0
  70. package/components/Stepper/Stepper.js +61 -0
  71. package/components/Tabs/Tabs.js +1 -0
  72. package/components/TagInput/TagInput.css +160 -0
  73. package/components/TagInput/TagInput.d.ts +43 -0
  74. package/components/TagInput/TagInput.js +137 -0
  75. package/components/Textarea/Textarea.js +1 -0
  76. package/components/TimePicker/TimePicker.css +230 -0
  77. package/components/TimePicker/TimePicker.d.ts +46 -0
  78. package/components/TimePicker/TimePicker.js +246 -0
  79. package/components/Toast/Toast.js +1 -0
  80. package/components/ToggleGroup/ToggleGroup.js +1 -0
  81. package/components/ToggleSwitch/ToggleSwitch.js +1 -0
  82. package/components/ToolCall/ToolCall.css +7 -11
  83. package/components/ToolCall/ToolCall.js +1 -0
  84. package/components/Tooltip/Tooltip.js +1 -0
  85. package/components/TreeView/TreeView.css +119 -0
  86. package/components/TreeView/TreeView.d.ts +45 -0
  87. package/components/TreeView/TreeView.js +232 -0
  88. package/components/registry.d.ts +22 -6
  89. package/components/registry.js +3 -1
  90. package/components/registry.json +206 -20
  91. package/components/registry.json.d.ts +206 -20
  92. package/components/registry.json.js +2 -2
  93. package/index.d.ts +11 -2
  94. package/index.js +21 -1
  95. package/package.json +1 -1
@@ -0,0 +1,230 @@
1
+ /* ============================================
2
+ TIMEPICKER COMPONENT
3
+ Time-of-day field with a dropdown listbox of
4
+ generated times. Mirrors Dropdown's anatomy;
5
+ the trigger is a real <button> styled as an
6
+ input.
7
+ ============================================ */
8
+
9
+ /* ============================================
10
+ BASE
11
+ ============================================ */
12
+
13
+ .ds-timepicker {
14
+ display: flex;
15
+ flex-direction: column;
16
+ gap: var(--gap-sm); /* 8px */
17
+ width: 100%;
18
+ position: relative;
19
+ }
20
+
21
+ /* ============================================
22
+ TRIGGER
23
+ ============================================ */
24
+
25
+ .ds-timepicker__trigger {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: var(--gap-sm); /* 8px */
29
+ width: 100%;
30
+ padding: var(--padding-sm) var(--padding-md); /* 8px 16px */
31
+ border: var(--border-xs) solid var(--color-input-border-primary);
32
+ border-radius: var(--radius-md); /* 12px — input shape, not the button pill */
33
+ background-color: var(--color-input-bg-primary);
34
+ text-align: left;
35
+ cursor: pointer;
36
+ transition: border-color var(--motion-duration-base) var(--motion-ease-standard);
37
+ outline: none;
38
+ }
39
+
40
+ .ds-timepicker__trigger:hover:not(:focus-visible):not(:disabled) {
41
+ border-color: var(--color-input-border-hover);
42
+ }
43
+
44
+ .ds-timepicker__trigger:focus-visible {
45
+ border-color: var(--color-input-border-selected);
46
+ }
47
+
48
+ .ds-timepicker--open .ds-timepicker__trigger {
49
+ border-color: var(--color-input-border-selected);
50
+ }
51
+
52
+ /* ============================================
53
+ CLOCK ICON
54
+ ============================================ */
55
+
56
+ .ds-timepicker__icon {
57
+ --icon-size: var(--icon-size-sm);
58
+ color: var(--color-icon-primary);
59
+ flex-shrink: 0;
60
+ }
61
+
62
+ /* ============================================
63
+ VALUE / PLACEHOLDER
64
+ ============================================ */
65
+
66
+ .ds-timepicker__value {
67
+ font-family: var(--font-paragraph-em-family);
68
+ font-size: var(--font-paragraph-em-size);
69
+ font-weight: var(--font-paragraph-em-weight);
70
+ line-height: var(--font-paragraph-em-line-height);
71
+ letter-spacing: var(--font-paragraph-em-letter-spacing);
72
+ color: var(--color-input-text-primary);
73
+ flex: 1;
74
+ overflow: hidden;
75
+ text-overflow: ellipsis;
76
+ white-space: nowrap;
77
+ }
78
+
79
+ .ds-timepicker__value--placeholder {
80
+ color: var(--color-input-text-placeholder);
81
+ }
82
+
83
+ /* ============================================
84
+ CHEVRON
85
+ ============================================ */
86
+
87
+ .ds-timepicker__chevron {
88
+ --icon-size: var(--icon-size-md);
89
+ color: var(--color-icon-primary);
90
+ transition: transform var(--motion-duration-base) var(--motion-ease-standard);
91
+ flex-shrink: 0;
92
+ }
93
+
94
+ .ds-timepicker--open .ds-timepicker__chevron {
95
+ transform: rotate(180deg);
96
+ }
97
+
98
+ /* ============================================
99
+ MENU
100
+ ============================================ */
101
+
102
+ .ds-timepicker__menu {
103
+ position: absolute;
104
+ top: 100%;
105
+ left: 0;
106
+ right: 0;
107
+ margin-top: var(--gap-xxs); /* 2px */
108
+ padding: var(--padding-xxs); /* inset gap on all sides */
109
+ border: var(--border-xs) solid var(--color-input-border-primary);
110
+ border-radius: var(--radius-md); /* 12px */
111
+ background-color: var(--color-bg-page-primary);
112
+ list-style: none;
113
+ max-height: 240px;
114
+ overflow-y: auto;
115
+ z-index: 10;
116
+ box-shadow: var(--shadow-floating);
117
+
118
+ /* Animation */
119
+ animation: ds-timepicker-appear var(--motion-duration-fast) var(--motion-ease-entrance);
120
+ }
121
+
122
+ @keyframes ds-timepicker-appear {
123
+ from {
124
+ opacity: 0;
125
+ transform: scale(0.96);
126
+ }
127
+ to {
128
+ opacity: 1;
129
+ transform: scale(1);
130
+ }
131
+ }
132
+
133
+ /* ============================================
134
+ OPTION
135
+ ============================================ */
136
+
137
+ .ds-timepicker__option {
138
+ display: flex;
139
+ align-items: center;
140
+ justify-content: space-between;
141
+ padding: var(--padding-sm) var(--padding-sm-md); /* 8px 12px */
142
+ border-radius: var(--radius-sm);
143
+ font-family: var(--font-paragraph-em-family);
144
+ font-size: var(--font-paragraph-em-size);
145
+ font-weight: var(--font-paragraph-em-weight);
146
+ line-height: var(--font-paragraph-em-line-height);
147
+ letter-spacing: var(--font-paragraph-em-letter-spacing);
148
+ font-variant-numeric: tabular-nums;
149
+ color: var(--color-text-primary);
150
+ cursor: pointer;
151
+ transition: background-color var(--motion-duration-fast) var(--motion-ease-standard);
152
+ }
153
+
154
+ .ds-timepicker__option:hover {
155
+ background-color: var(--color-action-passive-bg-hover);
156
+ }
157
+
158
+ .ds-timepicker__option--focused {
159
+ background-color: var(--color-action-passive-bg-hover);
160
+ }
161
+
162
+ .ds-timepicker__option--selected {
163
+ color: var(--color-action-primary-text-tertiary);
164
+ }
165
+
166
+ /* ============================================
167
+ CHECK ICON
168
+ ============================================ */
169
+
170
+ .ds-timepicker__check {
171
+ --icon-size: var(--icon-size-md);
172
+ color: var(--color-action-primary-bg);
173
+ }
174
+
175
+ /* ============================================
176
+ ERROR STATE
177
+ ============================================ */
178
+
179
+ .ds-timepicker--error .ds-timepicker__trigger {
180
+ border-color: var(--color-status-error-border);
181
+ }
182
+
183
+ /* ============================================
184
+ DISABLED STATE
185
+ ============================================ */
186
+
187
+ .ds-timepicker--disabled .ds-timepicker__trigger {
188
+ background-color: var(--color-input-bg-disabled);
189
+ border-color: var(--color-input-border-disabled);
190
+ opacity: 0.4;
191
+ cursor: not-allowed;
192
+ }
193
+
194
+ .ds-timepicker--disabled .ds-timepicker__value {
195
+ color: var(--color-input-text-disabled);
196
+ }
197
+
198
+ .ds-timepicker--disabled .ds-timepicker__icon,
199
+ .ds-timepicker--disabled .ds-timepicker__chevron {
200
+ color: var(--color-input-text-disabled);
201
+ }
202
+
203
+ /* ============================================
204
+ SIZE — COMPACT
205
+ ============================================ */
206
+
207
+ .ds-timepicker--compact .ds-timepicker__trigger {
208
+ padding: var(--padding-xs) var(--padding-sm-md); /* 6px 12px */
209
+ }
210
+
211
+ .ds-timepicker--compact .ds-timepicker__value {
212
+ font-size: var(--font-paragraph-sm-em-size);
213
+ line-height: var(--font-paragraph-sm-em-line-height);
214
+ letter-spacing: var(--font-paragraph-sm-em-letter-spacing);
215
+ }
216
+
217
+ .ds-timepicker--compact .ds-timepicker__chevron {
218
+ --icon-size: var(--icon-size-sm);
219
+ }
220
+
221
+ .ds-timepicker--compact .ds-timepicker__option {
222
+ padding: var(--padding-xs) var(--padding-sm); /* 6px 8px */
223
+ font-size: var(--font-paragraph-sm-em-size);
224
+ line-height: var(--font-paragraph-sm-em-line-height);
225
+ letter-spacing: var(--font-paragraph-sm-em-letter-spacing);
226
+ }
227
+
228
+ .ds-timepicker--compact .ds-timepicker__check {
229
+ --icon-size: var(--icon-size-sm);
230
+ }
@@ -0,0 +1,46 @@
1
+ import { default as React } from 'react';
2
+ /** Props owned by TimePicker itself — everything else falls through to the trigger button. */
3
+ type TimePickerOwnProps = {
4
+ /** Label text rendered above the trigger */
5
+ label?: string;
6
+ /** Placeholder shown when no time is selected */
7
+ placeholder?: string;
8
+ /** Currently selected time as a 24-hour "HH:MM" string (controlled) */
9
+ value?: string;
10
+ /** Initially selected time as a 24-hour "HH:MM" string (uncontrolled) */
11
+ defaultValue?: string;
12
+ /** Earliest generated option, as a 24-hour "HH:MM" string */
13
+ minTime?: string;
14
+ /** Latest generated option, as a 24-hour "HH:MM" string */
15
+ maxTime?: string;
16
+ /** Minutes between generated options */
17
+ stepMinutes?: number;
18
+ /** Display format for the trigger and options — the value stays a 24-hour "HH:MM" string either way */
19
+ hourFormat?: '12' | '24';
20
+ /** Component size */
21
+ size?: 'default' | 'compact';
22
+ /** Whether the picker is disabled */
23
+ disabled?: boolean;
24
+ /** Whether the field is required */
25
+ required?: boolean;
26
+ /** Error state */
27
+ error?: boolean;
28
+ /** Helper or error message */
29
+ helperText?: string;
30
+ /** Called with the newly selected 24-hour "HH:MM" value */
31
+ onValueChange?: (value: string) => void;
32
+ /** Additional CSS classes */
33
+ className?: string;
34
+ };
35
+ export interface TimePickerProps extends TimePickerOwnProps, Omit<React.ComponentPropsWithoutRef<'button'>, keyof TimePickerOwnProps | 'type'> {
36
+ }
37
+ /**
38
+ * Time-of-day form field. A button-shaped trigger opens a scrollable
39
+ * `role="listbox"` of times generated from `minTime`/`maxTime`/`stepMinutes`,
40
+ * with full keyboard navigation. The value is always a 24-hour "HH:MM"
41
+ * string; `hourFormat` only changes the display.
42
+ *
43
+ * Forwards a ref to the trigger button and spreads unrecognised props onto it.
44
+ */
45
+ export declare const TimePicker: React.ForwardRefExoticComponent<TimePickerProps & React.RefAttributes<HTMLButtonElement>>;
46
+ export {};
@@ -0,0 +1,246 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import React, { useState, useRef, useId, useMemo, useCallback, useEffect } from "react";
4
+ import { Field } from "../Field/Field.js";
5
+ import "./TimePicker.css";
6
+ import "../../fonts/material-symbols.css";
7
+ function parseMinutes(time) {
8
+ const [h, m] = time.split(":").map(Number);
9
+ return h * 60 + m;
10
+ }
11
+ function toTimeValue(minutes) {
12
+ const h = Math.floor(minutes / 60);
13
+ const m = minutes % 60;
14
+ return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
15
+ }
16
+ function formatTime(time, hourFormat) {
17
+ if (hourFormat === "24") return time;
18
+ const [h, m] = time.split(":").map(Number);
19
+ const suffix = h < 12 ? "AM" : "PM";
20
+ const hour12 = h % 12 === 0 ? 12 : h % 12;
21
+ return `${hour12}:${String(m).padStart(2, "0")} ${suffix}`;
22
+ }
23
+ const TimePicker = React.forwardRef(
24
+ ({
25
+ label,
26
+ placeholder = "Select time",
27
+ value,
28
+ defaultValue,
29
+ minTime = "00:00",
30
+ maxTime = "23:30",
31
+ stepMinutes = 30,
32
+ hourFormat = "12",
33
+ size = "default",
34
+ disabled = false,
35
+ required = false,
36
+ error = false,
37
+ helperText,
38
+ onValueChange,
39
+ className = "",
40
+ id,
41
+ ...rest
42
+ }, ref) => {
43
+ const [isOpen, setIsOpen] = useState(false);
44
+ const [focusedIndex, setFocusedIndex] = useState(-1);
45
+ const [internalValue, setInternalValue] = useState(defaultValue);
46
+ const rootRef = useRef(null);
47
+ const triggerRef = useRef(null);
48
+ const listRef = useRef(null);
49
+ const isControlled = value !== void 0;
50
+ const selectedValue = isControlled ? value : internalValue;
51
+ const setTriggerRef = (node) => {
52
+ triggerRef.current = node;
53
+ if (typeof ref === "function") ref(node);
54
+ else if (ref) ref.current = node;
55
+ };
56
+ const generatedId = useId();
57
+ const inputId = id || generatedId;
58
+ const baseClass = "ds-timepicker";
59
+ const classes = [
60
+ baseClass,
61
+ size === "compact" ? `${baseClass}--compact` : "",
62
+ isOpen ? `${baseClass}--open` : "",
63
+ error ? `${baseClass}--error` : "",
64
+ disabled ? `${baseClass}--disabled` : "",
65
+ className
66
+ ].filter(Boolean).join(" ");
67
+ const timeOptions = useMemo(() => {
68
+ const step = Math.max(1, Math.floor(stepMinutes));
69
+ const start = parseMinutes(minTime);
70
+ const end = parseMinutes(maxTime);
71
+ const opts = [];
72
+ for (let mins = start; mins <= end; mins += step) {
73
+ const v = toTimeValue(mins);
74
+ opts.push({ value: v, label: formatTime(v, hourFormat) });
75
+ }
76
+ return opts;
77
+ }, [minTime, maxTime, stepMinutes, hourFormat]);
78
+ const selectedIndex = timeOptions.findIndex((opt) => opt.value === selectedValue);
79
+ const selectedOption = selectedIndex >= 0 ? timeOptions[selectedIndex] : void 0;
80
+ const openMenu = () => {
81
+ setIsOpen(true);
82
+ setFocusedIndex(selectedIndex >= 0 ? selectedIndex : timeOptions.length > 0 ? 0 : -1);
83
+ };
84
+ const closeMenu = () => {
85
+ setIsOpen(false);
86
+ setFocusedIndex(-1);
87
+ };
88
+ const handleToggle = () => {
89
+ if (disabled) return;
90
+ if (isOpen) closeMenu();
91
+ else openMenu();
92
+ };
93
+ const handleSelect = (optionValue) => {
94
+ if (!isControlled) setInternalValue(optionValue);
95
+ onValueChange?.(optionValue);
96
+ closeMenu();
97
+ };
98
+ const handleClickOutside = useCallback((e) => {
99
+ if (rootRef.current && !rootRef.current.contains(e.target)) {
100
+ setIsOpen(false);
101
+ }
102
+ }, []);
103
+ useEffect(() => {
104
+ document.addEventListener("mousedown", handleClickOutside);
105
+ return () => document.removeEventListener("mousedown", handleClickOutside);
106
+ }, [handleClickOutside]);
107
+ const handleKeyDown = (e) => {
108
+ if (disabled) return;
109
+ switch (e.key) {
110
+ case "Enter":
111
+ case " ":
112
+ e.preventDefault();
113
+ if (isOpen && focusedIndex >= 0 && timeOptions[focusedIndex]) {
114
+ handleSelect(timeOptions[focusedIndex].value);
115
+ } else {
116
+ handleToggle();
117
+ }
118
+ break;
119
+ case "ArrowDown":
120
+ e.preventDefault();
121
+ if (!isOpen) {
122
+ openMenu();
123
+ } else {
124
+ setFocusedIndex((prev) => Math.min(prev + 1, timeOptions.length - 1));
125
+ }
126
+ break;
127
+ case "ArrowUp":
128
+ e.preventDefault();
129
+ if (!isOpen) {
130
+ openMenu();
131
+ } else {
132
+ setFocusedIndex((prev) => Math.max(prev - 1, 0));
133
+ }
134
+ break;
135
+ case "Home":
136
+ if (isOpen) {
137
+ e.preventDefault();
138
+ setFocusedIndex(0);
139
+ }
140
+ break;
141
+ case "End":
142
+ if (isOpen) {
143
+ e.preventDefault();
144
+ setFocusedIndex(timeOptions.length - 1);
145
+ }
146
+ break;
147
+ case "Escape":
148
+ closeMenu();
149
+ break;
150
+ case "Tab":
151
+ closeMenu();
152
+ break;
153
+ }
154
+ };
155
+ useEffect(() => {
156
+ if (isOpen && focusedIndex >= 0 && listRef.current) {
157
+ const focusedEl = listRef.current.children[focusedIndex];
158
+ focusedEl?.scrollIntoView({ block: "nearest" });
159
+ }
160
+ }, [focusedIndex, isOpen]);
161
+ return /* @__PURE__ */ jsxs(
162
+ Field,
163
+ {
164
+ ref: rootRef,
165
+ className: classes,
166
+ label,
167
+ helperText,
168
+ error,
169
+ required,
170
+ disabled,
171
+ size,
172
+ id: inputId,
173
+ children: [
174
+ /* @__PURE__ */ jsxs(
175
+ "button",
176
+ {
177
+ ...rest,
178
+ type: "button",
179
+ id: inputId,
180
+ ref: setTriggerRef,
181
+ className: `${baseClass}__trigger`,
182
+ "aria-expanded": isOpen,
183
+ "aria-haspopup": "listbox",
184
+ "aria-controls": `${inputId}-listbox`,
185
+ "aria-describedby": helperText ? `${inputId}-helper` : rest["aria-describedby"],
186
+ "aria-invalid": error || void 0,
187
+ disabled,
188
+ onClick: handleToggle,
189
+ onKeyDown: handleKeyDown,
190
+ children: [
191
+ /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon material-symbols-rounded`, "aria-hidden": "true", children: "schedule" }),
192
+ /* @__PURE__ */ jsx(
193
+ "span",
194
+ {
195
+ className: `${baseClass}__value ${!selectedOption ? `${baseClass}__value--placeholder` : ""}`,
196
+ children: selectedOption ? selectedOption.label : placeholder
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsx("span", { className: `${baseClass}__chevron material-symbols-rounded`, "aria-hidden": "true", children: "expand_more" })
200
+ ]
201
+ }
202
+ ),
203
+ isOpen && /* @__PURE__ */ jsx(
204
+ "ul",
205
+ {
206
+ className: `${baseClass}__menu`,
207
+ role: "listbox",
208
+ id: `${inputId}-listbox`,
209
+ ref: listRef,
210
+ "aria-labelledby": label ? `${inputId}-label` : void 0,
211
+ children: timeOptions.map((option, index) => /* @__PURE__ */ jsxs(
212
+ "li",
213
+ {
214
+ className: [
215
+ `${baseClass}__option`,
216
+ option.value === selectedValue ? `${baseClass}__option--selected` : "",
217
+ index === focusedIndex ? `${baseClass}__option--focused` : ""
218
+ ].filter(Boolean).join(" "),
219
+ role: "option",
220
+ "aria-selected": option.value === selectedValue,
221
+ onClick: () => handleSelect(option.value),
222
+ children: [
223
+ option.label,
224
+ option.value === selectedValue && /* @__PURE__ */ jsx(
225
+ "span",
226
+ {
227
+ className: `${baseClass}__check material-symbols-rounded`,
228
+ "aria-hidden": "true",
229
+ children: "check"
230
+ }
231
+ )
232
+ ]
233
+ },
234
+ option.value
235
+ ))
236
+ }
237
+ )
238
+ ]
239
+ }
240
+ );
241
+ }
242
+ );
243
+ TimePicker.displayName = "TimePicker";
244
+ export {
245
+ TimePicker
246
+ };
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsxs, jsx } from "react/jsx-runtime";
2
3
  import { useState, useSyncExternalStore, useCallback, useContext, createContext, useRef, useEffect } from "react";
3
4
  import ReactDOM from "react-dom";
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx } from "react/jsx-runtime";
2
3
  import React from "react";
3
4
  import "./ToggleGroup.css";
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsxs, jsx } from "react/jsx-runtime";
2
3
  import React from "react";
3
4
  import "./ToggleSwitch.css";
@@ -7,20 +7,19 @@
7
7
  The container stays neutral — colour lives in
8
8
  the indicator and the status word, so a long
9
9
  run of calls reads as a list rather than a
10
- wall of tinted cards. The two states a person
11
- has to act on, pending and error, also take a
12
- coloured border.
10
+ wall of tinted cards. The border is the
11
+ standard container hairline in every status;
12
+ the status word and icon carry the state.
13
13
  ============================================ */
14
14
 
15
15
  .ds-tool-call {
16
16
  --ds-tool-call-color: var(--color-text-secondary);
17
- --ds-tool-call-border: var(--color-bg-container-border);
18
17
 
19
18
  display: flex;
20
19
  flex-direction: column;
21
20
  width: 100%;
22
21
  background-color: var(--color-bg-container-primary);
23
- border: var(--border-xs) solid var(--ds-tool-call-border);
22
+ border: var(--border-xs) solid var(--color-bg-container-border);
24
23
  border-radius: var(--radius-md);
25
24
  overflow: hidden;
26
25
  }
@@ -34,7 +33,7 @@
34
33
  align-items: center;
35
34
  gap: var(--gap-sm);
36
35
  width: 100%;
37
- padding: var(--padding-xs) var(--padding-sm-md);
36
+ padding: var(--padding-sm) var(--padding-md);
38
37
  background: none;
39
38
  border: none;
40
39
  text-align: left;
@@ -144,7 +143,6 @@
144
143
 
145
144
  .ds-tool-call--pending {
146
145
  --ds-tool-call-color: var(--color-status-warning-text);
147
- --ds-tool-call-border: var(--color-status-warning-border);
148
146
  }
149
147
 
150
148
  .ds-tool-call--running {
@@ -157,7 +155,6 @@
157
155
 
158
156
  .ds-tool-call--error {
159
157
  --ds-tool-call-color: var(--color-status-error-text);
160
- --ds-tool-call-border: var(--color-status-error-border);
161
158
  }
162
159
 
163
160
  /* ============================================
@@ -184,7 +181,7 @@
184
181
  }
185
182
 
186
183
  .ds-tool-call--open .ds-tool-call__content {
187
- padding: var(--padding-sm-md);
184
+ padding: var(--padding-md);
188
185
  border-top: var(--border-xs) solid var(--color-divider);
189
186
  }
190
187
 
@@ -207,7 +204,6 @@
207
204
  align-items: center;
208
205
  justify-content: flex-end;
209
206
  gap: var(--gap-sm);
210
- padding: var(--padding-sm) var(--padding-sm-md);
207
+ padding: var(--padding-sm-md) var(--padding-md);
211
208
  border-top: var(--border-xs) solid var(--color-divider);
212
- background-color: var(--color-bg-container-secondary);
213
209
  }
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
3
  import React, { useId, useState, useCallback } from "react";
3
4
  import { Spinner } from "../Spinner/Spinner.js";
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsxs, jsx } from "react/jsx-runtime";
2
3
  import { useState, useRef, useId, isValidElement, cloneElement } from "react";
3
4
  import "./Tooltip.css";