@adia-ai/web-components 0.6.32 → 0.6.34

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 (164) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/components/accordion/accordion.css +2 -2
  3. package/components/action-list/action-list.css +2 -2
  4. package/components/agent-artifact/agent-artifact.css +31 -31
  5. package/components/agent-feedback-bar/agent-feedback-bar.css +10 -10
  6. package/components/agent-questions/agent-questions.css +57 -57
  7. package/components/agent-reasoning/agent-reasoning.css +62 -62
  8. package/components/agent-suggestions/agent-suggestions.css +4 -4
  9. package/components/agent-trace/agent-trace.css +53 -53
  10. package/components/alert/alert.css +41 -41
  11. package/components/avatar/avatar.css +27 -27
  12. package/components/badge/badge.css +27 -27
  13. package/components/block/block.css +16 -16
  14. package/components/breadcrumb/breadcrumb.css +23 -23
  15. package/components/button/button.css +101 -91
  16. package/components/calendar-grid/calendar-grid.a2ui.json +136 -0
  17. package/components/calendar-grid/calendar-grid.css +226 -0
  18. package/components/calendar-grid/calendar-grid.d.ts +37 -0
  19. package/components/calendar-grid/calendar-grid.js +17 -0
  20. package/components/calendar-grid/calendar-grid.yaml +116 -0
  21. package/components/calendar-grid/class.js +300 -0
  22. package/components/calendar-picker/calendar-picker.css +139 -139
  23. package/components/canvas/canvas.css +12 -12
  24. package/components/card/card.css +83 -83
  25. package/components/chart/chart.css +224 -224
  26. package/components/chart-legend/chart-legend.css +26 -26
  27. package/components/check/check.css +40 -40
  28. package/components/code/code.css +125 -125
  29. package/components/col/col.css +15 -15
  30. package/components/color-picker/color-picker.css +55 -55
  31. package/components/combobox/class.js +861 -0
  32. package/components/combobox/combobox.a2ui.json +363 -0
  33. package/components/combobox/combobox.css +244 -0
  34. package/components/combobox/combobox.d.ts +113 -0
  35. package/components/combobox/combobox.examples.md +59 -0
  36. package/components/combobox/combobox.js +17 -0
  37. package/components/combobox/combobox.test.js +181 -0
  38. package/components/combobox/combobox.yaml +369 -0
  39. package/components/command/command.css +90 -90
  40. package/components/date-range-picker/class.js +775 -0
  41. package/components/date-range-picker/date-range-picker.a2ui.json +300 -0
  42. package/components/date-range-picker/date-range-picker.css +178 -0
  43. package/components/date-range-picker/date-range-picker.d.ts +82 -0
  44. package/components/date-range-picker/date-range-picker.examples.md +37 -0
  45. package/components/date-range-picker/date-range-picker.js +17 -0
  46. package/components/date-range-picker/date-range-picker.test.js +387 -0
  47. package/components/date-range-picker/date-range-picker.yaml +285 -0
  48. package/components/datetime-picker/class.js +706 -0
  49. package/components/datetime-picker/datetime-picker.a2ui.json +334 -0
  50. package/components/datetime-picker/datetime-picker.css +150 -0
  51. package/components/datetime-picker/datetime-picker.d.ts +86 -0
  52. package/components/datetime-picker/datetime-picker.examples.md +46 -0
  53. package/components/datetime-picker/datetime-picker.js +17 -0
  54. package/components/datetime-picker/datetime-picker.test.js +454 -0
  55. package/components/datetime-picker/datetime-picker.yaml +332 -0
  56. package/components/demo-toggle/demo-toggle.css +27 -27
  57. package/components/description-list/description-list.css +18 -18
  58. package/components/divider/divider.css +24 -24
  59. package/components/embed/embed.css +6 -6
  60. package/components/empty-state/empty-state.css +27 -27
  61. package/components/feed/feed.css +12 -12
  62. package/components/field/field.css +37 -28
  63. package/components/field/field.test.js +32 -0
  64. package/components/fields/fields.css +5 -5
  65. package/components/grid/grid.css +5 -5
  66. package/components/heatmap/heatmap.css +63 -63
  67. package/components/icon/icon.css +12 -12
  68. package/components/image/image.css +14 -14
  69. package/components/index.js +8 -0
  70. package/components/input/input.css +66 -66
  71. package/components/inspector/inspector.css +6 -6
  72. package/components/integration-card/class.js +410 -0
  73. package/components/integration-card/integration-card.a2ui.json +268 -0
  74. package/components/integration-card/integration-card.css +169 -0
  75. package/components/integration-card/integration-card.d.ts +63 -0
  76. package/components/integration-card/integration-card.examples.md +41 -0
  77. package/components/integration-card/integration-card.js +17 -0
  78. package/components/integration-card/integration-card.test.js +306 -0
  79. package/components/integration-card/integration-card.yaml +280 -0
  80. package/components/kbd/kbd.css +32 -32
  81. package/components/link/link.css +12 -12
  82. package/components/list/list.css +8 -8
  83. package/components/list-window/class.js +688 -0
  84. package/components/list-window/list-window.a2ui.json +277 -0
  85. package/components/list-window/list-window.css +124 -0
  86. package/components/list-window/list-window.d.ts +84 -0
  87. package/components/list-window/list-window.examples.md +73 -0
  88. package/components/list-window/list-window.js +17 -0
  89. package/components/list-window/list-window.test.js +303 -0
  90. package/components/list-window/list-window.yaml +270 -0
  91. package/components/menu/menu.css +8 -8
  92. package/components/modal/modal.css +43 -43
  93. package/components/nav/nav.css +40 -40
  94. package/components/nav-group/nav-group.css +52 -52
  95. package/components/nav-item/nav-item.css +44 -44
  96. package/components/noodles/noodles.css +31 -31
  97. package/components/option-card/option-card.css +69 -69
  98. package/components/otp-input/otp-input.css +30 -30
  99. package/components/page/page.css +18 -18
  100. package/components/pagination/pagination.css +61 -61
  101. package/components/pane/pane.css +57 -57
  102. package/components/pipeline-status/pipeline-status.css +65 -65
  103. package/components/popover/popover.css +17 -17
  104. package/components/progress/progress.css +23 -23
  105. package/components/progress-row/progress-row.css +17 -17
  106. package/components/radio/radio.css +39 -39
  107. package/components/range/range.css +55 -55
  108. package/components/rating/rating.css +28 -28
  109. package/components/richtext/richtext.css +133 -133
  110. package/components/row/row.css +19 -19
  111. package/components/search/search.css +5 -5
  112. package/components/segment/segment.css +24 -24
  113. package/components/segmented/segmented.css +25 -25
  114. package/components/select/select.css +84 -84
  115. package/components/skeleton/skeleton.css +14 -14
  116. package/components/slider/slider.css +46 -46
  117. package/components/spinner/class.js +69 -0
  118. package/components/spinner/spinner.a2ui.json +197 -0
  119. package/components/spinner/spinner.css +165 -0
  120. package/components/spinner/spinner.d.ts +26 -0
  121. package/components/spinner/spinner.examples.md +26 -0
  122. package/components/spinner/spinner.js +17 -0
  123. package/components/spinner/spinner.test.js +234 -0
  124. package/components/spinner/spinner.yaml +230 -0
  125. package/components/stack/stack.css +11 -11
  126. package/components/stat/stat.css +25 -25
  127. package/components/step-progress/step-progress.css +20 -20
  128. package/components/stepper/stepper.css +29 -29
  129. package/components/stream/stream.css +12 -12
  130. package/components/swatch/swatch.css +68 -68
  131. package/components/swiper/swiper.css +57 -57
  132. package/components/switch/switch.css +52 -52
  133. package/components/table/class.js +9 -0
  134. package/components/table/table.a2ui.json +1 -1
  135. package/components/table/table.css +162 -162
  136. package/components/table/table.d.ts +1 -1
  137. package/components/table/table.test.js +53 -0
  138. package/components/table/table.yaml +13 -1
  139. package/components/table-toolbar/table-toolbar.css +32 -32
  140. package/components/tabs/tabs.css +51 -51
  141. package/components/tag/tag.css +48 -48
  142. package/components/text/text.css +44 -44
  143. package/components/textarea/textarea.css +46 -46
  144. package/components/time-picker/class.js +693 -0
  145. package/components/time-picker/time-picker.a2ui.json +267 -0
  146. package/components/time-picker/time-picker.css +122 -0
  147. package/components/time-picker/time-picker.d.ts +75 -0
  148. package/components/time-picker/time-picker.examples.md +35 -0
  149. package/components/time-picker/time-picker.js +17 -0
  150. package/components/time-picker/time-picker.test.js +287 -0
  151. package/components/time-picker/time-picker.yaml +256 -0
  152. package/components/timeline/timeline.css +50 -50
  153. package/components/toast/toast.css +58 -58
  154. package/components/toggle-group/toggle-group.css +6 -6
  155. package/components/toggle-scheme/toggle-scheme.css +2 -2
  156. package/components/toolbar/toolbar.css +17 -17
  157. package/components/tooltip/tooltip.css +2 -2
  158. package/components/tree/tree.css +37 -37
  159. package/components/upload/upload.css +49 -49
  160. package/dist/icons-manifest.js +3 -3
  161. package/dist/web-components.min.css +1 -1
  162. package/dist/web-components.min.js +121 -83
  163. package/package.json +1 -1
  164. package/styles/components.css +8 -0
@@ -0,0 +1,334 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://adiaui.dev/a2ui/v0_9/components/DatetimePicker.json",
4
+ "title": "DatetimePicker",
5
+ "description": "Single-control date + time selection. Trigger button opens a popover with a `<calendar-picker-ui>` on the left + a `<time-picker-ui>` on the right; commit emits a full ISO 8601 datetime string (\"YYYY-MM-DDTHH:mm\" or with seconds). Composes the two underlying primitives — never wraps a native `<input type=\"datetime-local\">` (per ADR-0025). Form-associated under one `name`. SPEC-038.",
6
+ "type": "object",
7
+ "allOf": [
8
+ {
9
+ "$ref": "common_types.json#/$defs/ComponentCommon"
10
+ },
11
+ {
12
+ "$ref": "common_types.json#/$defs/CatalogComponentCommon"
13
+ }
14
+ ],
15
+ "properties": {
16
+ "required": {
17
+ "description": "Required for validation when inside a `<form>`.",
18
+ "type": "boolean",
19
+ "default": false
20
+ },
21
+ "component": {
22
+ "const": "DatetimePicker"
23
+ },
24
+ "disabled": {
25
+ "description": "Block all interaction. Trigger remains rendered but does not open the popover.",
26
+ "type": "boolean",
27
+ "default": false
28
+ },
29
+ "format": {
30
+ "description": "Trigger button date format. `short`: `Jan 1, 2026 14:30`; `long`: `January 1, 2026 14:30`; `iso`: full ISO string.",
31
+ "type": "string",
32
+ "enum": [
33
+ "short",
34
+ "long",
35
+ "iso"
36
+ ],
37
+ "default": "short"
38
+ },
39
+ "hourcycle": {
40
+ "description": "Hour cycle for the time pane. Empty (default) derives from the\ndocument locale. `h12` forces a 12-hour cycle with an AM/PM\n(meridiem) segment; `h23` forces 24-hour cycle.\n",
41
+ "type": "string",
42
+ "enum": [
43
+ "",
44
+ "h12",
45
+ "h23"
46
+ ],
47
+ "default": ""
48
+ },
49
+ "locale": {
50
+ "description": "BCP-47 locale tag used to derive hour-cycle when `hour-cycle` is empty. Falls back to `<html lang>` then to browser default.",
51
+ "type": "string",
52
+ "default": ""
53
+ },
54
+ "max": {
55
+ "description": "Latest selectable ISO 8601 datetime (inclusive). Days after are disabled in the calendar pane; times after are rejected by the time pane on the same day.",
56
+ "type": "string",
57
+ "default": ""
58
+ },
59
+ "min": {
60
+ "description": "Earliest selectable ISO 8601 datetime (inclusive). Days before are disabled in the calendar pane; times before are rejected by the time pane on the same day.",
61
+ "type": "string",
62
+ "default": ""
63
+ },
64
+ "name": {
65
+ "description": "Form field name. The ISO 8601 datetime is submitted under this key when the picker is inside a `<form>`.",
66
+ "type": "string",
67
+ "default": ""
68
+ },
69
+ "open": {
70
+ "description": "Whether the popover is currently open.",
71
+ "type": "boolean",
72
+ "default": false
73
+ },
74
+ "placeholder": {
75
+ "description": "Text shown in the trigger when the value is empty.",
76
+ "type": "string",
77
+ "default": "Select date and time"
78
+ },
79
+ "precision": {
80
+ "description": "Time-pane precision. `minute` (default) emits `HH:mm`; `second` exposes the seconds segment and emits `HH:mm:ss`.",
81
+ "type": "string",
82
+ "enum": [
83
+ "minute",
84
+ "second"
85
+ ],
86
+ "default": "minute"
87
+ },
88
+ "readonly": {
89
+ "description": "Block edits; allow keyboard navigation for screen-reader inspection.",
90
+ "type": "boolean",
91
+ "default": false
92
+ },
93
+ "step": {
94
+ "description": "Per-Arrow-keypress increment in seconds for the time pane. 60 = minute precision (default), 900 = 15-minute, 1 = second precision.",
95
+ "type": "number",
96
+ "default": 60
97
+ },
98
+ "value": {
99
+ "description": "Current value as ISO 8601 datetime (\"YYYY-MM-DDTHH:mm\" or \"YYYY-MM-DDTHH:mm:ss\"). Empty when no value selected.",
100
+ "$ref": "common_types.json#/$defs/DynamicString"
101
+ }
102
+ },
103
+ "required": [
104
+ "component"
105
+ ],
106
+ "unevaluatedProperties": false,
107
+ "x-adiaui": {
108
+ "anti_patterns": [
109
+ {
110
+ "fix": "{\"component\": \"DatetimePicker\", \"value\": \"2026-05-24T00:00\"}\n",
111
+ "why": "`value` is a date-only string — no time component. The contract requires\na full ISO 8601 datetime including the `T` and time segment.\n",
112
+ "wrong": "{\"component\": \"DatetimePicker\", \"value\": \"2026-05-24\"}\n"
113
+ },
114
+ {
115
+ "fix": "{\"component\": \"DatetimePicker\", \"value\": \"2026-05-24T14:30\"}\n",
116
+ "why": "`value` is a time-only string — no date component. Use `<TimePicker>` for\ntime-only selection or supply the date portion.\n",
117
+ "wrong": "{\"component\": \"DatetimePicker\", \"value\": \"14:30\"}\n"
118
+ },
119
+ {
120
+ "fix": "{\"component\": \"DatetimePicker\", \"name\": \"field-name\"}\n",
121
+ "why": "Nesting a native datetime-local input violates ADR-0025 and bypasses\nElementInternals form participation.\n",
122
+ "wrong": "{\"component\": \"DatetimePicker\", \"children\": [\n {\"component\": \"Input\", \"type\": \"datetime-local\"}\n]}\n"
123
+ },
124
+ {
125
+ "fix": "<datetime-picker-ui name=\"appointment\"></datetime-picker-ui>\n",
126
+ "why": "Hand-rolled date + free-form time composition is the pattern this primitive\nreplaces. It misses the coordinated popover, the per-segment Spinbutton\na11y model, and unified form participation.\n",
127
+ "wrong": "<calendar-picker-ui></calendar-picker-ui>\n<input-ui type=\"text\" placeholder=\"HH:mm\"></input-ui>\n"
128
+ }
129
+ ],
130
+ "category": "input",
131
+ "composes": [
132
+ "calendar-grid-ui",
133
+ "time-picker-ui",
134
+ "button-ui",
135
+ "popover-ui",
136
+ "divider-ui"
137
+ ],
138
+ "events": {
139
+ "change": {
140
+ "description": "Fired when the value commits (date picked + time edited, OR Apply clicked in explicit-commit mode).",
141
+ "detail": {
142
+ "source": "string",
143
+ "value": "string"
144
+ }
145
+ },
146
+ "close": {
147
+ "description": "Popover closed (without commit, or after commit).",
148
+ "detail": {
149
+ "reason": "string"
150
+ }
151
+ },
152
+ "input": {
153
+ "description": "Fired during partial selection (date picked but time still pending, or vice versa).",
154
+ "detail": {
155
+ "value": "string"
156
+ }
157
+ },
158
+ "invalid": {
159
+ "description": "A constraint failed (out of range, parse error).",
160
+ "detail": {
161
+ "reason": "string",
162
+ "value": "string"
163
+ }
164
+ },
165
+ "open": {
166
+ "description": "Popover opened (user clicked the trigger or pressed Enter / Space).",
167
+ "detail": {
168
+ "trigger": "string"
169
+ }
170
+ }
171
+ },
172
+ "examples": [
173
+ {
174
+ "description": "Form-field-wrapped picker with min/max bounds.",
175
+ "a2ui": "[\n {\n \"id\": \"field\",\n \"component\": \"Field\",\n \"label\": \"Appointment\",\n \"children\": [\"dt\"]\n },\n {\n \"id\": \"dt\",\n \"component\": \"DatetimePicker\",\n \"name\": \"appointment\",\n \"min\": \"2026-01-01T00:00\",\n \"max\": \"2026-12-31T23:59\"\n }\n]\n",
176
+ "name": "canonical"
177
+ },
178
+ {
179
+ "description": "Log-cursor picker with second precision.",
180
+ "a2ui": "[\n {\n \"id\": \"dt\",\n \"component\": \"DatetimePicker\",\n \"name\": \"log-cursor\",\n \"precision\": \"second\",\n \"step\": 1,\n \"value\": \"2026-05-24T14:30:45\"\n }\n]\n",
181
+ "name": "second-precision"
182
+ },
183
+ {
184
+ "description": "Cron editor with forced 24-hour cycle.",
185
+ "a2ui": "[\n {\n \"id\": \"dt\",\n \"component\": \"DatetimePicker\",\n \"name\": \"cron\",\n \"hourCycle\": \"h23\"\n }\n]\n",
186
+ "name": "forced-24h"
187
+ },
188
+ {
189
+ "description": "Read-only datetime for inspection only.",
190
+ "a2ui": "[\n {\n \"id\": \"dt\",\n \"component\": \"DatetimePicker\",\n \"readonly\": true,\n \"value\": \"2026-05-24T14:30\"\n }\n]\n",
191
+ "name": "readonly"
192
+ }
193
+ ],
194
+ "keywords": [
195
+ "datetimepicker",
196
+ "datetime-picker",
197
+ "datetime",
198
+ "date-time",
199
+ "dateandtime",
200
+ "appointment",
201
+ "schedule",
202
+ "timestamp"
203
+ ],
204
+ "name": "UIDatetimePicker",
205
+ "related": [
206
+ "calendar-picker",
207
+ "time-picker",
208
+ "date-range-picker",
209
+ "popover",
210
+ "field",
211
+ "button"
212
+ ],
213
+ "slots": {
214
+ "footer": {
215
+ "description": "Optional Apply / Cancel buttons for explicit-commit flows. Spans both panes below the calendar + time area."
216
+ },
217
+ "trigger": {
218
+ "description": "Custom trigger replacement. When omitted, a default `<button-ui>` is stamped."
219
+ }
220
+ },
221
+ "states": [
222
+ {
223
+ "description": "Closed, no pending selection.",
224
+ "name": "idle"
225
+ },
226
+ {
227
+ "description": "Popover open, no calendar pick yet.",
228
+ "attribute": "open",
229
+ "name": "open-pending-date"
230
+ },
231
+ {
232
+ "description": "Date picked; time pane is the next focus target.",
233
+ "attribute": "open",
234
+ "name": "open-pending-time"
235
+ },
236
+ {
237
+ "description": "Both panes set; awaiting Apply (explicit-commit mode only).",
238
+ "attribute": "open",
239
+ "name": "open-committed"
240
+ },
241
+ {
242
+ "description": "Non-interactive; dimmed.",
243
+ "attribute": "disabled",
244
+ "name": "disabled"
245
+ },
246
+ {
247
+ "description": "Read-only; trigger keyboard-focusable but popover does not open.",
248
+ "attribute": "readonly",
249
+ "name": "readonly"
250
+ }
251
+ ],
252
+ "status": "experimental",
253
+ "synonyms": {
254
+ "appointment": [
255
+ "datetime",
256
+ "meeting",
257
+ "schedule"
258
+ ],
259
+ "datetime": [
260
+ "date-time",
261
+ "timestamp",
262
+ "appointment",
263
+ "schedule"
264
+ ],
265
+ "tags": [
266
+ "DateTimePicker",
267
+ "DateTimeInput",
268
+ "DatetimeInput",
269
+ "Timestamp"
270
+ ]
271
+ },
272
+ "tag": "datetime-picker-ui",
273
+ "tokens": {
274
+ "--datetime-picker-bg": {
275
+ "description": "Host background.",
276
+ "default": "var(--a-bg)"
277
+ },
278
+ "--datetime-picker-divider": {
279
+ "description": "Pane divider color.",
280
+ "default": "var(--a-border-subtle)"
281
+ },
282
+ "--datetime-picker-duration": {
283
+ "description": "Open/close transition duration.",
284
+ "default": "var(--a-duration-fast)"
285
+ },
286
+ "--datetime-picker-easing": {
287
+ "description": "Open/close transition easing.",
288
+ "default": "var(--a-easing)"
289
+ },
290
+ "--datetime-picker-fg": {
291
+ "description": "Host text color.",
292
+ "default": "var(--a-fg)"
293
+ },
294
+ "--datetime-picker-popover-bg": {
295
+ "description": "Popover background.",
296
+ "default": "var(--a-bg-subtle)"
297
+ },
298
+ "--datetime-picker-popover-border": {
299
+ "description": "Popover border color.",
300
+ "default": "var(--a-border-subtle)"
301
+ },
302
+ "--datetime-picker-popover-gap": {
303
+ "description": "Gap between calendar pane and time pane.",
304
+ "default": "var(--a-space-3)"
305
+ },
306
+ "--datetime-picker-popover-padding": {
307
+ "description": "Popover internal padding.",
308
+ "default": "var(--a-space-3)"
309
+ },
310
+ "--datetime-picker-popover-radius": {
311
+ "description": "Popover border radius.",
312
+ "default": "var(--a-radius-lg)"
313
+ },
314
+ "--datetime-picker-popover-shadow": {
315
+ "description": "Popover box shadow.",
316
+ "default": "var(--a-shadow-lg)"
317
+ },
318
+ "--datetime-picker-px": {
319
+ "description": "Horizontal popover padding.",
320
+ "default": "var(--a-space-3)"
321
+ },
322
+ "--datetime-picker-py": {
323
+ "description": "Vertical popover padding.",
324
+ "default": "var(--a-space-2)"
325
+ },
326
+ "--datetime-picker-trigger-min-width": {
327
+ "description": "Default trigger min-width — sized so the formatted date+time fits without truncation.",
328
+ "default": "16em"
329
+ }
330
+ },
331
+ "traits": [],
332
+ "version": 1
333
+ }
334
+ }
@@ -0,0 +1,150 @@
1
+ /* ============================================================
2
+ datetime-picker — two-block @scope per ADR-0003.
3
+ Block 1 (TOKENS): :where(:scope) — token defaults.
4
+ Block 2 (BASE): :scope + descendant selectors.
5
+ Popover surfaces live OUTSIDE @scope because the Popover API
6
+ lifts them into the top layer; custom-property inheritance
7
+ still cascades from the host so --datetime-picker-* tokens
8
+ reach the popover.
9
+ ============================================================ */
10
+
11
+ @scope (datetime-picker-ui) {
12
+ /* ── Block 1 — TOKENS ── */
13
+ :where(:scope) {
14
+ --datetime-picker-bg-default: var(--a-bg);
15
+ --datetime-picker-fg-default: var(--a-fg);
16
+
17
+ /* Popover surface */
18
+ --datetime-picker-popover-bg-default: var(--a-bg-subtle);
19
+ --datetime-picker-popover-border-default: var(--a-border-subtle);
20
+ --datetime-picker-popover-radius-default: var(--a-radius-lg);
21
+ --datetime-picker-popover-shadow-default: var(--a-shadow-lg);
22
+ --datetime-picker-popover-padding-default: var(--a-space-3);
23
+ --datetime-picker-popover-gap-default: var(--a-space-3);
24
+
25
+ /* Pane divider */
26
+ --datetime-picker-divider-default: var(--a-border-subtle);
27
+
28
+ /* Trigger */
29
+ --datetime-picker-trigger-min-width-default: 16em;
30
+
31
+ /* Padding */
32
+ --datetime-picker-px-default: var(--a-space-3);
33
+ --datetime-picker-py-default: var(--a-space-2);
34
+
35
+ /* Motion */
36
+ --datetime-picker-duration-default: var(--a-duration-fast);
37
+ --datetime-picker-easing-default: var(--a-easing);
38
+ }
39
+
40
+ /* ── Block 2 — BASE ── */
41
+ :scope {
42
+ box-sizing: border-box;
43
+ position: relative;
44
+ display: inline-block;
45
+ background: var(--datetime-picker-bg, var(--datetime-picker-bg-default));
46
+ color: var(--datetime-picker-fg, var(--datetime-picker-fg-default));
47
+ font-size: var(--a-ui-size);
48
+ }
49
+
50
+ /* Default trigger sizing — composes button-ui's surface; just
51
+ stretches the min-width so "Jan 1, 2026 14:30" fits. */
52
+ :scope > [slot="trigger"] {
53
+ min-width: var(--datetime-picker-trigger-min-width, var(--datetime-picker-trigger-min-width-default));
54
+ }
55
+
56
+ /* States */
57
+ :scope[disabled] {
58
+ opacity: 0.5;
59
+ pointer-events: none;
60
+ }
61
+ :scope[readonly] > [slot="trigger"] {
62
+ cursor: default;
63
+ }
64
+ }
65
+
66
+ /* ============================================================
67
+ Popover surface — outside @scope (lifted to top layer).
68
+ Custom properties inherit from the host so
69
+ --datetime-picker-* tokens are available here.
70
+ ============================================================ */
71
+
72
+ /* §FB-Wave1-QA — `display: grid` MUST be guarded by `:popover-open` so the
73
+ popover honors the UA `popover` `display: none` while closed. */
74
+ datetime-picker-ui [slot="popover"] {
75
+ margin: 0;
76
+ padding: var(--datetime-picker-py, var(--datetime-picker-py-default)) var(--datetime-picker-px, var(--datetime-picker-px-default));
77
+ border: 1px solid var(--datetime-picker-popover-border, var(--datetime-picker-popover-border-default));
78
+ border-radius: var(--datetime-picker-popover-radius, var(--datetime-picker-popover-radius-default));
79
+ background: var(--datetime-picker-popover-bg, var(--datetime-picker-popover-bg-default));
80
+ box-shadow: var(--datetime-picker-popover-shadow, var(--datetime-picker-popover-shadow-default));
81
+ color: var(--a-fg);
82
+ /* Anchor-positioning fallback — popover.css and anchor.js handle
83
+ placement; layout here just sets the grid. */
84
+ inset: auto;
85
+ /* Fade + lift in on first paint via @starting-style. */
86
+ opacity: 1;
87
+ translate: 0 0;
88
+ transition:
89
+ opacity var(--datetime-picker-duration, var(--datetime-picker-duration-default)) var(--datetime-picker-easing, var(--datetime-picker-easing-default)),
90
+ translate var(--datetime-picker-duration, var(--datetime-picker-duration-default)) var(--datetime-picker-easing, var(--datetime-picker-easing-default));
91
+ }
92
+
93
+ datetime-picker-ui [slot="popover"]:popover-open {
94
+ display: grid;
95
+ grid-template-columns: auto auto auto;
96
+ grid-template-areas: "cal divider time";
97
+ gap: var(--datetime-picker-popover-gap, var(--datetime-picker-popover-gap-default));
98
+ align-items: start;
99
+ }
100
+
101
+ datetime-picker-ui [slot="popover"]:popover-open {
102
+ @starting-style {
103
+ opacity: 0;
104
+ translate: 0 -4px;
105
+ }
106
+ }
107
+
108
+ @media (prefers-reduced-motion: reduce) {
109
+ datetime-picker-ui [slot="popover"] { transition: none; }
110
+ }
111
+
112
+ /* Pane areas. */
113
+ datetime-picker-ui [slot="popover"] > [data-cal-pane] {
114
+ grid-area: cal;
115
+ }
116
+ datetime-picker-ui [slot="popover"] > [data-pane-divider] {
117
+ grid-area: divider;
118
+ align-self: stretch;
119
+ --divider-color: var(--datetime-picker-divider, var(--datetime-picker-divider-default));
120
+ }
121
+ datetime-picker-ui [slot="popover"] > [data-time-pane] {
122
+ grid-area: time;
123
+ align-self: start;
124
+ }
125
+
126
+ /* Footer area (consumer-supplied [slot="footer"]) — spans all three
127
+ columns under the panes. */
128
+ datetime-picker-ui [slot="popover"] > [slot="footer"] {
129
+ grid-column: 1 / -1;
130
+ display: flex;
131
+ justify-content: flex-end;
132
+ gap: var(--a-space-2);
133
+ padding-block-start: var(--a-space-2);
134
+ border-block-start: 1px solid var(--a-border-subtle);
135
+ }
136
+
137
+ /* Narrow surfaces (e.g. inside a card on mobile): stack the panes
138
+ vertically and replace the vertical divider with a horizontal rule. */
139
+ @container (max-width: 32rem) {
140
+ datetime-picker-ui [slot="popover"]:popover-open {
141
+ grid-template-columns: 1fr;
142
+ grid-template-areas:
143
+ "cal"
144
+ "divider"
145
+ "time";
146
+ }
147
+ datetime-picker-ui [slot="popover"] > [data-pane-divider] {
148
+ align-self: auto;
149
+ }
150
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * `<datetime-picker-ui>` — Single-control date + time selection. Trigger button opens a popover with a `<calendar-picker-ui>` on the left + a `<time-picker-ui>` on the right; commit emits a full ISO 8601 datetime string ("YYYY-MM-DDTHH:mm" or with seconds). Composes the two underlying primitives — never wraps a native `<input type="datetime-local">` (per ADR-0025). Form-associated under one `name`. SPEC-038.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/datetime-picker
5
+ *
6
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
7
+ * the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
8
+ * run `npm run build:components`, then `npm run codegen:dts` to
9
+ * regenerate; or hand-author this file fully if rich event types are
10
+ * needed beyond what the yaml `events:` block can express.
11
+ */
12
+
13
+ import { UIElement } from '../../core/element.js';
14
+
15
+ export interface DatetimePickerChangeEventDetail {
16
+ source: string;
17
+ value: string;
18
+ }
19
+
20
+ export type DatetimePickerChangeEvent = CustomEvent<DatetimePickerChangeEventDetail>;
21
+ export interface DatetimePickerCloseEventDetail {
22
+ reason: string;
23
+ }
24
+
25
+ export type DatetimePickerCloseEvent = CustomEvent<DatetimePickerCloseEventDetail>;
26
+ export interface DatetimePickerInputEventDetail {
27
+ value: string;
28
+ }
29
+
30
+ export type DatetimePickerInputEvent = CustomEvent<DatetimePickerInputEventDetail>;
31
+ export interface DatetimePickerInvalidEventDetail {
32
+ reason: string;
33
+ value: string;
34
+ }
35
+
36
+ export type DatetimePickerInvalidEvent = CustomEvent<DatetimePickerInvalidEventDetail>;
37
+ export interface DatetimePickerOpenEventDetail {
38
+ trigger: string;
39
+ }
40
+
41
+ export type DatetimePickerOpenEvent = CustomEvent<DatetimePickerOpenEventDetail>;
42
+
43
+ export class UIDatetimePicker extends UIElement {
44
+ /** Required for validation when inside a `<form>`. */
45
+ required: boolean;
46
+ /** Block all interaction. Trigger remains rendered but does not open the popover. */
47
+ disabled: boolean;
48
+ /** Trigger button date format. `short`: `Jan 1, 2026 14:30`; `long`: `January 1, 2026 14:30`; `iso`: full ISO string. */
49
+ format: 'short' | 'long' | 'iso';
50
+ /** Hour cycle for the time pane. Empty (default) derives from the
51
+ document locale. `h12` forces a 12-hour cycle with an AM/PM
52
+ (meridiem) segment; `h23` forces 24-hour cycle.
53
+ */
54
+ hourcycle: '' | 'h12' | 'h23';
55
+ /** BCP-47 locale tag used to derive hour-cycle when `hour-cycle` is empty. Falls back to `<html lang>` then to browser default. */
56
+ locale: string;
57
+ /** Latest selectable ISO 8601 datetime (inclusive). Days after are disabled in the calendar pane; times after are rejected by the time pane on the same day. */
58
+ max: string;
59
+ /** Earliest selectable ISO 8601 datetime (inclusive). Days before are disabled in the calendar pane; times before are rejected by the time pane on the same day. */
60
+ min: string;
61
+ /** Form field name. The ISO 8601 datetime is submitted under this key when the picker is inside a `<form>`. */
62
+ name: string;
63
+ /** Whether the popover is currently open. */
64
+ open: boolean;
65
+ /** Text shown in the trigger when the value is empty. */
66
+ placeholder: string;
67
+ /** Time-pane precision. `minute` (default) emits `HH:mm`; `second` exposes the seconds segment and emits `HH:mm:ss`. */
68
+ precision: 'minute' | 'second';
69
+ /** Block edits; allow keyboard navigation for screen-reader inspection. */
70
+ readonly: boolean;
71
+ /** Per-Arrow-keypress increment in seconds for the time pane. 60 = minute precision (default), 900 = 15-minute, 1 = second precision. */
72
+ step: number;
73
+ /** Current value as ISO 8601 datetime ("YYYY-MM-DDTHH:mm" or "YYYY-MM-DDTHH:mm:ss"). Empty when no value selected. */
74
+ value: string;
75
+
76
+ addEventListener<K extends keyof HTMLElementEventMap>(
77
+ type: K,
78
+ listener: (this: UIDatetimePicker, ev: HTMLElementEventMap[K]) => unknown,
79
+ options?: boolean | AddEventListenerOptions,
80
+ ): void;
81
+ addEventListener(type: 'change', listener: (ev: DatetimePickerChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
82
+ addEventListener(type: 'close', listener: (ev: DatetimePickerCloseEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
83
+ addEventListener(type: 'input', listener: (ev: DatetimePickerInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
84
+ addEventListener(type: 'invalid', listener: (ev: DatetimePickerInvalidEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
85
+ addEventListener(type: 'open', listener: (ev: DatetimePickerOpenEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
86
+ }
@@ -0,0 +1,46 @@
1
+ # datetime-picker — Examples
2
+
3
+ ## Canonical
4
+
5
+ ```html
6
+ <field-ui label="Appointment">
7
+ <datetime-picker-ui
8
+ name="appointment"
9
+ min="2026-01-01T00:00"
10
+ max="2026-12-31T23:59">
11
+ </datetime-picker-ui>
12
+ </field-ui>
13
+ ```
14
+
15
+ ## Second precision
16
+
17
+ ```html
18
+ <datetime-picker-ui
19
+ precision="second"
20
+ step="1"
21
+ value="2026-05-24T14:30:45">
22
+ </datetime-picker-ui>
23
+ ```
24
+
25
+ ## Forced 24-hour cycle
26
+
27
+ ```html
28
+ <datetime-picker-ui hour-cycle="h23"></datetime-picker-ui>
29
+ ```
30
+
31
+ ## Explicit commit (Apply / Cancel)
32
+
33
+ ```html
34
+ <datetime-picker-ui name="explicit">
35
+ <div slot="footer">
36
+ <button-ui data-action="cancel" variant="ghost" text="Cancel"></button-ui>
37
+ <button-ui data-action="apply" variant="primary" text="Apply"></button-ui>
38
+ </div>
39
+ </datetime-picker-ui>
40
+ ```
41
+
42
+ ## Readonly
43
+
44
+ ```html
45
+ <datetime-picker-ui readonly value="2026-05-24T14:30"></datetime-picker-ui>
46
+ ```
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `<datetime-picker-ui>` — auto-registers the tag on import.
3
+ *
4
+ * For non-side-effect class import (test isolation, tag override), use
5
+ * the `class` subpath:
6
+ *
7
+ * import { UIDatetimePicker } from '@adia-ai/web-components/components/datetime-picker/class';
8
+ *
9
+ * @see ../../USAGE.md#registration--auto-vs-explicit
10
+ */
11
+
12
+ import { defineIfFree } from '../../core/register.js';
13
+ import { UIDatetimePicker } from './class.js';
14
+
15
+ defineIfFree('datetime-picker-ui', UIDatetimePicker);
16
+
17
+ export { UIDatetimePicker };