@jetbrains/ring-ui 8.0.0-beta.3 → 8.0.0-beta.4
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/components/checkbox/checkbox.d.ts +1 -1
- package/components/collapsible-group/collapsible-group.css +138 -0
- package/components/collapsible-group/collapsible-group.d.ts +20 -0
- package/components/collapsible-group/collapsible-group.js +73 -0
- package/components/editable-heading/editable-heading.js +14 -14
- package/components/expand/collapsible-group.css +23 -89
- package/components/expand/collapsible-group.d.ts +8 -20
- package/components/expand/collapsible-group.js +14 -73
- package/components/global/compose-refs.d.ts +2 -1
- package/components/global/compose-refs.js +24 -8
- package/components/global/focus-with-temporary-tabindex.d.ts +11 -0
- package/components/global/focus-with-temporary-tabindex.js +21 -0
- package/components/global/intersection-observer-context.d.ts +29 -9
- package/components/global/intersection-observer-context.js +43 -24
- package/components/global/is-within-interactive-element.d.ts +6 -0
- package/components/global/is-within-interactive-element.js +26 -0
- package/components/global/is-within-navigable-element.d.ts +6 -0
- package/components/global/is-within-navigable-element.js +27 -0
- package/components/global/parse-css-duration.d.ts +5 -0
- package/components/global/parse-css-duration.js +13 -0
- package/components/global/schedule-with-cleanup.d.ts +12 -0
- package/components/global/schedule-with-cleanup.js +34 -0
- package/components/global/table-selection.js +1 -1
- package/components/input/input.d.ts +1 -1
- package/components/legacy-table/row.d.ts +1 -1
- package/components/popup/popup.d.ts +2 -0
- package/components/popup/popup.js +2 -2
- package/components/select/select-popup.d.ts +1 -1
- package/components/select/select.d.ts +1 -1
- package/components/table/default-item-renderer.d.ts +23 -10
- package/components/table/default-item-renderer.js +40 -19
- package/components/table/internal/column-animation.d.ts +16 -0
- package/components/table/internal/column-animation.js +45 -0
- package/components/table/internal/table-header.d.ts +4 -0
- package/components/table/internal/table-header.js +357 -0
- package/components/table/internal/virtual-items.d.ts +34 -0
- package/components/table/{table-virtualize.js → internal/virtual-items.js} +68 -33
- package/components/table/item-virtualization.d.ts +35 -0
- package/components/table/item-virtualization.js +28 -0
- package/components/table/table-const.d.ts +40 -6
- package/components/table/table-const.js +14 -5
- package/components/table/table-primitives.d.ts +9 -16
- package/components/table/table-primitives.js +6 -60
- package/components/table/table-props.d.ts +280 -0
- package/components/table/table-props.js +1 -0
- package/components/table/table.css +171 -66
- package/components/table/table.d.ts +205 -209
- package/components/table/table.js +298 -2
- package/components/util-stories.d.ts +26 -0
- package/components/util-stories.js +61 -0
- package/package.json +29 -30
- package/components/date-picker/use-intersection-observer.d.ts +0 -6
- package/components/date-picker/use-intersection-observer.js +0 -48
- package/components/global/composeRefs.d.ts +0 -6
- package/components/global/composeRefs.js +0 -7
- package/components/table/table-component.d.ts +0 -80
- package/components/table/table-component.js +0 -130
- package/components/table/table-row-focus.d.ts +0 -4
- package/components/table/table-row-focus.js +0 -42
- package/components/table/table-virtualize.d.ts +0 -32
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { type ComponentPropsWithRef } from 'react';
|
|
2
|
-
import type { TableProps } from './table';
|
|
3
|
-
/**
|
|
4
|
-
* The new Table component. Use it instead of tables in the `legacy-table` folder.
|
|
5
|
-
*
|
|
6
|
-
* For every prop and component referenced here, see the corresponding docs
|
|
7
|
-
* for detailed behavior.
|
|
8
|
-
*
|
|
9
|
-
* ## Minimal usage
|
|
10
|
-
*
|
|
11
|
-
* You need the following props:
|
|
12
|
-
* - `data`
|
|
13
|
-
* - `getKey`
|
|
14
|
-
* - `columns`
|
|
15
|
-
* - `key`
|
|
16
|
-
* - `name` (not required but needed in most cases)
|
|
17
|
-
* - `renderCell` (not required but needed in most cases)
|
|
18
|
-
*
|
|
19
|
-
* ## Selection
|
|
20
|
-
*
|
|
21
|
-
* Selection is handled on item level via `renderItem` (often with
|
|
22
|
-
* `DefaultItemRenderer`) and its props:
|
|
23
|
-
*
|
|
24
|
-
* - `clickable`
|
|
25
|
-
* - `selected`
|
|
26
|
-
* - `onClick` or `onPointerUp`, etc.
|
|
27
|
-
*
|
|
28
|
-
* You may use the TableSelection from `global/table-selection.ts` for the selection control:
|
|
29
|
-
*
|
|
30
|
-
* - `selected={tableSelection.isSelected(item)}`
|
|
31
|
-
* - `onClick={() => setTableSelection(tableSelection.toggle(item))}`
|
|
32
|
-
*
|
|
33
|
-
* See the stories for examples with this utility.
|
|
34
|
-
*
|
|
35
|
-
* Additionally, for accessibility, you will likely need a cell with a checkbox
|
|
36
|
-
* to toggle item selection.
|
|
37
|
-
*
|
|
38
|
-
* ## Sorting
|
|
39
|
-
*
|
|
40
|
-
* You need the following to support sorting:
|
|
41
|
-
*
|
|
42
|
-
* - Include `<SortButton />` in a column header
|
|
43
|
-
* - Set initial `Column.sortOrder` to `none`. Do not leave `undefined`
|
|
44
|
-
* for accessibility reasons.
|
|
45
|
-
* - Handle `TableProps.onSort` callback in the client code. It is expected
|
|
46
|
-
* to update `columns` by setting the new `sortOrder` value for
|
|
47
|
-
* the corresponding column, and updating the data accordingly.
|
|
48
|
-
*
|
|
49
|
-
* ## Focus
|
|
50
|
-
*
|
|
51
|
-
* The table supports the ["roving tabindex"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Guides/Keyboard-navigable_JavaScript_widgets#technique_1_roving_tabindex)
|
|
52
|
-
* technique to focus rows with the up/down arrow keys and, possibly, with the pointer.
|
|
53
|
-
* To support it, use the following props of the `DefaultItemRenderer`:
|
|
54
|
-
*
|
|
55
|
-
* - `keyboardFocusable`
|
|
56
|
-
* - Possibly `onClick` invoking `focusRow(e.currentTarget)`
|
|
57
|
-
*
|
|
58
|
-
* In your custom row renderer, use `TableRow`, which also has the `keyboardFocusable` prop.
|
|
59
|
-
*
|
|
60
|
-
* ## Deleting columns
|
|
61
|
-
*
|
|
62
|
-
* You need the following to support deleting columns:
|
|
63
|
-
*
|
|
64
|
-
* - Make sure the `column` has a proper `name` or `key` prop, which will be
|
|
65
|
-
* automatically included in the aria-label of `<DeleteColumnButton />`.
|
|
66
|
-
* - Include `<DeleteColumnButton />` in a column header
|
|
67
|
-
* - Handle `TableProps.onColumnDelete` callback in the client code. It is expected
|
|
68
|
-
* to update `columns` by removing the corresponding column.
|
|
69
|
-
*
|
|
70
|
-
* ## Row virtualization
|
|
71
|
-
*
|
|
72
|
-
* To render only rows near the viewport and replace others with spacers, use:
|
|
73
|
-
*
|
|
74
|
-
* - `virtualizeRows`
|
|
75
|
-
* - `scrollerRef` — required when the scrollable container is not the whole document
|
|
76
|
-
* - `estimateHeight` — recommended when rows are expected to be taller than
|
|
77
|
-
* the default height (e.g. multiline or custom content)
|
|
78
|
-
* - Fine-tuning props: `lookaheadPx`, `retentionMarginPx`, `minScrollAndResizeDeltaPx`
|
|
79
|
-
*/
|
|
80
|
-
export default function Table<T>(props: TableProps<T> & ComponentPropsWithRef<'table'>): import("react").JSX.Element;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
import classNames from 'classnames';
|
|
3
|
-
import { mergeRefs } from 'react-merge-refs';
|
|
4
|
-
import { IntersectionObserverContext } from '../global/intersection-observer-context';
|
|
5
|
-
import { SpacerRow, useTableVirtualize } from './table-virtualize';
|
|
6
|
-
import { DefaultItemRenderer } from './default-item-renderer';
|
|
7
|
-
import { CollapseItemIntoSpacerContext, ColumnIndexContext, defaultLookaheadPx, defaultMinScrollAndResizeDeltaPx, defaultRetentionMarginPx, defaultRowHeight, TablePropsContext, } from './table-const';
|
|
8
|
-
import { onBlurCaptureTbody, onKeyDownTbody } from './table-row-focus';
|
|
9
|
-
import styles from './table.css';
|
|
10
|
-
/**
|
|
11
|
-
* The new Table component. Use it instead of tables in the `legacy-table` folder.
|
|
12
|
-
*
|
|
13
|
-
* For every prop and component referenced here, see the corresponding docs
|
|
14
|
-
* for detailed behavior.
|
|
15
|
-
*
|
|
16
|
-
* ## Minimal usage
|
|
17
|
-
*
|
|
18
|
-
* You need the following props:
|
|
19
|
-
* - `data`
|
|
20
|
-
* - `getKey`
|
|
21
|
-
* - `columns`
|
|
22
|
-
* - `key`
|
|
23
|
-
* - `name` (not required but needed in most cases)
|
|
24
|
-
* - `renderCell` (not required but needed in most cases)
|
|
25
|
-
*
|
|
26
|
-
* ## Selection
|
|
27
|
-
*
|
|
28
|
-
* Selection is handled on item level via `renderItem` (often with
|
|
29
|
-
* `DefaultItemRenderer`) and its props:
|
|
30
|
-
*
|
|
31
|
-
* - `clickable`
|
|
32
|
-
* - `selected`
|
|
33
|
-
* - `onClick` or `onPointerUp`, etc.
|
|
34
|
-
*
|
|
35
|
-
* You may use the TableSelection from `global/table-selection.ts` for the selection control:
|
|
36
|
-
*
|
|
37
|
-
* - `selected={tableSelection.isSelected(item)}`
|
|
38
|
-
* - `onClick={() => setTableSelection(tableSelection.toggle(item))}`
|
|
39
|
-
*
|
|
40
|
-
* See the stories for examples with this utility.
|
|
41
|
-
*
|
|
42
|
-
* Additionally, for accessibility, you will likely need a cell with a checkbox
|
|
43
|
-
* to toggle item selection.
|
|
44
|
-
*
|
|
45
|
-
* ## Sorting
|
|
46
|
-
*
|
|
47
|
-
* You need the following to support sorting:
|
|
48
|
-
*
|
|
49
|
-
* - Include `<SortButton />` in a column header
|
|
50
|
-
* - Set initial `Column.sortOrder` to `none`. Do not leave `undefined`
|
|
51
|
-
* for accessibility reasons.
|
|
52
|
-
* - Handle `TableProps.onSort` callback in the client code. It is expected
|
|
53
|
-
* to update `columns` by setting the new `sortOrder` value for
|
|
54
|
-
* the corresponding column, and updating the data accordingly.
|
|
55
|
-
*
|
|
56
|
-
* ## Focus
|
|
57
|
-
*
|
|
58
|
-
* The table supports the ["roving tabindex"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Guides/Keyboard-navigable_JavaScript_widgets#technique_1_roving_tabindex)
|
|
59
|
-
* technique to focus rows with the up/down arrow keys and, possibly, with the pointer.
|
|
60
|
-
* To support it, use the following props of the `DefaultItemRenderer`:
|
|
61
|
-
*
|
|
62
|
-
* - `keyboardFocusable`
|
|
63
|
-
* - Possibly `onClick` invoking `focusRow(e.currentTarget)`
|
|
64
|
-
*
|
|
65
|
-
* In your custom row renderer, use `TableRow`, which also has the `keyboardFocusable` prop.
|
|
66
|
-
*
|
|
67
|
-
* ## Deleting columns
|
|
68
|
-
*
|
|
69
|
-
* You need the following to support deleting columns:
|
|
70
|
-
*
|
|
71
|
-
* - Make sure the `column` has a proper `name` or `key` prop, which will be
|
|
72
|
-
* automatically included in the aria-label of `<DeleteColumnButton />`.
|
|
73
|
-
* - Include `<DeleteColumnButton />` in a column header
|
|
74
|
-
* - Handle `TableProps.onColumnDelete` callback in the client code. It is expected
|
|
75
|
-
* to update `columns` by removing the corresponding column.
|
|
76
|
-
*
|
|
77
|
-
* ## Row virtualization
|
|
78
|
-
*
|
|
79
|
-
* To render only rows near the viewport and replace others with spacers, use:
|
|
80
|
-
*
|
|
81
|
-
* - `virtualizeRows`
|
|
82
|
-
* - `scrollerRef` — required when the scrollable container is not the whole document
|
|
83
|
-
* - `estimateHeight` — recommended when rows are expected to be taller than
|
|
84
|
-
* the default height (e.g. multiline or custom content)
|
|
85
|
-
* - Fine-tuning props: `lookaheadPx`, `retentionMarginPx`, `minScrollAndResizeDeltaPx`
|
|
86
|
-
*/
|
|
87
|
-
export default function Table(props) {
|
|
88
|
-
const { data, columns, getKey, noHeader, onItemMove, onSort, onColumnDelete, onColumnMove, renderItem, virtualizeRows = false, scrollerRef, estimateHeight = () => defaultRowHeight, lookaheadPx = defaultLookaheadPx, retentionMarginPx = defaultRetentionMarginPx, minScrollAndResizeDeltaPx = defaultMinScrollAndResizeDeltaPx, columnEditButton, theadClassName, theadTrClassName, tbodyClassName, ref: userRef, className, ...restProps } = props;
|
|
89
|
-
const localRef = useRef(null);
|
|
90
|
-
const { virtualItems, intersectionObserverHandle, collapseItemIntoSpacer } = useTableVirtualize({
|
|
91
|
-
enabled: virtualizeRows,
|
|
92
|
-
data,
|
|
93
|
-
scrollerRef,
|
|
94
|
-
tableRef: localRef,
|
|
95
|
-
estimateHeight,
|
|
96
|
-
lookaheadPx,
|
|
97
|
-
retentionMarginPx,
|
|
98
|
-
minScrollAndResizeDeltaPx,
|
|
99
|
-
});
|
|
100
|
-
return (<TablePropsContext value={props}>
|
|
101
|
-
<IntersectionObserverContext value={intersectionObserverHandle}>
|
|
102
|
-
<table className={classNames(styles.table, className)} ref={mergeRefs([userRef, localRef])} {...restProps}>
|
|
103
|
-
{!noHeader && (<thead className={theadClassName}>
|
|
104
|
-
<tr className={classNames(styles.headerRow, theadTrClassName)}>
|
|
105
|
-
{columns.map((column, columnIndex) => (<th key={column.key} className={classNames(styles.headerCell, column.thClassName)} aria-sort={column.sortOrder}>
|
|
106
|
-
<ColumnIndexContext value={columnIndex}>
|
|
107
|
-
{column.renderHeader?.() ?? column.name ?? String(column.key)}
|
|
108
|
-
</ColumnIndexContext>
|
|
109
|
-
</th>))}
|
|
110
|
-
</tr>
|
|
111
|
-
</thead>)}
|
|
112
|
-
|
|
113
|
-
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
|
|
114
|
-
<tbody className={tbodyClassName} onKeyDown={onKeyDownTbody} onBlurCapture={onBlurCaptureTbody}>
|
|
115
|
-
{virtualItems.map(virtualItem => {
|
|
116
|
-
if (virtualItem.type === 'spacer') {
|
|
117
|
-
return <SpacerRow key={virtualItem.key} spacer={virtualItem} colSpan={columns.length}/>;
|
|
118
|
-
}
|
|
119
|
-
const index = virtualItem.index;
|
|
120
|
-
const item = data[index];
|
|
121
|
-
const key = getKey(item, index, data);
|
|
122
|
-
return (<CollapseItemIntoSpacerContext value={height => collapseItemIntoSpacer(index, height)} key={key}>
|
|
123
|
-
{renderItem ? renderItem(item, index, data) : <DefaultItemRenderer index={index}/>}
|
|
124
|
-
</CollapseItemIntoSpacerContext>);
|
|
125
|
-
})}
|
|
126
|
-
</tbody>
|
|
127
|
-
</table>
|
|
128
|
-
</IntersectionObserverContext>
|
|
129
|
-
</TablePropsContext>);
|
|
130
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare const keyboardFocusableAttrName = "data-keyboard-focusable";
|
|
2
|
-
export declare function focusRow(row: HTMLTableRowElement): void;
|
|
3
|
-
export declare function onKeyDownTbody(e: React.KeyboardEvent<HTMLTableSectionElement>): void;
|
|
4
|
-
export declare function onBlurCaptureTbody(e: React.FocusEvent<HTMLTableSectionElement>): void;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export const keyboardFocusableAttrName = 'data-keyboard-focusable';
|
|
2
|
-
const temporaryTabIndexAttrName = 'data-temporary-tabindex';
|
|
3
|
-
export function focusRow(row) {
|
|
4
|
-
if (!row.hasAttribute('tabindex')) {
|
|
5
|
-
row.tabIndex = 0;
|
|
6
|
-
row.setAttribute(temporaryTabIndexAttrName, '');
|
|
7
|
-
}
|
|
8
|
-
row.focus();
|
|
9
|
-
}
|
|
10
|
-
export function onKeyDownTbody(e) {
|
|
11
|
-
if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
const tbody = e.currentTarget;
|
|
15
|
-
const currentRow = e.target.closest('tr');
|
|
16
|
-
if (!(currentRow instanceof HTMLTableRowElement) || currentRow.parentElement !== tbody) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
let candidate = currentRow;
|
|
20
|
-
while (candidate) {
|
|
21
|
-
candidate =
|
|
22
|
-
e.key === 'ArrowUp'
|
|
23
|
-
? candidate.previousElementSibling
|
|
24
|
-
: candidate.nextElementSibling;
|
|
25
|
-
if (candidate?.hasAttribute(keyboardFocusableAttrName)) {
|
|
26
|
-
focusRow(candidate);
|
|
27
|
-
e.preventDefault();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export function onBlurCaptureTbody(e) {
|
|
33
|
-
const tbody = e.currentTarget;
|
|
34
|
-
if (!(e.target instanceof HTMLTableRowElement) || e.target.parentElement !== tbody) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const row = e.target;
|
|
38
|
-
if (row.hasAttribute(temporaryTabIndexAttrName)) {
|
|
39
|
-
row.removeAttribute('tabindex');
|
|
40
|
-
row.removeAttribute(temporaryTabIndexAttrName);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { type RefObject } from 'react';
|
|
2
|
-
export type VirtualItem = RenderedItem | Spacer;
|
|
3
|
-
interface RenderedItem {
|
|
4
|
-
type: 'rendered';
|
|
5
|
-
index: number;
|
|
6
|
-
}
|
|
7
|
-
interface Spacer {
|
|
8
|
-
type: 'spacer';
|
|
9
|
-
from: number;
|
|
10
|
-
to: number;
|
|
11
|
-
height: number;
|
|
12
|
-
key: string;
|
|
13
|
-
}
|
|
14
|
-
export declare function useTableVirtualize<T>({ enabled, data, data: { length }, scrollerRef, tableRef, estimateHeight, lookaheadPx, retentionMarginPx, minScrollAndResizeDeltaPx, }: {
|
|
15
|
-
enabled: boolean;
|
|
16
|
-
data: T[];
|
|
17
|
-
scrollerRef: RefObject<HTMLElement | null> | undefined;
|
|
18
|
-
tableRef: RefObject<HTMLTableElement | null>;
|
|
19
|
-
estimateHeight: (item: T, index: number, items: T[]) => number;
|
|
20
|
-
lookaheadPx: number;
|
|
21
|
-
retentionMarginPx: number;
|
|
22
|
-
minScrollAndResizeDeltaPx: number;
|
|
23
|
-
}): {
|
|
24
|
-
virtualItems: VirtualItem[];
|
|
25
|
-
intersectionObserverHandle: import("../global/intersection-observer-context").IntersectionObserverHandle | null;
|
|
26
|
-
collapseItemIntoSpacer: (index: number, height: number) => void;
|
|
27
|
-
};
|
|
28
|
-
export declare function SpacerRow({ spacer: { from, to, height }, colSpan }: {
|
|
29
|
-
spacer: Spacer;
|
|
30
|
-
colSpan: number;
|
|
31
|
-
}): import("react").JSX.Element;
|
|
32
|
-
export {};
|