@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.
Files changed (84) hide show
  1. package/cards/index.d.ts.map +1 -1
  2. package/cards/index.js +2 -3
  3. package/cards/index.js.map +1 -1
  4. package/internal/analytics/components/analytics-funnel.d.ts.map +1 -1
  5. package/internal/analytics/components/analytics-funnel.js +62 -5
  6. package/internal/analytics/components/analytics-funnel.js.map +1 -1
  7. package/internal/analytics/context/analytics-context.d.ts +2 -0
  8. package/internal/analytics/context/analytics-context.d.ts.map +1 -1
  9. package/internal/analytics/context/analytics-context.js +1 -0
  10. package/internal/analytics/context/analytics-context.js.map +1 -1
  11. package/internal/analytics/hooks/use-funnel.d.ts.map +1 -1
  12. package/internal/analytics/hooks/use-funnel.js +6 -2
  13. package/internal/analytics/hooks/use-funnel.js.map +1 -1
  14. package/internal/analytics/index.d.ts.map +1 -1
  15. package/internal/analytics/index.js +2 -0
  16. package/internal/analytics/index.js.map +1 -1
  17. package/internal/analytics/interfaces.d.ts +24 -0
  18. package/internal/analytics/interfaces.d.ts.map +1 -1
  19. package/internal/analytics/interfaces.js.map +1 -1
  20. package/internal/analytics/selectors.d.ts +1 -1
  21. package/internal/analytics/selectors.d.ts.map +1 -1
  22. package/internal/analytics/selectors.js +1 -1
  23. package/internal/analytics/selectors.js.map +1 -1
  24. package/internal/environment.js +1 -1
  25. package/internal/environment.json +1 -1
  26. package/internal/manifest.json +1 -1
  27. package/package.json +1 -1
  28. package/table/internal.d.ts.map +1 -1
  29. package/table/internal.js +2 -3
  30. package/table/internal.js.map +1 -1
  31. package/table/selection/index.d.ts +6 -0
  32. package/table/selection/index.d.ts.map +1 -0
  33. package/table/selection/index.js +7 -0
  34. package/table/selection/index.js.map +1 -0
  35. package/table/selection/interfaces.d.ts +10 -0
  36. package/table/selection/interfaces.d.ts.map +1 -0
  37. package/table/selection/interfaces.js +4 -0
  38. package/table/selection/interfaces.js.map +1 -0
  39. package/table/{selection-control/index.d.ts → selection/selection-control.d.ts} +3 -3
  40. package/table/selection/selection-control.d.ts.map +1 -0
  41. package/table/{selection-control/index.js → selection/selection-control.js} +2 -2
  42. package/table/selection/selection-control.js.map +1 -0
  43. package/table/selection/styles.css.js +8 -0
  44. package/table/{selection-control → selection}/styles.scoped.css +3 -3
  45. package/table/{selection-control → selection}/styles.selectors.js +3 -3
  46. package/table/selection/use-selection-focus-move.d.ts +12 -0
  47. package/table/selection/use-selection-focus-move.d.ts.map +1 -0
  48. package/table/selection/use-selection-focus-move.js +46 -0
  49. package/table/selection/use-selection-focus-move.js.map +1 -0
  50. package/table/selection/use-selection.d.ts +9 -0
  51. package/table/selection/use-selection.d.ts.map +1 -0
  52. package/table/{use-selection.js → selection/use-selection.js} +5 -64
  53. package/table/selection/use-selection.js.map +1 -0
  54. package/table/selection/utils.d.ts +23 -0
  55. package/table/selection/utils.d.ts.map +1 -0
  56. package/table/selection/utils.js +22 -0
  57. package/table/selection/utils.js.map +1 -0
  58. package/table/table-role/interfaces.d.ts +1 -1
  59. package/table/table-role/interfaces.js.map +1 -1
  60. package/table/table-role/table-role-helper.d.ts +2 -8
  61. package/table/table-role/table-role-helper.d.ts.map +1 -1
  62. package/table/table-role/table-role-helper.js +0 -6
  63. package/table/table-role/table-role-helper.js.map +1 -1
  64. package/table/table-role/use-grid-navigation.js +12 -33
  65. package/table/table-role/use-grid-navigation.js.map +1 -1
  66. package/table/table-role/utils.d.ts +1 -6
  67. package/table/table-role/utils.d.ts.map +1 -1
  68. package/table/table-role/utils.js +57 -51
  69. package/table/table-role/utils.js.map +1 -1
  70. package/table/thead.d.ts +1 -1
  71. package/table/thead.d.ts.map +1 -1
  72. package/table/thead.js +1 -2
  73. package/table/thead.js.map +1 -1
  74. package/test-utils/dom/table/index.js +1 -1
  75. package/test-utils/dom/table/index.js.map +1 -1
  76. package/test-utils/selectors/table/index.js +1 -1
  77. package/test-utils/selectors/table/index.js.map +1 -1
  78. package/test-utils/tsconfig.tsbuildinfo +1 -1
  79. package/table/selection-control/index.d.ts.map +0 -1
  80. package/table/selection-control/index.js.map +0 -1
  81. package/table/selection-control/styles.css.js +0 -8
  82. package/table/use-selection.d.ts +0 -38
  83. package/table/use-selection.d.ts.map +0 -1
  84. 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 '../internal/events';
5
- import { useUniqueId } from '../internal/hooks/use-unique-id';
6
- import { findUpUntil } from '../internal/utils/dom';
7
- import { getTrackableValue } from './utils';
8
- import selectionStyles from './selection-control/styles.css.js';
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"]}
@@ -13,6 +13,6 @@ export interface FocusedCell {
13
13
  rowElement: HTMLTableRowElement;
14
14
  cellElement: HTMLTableCellElement;
15
15
  element: HTMLElement;
16
- widget: boolean;
16
+ dialog: boolean;
17
17
  }
18
18
  //# sourceMappingURL=interfaces.d.ts.map
@@ -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 widget: boolean;\n}\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
- isWidget?: boolean;
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
- isWidget?: boolean;
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;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;;EAkBA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;;EAgBA"}
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":"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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 isWidget?: boolean;\n}) {\n const nativeProps: React.ThHTMLAttributes<HTMLTableCellElement> & { 'data-widget-cell'?: boolean } = {};\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 if (options.tableRole === 'grid' && options.isWidget) {\n nativeProps['data-widget-cell'] = true;\n }\n\n return nativeProps;\n}\n\nexport function getTableCellRoleProps(options: {\n tableRole: TableRole;\n colIndex: number;\n isRowHeader?: boolean;\n isWidget?: boolean;\n}) {\n const nativeProps: React.TdHTMLAttributes<HTMLTableCellElement> & { 'data-widget-cell'?: boolean } = {};\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 if (options.tableRole === 'grid' && options.isWidget) {\n nativeProps['data-widget-cell'] = true;\n }\n\n return nativeProps;\n}\n"]}
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, moveFocusIn, restoreTableFocusables, updateTableFocusables } from './utils';
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 widget cell only intercept Escape and F2 commands to move focus back to cell.
72
- if (from.widget && from.element !== from.cellElement) {
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.onMutation = (mutationRecords) => {
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 mutationObserver = new MutationObserver(this.onMutation);
159
- mutationObserver.observe(table, { childList: true, subtree: true });
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
- mutationObserver.disconnect();
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 between
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;AAE3C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,WAAW,CA0BrE;AAED;;;GAGG;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,QAuCtG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,QAE5C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,QAkCtF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,QAQ7D"}
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"}