@proyecto-viviana/solidaria 0.2.2 → 0.2.3

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 (210) hide show
  1. package/dist/autocomplete/createAutocomplete.d.ts +2 -2
  2. package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
  3. package/dist/index.js +233 -234
  4. package/dist/index.js.map +2 -2
  5. package/dist/index.ssr.js +233 -234
  6. package/dist/index.ssr.js.map +2 -2
  7. package/dist/interactions/PressEvent.d.ts +13 -10
  8. package/dist/interactions/PressEvent.d.ts.map +1 -1
  9. package/dist/interactions/createPress.d.ts.map +1 -1
  10. package/dist/interactions/index.d.ts +1 -1
  11. package/dist/interactions/index.d.ts.map +1 -1
  12. package/dist/select/createHiddenSelect.d.ts.map +1 -1
  13. package/dist/toolbar/createToolbar.d.ts.map +1 -1
  14. package/dist/tooltip/createTooltipTrigger.d.ts.map +1 -1
  15. package/package.json +9 -7
  16. package/src/autocomplete/createAutocomplete.ts +341 -0
  17. package/src/autocomplete/index.ts +9 -0
  18. package/src/breadcrumbs/createBreadcrumbs.ts +196 -0
  19. package/src/breadcrumbs/index.ts +8 -0
  20. package/src/button/createButton.ts +142 -0
  21. package/src/button/createToggleButton.ts +101 -0
  22. package/src/button/index.ts +4 -0
  23. package/src/button/types.ts +78 -0
  24. package/src/calendar/createCalendar.ts +138 -0
  25. package/src/calendar/createCalendarCell.ts +187 -0
  26. package/src/calendar/createCalendarGrid.ts +140 -0
  27. package/src/calendar/createRangeCalendar.ts +136 -0
  28. package/src/calendar/createRangeCalendarCell.ts +186 -0
  29. package/src/calendar/index.ts +34 -0
  30. package/src/checkbox/createCheckbox.ts +135 -0
  31. package/src/checkbox/createCheckboxGroup.ts +137 -0
  32. package/src/checkbox/createCheckboxGroupItem.ts +117 -0
  33. package/src/checkbox/createCheckboxGroupState.ts +193 -0
  34. package/src/checkbox/index.ts +13 -0
  35. package/src/color/createColorArea.ts +314 -0
  36. package/src/color/createColorField.ts +137 -0
  37. package/src/color/createColorSlider.ts +197 -0
  38. package/src/color/createColorSwatch.ts +40 -0
  39. package/src/color/createColorWheel.ts +208 -0
  40. package/src/color/index.ts +24 -0
  41. package/src/color/types.ts +116 -0
  42. package/src/combobox/createComboBox.ts +647 -0
  43. package/src/combobox/index.ts +6 -0
  44. package/src/combobox/intl/en-US.json +7 -0
  45. package/src/combobox/intl/es-ES.json +7 -0
  46. package/src/combobox/intl/index.ts +23 -0
  47. package/src/datepicker/createDateField.ts +154 -0
  48. package/src/datepicker/createDatePicker.ts +206 -0
  49. package/src/datepicker/createDateSegment.ts +229 -0
  50. package/src/datepicker/createTimeField.ts +154 -0
  51. package/src/datepicker/index.ts +28 -0
  52. package/src/dialog/createDialog.ts +120 -0
  53. package/src/dialog/index.ts +2 -0
  54. package/src/dialog/types.ts +19 -0
  55. package/src/disclosure/createDisclosure.ts +131 -0
  56. package/src/disclosure/createDisclosureGroup.ts +62 -0
  57. package/src/disclosure/index.ts +11 -0
  58. package/src/dnd/createDrag.ts +209 -0
  59. package/src/dnd/createDraggableCollection.ts +63 -0
  60. package/src/dnd/createDraggableItem.ts +243 -0
  61. package/src/dnd/createDrop.ts +321 -0
  62. package/src/dnd/createDroppableCollection.ts +293 -0
  63. package/src/dnd/createDroppableItem.ts +213 -0
  64. package/src/dnd/index.ts +47 -0
  65. package/src/dnd/types.ts +89 -0
  66. package/src/dnd/utils.ts +294 -0
  67. package/src/focus/FocusScope.tsx +408 -0
  68. package/src/focus/createAutoFocus.ts +321 -0
  69. package/src/focus/createFocusRestore.ts +313 -0
  70. package/src/focus/createVirtualFocus.ts +396 -0
  71. package/src/focus/index.ts +35 -0
  72. package/src/form/createFormReset.ts +51 -0
  73. package/src/form/createFormValidation.ts +224 -0
  74. package/src/form/index.ts +11 -0
  75. package/src/grid/GridKeyboardDelegate.ts +429 -0
  76. package/src/grid/createGrid.ts +261 -0
  77. package/src/grid/createGridCell.ts +182 -0
  78. package/src/grid/createGridRow.ts +153 -0
  79. package/src/grid/index.ts +18 -0
  80. package/src/grid/types.ts +133 -0
  81. package/src/gridlist/createGridList.ts +185 -0
  82. package/src/gridlist/createGridListItem.ts +180 -0
  83. package/src/gridlist/createGridListSelectionCheckbox.ts +59 -0
  84. package/src/gridlist/index.ts +16 -0
  85. package/src/gridlist/types.ts +81 -0
  86. package/src/i18n/NumberFormatter.ts +266 -0
  87. package/src/i18n/createCollator.ts +79 -0
  88. package/src/i18n/createDateFormatter.ts +83 -0
  89. package/src/i18n/createFilter.ts +131 -0
  90. package/src/i18n/createNumberFormatter.ts +52 -0
  91. package/src/i18n/createStringFormatter.ts +87 -0
  92. package/src/i18n/index.ts +40 -0
  93. package/src/i18n/locale.tsx +188 -0
  94. package/src/i18n/utils.ts +99 -0
  95. package/src/index.ts +670 -0
  96. package/src/interactions/FocusableProvider.tsx +44 -0
  97. package/src/interactions/PressEvent.ts +126 -0
  98. package/src/interactions/createFocus.ts +163 -0
  99. package/src/interactions/createFocusRing.ts +89 -0
  100. package/src/interactions/createFocusWithin.ts +206 -0
  101. package/src/interactions/createFocusable.ts +168 -0
  102. package/src/interactions/createHover.ts +254 -0
  103. package/src/interactions/createInteractionModality.ts +424 -0
  104. package/src/interactions/createKeyboard.ts +82 -0
  105. package/src/interactions/createLongPress.ts +174 -0
  106. package/src/interactions/createMove.ts +289 -0
  107. package/src/interactions/createPress.ts +834 -0
  108. package/src/interactions/index.ts +78 -0
  109. package/src/label/createField.ts +145 -0
  110. package/src/label/createLabel.ts +117 -0
  111. package/src/label/createLabels.ts +50 -0
  112. package/src/label/index.ts +19 -0
  113. package/src/landmark/createLandmark.ts +377 -0
  114. package/src/landmark/index.ts +8 -0
  115. package/src/link/createLink.ts +182 -0
  116. package/src/link/index.ts +1 -0
  117. package/src/listbox/createListBox.ts +269 -0
  118. package/src/listbox/createOption.ts +151 -0
  119. package/src/listbox/index.ts +12 -0
  120. package/src/live-announcer/announce.ts +322 -0
  121. package/src/live-announcer/index.ts +9 -0
  122. package/src/menu/createMenu.ts +396 -0
  123. package/src/menu/createMenuItem.ts +149 -0
  124. package/src/menu/createMenuTrigger.ts +88 -0
  125. package/src/menu/index.ts +18 -0
  126. package/src/meter/createMeter.ts +75 -0
  127. package/src/meter/index.ts +1 -0
  128. package/src/numberfield/createNumberField.ts +268 -0
  129. package/src/numberfield/index.ts +5 -0
  130. package/src/overlays/ariaHideOutside.ts +219 -0
  131. package/src/overlays/createInteractOutside.ts +149 -0
  132. package/src/overlays/createModal.tsx +202 -0
  133. package/src/overlays/createOverlay.ts +155 -0
  134. package/src/overlays/createOverlayTrigger.ts +85 -0
  135. package/src/overlays/createPreventScroll.ts +266 -0
  136. package/src/overlays/index.ts +44 -0
  137. package/src/popover/calculatePosition.ts +766 -0
  138. package/src/popover/createOverlayPosition.ts +356 -0
  139. package/src/popover/createPopover.ts +170 -0
  140. package/src/popover/index.ts +24 -0
  141. package/src/progress/createProgressBar.ts +128 -0
  142. package/src/progress/index.ts +5 -0
  143. package/src/radio/createRadio.ts +287 -0
  144. package/src/radio/createRadioGroup.ts +189 -0
  145. package/src/radio/createRadioGroupState.ts +201 -0
  146. package/src/radio/index.ts +23 -0
  147. package/src/searchfield/createSearchField.ts +186 -0
  148. package/src/searchfield/index.ts +2 -0
  149. package/src/select/createHiddenSelect.tsx +236 -0
  150. package/src/select/createSelect.ts +395 -0
  151. package/src/select/index.ts +14 -0
  152. package/src/selection/createTypeSelect.ts +201 -0
  153. package/src/selection/index.ts +6 -0
  154. package/src/separator/createSeparator.ts +82 -0
  155. package/src/separator/index.ts +6 -0
  156. package/src/slider/createSlider.ts +349 -0
  157. package/src/slider/index.ts +2 -0
  158. package/src/ssr/index.tsx +370 -0
  159. package/src/switch/createSwitch.ts +70 -0
  160. package/src/switch/index.ts +1 -0
  161. package/src/table/createTable.ts +526 -0
  162. package/src/table/createTableCell.ts +147 -0
  163. package/src/table/createTableColumnHeader.ts +115 -0
  164. package/src/table/createTableHeaderRow.ts +40 -0
  165. package/src/table/createTableRow.ts +155 -0
  166. package/src/table/createTableRowGroup.ts +32 -0
  167. package/src/table/createTableSelectAllCheckbox.ts +73 -0
  168. package/src/table/createTableSelectionCheckbox.ts +59 -0
  169. package/src/table/index.ts +30 -0
  170. package/src/table/types.ts +165 -0
  171. package/src/tabs/createTabs.ts +472 -0
  172. package/src/tabs/index.ts +14 -0
  173. package/src/tag/createTag.ts +194 -0
  174. package/src/tag/createTagGroup.ts +154 -0
  175. package/src/tag/index.ts +12 -0
  176. package/src/textfield/createTextField.ts +198 -0
  177. package/src/textfield/index.ts +5 -0
  178. package/src/toast/createToast.ts +118 -0
  179. package/src/toast/createToastRegion.ts +100 -0
  180. package/src/toast/index.ts +11 -0
  181. package/src/toggle/createToggle.ts +223 -0
  182. package/src/toggle/createToggleState.ts +94 -0
  183. package/src/toggle/index.ts +7 -0
  184. package/src/toolbar/createToolbar.ts +369 -0
  185. package/src/toolbar/index.ts +6 -0
  186. package/src/tooltip/createTooltip.ts +79 -0
  187. package/src/tooltip/createTooltipTrigger.ts +222 -0
  188. package/src/tooltip/index.ts +6 -0
  189. package/src/tree/createTree.ts +246 -0
  190. package/src/tree/createTreeItem.ts +233 -0
  191. package/src/tree/createTreeSelectionCheckbox.ts +68 -0
  192. package/src/tree/index.ts +16 -0
  193. package/src/tree/types.ts +87 -0
  194. package/src/utils/createDescription.ts +137 -0
  195. package/src/utils/dom.ts +327 -0
  196. package/src/utils/env.ts +54 -0
  197. package/src/utils/events.ts +106 -0
  198. package/src/utils/filterDOMProps.ts +116 -0
  199. package/src/utils/focus.ts +151 -0
  200. package/src/utils/geometry.ts +115 -0
  201. package/src/utils/globalListeners.ts +142 -0
  202. package/src/utils/index.ts +80 -0
  203. package/src/utils/mergeProps.ts +52 -0
  204. package/src/utils/platform.ts +52 -0
  205. package/src/utils/reactivity.ts +36 -0
  206. package/src/utils/textSelection.ts +114 -0
  207. package/src/visually-hidden/createVisuallyHidden.ts +124 -0
  208. package/src/visually-hidden/index.ts +6 -0
  209. package/dist/index.jsx +0 -15845
  210. package/dist/index.jsx.map +0 -7
@@ -0,0 +1,147 @@
1
+ /**
2
+ * createTableCell - Provides accessibility for a table cell.
3
+ * Based on @react-aria/table/useTableCell.
4
+ */
5
+
6
+ import { createMemo, createSignal, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import type { TableState, TableCollection } from '@proyecto-viviana/solid-stately';
9
+ import type { AriaTableCellProps, TableCellAria } from './types';
10
+ import { getTableData } from './createTable';
11
+
12
+ /**
13
+ * Creates accessibility props for a table cell.
14
+ */
15
+ export function createTableCell<T extends object>(
16
+ props: Accessor<AriaTableCellProps>,
17
+ state: Accessor<TableState<T, TableCollection<T>>>,
18
+ _ref: Accessor<HTMLTableCellElement | null>
19
+ ): TableCellAria {
20
+ const [isPressed, setIsPressed] = createSignal(false);
21
+
22
+ const isDisabled = createMemo(() => {
23
+ const s = state();
24
+ const p = props();
25
+ // Check if parent row is disabled
26
+ const node = p.node;
27
+ if (node.parentKey != null) {
28
+ return s.isDisabled(node.parentKey);
29
+ }
30
+ return false;
31
+ });
32
+
33
+ const isFocused = createMemo(() => {
34
+ const s = state();
35
+ const p = props();
36
+ return s.focusedKey === p.node.key;
37
+ });
38
+
39
+ // Handle click for cell actions
40
+ const onClick = () => {
41
+ const s = state();
42
+ const p = props();
43
+
44
+ if (isDisabled()) return;
45
+
46
+ // Get table metadata for actions
47
+ const tableData = getTableData(s);
48
+ const onCellAction = tableData?.actions.onCellAction;
49
+
50
+ // Call cell action handler
51
+ if (onCellAction) {
52
+ onCellAction(p.node.key);
53
+ }
54
+
55
+ if (p.onAction) {
56
+ p.onAction();
57
+ }
58
+ };
59
+
60
+ const onKeyDown = (e: KeyboardEvent) => {
61
+ const s = state();
62
+ const p = props();
63
+
64
+ if (isDisabled()) return;
65
+
66
+ // Enter triggers cell action
67
+ if (e.key === 'Enter') {
68
+ const tableData = getTableData(s);
69
+ const onCellAction = tableData?.actions.onCellAction;
70
+
71
+ if (onCellAction || p.onAction) {
72
+ e.preventDefault();
73
+
74
+ if (onCellAction) {
75
+ onCellAction(p.node.key);
76
+ }
77
+
78
+ if (p.onAction) {
79
+ p.onAction();
80
+ }
81
+ }
82
+ }
83
+ };
84
+
85
+ const onFocus = () => {
86
+ const s = state();
87
+ const p = props();
88
+ s.setFocusedKey(p.node.key);
89
+ };
90
+
91
+ const onPointerDown = () => {
92
+ setIsPressed(true);
93
+ };
94
+
95
+ const onPointerUp = () => {
96
+ setIsPressed(false);
97
+ };
98
+
99
+ const gridCellProps = createMemo(() => {
100
+ const s = state();
101
+ const p = props();
102
+ const node = p.node;
103
+ const tableData = getTableData(s);
104
+
105
+ // Determine the role based on node type
106
+ let role: string = 'gridcell';
107
+ if (node.type === 'rowheader') {
108
+ role = 'rowheader';
109
+ }
110
+
111
+ const baseProps: Record<string, unknown> = {
112
+ role,
113
+ id: tableData && node.parentKey != null
114
+ ? `${tableData.tableId}-${node.parentKey}-${node.key}`
115
+ : undefined,
116
+ 'aria-disabled': isDisabled() || undefined,
117
+ tabIndex: isFocused() ? 0 : -1,
118
+ onClick,
119
+ onKeyDown,
120
+ onFocus,
121
+ onPointerDown,
122
+ onPointerUp,
123
+ };
124
+
125
+ // Add aria-colindex for virtualized tables
126
+ if (p.isVirtualized && node.column != null) {
127
+ baseProps['aria-colindex'] = node.column + 1; // 1-based
128
+ }
129
+
130
+ // Add colspan if present
131
+ if (node.colspan != null && node.colspan > 1) {
132
+ baseProps['aria-colspan'] = node.colspan;
133
+ baseProps.colSpan = node.colspan;
134
+ }
135
+
136
+ return baseProps as JSX.HTMLAttributes<HTMLTableCellElement>;
137
+ });
138
+
139
+ return {
140
+ get gridCellProps() {
141
+ return gridCellProps();
142
+ },
143
+ get isPressed() {
144
+ return isPressed();
145
+ },
146
+ };
147
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * createTableColumnHeader - Provides accessibility for a table column header.
3
+ * Based on @react-aria/table/useTableColumnHeader.
4
+ */
5
+
6
+ import { createMemo, createSignal, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import type { TableState, TableCollection } from '@proyecto-viviana/solid-stately';
9
+ import type { AriaTableColumnHeaderProps, TableColumnHeaderAria } from './types';
10
+ import { getTableData } from './createTable';
11
+
12
+ /**
13
+ * Creates accessibility props for a table column header.
14
+ */
15
+ export function createTableColumnHeader<T extends object>(
16
+ props: Accessor<AriaTableColumnHeaderProps>,
17
+ state: Accessor<TableState<T, TableCollection<T>>>,
18
+ _ref: Accessor<HTMLTableCellElement | null>
19
+ ): TableColumnHeaderAria {
20
+ const [_isPressed, setIsPressed] = createSignal(false);
21
+
22
+ const isFocused = createMemo(() => {
23
+ const s = state();
24
+ const p = props();
25
+ return s.focusedKey === p.node.key;
26
+ });
27
+
28
+ // Handle click for sorting
29
+ const onClick = () => {
30
+ const s = state();
31
+ const p = props();
32
+
33
+ if (p.allowsSorting) {
34
+ s.sort(p.node.key);
35
+ }
36
+ };
37
+
38
+ const onKeyDown = (e: KeyboardEvent) => {
39
+ const p = props();
40
+ const s = state();
41
+
42
+ if (p.allowsSorting && (e.key === 'Enter' || e.key === ' ')) {
43
+ e.preventDefault();
44
+ s.sort(p.node.key);
45
+ }
46
+ };
47
+
48
+ const onFocus = () => {
49
+ const s = state();
50
+ const p = props();
51
+ s.setFocusedKey(p.node.key);
52
+ };
53
+
54
+ const onPointerDown = () => {
55
+ setIsPressed(true);
56
+ };
57
+
58
+ const onPointerUp = () => {
59
+ setIsPressed(false);
60
+ };
61
+
62
+ const columnHeaderProps = createMemo(() => {
63
+ const s = state();
64
+ const p = props();
65
+ const node = p.node;
66
+ const tableData = getTableData(s);
67
+
68
+ // Determine sort state
69
+ let ariaSort: 'none' | 'ascending' | 'descending' | undefined = undefined;
70
+ if (p.allowsSorting) {
71
+ const sortDescriptor = s.sortDescriptor;
72
+ if (sortDescriptor?.column === node.key) {
73
+ ariaSort = sortDescriptor.direction;
74
+ } else {
75
+ ariaSort = 'none';
76
+ }
77
+ }
78
+
79
+ const baseProps: Record<string, unknown> = {
80
+ role: 'columnheader',
81
+ id: tableData ? `${tableData.tableId}-${node.key}` : undefined,
82
+ 'aria-sort': ariaSort,
83
+ tabIndex: isFocused() ? 0 : -1,
84
+ onFocus,
85
+ };
86
+
87
+ // Add click handler if sortable
88
+ if (p.allowsSorting) {
89
+ baseProps.onClick = onClick;
90
+ baseProps.onKeyDown = onKeyDown;
91
+ baseProps.onPointerDown = onPointerDown;
92
+ baseProps.onPointerUp = onPointerUp;
93
+ baseProps.style = { cursor: 'pointer' };
94
+ }
95
+
96
+ // Add aria-colindex for virtualized tables
97
+ if (p.isVirtualized && node.column != null) {
98
+ baseProps['aria-colindex'] = node.column + 1; // 1-based
99
+ }
100
+
101
+ // Add colspan if present
102
+ if (node.colspan != null && node.colspan > 1) {
103
+ baseProps['aria-colspan'] = node.colspan;
104
+ baseProps.colSpan = node.colspan;
105
+ }
106
+
107
+ return baseProps as JSX.HTMLAttributes<HTMLTableCellElement>;
108
+ });
109
+
110
+ return {
111
+ get columnHeaderProps() {
112
+ return columnHeaderProps();
113
+ },
114
+ };
115
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * createTableHeaderRow - Provides accessibility for a table header row.
3
+ * Based on @react-aria/table/useTableHeaderRow.
4
+ */
5
+
6
+ import { createMemo, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import type { TableState, TableCollection } from '@proyecto-viviana/solid-stately';
9
+ import type { AriaTableHeaderRowProps, TableHeaderRowAria } from './types';
10
+
11
+ /**
12
+ * Creates accessibility props for a table header row.
13
+ */
14
+ export function createTableHeaderRow<T extends object>(
15
+ props: Accessor<AriaTableHeaderRowProps>,
16
+ _state: Accessor<TableState<T, TableCollection<T>>>,
17
+ _ref: Accessor<HTMLTableRowElement | null>
18
+ ): TableHeaderRowAria {
19
+ const rowProps = createMemo(() => {
20
+ const p = props();
21
+ const node = p.node;
22
+
23
+ const baseProps: Record<string, unknown> = {
24
+ role: 'row',
25
+ };
26
+
27
+ // Add aria-rowindex for virtualized tables
28
+ if (p.isVirtualized && node.rowIndex != null) {
29
+ baseProps['aria-rowindex'] = node.rowIndex + 1; // 1-based
30
+ }
31
+
32
+ return baseProps as JSX.HTMLAttributes<HTMLTableRowElement>;
33
+ });
34
+
35
+ return {
36
+ get rowProps() {
37
+ return rowProps();
38
+ },
39
+ };
40
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * createTableRow - Provides accessibility for a table row.
3
+ * Based on @react-aria/table/useTableRow.
4
+ */
5
+
6
+ import { createMemo, createSignal, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import type { TableState, TableCollection } from '@proyecto-viviana/solid-stately';
9
+ import type { AriaTableRowProps, TableRowAria } from './types';
10
+ import { getTableData } from './createTable';
11
+
12
+ /**
13
+ * Creates accessibility props for a table row.
14
+ */
15
+ export function createTableRow<T extends object>(
16
+ props: Accessor<AriaTableRowProps>,
17
+ state: Accessor<TableState<T, TableCollection<T>>>,
18
+ _ref: Accessor<HTMLTableRowElement | null>
19
+ ): TableRowAria {
20
+ const [isPressed, setIsPressed] = createSignal(false);
21
+
22
+ const isSelected = createMemo(() => {
23
+ const s = state();
24
+ const p = props();
25
+ return s.isSelected(p.node.key);
26
+ });
27
+
28
+ const isDisabled = createMemo(() => {
29
+ const s = state();
30
+ const p = props();
31
+ return s.isDisabled(p.node.key);
32
+ });
33
+
34
+ const isFocused = createMemo(() => {
35
+ const s = state();
36
+ const p = props();
37
+ return s.focusedKey === p.node.key;
38
+ });
39
+
40
+ // Handle click/press for selection
41
+ const onClick = (e: MouseEvent) => {
42
+ const s = state();
43
+ const p = props();
44
+
45
+ if (isDisabled()) return;
46
+
47
+ // Get table metadata for actions
48
+ const tableData = getTableData(s);
49
+ const onRowAction = tableData?.actions.onRowAction;
50
+
51
+ // Handle selection
52
+ if (s.selectionMode !== 'none') {
53
+ if (e.shiftKey && s.selectionMode === 'multiple') {
54
+ s.extendSelection(p.node.key);
55
+ } else if (e.ctrlKey || e.metaKey) {
56
+ s.toggleSelection(p.node.key);
57
+ } else {
58
+ // Replace selection
59
+ s.replaceSelection(p.node.key);
60
+ }
61
+ }
62
+
63
+ // Call action handler
64
+ if (onRowAction) {
65
+ onRowAction(p.node.key);
66
+ }
67
+
68
+ if (p.onAction) {
69
+ p.onAction();
70
+ }
71
+ };
72
+
73
+ const onKeyDown = (e: KeyboardEvent) => {
74
+ const s = state();
75
+ const p = props();
76
+
77
+ if (isDisabled()) return;
78
+
79
+ if (e.key === 'Enter' || e.key === ' ') {
80
+ e.preventDefault();
81
+
82
+ // Get table metadata for actions
83
+ const tableData = getTableData(s);
84
+ const onRowAction = tableData?.actions.onRowAction;
85
+
86
+ // Handle selection
87
+ if (s.selectionMode !== 'none') {
88
+ s.toggleSelection(p.node.key);
89
+ }
90
+
91
+ // Call action handler
92
+ if (onRowAction) {
93
+ onRowAction(p.node.key);
94
+ }
95
+
96
+ if (p.onAction) {
97
+ p.onAction();
98
+ }
99
+ }
100
+ };
101
+
102
+ const onFocus = () => {
103
+ const s = state();
104
+ const p = props();
105
+ s.setFocusedKey(p.node.key);
106
+ };
107
+
108
+ const onPointerDown = () => {
109
+ setIsPressed(true);
110
+ };
111
+
112
+ const onPointerUp = () => {
113
+ setIsPressed(false);
114
+ };
115
+
116
+ const rowProps = createMemo(() => {
117
+ const s = state();
118
+ const p = props();
119
+ const node = p.node;
120
+
121
+ const baseProps: Record<string, unknown> = {
122
+ role: 'row',
123
+ 'aria-selected': s.selectionMode !== 'none' ? isSelected() : undefined,
124
+ 'aria-disabled': isDisabled() || undefined,
125
+ tabIndex: isFocused() ? 0 : -1,
126
+ onClick,
127
+ onKeyDown,
128
+ onFocus,
129
+ onPointerDown,
130
+ onPointerUp,
131
+ };
132
+
133
+ // Add aria-rowindex for virtualized tables
134
+ if (p.isVirtualized && node.rowIndex != null) {
135
+ baseProps['aria-rowindex'] = node.rowIndex + 1; // 1-based
136
+ }
137
+
138
+ return baseProps as JSX.HTMLAttributes<HTMLTableRowElement>;
139
+ });
140
+
141
+ return {
142
+ get rowProps() {
143
+ return rowProps();
144
+ },
145
+ get isSelected() {
146
+ return isSelected();
147
+ },
148
+ get isDisabled() {
149
+ return isDisabled();
150
+ },
151
+ get isPressed() {
152
+ return isPressed();
153
+ },
154
+ };
155
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * createTableRowGroup - Provides accessibility for a table row group.
3
+ * Based on @react-aria/grid/useTableRowGroup.
4
+ */
5
+
6
+ import { createMemo, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import type { AriaTableRowGroupProps, TableRowGroupAria } from './types';
9
+
10
+ /**
11
+ * Creates accessibility props for a table row group (thead, tbody, tfoot).
12
+ */
13
+ export function createTableRowGroup(
14
+ props: Accessor<AriaTableRowGroupProps>
15
+ ): TableRowGroupAria {
16
+ const rowGroupProps = createMemo(() => {
17
+ // Access props for reactivity tracking, even though not currently used
18
+ void props();
19
+
20
+ const baseProps: Record<string, unknown> = {
21
+ role: 'rowgroup',
22
+ };
23
+
24
+ return baseProps as JSX.HTMLAttributes<HTMLTableSectionElement>;
25
+ });
26
+
27
+ return {
28
+ get rowGroupProps() {
29
+ return rowGroupProps();
30
+ },
31
+ };
32
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * createTableSelectAllCheckbox - Provides accessibility for a table select-all checkbox.
3
+ * Based on @react-aria/table/useTableSelectAllCheckbox.
4
+ */
5
+
6
+ import { createMemo, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import type { TableState, TableCollection } from '@proyecto-viviana/solid-stately';
9
+ import type { TableSelectAllCheckboxAria } from './types';
10
+
11
+ /**
12
+ * Creates accessibility props for a table select-all checkbox.
13
+ */
14
+ export function createTableSelectAllCheckbox<T extends object>(
15
+ state: Accessor<TableState<T, TableCollection<T>>>
16
+ ): TableSelectAllCheckboxAria {
17
+ const isSelectAll = createMemo(() => {
18
+ const s = state();
19
+ return s.selectedKeys === 'all';
20
+ });
21
+
22
+ const isEmpty = createMemo(() => {
23
+ const s = state();
24
+ return s.collection.size === 0;
25
+ });
26
+
27
+ const isIndeterminate = createMemo(() => {
28
+ const s = state();
29
+ const selectedKeys = s.selectedKeys;
30
+ if (selectedKeys === 'all') return false;
31
+ if (selectedKeys.size === 0) return false;
32
+ return selectedKeys.size < s.collection.size;
33
+ });
34
+
35
+ const isDisabled = createMemo(() => {
36
+ const s = state();
37
+ return s.selectionMode !== 'multiple' || isEmpty();
38
+ });
39
+
40
+ const onChange = () => {
41
+ const s = state();
42
+ if (!isDisabled()) {
43
+ s.toggleSelectAll();
44
+ }
45
+ };
46
+
47
+ const checkboxProps = createMemo(() => {
48
+ const s = state();
49
+
50
+ const baseProps: Record<string, unknown> = {
51
+ type: 'checkbox',
52
+ checked: isSelectAll(),
53
+ disabled: isDisabled(),
54
+ onChange,
55
+ 'aria-label': s.selectionMode === 'single' ? 'Select' : 'Select all',
56
+ };
57
+
58
+ // Handle indeterminate state
59
+ // Note: indeterminate is not a standard HTML attribute, it must be set via JavaScript
60
+ // The component using this should handle this separately
61
+ if (isIndeterminate()) {
62
+ baseProps['data-indeterminate'] = 'true';
63
+ }
64
+
65
+ return baseProps as JSX.InputHTMLAttributes<HTMLInputElement>;
66
+ });
67
+
68
+ return {
69
+ get checkboxProps() {
70
+ return checkboxProps();
71
+ },
72
+ };
73
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * createTableSelectionCheckbox - Provides accessibility for a table row selection checkbox.
3
+ * Based on @react-aria/table/useTableSelectionCheckbox.
4
+ */
5
+
6
+ import { createMemo, type Accessor } from 'solid-js';
7
+ import type { JSX } from 'solid-js';
8
+ import { createId } from '@proyecto-viviana/solid-stately';
9
+ import type { TableState, TableCollection } from '@proyecto-viviana/solid-stately';
10
+ import type { AriaTableSelectionCheckboxProps, TableSelectionCheckboxAria } from './types';
11
+
12
+ /**
13
+ * Creates accessibility props for a table row selection checkbox.
14
+ */
15
+ export function createTableSelectionCheckbox<T extends object>(
16
+ props: Accessor<AriaTableSelectionCheckboxProps>,
17
+ state: Accessor<TableState<T, TableCollection<T>>>
18
+ ): TableSelectionCheckboxAria {
19
+ const checkboxId = createId();
20
+
21
+ const isSelected = createMemo(() => {
22
+ const s = state();
23
+ const p = props();
24
+ return s.isSelected(p.key);
25
+ });
26
+
27
+ const isDisabled = createMemo(() => {
28
+ const s = state();
29
+ const p = props();
30
+ return s.isDisabled(p.key);
31
+ });
32
+
33
+ const onChange = () => {
34
+ const s = state();
35
+ const p = props();
36
+ if (!isDisabled()) {
37
+ s.toggleSelection(p.key);
38
+ }
39
+ };
40
+
41
+ const checkboxProps = createMemo(() => {
42
+ const baseProps: Record<string, unknown> = {
43
+ id: checkboxId,
44
+ type: 'checkbox',
45
+ checked: isSelected(),
46
+ disabled: isDisabled(),
47
+ onChange,
48
+ 'aria-label': 'Select',
49
+ };
50
+
51
+ return baseProps as JSX.InputHTMLAttributes<HTMLInputElement>;
52
+ });
53
+
54
+ return {
55
+ get checkboxProps() {
56
+ return checkboxProps();
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Table accessibility primitives for Table components.
3
+ * Based on @react-aria/table.
4
+ */
5
+
6
+ export { createTable, getTableData } from './createTable';
7
+ export { createTableHeaderRow } from './createTableHeaderRow';
8
+ export { createTableColumnHeader } from './createTableColumnHeader';
9
+ export { createTableRow } from './createTableRow';
10
+ export { createTableCell } from './createTableCell';
11
+ export { createTableRowGroup } from './createTableRowGroup';
12
+ export { createTableSelectionCheckbox } from './createTableSelectionCheckbox';
13
+ export { createTableSelectAllCheckbox } from './createTableSelectAllCheckbox';
14
+ export type {
15
+ AriaTableProps,
16
+ TableAria,
17
+ AriaTableHeaderRowProps,
18
+ TableHeaderRowAria,
19
+ AriaTableColumnHeaderProps,
20
+ TableColumnHeaderAria,
21
+ AriaTableRowProps,
22
+ TableRowAria,
23
+ AriaTableCellProps,
24
+ TableCellAria,
25
+ AriaTableRowGroupProps,
26
+ TableRowGroupAria,
27
+ AriaTableSelectionCheckboxProps,
28
+ TableSelectionCheckboxAria,
29
+ TableSelectAllCheckboxAria,
30
+ } from './types';