@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.
- package/dist/autocomplete/createAutocomplete.d.ts +2 -2
- package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
- package/dist/index.js +233 -234
- package/dist/index.js.map +2 -2
- package/dist/index.ssr.js +233 -234
- package/dist/index.ssr.js.map +2 -2
- package/dist/interactions/PressEvent.d.ts +13 -10
- package/dist/interactions/PressEvent.d.ts.map +1 -1
- package/dist/interactions/createPress.d.ts.map +1 -1
- package/dist/interactions/index.d.ts +1 -1
- package/dist/interactions/index.d.ts.map +1 -1
- package/dist/select/createHiddenSelect.d.ts.map +1 -1
- package/dist/toolbar/createToolbar.d.ts.map +1 -1
- package/dist/tooltip/createTooltipTrigger.d.ts.map +1 -1
- package/package.json +9 -7
- package/src/autocomplete/createAutocomplete.ts +341 -0
- package/src/autocomplete/index.ts +9 -0
- package/src/breadcrumbs/createBreadcrumbs.ts +196 -0
- package/src/breadcrumbs/index.ts +8 -0
- package/src/button/createButton.ts +142 -0
- package/src/button/createToggleButton.ts +101 -0
- package/src/button/index.ts +4 -0
- package/src/button/types.ts +78 -0
- package/src/calendar/createCalendar.ts +138 -0
- package/src/calendar/createCalendarCell.ts +187 -0
- package/src/calendar/createCalendarGrid.ts +140 -0
- package/src/calendar/createRangeCalendar.ts +136 -0
- package/src/calendar/createRangeCalendarCell.ts +186 -0
- package/src/calendar/index.ts +34 -0
- package/src/checkbox/createCheckbox.ts +135 -0
- package/src/checkbox/createCheckboxGroup.ts +137 -0
- package/src/checkbox/createCheckboxGroupItem.ts +117 -0
- package/src/checkbox/createCheckboxGroupState.ts +193 -0
- package/src/checkbox/index.ts +13 -0
- package/src/color/createColorArea.ts +314 -0
- package/src/color/createColorField.ts +137 -0
- package/src/color/createColorSlider.ts +197 -0
- package/src/color/createColorSwatch.ts +40 -0
- package/src/color/createColorWheel.ts +208 -0
- package/src/color/index.ts +24 -0
- package/src/color/types.ts +116 -0
- package/src/combobox/createComboBox.ts +647 -0
- package/src/combobox/index.ts +6 -0
- package/src/combobox/intl/en-US.json +7 -0
- package/src/combobox/intl/es-ES.json +7 -0
- package/src/combobox/intl/index.ts +23 -0
- package/src/datepicker/createDateField.ts +154 -0
- package/src/datepicker/createDatePicker.ts +206 -0
- package/src/datepicker/createDateSegment.ts +229 -0
- package/src/datepicker/createTimeField.ts +154 -0
- package/src/datepicker/index.ts +28 -0
- package/src/dialog/createDialog.ts +120 -0
- package/src/dialog/index.ts +2 -0
- package/src/dialog/types.ts +19 -0
- package/src/disclosure/createDisclosure.ts +131 -0
- package/src/disclosure/createDisclosureGroup.ts +62 -0
- package/src/disclosure/index.ts +11 -0
- package/src/dnd/createDrag.ts +209 -0
- package/src/dnd/createDraggableCollection.ts +63 -0
- package/src/dnd/createDraggableItem.ts +243 -0
- package/src/dnd/createDrop.ts +321 -0
- package/src/dnd/createDroppableCollection.ts +293 -0
- package/src/dnd/createDroppableItem.ts +213 -0
- package/src/dnd/index.ts +47 -0
- package/src/dnd/types.ts +89 -0
- package/src/dnd/utils.ts +294 -0
- package/src/focus/FocusScope.tsx +408 -0
- package/src/focus/createAutoFocus.ts +321 -0
- package/src/focus/createFocusRestore.ts +313 -0
- package/src/focus/createVirtualFocus.ts +396 -0
- package/src/focus/index.ts +35 -0
- package/src/form/createFormReset.ts +51 -0
- package/src/form/createFormValidation.ts +224 -0
- package/src/form/index.ts +11 -0
- package/src/grid/GridKeyboardDelegate.ts +429 -0
- package/src/grid/createGrid.ts +261 -0
- package/src/grid/createGridCell.ts +182 -0
- package/src/grid/createGridRow.ts +153 -0
- package/src/grid/index.ts +18 -0
- package/src/grid/types.ts +133 -0
- package/src/gridlist/createGridList.ts +185 -0
- package/src/gridlist/createGridListItem.ts +180 -0
- package/src/gridlist/createGridListSelectionCheckbox.ts +59 -0
- package/src/gridlist/index.ts +16 -0
- package/src/gridlist/types.ts +81 -0
- package/src/i18n/NumberFormatter.ts +266 -0
- package/src/i18n/createCollator.ts +79 -0
- package/src/i18n/createDateFormatter.ts +83 -0
- package/src/i18n/createFilter.ts +131 -0
- package/src/i18n/createNumberFormatter.ts +52 -0
- package/src/i18n/createStringFormatter.ts +87 -0
- package/src/i18n/index.ts +40 -0
- package/src/i18n/locale.tsx +188 -0
- package/src/i18n/utils.ts +99 -0
- package/src/index.ts +670 -0
- package/src/interactions/FocusableProvider.tsx +44 -0
- package/src/interactions/PressEvent.ts +126 -0
- package/src/interactions/createFocus.ts +163 -0
- package/src/interactions/createFocusRing.ts +89 -0
- package/src/interactions/createFocusWithin.ts +206 -0
- package/src/interactions/createFocusable.ts +168 -0
- package/src/interactions/createHover.ts +254 -0
- package/src/interactions/createInteractionModality.ts +424 -0
- package/src/interactions/createKeyboard.ts +82 -0
- package/src/interactions/createLongPress.ts +174 -0
- package/src/interactions/createMove.ts +289 -0
- package/src/interactions/createPress.ts +834 -0
- package/src/interactions/index.ts +78 -0
- package/src/label/createField.ts +145 -0
- package/src/label/createLabel.ts +117 -0
- package/src/label/createLabels.ts +50 -0
- package/src/label/index.ts +19 -0
- package/src/landmark/createLandmark.ts +377 -0
- package/src/landmark/index.ts +8 -0
- package/src/link/createLink.ts +182 -0
- package/src/link/index.ts +1 -0
- package/src/listbox/createListBox.ts +269 -0
- package/src/listbox/createOption.ts +151 -0
- package/src/listbox/index.ts +12 -0
- package/src/live-announcer/announce.ts +322 -0
- package/src/live-announcer/index.ts +9 -0
- package/src/menu/createMenu.ts +396 -0
- package/src/menu/createMenuItem.ts +149 -0
- package/src/menu/createMenuTrigger.ts +88 -0
- package/src/menu/index.ts +18 -0
- package/src/meter/createMeter.ts +75 -0
- package/src/meter/index.ts +1 -0
- package/src/numberfield/createNumberField.ts +268 -0
- package/src/numberfield/index.ts +5 -0
- package/src/overlays/ariaHideOutside.ts +219 -0
- package/src/overlays/createInteractOutside.ts +149 -0
- package/src/overlays/createModal.tsx +202 -0
- package/src/overlays/createOverlay.ts +155 -0
- package/src/overlays/createOverlayTrigger.ts +85 -0
- package/src/overlays/createPreventScroll.ts +266 -0
- package/src/overlays/index.ts +44 -0
- package/src/popover/calculatePosition.ts +766 -0
- package/src/popover/createOverlayPosition.ts +356 -0
- package/src/popover/createPopover.ts +170 -0
- package/src/popover/index.ts +24 -0
- package/src/progress/createProgressBar.ts +128 -0
- package/src/progress/index.ts +5 -0
- package/src/radio/createRadio.ts +287 -0
- package/src/radio/createRadioGroup.ts +189 -0
- package/src/radio/createRadioGroupState.ts +201 -0
- package/src/radio/index.ts +23 -0
- package/src/searchfield/createSearchField.ts +186 -0
- package/src/searchfield/index.ts +2 -0
- package/src/select/createHiddenSelect.tsx +236 -0
- package/src/select/createSelect.ts +395 -0
- package/src/select/index.ts +14 -0
- package/src/selection/createTypeSelect.ts +201 -0
- package/src/selection/index.ts +6 -0
- package/src/separator/createSeparator.ts +82 -0
- package/src/separator/index.ts +6 -0
- package/src/slider/createSlider.ts +349 -0
- package/src/slider/index.ts +2 -0
- package/src/ssr/index.tsx +370 -0
- package/src/switch/createSwitch.ts +70 -0
- package/src/switch/index.ts +1 -0
- package/src/table/createTable.ts +526 -0
- package/src/table/createTableCell.ts +147 -0
- package/src/table/createTableColumnHeader.ts +115 -0
- package/src/table/createTableHeaderRow.ts +40 -0
- package/src/table/createTableRow.ts +155 -0
- package/src/table/createTableRowGroup.ts +32 -0
- package/src/table/createTableSelectAllCheckbox.ts +73 -0
- package/src/table/createTableSelectionCheckbox.ts +59 -0
- package/src/table/index.ts +30 -0
- package/src/table/types.ts +165 -0
- package/src/tabs/createTabs.ts +472 -0
- package/src/tabs/index.ts +14 -0
- package/src/tag/createTag.ts +194 -0
- package/src/tag/createTagGroup.ts +154 -0
- package/src/tag/index.ts +12 -0
- package/src/textfield/createTextField.ts +198 -0
- package/src/textfield/index.ts +5 -0
- package/src/toast/createToast.ts +118 -0
- package/src/toast/createToastRegion.ts +100 -0
- package/src/toast/index.ts +11 -0
- package/src/toggle/createToggle.ts +223 -0
- package/src/toggle/createToggleState.ts +94 -0
- package/src/toggle/index.ts +7 -0
- package/src/toolbar/createToolbar.ts +369 -0
- package/src/toolbar/index.ts +6 -0
- package/src/tooltip/createTooltip.ts +79 -0
- package/src/tooltip/createTooltipTrigger.ts +222 -0
- package/src/tooltip/index.ts +6 -0
- package/src/tree/createTree.ts +246 -0
- package/src/tree/createTreeItem.ts +233 -0
- package/src/tree/createTreeSelectionCheckbox.ts +68 -0
- package/src/tree/index.ts +16 -0
- package/src/tree/types.ts +87 -0
- package/src/utils/createDescription.ts +137 -0
- package/src/utils/dom.ts +327 -0
- package/src/utils/env.ts +54 -0
- package/src/utils/events.ts +106 -0
- package/src/utils/filterDOMProps.ts +116 -0
- package/src/utils/focus.ts +151 -0
- package/src/utils/geometry.ts +115 -0
- package/src/utils/globalListeners.ts +142 -0
- package/src/utils/index.ts +80 -0
- package/src/utils/mergeProps.ts +52 -0
- package/src/utils/platform.ts +52 -0
- package/src/utils/reactivity.ts +36 -0
- package/src/utils/textSelection.ts +114 -0
- package/src/visually-hidden/createVisuallyHidden.ts +124 -0
- package/src/visually-hidden/index.ts +6 -0
- package/dist/index.jsx +0 -15845
- 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';
|