@proyecto-viviana/solidaria 0.2.4 → 0.2.8

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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/dist/actiongroup/createActionGroup.d.ts +29 -0
  3. package/dist/actiongroup/createActionGroup.d.ts.map +1 -0
  4. package/dist/actiongroup/index.d.ts +2 -0
  5. package/dist/actiongroup/index.d.ts.map +1 -0
  6. package/dist/autocomplete/createAutocomplete.d.ts +6 -2
  7. package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
  8. package/dist/breadcrumbs/createBreadcrumbs.d.ts +2 -0
  9. package/dist/breadcrumbs/createBreadcrumbs.d.ts.map +1 -1
  10. package/dist/button/createToggleButtonGroup.d.ts +32 -0
  11. package/dist/button/createToggleButtonGroup.d.ts.map +1 -0
  12. package/dist/button/index.d.ts +2 -0
  13. package/dist/button/index.d.ts.map +1 -1
  14. package/dist/calendar/createCalendarCell.d.ts +2 -0
  15. package/dist/calendar/createCalendarCell.d.ts.map +1 -1
  16. package/dist/calendar/createCalendarGrid.d.ts.map +1 -1
  17. package/dist/calendar/createRangeCalendarCell.d.ts +3 -1
  18. package/dist/calendar/createRangeCalendarCell.d.ts.map +1 -1
  19. package/dist/checkbox/createCheckboxGroup.d.ts +5 -1
  20. package/dist/checkbox/createCheckboxGroup.d.ts.map +1 -1
  21. package/dist/collections/index.d.ts +56 -0
  22. package/dist/collections/index.d.ts.map +1 -0
  23. package/dist/color/createColorArea.d.ts.map +1 -1
  24. package/dist/color/createColorSlider.d.ts.map +1 -1
  25. package/dist/color/createColorWheel.d.ts.map +1 -1
  26. package/dist/combobox/createComboBox.d.ts +6 -0
  27. package/dist/combobox/createComboBox.d.ts.map +1 -1
  28. package/dist/datepicker/createDatePicker.d.ts +6 -0
  29. package/dist/datepicker/createDatePicker.d.ts.map +1 -1
  30. package/dist/datepicker/createDateRangePicker.d.ts +40 -0
  31. package/dist/datepicker/createDateRangePicker.d.ts.map +1 -0
  32. package/dist/datepicker/createDateSegment.d.ts +1 -1
  33. package/dist/datepicker/createDateSegment.d.ts.map +1 -1
  34. package/dist/datepicker/createTimeSegment.d.ts +29 -0
  35. package/dist/datepicker/createTimeSegment.d.ts.map +1 -0
  36. package/dist/datepicker/index.d.ts +2 -0
  37. package/dist/datepicker/index.d.ts.map +1 -1
  38. package/dist/disclosure/createDisclosureGroup.d.ts +2 -1
  39. package/dist/disclosure/createDisclosureGroup.d.ts.map +1 -1
  40. package/dist/dnd/createDrag.d.ts.map +1 -1
  41. package/dist/dnd/createDraggableCollection.d.ts +4 -0
  42. package/dist/dnd/createDraggableCollection.d.ts.map +1 -1
  43. package/dist/dnd/createDraggableItem.d.ts.map +1 -1
  44. package/dist/dnd/createDrop.d.ts.map +1 -1
  45. package/dist/dnd/createDroppableCollection.d.ts +32 -1
  46. package/dist/dnd/createDroppableCollection.d.ts.map +1 -1
  47. package/dist/dnd/createDroppableItem.d.ts.map +1 -1
  48. package/dist/dnd/index.d.ts +1 -1
  49. package/dist/dnd/index.d.ts.map +1 -1
  50. package/dist/grid/createGrid.d.ts.map +1 -1
  51. package/dist/gridlist/createGridList.d.ts.map +1 -1
  52. package/dist/index.d.ts +6 -4
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +4659 -3452
  55. package/dist/index.js.map +1 -7
  56. package/dist/index.ssr.js +4659 -3452
  57. package/dist/index.ssr.js.map +1 -7
  58. package/dist/interactions/createFocus.d.ts.map +1 -1
  59. package/dist/interactions/createFocusWithin.d.ts.map +1 -1
  60. package/dist/link/createLink.d.ts +10 -0
  61. package/dist/link/createLink.d.ts.map +1 -1
  62. package/dist/listbox/createListBox.d.ts +1 -0
  63. package/dist/listbox/createListBox.d.ts.map +1 -1
  64. package/dist/listbox/createOption.d.ts.map +1 -1
  65. package/dist/menu/createMenu.d.ts +1 -0
  66. package/dist/menu/createMenu.d.ts.map +1 -1
  67. package/dist/meter/createMeter.d.ts.map +1 -1
  68. package/dist/numberfield/createNumberField.d.ts +18 -0
  69. package/dist/numberfield/createNumberField.d.ts.map +1 -1
  70. package/dist/overlays/createModal.d.ts +16 -0
  71. package/dist/overlays/createModal.d.ts.map +1 -1
  72. package/dist/overlays/createOverlay.d.ts.map +1 -1
  73. package/dist/overlays/index.d.ts +1 -1
  74. package/dist/overlays/index.d.ts.map +1 -1
  75. package/dist/popover/createOverlayPosition.d.ts.map +1 -1
  76. package/dist/popover/createPopover.d.ts.map +1 -1
  77. package/dist/progress/createProgressBar.d.ts.map +1 -1
  78. package/dist/radio/createRadioGroup.d.ts +2 -2
  79. package/dist/radio/createRadioGroup.d.ts.map +1 -1
  80. package/dist/searchfield/createSearchField.d.ts.map +1 -1
  81. package/dist/select/createHiddenSelect.d.ts.map +1 -1
  82. package/dist/select/createSelect.d.ts.map +1 -1
  83. package/dist/slider/createSlider.d.ts.map +1 -1
  84. package/dist/table/createTable.d.ts.map +1 -1
  85. package/dist/tabs/createTabs.d.ts +1 -1
  86. package/dist/tabs/createTabs.d.ts.map +1 -1
  87. package/dist/tag/createTag.d.ts.map +1 -1
  88. package/dist/tag/createTagGroup.d.ts.map +1 -1
  89. package/dist/toast/createToast.d.ts +4 -0
  90. package/dist/toast/createToast.d.ts.map +1 -1
  91. package/dist/toast/createToastRegion.d.ts.map +1 -1
  92. package/dist/toolbar/createToolbar.d.ts.map +1 -1
  93. package/dist/tooltip/createTooltipTrigger.d.ts.map +1 -1
  94. package/dist/tree/createTree.d.ts.map +1 -1
  95. package/dist/tree/createTreeItem.d.ts.map +1 -1
  96. package/dist/tree/types.d.ts +4 -0
  97. package/dist/tree/types.d.ts.map +1 -1
  98. package/dist/utils/env.d.ts +1 -1
  99. package/dist/utils/env.d.ts.map +1 -1
  100. package/dist/utils/platform.d.ts.map +1 -1
  101. package/dist/visually-hidden/createVisuallyHidden.d.ts.map +1 -1
  102. package/package.json +8 -6
  103. package/src/actiongroup/createActionGroup.ts +324 -0
  104. package/src/actiongroup/index.ts +8 -0
  105. package/src/autocomplete/createAutocomplete.ts +32 -9
  106. package/src/breadcrumbs/createBreadcrumbs.ts +10 -15
  107. package/src/button/createButton.ts +1 -1
  108. package/src/button/createToggleButtonGroup.ts +128 -0
  109. package/src/button/index.ts +9 -0
  110. package/src/calendar/createCalendarCell.ts +6 -4
  111. package/src/calendar/createCalendarGrid.ts +27 -18
  112. package/src/calendar/createRangeCalendarCell.ts +26 -9
  113. package/src/checkbox/createCheckboxGroup.ts +21 -4
  114. package/src/collections/index.ts +242 -0
  115. package/src/color/createColorArea.ts +380 -314
  116. package/src/color/createColorField.ts +137 -137
  117. package/src/color/createColorSlider.ts +286 -197
  118. package/src/color/createColorSwatch.ts +40 -40
  119. package/src/color/createColorWheel.ts +218 -208
  120. package/src/color/index.ts +24 -24
  121. package/src/color/types.ts +116 -116
  122. package/src/combobox/createComboBox.ts +670 -647
  123. package/src/combobox/index.ts +6 -6
  124. package/src/datepicker/createDatePicker.ts +54 -16
  125. package/src/datepicker/createDateRangePicker.ts +246 -0
  126. package/src/datepicker/createDateSegment.ts +185 -31
  127. package/src/datepicker/createTimeSegment.ts +370 -0
  128. package/src/datepicker/index.ts +14 -0
  129. package/src/dialog/createDialog.ts +120 -120
  130. package/src/dialog/index.ts +2 -2
  131. package/src/dialog/types.ts +19 -19
  132. package/src/disclosure/createDisclosureGroup.ts +5 -2
  133. package/src/dnd/createDrag.ts +224 -209
  134. package/src/dnd/createDraggableCollection.ts +96 -63
  135. package/src/dnd/createDraggableItem.ts +259 -243
  136. package/src/dnd/createDrop.ts +322 -321
  137. package/src/dnd/createDroppableCollection.ts +682 -293
  138. package/src/dnd/createDroppableItem.ts +215 -213
  139. package/src/dnd/index.ts +55 -47
  140. package/src/dnd/types.ts +89 -89
  141. package/src/dnd/utils.ts +294 -294
  142. package/src/focus/createAutoFocus.ts +321 -321
  143. package/src/focus/createFocusRestore.ts +313 -313
  144. package/src/focus/createVirtualFocus.ts +396 -396
  145. package/src/form/createFormValidation.ts +224 -224
  146. package/src/form/index.ts +11 -11
  147. package/src/grid/createGrid.ts +3 -1
  148. package/src/gridlist/createGridList.ts +16 -0
  149. package/src/gridlist/createGridListItem.ts +1 -1
  150. package/src/i18n/NumberFormatter.ts +266 -266
  151. package/src/i18n/createCollator.ts +79 -79
  152. package/src/i18n/createDateFormatter.ts +83 -83
  153. package/src/i18n/createFilter.ts +131 -131
  154. package/src/i18n/createNumberFormatter.ts +52 -52
  155. package/src/i18n/index.ts +40 -40
  156. package/src/i18n/locale.tsx +188 -188
  157. package/src/i18n/utils.ts +99 -99
  158. package/src/index.ts +51 -0
  159. package/src/interactions/createFocus.ts +6 -5
  160. package/src/interactions/createFocusWithin.ts +6 -5
  161. package/src/interactions/createLongPress.ts +174 -174
  162. package/src/interactions/createMove.ts +289 -289
  163. package/src/interactions/createPress.ts +5 -5
  164. package/src/landmark/createLandmark.ts +377 -377
  165. package/src/landmark/index.ts +8 -8
  166. package/src/link/createLink.ts +23 -8
  167. package/src/listbox/createListBox.ts +308 -269
  168. package/src/listbox/createOption.ts +162 -151
  169. package/src/listbox/index.ts +12 -12
  170. package/src/live-announcer/announce.ts +322 -322
  171. package/src/live-announcer/index.ts +9 -9
  172. package/src/menu/createMenu.ts +405 -396
  173. package/src/menu/createMenuItem.ts +149 -149
  174. package/src/menu/createMenuTrigger.ts +88 -88
  175. package/src/menu/index.ts +18 -18
  176. package/src/meter/createMeter.ts +1 -6
  177. package/src/numberfield/createNumberField.ts +311 -268
  178. package/src/numberfield/index.ts +5 -5
  179. package/src/overlays/ariaHideOutside.ts +219 -219
  180. package/src/overlays/createInteractOutside.ts +149 -149
  181. package/src/overlays/createModal.tsx +238 -202
  182. package/src/overlays/createOverlay.ts +165 -155
  183. package/src/overlays/createOverlayTrigger.ts +85 -85
  184. package/src/overlays/createPreventScroll.ts +266 -266
  185. package/src/overlays/index.ts +48 -44
  186. package/src/popover/calculatePosition.ts +6 -6
  187. package/src/popover/createOverlayPosition.ts +7 -4
  188. package/src/popover/createPopover.ts +21 -7
  189. package/src/progress/createProgressBar.ts +6 -1
  190. package/src/radio/createRadioGroup.ts +88 -14
  191. package/src/searchfield/createSearchField.ts +241 -186
  192. package/src/searchfield/index.ts +2 -2
  193. package/src/select/createHiddenSelect.tsx +263 -236
  194. package/src/select/createSelect.ts +373 -395
  195. package/src/select/index.ts +14 -14
  196. package/src/slider/createSlider.ts +364 -349
  197. package/src/slider/index.ts +2 -2
  198. package/src/ssr/index.tsx +370 -370
  199. package/src/table/createTable.ts +3 -1
  200. package/src/table/createTableColumnHeader.ts +1 -1
  201. package/src/table/createTableRow.ts +1 -1
  202. package/src/tabs/createTabs.ts +80 -51
  203. package/src/tag/createTag.ts +135 -6
  204. package/src/tag/createTagGroup.ts +7 -2
  205. package/src/toast/createToast.ts +8 -2
  206. package/src/toast/createToastRegion.ts +0 -1
  207. package/src/toolbar/createToolbar.ts +75 -1
  208. package/src/tooltip/createTooltip.ts +79 -79
  209. package/src/tooltip/createTooltipTrigger.ts +226 -222
  210. package/src/tooltip/index.ts +6 -6
  211. package/src/tree/createTree.ts +261 -246
  212. package/src/tree/createTreeItem.ts +282 -233
  213. package/src/tree/createTreeSelectionCheckbox.ts +68 -68
  214. package/src/tree/index.ts +16 -16
  215. package/src/tree/types.ts +91 -87
  216. package/src/utils/env.ts +55 -54
  217. package/src/utils/platform.ts +16 -6
  218. package/src/visually-hidden/createVisuallyHidden.ts +139 -124
  219. package/src/visually-hidden/index.ts +6 -6
@@ -1,79 +1,79 @@
1
- /**
2
- * createCollator hook for solidaria
3
- *
4
- * Provides localized string comparison/collation with caching.
5
- *
6
- * Port of @react-aria/i18n useCollator.
7
- */
8
-
9
- import { createMemo } from 'solid-js';
10
- import { useLocale } from './locale';
11
- import { createCacheKey } from './utils';
12
-
13
- // ============================================
14
- // CACHE
15
- // ============================================
16
-
17
- const collatorCache = new Map<string, Intl.Collator>();
18
-
19
- /**
20
- * Gets or creates a cached collator.
21
- */
22
- function getCachedCollator(
23
- locale: string,
24
- options?: Intl.CollatorOptions
25
- ): Intl.Collator {
26
- const cacheKey = createCacheKey(locale, options as Record<string, unknown>);
27
-
28
- if (collatorCache.has(cacheKey)) {
29
- return collatorCache.get(cacheKey)!;
30
- }
31
-
32
- const collator = new Intl.Collator(locale, options);
33
- collatorCache.set(cacheKey, collator);
34
- return collator;
35
- }
36
-
37
- // ============================================
38
- // HOOK
39
- // ============================================
40
-
41
- /**
42
- * Provides localized string collation for the current locale.
43
- * Useful for sorting strings according to locale-specific rules.
44
- *
45
- * @example
46
- * ```tsx
47
- * function SortedList(props: { items: string[] }) {
48
- * const collator = createCollator();
49
- *
50
- * const sortedItems = () =>
51
- * [...props.items].sort((a, b) => collator().compare(a, b));
52
- *
53
- * return (
54
- * <ul>
55
- * <For each={sortedItems()}>
56
- * {(item) => <li>{item}</li>}
57
- * </For>
58
- * </ul>
59
- * );
60
- * }
61
- * ```
62
- *
63
- * @example
64
- * ```tsx
65
- * // Case-insensitive sorting
66
- * const collator = createCollator({ sensitivity: 'base' });
67
- *
68
- * // Numeric sorting
69
- * const numericCollator = createCollator({ numeric: true });
70
- * // ['a1', 'a10', 'a2'].sort(numericCollator().compare) -> ['a1', 'a2', 'a10']
71
- * ```
72
- */
73
- export function createCollator(
74
- options?: Intl.CollatorOptions
75
- ): () => Intl.Collator {
76
- const locale = useLocale();
77
-
78
- return createMemo(() => getCachedCollator(locale().locale, options));
79
- }
1
+ /**
2
+ * createCollator hook for solidaria
3
+ *
4
+ * Provides localized string comparison/collation with caching.
5
+ *
6
+ * Port of @react-aria/i18n useCollator.
7
+ */
8
+
9
+ import { createMemo } from 'solid-js';
10
+ import { useLocale } from './locale';
11
+ import { createCacheKey } from './utils';
12
+
13
+ // ============================================
14
+ // CACHE
15
+ // ============================================
16
+
17
+ const collatorCache = new Map<string, Intl.Collator>();
18
+
19
+ /**
20
+ * Gets or creates a cached collator.
21
+ */
22
+ function getCachedCollator(
23
+ locale: string,
24
+ options?: Intl.CollatorOptions
25
+ ): Intl.Collator {
26
+ const cacheKey = createCacheKey(locale, options as Record<string, unknown>);
27
+
28
+ if (collatorCache.has(cacheKey)) {
29
+ return collatorCache.get(cacheKey)!;
30
+ }
31
+
32
+ const collator = new Intl.Collator(locale, options);
33
+ collatorCache.set(cacheKey, collator);
34
+ return collator;
35
+ }
36
+
37
+ // ============================================
38
+ // HOOK
39
+ // ============================================
40
+
41
+ /**
42
+ * Provides localized string collation for the current locale.
43
+ * Useful for sorting strings according to locale-specific rules.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * function SortedList(props: { items: string[] }) {
48
+ * const collator = createCollator();
49
+ *
50
+ * const sortedItems = () =>
51
+ * [...props.items].sort((a, b) => collator().compare(a, b));
52
+ *
53
+ * return (
54
+ * <ul>
55
+ * <For each={sortedItems()}>
56
+ * {(item) => <li>{item}</li>}
57
+ * </For>
58
+ * </ul>
59
+ * );
60
+ * }
61
+ * ```
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * // Case-insensitive sorting
66
+ * const collator = createCollator({ sensitivity: 'base' });
67
+ *
68
+ * // Numeric sorting
69
+ * const numericCollator = createCollator({ numeric: true });
70
+ * // ['a1', 'a10', 'a2'].sort(numericCollator().compare) -> ['a1', 'a2', 'a10']
71
+ * ```
72
+ */
73
+ export function createCollator(
74
+ options?: Intl.CollatorOptions
75
+ ): () => Intl.Collator {
76
+ const locale = useLocale();
77
+
78
+ return createMemo(() => getCachedCollator(locale().locale, options));
79
+ }
@@ -1,83 +1,83 @@
1
- /**
2
- * createDateFormatter hook for solidaria
3
- *
4
- * Provides localized date formatting with caching.
5
- *
6
- * Port of @react-aria/i18n useDateFormatter.
7
- */
8
-
9
- import { createMemo } from 'solid-js';
10
- import { useLocale } from './locale';
11
- import { createCacheKey } from './utils';
12
-
13
- // ============================================
14
- // CACHE
15
- // ============================================
16
-
17
- const dateFormatterCache = new Map<string, Intl.DateTimeFormat>();
18
-
19
- /**
20
- * Gets or creates a cached date formatter.
21
- */
22
- function getCachedDateFormatter(
23
- locale: string,
24
- options?: Intl.DateTimeFormatOptions
25
- ): Intl.DateTimeFormat {
26
- const cacheKey = createCacheKey(locale, options as Record<string, unknown>);
27
-
28
- if (dateFormatterCache.has(cacheKey)) {
29
- return dateFormatterCache.get(cacheKey)!;
30
- }
31
-
32
- const formatter = new Intl.DateTimeFormat(locale, options);
33
- dateFormatterCache.set(cacheKey, formatter);
34
- return formatter;
35
- }
36
-
37
- // ============================================
38
- // HOOK
39
- // ============================================
40
-
41
- /**
42
- * Provides localized date and time formatting for the current locale.
43
- * Automatically updates when the locale changes.
44
- *
45
- * @example
46
- * ```tsx
47
- * function DateDisplay(props: { date: Date }) {
48
- * const formatter = createDateFormatter({
49
- * year: 'numeric',
50
- * month: 'long',
51
- * day: 'numeric',
52
- * });
53
- *
54
- * return <span>{formatter().format(props.date)}</span>;
55
- * }
56
- * ```
57
- *
58
- * @example
59
- * ```tsx
60
- * // Short date
61
- * const shortDate = createDateFormatter({ dateStyle: 'short' });
62
- * shortDate().format(new Date()); // '1/19/26' (US) or '19/01/26' (UK)
63
- *
64
- * // Full date with time
65
- * const fullDateTime = createDateFormatter({
66
- * dateStyle: 'full',
67
- * timeStyle: 'short',
68
- * });
69
- *
70
- * // Time only
71
- * const timeFormatter = createDateFormatter({
72
- * hour: 'numeric',
73
- * minute: '2-digit',
74
- * });
75
- * ```
76
- */
77
- export function createDateFormatter(
78
- options?: Intl.DateTimeFormatOptions
79
- ): () => Intl.DateTimeFormat {
80
- const locale = useLocale();
81
-
82
- return createMemo(() => getCachedDateFormatter(locale().locale, options));
83
- }
1
+ /**
2
+ * createDateFormatter hook for solidaria
3
+ *
4
+ * Provides localized date formatting with caching.
5
+ *
6
+ * Port of @react-aria/i18n useDateFormatter.
7
+ */
8
+
9
+ import { createMemo } from 'solid-js';
10
+ import { useLocale } from './locale';
11
+ import { createCacheKey } from './utils';
12
+
13
+ // ============================================
14
+ // CACHE
15
+ // ============================================
16
+
17
+ const dateFormatterCache = new Map<string, Intl.DateTimeFormat>();
18
+
19
+ /**
20
+ * Gets or creates a cached date formatter.
21
+ */
22
+ function getCachedDateFormatter(
23
+ locale: string,
24
+ options?: Intl.DateTimeFormatOptions
25
+ ): Intl.DateTimeFormat {
26
+ const cacheKey = createCacheKey(locale, options as Record<string, unknown>);
27
+
28
+ if (dateFormatterCache.has(cacheKey)) {
29
+ return dateFormatterCache.get(cacheKey)!;
30
+ }
31
+
32
+ const formatter = new Intl.DateTimeFormat(locale, options);
33
+ dateFormatterCache.set(cacheKey, formatter);
34
+ return formatter;
35
+ }
36
+
37
+ // ============================================
38
+ // HOOK
39
+ // ============================================
40
+
41
+ /**
42
+ * Provides localized date and time formatting for the current locale.
43
+ * Automatically updates when the locale changes.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * function DateDisplay(props: { date: Date }) {
48
+ * const formatter = createDateFormatter({
49
+ * year: 'numeric',
50
+ * month: 'long',
51
+ * day: 'numeric',
52
+ * });
53
+ *
54
+ * return <span>{formatter().format(props.date)}</span>;
55
+ * }
56
+ * ```
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * // Short date
61
+ * const shortDate = createDateFormatter({ dateStyle: 'short' });
62
+ * shortDate().format(new Date()); // '1/19/26' (US) or '19/01/26' (UK)
63
+ *
64
+ * // Full date with time
65
+ * const fullDateTime = createDateFormatter({
66
+ * dateStyle: 'full',
67
+ * timeStyle: 'short',
68
+ * });
69
+ *
70
+ * // Time only
71
+ * const timeFormatter = createDateFormatter({
72
+ * hour: 'numeric',
73
+ * minute: '2-digit',
74
+ * });
75
+ * ```
76
+ */
77
+ export function createDateFormatter(
78
+ options?: Intl.DateTimeFormatOptions
79
+ ): () => Intl.DateTimeFormat {
80
+ const locale = useLocale();
81
+
82
+ return createMemo(() => getCachedDateFormatter(locale().locale, options));
83
+ }
@@ -1,131 +1,131 @@
1
- /**
2
- * createFilter hook for solidaria
3
- *
4
- * Provides localized string filtering with collation support.
5
- *
6
- * Port of @react-aria/i18n useFilter.
7
- */
8
-
9
- import { createMemo } from 'solid-js';
10
- import { createCollator } from './createCollator';
11
-
12
- // ============================================
13
- // TYPES
14
- // ============================================
15
-
16
- export interface Filter {
17
- /** Returns whether a string starts with a given substring. */
18
- startsWith(string: string, substring: string): boolean;
19
- /** Returns whether a string ends with a given substring. */
20
- endsWith(string: string, substring: string): boolean;
21
- /** Returns whether a string contains a given substring. */
22
- contains(string: string, substring: string): boolean;
23
- }
24
-
25
- // ============================================
26
- // HOOK
27
- // ============================================
28
-
29
- /**
30
- * Provides localized string search functionality for filtering or matching items.
31
- * Respects locale-specific collation rules for case and diacritic sensitivity.
32
- *
33
- * @example
34
- * ```tsx
35
- * function SearchableList(props: { items: { name: string }[] }) {
36
- * const [query, setQuery] = createSignal('');
37
- * const filter = createFilter({ sensitivity: 'base' });
38
- *
39
- * const filteredItems = () =>
40
- * props.items.filter((item) =>
41
- * filter().contains(item.name, query())
42
- * );
43
- *
44
- * return (
45
- * <>
46
- * <input
47
- * value={query()}
48
- * onInput={(e) => setQuery(e.target.value)}
49
- * placeholder="Search..."
50
- * />
51
- * <ul>
52
- * <For each={filteredItems()}>
53
- * {(item) => <li>{item.name}</li>}
54
- * </For>
55
- * </ul>
56
- * </>
57
- * );
58
- * }
59
- * ```
60
- *
61
- * @example
62
- * ```tsx
63
- * // Case-insensitive, diacritic-insensitive filtering
64
- * const filter = createFilter({ sensitivity: 'base' });
65
- * filter().contains('Café', 'cafe'); // true
66
- * filter().startsWith('Hello', 'hello'); // true
67
- * ```
68
- */
69
- export function createFilter(options?: Intl.CollatorOptions): () => Filter {
70
- const collator = createCollator({
71
- usage: 'search',
72
- ...options,
73
- });
74
-
75
- return createMemo(() => {
76
- const coll = collator();
77
-
78
- const startsWith = (str: string, substring: string): boolean => {
79
- if (substring.length === 0) {
80
- return true;
81
- }
82
-
83
- // Normalize both strings for safe slicing
84
- const normalizedStr = str.normalize('NFC');
85
- const normalizedSub = substring.normalize('NFC');
86
-
87
- return (
88
- coll.compare(normalizedStr.slice(0, normalizedSub.length), normalizedSub) ===
89
- 0
90
- );
91
- };
92
-
93
- const endsWith = (str: string, substring: string): boolean => {
94
- if (substring.length === 0) {
95
- return true;
96
- }
97
-
98
- const normalizedStr = str.normalize('NFC');
99
- const normalizedSub = substring.normalize('NFC');
100
-
101
- return (
102
- coll.compare(normalizedStr.slice(-normalizedSub.length), normalizedSub) === 0
103
- );
104
- };
105
-
106
- const contains = (str: string, substring: string): boolean => {
107
- if (substring.length === 0) {
108
- return true;
109
- }
110
-
111
- const normalizedStr = str.normalize('NFC');
112
- const normalizedSub = substring.normalize('NFC');
113
- const sliceLen = normalizedSub.length;
114
-
115
- for (let scan = 0; scan + sliceLen <= normalizedStr.length; scan++) {
116
- const slice = normalizedStr.slice(scan, scan + sliceLen);
117
- if (coll.compare(normalizedSub, slice) === 0) {
118
- return true;
119
- }
120
- }
121
-
122
- return false;
123
- };
124
-
125
- return {
126
- startsWith,
127
- endsWith,
128
- contains,
129
- };
130
- });
131
- }
1
+ /**
2
+ * createFilter hook for solidaria
3
+ *
4
+ * Provides localized string filtering with collation support.
5
+ *
6
+ * Port of @react-aria/i18n useFilter.
7
+ */
8
+
9
+ import { createMemo } from 'solid-js';
10
+ import { createCollator } from './createCollator';
11
+
12
+ // ============================================
13
+ // TYPES
14
+ // ============================================
15
+
16
+ export interface Filter {
17
+ /** Returns whether a string starts with a given substring. */
18
+ startsWith(string: string, substring: string): boolean;
19
+ /** Returns whether a string ends with a given substring. */
20
+ endsWith(string: string, substring: string): boolean;
21
+ /** Returns whether a string contains a given substring. */
22
+ contains(string: string, substring: string): boolean;
23
+ }
24
+
25
+ // ============================================
26
+ // HOOK
27
+ // ============================================
28
+
29
+ /**
30
+ * Provides localized string search functionality for filtering or matching items.
31
+ * Respects locale-specific collation rules for case and diacritic sensitivity.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * function SearchableList(props: { items: { name: string }[] }) {
36
+ * const [query, setQuery] = createSignal('');
37
+ * const filter = createFilter({ sensitivity: 'base' });
38
+ *
39
+ * const filteredItems = () =>
40
+ * props.items.filter((item) =>
41
+ * filter().contains(item.name, query())
42
+ * );
43
+ *
44
+ * return (
45
+ * <>
46
+ * <input
47
+ * value={query()}
48
+ * onInput={(e) => setQuery(e.target.value)}
49
+ * placeholder="Search..."
50
+ * />
51
+ * <ul>
52
+ * <For each={filteredItems()}>
53
+ * {(item) => <li>{item.name}</li>}
54
+ * </For>
55
+ * </ul>
56
+ * </>
57
+ * );
58
+ * }
59
+ * ```
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * // Case-insensitive, diacritic-insensitive filtering
64
+ * const filter = createFilter({ sensitivity: 'base' });
65
+ * filter().contains('Café', 'cafe'); // true
66
+ * filter().startsWith('Hello', 'hello'); // true
67
+ * ```
68
+ */
69
+ export function createFilter(options?: Intl.CollatorOptions): () => Filter {
70
+ const collator = createCollator({
71
+ usage: 'search',
72
+ ...options,
73
+ });
74
+
75
+ return createMemo(() => {
76
+ const coll = collator();
77
+
78
+ const startsWith = (str: string, substring: string): boolean => {
79
+ if (substring.length === 0) {
80
+ return true;
81
+ }
82
+
83
+ // Normalize both strings for safe slicing
84
+ const normalizedStr = str.normalize('NFC');
85
+ const normalizedSub = substring.normalize('NFC');
86
+
87
+ return (
88
+ coll.compare(normalizedStr.slice(0, normalizedSub.length), normalizedSub) ===
89
+ 0
90
+ );
91
+ };
92
+
93
+ const endsWith = (str: string, substring: string): boolean => {
94
+ if (substring.length === 0) {
95
+ return true;
96
+ }
97
+
98
+ const normalizedStr = str.normalize('NFC');
99
+ const normalizedSub = substring.normalize('NFC');
100
+
101
+ return (
102
+ coll.compare(normalizedStr.slice(-normalizedSub.length), normalizedSub) === 0
103
+ );
104
+ };
105
+
106
+ const contains = (str: string, substring: string): boolean => {
107
+ if (substring.length === 0) {
108
+ return true;
109
+ }
110
+
111
+ const normalizedStr = str.normalize('NFC');
112
+ const normalizedSub = substring.normalize('NFC');
113
+ const sliceLen = normalizedSub.length;
114
+
115
+ for (let scan = 0; scan + sliceLen <= normalizedStr.length; scan++) {
116
+ const slice = normalizedStr.slice(scan, scan + sliceLen);
117
+ if (coll.compare(normalizedSub, slice) === 0) {
118
+ return true;
119
+ }
120
+ }
121
+
122
+ return false;
123
+ };
124
+
125
+ return {
126
+ startsWith,
127
+ endsWith,
128
+ contains,
129
+ };
130
+ });
131
+ }