@cloudscape-design/components 3.0.376 → 3.0.378
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/cards/index.d.ts.map +1 -1
- package/cards/index.js +2 -3
- package/cards/index.js.map +1 -1
- package/internal/analytics/components/analytics-funnel.d.ts.map +1 -1
- package/internal/analytics/components/analytics-funnel.js +62 -5
- package/internal/analytics/components/analytics-funnel.js.map +1 -1
- package/internal/analytics/context/analytics-context.d.ts +2 -0
- package/internal/analytics/context/analytics-context.d.ts.map +1 -1
- package/internal/analytics/context/analytics-context.js +1 -0
- package/internal/analytics/context/analytics-context.js.map +1 -1
- package/internal/analytics/hooks/use-funnel.d.ts.map +1 -1
- package/internal/analytics/hooks/use-funnel.js +6 -2
- package/internal/analytics/hooks/use-funnel.js.map +1 -1
- package/internal/analytics/index.d.ts.map +1 -1
- package/internal/analytics/index.js +2 -0
- package/internal/analytics/index.js.map +1 -1
- package/internal/analytics/interfaces.d.ts +24 -0
- package/internal/analytics/interfaces.d.ts.map +1 -1
- package/internal/analytics/interfaces.js.map +1 -1
- package/internal/analytics/selectors.d.ts +1 -1
- package/internal/analytics/selectors.d.ts.map +1 -1
- package/internal/analytics/selectors.js +1 -1
- package/internal/analytics/selectors.js.map +1 -1
- package/internal/environment.js +1 -1
- package/internal/environment.json +1 -1
- package/internal/manifest.json +1 -1
- package/package.json +1 -1
- package/table/internal.d.ts.map +1 -1
- package/table/internal.js +2 -3
- package/table/internal.js.map +1 -1
- package/table/selection/index.d.ts +6 -0
- package/table/selection/index.d.ts.map +1 -0
- package/table/selection/index.js +7 -0
- package/table/selection/index.js.map +1 -0
- package/table/selection/interfaces.d.ts +10 -0
- package/table/selection/interfaces.d.ts.map +1 -0
- package/table/selection/interfaces.js +4 -0
- package/table/selection/interfaces.js.map +1 -0
- package/table/{selection-control/index.d.ts → selection/selection-control.d.ts} +3 -3
- package/table/selection/selection-control.d.ts.map +1 -0
- package/table/{selection-control/index.js → selection/selection-control.js} +2 -2
- package/table/selection/selection-control.js.map +1 -0
- package/table/selection/styles.css.js +8 -0
- package/table/{selection-control → selection}/styles.scoped.css +3 -3
- package/table/{selection-control → selection}/styles.selectors.js +3 -3
- package/table/selection/use-selection-focus-move.d.ts +12 -0
- package/table/selection/use-selection-focus-move.d.ts.map +1 -0
- package/table/selection/use-selection-focus-move.js +46 -0
- package/table/selection/use-selection-focus-move.js.map +1 -0
- package/table/selection/use-selection.d.ts +9 -0
- package/table/selection/use-selection.d.ts.map +1 -0
- package/table/{use-selection.js → selection/use-selection.js} +5 -64
- package/table/selection/use-selection.js.map +1 -0
- package/table/selection/utils.d.ts +23 -0
- package/table/selection/utils.d.ts.map +1 -0
- package/table/selection/utils.js +22 -0
- package/table/selection/utils.js.map +1 -0
- package/table/table-role/interfaces.d.ts +1 -1
- package/table/table-role/interfaces.js.map +1 -1
- package/table/table-role/table-role-helper.d.ts +2 -8
- package/table/table-role/table-role-helper.d.ts.map +1 -1
- package/table/table-role/table-role-helper.js +0 -6
- package/table/table-role/table-role-helper.js.map +1 -1
- package/table/table-role/use-grid-navigation.js +12 -33
- package/table/table-role/use-grid-navigation.js.map +1 -1
- package/table/table-role/utils.d.ts +1 -6
- package/table/table-role/utils.d.ts.map +1 -1
- package/table/table-role/utils.js +57 -51
- package/table/table-role/utils.js.map +1 -1
- package/table/thead.d.ts +1 -1
- package/table/thead.d.ts.map +1 -1
- package/table/thead.js +1 -2
- package/table/thead.js.map +1 -1
- package/test-utils/dom/table/index.js +1 -1
- package/test-utils/dom/table/index.js.map +1 -1
- package/test-utils/selectors/table/index.js +1 -1
- package/test-utils/selectors/table/index.js.map +1 -1
- package/test-utils/tsconfig.tsbuildinfo +1 -1
- package/table/selection-control/index.d.ts.map +0 -1
- package/table/selection-control/index.js.map +0 -1
- package/table/selection-control/styles.css.js +0 -8
- package/table/use-selection.d.ts +0 -38
- package/table/use-selection.d.ts.map +0 -1
- package/table/use-selection.js.map +0 -1
|
@@ -1,70 +1,11 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import { fireNonCancelableEvent } from '
|
|
5
|
-
import { useUniqueId } from '
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { joinStrings } from '../internal/utils/strings';
|
|
10
|
-
const SELECTION_ITEM = 'selection-item';
|
|
11
|
-
const SELECTION_ROOT = 'selection-root';
|
|
12
|
-
function findSelectionControlByIndex(rootContainer, index) {
|
|
13
|
-
if (index === -1) {
|
|
14
|
-
// find "select all" checkbox
|
|
15
|
-
return rootContainer.querySelector(`[data-${SELECTION_ITEM}="all"] .${selectionStyles.root} input`);
|
|
16
|
-
}
|
|
17
|
-
return rootContainer.querySelectorAll(`[data-${SELECTION_ITEM}="item"] .${selectionStyles.root} input`)[index];
|
|
18
|
-
}
|
|
19
|
-
function findRootContainer(element) {
|
|
20
|
-
return findUpUntil(element, node => node.dataset.selectionRoot === 'true');
|
|
21
|
-
}
|
|
22
|
-
export function useFocusMove(selectionType, totalItems) {
|
|
23
|
-
if (selectionType !== 'multi') {
|
|
24
|
-
return {};
|
|
25
|
-
}
|
|
26
|
-
function moveFocus(sourceElement, fromIndex, direction) {
|
|
27
|
-
let index = fromIndex;
|
|
28
|
-
const rootContainer = findRootContainer(sourceElement);
|
|
29
|
-
while (index >= -1 && index < totalItems) {
|
|
30
|
-
index += direction;
|
|
31
|
-
const control = findSelectionControlByIndex(rootContainer, index);
|
|
32
|
-
if (control && !control.disabled) {
|
|
33
|
-
control.focus();
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const [moveFocusDown, moveFocusUp] = [1, -1].map(direction => {
|
|
39
|
-
return (event) => {
|
|
40
|
-
const target = event.currentTarget;
|
|
41
|
-
const itemNode = findUpUntil(target, node => node.dataset.selectionItem === 'item');
|
|
42
|
-
const fromIndex = Array.prototype.indexOf.call(itemNode.parentElement.children, itemNode);
|
|
43
|
-
moveFocus(target, fromIndex, direction);
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
return {
|
|
47
|
-
moveFocusDown,
|
|
48
|
-
moveFocusUp,
|
|
49
|
-
moveFocus,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
// A set, that compares items by their "trackables" (the results of applying `trackBy` to them)
|
|
53
|
-
class ItemSet {
|
|
54
|
-
constructor(trackBy, items) {
|
|
55
|
-
this.map = new Map();
|
|
56
|
-
this.put = (item) => this.map.set.call(this.map, getTrackableValue(this.trackBy, item), item);
|
|
57
|
-
this.has = (item) => this.map.has.call(this.map, getTrackableValue(this.trackBy, item));
|
|
58
|
-
this.forEach = this.map.forEach.bind(this.map);
|
|
59
|
-
this.trackBy = trackBy;
|
|
60
|
-
items.forEach(this.put);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
export const focusMarkers = {
|
|
64
|
-
item: { ['data-' + SELECTION_ITEM]: 'item' },
|
|
65
|
-
all: { ['data-' + SELECTION_ITEM]: 'all' },
|
|
66
|
-
root: { ['data-' + SELECTION_ROOT]: 'true' },
|
|
67
|
-
};
|
|
4
|
+
import { fireNonCancelableEvent } from '../../internal/events';
|
|
5
|
+
import { useUniqueId } from '../../internal/hooks/use-unique-id';
|
|
6
|
+
import { getTrackableValue } from '../utils';
|
|
7
|
+
import { joinStrings } from '../../internal/utils/strings';
|
|
8
|
+
import { ItemSet } from './utils';
|
|
68
9
|
export function useSelection({ items, selectedItems = [], selectionType, isItemDisabled = () => false, trackBy, onSelectionChange, ariaLabels, loading, }) {
|
|
69
10
|
const [shiftPressed, setShiftPressed] = useState(false);
|
|
70
11
|
const [lastClickedItem, setLastClickedItem] = useState(null);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-selection.js","sourceRoot":"lib/default/","sources":["table/selection/use-selection.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { useState } from 'react';\nimport { fireNonCancelableEvent } from '../../internal/events';\nimport { useUniqueId } from '../../internal/hooks/use-unique-id';\nimport { TableProps } from '../interfaces';\nimport { getTrackableValue } from '../utils';\nimport { joinStrings } from '../../internal/utils/strings';\nimport { SelectionProps } from './interfaces';\nimport { ItemSet } from './utils';\n\nexport function useSelection<T>({\n items,\n selectedItems = [],\n selectionType,\n isItemDisabled = () => false,\n trackBy,\n onSelectionChange,\n ariaLabels,\n loading,\n}: Pick<\n TableProps<T>,\n | 'ariaLabels'\n | 'items'\n | 'selectedItems'\n | 'selectionType'\n | 'isItemDisabled'\n | 'trackBy'\n | 'onSelectionChange'\n | 'loading'\n>) {\n const [shiftPressed, setShiftPressed] = useState(false);\n const [lastClickedItem, setLastClickedItem] = useState<T | null>(null);\n const selectionName = useUniqueId();\n const finalSelectedItems = selectionType === 'single' ? selectedItems.slice(0, 1) : selectedItems;\n const selectedSet = new ItemSet(trackBy, finalSelectedItems);\n const itemIndexesMap = new Map();\n items.forEach((item, i) => itemIndexesMap.set(getTrackableValue(trackBy, item), i));\n const isItemSelected = selectedSet.has.bind(selectedSet);\n const getItemState = (item: T) => ({\n disabled: isItemDisabled(item),\n selected: isItemSelected(item),\n });\n const [allDisabled, allEnabledSelected] = selectionType\n ? items.reduce(\n ([allDisabled, allEnabledSelected], item) => {\n const { disabled, selected } = getItemState(item);\n return [\n // all items are disabled (or none are present)\n allDisabled && disabled,\n // all enabled items are selected (or none are present)\n allEnabledSelected && (selected || disabled),\n ];\n },\n [true, true]\n )\n : [true, true];\n\n // the page has at least one selected item\n const hasSelected = finalSelectedItems.length > 0;\n\n const handleToggleAll = () => {\n const requestedItems = new ItemSet(trackBy, items);\n const newSelectedItems = allEnabledSelected ? deselectItems(requestedItems) : selectItems(requestedItems);\n fireNonCancelableEvent(onSelectionChange, { selectedItems: newSelectedItems });\n };\n\n const getRequestedItems = (item: T) => {\n const requestedItems = new ItemSet(trackBy, [item]);\n let lastClickedItemIndex = lastClickedItem ? itemIndexesMap.get(getTrackableValue(trackBy, lastClickedItem)) : -1;\n if (lastClickedItemIndex === undefined) {\n lastClickedItemIndex = -1;\n }\n // we use lastClickedItemIndex to determine if filtering/sorting/pagination\n // made previously selected item invisible, therefore we reset state for shift-select\n if (shiftPressed && lastClickedItemIndex !== -1) {\n // item is always in items\n const currentItemIndex = itemIndexesMap.get(getTrackableValue(trackBy, item)) as number;\n const start = Math.min(currentItemIndex, lastClickedItemIndex);\n const end = Math.max(currentItemIndex, lastClickedItemIndex);\n items.slice(start, end + 1).forEach(item => requestedItems.put(item));\n }\n return requestedItems;\n };\n\n const deselectItems = (requestedItems: ItemSet<T>) => {\n const newSelectedItems: Array<T> = [];\n selectedItems.forEach(selectedItem => {\n const toUnselect = requestedItems.has(selectedItem);\n if (!toUnselect || isItemDisabled(selectedItem)) {\n newSelectedItems.push(selectedItem);\n }\n });\n return newSelectedItems;\n };\n\n const selectItems = (requestedItems: ItemSet<T>) => {\n const newSelectedItems = [...selectedItems];\n requestedItems.forEach(newItem => {\n const { selected, disabled } = getItemState(newItem);\n if (!selected && !disabled) {\n newSelectedItems.push(newItem);\n }\n });\n return newSelectedItems;\n };\n\n const handleToggleItem = (item: T) => () => {\n const { disabled, selected } = getItemState(item);\n if (disabled || (selectionType === 'single' && selected)) {\n return;\n }\n if (selectionType === 'single') {\n fireNonCancelableEvent(onSelectionChange, { selectedItems: [item] });\n } else {\n const requestedItems = getRequestedItems(item);\n const selectedItems = selected ? deselectItems(requestedItems) : selectItems(requestedItems);\n fireNonCancelableEvent(onSelectionChange, { selectedItems });\n setLastClickedItem(item);\n }\n };\n\n return {\n isItemSelected,\n getSelectAllProps: (): SelectionProps => {\n if (!selectionType) {\n throw new Error('Invariant violation: calling selection props with missing selection type.');\n }\n return {\n name: selectionName,\n disabled: allDisabled || !!loading,\n selectionType: selectionType,\n indeterminate: hasSelected && !allEnabledSelected,\n checked: hasSelected && allEnabledSelected,\n onChange: handleToggleAll,\n ariaLabel: joinStrings(\n ariaLabels?.selectionGroupLabel,\n ariaLabels?.allItemsSelectionLabel?.({ selectedItems })\n ),\n };\n },\n getItemSelectionProps: (item: T): SelectionProps => {\n if (!selectionType) {\n throw new Error('Invariant violation: calling selection props with missing selection type.');\n }\n return {\n name: selectionName,\n selectionType: selectionType,\n ariaLabel: joinStrings(\n ariaLabels?.selectionGroupLabel,\n ariaLabels?.itemSelectionLabel?.({ selectedItems }, item)\n ),\n onChange: handleToggleItem(item),\n checked: isItemSelected(item),\n disabled: isItemDisabled(item),\n };\n },\n updateShiftToggle: (value: boolean) => {\n setShiftPressed(value);\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TableProps } from '../interfaces';
|
|
2
|
+
export declare const SELECTION_ITEM = "selection-item";
|
|
3
|
+
export declare const SELECTION_ROOT = "selection-root";
|
|
4
|
+
export declare class ItemSet<T> {
|
|
5
|
+
constructor(trackBy: TableProps.TrackBy<T> | undefined, items: ReadonlyArray<T>);
|
|
6
|
+
private trackBy;
|
|
7
|
+
private map;
|
|
8
|
+
put: (item: T) => Map<unknown, T>;
|
|
9
|
+
has: (item: T) => boolean;
|
|
10
|
+
forEach: (callbackfn: (value: T, key: unknown, map: Map<unknown, T>) => void, thisArg?: any) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const focusMarkers: {
|
|
13
|
+
item: {
|
|
14
|
+
[x: string]: string;
|
|
15
|
+
};
|
|
16
|
+
all: {
|
|
17
|
+
[x: string]: string;
|
|
18
|
+
};
|
|
19
|
+
root: {
|
|
20
|
+
[x: string]: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"lib/default/","sources":["table/selection/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAC/C,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAG/C,qBAAa,OAAO,CAAC,CAAC;gBACR,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;IAI/E,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,GAAG,CAA8B;IACzC,GAAG,SAAU,CAAC,qBAA8E;IAC5F,GAAG,SAAU,CAAC,aAAwE;IACtF,OAAO,8FAAmC;CAC3C;AAED,eAAO,MAAM,YAAY;;;;;;;;;;CAIxB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { getTrackableValue } from '../utils';
|
|
4
|
+
export const SELECTION_ITEM = 'selection-item';
|
|
5
|
+
export const SELECTION_ROOT = 'selection-root';
|
|
6
|
+
// A set, that compares items by their "trackables" (the results of applying `trackBy` to them)
|
|
7
|
+
export class ItemSet {
|
|
8
|
+
constructor(trackBy, items) {
|
|
9
|
+
this.map = new Map();
|
|
10
|
+
this.put = (item) => this.map.set.call(this.map, getTrackableValue(this.trackBy, item), item);
|
|
11
|
+
this.has = (item) => this.map.has.call(this.map, getTrackableValue(this.trackBy, item));
|
|
12
|
+
this.forEach = this.map.forEach.bind(this.map);
|
|
13
|
+
this.trackBy = trackBy;
|
|
14
|
+
items.forEach(this.put);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export const focusMarkers = {
|
|
18
|
+
item: { ['data-' + SELECTION_ITEM]: 'item' },
|
|
19
|
+
all: { ['data-' + SELECTION_ITEM]: 'all' },
|
|
20
|
+
root: { ['data-' + SELECTION_ROOT]: 'true' },
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"lib/default/","sources":["table/selection/utils.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,+FAA+F;AAC/F,MAAM,OAAO,OAAO;IAClB,YAAY,OAA0C,EAAE,KAAuB;QAKvE,QAAG,GAAoB,IAAI,GAAG,EAAE,CAAC;QACzC,QAAG,GAAG,CAAC,IAAO,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5F,QAAG,GAAG,CAAC,IAAO,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACtF,YAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAPxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CAMF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE;IAC5C,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,EAAE,KAAK,EAAE;IAC1C,IAAI,EAAE,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE;CAC7C,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { TableProps } from '../interfaces';\nimport { getTrackableValue } from '../utils';\n\nexport const SELECTION_ITEM = 'selection-item';\nexport const SELECTION_ROOT = 'selection-root';\n\n// A set, that compares items by their \"trackables\" (the results of applying `trackBy` to them)\nexport class ItemSet<T> {\n constructor(trackBy: TableProps.TrackBy<T> | undefined, items: ReadonlyArray<T>) {\n this.trackBy = trackBy;\n items.forEach(this.put);\n }\n private trackBy: TableProps.TrackBy<T> | undefined;\n private map: Map<unknown, T> = new Map();\n put = (item: T) => this.map.set.call(this.map, getTrackableValue(this.trackBy, item), item);\n has = (item: T) => this.map.has.call(this.map, getTrackableValue(this.trackBy, item));\n forEach = this.map.forEach.bind(this.map);\n}\n\nexport const focusMarkers = {\n item: { ['data-' + SELECTION_ITEM]: 'item' },\n all: { ['data-' + SELECTION_ITEM]: 'all' },\n root: { ['data-' + SELECTION_ROOT]: 'true' },\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.js","sourceRoot":"lib/default/","sources":["table/table-role/interfaces.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nexport type TableRole = 'table' | 'grid' | 'grid-default';\n\nexport interface GridNavigationProps {\n tableRole: TableRole;\n pageSize: number;\n getTable: () => null | HTMLTableElement;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface GridNavigationAPI {}\n\nexport interface FocusedCell {\n rowIndex: number;\n colIndex: number;\n elementIndex: number;\n rowElement: HTMLTableRowElement;\n cellElement: HTMLTableCellElement;\n element: HTMLElement;\n
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"lib/default/","sources":["table/table-role/interfaces.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nexport type TableRole = 'table' | 'grid' | 'grid-default';\n\nexport interface GridNavigationProps {\n tableRole: TableRole;\n pageSize: number;\n getTable: () => null | HTMLTableElement;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface GridNavigationAPI {}\n\nexport interface FocusedCell {\n rowIndex: number;\n colIndex: number;\n elementIndex: number;\n rowElement: HTMLTableRowElement;\n cellElement: HTMLTableCellElement;\n element: HTMLElement;\n dialog: boolean;\n}\n"]}
|
|
@@ -25,17 +25,11 @@ export declare function getTableColHeaderRoleProps(options: {
|
|
|
25
25
|
tableRole: TableRole;
|
|
26
26
|
colIndex: number;
|
|
27
27
|
sortingStatus?: SortingStatus;
|
|
28
|
-
|
|
29
|
-
}): import("react").ThHTMLAttributes<HTMLTableCellElement> & {
|
|
30
|
-
'data-widget-cell'?: boolean | undefined;
|
|
31
|
-
};
|
|
28
|
+
}): import("react").ThHTMLAttributes<HTMLTableCellElement>;
|
|
32
29
|
export declare function getTableCellRoleProps(options: {
|
|
33
30
|
tableRole: TableRole;
|
|
34
31
|
colIndex: number;
|
|
35
32
|
isRowHeader?: boolean;
|
|
36
|
-
|
|
37
|
-
}): import("react").TdHTMLAttributes<HTMLTableCellElement> & {
|
|
38
|
-
'data-widget-cell'?: boolean | undefined;
|
|
39
|
-
};
|
|
33
|
+
}): import("react").TdHTMLAttributes<HTMLTableCellElement>;
|
|
40
34
|
export {};
|
|
41
35
|
//# sourceMappingURL=table-role-helper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-role-helper.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/table-role-helper.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,KAAK,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;AAa7D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAuB9C;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,kDAWpH;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,uDAS3E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,uDAa5G;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"table-role-helper.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/table-role-helper.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,KAAK,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;AAa7D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAuB9C;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,kDAWpH;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,uDAS3E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,uDAa5G;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,0DAcA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,0DAY/G"}
|
|
@@ -66,9 +66,6 @@ export function getTableColHeaderRoleProps(options) {
|
|
|
66
66
|
if (options.sortingStatus) {
|
|
67
67
|
nativeProps['aria-sort'] = getAriaSort(options.sortingStatus);
|
|
68
68
|
}
|
|
69
|
-
if (options.tableRole === 'grid' && options.isWidget) {
|
|
70
|
-
nativeProps['data-widget-cell'] = true;
|
|
71
|
-
}
|
|
72
69
|
return nativeProps;
|
|
73
70
|
}
|
|
74
71
|
export function getTableCellRoleProps(options) {
|
|
@@ -79,9 +76,6 @@ export function getTableCellRoleProps(options) {
|
|
|
79
76
|
if (options.isRowHeader) {
|
|
80
77
|
nativeProps.scope = 'row';
|
|
81
78
|
}
|
|
82
|
-
if (options.tableRole === 'grid' && options.isWidget) {
|
|
83
|
-
nativeProps['data-widget-cell'] = true;
|
|
84
|
-
}
|
|
85
79
|
return nativeProps;
|
|
86
80
|
}
|
|
87
81
|
//# sourceMappingURL=table-role-helper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-role-helper.js","sourceRoot":"lib/default/","sources":["table/table-role/table-role-helper.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAMtC,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,WAAW;IACtB,UAAU,EAAE,YAAY;CAChB,CAAC;AACX,MAAM,WAAW,GAAG,CAAC,YAA2B,EAAE,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;AAEnF,mGAAmG;AACnG,8GAA8G;AAC9G,uFAAuF;AAEvF,MAAM,UAAU,iBAAiB,CAAC,OAMjC;IACC,MAAM,WAAW,GAAgD,EAAE,CAAC;IAEpE,sFAAsF;IACtF,qFAAqF;IACrF,WAAW,CAAC,IAAI,GAAG,OAAO,CAAC,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAErF,WAAW,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAC9C,WAAW,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;IAExD,qEAAqE;IACrE,WAAW,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1F,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE;QAChC,WAAW,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC;KAC1D;IAED,sGAAsG;IACtG,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE;QAChC,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;KAC3B;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAA4E;IACnH,MAAM,WAAW,GAAyC,EAAE,CAAC;IAE7D,iIAAiI;IACjI,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE;QACxD,WAAW,CAAC,IAAI,GAAG,QAAQ,CAAC;QAC5B,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,WAAW,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;KAC/C;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAiC;IAC1E,MAAM,WAAW,GAA8C,EAAE,CAAC;IAElE,kFAAkF;IAClF,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,IAAI,OAAO,CAAC,SAAS,KAAK,cAAc,EAAE;QACxE,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;KAClC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAwE;IAC3G,MAAM,WAAW,GAA8C,EAAE,CAAC;IAElE,8EAA8E;IAC9E,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE;QAChC,WAAW,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;KACjF;IACD,8FAA8F;SACzF,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE;QACzC,WAAW,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;KAC1E;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,
|
|
1
|
+
{"version":3,"file":"table-role-helper.js","sourceRoot":"lib/default/","sources":["table/table-role/table-role-helper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { TableRole } from './interfaces';\n\ntype SortingStatus = 'sortable' | 'ascending' | 'descending';\n\nconst stateToAriaSort = {\n sortable: 'none',\n ascending: 'ascending',\n descending: 'descending',\n} as const;\nconst getAriaSort = (sortingState: SortingStatus) => stateToAriaSort[sortingState];\n\n// Depending on its content the table can have different semantic representation which includes the\n// ARIA role of the table component (\"table\", \"grid\", \"treegrid\") but also roles and other semantic attributes\n// of the child elements. The TableRole helper encapsulates table's semantic structure.\n\nexport function getTableRoleProps(options: {\n tableRole: TableRole;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n totalItemsCount?: number;\n totalColumnsCount?: number;\n}): React.TableHTMLAttributes<HTMLTableElement> {\n const nativeProps: React.TableHTMLAttributes<HTMLTableElement> = {};\n\n // Browsers have weird mechanism to guess whether it's a data table or a layout table.\n // If we state explicitly, they get it always correctly even with low number of rows.\n nativeProps.role = options.tableRole === 'grid-default' ? 'grid' : options.tableRole;\n\n nativeProps['aria-label'] = options.ariaLabel;\n nativeProps['aria-labelledby'] = options.ariaLabelledBy;\n\n // Incrementing the total count by one to account for the header row.\n nativeProps['aria-rowcount'] = options.totalItemsCount ? options.totalItemsCount + 1 : -1;\n\n if (options.tableRole === 'grid') {\n nativeProps['aria-colcount'] = options.totalColumnsCount;\n }\n\n // Make table component programmatically focusable to attach focusin/focusout for keyboard navigation.\n if (options.tableRole === 'grid') {\n nativeProps.tabIndex = -1;\n }\n\n return nativeProps;\n}\n\nexport function getTableWrapperRoleProps(options: { tableRole: TableRole; isScrollable: boolean; ariaLabel?: string }) {\n const nativeProps: React.HTMLAttributes<HTMLDivElement> = {};\n\n // When the table is scrollable, the wrapper is made focusable so that keyboard users can scroll it horizontally with arrow keys.\n if (options.isScrollable && options.tableRole !== 'grid') {\n nativeProps.role = 'region';\n nativeProps.tabIndex = 0;\n nativeProps['aria-label'] = options.ariaLabel;\n }\n\n return nativeProps;\n}\n\nexport function getTableHeaderRowRoleProps(options: { tableRole: TableRole }) {\n const nativeProps: React.HTMLAttributes<HTMLTableRowElement> = {};\n\n // For grids headers are treated similar to data rows and are indexed accordingly.\n if (options.tableRole === 'grid' || options.tableRole === 'grid-default') {\n nativeProps['aria-rowindex'] = 1;\n }\n\n return nativeProps;\n}\n\nexport function getTableRowRoleProps(options: { tableRole: TableRole; rowIndex: number; firstIndex?: number }) {\n const nativeProps: React.HTMLAttributes<HTMLTableRowElement> = {};\n\n // The data cell indices are incremented by 1 to account for the header cells.\n if (options.tableRole === 'grid') {\n nativeProps['aria-rowindex'] = (options.firstIndex || 1) + options.rowIndex + 1;\n }\n // For tables indices are only added when the first index is not 0 (not the first page/frame).\n else if (options.firstIndex !== undefined) {\n nativeProps['aria-rowindex'] = options.firstIndex + options.rowIndex + 1;\n }\n\n return nativeProps;\n}\n\nexport function getTableColHeaderRoleProps(options: {\n tableRole: TableRole;\n colIndex: number;\n sortingStatus?: SortingStatus;\n}) {\n const nativeProps: React.ThHTMLAttributes<HTMLTableCellElement> = {};\n\n nativeProps.scope = 'col';\n\n if (options.tableRole === 'grid') {\n nativeProps['aria-colindex'] = options.colIndex + 1;\n }\n\n if (options.sortingStatus) {\n nativeProps['aria-sort'] = getAriaSort(options.sortingStatus);\n }\n\n return nativeProps;\n}\n\nexport function getTableCellRoleProps(options: { tableRole: TableRole; colIndex: number; isRowHeader?: boolean }) {\n const nativeProps: React.TdHTMLAttributes<HTMLTableCellElement> = {};\n\n if (options.tableRole === 'grid') {\n nativeProps['aria-colindex'] = options.colIndex + 1;\n }\n\n if (options.isRowHeader) {\n nativeProps.scope = 'row';\n }\n\n return nativeProps;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { useEffect, useMemo } from 'react';
|
|
4
|
-
import { findFocusinCell, moveFocusBy,
|
|
4
|
+
import { findFocusinCell, moveFocusBy, restoreTableFocusables, updateTableFocusables } from './utils';
|
|
5
5
|
import { KeyCode } from '../../internal/keycode';
|
|
6
6
|
import { nodeContains } from '@cloudscape-design/component-toolkit/dom';
|
|
7
7
|
/**
|
|
@@ -41,6 +41,10 @@ class GridNavigationModel {
|
|
|
41
41
|
if (!cell) {
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
+
if (cell.element !== event.target) {
|
|
45
|
+
cell.element.focus();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
44
48
|
this.prevFocusedCell = cell;
|
|
45
49
|
this.focusedCell = cell;
|
|
46
50
|
updateTableFocusables(this.table, cell);
|
|
@@ -52,7 +56,6 @@ class GridNavigationModel {
|
|
|
52
56
|
if (!this.focusedCell) {
|
|
53
57
|
return;
|
|
54
58
|
}
|
|
55
|
-
const f2Code = 113;
|
|
56
59
|
const ctrlKey = event.ctrlKey ? 1 : 0;
|
|
57
60
|
const altKey = event.altKey ? 1 : 0;
|
|
58
61
|
const shiftKey = event.shiftKey ? 1 : 0;
|
|
@@ -68,12 +71,8 @@ class GridNavigationModel {
|
|
|
68
71
|
const from = this.focusedCell;
|
|
69
72
|
const minExtreme = Number.NEGATIVE_INFINITY;
|
|
70
73
|
const maxExtreme = Number.POSITIVE_INFINITY;
|
|
71
|
-
// When focus is inside
|
|
72
|
-
if (from.
|
|
73
|
-
if (key === KeyCode.escape || key === f2Code) {
|
|
74
|
-
event.preventDefault();
|
|
75
|
-
return moveFocusBy(this.table, from, { y: 0, x: 0 });
|
|
76
|
-
}
|
|
74
|
+
// When focus is inside a dialog do not intercept any keyboard input.
|
|
75
|
+
if (from.dialog) {
|
|
77
76
|
return;
|
|
78
77
|
}
|
|
79
78
|
switch (key) {
|
|
@@ -107,31 +106,11 @@ class GridNavigationModel {
|
|
|
107
106
|
case -KeyCode.end:
|
|
108
107
|
event.preventDefault();
|
|
109
108
|
return moveFocusBy(this.table, from, { y: maxExtreme, x: maxExtreme });
|
|
110
|
-
case KeyCode.enter:
|
|
111
|
-
if (from.element === from.cellElement) {
|
|
112
|
-
event.preventDefault();
|
|
113
|
-
return moveFocusIn(from);
|
|
114
|
-
}
|
|
115
|
-
break;
|
|
116
|
-
case KeyCode.escape:
|
|
117
|
-
if (from.element !== from.cellElement) {
|
|
118
|
-
event.preventDefault();
|
|
119
|
-
return moveFocusBy(this.table, from, { y: 0, x: 0 });
|
|
120
|
-
}
|
|
121
|
-
break;
|
|
122
|
-
case f2Code:
|
|
123
|
-
event.preventDefault();
|
|
124
|
-
if (from.element === from.cellElement) {
|
|
125
|
-
return moveFocusIn(from);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
return moveFocusBy(this.table, from, { y: 0, x: 0 });
|
|
129
|
-
}
|
|
130
109
|
default:
|
|
131
110
|
return;
|
|
132
111
|
}
|
|
133
112
|
};
|
|
134
|
-
this.
|
|
113
|
+
this.onTableNodeMutation = (mutationRecords) => {
|
|
135
114
|
var _a;
|
|
136
115
|
if (!this.prevFocusedCell) {
|
|
137
116
|
return;
|
|
@@ -141,12 +120,12 @@ class GridNavigationModel {
|
|
|
141
120
|
if (record.type === 'childList') {
|
|
142
121
|
for (const removedNode of Array.from(record.removedNodes)) {
|
|
143
122
|
if (removedNode === this.prevFocusedCell.element || nodeContains(removedNode, this.prevFocusedCell.element)) {
|
|
123
|
+
updateTableFocusables(this.table, (_a = this.focusedCell) !== null && _a !== void 0 ? _a : this.prevFocusedCell);
|
|
144
124
|
moveFocusBy(this.table, this.prevFocusedCell, { y: 0, x: 0 });
|
|
145
125
|
}
|
|
146
126
|
}
|
|
147
127
|
}
|
|
148
128
|
}
|
|
149
|
-
updateTableFocusables(this.table, (_a = this.focusedCell) !== null && _a !== void 0 ? _a : this.prevFocusedCell);
|
|
150
129
|
};
|
|
151
130
|
}
|
|
152
131
|
init(table) {
|
|
@@ -155,14 +134,14 @@ class GridNavigationModel {
|
|
|
155
134
|
this.table.addEventListener('focusin', this.onFocusin);
|
|
156
135
|
this.table.addEventListener('focusout', this.onFocusout);
|
|
157
136
|
this.table.addEventListener('keydown', this.onKeydown);
|
|
158
|
-
const
|
|
159
|
-
|
|
137
|
+
const tableNodesObserver = new MutationObserver(this.onTableNodeMutation);
|
|
138
|
+
tableNodesObserver.observe(table, { childList: true, subtree: true });
|
|
160
139
|
updateTableFocusables(this.table, (_a = this.focusedCell) !== null && _a !== void 0 ? _a : this.prevFocusedCell);
|
|
161
140
|
this.cleanup = () => {
|
|
162
141
|
this.table.removeEventListener('focusin', this.onFocusin);
|
|
163
142
|
this.table.removeEventListener('focusout', this.onFocusout);
|
|
164
143
|
this.table.removeEventListener('keydown', this.onKeydown);
|
|
165
|
-
|
|
144
|
+
tableNodesObserver.disconnect();
|
|
166
145
|
restoreTableFocusables(this.table);
|
|
167
146
|
};
|
|
168
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-grid-navigation.js","sourceRoot":"lib/default/","sources":["table/table-role/use-grid-navigation.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useEffect, useMemo } from 'react';\nimport { findFocusinCell, moveFocusBy, moveFocusIn, restoreTableFocusables, updateTableFocusables } from './utils';\nimport { FocusedCell, GridNavigationAPI, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { nodeContains } from '@cloudscape-design/component-toolkit/dom';\n\n/**\n * Makes table with role=\"grid\" navigable with keyboard commands.\n * See https://www.w3.org/WAI/ARIA/apg/patterns/grid\n */\nexport function useGridNavigation({ tableRole, pageSize, getTable }: GridNavigationProps): GridNavigationAPI {\n const model = useMemo(() => new GridNavigationModel(), []);\n\n // Initialize the model with the table container assuming it is mounted synchronously and only once.\n useEffect(\n () => {\n if (tableRole === 'grid') {\n const table = getTable();\n table && model.init(table);\n }\n return () => model.destroy();\n },\n // Assuming getTable is stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [model, tableRole]\n );\n\n // Notify the model of the props change.\n useEffect(() => {\n model.update({ pageSize });\n }, [model, pageSize]);\n\n return {};\n}\n\nclass GridNavigationModel {\n // Props\n private _pageSize = 0;\n private _table: null | HTMLTableElement = null;\n\n // State\n private prevFocusedCell: null | FocusedCell = null;\n private focusedCell: null | FocusedCell = null;\n private cleanup = () => {};\n\n public init(table: HTMLTableElement) {\n this._table = table;\n\n this.table.addEventListener('focusin', this.onFocusin);\n this.table.addEventListener('focusout', this.onFocusout);\n this.table.addEventListener('keydown', this.onKeydown);\n\n const mutationObserver = new MutationObserver(this.onMutation);\n mutationObserver.observe(table, { childList: true, subtree: true });\n\n updateTableFocusables(this.table, this.focusedCell ?? this.prevFocusedCell);\n\n this.cleanup = () => {\n this.table.removeEventListener('focusin', this.onFocusin);\n this.table.removeEventListener('focusout', this.onFocusout);\n this.table.removeEventListener('keydown', this.onKeydown);\n\n mutationObserver.disconnect();\n\n restoreTableFocusables(this.table);\n };\n }\n\n public destroy() {\n this.cleanup();\n }\n\n public update({ pageSize }: { pageSize: number }) {\n this._pageSize = pageSize;\n }\n\n private get pageSize() {\n return this._pageSize;\n }\n\n private get table(): HTMLTableElement {\n if (!this._table) {\n throw new Error('Invariant violation: GridNavigationModel is used before initialization.');\n }\n return this._table;\n }\n\n private onFocusin = (event: FocusEvent) => {\n const cell = findFocusinCell(event);\n\n if (!cell) {\n return;\n }\n this.prevFocusedCell = cell;\n this.focusedCell = cell;\n\n updateTableFocusables(this.table, cell);\n };\n\n private onFocusout = () => {\n this.focusedCell = null;\n };\n\n private onKeydown = (event: KeyboardEvent) => {\n if (!this.focusedCell) {\n return;\n }\n\n const f2Code = 113;\n const ctrlKey = event.ctrlKey ? 1 : 0;\n const altKey = event.altKey ? 1 : 0;\n const shiftKey = event.shiftKey ? 1 : 0;\n const metaKey = event.metaKey ? 1 : 0;\n const numModifiersPressed = ctrlKey + altKey + shiftKey + metaKey;\n\n let key = event.keyCode;\n if (numModifiersPressed === 1 && event.ctrlKey) {\n key = -key;\n } else if (numModifiersPressed) {\n return;\n }\n\n const from = this.focusedCell;\n const minExtreme = Number.NEGATIVE_INFINITY;\n const maxExtreme = Number.POSITIVE_INFINITY;\n\n // When focus is inside widget cell only intercept Escape and F2 commands to move focus back to cell.\n if (from.widget && from.element !== from.cellElement) {\n if (key === KeyCode.escape || key === f2Code) {\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: 0 });\n }\n return;\n }\n\n switch (key) {\n case KeyCode.up:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: -1, x: 0 });\n\n case KeyCode.down:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 1, x: 0 });\n\n case KeyCode.left:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: -1 });\n\n case KeyCode.right:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: 1 });\n\n case KeyCode.pageUp:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: -this.pageSize, x: 0 });\n\n case KeyCode.pageDown:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: this.pageSize, x: 0 });\n\n case KeyCode.home:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: minExtreme });\n\n case KeyCode.end:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: maxExtreme });\n\n case -KeyCode.home:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: minExtreme, x: minExtreme });\n\n case -KeyCode.end:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: maxExtreme, x: maxExtreme });\n\n case KeyCode.enter:\n if (from.element === from.cellElement) {\n event.preventDefault();\n return moveFocusIn(from);\n }\n break;\n\n case KeyCode.escape:\n if (from.element !== from.cellElement) {\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: 0 });\n }\n break;\n\n case f2Code:\n event.preventDefault();\n if (from.element === from.cellElement) {\n return moveFocusIn(from);\n } else {\n return moveFocusBy(this.table, from, { y: 0, x: 0 });\n }\n\n default:\n return;\n }\n };\n\n private onMutation = (mutationRecords: MutationRecord[]) => {\n if (!this.prevFocusedCell) {\n return;\n }\n\n // When focused cell was un-mounted - re-apply focus to the same location.\n for (const record of mutationRecords) {\n if (record.type === 'childList') {\n for (const removedNode of Array.from(record.removedNodes)) {\n if (removedNode === this.prevFocusedCell.element || nodeContains(removedNode, this.prevFocusedCell.element)) {\n moveFocusBy(this.table, this.prevFocusedCell, { y: 0, x: 0 });\n }\n }\n }\n }\n\n updateTableFocusables(this.table, this.focusedCell ?? this.prevFocusedCell);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-grid-navigation.js","sourceRoot":"lib/default/","sources":["table/table-role/use-grid-navigation.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useEffect, useMemo } from 'react';\nimport { findFocusinCell, moveFocusBy, restoreTableFocusables, updateTableFocusables } from './utils';\nimport { FocusedCell, GridNavigationAPI, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { nodeContains } from '@cloudscape-design/component-toolkit/dom';\n\n/**\n * Makes table with role=\"grid\" navigable with keyboard commands.\n * See https://www.w3.org/WAI/ARIA/apg/patterns/grid\n */\nexport function useGridNavigation({ tableRole, pageSize, getTable }: GridNavigationProps): GridNavigationAPI {\n const model = useMemo(() => new GridNavigationModel(), []);\n\n // Initialize the model with the table container assuming it is mounted synchronously and only once.\n useEffect(\n () => {\n if (tableRole === 'grid') {\n const table = getTable();\n table && model.init(table);\n }\n return () => model.destroy();\n },\n // Assuming getTable is stable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [model, tableRole]\n );\n\n // Notify the model of the props change.\n useEffect(() => {\n model.update({ pageSize });\n }, [model, pageSize]);\n\n return {};\n}\n\nclass GridNavigationModel {\n // Props\n private _pageSize = 0;\n private _table: null | HTMLTableElement = null;\n\n // State\n private prevFocusedCell: null | FocusedCell = null;\n private focusedCell: null | FocusedCell = null;\n private cleanup = () => {};\n\n public init(table: HTMLTableElement) {\n this._table = table;\n\n this.table.addEventListener('focusin', this.onFocusin);\n this.table.addEventListener('focusout', this.onFocusout);\n this.table.addEventListener('keydown', this.onKeydown);\n\n const tableNodesObserver = new MutationObserver(this.onTableNodeMutation);\n tableNodesObserver.observe(table, { childList: true, subtree: true });\n\n updateTableFocusables(this.table, this.focusedCell ?? this.prevFocusedCell);\n\n this.cleanup = () => {\n this.table.removeEventListener('focusin', this.onFocusin);\n this.table.removeEventListener('focusout', this.onFocusout);\n this.table.removeEventListener('keydown', this.onKeydown);\n\n tableNodesObserver.disconnect();\n\n restoreTableFocusables(this.table);\n };\n }\n\n public destroy() {\n this.cleanup();\n }\n\n public update({ pageSize }: { pageSize: number }) {\n this._pageSize = pageSize;\n }\n\n private get pageSize() {\n return this._pageSize;\n }\n\n private get table(): HTMLTableElement {\n if (!this._table) {\n throw new Error('Invariant violation: GridNavigationModel is used before initialization.');\n }\n return this._table;\n }\n\n private onFocusin = (event: FocusEvent) => {\n const cell = findFocusinCell(event);\n\n if (!cell) {\n return;\n }\n\n if (cell.element !== event.target) {\n cell.element.focus();\n return;\n }\n\n this.prevFocusedCell = cell;\n this.focusedCell = cell;\n\n updateTableFocusables(this.table, cell);\n };\n\n private onFocusout = () => {\n this.focusedCell = null;\n };\n\n private onKeydown = (event: KeyboardEvent) => {\n if (!this.focusedCell) {\n return;\n }\n\n const ctrlKey = event.ctrlKey ? 1 : 0;\n const altKey = event.altKey ? 1 : 0;\n const shiftKey = event.shiftKey ? 1 : 0;\n const metaKey = event.metaKey ? 1 : 0;\n const numModifiersPressed = ctrlKey + altKey + shiftKey + metaKey;\n\n let key = event.keyCode;\n if (numModifiersPressed === 1 && event.ctrlKey) {\n key = -key;\n } else if (numModifiersPressed) {\n return;\n }\n\n const from = this.focusedCell;\n const minExtreme = Number.NEGATIVE_INFINITY;\n const maxExtreme = Number.POSITIVE_INFINITY;\n\n // When focus is inside a dialog do not intercept any keyboard input.\n if (from.dialog) {\n return;\n }\n\n switch (key) {\n case KeyCode.up:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: -1, x: 0 });\n\n case KeyCode.down:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 1, x: 0 });\n\n case KeyCode.left:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: -1 });\n\n case KeyCode.right:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: 1 });\n\n case KeyCode.pageUp:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: -this.pageSize, x: 0 });\n\n case KeyCode.pageDown:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: this.pageSize, x: 0 });\n\n case KeyCode.home:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: minExtreme });\n\n case KeyCode.end:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: 0, x: maxExtreme });\n\n case -KeyCode.home:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: minExtreme, x: minExtreme });\n\n case -KeyCode.end:\n event.preventDefault();\n return moveFocusBy(this.table, from, { y: maxExtreme, x: maxExtreme });\n\n default:\n return;\n }\n };\n\n private onTableNodeMutation = (mutationRecords: MutationRecord[]) => {\n if (!this.prevFocusedCell) {\n return;\n }\n\n // When focused cell was un-mounted - re-apply focus to the same location.\n for (const record of mutationRecords) {\n if (record.type === 'childList') {\n for (const removedNode of Array.from(record.removedNodes)) {\n if (removedNode === this.prevFocusedCell.element || nodeContains(removedNode, this.prevFocusedCell.element)) {\n updateTableFocusables(this.table, this.focusedCell ?? this.prevFocusedCell);\n moveFocusBy(this.table, this.prevFocusedCell, { y: 0, x: 0 });\n }\n }\n }\n }\n };\n}\n"]}
|
|
@@ -5,17 +5,12 @@ import { FocusedCell } from './interfaces';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare function findFocusinCell(event: FocusEvent): null | FocusedCell;
|
|
7
7
|
/**
|
|
8
|
-
* Moves table focus in the provided direction. The focus can transition between cells or
|
|
9
|
-
* focusable elements within a cell unless the cell is marked as a widget.
|
|
8
|
+
* Moves table focus in the provided direction. The focus can transition between cells or interactive elements inside cells.
|
|
10
9
|
*/
|
|
11
10
|
export declare function moveFocusBy(table: HTMLTableElement, from: FocusedCell, delta: {
|
|
12
11
|
y: number;
|
|
13
12
|
x: number;
|
|
14
13
|
}): void;
|
|
15
|
-
/**
|
|
16
|
-
* Moves focus to the first focusable element inside the cell.
|
|
17
|
-
*/
|
|
18
|
-
export declare function moveFocusIn(from: FocusedCell): void;
|
|
19
14
|
/**
|
|
20
15
|
* Overrides focusability of the table elements to make focus targets controllable with keyboard commands.
|
|
21
16
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAM3C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,WAAW,CAgCrE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,QA4BtG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,QA8BtF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,QAQ7D"}
|