@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
package/src/tree/index.ts CHANGED
@@ -1,16 +1,16 @@
1
- /**
2
- * Tree ARIA layer exports.
3
- */
4
-
5
- export { createTree, getTreeData } from './createTree';
6
- export { createTreeItem } from './createTreeItem';
7
- export { createTreeSelectionCheckbox } from './createTreeSelectionCheckbox';
8
-
9
- export type {
10
- AriaTreeProps,
11
- TreeAria,
12
- AriaTreeItemProps,
13
- TreeItemAria,
14
- AriaTreeSelectionCheckboxProps,
15
- TreeSelectionCheckboxAria,
16
- } from './types';
1
+ /**
2
+ * Tree ARIA layer exports.
3
+ */
4
+
5
+ export { createTree, getTreeData } from './createTree';
6
+ export { createTreeItem } from './createTreeItem';
7
+ export { createTreeSelectionCheckbox } from './createTreeSelectionCheckbox';
8
+
9
+ export type {
10
+ AriaTreeProps,
11
+ TreeAria,
12
+ AriaTreeItemProps,
13
+ TreeItemAria,
14
+ AriaTreeSelectionCheckboxProps,
15
+ TreeSelectionCheckboxAria,
16
+ } from './types';
package/src/tree/types.ts CHANGED
@@ -1,87 +1,91 @@
1
- /**
2
- * Tree ARIA types.
3
- * Based on @react-aria/tree.
4
- */
5
-
6
- import type { JSX } from 'solid-js';
7
- import type { Key, TreeNode } from '@proyecto-viviana/solid-stately';
8
-
9
- /**
10
- * Props for createTree.
11
- */
12
- export interface AriaTreeProps {
13
- /** The unique id for the tree. */
14
- id?: string;
15
- /** Label for accessibility. */
16
- 'aria-label'?: string;
17
- /** ID of an element that labels the tree. */
18
- 'aria-labelledby'?: string;
19
- /** ID of an element that describes the tree. */
20
- 'aria-describedby'?: string;
21
- /** Whether the tree is virtualized. */
22
- isVirtualized?: boolean;
23
- /** Handler called when an item action is triggered. */
24
- onAction?: (key: Key) => void;
25
- /** Whether the tree is disabled. */
26
- isDisabled?: boolean;
27
- }
28
-
29
- /**
30
- * Return value for createTree.
31
- */
32
- export interface TreeAria {
33
- /** Props for the tree container (role="treegrid"). */
34
- treeProps: JSX.HTMLAttributes<HTMLDivElement>;
35
- }
36
-
37
- /**
38
- * Props for createTreeItem.
39
- */
40
- export interface AriaTreeItemProps<T = unknown> {
41
- /** The tree node this item represents. */
42
- node: TreeNode<T>;
43
- /** Whether the item is rendered in a virtualized list. */
44
- isVirtualized?: boolean;
45
- /** Handler called when this item's action is triggered. */
46
- onAction?: () => void;
47
- }
48
-
49
- /**
50
- * Return value for createTreeItem.
51
- */
52
- export interface TreeItemAria {
53
- /** Props for the row element. */
54
- rowProps: JSX.HTMLAttributes<HTMLDivElement>;
55
- /** Props for the grid cell content wrapper. */
56
- gridCellProps: JSX.HTMLAttributes<HTMLDivElement>;
57
- /** Props for the expand button (if the item is expandable). */
58
- expandButtonProps: JSX.ButtonHTMLAttributes<HTMLButtonElement>;
59
- /** Whether the item is selected. */
60
- isSelected: boolean;
61
- /** Whether the item is disabled. */
62
- isDisabled: boolean;
63
- /** Whether the item is being pressed. */
64
- isPressed: boolean;
65
- /** Whether the item is expanded. */
66
- isExpanded: boolean;
67
- /** Whether the item is expandable (has children). */
68
- isExpandable: boolean;
69
- /** The nesting level of the item (0 for root). */
70
- level: number;
71
- }
72
-
73
- /**
74
- * Props for createTreeSelectionCheckbox.
75
- */
76
- export interface AriaTreeSelectionCheckboxProps {
77
- /** The key of the tree item this checkbox belongs to. */
78
- key: Key;
79
- }
80
-
81
- /**
82
- * Return value for createTreeSelectionCheckbox.
83
- */
84
- export interface TreeSelectionCheckboxAria {
85
- /** Props for the checkbox input element. */
86
- checkboxProps: JSX.InputHTMLAttributes<HTMLInputElement>;
87
- }
1
+ /**
2
+ * Tree ARIA types.
3
+ * Based on @react-aria/tree.
4
+ */
5
+
6
+ import type { JSX } from 'solid-js';
7
+ import type { Key, TreeNode } from '@proyecto-viviana/solid-stately';
8
+
9
+ /**
10
+ * Props for createTree.
11
+ */
12
+ export interface AriaTreeProps {
13
+ /** The unique id for the tree. */
14
+ id?: string;
15
+ /** Label for accessibility. */
16
+ 'aria-label'?: string;
17
+ /** ID of an element that labels the tree. */
18
+ 'aria-labelledby'?: string;
19
+ /** ID of an element that describes the tree. */
20
+ 'aria-describedby'?: string;
21
+ /** Whether the tree is virtualized. */
22
+ isVirtualized?: boolean;
23
+ /** Handler called when an item action is triggered. */
24
+ onAction?: (key: Key) => void;
25
+ /** Whether the tree is disabled. */
26
+ isDisabled?: boolean;
27
+ /** The writing direction for the tree. Determines expand/collapse key mapping. */
28
+ direction?: 'ltr' | 'rtl';
29
+ }
30
+
31
+ /**
32
+ * Return value for createTree.
33
+ */
34
+ export interface TreeAria {
35
+ /** Props for the tree container (role="treegrid"). */
36
+ treeProps: JSX.HTMLAttributes<HTMLDivElement>;
37
+ }
38
+
39
+ /**
40
+ * Props for createTreeItem.
41
+ */
42
+ export interface AriaTreeItemProps<T = unknown> {
43
+ /** The tree node this item represents. */
44
+ node: TreeNode<T>;
45
+ /** Whether the item is rendered in a virtualized list. */
46
+ isVirtualized?: boolean;
47
+ /** Handler called when this item's action is triggered. */
48
+ onAction?: () => void;
49
+ /** The text value for the item (used for aria-label on the row). */
50
+ textValue?: string;
51
+ }
52
+
53
+ /**
54
+ * Return value for createTreeItem.
55
+ */
56
+ export interface TreeItemAria {
57
+ /** Props for the row element. */
58
+ rowProps: JSX.HTMLAttributes<HTMLDivElement>;
59
+ /** Props for the grid cell content wrapper. */
60
+ gridCellProps: JSX.HTMLAttributes<HTMLDivElement>;
61
+ /** Props for the expand button (if the item is expandable). */
62
+ expandButtonProps: JSX.ButtonHTMLAttributes<HTMLButtonElement>;
63
+ /** Whether the item is selected. */
64
+ isSelected: boolean;
65
+ /** Whether the item is disabled. */
66
+ isDisabled: boolean;
67
+ /** Whether the item is being pressed. */
68
+ isPressed: boolean;
69
+ /** Whether the item is expanded. */
70
+ isExpanded: boolean;
71
+ /** Whether the item is expandable (has children). */
72
+ isExpandable: boolean;
73
+ /** The nesting level of the item (0 for root). */
74
+ level: number;
75
+ }
76
+
77
+ /**
78
+ * Props for createTreeSelectionCheckbox.
79
+ */
80
+ export interface AriaTreeSelectionCheckboxProps {
81
+ /** The key of the tree item this checkbox belongs to. */
82
+ key: Key;
83
+ }
84
+
85
+ /**
86
+ * Return value for createTreeSelectionCheckbox.
87
+ */
88
+ export interface TreeSelectionCheckboxAria {
89
+ /** Props for the checkbox input element. */
90
+ checkboxProps: JSX.InputHTMLAttributes<HTMLInputElement>;
91
+ }
package/src/utils/env.ts CHANGED
@@ -1,54 +1,55 @@
1
- /**
2
- * Environment detection utilities.
3
- * These avoid direct references to process.env which can cause TypeScript issues in browser environments.
4
- * Compatible with Node.js, Deno, and Vite environments.
5
- */
6
-
7
- // Type-safe access to import.meta.env (Vite) and Deno.env
8
- declare const Deno: { env?: { get(key: string): string | undefined } } | undefined;
9
-
10
- function getEnvVar(key: string): string | undefined {
11
- // Check Vite's import.meta.env
12
- if (typeof import.meta !== 'undefined' && (import.meta as any).env) {
13
- return (import.meta as any).env[key];
14
- }
15
- // Check Deno
16
- if (typeof Deno !== 'undefined' && Deno.env) {
17
- return Deno.env.get(key);
18
- }
19
- // Check Node.js process.env via globalThis
20
- if (typeof globalThis !== 'undefined' && (globalThis as any).process?.env) {
21
- return (globalThis as any).process.env[key];
22
- }
23
- return undefined;
24
- }
25
-
26
- /**
27
- * Check if we're running in a test environment.
28
- */
29
- export function isTestEnv(): boolean {
30
- return getEnvVar('NODE_ENV') === 'test';
31
- }
32
-
33
- /**
34
- * Check if we're running in a development environment (not production).
35
- */
36
- export function isDevEnv(): boolean {
37
- // Check Vite's DEV flag
38
- if (typeof import.meta !== 'undefined' && (import.meta as any).env?.DEV) {
39
- return true;
40
- }
41
- const nodeEnv = getEnvVar('NODE_ENV');
42
- return nodeEnv !== 'production';
43
- }
44
-
45
- /**
46
- * Check if we're running in production.
47
- */
48
- export function isProdEnv(): boolean {
49
- // Check Vite's PROD flag
50
- if (typeof import.meta !== 'undefined' && (import.meta as any).env?.PROD) {
51
- return true;
52
- }
53
- return getEnvVar('NODE_ENV') === 'production';
54
- }
1
+ /**
2
+ * Environment detection utilities.
3
+ * These avoid direct references to process.env which can cause TypeScript issues in browser environments.
4
+ * Compatible with Node.js and Vite environments.
5
+ */
6
+
7
+ // Type-safe access to import.meta.env (Vite) and process.env
8
+ type ImportMetaWithEnv = ImportMeta & { env?: Record<string, unknown> & { DEV?: boolean; PROD?: boolean } };
9
+ type ProcessLike = { env?: Record<string, string | undefined> };
10
+
11
+ function getEnvVar(key: string): string | undefined {
12
+ // Check Vite's import.meta.env
13
+ const importMetaEnv = (import.meta as ImportMetaWithEnv).env;
14
+ if (importMetaEnv && typeof importMetaEnv[key] === 'string') {
15
+ return importMetaEnv[key] as string;
16
+ }
17
+ // Check Node.js process.env via globalThis
18
+ const processEnv = (globalThis as typeof globalThis & { process?: ProcessLike }).process?.env;
19
+ if (processEnv) {
20
+ return processEnv[key];
21
+ }
22
+ return undefined;
23
+ }
24
+
25
+ /**
26
+ * Check if we're running in a test environment.
27
+ */
28
+ export function isTestEnv(): boolean {
29
+ return getEnvVar('NODE_ENV') === 'test';
30
+ }
31
+
32
+ /**
33
+ * Check if we're running in a development environment (not production).
34
+ */
35
+ export function isDevEnv(): boolean {
36
+ // Check Vite's DEV flag
37
+ const importMetaEnv = (import.meta as ImportMetaWithEnv).env;
38
+ if (importMetaEnv?.DEV === true) {
39
+ return true;
40
+ }
41
+ const nodeEnv = getEnvVar('NODE_ENV');
42
+ return nodeEnv !== 'production';
43
+ }
44
+
45
+ /**
46
+ * Check if we're running in production.
47
+ */
48
+ export function isProdEnv(): boolean {
49
+ // Check Vite's PROD flag
50
+ const importMetaEnv = (import.meta as ImportMetaWithEnv).env;
51
+ if (importMetaEnv?.PROD === true) {
52
+ return true;
53
+ }
54
+ return getEnvVar('NODE_ENV') === 'production';
55
+ }
@@ -3,16 +3,26 @@
3
3
  * Based on @react-aria/utils platform detection.
4
4
  */
5
5
 
6
+ interface NavigatorWithUserAgentData extends Navigator {
7
+ userAgentData?: {
8
+ platform?: string;
9
+ };
10
+ }
11
+
12
+ function getNavigator(): NavigatorWithUserAgentData | null {
13
+ if (typeof window === 'undefined' || window.navigator == null) return null;
14
+ return window.navigator as NavigatorWithUserAgentData;
15
+ }
16
+
6
17
  function testPlatform(re: RegExp): boolean {
7
- return typeof window !== 'undefined' && window.navigator != null
8
- ? re.test(window.navigator.platform || (window.navigator as any).userAgentData?.platform || '')
9
- : false;
18
+ const nav = getNavigator();
19
+ if (!nav) return false;
20
+ return re.test(nav.platform || nav.userAgentData?.platform || '');
10
21
  }
11
22
 
12
23
  function testUserAgent(re: RegExp): boolean {
13
- return typeof window !== 'undefined' && window.navigator != null
14
- ? re.test(window.navigator.userAgent)
15
- : false;
24
+ const nav = getNavigator();
25
+ return nav ? re.test(nav.userAgent) : false;
16
26
  }
17
27
 
18
28
  export function isMac(): boolean {
@@ -1,124 +1,139 @@
1
- /**
2
- * createVisuallyHidden hook for solidaria
3
- *
4
- * Provides styles and props to visually hide content while keeping it
5
- * accessible to screen readers.
6
- *
7
- * Port of react-aria's useVisuallyHidden.
8
- */
9
-
10
- import { type Accessor, type JSX, createMemo, createSignal } from 'solid-js';
11
- import { createFocusWithin } from '../interactions/createFocusWithin';
12
- import { access, type MaybeAccessor } from '../utils';
13
-
14
- // ============================================
15
- // TYPES
16
- // ============================================
17
-
18
- export interface AriaVisuallyHiddenProps {
19
- /** Inline styles to merge with the visually hidden styles. */
20
- style?: JSX.CSSProperties;
21
- /** Whether the element should become visible when focused (e.g., skip links). */
22
- isFocusable?: boolean;
23
- }
24
-
25
- export interface VisuallyHiddenAria {
26
- /** Props to spread on the visually hidden element. */
27
- visuallyHiddenProps: Accessor<JSX.HTMLAttributes<HTMLElement>>;
28
- }
29
-
30
- // ============================================
31
- // STYLES
32
- // ============================================
33
-
34
- /**
35
- * CSS styles that visually hide an element while keeping it accessible.
36
- * These styles ensure the element is read by screen readers but not visible on screen.
37
- */
38
- export const visuallyHiddenStyles: JSX.CSSProperties = {
39
- border: '0',
40
- clip: 'rect(0 0 0 0)',
41
- 'clip-path': 'inset(50%)',
42
- height: '1px',
43
- margin: '-1px',
44
- overflow: 'hidden',
45
- padding: '0',
46
- position: 'absolute',
47
- width: '1px',
48
- 'white-space': 'nowrap',
49
- };
50
-
51
- // ============================================
52
- // HOOK
53
- // ============================================
54
-
55
- /**
56
- * Provides props for an element that hides its children visually
57
- * but keeps content visible to assistive technology.
58
- *
59
- * @example
60
- * ```tsx
61
- * function SkipLink() {
62
- * let ref: HTMLAnchorElement | undefined;
63
- * const { visuallyHiddenProps } = createVisuallyHidden({ isFocusable: true });
64
- *
65
- * return (
66
- * <a
67
- * ref={ref}
68
- * href="#main-content"
69
- * {...visuallyHiddenProps()}
70
- * >
71
- * Skip to main content
72
- * </a>
73
- * );
74
- * }
75
- *
76
- * // For content that should always be hidden
77
- * function ScreenReaderOnly(props: ParentProps) {
78
- * const { visuallyHiddenProps } = createVisuallyHidden();
79
- *
80
- * return (
81
- * <span {...visuallyHiddenProps()}>
82
- * {props.children}
83
- * </span>
84
- * );
85
- * }
86
- * ```
87
- */
88
- export function createVisuallyHidden(
89
- props: MaybeAccessor<AriaVisuallyHiddenProps> = {}
90
- ): VisuallyHiddenAria {
91
- const [isFocused, setIsFocused] = createSignal(false);
92
-
93
- const isFocusable = () => access(props).isFocusable ?? false;
94
- const style = () => access(props).style;
95
-
96
- // Track focus within for focusable visually hidden elements
97
- const { focusWithinProps } = createFocusWithin({
98
- get isDisabled() {
99
- return !isFocusable();
100
- },
101
- onFocusWithinChange: (val: boolean) => setIsFocused(val),
102
- });
103
-
104
- // Compute combined styles
105
- const combinedStyles = createMemo<JSX.CSSProperties>(() => {
106
- if (isFocused()) {
107
- // If focused, show the element (for skip links, etc.)
108
- return style() ?? {};
109
- } else if (style()) {
110
- return { ...visuallyHiddenStyles, ...style() };
111
- } else {
112
- return visuallyHiddenStyles;
113
- }
114
- });
115
-
116
- const visuallyHiddenProps = createMemo<JSX.HTMLAttributes<HTMLElement>>(() => ({
117
- ...focusWithinProps,
118
- style: combinedStyles(),
119
- }));
120
-
121
- return {
122
- visuallyHiddenProps,
123
- };
124
- }
1
+ /**
2
+ * createVisuallyHidden hook for solidaria
3
+ *
4
+ * Provides styles and props to visually hide content while keeping it
5
+ * accessible to screen readers.
6
+ *
7
+ * Port of react-aria's useVisuallyHidden.
8
+ */
9
+
10
+ import { type Accessor, type JSX, createMemo, createSignal } from 'solid-js';
11
+ import { createFocusWithin } from '../interactions/createFocusWithin';
12
+ import { access, type MaybeAccessor } from '../utils';
13
+ import { mergeProps } from '../utils/mergeProps';
14
+
15
+ // ============================================
16
+ // TYPES
17
+ // ============================================
18
+
19
+ export interface AriaVisuallyHiddenProps {
20
+ /** Inline styles to merge with the visually hidden styles. */
21
+ style?: JSX.CSSProperties;
22
+ /** Whether the element should become visible when focused (e.g., skip links). */
23
+ isFocusable?: boolean;
24
+ }
25
+
26
+ export interface VisuallyHiddenAria {
27
+ /** Props to spread on the visually hidden element. */
28
+ visuallyHiddenProps: Accessor<JSX.HTMLAttributes<HTMLElement>>;
29
+ }
30
+
31
+ // ============================================
32
+ // STYLES
33
+ // ============================================
34
+
35
+ /**
36
+ * CSS styles that visually hide an element while keeping it accessible.
37
+ * These styles ensure the element is read by screen readers but not visible on screen.
38
+ */
39
+ export const visuallyHiddenStyles: JSX.CSSProperties = {
40
+ border: '0',
41
+ clip: 'rect(0 0 0 0)',
42
+ 'clip-path': 'inset(50%)',
43
+ height: '1px',
44
+ margin: '-1px',
45
+ overflow: 'hidden',
46
+ padding: '0',
47
+ position: 'absolute',
48
+ width: '1px',
49
+ 'white-space': 'nowrap',
50
+ };
51
+
52
+ // ============================================
53
+ // HOOK
54
+ // ============================================
55
+
56
+ /**
57
+ * Provides props for an element that hides its children visually
58
+ * but keeps content visible to assistive technology.
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * function SkipLink() {
63
+ * let ref: HTMLAnchorElement | undefined;
64
+ * const { visuallyHiddenProps } = createVisuallyHidden({ isFocusable: true });
65
+ *
66
+ * return (
67
+ * <a
68
+ * ref={ref}
69
+ * href="#main-content"
70
+ * {...visuallyHiddenProps()}
71
+ * >
72
+ * Skip to main content
73
+ * </a>
74
+ * );
75
+ * }
76
+ *
77
+ * // For content that should always be hidden
78
+ * function ScreenReaderOnly(props: ParentProps) {
79
+ * const { visuallyHiddenProps } = createVisuallyHidden();
80
+ *
81
+ * return (
82
+ * <span {...visuallyHiddenProps()}>
83
+ * {props.children}
84
+ * </span>
85
+ * );
86
+ * }
87
+ * ```
88
+ */
89
+ export function createVisuallyHidden(
90
+ props: MaybeAccessor<AriaVisuallyHiddenProps> = {}
91
+ ): VisuallyHiddenAria {
92
+ const [isFocused, setIsFocused] = createSignal(false);
93
+
94
+ const isFocusable = () => access(props).isFocusable ?? false;
95
+ const style = () => access(props).style;
96
+
97
+ // Track focus within for focusable visually hidden elements
98
+ const { focusWithinProps } = createFocusWithin({
99
+ get isDisabled() {
100
+ return !isFocusable();
101
+ },
102
+ onFocusWithinChange: (val: boolean) => setIsFocused(val),
103
+ });
104
+
105
+ // Compute combined styles
106
+ const combinedStyles = createMemo<JSX.CSSProperties | undefined>(() => {
107
+ if (isFocused()) {
108
+ // If focused, show the element (for skip links, etc.)
109
+ return style();
110
+ } else if (style()) {
111
+ return { ...visuallyHiddenStyles, ...style() };
112
+ } else {
113
+ return visuallyHiddenStyles;
114
+ }
115
+ });
116
+
117
+ const visuallyHiddenProps = createMemo<JSX.HTMLAttributes<HTMLElement>>(() => ({
118
+ ...mergeProps(
119
+ focusWithinProps as unknown as Record<string, unknown>,
120
+ isFocusable()
121
+ ? {
122
+ onFocusIn: () => setIsFocused(true),
123
+ onFocusOut: (e: FocusEvent) => {
124
+ const currentTarget = e.currentTarget as Element | null;
125
+ const relatedTarget = e.relatedTarget as Element | null;
126
+ if (currentTarget && !currentTarget.contains(relatedTarget)) {
127
+ setIsFocused(false);
128
+ }
129
+ },
130
+ }
131
+ : {},
132
+ { style: combinedStyles() }
133
+ ),
134
+ }));
135
+
136
+ return {
137
+ visuallyHiddenProps,
138
+ };
139
+ }
@@ -1,6 +1,6 @@
1
- export {
2
- createVisuallyHidden,
3
- visuallyHiddenStyles,
4
- type AriaVisuallyHiddenProps,
5
- type VisuallyHiddenAria,
6
- } from './createVisuallyHidden';
1
+ export {
2
+ createVisuallyHidden,
3
+ visuallyHiddenStyles,
4
+ type AriaVisuallyHiddenProps,
5
+ type VisuallyHiddenAria,
6
+ } from './createVisuallyHidden';