@proyecto-viviana/solidaria-components 0.4.0 → 0.4.1

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 (192) hide show
  1. package/dist/ActionBar.d.ts.map +1 -1
  2. package/dist/ActionBar.js +2 -11
  3. package/dist/ActionBar.js.map +1 -1
  4. package/dist/ActionBar.jsx +2 -11
  5. package/dist/ActionBar.jsx.map +1 -1
  6. package/dist/ActionGroup.d.ts.map +1 -1
  7. package/dist/ActionGroup.js +1 -1
  8. package/dist/ActionGroup.js.map +1 -1
  9. package/dist/ActionGroup.jsx +1 -1
  10. package/dist/ActionGroup.jsx.map +1 -1
  11. package/dist/Autocomplete.d.ts +2 -2
  12. package/dist/Autocomplete.d.ts.map +1 -1
  13. package/dist/Autocomplete.js +7 -7
  14. package/dist/Autocomplete.js.map +1 -1
  15. package/dist/Autocomplete.jsx +7 -7
  16. package/dist/Autocomplete.jsx.map +1 -1
  17. package/dist/Breadcrumbs.d.ts.map +1 -1
  18. package/dist/Breadcrumbs.js +15 -16
  19. package/dist/Breadcrumbs.js.map +1 -1
  20. package/dist/Breadcrumbs.jsx +19 -24
  21. package/dist/Breadcrumbs.jsx.map +1 -1
  22. package/dist/Calendar.d.ts.map +1 -1
  23. package/dist/Calendar.js +100 -65
  24. package/dist/Calendar.js.map +1 -1
  25. package/dist/Calendar.jsx +10 -1
  26. package/dist/Calendar.jsx.map +1 -1
  27. package/dist/Color.d.ts.map +1 -1
  28. package/dist/Color.js +15 -18
  29. package/dist/Color.js.map +1 -1
  30. package/dist/Color.jsx +15 -19
  31. package/dist/Color.jsx.map +1 -1
  32. package/dist/ComboBox.d.ts +4 -0
  33. package/dist/ComboBox.d.ts.map +1 -1
  34. package/dist/ComboBox.js +21 -13
  35. package/dist/ComboBox.js.map +1 -1
  36. package/dist/ComboBox.jsx +23 -13
  37. package/dist/ComboBox.jsx.map +1 -1
  38. package/dist/DateField.d.ts +11 -2
  39. package/dist/DateField.d.ts.map +1 -1
  40. package/dist/DateField2.js +237 -234
  41. package/dist/DateField2.js.map +1 -1
  42. package/dist/DateField2.jsx +134 -97
  43. package/dist/DateField2.jsx.map +1 -1
  44. package/dist/DatePicker.d.ts +42 -3
  45. package/dist/DatePicker.d.ts.map +1 -1
  46. package/dist/DatePicker.js +6 -990
  47. package/dist/DatePicker.jsx +6 -681
  48. package/dist/DatePicker2.js +1171 -0
  49. package/dist/DatePicker2.js.map +1 -0
  50. package/dist/DatePicker2.jsx +820 -0
  51. package/dist/DatePicker2.jsx.map +1 -0
  52. package/dist/DateRangePickerContext.d.ts +2 -0
  53. package/dist/DateRangePickerContext.d.ts.map +1 -1
  54. package/dist/Disclosure.d.ts.map +1 -1
  55. package/dist/Disclosure.js +3 -0
  56. package/dist/Disclosure.js.map +1 -1
  57. package/dist/Disclosure.jsx +1 -1
  58. package/dist/Disclosure.jsx.map +1 -1
  59. package/dist/GridList.d.ts.map +1 -1
  60. package/dist/GridList.js +2 -2
  61. package/dist/GridList.js.map +1 -1
  62. package/dist/GridList.jsx +2 -2
  63. package/dist/GridList.jsx.map +1 -1
  64. package/dist/ListBox.d.ts +2 -2
  65. package/dist/ListBox.d.ts.map +1 -1
  66. package/dist/ListBox.js +327 -166
  67. package/dist/ListBox.js.map +1 -1
  68. package/dist/ListBox.jsx +161 -25
  69. package/dist/ListBox.jsx.map +1 -1
  70. package/dist/Modal.d.ts.map +1 -1
  71. package/dist/Modal.js +7 -5
  72. package/dist/Modal.js.map +1 -1
  73. package/dist/Modal.jsx +5 -5
  74. package/dist/Modal.jsx.map +1 -1
  75. package/dist/Popover.d.ts.map +1 -1
  76. package/dist/Popover.js +16 -9
  77. package/dist/Popover.js.map +1 -1
  78. package/dist/Popover.jsx +25 -4
  79. package/dist/Popover.jsx.map +1 -1
  80. package/dist/RangeCalendar.d.ts.map +1 -1
  81. package/dist/RangeCalendar.js +182 -46
  82. package/dist/RangeCalendar.js.map +1 -1
  83. package/dist/RangeCalendar.jsx +72 -2
  84. package/dist/RangeCalendar.jsx.map +1 -1
  85. package/dist/SearchField.d.ts.map +1 -1
  86. package/dist/SearchField.js +26 -2
  87. package/dist/SearchField.js.map +1 -1
  88. package/dist/SearchField.jsx +26 -2
  89. package/dist/SearchField.jsx.map +1 -1
  90. package/dist/Select.d.ts +7 -0
  91. package/dist/Select.d.ts.map +1 -1
  92. package/dist/Select.js +62 -49
  93. package/dist/Select.js.map +1 -1
  94. package/dist/Select.jsx +33 -18
  95. package/dist/Select.jsx.map +1 -1
  96. package/dist/SharedElementTransition.d.ts.map +1 -1
  97. package/dist/SharedElementTransition.js +35 -33
  98. package/dist/SharedElementTransition.js.map +1 -1
  99. package/dist/SharedElementTransition.jsx +35 -33
  100. package/dist/SharedElementTransition.jsx.map +1 -1
  101. package/dist/StepList.d.ts.map +1 -1
  102. package/dist/StepList.js +2 -9
  103. package/dist/StepList.js.map +1 -1
  104. package/dist/StepList.jsx +1 -6
  105. package/dist/StepList.jsx.map +1 -1
  106. package/dist/Table.d.ts +2 -0
  107. package/dist/Table.d.ts.map +1 -1
  108. package/dist/Table.js +10 -3
  109. package/dist/Table.js.map +1 -1
  110. package/dist/Table.jsx +10 -3
  111. package/dist/Table.jsx.map +1 -1
  112. package/dist/Tabs.d.ts.map +1 -1
  113. package/dist/Tabs.js +3 -0
  114. package/dist/Tabs.js.map +1 -1
  115. package/dist/Tabs.jsx +1 -1
  116. package/dist/Tabs.jsx.map +1 -1
  117. package/dist/TagGroup.d.ts +3 -1
  118. package/dist/TagGroup.d.ts.map +1 -1
  119. package/dist/TagGroup.js +12 -8
  120. package/dist/TagGroup.js.map +1 -1
  121. package/dist/TagGroup.jsx +11 -8
  122. package/dist/TagGroup.jsx.map +1 -1
  123. package/dist/TextField.js +4 -1
  124. package/dist/TextField.js.map +1 -1
  125. package/dist/TextField.jsx +4 -1
  126. package/dist/TextField.jsx.map +1 -1
  127. package/dist/TimeField.d.ts +14 -50
  128. package/dist/TimeField.d.ts.map +1 -1
  129. package/dist/TimeField.js +111 -205
  130. package/dist/TimeField.js.map +1 -1
  131. package/dist/TimeField.jsx +76 -82
  132. package/dist/TimeField.jsx.map +1 -1
  133. package/dist/Tree.d.ts.map +1 -1
  134. package/dist/Tree.js +3 -3
  135. package/dist/Tree.js.map +1 -1
  136. package/dist/Tree.jsx +3 -3
  137. package/dist/Tree.jsx.map +1 -1
  138. package/dist/index.d.ts +2 -3
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +5 -6
  141. package/dist/index.jsx +5 -6
  142. package/dist/useDragAndDrop.d.ts +0 -8
  143. package/dist/useDragAndDrop.d.ts.map +1 -1
  144. package/dist/useDragAndDrop2.js +6 -2
  145. package/dist/useDragAndDrop2.js.map +1 -1
  146. package/dist/useDragAndDrop2.jsx +6 -2
  147. package/dist/useDragAndDrop2.jsx.map +1 -1
  148. package/dist/utils.d.ts +1 -0
  149. package/dist/utils.d.ts.map +1 -1
  150. package/dist/utils.js +2 -2
  151. package/dist/utils.js.map +1 -1
  152. package/dist/utils.jsx +2 -2
  153. package/dist/utils.jsx.map +1 -1
  154. package/package.json +3 -9
  155. package/src/ActionBar.tsx +10 -12
  156. package/src/ActionGroup.tsx +5 -3
  157. package/src/Autocomplete.tsx +14 -9
  158. package/src/Breadcrumbs.tsx +55 -38
  159. package/src/Calendar.tsx +30 -1
  160. package/src/Color.tsx +42 -27
  161. package/src/ComboBox.tsx +49 -17
  162. package/src/DateField.tsx +285 -52
  163. package/src/DatePicker.tsx +345 -57
  164. package/src/DateRangePickerContext.tsx +2 -0
  165. package/src/Disclosure.tsx +4 -0
  166. package/src/GridList.tsx +8 -2
  167. package/src/ListBox.tsx +323 -21
  168. package/src/Modal.tsx +21 -5
  169. package/src/Popover.tsx +28 -7
  170. package/src/RangeCalendar.tsx +120 -1
  171. package/src/SearchField.tsx +53 -1
  172. package/src/Select.tsx +101 -20
  173. package/src/SharedElementTransition.tsx +92 -36
  174. package/src/StepList.tsx +0 -7
  175. package/src/Table.tsx +19 -4
  176. package/src/Tabs.tsx +1 -0
  177. package/src/TagGroup.tsx +26 -6
  178. package/src/TextField.tsx +1 -1
  179. package/src/TimeField.tsx +113 -196
  180. package/src/Tree.tsx +14 -4
  181. package/src/index.ts +1 -8
  182. package/src/useDragAndDrop.ts +8 -10
  183. package/src/utils.tsx +3 -3
  184. package/dist/DatePicker.js.map +0 -1
  185. package/dist/DatePicker.jsx.map +0 -1
  186. package/dist/HiddenTimeInput.d.ts +0 -25
  187. package/dist/HiddenTimeInput.d.ts.map +0 -1
  188. package/dist/HiddenTimeInput.js +0 -104
  189. package/dist/HiddenTimeInput.js.map +0 -1
  190. package/dist/HiddenTimeInput.jsx +0 -69
  191. package/dist/HiddenTimeInput.jsx.map +0 -1
  192. package/src/HiddenTimeInput.tsx +0 -133
package/src/TimeField.tsx CHANGED
@@ -1,8 +1,16 @@
1
1
  /**
2
2
  * TimeField component for solidaria-components
3
3
  *
4
- * Pre-wired headless time field component with segment-based editing.
5
- * Port of react-aria-components/src/TimeField.tsx
4
+ * Pre-wired headless time field. Faithful port of react-aria-components'
5
+ * TimeField, which does NOT define its own segment primitives — it reuses
6
+ * `DateInput`/`DateSegment` (there is no `TimeInput`/`TimeSegment` upstream).
7
+ * `TimeFieldState` IS a `DateFieldState` (plus `timeValue`), so this component
8
+ * drives the certified DateField segment/group stack directly: it provides the
9
+ * shared `DateFieldContext`/`DateFieldStateContext` that `DateInput`/`DateSegment`
10
+ * read, plus a `TimeFieldContext` for the time-field label/description/error
11
+ * chrome. Unlike DateField, TimeField renders NO root hidden autofill input (RAC
12
+ * TimeField renders none); its native-validation `<input>` is still emitted by
13
+ * the inner DateInput sibling.
6
14
  */
7
15
 
8
16
  import {
@@ -13,14 +21,9 @@ import {
13
21
  createSignal,
14
22
  splitProps,
15
23
  useContext,
16
- For,
17
24
  Show,
18
25
  } from "solid-js";
19
- import {
20
- createTimeField,
21
- createTimeSegment,
22
- type AriaTimeFieldProps,
23
- } from "@proyecto-viviana/solidaria";
26
+ import { createTimeField, mergeProps, type AriaTimeFieldProps } from "@proyecto-viviana/solidaria";
24
27
  import {
25
28
  createTimeFieldState,
26
29
  access,
@@ -30,7 +33,11 @@ import {
30
33
  type TimeValue,
31
34
  } from "@proyecto-viviana/solid-stately";
32
35
  import {
33
- type RenderChildren,
36
+ DateFieldContext,
37
+ DateFieldStateContext,
38
+ type DateFieldContextValue,
39
+ } from "./DateField";
40
+ import {
34
41
  type ClassNameOrFunction,
35
42
  type StyleOrFunction,
36
43
  type SlotProps,
@@ -40,7 +47,6 @@ import {
40
47
  Provider,
41
48
  } from "./utils";
42
49
  import { TextContext } from "./Text";
43
- import { HiddenTimeInput } from "./HiddenTimeInput";
44
50
  import { FormContext, type FormProps } from "./Form";
45
51
 
46
52
  export interface TimeFieldRenderProps {
@@ -69,46 +75,6 @@ export interface TimeFieldProps<T extends TimeValue = TimeValue>
69
75
  locale?: string;
70
76
  }
71
77
 
72
- export interface TimeInputRenderProps {
73
- /** Whether the input is disabled. */
74
- isDisabled: boolean;
75
- /** Whether the input is focused. */
76
- isFocused: boolean;
77
- }
78
-
79
- export interface TimeInputProps extends SlotProps {
80
- /** The children of the component (render function receiving segments). */
81
- children?: (segment: TimeSegmentType) => JSX.Element;
82
- /** The CSS className for the element. */
83
- class?: ClassNameOrFunction<TimeInputRenderProps>;
84
- /** The inline style for the element. */
85
- style?: StyleOrFunction<TimeInputRenderProps>;
86
- }
87
-
88
- export interface TimeSegmentRenderProps {
89
- /** Whether the segment is focused. */
90
- isFocused: boolean;
91
- /** Whether the segment is editable. */
92
- isEditable: boolean;
93
- /** Whether the segment is a placeholder. */
94
- isPlaceholder: boolean;
95
- /** The segment type. */
96
- type: TimeSegmentType["type"];
97
- /** The text to display. */
98
- text: string;
99
- }
100
-
101
- export interface TimeSegmentProps extends SlotProps {
102
- /** The segment data. */
103
- segment: TimeSegmentType;
104
- /** The children of the component. A function may be provided to receive render props. */
105
- children?: RenderChildren<TimeSegmentRenderProps>;
106
- /** The CSS className for the element. */
107
- class?: ClassNameOrFunction<TimeSegmentRenderProps>;
108
- /** The inline style for the element. */
109
- style?: StyleOrFunction<TimeSegmentRenderProps>;
110
- }
111
-
112
78
  export interface TimeFieldContextValue {
113
79
  state: TimeFieldState<TimeValue>;
114
80
  aria: {
@@ -188,9 +154,9 @@ export function useTimeFieldContext(): TimeFieldState<TimeValue> {
188
154
  * ```tsx
189
155
  * <TimeField label="Time">
190
156
  * <Label>Time</Label>
191
- * <TimeInput>
192
- * {(segment) => <TimeSegment segment={segment} />}
193
- * </TimeInput>
157
+ * <DateInput>
158
+ * {(segment) => <DateSegment segment={segment} />}
159
+ * </DateInput>
194
160
  * </TimeField>
195
161
  * ```
196
162
  */
@@ -239,6 +205,7 @@ function TimeFieldInner<T extends TimeValue = TimeValue>(
239
205
  "locale",
240
206
  "granularity",
241
207
  "hourCycle",
208
+ "hideTimeZone",
242
209
  "shouldForceLeadingZeros",
243
210
  "validationState",
244
211
  "validationBehavior",
@@ -250,14 +217,29 @@ function TimeFieldInner<T extends TimeValue = TimeValue>(
250
217
  );
251
218
 
252
219
  const [fieldRef, setFieldRef] = createSignal<HTMLDivElement | null>(null);
220
+ // Ref to the hidden validation <input> (the DateInput's `<Input>` sibling).
221
+ // Mirrors DateField: create it here, hand it to createTimeField below, and
222
+ // attach it to the same input through the DateFieldContext getter.
223
+ const [validationInputRef, setValidationInputRef] =
224
+ createSignal<HTMLInputElement | null>(null);
253
225
 
254
226
  const state = createTimeFieldState(stateProps);
255
227
 
256
228
  const fieldAria = createTimeField(
257
229
  () => ({
258
230
  ...(rest as Record<string, unknown>),
231
+ // RAC threads these props into both useTimeFieldState and useTimeField;
232
+ // they live in `stateProps` here, so forward them for the field hook's
233
+ // aria-disabled and the native validation <input> (type/required).
234
+ isDisabled: access(stateProps.isDisabled),
235
+ isReadOnly: access(stateProps.isReadOnly),
236
+ isRequired: access(stateProps.isRequired),
237
+ // Standalone default flips the hidden input to type="text" so an empty
238
+ // required value blocks HTML form submission (mirrors DateField).
239
+ validationBehavior: stateProps.validationBehavior ?? "native",
259
240
  description: stateProps.description,
260
241
  errorMessage: stateProps.errorMessage,
242
+ inputRef: () => validationInputRef() ?? undefined,
261
243
  }),
262
244
  state as unknown as TimeFieldState<TimeValue>,
263
245
  fieldRef,
@@ -279,11 +261,6 @@ function TimeFieldInner<T extends TimeValue = TimeValue>(
279
261
  renderValues,
280
262
  );
281
263
 
282
- const validationBehavior = () =>
283
- (stateProps as { validationBehavior?: "aria" | "native" }).validationBehavior ??
284
- formContext?.validationBehavior ??
285
- "native";
286
-
287
264
  const textSlots = {
288
265
  slots: {
289
266
  get description() {
@@ -295,146 +272,86 @@ function TimeFieldInner<T extends TimeValue = TimeValue>(
295
272
  },
296
273
  };
297
274
 
298
- return (
299
- <TimeFieldStateContext.Provider value={state as unknown as TimeFieldState<TimeValue>}>
300
- <TimeFieldContext.Provider
301
- value={{
302
- state: state as unknown as TimeFieldState<TimeValue>,
303
- aria: {
304
- labelProps: fieldAria.labelProps,
305
- inputProps: fieldAria.inputProps,
306
- descriptionProps: fieldAria.descriptionProps,
307
- errorMessageProps: fieldAria.errorMessageProps,
308
- },
309
- }}
310
- >
311
- <div
312
- ref={setFieldRef}
313
- {...fieldAria.fieldProps}
314
- class={renderProps.class()}
315
- style={renderProps.style()}
316
- data-disabled={dataAttr(state.isDisabled())}
317
- data-readonly={dataAttr(state.isReadOnly())}
318
- data-required={dataAttr(state.isRequired())}
319
- data-invalid={dataAttr(state.isInvalid())}
320
- >
321
- <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>
322
- {local.children as JSX.Element}
323
- </Provider>
324
- </div>
325
- <Show when={(rest as Record<string, unknown>).name}>
326
- <HiddenTimeInput
327
- name={(rest as Record<string, unknown>).name as string | undefined}
328
- form={(rest as Record<string, unknown>).form as string | undefined}
329
- value={state.value()}
330
- autoComplete={(rest as Record<string, unknown>).autoComplete as string | undefined}
331
- isDisabled={state.isDisabled()}
332
- isRequired={state.isRequired()}
333
- validationBehavior={validationBehavior()}
334
- validationState={state}
335
- focus={() => {
336
- fieldRef()?.querySelector<HTMLElement>('[role="spinbutton"]')?.focus();
337
- }}
338
- minValue={access(stateProps.minValue) as TimeValue | undefined}
339
- maxValue={access(stateProps.maxValue) as TimeValue | undefined}
340
- granularity={state.granularity}
341
- />
342
- </Show>
343
- </TimeFieldContext.Provider>
344
- </TimeFieldStateContext.Provider>
345
- );
346
- }
347
-
348
- /**
349
- * The input area containing time segments.
350
- */
351
- export function TimeInput(props: TimeInputProps): JSX.Element {
352
- const { state, aria } = useTimeFieldContextValue();
353
- const [isFocused, setIsFocused] = createSignal(false);
354
-
355
- const renderValues = createMemo<TimeInputRenderProps>(() => ({
356
- isDisabled: state.isDisabled(),
357
- isFocused: isFocused(),
358
- }));
359
-
360
- const renderProps = useRenderProps(
361
- {
362
- class: props.class,
363
- style: props.style,
364
- defaultClassName: "solidaria-TimeInput",
275
+ // The shared context read by the reused DateInput/DateSegment. Read through
276
+ // getters so consumers see the LIVE memo values (createDescription appends the
277
+ // value-description id via a deferred effect; a frozen snapshot would miss it).
278
+ const dateFieldContextValue: DateFieldContextValue = {
279
+ get state() {
280
+ return state as unknown as DateFieldContextValue["state"];
365
281
  },
366
- renderValues,
367
- );
368
-
369
- return (
370
- <div
371
- {...aria.inputProps}
372
- class={renderProps.class()}
373
- style={renderProps.style()}
374
- data-disabled={dataAttr(state.isDisabled())}
375
- data-focused={dataAttr(isFocused())}
376
- onFocusIn={() => setIsFocused(true)}
377
- onFocusOut={() => setIsFocused(false)}
378
- >
379
- <For each={state.segments()}>{(segment) => props.children?.(segment)}</For>
380
- </div>
381
- );
382
- }
383
-
384
- /**
385
- * A segment of a time field (hour, minute, second, AM/PM).
386
- */
387
- export function TimeSegment(props: TimeSegmentProps): JSX.Element {
388
- const state = useTimeFieldContext();
389
- const [segmentRef, setSegmentRef] = createSignal<HTMLDivElement | null>(null);
390
-
391
- const segmentAria = createTimeSegment(
392
- { segment: props.segment },
393
- state as unknown as TimeFieldState,
394
- segmentRef,
395
- );
396
-
397
- const renderValues = createMemo<TimeSegmentRenderProps>(() => ({
398
- isFocused: segmentAria.isFocused,
399
- isEditable: segmentAria.isEditable,
400
- isPlaceholder: segmentAria.isPlaceholder,
401
- type: props.segment.type,
402
- text: segmentAria.text,
403
- }));
404
-
405
- const renderProps = useRenderProps(
406
- {
407
- get children() {
408
- return props.children;
282
+ aria: {
283
+ get labelProps() {
284
+ return fieldAria.labelProps;
285
+ },
286
+ // The segment group props (role="group", aria-labelledby, unicode-bidi
287
+ // isolate, arrow-key nav, focus-within handlers) are routed to the
288
+ // DateInput element; the outer wrapper stays roleless.
289
+ get inputProps() {
290
+ return fieldAria.fieldProps;
291
+ },
292
+ // The native validation <input> props (type/hidden/required/onChange under
293
+ // native validation), rendered as the DateInput's sibling. Thread the
294
+ // validation-input ref so createTimeField's form-reset/validation wiring
295
+ // resolves to the mounted element.
296
+ get hiddenInputProps() {
297
+ return mergeProps(fieldAria.inputProps, { ref: setValidationInputRef });
298
+ },
299
+ get descriptionProps() {
300
+ return fieldAria.descriptionProps;
301
+ },
302
+ get errorMessageProps() {
303
+ return fieldAria.errorMessageProps;
409
304
  },
410
- class: props.class,
411
- style: props.style,
412
- defaultClassName: "solidaria-TimeSegment",
413
305
  },
414
- renderValues,
415
- );
416
-
417
- // Determine children content - avoid Show for SSR hydration compatibility
418
- const getChildren = () => {
419
- if (typeof props.children === "function") {
420
- return renderProps.renderChildren();
421
- }
422
- return segmentAria.text;
423
306
  };
424
307
 
425
308
  return (
426
- <div
427
- ref={setSegmentRef}
428
- {...segmentAria.segmentProps}
429
- class={renderProps.class()}
430
- style={renderProps.style()}
431
- data-focused={dataAttr(segmentAria.isFocused)}
432
- data-editable={dataAttr(segmentAria.isEditable)}
433
- data-placeholder={dataAttr(segmentAria.isPlaceholder)}
434
- data-type={props.segment.type}
435
- >
436
- {getChildren()}
437
- </div>
309
+ <TimeFieldStateContext.Provider value={state as unknown as TimeFieldState<TimeValue>}>
310
+ <DateFieldStateContext.Provider
311
+ value={state as unknown as DateFieldContextValue["state"]}
312
+ >
313
+ <DateFieldContext.Provider value={dateFieldContextValue}>
314
+ <TimeFieldContext.Provider
315
+ value={{
316
+ state: state as unknown as TimeFieldState<TimeValue>,
317
+ aria: {
318
+ get labelProps() {
319
+ return fieldAria.labelProps;
320
+ },
321
+ get inputProps() {
322
+ return fieldAria.fieldProps;
323
+ },
324
+ get descriptionProps() {
325
+ return fieldAria.descriptionProps;
326
+ },
327
+ get errorMessageProps() {
328
+ return fieldAria.errorMessageProps;
329
+ },
330
+ },
331
+ }}
332
+ >
333
+ <div
334
+ ref={setFieldRef}
335
+ class={renderProps.class()}
336
+ style={renderProps.style()}
337
+ data-disabled={dataAttr(state.isDisabled())}
338
+ data-readonly={dataAttr(state.isReadOnly())}
339
+ data-required={dataAttr(state.isRequired())}
340
+ data-invalid={dataAttr(state.isInvalid())}
341
+ >
342
+ <Provider values={[[TextContext, textSlots]] as Array<[Context<unknown>, unknown]>}>
343
+ {local.children as JSX.Element}
344
+ </Provider>
345
+ </div>
346
+ {/*
347
+ Unlike DateField, TimeField renders NO root hidden autofill input —
348
+ RAC TimeField renders none (react-aria-components TimeField.mjs). The
349
+ native-validation <input> is emitted by the inner DateInput sibling.
350
+ */}
351
+ </TimeFieldContext.Provider>
352
+ </DateFieldContext.Provider>
353
+ </DateFieldStateContext.Provider>
354
+ </TimeFieldStateContext.Provider>
438
355
  );
439
356
  }
440
357
 
@@ -460,9 +377,9 @@ export interface TimeFieldDescriptionProps {
460
377
  export function TimeFieldDescription(props: TimeFieldDescriptionProps): JSX.Element {
461
378
  const { aria } = useTimeFieldContextValue();
462
379
  return (
463
- <p {...aria.descriptionProps} class={props.class}>
380
+ <span {...aria.descriptionProps} class={props.class}>
464
381
  {props.children}
465
- </p>
382
+ </span>
466
383
  );
467
384
  }
468
385
 
@@ -474,9 +391,9 @@ export interface TimeFieldErrorMessageProps {
474
391
  export function TimeFieldErrorMessage(props: TimeFieldErrorMessageProps): JSX.Element {
475
392
  const { aria } = useTimeFieldContextValue();
476
393
  return (
477
- <p {...aria.errorMessageProps} class={props.class}>
394
+ <span {...aria.errorMessageProps} class={props.class}>
478
395
  {props.children}
479
- </p>
396
+ </span>
480
397
  );
481
398
  }
482
399
 
package/src/Tree.tsx CHANGED
@@ -40,6 +40,7 @@ import {
40
40
  type Key,
41
41
  type DropTarget,
42
42
  type ItemDropTarget,
43
+ type Collection,
43
44
  } from "@proyecto-viviana/solid-stately";
44
45
  import {
45
46
  type RenderChildren,
@@ -886,7 +887,13 @@ export function Tree<T extends object>(props: TreeProps<T>): JSX.Element {
886
887
  // Resolve writing direction for keyboard expand/collapse parity
887
888
  const treeDirection = createMemo(() => ariaProps.direction ?? resolveTreeDirection(ref()));
888
889
 
889
- const { treeProps } = createTree<T, TreeCollection<T>>(
890
+ // Keep the aria object (do NOT destructure `treeProps`): its `treeProps` getter
891
+ // wraps a memo carrying the reactive roving-container `tabIndex`, which rolls to
892
+ // -1 once a row takes focus. Destructuring here would read the getter once and
893
+ // freeze it at its first value (tabIndex 0), so the roll would never reach the
894
+ // DOM. Read `treeAria.treeProps` inside `cleanTreeProps` instead, so the spread's
895
+ // reactive re-run re-enters the memo and tracks `focusedKey`. (Mirrors GridList.)
896
+ const treeAria = createTree<T, TreeCollection<T>>(
890
897
  () => ({
891
898
  id: ariaProps.id,
892
899
  "aria-label": ariaProps["aria-label"],
@@ -926,7 +933,7 @@ export function Tree<T extends object>(props: TreeProps<T>): JSX.Element {
926
933
  });
927
934
 
928
935
  const cleanTreeProps = () => {
929
- const { ref: _ref1, ...rest } = treeProps as Record<string, unknown>;
936
+ const { ref: _ref1, ...rest } = treeAria.treeProps as Record<string, unknown>;
930
937
  return rest;
931
938
  };
932
939
  const cleanFocusProps = () => {
@@ -1054,8 +1061,11 @@ export function Tree<T extends object>(props: TreeProps<T>): JSX.Element {
1054
1061
  getKeyPageBelow: (key) => state.collection.getKeyAfter(key),
1055
1062
  getKeyPageAbove: (key) => state.collection.getKeyBefore(key),
1056
1063
  },
1064
+ // TreeCollection carries a wider node.type union than the narrow
1065
+ // Collection option but is structurally a valid Collection for
1066
+ // navigate()/focus restoration — cast at the seam.
1057
1067
  get collection() {
1058
- return state.collection;
1068
+ return state.collection as unknown as Collection;
1059
1069
  },
1060
1070
  get selectedKeys() {
1061
1071
  return state.selectedKeys;
@@ -1769,7 +1779,7 @@ export function TreeSelectionCheckbox(props: {
1769
1779
  {...treeSelectionCheckboxAria.checkboxProps}
1770
1780
  class={props.class ?? "solidaria-Tree-checkbox"}
1771
1781
  style={props.style}
1772
- tabIndex={props.excludeFromTabOrder ? -1 : undefined}
1782
+ tabIndex={props.excludeFromTabOrder ? -1 : 0}
1773
1783
  aria-label={props["aria-label"] ?? treeSelectionCheckboxAria.checkboxProps["aria-label"]}
1774
1784
  />
1775
1785
  );
package/src/index.ts CHANGED
@@ -372,6 +372,7 @@ export {
372
372
  BreadcrumbItem,
373
373
  BreadcrumbItem as Breadcrumb,
374
374
  BreadcrumbsContext,
375
+ BreadcrumbItemContext,
375
376
  type BreadcrumbsProps,
376
377
  type BreadcrumbsRenderProps,
377
378
  type BreadcrumbItemProps,
@@ -681,17 +682,11 @@ export {
681
682
  TimeFieldLabel,
682
683
  TimeFieldDescription,
683
684
  TimeFieldErrorMessage,
684
- TimeInput,
685
- TimeSegment,
686
685
  TimeFieldContext,
687
686
  TimeFieldStateContext,
688
687
  useTimeFieldContext,
689
688
  type TimeFieldProps,
690
689
  type TimeFieldRenderProps,
691
- type TimeInputProps,
692
- type TimeInputRenderProps,
693
- type TimeSegmentProps,
694
- type TimeSegmentRenderProps,
695
690
  type TimeFieldLabelProps,
696
691
  type TimeFieldDescriptionProps,
697
692
  type TimeFieldErrorMessageProps,
@@ -701,8 +696,6 @@ export {
701
696
  type TimeValue,
702
697
  } from "./TimeField";
703
698
 
704
- export { HiddenTimeInput, type HiddenTimeInputProps } from "./HiddenTimeInput";
705
-
706
699
  export {
707
700
  DatePicker,
708
701
  DateRangePicker,
@@ -101,14 +101,6 @@ export interface DragAndDrop<T = object> {
101
101
 
102
102
  export interface DragAndDropOptions<T = object>
103
103
  extends Partial<Omit<DraggableCollectionProps<T>, "preview">>, Partial<DroppableCollectionProps> {
104
- /**
105
- * Optional keyboard delegate forwarded to the collection droppable hook.
106
- */
107
- keyboardDelegate?: DroppableCollectionOptions["keyboardDelegate"];
108
- /**
109
- * Optional keydown handler composed with collection droppable keyboard behavior.
110
- */
111
- onKeyDown?: DroppableCollectionOptions["onKeyDown"];
112
104
  /**
113
105
  * A function that returns the items being dragged.
114
106
  * If omitted, draggable hooks are not added.
@@ -261,8 +253,14 @@ export function useDragAndDrop<T = object>(options: DragAndDropOptions<T> = {}):
261
253
  () => ({
262
254
  ref,
263
255
  dropTargetDelegate: options.dropTargetDelegate ?? props.dropTargetDelegate,
264
- keyboardDelegate: options.keyboardDelegate ?? props.keyboardDelegate,
265
- onKeyDown: options.onKeyDown ?? props.onKeyDown,
256
+ keyboardDelegate: props.keyboardDelegate,
257
+ // Host collection + selection/focus setters, forwarded so keyboard
258
+ // drop-target navigation and post-drop focus restoration work.
259
+ collection: props.collection,
260
+ selectedKeys: props.selectedKeys,
261
+ setSelectedKeys: props.setSelectedKeys,
262
+ setFocusedKey: props.setFocusedKey,
263
+ onKeyDown: props.onKeyDown,
266
264
  acceptedDragTypes: normalizedAcceptedDragTypes,
267
265
  isDisabled: options.isDisabled ?? props.isDisabled,
268
266
  onDropActivate: (e) => {
package/src/utils.tsx CHANGED
@@ -428,9 +428,9 @@ export function removeDataAttributes<T extends Record<string, unknown>>(props: T
428
428
  */
429
429
  export function filterDOMProps<R extends object = Record<string, unknown>>(
430
430
  props: object,
431
- options: { global?: boolean } = {},
431
+ options: { global?: boolean; events?: boolean } = {},
432
432
  ): R {
433
- const { global = false } = options;
433
+ const { global = false, events = true } = options;
434
434
  const result: Record<string, unknown> = {};
435
435
 
436
436
  const globalAttrs = new Set([
@@ -459,7 +459,7 @@ export function filterDOMProps<R extends object = Record<string, unknown>>(
459
459
  ((global && globalAttrs.has(key)) ||
460
460
  ariaAttrs.test(key) ||
461
461
  dataAttrs.test(key) ||
462
- eventHandlers.test(key))
462
+ (events && eventHandlers.test(key)))
463
463
  ) {
464
464
  result[key] = (props as Record<string, unknown>)[key];
465
465
  }