@proyecto-viviana/solidaria-components 0.2.9 → 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.
Files changed (222) hide show
  1. package/README.md +39 -272
  2. package/dist/ActionBar.d.ts +21 -13
  3. package/dist/ActionBar.d.ts.map +1 -1
  4. package/dist/ActionGroup.d.ts +8 -8
  5. package/dist/ActionGroup.d.ts.map +1 -1
  6. package/dist/Alert.d.ts +5 -5
  7. package/dist/Alert.d.ts.map +1 -1
  8. package/dist/Autocomplete.d.ts +5 -5
  9. package/dist/Autocomplete.d.ts.map +1 -1
  10. package/dist/Breadcrumbs.d.ts +18 -7
  11. package/dist/Breadcrumbs.d.ts.map +1 -1
  12. package/dist/Button.d.ts +24 -5
  13. package/dist/Button.d.ts.map +1 -1
  14. package/dist/Calendar.d.ts +38 -7
  15. package/dist/Calendar.d.ts.map +1 -1
  16. package/dist/Checkbox.d.ts +32 -7
  17. package/dist/Checkbox.d.ts.map +1 -1
  18. package/dist/Collection.d.ts +19 -14
  19. package/dist/Collection.d.ts.map +1 -1
  20. package/dist/Color.d.ts +103 -14
  21. package/dist/Color.d.ts.map +1 -1
  22. package/dist/ColorEditor.d.ts +6 -6
  23. package/dist/ColorEditor.d.ts.map +1 -1
  24. package/dist/ComboBox.d.ts +85 -19
  25. package/dist/ComboBox.d.ts.map +1 -1
  26. package/dist/ContextualHelpTrigger.d.ts +2 -2
  27. package/dist/ContextualHelpTrigger.d.ts.map +1 -1
  28. package/dist/DateField.d.ts +8 -6
  29. package/dist/DateField.d.ts.map +1 -1
  30. package/dist/DatePicker.d.ts +53 -22
  31. package/dist/DatePicker.d.ts.map +1 -1
  32. package/dist/DateRangePickerContext.d.ts +30 -0
  33. package/dist/DateRangePickerContext.d.ts.map +1 -0
  34. package/dist/Dialog.d.ts +5 -5
  35. package/dist/Dialog.d.ts.map +1 -1
  36. package/dist/Disclosure.d.ts +23 -5
  37. package/dist/Disclosure.d.ts.map +1 -1
  38. package/dist/DragAndDrop.d.ts +6 -6
  39. package/dist/DragAndDrop.d.ts.map +1 -1
  40. package/dist/DragPreview.d.ts +2 -2
  41. package/dist/DragPreview.d.ts.map +1 -1
  42. package/dist/DropZone.d.ts +4 -4
  43. package/dist/DropZone.d.ts.map +1 -1
  44. package/dist/FieldError.d.ts +9 -5
  45. package/dist/FieldError.d.ts.map +1 -1
  46. package/dist/FileTrigger.d.ts +3 -3
  47. package/dist/FileTrigger.d.ts.map +1 -1
  48. package/dist/Focusable.d.ts +2 -2
  49. package/dist/Focusable.d.ts.map +1 -1
  50. package/dist/Form.d.ts +18 -4
  51. package/dist/Form.d.ts.map +1 -1
  52. package/dist/GridList.d.ts +32 -12
  53. package/dist/GridList.d.ts.map +1 -1
  54. package/dist/HiddenDateInput.d.ts +26 -0
  55. package/dist/HiddenDateInput.d.ts.map +1 -0
  56. package/dist/HiddenTimeInput.d.ts +25 -0
  57. package/dist/HiddenTimeInput.d.ts.map +1 -0
  58. package/dist/Icon.d.ts +5 -5
  59. package/dist/Icon.d.ts.map +1 -1
  60. package/dist/Keyboard.d.ts +1 -1
  61. package/dist/Landmark.d.ts +3 -3
  62. package/dist/Landmark.d.ts.map +1 -1
  63. package/dist/Link.d.ts +10 -4
  64. package/dist/Link.d.ts.map +1 -1
  65. package/dist/ListBox.d.ts +32 -12
  66. package/dist/ListBox.d.ts.map +1 -1
  67. package/dist/ListDropTargetDelegate.d.ts +6 -6
  68. package/dist/ListDropTargetDelegate.d.ts.map +1 -1
  69. package/dist/Menu.d.ts +65 -14
  70. package/dist/Menu.d.ts.map +1 -1
  71. package/dist/Meter.d.ts +3 -3
  72. package/dist/Meter.d.ts.map +1 -1
  73. package/dist/Modal.d.ts +5 -5
  74. package/dist/Modal.d.ts.map +1 -1
  75. package/dist/NumberField.d.ts +8 -12
  76. package/dist/NumberField.d.ts.map +1 -1
  77. package/dist/Popover.d.ts +28 -5
  78. package/dist/Popover.d.ts.map +1 -1
  79. package/dist/Pressable.d.ts +2 -2
  80. package/dist/Pressable.d.ts.map +1 -1
  81. package/dist/ProgressBar.d.ts +5 -3
  82. package/dist/ProgressBar.d.ts.map +1 -1
  83. package/dist/RadioGroup.d.ts +43 -9
  84. package/dist/RadioGroup.d.ts.map +1 -1
  85. package/dist/RangeCalendar.d.ts +34 -7
  86. package/dist/RangeCalendar.d.ts.map +1 -1
  87. package/dist/RouterProvider.d.ts +2 -2
  88. package/dist/RouterProvider.d.ts.map +1 -1
  89. package/dist/SearchField.d.ts +23 -20
  90. package/dist/SearchField.d.ts.map +1 -1
  91. package/dist/Select.d.ts +41 -11
  92. package/dist/Select.d.ts.map +1 -1
  93. package/dist/SelectionIndicator.d.ts +3 -3
  94. package/dist/SelectionIndicator.d.ts.map +1 -1
  95. package/dist/Separator.d.ts +9 -3
  96. package/dist/Separator.d.ts.map +1 -1
  97. package/dist/SharedElementTransition.d.ts +6 -4
  98. package/dist/SharedElementTransition.d.ts.map +1 -1
  99. package/dist/Slider.d.ts +12 -8
  100. package/dist/Slider.d.ts.map +1 -1
  101. package/dist/StepList.d.ts +90 -0
  102. package/dist/StepList.d.ts.map +1 -0
  103. package/dist/Switch.d.ts +11 -5
  104. package/dist/Switch.d.ts.map +1 -1
  105. package/dist/Table.d.ts +187 -23
  106. package/dist/Table.d.ts.map +1 -1
  107. package/dist/Tabs.d.ts +45 -9
  108. package/dist/Tabs.d.ts.map +1 -1
  109. package/dist/TagGroup.d.ts +12 -10
  110. package/dist/TagGroup.d.ts.map +1 -1
  111. package/dist/Text.d.ts +2 -2
  112. package/dist/TextField.d.ts +15 -11
  113. package/dist/TextField.d.ts.map +1 -1
  114. package/dist/TimeField.d.ts +6 -6
  115. package/dist/TimeField.d.ts.map +1 -1
  116. package/dist/Toast.d.ts +29 -14
  117. package/dist/Toast.d.ts.map +1 -1
  118. package/dist/ToggleButton.d.ts +11 -5
  119. package/dist/ToggleButton.d.ts.map +1 -1
  120. package/dist/ToggleButtonGroup.d.ts +7 -7
  121. package/dist/ToggleButtonGroup.d.ts.map +1 -1
  122. package/dist/Toolbar.d.ts +7 -3
  123. package/dist/Toolbar.d.ts.map +1 -1
  124. package/dist/Tooltip.d.ts +50 -8
  125. package/dist/Tooltip.d.ts.map +1 -1
  126. package/dist/Tree.d.ts +66 -17
  127. package/dist/Tree.d.ts.map +1 -1
  128. package/dist/Virtualizer.d.ts +12 -12
  129. package/dist/Virtualizer.d.ts.map +1 -1
  130. package/dist/VirtualizerLayouts.d.ts +2 -2
  131. package/dist/VirtualizerLayouts.d.ts.map +1 -1
  132. package/dist/VisuallyHidden.d.ts +1 -1
  133. package/dist/VisuallyHidden.d.ts.map +1 -1
  134. package/dist/contexts.d.ts +5 -1
  135. package/dist/contexts.d.ts.map +1 -1
  136. package/dist/index.d.ts +73 -71
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +23247 -18564
  139. package/dist/index.js.map +1 -1
  140. package/dist/index.jsx +18110 -0
  141. package/dist/index.jsx.map +1 -0
  142. package/dist/useDragAndDrop.d.ts +13 -13
  143. package/dist/useDragAndDrop.d.ts.map +1 -1
  144. package/dist/utils.d.ts +2 -2
  145. package/dist/utils.d.ts.map +1 -1
  146. package/dist/virtualizer/Layout.d.ts +1 -1
  147. package/dist/virtualizer/Layout.d.ts.map +1 -1
  148. package/package.json +31 -32
  149. package/src/ActionBar.tsx +75 -72
  150. package/src/ActionGroup.tsx +53 -61
  151. package/src/Alert.tsx +17 -42
  152. package/src/Autocomplete.tsx +39 -44
  153. package/src/Breadcrumbs.tsx +149 -80
  154. package/src/Button.tsx +267 -70
  155. package/src/Calendar.tsx +218 -138
  156. package/src/Checkbox.tsx +413 -121
  157. package/src/Collection.tsx +67 -58
  158. package/src/Color.tsx +803 -380
  159. package/src/ColorEditor.tsx +131 -149
  160. package/src/ComboBox.tsx +414 -249
  161. package/src/ContextualHelpTrigger.tsx +86 -74
  162. package/src/DateField.tsx +185 -91
  163. package/src/DatePicker.tsx +524 -213
  164. package/src/DateRangePickerContext.tsx +44 -0
  165. package/src/Dialog.tsx +156 -118
  166. package/src/Disclosure.tsx +127 -80
  167. package/src/DragAndDrop.tsx +60 -54
  168. package/src/DragPreview.tsx +13 -11
  169. package/src/DropZone.tsx +42 -22
  170. package/src/FieldError.tsx +45 -23
  171. package/src/FileTrigger.tsx +19 -19
  172. package/src/Focusable.tsx +21 -24
  173. package/src/Form.tsx +71 -16
  174. package/src/GridList.tsx +273 -197
  175. package/src/HiddenDateInput.tsx +153 -0
  176. package/src/HiddenTimeInput.tsx +133 -0
  177. package/src/Icon.tsx +22 -43
  178. package/src/Keyboard.tsx +3 -3
  179. package/src/Landmark.tsx +37 -63
  180. package/src/Link.tsx +125 -75
  181. package/src/ListBox.tsx +332 -233
  182. package/src/ListDropTargetDelegate.ts +81 -80
  183. package/src/Menu.tsx +1023 -274
  184. package/src/Meter.tsx +38 -56
  185. package/src/Modal.tsx +243 -175
  186. package/src/NumberField.tsx +139 -143
  187. package/src/Popover.tsx +386 -233
  188. package/src/Pressable.tsx +21 -21
  189. package/src/ProgressBar.tsx +48 -57
  190. package/src/RadioGroup.tsx +524 -122
  191. package/src/RangeCalendar.tsx +157 -90
  192. package/src/RouterProvider.tsx +30 -47
  193. package/src/SearchField.tsx +362 -143
  194. package/src/Select.tsx +656 -233
  195. package/src/SelectionIndicator.tsx +18 -15
  196. package/src/Separator.tsx +47 -49
  197. package/src/SharedElementTransition.tsx +103 -97
  198. package/src/Slider.tsx +138 -98
  199. package/src/StepList.tsx +272 -0
  200. package/src/Switch.tsx +93 -46
  201. package/src/Table.tsx +1308 -342
  202. package/src/Tabs.tsx +324 -103
  203. package/src/TagGroup.tsx +139 -126
  204. package/src/Text.tsx +3 -3
  205. package/src/TextField.tsx +389 -79
  206. package/src/TimeField.tsx +136 -76
  207. package/src/Toast.tsx +209 -157
  208. package/src/ToggleButton.tsx +47 -37
  209. package/src/ToggleButtonGroup.tsx +39 -34
  210. package/src/Toolbar.tsx +54 -69
  211. package/src/Tooltip.tsx +387 -119
  212. package/src/Tree.tsx +651 -368
  213. package/src/Virtualizer.tsx +208 -180
  214. package/src/VirtualizerLayouts.ts +45 -30
  215. package/src/VisuallyHidden.tsx +19 -19
  216. package/src/contexts.ts +29 -37
  217. package/src/index.ts +110 -195
  218. package/src/useDragAndDrop.ts +87 -71
  219. package/src/utils.tsx +40 -55
  220. package/src/virtualizer/Layout.ts +14 -22
  221. package/dist/index.ssr.js +0 -16996
  222. package/dist/index.ssr.js.map +0 -1
@@ -4,28 +4,22 @@
4
4
  * Compatibility target: react-aria-components DragAndDrop exports.
5
5
  */
6
6
 
7
- import {
8
- type JSX,
9
- type Accessor,
10
- createContext,
11
- createMemo,
12
- useContext,
13
- } from 'solid-js';
7
+ import { type JSX, type Accessor, createContext, createMemo, useContext } from "solid-js";
14
8
  import type {
15
9
  DragTypes,
16
10
  DropOperation,
17
11
  DropTarget,
18
12
  ItemDropTarget,
19
13
  Key,
20
- } from '@proyecto-viviana/solid-stately';
21
- import type { DragAndDropHooks } from './useDragAndDrop';
14
+ } from "@proyecto-viviana/solid-stately";
15
+ import type { DragAndDropHooks } from "./useDragAndDrop";
22
16
  import {
23
17
  type ClassNameOrFunction,
24
18
  type StyleOrFunction,
25
19
  type SlotProps,
26
20
  useRenderProps,
27
21
  dataAttr,
28
- } from './utils';
22
+ } from "./utils";
29
23
 
30
24
  export interface DragAndDropContextValue {
31
25
  dragAndDropHooks?: DragAndDropHooks<unknown>;
@@ -67,11 +61,11 @@ function DefaultDropIndicator(props: DropIndicatorProps): JSX.Element {
67
61
  children: props.children,
68
62
  class: props.class,
69
63
  style: props.style,
70
- defaultClassName: 'solidaria-DropIndicator',
64
+ defaultClassName: "solidaria-DropIndicator",
71
65
  },
72
66
  () => ({
73
67
  isDropTarget: isDropTarget(),
74
- })
68
+ }),
75
69
  );
76
70
 
77
71
  return (
@@ -95,32 +89,34 @@ export function DropIndicator(props: DropIndicatorProps): JSX.Element {
95
89
 
96
90
  export function useRenderDropIndicator(
97
91
  hooksOrDropState?:
98
- | Pick<DragAndDropHooks<unknown>, 'renderDropIndicator' | 'isVirtualDragging' | 'useDropIndicator'>
92
+ | Pick<
93
+ DragAndDropHooks<unknown>,
94
+ "renderDropIndicator" | "isVirtualDragging" | "useDropIndicator"
95
+ >
99
96
  | {
100
- target?: DropTarget | null;
101
- isDropTarget?: ((target: DropTarget) => boolean) | boolean;
102
- },
97
+ target?: DropTarget | null;
98
+ isDropTarget?: ((target: DropTarget) => boolean) | boolean;
99
+ },
103
100
  maybeDropState?: {
104
101
  target?: DropTarget | null;
105
102
  isDropTarget?: ((target: DropTarget) => boolean) | boolean;
106
- }
103
+ },
107
104
  ): ((target: ItemDropTarget) => JSX.Element | undefined) | undefined {
108
105
  const looksLikeDropState = (
109
- value: unknown
106
+ value: unknown,
110
107
  ): value is {
111
108
  target?: DropTarget | null;
112
109
  isDropTarget?: ((target: DropTarget) => boolean) | boolean;
113
110
  } => {
114
111
  return Boolean(
115
112
  value &&
116
- typeof value === 'object' &&
117
- ('isDropTarget' in (value as Record<string, unknown>) || 'target' in (value as Record<string, unknown>))
113
+ typeof value === "object" &&
114
+ ("isDropTarget" in (value as Record<string, unknown>) ||
115
+ "target" in (value as Record<string, unknown>)),
118
116
  );
119
117
  };
120
118
 
121
- const dragAndDropHooks = looksLikeDropState(hooksOrDropState)
122
- ? undefined
123
- : hooksOrDropState;
119
+ const dragAndDropHooks = looksLikeDropState(hooksOrDropState) ? undefined : hooksOrDropState;
124
120
  const dropState = looksLikeDropState(hooksOrDropState) ? hooksOrDropState : maybeDropState;
125
121
 
126
122
  // RAC only renders collection indicators when drop hooks are present.
@@ -130,23 +126,26 @@ export function useRenderDropIndicator(
130
126
  const targetsEqual = (a: DropTarget | null | undefined, b: DropTarget): boolean => {
131
127
  if (!a) return false;
132
128
  if (a.type !== b.type) return false;
133
- if (a.type === 'root' && b.type === 'root') return true;
134
- if (a.type !== 'item' || b.type !== 'item') return false;
129
+ if (a.type === "root" && b.type === "root") return true;
130
+ if (a.type !== "item" || b.type !== "item") return false;
135
131
  return a.key === b.key && a.dropPosition === b.dropPosition;
136
132
  };
137
133
 
138
134
  return (target: ItemDropTarget) => {
139
135
  const stateIsDropTarget = dropState?.isDropTarget;
140
- const isTarget = typeof stateIsDropTarget === 'function'
141
- ? stateIsDropTarget(target)
142
- : stateIsDropTarget === true
143
- ? targetsEqual(dropState?.target, target)
144
- : false;
136
+ const isTarget =
137
+ typeof stateIsDropTarget === "function"
138
+ ? stateIsDropTarget(target)
139
+ : stateIsDropTarget === true
140
+ ? targetsEqual(dropState?.target, target)
141
+ : false;
145
142
  const isVirtualDragging = dragAndDropHooks?.isVirtualDragging?.() ?? false;
146
143
  if (!isTarget && !isVirtualDragging) return undefined;
147
- return dragAndDropHooks?.renderDropIndicator
148
- ? dragAndDropHooks.renderDropIndicator(target)
149
- : <DropIndicator target={target} />;
144
+ return dragAndDropHooks?.renderDropIndicator ? (
145
+ dragAndDropHooks.renderDropIndicator(target)
146
+ ) : (
147
+ <DropIndicator target={target} />
148
+ );
150
149
  };
151
150
  }
152
151
 
@@ -177,17 +176,14 @@ export interface LayoutInfoProviderLike {
177
176
  }
178
177
 
179
178
  function resolveKey(value: KeyAccessor): Key | null | undefined {
180
- if (typeof value === 'function') {
179
+ if (typeof value === "function") {
181
180
  return (value as Accessor<Key | null | undefined>)();
182
181
  }
183
182
  return value;
184
183
  }
185
184
 
186
- function getAfterDropNormalizedKey(
187
- target: ItemDropTarget,
188
- collection?: CollectionLike
189
- ): Key {
190
- if (target.dropPosition !== 'after' || !collection) return target.key;
185
+ function getAfterDropNormalizedKey(target: ItemDropTarget, collection?: CollectionLike): Key {
186
+ if (target.dropPosition !== "after" || !collection) return target.key;
191
187
 
192
188
  let nextKey = collection.getKeyAfter(target.key);
193
189
  let lastDescendantKey: Key | null = null;
@@ -197,7 +193,7 @@ function getAfterDropNormalizedKey(
197
193
  while (nextKey != null) {
198
194
  const node = collection.getItem(nextKey);
199
195
  if (!node) break;
200
- if (node.type && node.type !== 'item') {
196
+ if (node.type && node.type !== "item") {
201
197
  nextKey = collection.getKeyAfter(nextKey);
202
198
  continue;
203
199
  }
@@ -212,23 +208,23 @@ function getAfterDropNormalizedKey(
212
208
 
213
209
  export function getNormalizedDropTargetKey(
214
210
  target: DropTarget | null | undefined,
215
- collection?: CollectionLike
211
+ collection?: CollectionLike,
216
212
  ): Key | null {
217
- if (!target || target.type !== 'item') return null;
213
+ if (!target || target.type !== "item") return null;
218
214
  return getAfterDropNormalizedKey(target, collection);
219
215
  }
220
216
 
221
217
  export function useDndPersistedKeys(
222
218
  selectionManager: SelectionManagerLike | null | undefined,
223
- dragAndDropHooks?: Pick<DragAndDropHooks<unknown>, 'isVirtualDragging'>,
219
+ dragAndDropHooks?: Pick<DragAndDropHooks<unknown>, "isVirtualDragging">,
224
220
  dropState?: DroppableCollectionStateLike,
225
- collection?: CollectionLike
221
+ collection?: CollectionLike,
226
222
  ): Accessor<Set<Key>> {
227
223
  return createMemo(() => {
228
224
  const focusedKey = resolveKey(selectionManager?.focusedKey);
229
225
  let dropTargetKey: Key | null | undefined;
230
226
 
231
- if (dragAndDropHooks?.isVirtualDragging?.() && dropState?.target?.type === 'item') {
227
+ if (dragAndDropHooks?.isVirtualDragging?.() && dropState?.target?.type === "item") {
232
228
  dropTargetKey = getNormalizedDropTargetKey(dropState.target, collection) ?? undefined;
233
229
  }
234
230
 
@@ -249,13 +245,15 @@ export function mergePersistedKeysIntoVirtualRange(
249
245
  forceIncludeIndexes?: number[];
250
246
  forceIncludeMaxSpan?: number;
251
247
  fallbackToForcedWindow?: boolean;
252
- }
248
+ },
253
249
  ): VirtualRangeLike {
254
250
  const validPersistedIndexes = Array.from(
255
- new Set(persistedIndexes.filter((index) => index >= 0 && index < itemCount))
251
+ new Set(persistedIndexes.filter((index) => index >= 0 && index < itemCount)),
256
252
  ).sort((a, b) => a - b);
257
253
  const forceIndexes = Array.from(
258
- new Set((options?.forceIncludeIndexes ?? []).filter((index) => index >= 0 && index < itemCount))
254
+ new Set(
255
+ (options?.forceIncludeIndexes ?? []).filter((index) => index >= 0 && index < itemCount),
256
+ ),
259
257
  );
260
258
 
261
259
  if (itemCount <= 0) return baseRange;
@@ -273,7 +271,9 @@ export function mergePersistedKeysIntoVirtualRange(
273
271
  return 0;
274
272
  };
275
273
 
276
- for (const index of validPersistedIndexes.sort((a, b) => distanceToBaseRange(a) - distanceToBaseRange(b))) {
274
+ for (const index of validPersistedIndexes.sort(
275
+ (a, b) => distanceToBaseRange(a) - distanceToBaseRange(b),
276
+ )) {
277
277
  const nextStart = Math.min(start, index);
278
278
  const nextEnd = Math.max(end, index + 1);
279
279
  if (nextEnd - nextStart <= maxSpan) {
@@ -297,9 +297,15 @@ export function mergePersistedKeysIntoVirtualRange(
297
297
  const missingForced = forceIndexes.filter((index) => index < start || index >= end);
298
298
  if (missingForced.length > 0) {
299
299
  const nearestForced = missingForced[0];
300
- const forceMaxSpan = Math.max(maxSpan, options?.forceIncludeMaxSpan ?? Math.max(maxSpan, 300));
300
+ const forceMaxSpan = Math.max(
301
+ maxSpan,
302
+ options?.forceIncludeMaxSpan ?? Math.max(maxSpan, 300),
303
+ );
301
304
  const windowSpan = Math.min(itemCount, Math.max(baseSpan, forceMaxSpan));
302
- const centeredStart = Math.max(0, Math.min(itemCount - windowSpan, nearestForced - Math.floor(windowSpan / 2)));
305
+ const centeredStart = Math.max(
306
+ 0,
307
+ Math.min(itemCount - windowSpan, nearestForced - Math.floor(windowSpan / 2)),
308
+ );
303
309
  start = centeredStart;
304
310
  end = Math.min(itemCount, centeredStart + windowSpan);
305
311
  }
@@ -316,7 +322,7 @@ export function mergePersistedKeysIntoVirtualRange(
316
322
  start,
317
323
  end,
318
324
  offsetTop: Math.max(0, startRect.y),
319
- offsetBottom: Math.max(0, (lastRect.y + lastRect.height) - (endRect.y + endRect.height)),
325
+ offsetBottom: Math.max(0, lastRect.y + lastRect.height - (endRect.y + endRect.height)),
320
326
  };
321
327
  }
322
328
 
@@ -324,11 +330,11 @@ export type DropTargetDelegate = {
324
330
  getDropTargetFromPoint: (
325
331
  x: number,
326
332
  y: number,
327
- isValidDropTarget: (target: DropTarget) => boolean
333
+ isValidDropTarget: (target: DropTarget) => boolean,
328
334
  ) => DropTarget | null;
329
335
  getDropOperation: (
330
336
  target: DropTarget,
331
337
  types: DragTypes,
332
- allowedOperations: DropOperation[]
338
+ allowedOperations: DropOperation[],
333
339
  ) => DropOperation;
334
340
  };
@@ -1,17 +1,19 @@
1
- import { onCleanup, type JSX } from 'solid-js';
2
- import type { DragItem, DragPreviewRenderer } from '@proyecto-viviana/solid-stately';
1
+ import { onCleanup, type JSX } from "solid-js";
2
+ import type { DragItem, DragPreviewRenderer } from "@proyecto-viviana/solid-stately";
3
3
 
4
4
  export interface DragPreviewProps {
5
5
  ref?: { current: DragPreviewRenderer | null };
6
- children: (items: DragItem[]) => JSX.Element | { element: JSX.Element; x?: number; y?: number } | null | undefined;
6
+ children: (
7
+ items: DragItem[],
8
+ ) => JSX.Element | { element: JSX.Element; x?: number; y?: number } | null | undefined;
7
9
  }
8
10
 
9
11
  export function DragPreview(props: DragPreviewProps): JSX.Element {
10
- const hasDom = typeof HTMLElement !== 'undefined';
12
+ const hasDom = typeof HTMLElement !== "undefined";
11
13
  const isElementNode = (value: unknown): value is HTMLElement => {
12
14
  if (!value) return false;
13
15
  if (hasDom && value instanceof HTMLElement) return true;
14
- return typeof value === 'object' && (value as { nodeType?: number }).nodeType === 1;
16
+ return typeof value === "object" && (value as { nodeType?: number }).nodeType === 1;
15
17
  };
16
18
 
17
19
  if (props.ref) {
@@ -21,13 +23,13 @@ export function DragPreview(props: DragPreviewProps): JSX.Element {
21
23
  callback(null);
22
24
  return;
23
25
  }
24
- if (
25
- typeof rendered === 'object' &&
26
- rendered !== null &&
27
- 'element' in rendered
28
- ) {
26
+ if (typeof rendered === "object" && rendered !== null && "element" in rendered) {
29
27
  const previewValue = rendered as { element: unknown; x?: number; y?: number };
30
- callback(isElementNode(previewValue.element) ? previewValue.element : null, previewValue.x, previewValue.y);
28
+ callback(
29
+ isElementNode(previewValue.element) ? previewValue.element : null,
30
+ previewValue.x,
31
+ previewValue.y,
32
+ );
31
33
  return;
32
34
  }
33
35
  callback(isElementNode(rendered) ? rendered : null);
package/src/DropZone.tsx CHANGED
@@ -5,7 +5,15 @@
5
5
  * Parity target: react-aria-components/src/DropZone.tsx
6
6
  */
7
7
 
8
- import { type JSX, createContext, createMemo, createSignal, splitProps } from 'solid-js';
8
+ import {
9
+ type JSX,
10
+ createContext,
11
+ createMemo,
12
+ createSignal,
13
+ mergeProps,
14
+ splitProps,
15
+ useContext,
16
+ } from "solid-js";
9
17
  import {
10
18
  createDrop,
11
19
  createFocusRing,
@@ -13,7 +21,7 @@ import {
13
21
  readFromDataTransfer,
14
22
  type HoverEvents,
15
23
  type AriaDropOptions,
16
- } from '@proyecto-viviana/solidaria';
24
+ } from "@proyecto-viviana/solidaria";
17
25
  import {
18
26
  type ClassNameOrFunction,
19
27
  type StyleOrFunction,
@@ -21,8 +29,8 @@ import {
21
29
  type SlotProps,
22
30
  useRenderProps,
23
31
  filterDOMProps,
24
- } from './utils';
25
- import { VisuallyHidden } from './VisuallyHidden';
32
+ } from "./utils";
33
+ import { VisuallyHidden } from "./VisuallyHidden";
26
34
 
27
35
  export interface DropZoneRenderProps {
28
36
  isHovered: boolean;
@@ -33,8 +41,9 @@ export interface DropZoneRenderProps {
33
41
  }
34
42
 
35
43
  export interface DropZoneProps
36
- extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children' | 'class' | 'style' | 'onDrop'>,
37
- Omit<AriaDropOptions, 'hasDropButton'>,
44
+ extends
45
+ Omit<JSX.HTMLAttributes<HTMLDivElement>, "children" | "class" | "style" | "onDrop">,
46
+ Omit<AriaDropOptions, "hasDropButton">,
38
47
  HoverEvents,
39
48
  SlotProps {
40
49
  children?: RenderChildren<DropZoneRenderProps>;
@@ -43,16 +52,16 @@ export interface DropZoneProps
43
52
  }
44
53
 
45
54
  export const DropZoneContext = createContext<DropZoneProps | null>(null);
46
- const DEFAULT_DROPZONE_LABEL = 'Drop files';
55
+ const DEFAULT_DROPZONE_LABEL = "Drop files";
47
56
  const FOCUSABLE_SELECTOR = [
48
- 'a[href]',
49
- 'button:not([disabled])',
57
+ "a[href]",
58
+ "button:not([disabled])",
50
59
  'input:not([disabled]):not([type="hidden"])',
51
- 'select:not([disabled])',
52
- 'textarea:not([disabled])',
60
+ "select:not([disabled])",
61
+ "textarea:not([disabled])",
53
62
  '[tabindex]:not([tabindex="-1"])',
54
63
  '[contenteditable="true"]',
55
- ].join(',');
64
+ ].join(",");
56
65
 
57
66
  function isFocusableElement(target: Element): boolean {
58
67
  return target instanceof HTMLElement && target.matches(FOCUSABLE_SELECTOR);
@@ -62,11 +71,22 @@ function isFocusableElement(target: Element): boolean {
62
71
  * A drop zone is an area into which one or multiple objects can be dropped.
63
72
  */
64
73
  export function DropZone(props: DropZoneProps): JSX.Element {
74
+ const contextProps = useContext(DropZoneContext);
75
+ const mergedProps = mergeProps(contextProps ?? {}, props);
65
76
  const [local, dropProps, hoverEventProps, domProps] = splitProps(
66
- props,
67
- ['children', 'class', 'style', 'slot', 'aria-label', 'aria-labelledby'],
68
- ['getDropOperation', 'getDropOperationForPoint', 'onDropEnter', 'onDropMove', 'onDropActivate', 'onDropExit', 'onDrop', 'isDisabled'],
69
- ['onHoverStart', 'onHoverEnd', 'onHoverChange']
77
+ mergedProps,
78
+ ["children", "class", "style", "slot", "aria-label", "aria-labelledby"],
79
+ [
80
+ "getDropOperation",
81
+ "getDropOperationForPoint",
82
+ "onDropEnter",
83
+ "onDropMove",
84
+ "onDropActivate",
85
+ "onDropExit",
86
+ "onDrop",
87
+ "isDisabled",
88
+ ],
89
+ ["onHoverStart", "onHoverEnd", "onHoverChange"],
70
90
  );
71
91
 
72
92
  const [dropZoneRef, setDropZoneRef] = createSignal<HTMLDivElement | null>(null);
@@ -105,9 +125,9 @@ export function DropZone(props: DropZoneProps): JSX.Element {
105
125
  children: local.children,
106
126
  class: local.class,
107
127
  style: local.style,
108
- defaultClassName: 'solidaria-DropZone',
128
+ defaultClassName: "solidaria-DropZone",
109
129
  },
110
- renderValues
130
+ renderValues,
111
131
  );
112
132
 
113
133
  const filteredDomProps = createMemo(() => filterDOMProps(domProps, { global: true }));
@@ -169,16 +189,16 @@ export function DropZone(props: DropZoneProps): JSX.Element {
169
189
 
170
190
  e.preventDefault();
171
191
  dropProps.onDrop?.({
172
- type: 'drop',
192
+ type: "drop",
173
193
  x: 0,
174
194
  y: 0,
175
195
  items,
176
- dropOperation: 'copy',
196
+ dropOperation: "copy",
177
197
  });
178
198
  };
179
199
 
180
200
  const dropButtonAriaLabel = createMemo(
181
- () => local['aria-label'] ?? (!local['aria-labelledby'] ? DEFAULT_DROPZONE_LABEL : undefined)
201
+ () => local["aria-label"] ?? (!local["aria-labelledby"] ? DEFAULT_DROPZONE_LABEL : undefined),
182
202
  );
183
203
 
184
204
  return (
@@ -203,7 +223,7 @@ export function DropZone(props: DropZoneProps): JSX.Element {
203
223
  {...cleanDropButtonProps()}
204
224
  {...cleanFocusProps()}
205
225
  aria-label={dropButtonAriaLabel()}
206
- aria-labelledby={local['aria-labelledby']}
226
+ aria-labelledby={local["aria-labelledby"]}
207
227
  onPaste={onHiddenButtonPaste}
208
228
  />
209
229
  </VisuallyHidden>
@@ -5,8 +5,8 @@
5
5
  * Port direction: react-aria-components/src/FieldError.tsx
6
6
  */
7
7
 
8
- import { type JSX, createContext, createMemo, splitProps, useContext } from 'solid-js';
9
- import type { ValidationResult } from '@proyecto-viviana/solid-stately';
8
+ import { type JSX, Show, createContext, createMemo, splitProps, useContext } from "solid-js";
9
+ import { DEFAULT_VALIDATION_RESULT, type ValidationResult } from "@proyecto-viviana/solid-stately";
10
10
  import {
11
11
  type ClassNameOrFunction,
12
12
  type StyleOrFunction,
@@ -14,13 +14,17 @@ import {
14
14
  type SlotProps,
15
15
  useRenderProps,
16
16
  filterDOMProps,
17
- } from './utils';
17
+ } from "./utils";
18
18
 
19
19
  export type FieldErrorRenderProps = ValidationResult;
20
20
 
21
+ export interface FieldErrorContextValue {
22
+ validation: ValidationResult | null;
23
+ errorMessageProps?: JSX.HTMLAttributes<HTMLElement>;
24
+ }
25
+
21
26
  export interface FieldErrorProps
22
- extends Omit<JSX.HTMLAttributes<HTMLElement>, 'children' | 'class' | 'style'>,
23
- SlotProps {
27
+ extends Omit<JSX.HTMLAttributes<HTMLElement>, "children" | "class" | "style">, SlotProps {
24
28
  /** Validation result. Falls back to context when omitted. */
25
29
  validation?: ValidationResult | null;
26
30
  /** The children of the component. */
@@ -31,37 +35,55 @@ export interface FieldErrorProps
31
35
  style?: StyleOrFunction<FieldErrorRenderProps>;
32
36
  }
33
37
 
34
- export const FieldErrorContext = createContext<ValidationResult | null>(null);
38
+ export const FieldErrorContext = createContext<ValidationResult | FieldErrorContextValue | null>(
39
+ null,
40
+ );
35
41
 
36
42
  export function FieldError(props: FieldErrorProps): JSX.Element | null {
37
- const contextValidation = useContext(FieldErrorContext);
38
- const [local, domProps] = splitProps(props, ['validation', 'children', 'class', 'style', 'slot']);
43
+ const contextValue = useContext(FieldErrorContext);
44
+ const contextValidation = () => {
45
+ if (contextValue && "validation" in contextValue) {
46
+ return contextValue.validation;
47
+ }
48
+ return contextValue;
49
+ };
50
+ const contextErrorMessageProps = () => {
51
+ if (contextValue && "validation" in contextValue) {
52
+ return contextValue.errorMessageProps ?? {};
53
+ }
54
+ return {};
55
+ };
56
+ const [local, domProps] = splitProps(props, ["validation", "children", "class", "style", "slot"]);
39
57
 
40
- const validation = createMemo<ValidationResult | null>(() => local.validation ?? contextValidation);
41
- if (!validation()?.isInvalid) return null;
58
+ const validation = createMemo<ValidationResult | null>(
59
+ () => local.validation ?? contextValidation(),
60
+ );
42
61
 
43
62
  const renderProps = useRenderProps(
44
63
  {
45
- children: local.children ?? validation()!.validationErrors.join(' '),
64
+ children:
65
+ local.children ?? ((currentValidation) => currentValidation.validationErrors.join(" ")),
46
66
  class: local.class,
47
67
  style: local.style,
48
- defaultClassName: 'solidaria-FieldError',
68
+ defaultClassName: "solidaria-FieldError",
49
69
  },
50
- () => validation()!
70
+ () => validation() ?? DEFAULT_VALIDATION_RESULT,
51
71
  );
52
72
 
53
- if (renderProps.renderChildren() == null) return null;
54
-
55
73
  const filteredDomProps = filterDOMProps(domProps, { global: true });
74
+ const children = () => renderProps.renderChildren();
56
75
 
57
76
  return (
58
- <div
59
- {...filteredDomProps}
60
- slot={local.slot ?? 'errorMessage'}
61
- class={renderProps.class()}
62
- style={renderProps.style()}
63
- >
64
- {renderProps.renderChildren()}
65
- </div>
77
+ <Show when={validation()?.isInvalid && children()}>
78
+ <div
79
+ {...(contextErrorMessageProps() as unknown as JSX.HTMLAttributes<HTMLDivElement>)}
80
+ {...(filteredDomProps as JSX.HTMLAttributes<HTMLDivElement>)}
81
+ slot={local.slot ?? "errorMessage"}
82
+ class={renderProps.class()}
83
+ style={renderProps.style()}
84
+ >
85
+ {children()}
86
+ </div>
87
+ </Show>
66
88
  );
67
89
  }
@@ -5,17 +5,19 @@
5
5
  * Parity target: react-aria-components/src/FileTrigger.tsx
6
6
  */
7
7
 
8
- import { type JSX, createSignal, splitProps } from 'solid-js';
9
- import { createPress, type PressEvent } from '@proyecto-viviana/solidaria';
8
+ import { type JSX, createSignal, splitProps } from "solid-js";
9
+ import { createPress, type PressEvent } from "@proyecto-viviana/solidaria";
10
10
 
11
- export interface FileTriggerProps
12
- extends Omit<JSX.InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange' | 'children' | 'onSelect'> {
11
+ export interface FileTriggerProps extends Omit<
12
+ JSX.InputHTMLAttributes<HTMLInputElement>,
13
+ "type" | "onChange" | "children" | "onSelect"
14
+ > {
13
15
  /** Mime types accepted by the file picker. */
14
16
  acceptedFileTypes?: ReadonlyArray<string>;
15
17
  /** Whether multiple files can be selected. */
16
18
  allowsMultiple?: boolean;
17
19
  /** Default camera capture mode for mobile devices. */
18
- defaultCamera?: 'user' | 'environment';
20
+ defaultCamera?: "user" | "environment";
19
21
  /** Enables directory selection in supported browsers. */
20
22
  acceptDirectory?: boolean;
21
23
  /** Called when user selection changes. */
@@ -29,13 +31,13 @@ export interface FileTriggerProps
29
31
  */
30
32
  export function FileTrigger(props: FileTriggerProps): JSX.Element {
31
33
  const [local, inputProps] = splitProps(props, [
32
- 'acceptedFileTypes',
33
- 'allowsMultiple',
34
- 'defaultCamera',
35
- 'acceptDirectory',
36
- 'onSelect',
37
- 'children',
38
- 'disabled',
34
+ "acceptedFileTypes",
35
+ "allowsMultiple",
36
+ "defaultCamera",
37
+ "acceptDirectory",
38
+ "onSelect",
39
+ "children",
40
+ "disabled",
39
41
  ]);
40
42
 
41
43
  const [inputRef, setInputRef] = createSignal<HTMLInputElement | null>(null);
@@ -43,7 +45,7 @@ export function FileTrigger(props: FileTriggerProps): JSX.Element {
43
45
  const openFilePicker = () => {
44
46
  const input = inputRef();
45
47
  if (!input) return;
46
- if (input.value) input.value = '';
48
+ if (input.value) input.value = "";
47
49
  input.click();
48
50
  };
49
51
 
@@ -62,20 +64,18 @@ export function FileTrigger(props: FileTriggerProps): JSX.Element {
62
64
 
63
65
  return (
64
66
  <>
65
- <span {...pressProps}>
66
- {local.children}
67
- </span>
67
+ <span {...pressProps}>{local.children}</span>
68
68
  <input
69
69
  {...inputProps}
70
70
  ref={setInputRef}
71
71
  type="file"
72
- style={{ display: 'none' }}
73
- accept={local.acceptedFileTypes?.join(',')}
72
+ style={{ display: "none" }}
73
+ accept={local.acceptedFileTypes?.join(",")}
74
74
  multiple={local.allowsMultiple}
75
75
  capture={local.defaultCamera}
76
76
  disabled={local.disabled}
77
77
  // @ts-expect-error Non-standard attribute supported by WebKit browsers.
78
- webkitdirectory={local.acceptDirectory ? '' : undefined}
78
+ webkitdirectory={local.acceptDirectory ? "" : undefined}
79
79
  onChange={onInputChange}
80
80
  />
81
81
  </>