@pingux/astro 2.206.2-alpha.0 → 2.207.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/Button/Buttons.styles.d.ts +14 -0
- package/lib/cjs/components/Button/Buttons.styles.js +11 -1
- package/lib/cjs/components/TableBase/TableBase.js +138 -32
- package/lib/cjs/components/TableBase/TableBase.mdx +46 -13
- package/lib/cjs/components/TableBase/TableBase.stories.js +52 -2
- package/lib/cjs/components/TableBase/TableBase.styles.d.ts +84 -9
- package/lib/cjs/components/TableBase/TableBase.styles.js +61 -10
- package/lib/cjs/components/TableBase/TableBase.test.js +585 -105
- package/lib/cjs/styles/themeOverrides/nextGenDarkMode/variants/variants.d.ts +14 -0
- package/lib/cjs/styles/themeOverrides/nextGenDarkMode/variants/variants.js +16 -2
- package/lib/cjs/styles/themes/next-gen/next-gen.d.ts +10 -0
- package/lib/cjs/styles/themes/next-gen/variants/button.d.ts +7 -0
- package/lib/cjs/styles/themes/next-gen/variants/button.js +4 -1
- package/lib/cjs/styles/themes/next-gen/variants/tableBase.d.ts +3 -0
- package/lib/cjs/styles/themes/next-gen/variants/tableBase.js +6 -1
- package/lib/cjs/styles/themes/next-gen/variants/variants.d.ts +3 -0
- package/lib/cjs/types/tableBase.d.ts +21 -5
- package/lib/components/Button/Buttons.styles.js +11 -1
- package/lib/components/TableBase/TableBase.js +139 -33
- package/lib/components/TableBase/TableBase.mdx +46 -13
- package/lib/components/TableBase/TableBase.stories.js +51 -1
- package/lib/components/TableBase/TableBase.styles.js +61 -10
- package/lib/components/TableBase/TableBase.test.js +585 -105
- package/lib/styles/themeOverrides/nextGenDarkMode/variants/variants.js +16 -2
- package/lib/styles/themes/next-gen/variants/button.js +4 -1
- package/lib/styles/themes/next-gen/variants/tableBase.js +6 -1
- package/package.json +1 -1
|
@@ -644,10 +644,21 @@ declare const _default: {
|
|
|
644
644
|
'&.is-last-column-sticky': {
|
|
645
645
|
'thead tr th:last-of-type': {
|
|
646
646
|
backgroundColor: string;
|
|
647
|
+
'&::after': {
|
|
648
|
+
backgroundColor: any;
|
|
649
|
+
};
|
|
647
650
|
};
|
|
648
651
|
'tbody tr': {
|
|
652
|
+
'&:nth-of-type(odd) td:last-of-type': {
|
|
653
|
+
'&::after': {
|
|
654
|
+
backgroundColor: any;
|
|
655
|
+
};
|
|
656
|
+
};
|
|
649
657
|
'&:nth-of-type(even) td:last-of-type': {
|
|
650
658
|
backgroundColor: string;
|
|
659
|
+
'&::after': {
|
|
660
|
+
backgroundColor: any;
|
|
661
|
+
};
|
|
651
662
|
};
|
|
652
663
|
};
|
|
653
664
|
};
|
|
@@ -666,6 +677,9 @@ declare const _default: {
|
|
|
666
677
|
data: {
|
|
667
678
|
color: string;
|
|
668
679
|
};
|
|
680
|
+
resizer: {
|
|
681
|
+
backgroundColor: any;
|
|
682
|
+
};
|
|
669
683
|
};
|
|
670
684
|
statusIcon: {
|
|
671
685
|
base: {
|
|
@@ -241,11 +241,22 @@ var _default = exports["default"] = {
|
|
|
241
241
|
container: {
|
|
242
242
|
'&.is-last-column-sticky': {
|
|
243
243
|
'thead tr th:last-of-type': {
|
|
244
|
-
backgroundColor: 'backgroundBase'
|
|
244
|
+
backgroundColor: 'backgroundBase',
|
|
245
|
+
'&::after': {
|
|
246
|
+
backgroundColor: _onyxTokens.astroTokensDark.color.common['border-dark']
|
|
247
|
+
}
|
|
245
248
|
},
|
|
246
249
|
'tbody tr': {
|
|
250
|
+
'&:nth-of-type(odd) td:last-of-type': {
|
|
251
|
+
'&::after': {
|
|
252
|
+
backgroundColor: _onyxTokens.astroTokensDark.color.common['border-dark']
|
|
253
|
+
}
|
|
254
|
+
},
|
|
247
255
|
'&:nth-of-type(even) td:last-of-type': {
|
|
248
|
-
backgroundColor: 'backgroundBase'
|
|
256
|
+
backgroundColor: 'backgroundBase',
|
|
257
|
+
'&::after': {
|
|
258
|
+
backgroundColor: _onyxTokens.astroTokensDark.color.common['border-dark']
|
|
259
|
+
}
|
|
249
260
|
}
|
|
250
261
|
}
|
|
251
262
|
}
|
|
@@ -263,6 +274,9 @@ var _default = exports["default"] = {
|
|
|
263
274
|
},
|
|
264
275
|
data: {
|
|
265
276
|
color: 'text.secondary'
|
|
277
|
+
},
|
|
278
|
+
resizer: {
|
|
279
|
+
backgroundColor: _onyxTokens.astroTokensDark.color.common['border-dark']
|
|
266
280
|
}
|
|
267
281
|
},
|
|
268
282
|
statusIcon: statusIcon,
|
|
@@ -1826,6 +1826,13 @@ declare const _default: {
|
|
|
1826
1826
|
fontSize: string;
|
|
1827
1827
|
py: string;
|
|
1828
1828
|
};
|
|
1829
|
+
tableHeaderButton: {
|
|
1830
|
+
'&.is-focused': {
|
|
1831
|
+
outline: string;
|
|
1832
|
+
outlineColor: string;
|
|
1833
|
+
outlineOffset: string;
|
|
1834
|
+
};
|
|
1835
|
+
};
|
|
1829
1836
|
};
|
|
1830
1837
|
forms: {
|
|
1831
1838
|
input: import("theme-ui").ThemeUICSSObject;
|
|
@@ -6921,6 +6928,9 @@ declare const _default: {
|
|
|
6921
6928
|
outlineColor: string;
|
|
6922
6929
|
};
|
|
6923
6930
|
};
|
|
6931
|
+
resizer: {
|
|
6932
|
+
backgroundColor: any;
|
|
6933
|
+
};
|
|
6924
6934
|
};
|
|
6925
6935
|
tabs: {
|
|
6926
6936
|
'&.is-horizontal': {
|
|
@@ -1522,5 +1522,12 @@ declare const buttons: {
|
|
|
1522
1522
|
fontSize: string;
|
|
1523
1523
|
py: string;
|
|
1524
1524
|
};
|
|
1525
|
+
tableHeaderButton: {
|
|
1526
|
+
'&.is-focused': {
|
|
1527
|
+
outline: string;
|
|
1528
|
+
outlineColor: string;
|
|
1529
|
+
outlineOffset: string;
|
|
1530
|
+
};
|
|
1531
|
+
};
|
|
1525
1532
|
};
|
|
1526
1533
|
export default buttons;
|
|
@@ -648,6 +648,9 @@ var buttons = {
|
|
|
648
648
|
aiChat: aiChat,
|
|
649
649
|
paginationMenu: paginationMenu,
|
|
650
650
|
ButtonInputGroupContentRight: ButtonInputGroupContentRight,
|
|
651
|
-
selectLink: selectLink
|
|
651
|
+
selectLink: selectLink,
|
|
652
|
+
tableHeaderButton: {
|
|
653
|
+
'&.is-focused': _objectSpread({}, defaultFocus)
|
|
654
|
+
}
|
|
652
655
|
};
|
|
653
656
|
var _default = exports["default"] = buttons;
|
|
@@ -14,6 +14,7 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
14
14
|
});
|
|
15
15
|
exports.tableBase = void 0;
|
|
16
16
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
|
|
17
|
+
var _onyxTokens = require("@pingux/onyx-tokens");
|
|
17
18
|
var _colors = _interopRequireDefault(require("../colors/colors"));
|
|
18
19
|
var _button = require("./button");
|
|
19
20
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -92,6 +93,9 @@ var thead = {
|
|
|
92
93
|
boxShadow: "0 1px 0 ".concat(_colors["default"].border.base)
|
|
93
94
|
}
|
|
94
95
|
};
|
|
96
|
+
var resizer = {
|
|
97
|
+
backgroundColor: _onyxTokens.astroTokens.color.common['border-dark']
|
|
98
|
+
};
|
|
95
99
|
var head = {
|
|
96
100
|
px: 'lg',
|
|
97
101
|
py: 'sm',
|
|
@@ -126,5 +130,6 @@ var tableBase = exports.tableBase = {
|
|
|
126
130
|
thead: thead,
|
|
127
131
|
head: head,
|
|
128
132
|
tbody: tbody,
|
|
129
|
-
data: data
|
|
133
|
+
data: data,
|
|
134
|
+
resizer: resizer
|
|
130
135
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { ReactNode, RefObject } from 'react';
|
|
2
2
|
import type { TableState } from '@react-stately/table';
|
|
3
3
|
import { TableColumnResizeState } from '@react-stately/table';
|
|
4
4
|
import type { GridNode } from '@react-types/grid';
|
|
5
|
-
import type { Node } from '@react-types/shared';
|
|
6
|
-
import type { TableProps } from '@react-types/table';
|
|
5
|
+
import type { FocusableElement, Key, Node } from '@react-types/shared';
|
|
6
|
+
import type { ColumnSize, TableProps } from '@react-types/table';
|
|
7
7
|
import { TestingAttributes } from './shared/test';
|
|
8
8
|
import { BoxProps } from './box';
|
|
9
9
|
import { DOMAttributes } from './shared';
|
|
10
|
+
export type ResizeHandler = (widths: Map<Key, ColumnSize>) => void;
|
|
10
11
|
export interface BaseProp extends BoxProps, TestingAttributes, DOMAttributes {
|
|
11
12
|
}
|
|
12
|
-
export interface TableBaseProps<T extends object> extends TableProps<T>, Omit<BaseProp, 'children'> {
|
|
13
|
+
export interface TableBaseProps<T extends object> extends TableProps<T>, Omit<BaseProp, 'children' | 'onResize'> {
|
|
13
14
|
'aria-label'?: string;
|
|
14
15
|
selectionMode?: 'none' | 'single' | 'multiple';
|
|
15
16
|
selectionBehavior?: 'replace' | 'toggle';
|
|
@@ -18,6 +19,9 @@ export interface TableBaseProps<T extends object> extends TableProps<T>, Omit<Ba
|
|
|
18
19
|
caption?: ReactNode | string;
|
|
19
20
|
isStickyHeader?: boolean;
|
|
20
21
|
isLastColumnSticky?: boolean;
|
|
22
|
+
onResizeStart?: ResizeHandler;
|
|
23
|
+
onResize?: ResizeHandler;
|
|
24
|
+
onResizeEnd?: ResizeHandler;
|
|
21
25
|
}
|
|
22
26
|
export interface TableRowGroupProps extends BaseProp {
|
|
23
27
|
type: 'thead' | 'tbody';
|
|
@@ -30,17 +34,29 @@ export interface TableHeaderRowProps<T> extends BaseProp {
|
|
|
30
34
|
children: ReactNode;
|
|
31
35
|
className?: string;
|
|
32
36
|
}
|
|
33
|
-
export interface
|
|
37
|
+
export interface ResizerProps<T> {
|
|
38
|
+
column: GridNode<T>;
|
|
39
|
+
layoutState: TableColumnResizeState<T>;
|
|
40
|
+
triggerRef?: RefObject<FocusableElement | null>;
|
|
41
|
+
onResizeStart?: (widths: Map<Key, ColumnSize>) => void;
|
|
42
|
+
onResize?: (widths: Map<Key, ColumnSize>) => void;
|
|
43
|
+
onResizeEnd?: (widths: Map<Key, ColumnSize>) => void;
|
|
44
|
+
}
|
|
45
|
+
export interface TableColumnHeaderProps<T> extends Omit<BaseProp, 'onResize'> {
|
|
34
46
|
column: GridNode<T>;
|
|
35
47
|
state: TableState<T>;
|
|
36
48
|
className?: string;
|
|
37
49
|
layoutState: TableColumnResizeState<T>;
|
|
50
|
+
onResizeStart?: ResizeHandler;
|
|
51
|
+
onResize?: ResizeHandler;
|
|
52
|
+
onResizeEnd?: ResizeHandler;
|
|
38
53
|
}
|
|
39
54
|
export interface TableRowProps<T> extends BaseProp {
|
|
40
55
|
item: Node<T>;
|
|
41
56
|
state: TableState<T>;
|
|
42
57
|
children: ReactNode;
|
|
43
58
|
className?: string;
|
|
59
|
+
hasSelectionCheckboxes?: boolean;
|
|
44
60
|
}
|
|
45
61
|
export interface TableCellProps<T> extends BaseProp {
|
|
46
62
|
cell: GridNode<T>;
|
|
@@ -342,5 +342,15 @@ export default {
|
|
|
342
342
|
withIcon: withIcon,
|
|
343
343
|
filter: filter,
|
|
344
344
|
searchNavTabLabel: tabLabelButton,
|
|
345
|
-
selectLink: selectLink
|
|
345
|
+
selectLink: selectLink,
|
|
346
|
+
tableHeaderButton: {
|
|
347
|
+
fontSize: 'md',
|
|
348
|
+
fontWeight: '1',
|
|
349
|
+
color: 'text.primary',
|
|
350
|
+
lineHeight: 'body',
|
|
351
|
+
backgroundColor: 'transparent',
|
|
352
|
+
borderRadius: '0px',
|
|
353
|
+
textAlign: 'left',
|
|
354
|
+
'&.is-focused': _objectSpread({}, defaultFocus)
|
|
355
|
+
}
|
|
346
356
|
};
|
|
@@ -10,7 +10,7 @@ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
|
10
10
|
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
11
11
|
import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
|
|
12
12
|
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
|
13
|
-
var _excluded = ["caption", "selectionMode", "selectionBehavior", "hasSelectionCheckboxes", "isStickyHeader", "className", "isLastColumnSticky"],
|
|
13
|
+
var _excluded = ["caption", "selectionMode", "selectionBehavior", "hasSelectionCheckboxes", "isStickyHeader", "className", "isLastColumnSticky", "onResizeStart", "onResize", "onResizeEnd"],
|
|
14
14
|
_excluded2 = ["caption"],
|
|
15
15
|
_excluded3 = ["type", "children", "className", "isSticky"];
|
|
16
16
|
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
|
|
@@ -20,7 +20,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _co
|
|
|
20
20
|
import React, { forwardRef, useCallback, useLayoutEffect, useRef, useState } from 'react';
|
|
21
21
|
import { useFocusRing } from '@react-aria/focus';
|
|
22
22
|
import { useHover, usePress } from '@react-aria/interactions';
|
|
23
|
-
import { useTable, useTableCell, useTableColumnHeader, useTableHeaderRow, useTableRow, useTableRowGroup, useTableSelectAllCheckbox, useTableSelectionCheckbox } from '@react-aria/table';
|
|
23
|
+
import { useTable, useTableCell, useTableColumnHeader, useTableColumnResize, useTableHeaderRow, useTableRow, useTableRowGroup, useTableSelectAllCheckbox, useTableSelectionCheckbox } from '@react-aria/table';
|
|
24
24
|
import { mergeProps, useResizeObserver } from '@react-aria/utils';
|
|
25
25
|
import { VisuallyHidden } from '@react-aria/visually-hidden';
|
|
26
26
|
import { useTableColumnResizeState, useTableState } from '@react-stately/table';
|
|
@@ -56,6 +56,9 @@ var TableBase = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
56
56
|
isStickyHeader = _props$isStickyHeader === void 0 ? false : _props$isStickyHeader,
|
|
57
57
|
className = props.className,
|
|
58
58
|
isLastColumnSticky = props.isLastColumnSticky,
|
|
59
|
+
onResizeStart = props.onResizeStart,
|
|
60
|
+
onResize = props.onResize,
|
|
61
|
+
onResizeEnd = props.onResizeEnd,
|
|
59
62
|
others = _objectWithoutProperties(props, _excluded);
|
|
60
63
|
var tableRef = useLocalOrForwardRef(ref);
|
|
61
64
|
var headerRef = useRef(null);
|
|
@@ -136,7 +139,10 @@ var TableBase = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
136
139
|
key: column.key,
|
|
137
140
|
column: column,
|
|
138
141
|
state: state,
|
|
139
|
-
layoutState: layoutState
|
|
142
|
+
layoutState: layoutState,
|
|
143
|
+
onResizeStart: onResizeStart,
|
|
144
|
+
onResize: onResize,
|
|
145
|
+
onResizeEnd: onResizeEnd
|
|
140
146
|
});
|
|
141
147
|
}));
|
|
142
148
|
})), ___EmotionJSX(TableRowGroup, _extends({
|
|
@@ -154,12 +160,13 @@ var TableBase = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
154
160
|
}, ___EmotionJSX(Loader, {
|
|
155
161
|
variant: "loader.withinDataTable"
|
|
156
162
|
})), _mapInstanceProperty(_context3 = _Array$from(collection.body.childNodes)).call(_context3, function (row) {
|
|
157
|
-
var _context4;
|
|
163
|
+
var _context4, _collection$getChildr, _collection$getChildr2;
|
|
158
164
|
return ___EmotionJSX(TableRow, {
|
|
159
165
|
key: row.key,
|
|
160
166
|
item: row,
|
|
161
|
-
state: state
|
|
162
|
-
|
|
167
|
+
state: state,
|
|
168
|
+
hasSelectionCheckboxes: hasSelectionCheckboxes
|
|
169
|
+
}, _mapInstanceProperty(_context4 = _Array$from((_collection$getChildr = (_collection$getChildr2 = collection.getChildren) === null || _collection$getChildr2 === void 0 ? void 0 : _collection$getChildr2.call(collection, row.key)) !== null && _collection$getChildr !== void 0 ? _collection$getChildr : [])).call(_context4, function (cell) {
|
|
163
170
|
return cell.props.isSelectionCell ? ___EmotionJSX(TableCheckboxCell, {
|
|
164
171
|
key: cell.key,
|
|
165
172
|
cell: cell,
|
|
@@ -225,39 +232,87 @@ function TableHeaderRow(props) {
|
|
|
225
232
|
ref: ref
|
|
226
233
|
}), children);
|
|
227
234
|
}
|
|
235
|
+
function Resizer(props) {
|
|
236
|
+
var column = props.column,
|
|
237
|
+
layoutState = props.layoutState,
|
|
238
|
+
triggerRef = props.triggerRef,
|
|
239
|
+
onResizeStart = props.onResizeStart,
|
|
240
|
+
onResize = props.onResize,
|
|
241
|
+
onResizeEnd = props.onResizeEnd;
|
|
242
|
+
var ref = useRef(null);
|
|
243
|
+
var _useTableColumnResize = useTableColumnResize({
|
|
244
|
+
column: column,
|
|
245
|
+
'aria-label': "".concat(column.textValue, " column width"),
|
|
246
|
+
triggerRef: triggerRef,
|
|
247
|
+
onResizeStart: onResizeStart,
|
|
248
|
+
onResize: onResize,
|
|
249
|
+
onResizeEnd: onResizeEnd
|
|
250
|
+
}, layoutState, ref),
|
|
251
|
+
resizerProps = _useTableColumnResize.resizerProps,
|
|
252
|
+
inputProps = _useTableColumnResize.inputProps;
|
|
253
|
+
var _useFocusRing = useFocusRing(),
|
|
254
|
+
isFocusVisible = _useFocusRing.isFocusVisible,
|
|
255
|
+
focusProps = _useFocusRing.focusProps;
|
|
256
|
+
|
|
257
|
+
// The input must be nested inside the Box that carries resizerProps so that
|
|
258
|
+
// keyboard events fired on the input (Enter to start resize, Escape/Tab to
|
|
259
|
+
// end it) bubble up to the element with the keyboard handlers.
|
|
260
|
+
|
|
261
|
+
var _useStatusClasses3 = useStatusClasses('', {
|
|
262
|
+
isFocused: isFocusVisible
|
|
263
|
+
}),
|
|
264
|
+
classNames = _useStatusClasses3.classNames;
|
|
265
|
+
return ___EmotionJSX(Box, _extends({
|
|
266
|
+
role: "presentation",
|
|
267
|
+
variant: "tableBase.resizer",
|
|
268
|
+
className: classNames
|
|
269
|
+
}, resizerProps), ___EmotionJSX("input", _extends({
|
|
270
|
+
ref: ref
|
|
271
|
+
}, mergeProps(inputProps, focusProps))));
|
|
272
|
+
}
|
|
228
273
|
function TableColumnHeader(props) {
|
|
229
|
-
var _column$props;
|
|
274
|
+
var _column$props, _column$props2;
|
|
230
275
|
var column = props.column,
|
|
231
276
|
state = props.state,
|
|
232
277
|
className = props.className,
|
|
233
|
-
layoutState = props.layoutState
|
|
278
|
+
layoutState = props.layoutState,
|
|
279
|
+
onResizeStart = props.onResizeStart,
|
|
280
|
+
onResize = props.onResize,
|
|
281
|
+
onResizeEnd = props.onResizeEnd;
|
|
234
282
|
var ref = useRef(null);
|
|
235
283
|
var _useTableColumnHeader = useTableColumnHeader({
|
|
236
284
|
node: column
|
|
237
285
|
}, state, ref),
|
|
238
286
|
columnHeaderProps = _useTableColumnHeader.columnHeaderProps;
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
287
|
+
|
|
288
|
+
// within: true catches keyboard focus on the resizer <input> child so the
|
|
289
|
+
// <th> shows its focus ring even when the child is the active element.
|
|
290
|
+
var _useFocusRing2 = useFocusRing({
|
|
291
|
+
within: true
|
|
292
|
+
}),
|
|
293
|
+
isFocusVisible = _useFocusRing2.isFocusVisible,
|
|
294
|
+
focusProps = _useFocusRing2.focusProps;
|
|
242
295
|
var allowsSorting = (_column$props = column.props) === null || _column$props === void 0 ? void 0 : _column$props.allowsSorting;
|
|
296
|
+
var allowsResizing = (_column$props2 = column.props) === null || _column$props2 === void 0 ? void 0 : _column$props2.allowsResizing;
|
|
243
297
|
var _useGetTheme = useGetTheme(),
|
|
244
298
|
icons = _useGetTheme.icons;
|
|
245
299
|
var Ascending = icons.Ascending,
|
|
246
300
|
Descending = icons.Descending;
|
|
247
301
|
var sortDescriptor = state.sortDescriptor;
|
|
248
|
-
var
|
|
302
|
+
var isSortedAscending = (sortDescriptor === null || sortDescriptor === void 0 ? void 0 : sortDescriptor.column) === column.key && (sortDescriptor === null || sortDescriptor === void 0 ? void 0 : sortDescriptor.direction) === 'ascending';
|
|
303
|
+
var arrowIcon = isSortedAscending ? Ascending : Descending;
|
|
249
304
|
var sortIcon = ___EmotionJSX(Icon, {
|
|
250
305
|
icon: arrowIcon,
|
|
251
306
|
size: "xs",
|
|
252
307
|
"aria-hidden": "true",
|
|
253
308
|
title: {
|
|
254
|
-
name:
|
|
309
|
+
name: isSortedAscending ? 'Sort ascending' : 'Sort descending'
|
|
255
310
|
}
|
|
256
311
|
});
|
|
257
|
-
var
|
|
312
|
+
var _useStatusClasses4 = useStatusClasses(className, {
|
|
258
313
|
isFocused: isFocusVisible
|
|
259
314
|
}),
|
|
260
|
-
classNames =
|
|
315
|
+
classNames = _useStatusClasses4.classNames;
|
|
261
316
|
useHandleFocusRef(ref);
|
|
262
317
|
return ___EmotionJSX(Box, _extends({
|
|
263
318
|
as: "th",
|
|
@@ -266,19 +321,27 @@ function TableColumnHeader(props) {
|
|
|
266
321
|
variant: "tableBase.head",
|
|
267
322
|
className: classNames,
|
|
268
323
|
sx: _objectSpread({
|
|
269
|
-
width: layoutState === null || layoutState === void 0 ? void 0 : layoutState.getColumnWidth(column.key)
|
|
324
|
+
width: layoutState === null || layoutState === void 0 ? void 0 : layoutState.getColumnWidth(column.key),
|
|
325
|
+
position: 'relative'
|
|
270
326
|
}, column.props.sx)
|
|
271
327
|
}, mergeProps(columnHeaderProps, focusProps, column.props)), ___EmotionJSX(Box, {
|
|
272
328
|
isRow: true,
|
|
273
329
|
gap: "sm",
|
|
274
330
|
alignItems: "center"
|
|
275
|
-
}, ___EmotionJSX(Text, null, column.rendered), allowsSorting && sortIcon)
|
|
331
|
+
}, ___EmotionJSX(Text, null, column.rendered), allowsSorting && sortIcon), allowsResizing && ___EmotionJSX(Resizer, {
|
|
332
|
+
column: column,
|
|
333
|
+
layoutState: layoutState,
|
|
334
|
+
onResizeStart: onResizeStart,
|
|
335
|
+
onResize: onResize,
|
|
336
|
+
onResizeEnd: onResizeEnd
|
|
337
|
+
}));
|
|
276
338
|
}
|
|
277
339
|
function TableRow(props) {
|
|
278
340
|
var item = props.item,
|
|
279
341
|
state = props.state,
|
|
280
342
|
children = props.children,
|
|
281
|
-
className = props.className
|
|
343
|
+
className = props.className,
|
|
344
|
+
hasSelectionCheckboxes = props.hasSelectionCheckboxes;
|
|
282
345
|
var ref = useRef(null);
|
|
283
346
|
var _useTableRow = useTableRow({
|
|
284
347
|
node: item
|
|
@@ -286,31 +349,50 @@ function TableRow(props) {
|
|
|
286
349
|
rowProps = _useTableRow.rowProps;
|
|
287
350
|
var isSelected = state.selectionManager.isSelected(item.key);
|
|
288
351
|
var isDisabled = state.disabledKeys.has(item.key);
|
|
289
|
-
var
|
|
290
|
-
isFocusVisible =
|
|
291
|
-
focusProps =
|
|
352
|
+
var _useFocusRing3 = useFocusRing(),
|
|
353
|
+
isFocusVisible = _useFocusRing3.isFocusVisible,
|
|
354
|
+
focusProps = _useFocusRing3.focusProps;
|
|
292
355
|
var _useHover = useHover({}),
|
|
293
356
|
hoverProps = _useHover.hoverProps,
|
|
294
357
|
isHovered = _useHover.isHovered;
|
|
358
|
+
|
|
359
|
+
// allowTextSelectionOnPress: true prevents the press handler from suppressing
|
|
360
|
+
// native text-selection drags (user-select: none is not applied on pointer down).
|
|
361
|
+
// When hasSelectionCheckboxes is true, isDisabled: true disables the visual
|
|
362
|
+
// isPressed state — selection is handled solely by the checkbox cells.
|
|
295
363
|
var _usePress = usePress({
|
|
296
|
-
ref: ref
|
|
364
|
+
ref: ref,
|
|
365
|
+
allowTextSelectionOnPress: true,
|
|
366
|
+
isDisabled: !!hasSelectionCheckboxes
|
|
297
367
|
}),
|
|
298
368
|
pressProps = _usePress.pressProps,
|
|
299
369
|
isPressed = _usePress.isPressed;
|
|
300
|
-
|
|
370
|
+
|
|
371
|
+
// React Aria's useSelectableItem only maps Space to selection (not Enter).
|
|
372
|
+
// Enter is reserved for "action" which is unused here, so we manually toggle
|
|
373
|
+
// selection on Enter to match expected keyboard behavior.
|
|
374
|
+
var enterKeyProps = useCallback(function (e) {
|
|
375
|
+
if (e.key !== 'Enter') return;
|
|
376
|
+
if (isDisabled || state.selectionManager.selectionMode === 'none') return;
|
|
377
|
+
e.preventDefault();
|
|
378
|
+
state.selectionManager.toggleSelection(item.key);
|
|
379
|
+
}, [isDisabled, item.key, state.selectionManager]);
|
|
380
|
+
var _useStatusClasses5 = useStatusClasses(className, {
|
|
301
381
|
isSelected: isSelected,
|
|
302
382
|
isHovered: isHovered,
|
|
303
383
|
isPressed: isPressed,
|
|
304
384
|
isFocused: isFocusVisible,
|
|
305
385
|
isDisabled: isDisabled
|
|
306
386
|
}),
|
|
307
|
-
classNames =
|
|
387
|
+
classNames = _useStatusClasses5.classNames;
|
|
308
388
|
return ___EmotionJSX(Box, _extends({
|
|
309
389
|
as: "tr",
|
|
310
390
|
display: "table-row",
|
|
311
391
|
className: classNames,
|
|
312
392
|
variant: "tableBase.row"
|
|
313
|
-
}, mergeProps(rowProps, focusProps, hoverProps, pressProps
|
|
393
|
+
}, mergeProps(rowProps, focusProps, hoverProps, pressProps, {
|
|
394
|
+
onKeyDown: enterKeyProps
|
|
395
|
+
}), {
|
|
314
396
|
ref: ref
|
|
315
397
|
}), children);
|
|
316
398
|
}
|
|
@@ -324,14 +406,19 @@ function TableCell(props) {
|
|
|
324
406
|
node: cell
|
|
325
407
|
}, state, ref),
|
|
326
408
|
gridCellProps = _useTableCell.gridCellProps;
|
|
327
|
-
var
|
|
328
|
-
isFocusVisible =
|
|
329
|
-
focusProps =
|
|
330
|
-
var
|
|
409
|
+
var _useFocusRing4 = useFocusRing(),
|
|
410
|
+
isFocusVisible = _useFocusRing4.isFocusVisible,
|
|
411
|
+
focusProps = _useFocusRing4.focusProps;
|
|
412
|
+
var _useStatusClasses6 = useStatusClasses(className, {
|
|
331
413
|
isFocused: isFocusVisible
|
|
332
414
|
}),
|
|
333
|
-
classNames =
|
|
415
|
+
classNames = _useStatusClasses6.classNames;
|
|
334
416
|
useHandleFocusRef(ref);
|
|
417
|
+
|
|
418
|
+
// Prevents pointer events reaching the row's press handler, allowing native text-selection drags.
|
|
419
|
+
var stopPointerPropagation = useCallback(function (e) {
|
|
420
|
+
e.stopPropagation();
|
|
421
|
+
}, []);
|
|
335
422
|
return ___EmotionJSX(Box, _extends({
|
|
336
423
|
as: "td",
|
|
337
424
|
display: "table-cell",
|
|
@@ -341,8 +428,22 @@ function TableCell(props) {
|
|
|
341
428
|
sx: _objectSpread({
|
|
342
429
|
width: layoutState === null || layoutState === void 0 ? void 0 : layoutState.getColumnWidth(cell.column.key)
|
|
343
430
|
}, cell.props.sx)
|
|
344
|
-
}, mergeProps(
|
|
431
|
+
}, mergeProps({
|
|
432
|
+
onPointerDown: stopPointerPropagation,
|
|
433
|
+
onMouseDown: stopPointerPropagation
|
|
434
|
+
}, gridCellProps, focusProps, cell.props)), cell.rendered);
|
|
345
435
|
}
|
|
436
|
+
|
|
437
|
+
// Native checkboxes only toggle on Space, not Enter. This handler makes Enter
|
|
438
|
+
// behave the same as Space by calling the checkbox's onChange callback.
|
|
439
|
+
var handleCheckboxEnterKey = function handleCheckboxEnterKey(onChange, isSelected) {
|
|
440
|
+
return function (e) {
|
|
441
|
+
if (e.key === 'Enter') {
|
|
442
|
+
e.preventDefault();
|
|
443
|
+
onChange === null || onChange === void 0 || onChange(!isSelected);
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
};
|
|
346
447
|
function TableSelectAllCell(props) {
|
|
347
448
|
var column = props.column,
|
|
348
449
|
state = props.state,
|
|
@@ -365,7 +466,8 @@ function TableSelectAllCell(props) {
|
|
|
365
466
|
ref: ref
|
|
366
467
|
}), state.selectionManager.selectionMode === 'single' ? ___EmotionJSX(VisuallyHidden, null, checkboxProps['aria-label']) : ___EmotionJSX(CheckboxField, _extends({
|
|
367
468
|
checkBoxProps: {
|
|
368
|
-
'data-testid': 'select-all-checkbox'
|
|
469
|
+
'data-testid': 'select-all-checkbox',
|
|
470
|
+
onKeyDown: handleCheckboxEnterKey(checkboxProps.onChange, checkboxProps.isSelected)
|
|
369
471
|
}
|
|
370
472
|
}, checkboxProps)));
|
|
371
473
|
}
|
|
@@ -391,6 +493,10 @@ function TableCheckboxCell(props) {
|
|
|
391
493
|
}, cell.props.sx)
|
|
392
494
|
}, gridCellProps, {
|
|
393
495
|
ref: ref
|
|
394
|
-
}), ___EmotionJSX(CheckboxField,
|
|
496
|
+
}), ___EmotionJSX(CheckboxField, _extends({
|
|
497
|
+
checkBoxProps: {
|
|
498
|
+
onKeyDown: handleCheckboxEnterKey(checkboxProps.onChange, checkboxProps.isSelected)
|
|
499
|
+
}
|
|
500
|
+
}, checkboxProps)));
|
|
395
501
|
}
|
|
396
502
|
export default TableBase;
|
|
@@ -3,29 +3,62 @@ import * as TableBaseStories from './TableBase.stories';
|
|
|
3
3
|
|
|
4
4
|
<Meta of={TableBaseStories} isTemplate />
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# TableBase
|
|
7
7
|
|
|
8
|
-
Data tables display information in a grid-like format of rows and columns.
|
|
9
|
-
They organize information in a way that
|
|
8
|
+
Data tables display information in a grid-like format of rows and columns.
|
|
9
|
+
They organize information in a way that's easy to scan so that users can look for patterns and develop insights from data.
|
|
10
10
|
|
|
11
|
-
Column header names describe the type of content displayed in each column.
|
|
11
|
+
Column header names describe the type of content displayed in each column.
|
|
12
12
|
Each row contains data related to a single entity.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
TableBase should:
|
|
15
15
|
- Have consistently aligned content.
|
|
16
16
|
- Use multiple heading rows for higher-level grouping of the columns.
|
|
17
17
|
- Use column dividers sparingly.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
This basic component is rendered as an HTML `<table>`, which accepts the `<TBody>` component and the `<THead>` as children.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
### When to Use
|
|
22
|
+
|
|
23
|
+
Use TableBase when you need a fully custom table implementation that goes beyond what higher-level table components provide. Common use cases include:
|
|
24
|
+
|
|
25
|
+
- Sticky columns (e.g., pinning the last column during horizontal scroll)
|
|
26
|
+
- Custom row or column grouping
|
|
27
|
+
- Non-standard selection behaviors
|
|
28
|
+
- Bespoke cell rendering or layout that requires direct control over the table structure
|
|
29
|
+
|
|
30
|
+
TableBase is the lowest-level table primitive in Astro and gives you direct access to the underlying React Aria/Stately table hooks. Use it when you need that level of control.
|
|
22
31
|
|
|
23
32
|
### Required Components
|
|
24
33
|
|
|
25
|
-
This component requires these additional components:
|
|
34
|
+
This component requires these additional components:
|
|
35
|
+
|
|
36
|
+
- **TableCaption** — renders an accessible `<caption>` element for the table
|
|
37
|
+
- **THead** — wraps the header section (`<thead>`)
|
|
38
|
+
- **Column** — defines each column header cell (`<th>`)
|
|
39
|
+
- **TBody** — wraps the body section (`<tbody>`)
|
|
40
|
+
- **Row** — defines each data row (`<tr>`)
|
|
41
|
+
- **Cell** — defines each data cell (`<td>`)
|
|
42
|
+
|
|
43
|
+
### Accessibility
|
|
44
|
+
|
|
45
|
+
#### Keyboard Navigation
|
|
46
|
+
|
|
47
|
+
These keys provide additional functionality to the component.
|
|
48
|
+
|
|
49
|
+
| Keys | Functions |
|
|
50
|
+
| ---- | --------- |
|
|
51
|
+
| Tab | Moves focus to the next focusable component. All focusable components in the table are included in the page tab sequence. |
|
|
52
|
+
| Shift + Tab | Moves focus to the previous focusable component. |
|
|
53
|
+
| Space or Enter | Focuses the component and triggers an action if one is associated with it. |
|
|
54
|
+
| Arrow keys | Can be used to navigate between the components in the table. |
|
|
55
|
+
| Home or Page Up | Shifts the focus to the first row. |
|
|
56
|
+
| End or Page Down | Shifts the focus to the last visible row. |
|
|
57
|
+
|
|
58
|
+
#### Screen Readers
|
|
26
59
|
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
60
|
+
This component uses the following attributes to assist screen readers:
|
|
61
|
+
- The **`aria-label`** attribute should be provided on the `TableBase` to give the table an accessible name. When a visible `TableCaption` is present, use **`aria-labelledby`** to associate the caption with the table instead.
|
|
62
|
+
- The **`aria-rowcount`** and **`aria-columncount`** attributes are used to indicate the total number of rows and columns in the grid structure.
|
|
63
|
+
- Each `Row` uses the **`aria-rowindex`** attribute to enumerate its position within the table.
|
|
64
|
+
- Each `Column` and `Cell` uses the **`aria-colindex`** attribute to enumerate its position within its row.
|