@cloudscape-design/components 3.0.362 → 3.0.364

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 (144) hide show
  1. package/alert/index.d.ts.map +1 -1
  2. package/alert/index.js +21 -16
  3. package/alert/index.js.map +1 -1
  4. package/alert/internal.d.ts.map +1 -1
  5. package/alert/internal.js +13 -14
  6. package/alert/internal.js.map +1 -1
  7. package/alert/styles.css.js +25 -25
  8. package/alert/styles.scoped.css +52 -66
  9. package/alert/styles.selectors.js +25 -25
  10. package/area-chart/model/use-chart-model.js +1 -1
  11. package/area-chart/model/use-chart-model.js.map +1 -1
  12. package/breadcrumb-group/internal.d.ts.map +1 -1
  13. package/breadcrumb-group/internal.js +5 -5
  14. package/breadcrumb-group/internal.js.map +1 -1
  15. package/button-dropdown/interfaces.d.ts +9 -1
  16. package/button-dropdown/interfaces.d.ts.map +1 -1
  17. package/button-dropdown/interfaces.js.map +1 -1
  18. package/button-dropdown/internal.d.ts.map +1 -1
  19. package/button-dropdown/internal.js +9 -2
  20. package/button-dropdown/internal.js.map +1 -1
  21. package/button-dropdown/styles.css.js +15 -14
  22. package/button-dropdown/styles.scoped.css +25 -21
  23. package/button-dropdown/styles.selectors.js +15 -14
  24. package/code-editor/index.d.ts.map +1 -1
  25. package/code-editor/index.js +26 -71
  26. package/code-editor/index.js.map +1 -1
  27. package/code-editor/listeners.d.ts +1 -1
  28. package/code-editor/listeners.d.ts.map +1 -1
  29. package/code-editor/listeners.js.map +1 -1
  30. package/code-editor/setup-editor.d.ts.map +1 -1
  31. package/code-editor/setup-editor.js +39 -36
  32. package/code-editor/setup-editor.js.map +1 -1
  33. package/code-editor/use-editor.d.ts +24 -0
  34. package/code-editor/use-editor.d.ts.map +1 -0
  35. package/code-editor/use-editor.js +71 -0
  36. package/code-editor/use-editor.js.map +1 -0
  37. package/form/index.d.ts.map +1 -1
  38. package/form/index.js +2 -1
  39. package/form/index.js.map +1 -1
  40. package/form-field/internal.d.ts.map +1 -1
  41. package/form-field/internal.js +17 -12
  42. package/form-field/internal.js.map +1 -1
  43. package/internal/analytics/components/analytics-funnel.d.ts +1 -1
  44. package/internal/analytics/components/analytics-funnel.d.ts.map +1 -1
  45. package/internal/analytics/components/analytics-funnel.js +92 -26
  46. package/internal/analytics/components/analytics-funnel.js.map +1 -1
  47. package/internal/analytics/context/analytics-context.d.ts +4 -0
  48. package/internal/analytics/context/analytics-context.d.ts.map +1 -1
  49. package/internal/analytics/context/analytics-context.js +4 -0
  50. package/internal/analytics/context/analytics-context.js.map +1 -1
  51. package/internal/analytics/hooks/use-funnel.d.ts +2 -0
  52. package/internal/analytics/hooks/use-funnel.d.ts.map +1 -1
  53. package/internal/components/chart-popover/index.d.ts.map +1 -1
  54. package/internal/components/chart-popover/index.js +1 -1
  55. package/internal/components/chart-popover/index.js.map +1 -1
  56. package/internal/components/menu-dropdown/index.d.ts +1 -1
  57. package/internal/components/menu-dropdown/index.d.ts.map +1 -1
  58. package/internal/components/menu-dropdown/index.js +7 -5
  59. package/internal/components/menu-dropdown/index.js.map +1 -1
  60. package/internal/components/menu-dropdown/interfaces.d.ts +1 -0
  61. package/internal/components/menu-dropdown/interfaces.d.ts.map +1 -1
  62. package/internal/components/menu-dropdown/interfaces.js.map +1 -1
  63. package/internal/environment.js +1 -1
  64. package/internal/environment.json +1 -1
  65. package/internal/manifest.json +1 -1
  66. package/internal/plugins/api.d.ts +21 -25
  67. package/internal/plugins/api.d.ts.map +1 -1
  68. package/internal/plugins/api.js +15 -35
  69. package/internal/plugins/api.js.map +1 -1
  70. package/internal/plugins/controllers/action-buttons.d.ts +9 -0
  71. package/internal/plugins/controllers/action-buttons.d.ts.map +1 -1
  72. package/internal/plugins/controllers/action-buttons.js +11 -0
  73. package/internal/plugins/controllers/action-buttons.js.map +1 -1
  74. package/internal/plugins/controllers/drawers.d.ts +9 -0
  75. package/internal/plugins/controllers/drawers.d.ts.map +1 -1
  76. package/internal/plugins/controllers/drawers.js +11 -0
  77. package/internal/plugins/controllers/drawers.js.map +1 -1
  78. package/internal/utils/dom.d.ts +1 -8
  79. package/internal/utils/dom.d.ts.map +1 -1
  80. package/internal/utils/dom.js +1 -22
  81. package/internal/utils/dom.js.map +1 -1
  82. package/mixed-line-bar-chart/bar-series.d.ts.map +1 -1
  83. package/mixed-line-bar-chart/bar-series.js +14 -3
  84. package/mixed-line-bar-chart/bar-series.js.map +1 -1
  85. package/mixed-line-bar-chart/hooks/use-mouse-hover.js +1 -1
  86. package/mixed-line-bar-chart/hooks/use-mouse-hover.js.map +1 -1
  87. package/mixed-line-bar-chart/styles.css.js +11 -11
  88. package/mixed-line-bar-chart/styles.scoped.css +17 -22
  89. package/mixed-line-bar-chart/styles.selectors.js +11 -11
  90. package/modal/internal.d.ts.map +1 -1
  91. package/modal/internal.js +14 -12
  92. package/modal/internal.js.map +1 -1
  93. package/package.json +1 -1
  94. package/pie-chart/pie-chart.d.ts.map +1 -1
  95. package/pie-chart/pie-chart.js +1 -1
  96. package/pie-chart/pie-chart.js.map +1 -1
  97. package/popover/container.d.ts.map +1 -1
  98. package/popover/container.js +3 -2
  99. package/popover/container.js.map +1 -1
  100. package/progress-bar/index.d.ts.map +1 -1
  101. package/progress-bar/index.js +7 -4
  102. package/progress-bar/index.js.map +1 -1
  103. package/table/body-cell/td-element.d.ts +2 -1
  104. package/table/body-cell/td-element.d.ts.map +1 -1
  105. package/table/body-cell/td-element.js +3 -3
  106. package/table/body-cell/td-element.js.map +1 -1
  107. package/table/header-cell/index.d.ts +1 -1
  108. package/table/header-cell/index.d.ts.map +1 -1
  109. package/table/header-cell/index.js +2 -2
  110. package/table/header-cell/index.js.map +1 -1
  111. package/table/internal.d.ts.map +1 -1
  112. package/table/internal.js +12 -14
  113. package/table/internal.js.map +1 -1
  114. package/table/table-role/index.d.ts +3 -1
  115. package/table/table-role/index.d.ts.map +1 -1
  116. package/table/table-role/index.js +2 -1
  117. package/table/table-role/index.js.map +1 -1
  118. package/table/table-role/interfaces.d.ts +18 -0
  119. package/table/table-role/interfaces.d.ts.map +1 -0
  120. package/table/table-role/interfaces.js +4 -0
  121. package/table/table-role/interfaces.js.map +1 -0
  122. package/table/table-role/table-role-helper.d.ts +16 -4
  123. package/table/table-role/table-role-helper.d.ts.map +1 -1
  124. package/table/table-role/table-role-helper.js +39 -4
  125. package/table/table-role/table-role-helper.js.map +1 -1
  126. package/table/table-role/use-grid-navigation.d.ts +7 -0
  127. package/table/table-role/use-grid-navigation.d.ts.map +1 -0
  128. package/table/table-role/use-grid-navigation.js +185 -0
  129. package/table/table-role/use-grid-navigation.js.map +1 -0
  130. package/table/table-role/utils.d.ts +23 -0
  131. package/table/table-role/utils.d.ts.map +1 -0
  132. package/table/table-role/utils.js +141 -0
  133. package/table/table-role/utils.js.map +1 -0
  134. package/table/thead.d.ts.map +1 -1
  135. package/table/thead.js +4 -4
  136. package/table/thead.js.map +1 -1
  137. package/test-utils/dom/button-dropdown/index.js +1 -3
  138. package/test-utils/dom/button-dropdown/index.js.map +1 -1
  139. package/test-utils/selectors/button-dropdown/index.js +1 -3
  140. package/test-utils/selectors/button-dropdown/index.js.map +1 -1
  141. package/test-utils/tsconfig.tsbuildinfo +1 -1
  142. package/wizard/index.d.ts.map +1 -1
  143. package/wizard/index.js +8 -1
  144. package/wizard/index.js.map +1 -1
@@ -1,23 +1,35 @@
1
1
  /// <reference types="react" />
2
+ import { TableRole } from './interfaces';
2
3
  type SortingStatus = 'sortable' | 'ascending' | 'descending';
3
- export type TableRole = 'table' | 'grid';
4
4
  export declare function getTableRoleProps(options: {
5
5
  tableRole: TableRole;
6
6
  ariaLabel?: string;
7
7
  ariaLabelledBy?: string;
8
8
  totalItemsCount?: number;
9
+ totalColumnsCount?: number;
9
10
  }): React.TableHTMLAttributes<HTMLTableElement>;
11
+ export declare function getTableWrapperRoleProps(options: {
12
+ tableRole: TableRole;
13
+ isScrollable: boolean;
14
+ ariaLabel?: string;
15
+ }): import("react").HTMLAttributes<HTMLDivElement>;
16
+ export declare function getTableHeaderRowRoleProps(options: {
17
+ tableRole: TableRole;
18
+ }): import("react").HTMLAttributes<HTMLTableRowElement>;
10
19
  export declare function getTableRowRoleProps(options: {
11
20
  tableRole: TableRole;
12
21
  rowIndex: number;
13
22
  firstIndex?: number;
14
- }): React.HTMLAttributes<HTMLTableRowElement>;
23
+ }): import("react").HTMLAttributes<HTMLTableRowElement>;
15
24
  export declare function getTableColHeaderRoleProps(options: {
25
+ tableRole: TableRole;
26
+ colIndex: number;
16
27
  sortingStatus?: SortingStatus;
17
- }): React.ThHTMLAttributes<HTMLTableCellElement>;
28
+ }): import("react").ThHTMLAttributes<HTMLTableCellElement>;
18
29
  export declare function getTableCellRoleProps(options: {
19
30
  tableRole: TableRole;
31
+ colIndex: number;
20
32
  isRowHeader?: boolean;
21
- }): React.TdHTMLAttributes<HTMLTableCellElement>;
33
+ }): import("react").TdHTMLAttributes<HTMLTableCellElement>;
22
34
  export {};
23
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,KAAK,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;AAa7D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEzC,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;CAC1B,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAc9C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAY5C;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,GAAG,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAU/C;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAY/C"}
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,kDAYpH;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"}
@@ -6,6 +6,9 @@ const stateToAriaSort = {
6
6
  descending: 'descending',
7
7
  };
8
8
  const getAriaSort = (sortingState) => stateToAriaSort[sortingState];
9
+ // Depending on its content the table can have different semantic representation which includes the
10
+ // ARIA role of the table component ("table", "grid", "treegrid") but also roles and other semantic attributes
11
+ // of the child elements. The TableRole helper encapsulates table's semantic structure.
9
12
  export function getTableRoleProps(options) {
10
13
  const nativeProps = {};
11
14
  // Browsers have weird mechanism to guess whether it's a data table or a layout table.
@@ -15,21 +18,53 @@ export function getTableRoleProps(options) {
15
18
  nativeProps['aria-labelledby'] = options.ariaLabelledBy;
16
19
  // Incrementing the total count by one to account for the header row.
17
20
  nativeProps['aria-rowcount'] = options.totalItemsCount ? options.totalItemsCount + 1 : -1;
21
+ if (options.tableRole === 'grid') {
22
+ nativeProps['aria-colcount'] = options.totalColumnsCount;
23
+ }
24
+ // Make table component programmatically focusable to attach focusin/focusout for keyboard navigation.
25
+ if (options.tableRole === 'grid') {
26
+ nativeProps.tabIndex = -1;
27
+ }
28
+ return nativeProps;
29
+ }
30
+ export function getTableWrapperRoleProps(options) {
31
+ const nativeProps = {};
32
+ // TODO: do not make wrapper focusable for grids once custom navigation is available.
33
+ // When the table is scrollable, the wrapper is made focusable so that keyboard users can scroll it horizontally with arrow keys.
34
+ if (options.isScrollable) {
35
+ nativeProps.role = 'region';
36
+ nativeProps.tabIndex = 0;
37
+ nativeProps['aria-label'] = options.ariaLabel;
38
+ }
39
+ return nativeProps;
40
+ }
41
+ export function getTableHeaderRowRoleProps(options) {
42
+ const nativeProps = {};
43
+ // For grids headers are treated similar to data rows and are indexed accordingly.
44
+ if (options.tableRole === 'grid') {
45
+ nativeProps['aria-rowindex'] = 1;
46
+ }
18
47
  return nativeProps;
19
48
  }
20
49
  export function getTableRowRoleProps(options) {
50
+ var _a, _b;
21
51
  const nativeProps = {};
52
+ // For grids data cell indices are incremented by 2 to account for the header cells.
22
53
  if (options.tableRole === 'grid') {
23
- nativeProps.role = 'row';
54
+ nativeProps['aria-rowindex'] = ((_a = options.firstIndex) !== null && _a !== void 0 ? _a : 0) + options.rowIndex + 2;
24
55
  }
25
- if (options.firstIndex !== undefined) {
26
- nativeProps['aria-rowindex'] = options.firstIndex + options.rowIndex + 1;
56
+ // For tables indices are only added when the first index is not 0 (not the first page/frame).
57
+ else if (options.firstIndex !== undefined) {
58
+ nativeProps['aria-rowindex'] = ((_b = options.firstIndex) !== null && _b !== void 0 ? _b : 0) + options.rowIndex + 1;
27
59
  }
28
60
  return nativeProps;
29
61
  }
30
62
  export function getTableColHeaderRoleProps(options) {
31
63
  const nativeProps = {};
32
64
  nativeProps.scope = 'col';
65
+ if (options.tableRole === 'grid') {
66
+ nativeProps['aria-colindex'] = options.colIndex + 1;
67
+ }
33
68
  if (options.sortingStatus) {
34
69
  nativeProps['aria-sort'] = getAriaSort(options.sortingStatus);
35
70
  }
@@ -38,7 +73,7 @@ export function getTableColHeaderRoleProps(options) {
38
73
  export function getTableCellRoleProps(options) {
39
74
  const nativeProps = {};
40
75
  if (options.tableRole === 'grid') {
41
- nativeProps.role = 'gridcell';
76
+ nativeProps['aria-colindex'] = options.colIndex + 1;
42
77
  }
43
78
  if (options.isRowHeader) {
44
79
  nativeProps.scope = 'row';
@@ -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;AAItC,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;AAQnF,MAAM,UAAU,iBAAiB,CAAC,OAKjC;IACC,MAAM,WAAW,GAAgD,EAAE,CAAC;IAEpE,sFAAsF;IACtF,qFAAqF;IACrF,WAAW,CAAC,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;IAErC,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,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAIpC;IACC,MAAM,WAAW,GAA8C,EAAE,CAAC;IAElE,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE;QAChC,WAAW,CAAC,IAAI,GAAG,KAAK,CAAC;KAC1B;IAED,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE;QACpC,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,OAE1C;IACC,MAAM,WAAW,GAAiD,EAAE,CAAC;IAErE,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;IAE1B,IAAI,OAAO,CAAC,aAAa,EAAE;QACzB,WAAW,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;KAC/D;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAGrC;IACC,MAAM,WAAW,GAAiD,EAAE,CAAC;IAErE,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,EAAE;QAChC,WAAW,CAAC,IAAI,GAAG,UAAU,CAAC;KAC/B;IAED,IAAI,OAAO,CAAC,WAAW,EAAE;QACvB,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;KAC3B;IAED,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\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 type TableRole = 'table' | 'grid';\n\nexport function getTableRoleProps(options: {\n tableRole: TableRole;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n totalItemsCount?: 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;\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 return nativeProps;\n}\n\nexport function getTableRowRoleProps(options: {\n tableRole: TableRole;\n rowIndex: number;\n firstIndex?: number;\n}): React.HTMLAttributes<HTMLTableRowElement> {\n const nativeProps: React.HTMLAttributes<HTMLTableRowElement> = {};\n\n if (options.tableRole === 'grid') {\n nativeProps.role = 'row';\n }\n\n 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 sortingStatus?: SortingStatus;\n}): React.ThHTMLAttributes<HTMLTableCellElement> {\n const nativeProps: React.ThHTMLAttributes<HTMLTableCellElement> = {};\n\n nativeProps.scope = 'col';\n\n if (options.sortingStatus) {\n nativeProps['aria-sort'] = getAriaSort(options.sortingStatus);\n }\n\n return nativeProps;\n}\n\nexport function getTableCellRoleProps(options: {\n tableRole: TableRole;\n isRowHeader?: boolean;\n}): React.TdHTMLAttributes<HTMLTableCellElement> {\n const nativeProps: React.TdHTMLAttributes<HTMLTableCellElement> = {};\n\n if (options.tableRole === 'grid') {\n nativeProps.role = 'gridcell';\n }\n\n if (options.isRowHeader) {\n nativeProps.scope = 'row';\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;\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 // TODO: do not make wrapper focusable for grids once custom navigation is available.\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) {\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') {\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 // For grids data cell indices are incremented by 2 to account for the header cells.\n if (options.tableRole === 'grid') {\n nativeProps['aria-rowindex'] = (options.firstIndex ?? 0) + options.rowIndex + 2;\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 ?? 0) + 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"]}
@@ -0,0 +1,7 @@
1
+ import { GridNavigationAPI, GridNavigationProps } from './interfaces';
2
+ /**
3
+ * Makes table with role="grid" navigable with keyboard commands.
4
+ * See https://www.w3.org/WAI/ARIA/apg/patterns/grid
5
+ */
6
+ export declare function useGridNavigation({ tableRole, pageSize, getTable }: GridNavigationProps): GridNavigationAPI;
7
+ //# sourceMappingURL=use-grid-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-grid-navigation.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/use-grid-navigation.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAInF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,GAAG,iBAAiB,CAuB3G"}
@@ -0,0 +1,185 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { useEffect, useMemo } from 'react';
4
+ import { findFocusinCell, moveFocusBy, moveFocusIn, updateTableIndices } from './utils';
5
+ import { KeyCode } from '../../internal/keycode';
6
+ import { containsOrEqual } from '../../internal/utils/dom';
7
+ /**
8
+ * Makes table with role="grid" navigable with keyboard commands.
9
+ * See https://www.w3.org/WAI/ARIA/apg/patterns/grid
10
+ */
11
+ export function useGridNavigation({ tableRole, pageSize, getTable }) {
12
+ const model = useMemo(() => new GridNavigationModel(), []);
13
+ // Initialize the model with the table container assuming it is mounted synchronously and only once.
14
+ useEffect(() => {
15
+ if (tableRole === 'grid') {
16
+ const table = getTable();
17
+ table && model.init(table);
18
+ }
19
+ return () => model.destroy();
20
+ },
21
+ // Assuming getTable is stable.
22
+ // eslint-disable-next-line react-hooks/exhaustive-deps
23
+ [model, tableRole]);
24
+ // Notify the model of the props change.
25
+ useEffect(() => {
26
+ model.update({ pageSize });
27
+ }, [model, pageSize]);
28
+ return {};
29
+ }
30
+ class GridNavigationModel {
31
+ constructor() {
32
+ // Props
33
+ this._pageSize = 0;
34
+ this._table = null;
35
+ // State
36
+ this.prevFocusedCell = null;
37
+ this.focusedCell = null;
38
+ this.cleanup = () => { };
39
+ this.onFocusin = (event) => {
40
+ const cell = findFocusinCell(event);
41
+ if (!cell) {
42
+ return;
43
+ }
44
+ this.prevFocusedCell = cell;
45
+ this.focusedCell = cell;
46
+ updateTableIndices(this.table, cell);
47
+ };
48
+ this.onFocusout = () => {
49
+ this.focusedCell = null;
50
+ };
51
+ this.onKeydown = (event) => {
52
+ if (!this.focusedCell) {
53
+ return;
54
+ }
55
+ const f2Code = 113;
56
+ const ctrlKey = event.ctrlKey ? 1 : 0;
57
+ const altKey = event.altKey ? 1 : 0;
58
+ const shiftKey = event.shiftKey ? 1 : 0;
59
+ const metaKey = event.metaKey ? 1 : 0;
60
+ const numModifiersPressed = ctrlKey + altKey + shiftKey + metaKey;
61
+ let key = event.keyCode;
62
+ if (numModifiersPressed === 1 && event.ctrlKey) {
63
+ key = -key;
64
+ }
65
+ else if (numModifiersPressed) {
66
+ return;
67
+ }
68
+ const from = this.focusedCell;
69
+ const minExtreme = Number.NEGATIVE_INFINITY;
70
+ 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
+ }
77
+ return;
78
+ }
79
+ switch (key) {
80
+ case KeyCode.up:
81
+ event.preventDefault();
82
+ return moveFocusBy(this.table, from, { y: -1, x: 0 });
83
+ case KeyCode.down:
84
+ event.preventDefault();
85
+ return moveFocusBy(this.table, from, { y: 1, x: 0 });
86
+ case KeyCode.left:
87
+ event.preventDefault();
88
+ return moveFocusBy(this.table, from, { y: 0, x: -1 });
89
+ case KeyCode.right:
90
+ event.preventDefault();
91
+ return moveFocusBy(this.table, from, { y: 0, x: 1 });
92
+ case KeyCode.pageUp:
93
+ event.preventDefault();
94
+ return moveFocusBy(this.table, from, { y: -this.pageSize, x: 0 });
95
+ case KeyCode.pageDown:
96
+ event.preventDefault();
97
+ return moveFocusBy(this.table, from, { y: this.pageSize, x: 0 });
98
+ case KeyCode.home:
99
+ event.preventDefault();
100
+ return moveFocusBy(this.table, from, { y: 0, x: minExtreme });
101
+ case KeyCode.end:
102
+ event.preventDefault();
103
+ return moveFocusBy(this.table, from, { y: 0, x: maxExtreme });
104
+ case -KeyCode.home:
105
+ event.preventDefault();
106
+ return moveFocusBy(this.table, from, { y: minExtreme, x: minExtreme });
107
+ case -KeyCode.end:
108
+ event.preventDefault();
109
+ 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
+ default:
131
+ return;
132
+ }
133
+ };
134
+ this.onMutation = (mutationRecords) => {
135
+ var _a;
136
+ if (!this.prevFocusedCell) {
137
+ return;
138
+ }
139
+ // When focused cell was un-mounted - re-apply focus to the same location.
140
+ for (const record of mutationRecords) {
141
+ if (record.type === 'childList') {
142
+ for (const removedNode of Array.from(record.removedNodes)) {
143
+ if (containsOrEqual(removedNode, this.prevFocusedCell.element)) {
144
+ moveFocusBy(this.table, this.prevFocusedCell, { y: 0, x: 0 });
145
+ }
146
+ }
147
+ }
148
+ }
149
+ updateTableIndices(this.table, (_a = this.focusedCell) !== null && _a !== void 0 ? _a : this.prevFocusedCell);
150
+ };
151
+ }
152
+ init(table) {
153
+ var _a;
154
+ this._table = table;
155
+ this.table.addEventListener('focusin', this.onFocusin);
156
+ this.table.addEventListener('focusout', this.onFocusout);
157
+ this.table.addEventListener('keydown', this.onKeydown);
158
+ const mutationObserver = new MutationObserver(this.onMutation);
159
+ mutationObserver.observe(table, { childList: true, subtree: true });
160
+ // No need to clean this up as no resources are allocated.
161
+ updateTableIndices(this.table, (_a = this.focusedCell) !== null && _a !== void 0 ? _a : this.prevFocusedCell);
162
+ this.cleanup = () => {
163
+ this.table.removeEventListener('focusin', this.onFocusin);
164
+ this.table.removeEventListener('focusout', this.onFocusout);
165
+ this.table.removeEventListener('keydown', this.onKeydown);
166
+ mutationObserver.disconnect();
167
+ };
168
+ }
169
+ destroy() {
170
+ this.cleanup();
171
+ }
172
+ update({ pageSize }) {
173
+ this._pageSize = pageSize;
174
+ }
175
+ get pageSize() {
176
+ return this._pageSize;
177
+ }
178
+ get table() {
179
+ if (!this._table) {
180
+ throw new Error('Invariant violation: GridNavigationModel is used before initialization.');
181
+ }
182
+ return this._table;
183
+ }
184
+ }
185
+ //# sourceMappingURL=use-grid-navigation.js.map
@@ -0,0 +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, updateTableIndices } from './utils';\nimport { FocusedCell, GridNavigationAPI, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { containsOrEqual } from '../../internal/utils/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 // No need to clean this up as no resources are allocated.\n updateTableIndices(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 }\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 updateTableIndices(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 (containsOrEqual(removedNode, this.prevFocusedCell.element)) {\n moveFocusBy(this.table, this.prevFocusedCell, { y: 0, x: 0 });\n }\n }\n }\n }\n\n updateTableIndices(this.table, this.focusedCell ?? this.prevFocusedCell);\n };\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { FocusedCell } from './interfaces';
2
+ /**
3
+ * Finds focused cell props corresponding the focused element inside the table.
4
+ * The function relies on ARIA colindex/rowindex attributes being set.
5
+ */
6
+ export declare function findFocusinCell(event: FocusEvent): null | FocusedCell;
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.
10
+ */
11
+ export declare function moveFocusBy(table: HTMLTableElement, from: FocusedCell, delta: {
12
+ y: number;
13
+ x: number;
14
+ }): void;
15
+ /**
16
+ * Moves focus to the first focusable element inside the cell.
17
+ */
18
+ export declare function moveFocusIn(from: FocusedCell): void;
19
+ /**
20
+ * Ensures exactly one table element is focusable for the entire table to have a single TAB stop.
21
+ */
22
+ export declare function updateTableIndices(table: HTMLTableElement, cell: null | FocusedCell): void;
23
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +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,QAsCtG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,QAE5C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,QA2BnF"}
@@ -0,0 +1,141 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { getFocusables as getActualFocusables } from '../../internal/components/focus-lock/utils';
4
+ /**
5
+ * Finds focused cell props corresponding the focused element inside the table.
6
+ * The function relies on ARIA colindex/rowindex attributes being set.
7
+ */
8
+ export function findFocusinCell(event) {
9
+ var _a, _b;
10
+ const element = event.target;
11
+ if (!(element instanceof HTMLElement)) {
12
+ return null;
13
+ }
14
+ const cellElement = element.closest('td,th');
15
+ const rowElement = cellElement === null || cellElement === void 0 ? void 0 : cellElement.closest('tr');
16
+ if (!cellElement || !rowElement) {
17
+ return null;
18
+ }
19
+ const colIndex = parseInt((_a = cellElement.getAttribute('aria-colindex')) !== null && _a !== void 0 ? _a : '');
20
+ const rowIndex = parseInt((_b = rowElement.getAttribute('aria-rowindex')) !== null && _b !== void 0 ? _b : '');
21
+ if (isNaN(colIndex) || isNaN(rowIndex)) {
22
+ return null;
23
+ }
24
+ const cellFocusables = getFocusables(cellElement);
25
+ const elementIndex = cellFocusables.indexOf(element);
26
+ const widget = isWidgetCell(cellElement);
27
+ return { rowIndex, colIndex, elementIndex, rowElement, cellElement, element, widget };
28
+ }
29
+ /**
30
+ * Moves table focus in the provided direction. The focus can transition between cells or between
31
+ * focusable elements within a cell unless the cell is marked as a widget.
32
+ */
33
+ export function moveFocusBy(table, from, delta) {
34
+ var _a;
35
+ const targetAriaRowIndex = from.rowIndex + delta.y;
36
+ const targetRow = findTableRowByAriaRowIndex(table, targetAriaRowIndex, delta.y);
37
+ if (!targetRow) {
38
+ return;
39
+ }
40
+ // Move focus to the next focusable element within a cell if eligible.
41
+ const cellFocusables = getFocusables(from.cellElement);
42
+ const eligibleForElementFocus = delta.x && !isWidgetCell(from.element) && (cellFocusables.length === 1 || from.element !== from.cellElement);
43
+ const targetElementIndex = from.elementIndex + delta.x;
44
+ if (eligibleForElementFocus && 0 <= targetElementIndex && targetElementIndex < cellFocusables.length) {
45
+ focus(cellFocusables[targetElementIndex]);
46
+ return;
47
+ }
48
+ const targetAriaColIndex = from.colIndex + delta.x;
49
+ const targetCell = findTableRowCellByAriaColIndex(targetRow, targetAriaColIndex, delta.x);
50
+ if (!targetCell) {
51
+ return;
52
+ }
53
+ // For widget cells always focus on the cell element itself.
54
+ if (isWidgetCell(targetCell)) {
55
+ return focus(targetCell);
56
+ }
57
+ // For zero delta (exiting command) and multi-element cell focus cell itself.
58
+ const targetCellFocusables = getFocusables(targetCell);
59
+ if (delta.x === 0 && delta.y === 0 && targetCellFocusables.length > 1) {
60
+ return focus(targetCell);
61
+ }
62
+ // For non-widget cell focus on the focusable element inside if exactly one is available.
63
+ const focusIndex = delta.x === 0 ? from.elementIndex : targetCellFocusables.length === 1 ? 0 : -1;
64
+ const focusTarget = (_a = targetCellFocusables[focusIndex]) !== null && _a !== void 0 ? _a : targetCell;
65
+ focus(focusTarget);
66
+ }
67
+ /**
68
+ * Moves focus to the first focusable element inside the cell.
69
+ */
70
+ export function moveFocusIn(from) {
71
+ focus(getFirstFocusable(from.cellElement));
72
+ }
73
+ /**
74
+ * Ensures exactly one table element is focusable for the entire table to have a single TAB stop.
75
+ */
76
+ export function updateTableIndices(table, cell) {
77
+ const tableCells = table.querySelectorAll('td,th');
78
+ for (const cell of Array.from(tableCells)) {
79
+ cell.tabIndex = -1;
80
+ cell.setAttribute('data-focusable', 'true');
81
+ }
82
+ for (const focusable of getActualFocusables(table)) {
83
+ focusable.tabIndex = -1;
84
+ focusable.setAttribute('data-focusable', 'true');
85
+ }
86
+ // Make focused element the only focusable element of the table.
87
+ if (cell && table.contains(cell.element)) {
88
+ cell.element.tabIndex = 0;
89
+ // For widget cells also unmute all cell elements to be focusable with Tab/Shift+Tab.
90
+ if (cell.widget) {
91
+ getFocusables(cell.cellElement).forEach(element => (element.tabIndex = 0));
92
+ }
93
+ }
94
+ // Make first table cell the only focusable element of the table.
95
+ else if (tableCells[0]) {
96
+ const cellFocusables = getFocusables(tableCells[0]);
97
+ cellFocusables[0] ? (cellFocusables[0].tabIndex = 0) : (tableCells[0].tabIndex = 0);
98
+ }
99
+ }
100
+ function isWidgetCell(cell) {
101
+ return cell.getAttribute('data-widget-cell') === 'true';
102
+ }
103
+ function getFocusables(element) {
104
+ return Array.from(element.querySelectorAll('[data-focusable="true"]'));
105
+ }
106
+ function getFirstFocusable(element) {
107
+ return getFocusables(element)[0];
108
+ }
109
+ function findTableRowByAriaRowIndex(table, targetAriaRowIndex, delta) {
110
+ var _a;
111
+ let targetRow = null;
112
+ const rowElements = table.querySelectorAll('tr[aria-rowindex]');
113
+ for (let elementIndex = 0; elementIndex < rowElements.length; elementIndex++) {
114
+ const rowIndex = parseInt((_a = rowElements[elementIndex].getAttribute('aria-rowindex')) !== null && _a !== void 0 ? _a : '');
115
+ targetRow = rowElements[elementIndex];
116
+ if (rowIndex === targetAriaRowIndex || (delta < 0 && rowIndex >= targetAriaRowIndex)) {
117
+ break;
118
+ }
119
+ }
120
+ return targetRow;
121
+ }
122
+ function findTableRowCellByAriaColIndex(tableRow, targetAriaColIndex, delta) {
123
+ var _a;
124
+ let targetCell = null;
125
+ const cellElements = tableRow.querySelectorAll('td[aria-colindex],th[aria-colindex]');
126
+ for (let elementIndex = 0; elementIndex < cellElements.length; elementIndex++) {
127
+ const columnIndex = parseInt((_a = cellElements[elementIndex].getAttribute('aria-colindex')) !== null && _a !== void 0 ? _a : '');
128
+ targetCell = cellElements[elementIndex];
129
+ if (columnIndex === targetAriaColIndex || (delta < 0 && columnIndex >= targetAriaColIndex)) {
130
+ break;
131
+ }
132
+ }
133
+ return targetCell;
134
+ }
135
+ function focus(element) {
136
+ if (element) {
137
+ element.tabIndex = 0;
138
+ element.focus();
139
+ }
140
+ }
141
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"lib/default/","sources":["table/table-role/utils.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,aAAa,IAAI,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAGlG;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAiB;;IAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;IAE7B,IAAI,CAAC,CAAC,OAAO,YAAY,WAAW,CAAC,EAAE;QACrC,OAAO,IAAI,CAAC;KACb;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAgC,CAAC;IAC5E,MAAM,UAAU,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,EAAE;QAC/B,OAAO,IAAI,CAAC;KACb;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAA,WAAW,CAAC,YAAY,CAAC,eAAe,CAAC,mCAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAA,UAAU,CAAC,YAAY,CAAC,eAAe,CAAC,mCAAI,EAAE,CAAC,CAAC;IAC1E,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE;QACtC,OAAO,IAAI,CAAC;KACb;IAED,MAAM,cAAc,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAEzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB,EAAE,IAAiB,EAAE,KAA+B;;IACrG,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,0BAA0B,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC,SAAS,EAAE;QACd,OAAO;KACR;IAED,sEAAsE;IACtE,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,uBAAuB,GAC3B,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/G,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC;IACvD,IAAI,uBAAuB,IAAI,CAAC,IAAI,kBAAkB,IAAI,kBAAkB,GAAG,cAAc,CAAC,MAAM,EAAE;QACpG,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC1C,OAAO;KACR;IAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,8BAA8B,CAAC,SAAS,EAAE,kBAAkB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC,UAAU,EAAE;QACf,OAAO;KACR;IAED,4DAA4D;IAC5D,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE;QAC5B,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC;KAC1B;IAED,6EAA6E;IAC7E,MAAM,oBAAoB,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;QACrE,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC;KAC1B;IAED,yFAAyF;IACzF,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClG,MAAM,WAAW,GAAG,MAAA,oBAAoB,CAAC,UAAU,CAAC,mCAAI,UAAU,CAAC;IACnE,KAAK,CAAC,WAAW,CAAC,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAiB;IAC3C,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAuB,EAAE,IAAwB;IAClF,MAAM,UAAU,GAAG,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAqC,CAAC;IAEvF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QACzC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;KAC7C;IACD,KAAK,MAAM,SAAS,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE;QAClD,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACxB,SAAS,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;KAClD;IAED,gEAAgE;IAChE,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QACxC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAE1B,qFAAqF;QACrF,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;SAC5E;KACF;IAED,iEAAiE;SAC5D,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE;QACtB,MAAM,cAAc,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;KACrF;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAiB;IACrC,OAAO,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,KAAK,MAAM,CAAC;AAC1D,CAAC;AAED,SAAS,aAAa,CAAC,OAAoB;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,CAAkB,CAAC;AAC1F,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAoB;IAC7C,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAuB,CAAC;AACzD,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAuB,EAAE,kBAA0B,EAAE,KAAa;;IACpG,IAAI,SAAS,GAA+B,IAAI,CAAC;IACjD,MAAM,WAAW,GAAG,KAAK,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;IAChE,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE;QAC5E,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAA,WAAW,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,mCAAI,EAAE,CAAC,CAAC;QACzF,SAAS,GAAG,WAAW,CAAC,YAAY,CAAwB,CAAC;QAE7D,IAAI,QAAQ,KAAK,kBAAkB,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,QAAQ,IAAI,kBAAkB,CAAC,EAAE;YACpF,MAAM;SACP;KACF;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,8BAA8B,CAAC,QAA6B,EAAE,kBAA0B,EAAE,KAAa;;IAC9G,IAAI,UAAU,GAAgC,IAAI,CAAC;IACnD,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,CAAC,qCAAqC,CAAC,CAAC;IACtF,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE;QAC7E,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAA,YAAY,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,mCAAI,EAAE,CAAC,CAAC;QAC7F,UAAU,GAAG,YAAY,CAAC,YAAY,CAAyB,CAAC;QAEhE,IAAI,WAAW,KAAK,kBAAkB,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,WAAW,IAAI,kBAAkB,CAAC,EAAE;YAC1F,MAAM;SACP;KACF;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,KAAK,CAAC,OAA2B;IACxC,IAAI,OAAO,EAAE;QACX,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO,CAAC,KAAK,EAAE,CAAC;KACjB;AACH,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { getFocusables as getActualFocusables } from '../../internal/components/focus-lock/utils';\nimport { FocusedCell } from './interfaces';\n\n/**\n * Finds focused cell props corresponding the focused element inside the table.\n * The function relies on ARIA colindex/rowindex attributes being set.\n */\nexport function findFocusinCell(event: FocusEvent): null | FocusedCell {\n const element = event.target;\n\n if (!(element instanceof HTMLElement)) {\n return null;\n }\n\n const cellElement = element.closest('td,th') as null | HTMLTableCellElement;\n const rowElement = cellElement?.closest('tr');\n\n if (!cellElement || !rowElement) {\n return null;\n }\n\n const colIndex = parseInt(cellElement.getAttribute('aria-colindex') ?? '');\n const rowIndex = parseInt(rowElement.getAttribute('aria-rowindex') ?? '');\n if (isNaN(colIndex) || isNaN(rowIndex)) {\n return null;\n }\n\n const cellFocusables = getFocusables(cellElement);\n const elementIndex = cellFocusables.indexOf(element);\n\n const widget = isWidgetCell(cellElement);\n\n return { rowIndex, colIndex, elementIndex, rowElement, cellElement, element, widget };\n}\n\n/**\n * Moves table focus in the provided direction. The focus can transition between cells or between\n * focusable elements within a cell unless the cell is marked as a widget.\n */\nexport function moveFocusBy(table: HTMLTableElement, from: FocusedCell, delta: { y: number; x: number }) {\n const targetAriaRowIndex = from.rowIndex + delta.y;\n const targetRow = findTableRowByAriaRowIndex(table, targetAriaRowIndex, delta.y);\n if (!targetRow) {\n return;\n }\n\n // Move focus to the next focusable element within a cell if eligible.\n const cellFocusables = getFocusables(from.cellElement);\n const eligibleForElementFocus =\n delta.x && !isWidgetCell(from.element) && (cellFocusables.length === 1 || from.element !== from.cellElement);\n const targetElementIndex = from.elementIndex + delta.x;\n if (eligibleForElementFocus && 0 <= targetElementIndex && targetElementIndex < cellFocusables.length) {\n focus(cellFocusables[targetElementIndex]);\n return;\n }\n\n const targetAriaColIndex = from.colIndex + delta.x;\n const targetCell = findTableRowCellByAriaColIndex(targetRow, targetAriaColIndex, delta.x);\n if (!targetCell) {\n return;\n }\n\n // For widget cells always focus on the cell element itself.\n if (isWidgetCell(targetCell)) {\n return focus(targetCell);\n }\n\n // For zero delta (exiting command) and multi-element cell focus cell itself.\n const targetCellFocusables = getFocusables(targetCell);\n if (delta.x === 0 && delta.y === 0 && targetCellFocusables.length > 1) {\n return focus(targetCell);\n }\n\n // For non-widget cell focus on the focusable element inside if exactly one is available.\n const focusIndex = delta.x === 0 ? from.elementIndex : targetCellFocusables.length === 1 ? 0 : -1;\n const focusTarget = targetCellFocusables[focusIndex] ?? targetCell;\n focus(focusTarget);\n}\n\n/**\n * Moves focus to the first focusable element inside the cell.\n */\nexport function moveFocusIn(from: FocusedCell) {\n focus(getFirstFocusable(from.cellElement));\n}\n\n/**\n * Ensures exactly one table element is focusable for the entire table to have a single TAB stop.\n */\nexport function updateTableIndices(table: HTMLTableElement, cell: null | FocusedCell) {\n const tableCells = table.querySelectorAll('td,th') as NodeListOf<HTMLTableCellElement>;\n\n for (const cell of Array.from(tableCells)) {\n cell.tabIndex = -1;\n cell.setAttribute('data-focusable', 'true');\n }\n for (const focusable of getActualFocusables(table)) {\n focusable.tabIndex = -1;\n focusable.setAttribute('data-focusable', 'true');\n }\n\n // Make focused element the only focusable element of the table.\n if (cell && table.contains(cell.element)) {\n cell.element.tabIndex = 0;\n\n // For widget cells also unmute all cell elements to be focusable with Tab/Shift+Tab.\n if (cell.widget) {\n getFocusables(cell.cellElement).forEach(element => (element.tabIndex = 0));\n }\n }\n\n // Make first table cell the only focusable element of the table.\n else if (tableCells[0]) {\n const cellFocusables = getFocusables(tableCells[0]);\n cellFocusables[0] ? (cellFocusables[0].tabIndex = 0) : (tableCells[0].tabIndex = 0);\n }\n}\n\nfunction isWidgetCell(cell: HTMLElement) {\n return cell.getAttribute('data-widget-cell') === 'true';\n}\n\nfunction getFocusables(element: HTMLElement) {\n return Array.from(element.querySelectorAll('[data-focusable=\"true\"]')) as HTMLElement[];\n}\n\nfunction getFirstFocusable(element: HTMLElement) {\n return getFocusables(element)[0] as null | HTMLElement;\n}\n\nfunction findTableRowByAriaRowIndex(table: HTMLTableElement, targetAriaRowIndex: number, delta: number) {\n let targetRow: null | HTMLTableRowElement = null;\n const rowElements = table.querySelectorAll('tr[aria-rowindex]');\n for (let elementIndex = 0; elementIndex < rowElements.length; elementIndex++) {\n const rowIndex = parseInt(rowElements[elementIndex].getAttribute('aria-rowindex') ?? '');\n targetRow = rowElements[elementIndex] as HTMLTableRowElement;\n\n if (rowIndex === targetAriaRowIndex || (delta < 0 && rowIndex >= targetAriaRowIndex)) {\n break;\n }\n }\n return targetRow;\n}\n\nfunction findTableRowCellByAriaColIndex(tableRow: HTMLTableRowElement, targetAriaColIndex: number, delta: number) {\n let targetCell: null | HTMLTableCellElement = null;\n const cellElements = tableRow.querySelectorAll('td[aria-colindex],th[aria-colindex]');\n for (let elementIndex = 0; elementIndex < cellElements.length; elementIndex++) {\n const columnIndex = parseInt(cellElements[elementIndex].getAttribute('aria-colindex') ?? '');\n targetCell = cellElements[elementIndex] as HTMLTableCellElement;\n\n if (columnIndex === targetAriaColIndex || (delta < 0 && columnIndex >= targetAriaColIndex)) {\n break;\n }\n }\n return targetCell;\n}\n\nfunction focus(element: null | HTMLElement) {\n if (element) {\n element.tabIndex = 0;\n element.focus();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"thead.d.ts","sourceRoot":"lib/default/","sources":["table/thead.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAA0B,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AASvF,OAAO,EAAE,kBAAkB,EAAuB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAA8B,SAAS,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,UAAU,CAAC,aAAa,GAAG,SAAS,CAAC;IACpD,iBAAiB,EAAE,aAAa,CAAC,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,aAAa,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACzD,iBAAiB,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,eAAe,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC;IAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,iBAAiB,EAAE,MAAM,cAAc,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtG,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5D,eAAe,EAAE,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;IACrF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,kBAAkB,CAAC;IAChC,iBAAiB,EAAE,WAAW,CAAC;IAC/B,gBAAgB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC/C,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1E,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,KAAK,wFAsIV,CAAC;AAEF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"thead.d.ts","sourceRoot":"lib/default/","sources":["table/thead.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAA0B,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AASvF,OAAO,EAAE,kBAAkB,EAAuB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAA0D,SAAS,EAAE,MAAM,cAAc,CAAC;AAEjG,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,UAAU,CAAC,aAAa,GAAG,SAAS,CAAC;IACpD,iBAAiB,EAAE,aAAa,CAAC,UAAU,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IACnE,aAAa,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACzD,iBAAiB,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,eAAe,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC;IAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,iBAAiB,EAAE,MAAM,cAAc,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtG,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5D,eAAe,EAAE,yBAAyB,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;IACrF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,kBAAkB,CAAC;IAChC,iBAAiB,EAAE,WAAW,CAAC;IAC/B,gBAAgB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC/C,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1E,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,QAAA,MAAM,KAAK,wFAsIV,CAAC;AAEF,eAAe,KAAK,CAAC"}
package/table/thead.js CHANGED
@@ -14,7 +14,7 @@ import cellStyles from './header-cell/styles.css.js';
14
14
  import headerCellStyles from './header-cell/styles.css.js';
15
15
  import ScreenreaderOnly from '../internal/components/screenreader-only';
16
16
  import { useStickyCellStyles } from './sticky-columns';
17
- import { getTableColHeaderRoleProps } from './table-role';
17
+ import { getTableColHeaderRoleProps, getTableHeaderRowRoleProps } from './table-role';
18
18
  const Thead = React.forwardRef(({ containerWidth, selectionType, getSelectAllProps, columnDefinitions, sortingColumn, sortingDisabled, sortingDescending, resizableColumns, variant, wrapLines, onFocusMove, onSortingChange, onResizeFinish, singleSelectionHeaderAriaLabel, stripedRows, sticky = false, hidden = false, stuck = false, stickyState, selectionColumnId, focusedComponent, onFocusedComponentChange, tableRole, }, outerRef) => {
19
19
  const isVisualRefresh = useVisualRefresh();
20
20
  const headerCellClass = clsx(headerCellStyles['header-cell'], headerCellStyles[`header-cell-variant-${variant}`], sticky && headerCellStyles['header-cell-sticky'], stuck && headerCellStyles['header-cell-stuck'], stripedRows && headerCellStyles['has-striped-rows'], isVisualRefresh && headerCellStyles['is-visual-refresh']);
@@ -26,8 +26,8 @@ const Thead = React.forwardRef(({ containerWidth, selectionType, getSelectAllPro
26
26
  getClassName: props => getStickyClassNames(cellStyles, props),
27
27
  });
28
28
  return (React.createElement("thead", { className: clsx(!hidden && styles['thead-active']) },
29
- React.createElement("tr", Object.assign({}, focusMarkers.all, { ref: outerRef, "aria-rowindex": 1 }),
30
- selectionType ? (React.createElement("th", Object.assign({ className: clsx(headerCellClass, selectionCellClass, hidden && headerCellStyles['header-cell-hidden'], stickyStyles.className), style: stickyStyles.style, ref: stickyStyles.ref, scope: "col" }, getTableColHeaderRoleProps({})), selectionType === 'multi' ? (React.createElement(SelectionControl, Object.assign({ onFocusDown: event => {
29
+ React.createElement("tr", Object.assign({}, focusMarkers.all, { ref: outerRef, "aria-rowindex": 1 }, getTableHeaderRowRoleProps({ tableRole })),
30
+ selectionType ? (React.createElement("th", Object.assign({ className: clsx(headerCellClass, selectionCellClass, hidden && headerCellStyles['header-cell-hidden'], stickyStyles.className), style: stickyStyles.style, ref: stickyStyles.ref, scope: "col" }, getTableColHeaderRoleProps({ tableRole, colIndex: 0 })), selectionType === 'multi' ? (React.createElement(SelectionControl, Object.assign({ onFocusDown: event => {
31
31
  onFocusMove(event.target, -1, +1);
32
32
  }, focusedComponent: focusedComponent, onFocusedComponentChange: onFocusedComponentChange }, getSelectAllProps(), (sticky ? { tabIndex: -1 } : {})))) : (React.createElement(ScreenreaderOnly, null, singleSelectionHeaderAriaLabel)))) : null,
33
33
  columnDefinitions.map((column, colIndex) => {
@@ -47,7 +47,7 @@ const Thead = React.forwardRef(({ containerWidth, selectionType, getSelectAllPro
47
47
  width: widthOverride || column.width,
48
48
  minWidth: sticky ? undefined : column.minWidth,
49
49
  maxWidth: resizableColumns || sticky ? undefined : column.maxWidth,
50
- }, tabIndex: sticky ? -1 : 0, focusedComponent: focusedComponent, onFocusedComponentChange: onFocusedComponentChange, column: column, activeSortingColumn: sortingColumn, sortingDescending: sortingDescending, sortingDisabled: sortingDisabled, wrapLines: wrapLines, hidden: hidden, colIndex: colIndex, columnId: columnId, updateColumn: updateColumn, onResizeFinish: () => onResizeFinish(columnWidths), resizableColumns: resizableColumns, onClick: detail => fireNonCancelableEvent(onSortingChange, detail), isEditable: !!column.editConfig, stickyState: stickyState, cellRef: node => setCell(columnId, node), tableRole: tableRole }));
50
+ }, tabIndex: sticky ? -1 : 0, focusedComponent: focusedComponent, onFocusedComponentChange: onFocusedComponentChange, column: column, activeSortingColumn: sortingColumn, sortingDescending: sortingDescending, sortingDisabled: sortingDisabled, wrapLines: wrapLines, hidden: hidden, colIndex: selectionType ? colIndex + 1 : colIndex, columnId: columnId, updateColumn: updateColumn, onResizeFinish: () => onResizeFinish(columnWidths), resizableColumns: resizableColumns, onClick: detail => fireNonCancelableEvent(onSortingChange, detail), isEditable: !!column.editConfig, stickyState: stickyState, cellRef: node => setCell(columnId, node), tableRole: tableRole }));
51
51
  }))));
52
52
  });
53
53
  export default Thead;