@cloudscape-design/components 3.0.494 → 3.0.496

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 (230) hide show
  1. package/alert/styles.css.js +25 -25
  2. package/alert/styles.scoped.css +45 -51
  3. package/alert/styles.selectors.js +25 -25
  4. package/anchor-navigation/styles.css.js +8 -8
  5. package/anchor-navigation/styles.scoped.css +21 -24
  6. package/anchor-navigation/styles.selectors.js +8 -8
  7. package/annotation-context/annotation/styles.css.js +24 -24
  8. package/annotation-context/annotation/styles.scoped.css +32 -35
  9. package/annotation-context/annotation/styles.selectors.js +24 -24
  10. package/app-layout/visual-refresh/styles.css.js +80 -80
  11. package/app-layout/visual-refresh/styles.scoped.css +175 -181
  12. package/app-layout/visual-refresh/styles.selectors.js +80 -80
  13. package/attribute-editor/styles.css.js +14 -14
  14. package/attribute-editor/styles.scoped.css +27 -30
  15. package/attribute-editor/styles.selectors.js +14 -14
  16. package/badge/styles.css.js +5 -5
  17. package/badge/styles.scoped.css +8 -11
  18. package/badge/styles.selectors.js +5 -5
  19. package/breadcrumb-group/styles.css.js +7 -7
  20. package/breadcrumb-group/styles.scoped.css +18 -24
  21. package/breadcrumb-group/styles.selectors.js +7 -7
  22. package/button/styles.css.js +20 -20
  23. package/button/styles.scoped.css +154 -157
  24. package/button/styles.selectors.js +20 -20
  25. package/button-dropdown/mobile-expandable-group/styles.css.js +5 -5
  26. package/button-dropdown/mobile-expandable-group/styles.scoped.css +8 -11
  27. package/button-dropdown/mobile-expandable-group/styles.selectors.js +5 -5
  28. package/calendar/styles.css.js +18 -18
  29. package/calendar/styles.scoped.css +41 -44
  30. package/calendar/styles.selectors.js +18 -18
  31. package/cards/styles.css.js +39 -39
  32. package/cards/styles.scoped.css +52 -55
  33. package/cards/styles.selectors.js +39 -39
  34. package/checkbox/styles.css.js +3 -3
  35. package/checkbox/styles.scoped.css +8 -11
  36. package/checkbox/styles.selectors.js +3 -3
  37. package/code-editor/styles.css.js +32 -32
  38. package/code-editor/styles.scoped.css +132 -135
  39. package/code-editor/styles.selectors.js +32 -32
  40. package/collection-preferences/content-display/styles.css.js +11 -11
  41. package/collection-preferences/content-display/styles.scoped.css +20 -23
  42. package/collection-preferences/content-display/styles.selectors.js +11 -11
  43. package/collection-preferences/styles.css.js +37 -37
  44. package/collection-preferences/styles.scoped.css +47 -50
  45. package/collection-preferences/styles.selectors.js +37 -37
  46. package/column-layout/styles.css.js +13 -13
  47. package/column-layout/styles.scoped.css +46 -49
  48. package/column-layout/styles.selectors.js +13 -13
  49. package/container/styles.css.js +29 -29
  50. package/container/styles.scoped.css +55 -58
  51. package/container/styles.selectors.js +29 -29
  52. package/date-picker/styles.css.js +7 -7
  53. package/date-picker/styles.scoped.css +12 -15
  54. package/date-picker/styles.selectors.js +7 -7
  55. package/date-range-picker/styles.css.js +38 -38
  56. package/date-range-picker/styles.scoped.css +49 -52
  57. package/date-range-picker/styles.selectors.js +38 -38
  58. package/drawer/styles.css.js +3 -3
  59. package/drawer/styles.scoped.css +11 -14
  60. package/drawer/styles.selectors.js +3 -3
  61. package/expandable-section/styles.css.js +32 -32
  62. package/expandable-section/styles.scoped.css +65 -68
  63. package/expandable-section/styles.selectors.js +32 -32
  64. package/flashbar/styles.css.js +47 -47
  65. package/flashbar/styles.scoped.css +149 -152
  66. package/flashbar/styles.selectors.js +47 -47
  67. package/form/styles.css.js +9 -9
  68. package/form/styles.scoped.css +11 -14
  69. package/form/styles.selectors.js +9 -9
  70. package/form-field/styles.css.js +19 -19
  71. package/form-field/styles.scoped.css +32 -35
  72. package/form-field/styles.selectors.js +19 -19
  73. package/grid/styles.css.js +53 -53
  74. package/grid/styles.scoped.css +57 -60
  75. package/grid/styles.selectors.js +53 -53
  76. package/header/styles.css.js +34 -34
  77. package/header/styles.scoped.css +53 -56
  78. package/header/styles.selectors.js +34 -34
  79. package/help-panel/styles.css.js +4 -4
  80. package/help-panel/styles.scoped.css +66 -69
  81. package/help-panel/styles.selectors.js +4 -4
  82. package/input/styles.css.js +12 -12
  83. package/input/styles.scoped.css +33 -36
  84. package/input/styles.selectors.js +12 -12
  85. package/internal/components/button-trigger/styles.css.js +10 -10
  86. package/internal/components/button-trigger/styles.scoped.css +27 -30
  87. package/internal/components/button-trigger/styles.selectors.js +10 -10
  88. package/internal/components/chart-filter/styles.css.js +3 -3
  89. package/internal/components/chart-filter/styles.scoped.css +6 -9
  90. package/internal/components/chart-filter/styles.selectors.js +3 -3
  91. package/internal/components/chart-legend/styles.css.js +6 -6
  92. package/internal/components/chart-legend/styles.scoped.css +18 -21
  93. package/internal/components/chart-legend/styles.selectors.js +6 -6
  94. package/internal/components/chart-popover/styles.css.js +3 -3
  95. package/internal/components/chart-popover/styles.scoped.css +6 -9
  96. package/internal/components/chart-popover/styles.selectors.js +3 -3
  97. package/internal/components/chart-series-details/styles.css.js +20 -20
  98. package/internal/components/chart-series-details/styles.scoped.css +42 -51
  99. package/internal/components/chart-series-details/styles.selectors.js +20 -20
  100. package/internal/components/chart-series-marker/styles.css.js +5 -5
  101. package/internal/components/chart-series-marker/styles.scoped.css +10 -13
  102. package/internal/components/chart-series-marker/styles.selectors.js +5 -5
  103. package/internal/components/chart-wrapper/styles.css.js +9 -9
  104. package/internal/components/chart-wrapper/styles.scoped.css +12 -15
  105. package/internal/components/chart-wrapper/styles.selectors.js +9 -9
  106. package/internal/components/dropdown/styles.css.js +20 -20
  107. package/internal/components/dropdown/styles.scoped.css +38 -41
  108. package/internal/components/dropdown/styles.selectors.js +20 -20
  109. package/internal/components/dropdown-footer/styles.css.js +3 -3
  110. package/internal/components/dropdown-footer/styles.scoped.css +6 -9
  111. package/internal/components/dropdown-footer/styles.selectors.js +3 -3
  112. package/internal/components/dropdown-status/styles.css.js +2 -2
  113. package/internal/components/dropdown-status/styles.scoped.css +5 -8
  114. package/internal/components/dropdown-status/styles.selectors.js +2 -2
  115. package/internal/components/focus-lock/utils.d.ts +1 -0
  116. package/internal/components/focus-lock/utils.d.ts.map +1 -1
  117. package/internal/components/focus-lock/utils.js +4 -3
  118. package/internal/components/focus-lock/utils.js.map +1 -1
  119. package/internal/components/menu-dropdown/styles.css.js +7 -7
  120. package/internal/components/menu-dropdown/styles.scoped.css +16 -19
  121. package/internal/components/menu-dropdown/styles.selectors.js +7 -7
  122. package/internal/components/option/styles.css.js +17 -17
  123. package/internal/components/option/styles.scoped.css +32 -35
  124. package/internal/components/option/styles.selectors.js +17 -17
  125. package/internal/components/options-list/styles.css.js +2 -2
  126. package/internal/components/options-list/styles.scoped.css +5 -8
  127. package/internal/components/options-list/styles.selectors.js +2 -2
  128. package/internal/components/token-list/styles.css.js +9 -9
  129. package/internal/components/token-list/styles.scoped.css +23 -26
  130. package/internal/components/token-list/styles.selectors.js +9 -9
  131. package/internal/context/single-tab-stop-navigation-context.d.ts +9 -4
  132. package/internal/context/single-tab-stop-navigation-context.d.ts.map +1 -1
  133. package/internal/context/single-tab-stop-navigation-context.js +15 -5
  134. package/internal/context/single-tab-stop-navigation-context.js.map +1 -1
  135. package/internal/environment.js +1 -1
  136. package/internal/environment.json +1 -1
  137. package/internal/manifest.json +1 -1
  138. package/internal/utils/scrollable-containers.d.ts +2 -1
  139. package/internal/utils/scrollable-containers.d.ts.map +1 -1
  140. package/internal/utils/scrollable-containers.js +11 -2
  141. package/internal/utils/scrollable-containers.js.map +1 -1
  142. package/link/styles.css.js +20 -20
  143. package/link/styles.scoped.css +74 -77
  144. package/link/styles.selectors.js +20 -20
  145. package/modal/styles.css.js +23 -23
  146. package/modal/styles.scoped.css +44 -50
  147. package/modal/styles.selectors.js +23 -23
  148. package/multiselect/styles.css.js +2 -2
  149. package/multiselect/styles.scoped.css +5 -8
  150. package/multiselect/styles.selectors.js +2 -2
  151. package/package.json +1 -1
  152. package/pagination/styles.css.js +9 -9
  153. package/pagination/styles.scoped.css +26 -29
  154. package/pagination/styles.selectors.js +9 -9
  155. package/popover/styles.css.js +50 -50
  156. package/popover/styles.scoped.css +72 -81
  157. package/popover/styles.selectors.js +50 -50
  158. package/popover/use-popover-position.d.ts.map +1 -1
  159. package/popover/use-popover-position.js +4 -2
  160. package/popover/use-popover-position.js.map +1 -1
  161. package/progress-bar/styles.css.js +18 -18
  162. package/progress-bar/styles.scoped.css +35 -38
  163. package/progress-bar/styles.selectors.js +18 -18
  164. package/property-filter/styles.css.js +31 -31
  165. package/property-filter/styles.scoped.css +36 -39
  166. package/property-filter/styles.selectors.js +31 -31
  167. package/radio-group/styles.css.js +9 -9
  168. package/radio-group/styles.scoped.css +18 -21
  169. package/radio-group/styles.selectors.js +9 -9
  170. package/segmented-control/styles.css.js +14 -14
  171. package/segmented-control/styles.scoped.css +36 -39
  172. package/segmented-control/styles.selectors.js +14 -14
  173. package/select/styles.css.js +1 -1
  174. package/select/styles.scoped.css +4 -7
  175. package/select/styles.selectors.js +1 -1
  176. package/side-navigation/styles.css.js +28 -28
  177. package/side-navigation/styles.scoped.css +41 -44
  178. package/side-navigation/styles.selectors.js +28 -28
  179. package/split-panel/styles.css.js +55 -55
  180. package/split-panel/styles.scoped.css +78 -81
  181. package/split-panel/styles.selectors.js +55 -55
  182. package/table/resizer/styles.css.js +8 -8
  183. package/table/resizer/styles.scoped.css +17 -20
  184. package/table/resizer/styles.selectors.js +8 -8
  185. package/table/table-role/grid-navigation.d.ts.map +1 -1
  186. package/table/table-role/grid-navigation.js +73 -41
  187. package/table/table-role/grid-navigation.js.map +1 -1
  188. package/table/table-role/utils.d.ts +1 -16
  189. package/table/table-role/utils.d.ts.map +1 -1
  190. package/table/table-role/utils.js +0 -53
  191. package/table/table-role/utils.js.map +1 -1
  192. package/tabs/styles.css.js +21 -21
  193. package/tabs/styles.scoped.css +42 -45
  194. package/tabs/styles.selectors.js +21 -21
  195. package/text-content/styles.css.js +1 -1
  196. package/text-content/styles.scoped.css +63 -66
  197. package/text-content/styles.selectors.js +1 -1
  198. package/text-filter/styles.css.js +3 -3
  199. package/text-filter/styles.scoped.css +6 -9
  200. package/text-filter/styles.selectors.js +3 -3
  201. package/textarea/styles.css.js +4 -4
  202. package/textarea/styles.scoped.css +15 -18
  203. package/textarea/styles.selectors.js +4 -4
  204. package/tiles/styles.css.js +29 -29
  205. package/tiles/styles.scoped.css +76 -82
  206. package/tiles/styles.selectors.js +29 -29
  207. package/toggle/styles.css.js +8 -8
  208. package/toggle/styles.scoped.css +16 -19
  209. package/toggle/styles.selectors.js +8 -8
  210. package/token-group/styles.css.js +8 -8
  211. package/token-group/styles.scoped.css +19 -22
  212. package/token-group/styles.selectors.js +8 -8
  213. package/top-navigation/1.0-beta/styles.css.js +25 -25
  214. package/top-navigation/1.0-beta/styles.scoped.css +45 -48
  215. package/top-navigation/1.0-beta/styles.selectors.js +25 -25
  216. package/top-navigation/styles.css.js +47 -47
  217. package/top-navigation/styles.scoped.css +75 -84
  218. package/top-navigation/styles.selectors.js +47 -47
  219. package/tutorial-panel/components/tutorial-detail-view/styles.css.js +20 -20
  220. package/tutorial-panel/components/tutorial-detail-view/styles.scoped.css +24 -27
  221. package/tutorial-panel/components/tutorial-detail-view/styles.selectors.js +20 -20
  222. package/tutorial-panel/components/tutorial-list/styles.css.js +18 -18
  223. package/tutorial-panel/components/tutorial-list/styles.scoped.css +36 -45
  224. package/tutorial-panel/components/tutorial-list/styles.selectors.js +18 -18
  225. package/tutorial-panel/styles.css.js +1 -1
  226. package/tutorial-panel/styles.scoped.css +4 -7
  227. package/tutorial-panel/styles.selectors.js +1 -1
  228. package/wizard/styles.css.js +31 -31
  229. package/wizard/styles.scoped.css +65 -68
  230. package/wizard/styles.selectors.js +31 -31
@@ -90,13 +90,13 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
90
90
  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
91
91
  SPDX-License-Identifier: Apache-2.0
92
92
  */
93
- .awsui_resize-active_x7peu_1n0ne_93:not(#\9):not(.awsui_resize-active-with-focus_x7peu_1n0ne_93) * {
93
+ .awsui_resize-active_x7peu_5w5bo_93:not(#\9):not(.awsui_resize-active-with-focus_x7peu_5w5bo_93) * {
94
94
  cursor: col-resize;
95
95
  -webkit-user-select: none;
96
96
  user-select: none;
97
97
  }
98
98
 
99
- th:not(#\9):not(:last-child) > .awsui_divider_x7peu_1n0ne_98 {
99
+ th:not(#\9):not(:last-child) > .awsui_divider_x7peu_5w5bo_98 {
100
100
  position: absolute;
101
101
  outline: none;
102
102
  pointer-events: none;
@@ -109,26 +109,26 @@ th:not(#\9):not(:last-child) > .awsui_divider_x7peu_1n0ne_98 {
109
109
  border-left: var(--border-item-width-yel47s, 2px) solid var(--color-border-divider-interactive-default-byy830, #7d8998);
110
110
  box-sizing: border-box;
111
111
  }
112
- th:not(#\9):not(:last-child) > .awsui_divider-disabled_x7peu_1n0ne_111 {
112
+ th:not(#\9):not(:last-child) > .awsui_divider-disabled_x7peu_5w5bo_111 {
113
113
  border-left-color: var(--color-border-divider-default-j74lyz, #b6bec9);
114
114
  }
115
- th:not(#\9):not(:last-child) > .awsui_divider-active_x7peu_1n0ne_114 {
115
+ th:not(#\9):not(:last-child) > .awsui_divider-active_x7peu_5w5bo_114 {
116
116
  border-left: 2px solid var(--color-border-divider-active-k4haaf, #000716);
117
117
  }
118
118
 
119
- .awsui_resizer_x7peu_1n0ne_118:not(#\9) {
120
- /* stylelint-disable-next-line plugin/no-unsupported-browser-features */
119
+ .awsui_resizer_x7peu_5w5bo_118:not(#\9) {
121
120
  border-collapse: separate;
122
121
  border-spacing: 0;
122
+ box-sizing: border-box;
123
123
  caption-side: top;
124
124
  cursor: auto;
125
- direction: ltr;
125
+ direction: inherit;
126
126
  empty-cells: show;
127
127
  font-family: serif;
128
128
  font-size: medium;
129
129
  font-style: normal;
130
130
  font-variant: normal;
131
- font-weight: normal;
131
+ font-weight: 400;
132
132
  font-stretch: normal;
133
133
  line-height: normal;
134
134
  -webkit-hyphens: none;
@@ -137,15 +137,12 @@ th:not(#\9):not(:last-child) > .awsui_divider-active_x7peu_1n0ne_114 {
137
137
  list-style: disc outside none;
138
138
  tab-size: 8;
139
139
  text-align: left;
140
- text-align-last: auto;
141
140
  text-indent: 0;
142
141
  text-shadow: none;
143
142
  text-transform: none;
144
143
  visibility: visible;
145
144
  white-space: normal;
146
- widows: 2;
147
145
  word-spacing: normal;
148
- box-sizing: border-box;
149
146
  font-size: var(--font-size-body-m-x4okxb, 14px);
150
147
  line-height: var(--line-height-body-m-30ar75, 20px);
151
148
  color: var(--color-text-body-default-at06ol, #000716);
@@ -163,29 +160,29 @@ th:not(#\9):not(:last-child) > .awsui_divider-active_x7peu_1n0ne_114 {
163
160
  width: var(--space-l-t419sm, 20px);
164
161
  z-index: 10;
165
162
  }
166
- .awsui_resizer_x7peu_1n0ne_118:not(#\9):focus {
163
+ .awsui_resizer_x7peu_5w5bo_118:not(#\9):focus {
167
164
  outline: none;
168
165
  text-decoration: none;
169
166
  }
170
- .awsui_resize-active_x7peu_1n0ne_93 .awsui_resizer_x7peu_1n0ne_118:not(#\9) {
167
+ .awsui_resize-active_x7peu_5w5bo_93 .awsui_resizer_x7peu_5w5bo_118:not(#\9) {
171
168
  pointer-events: none;
172
169
  }
173
- th:not(#\9):last-child > .awsui_resizer_x7peu_1n0ne_118 {
170
+ th:not(#\9):last-child > .awsui_resizer_x7peu_5w5bo_118 {
174
171
  width: calc(var(--space-l-t419sm, 20px) / 2);
175
172
  right: 0;
176
173
  }
177
- .awsui_resizer_x7peu_1n0ne_118:not(#\9):hover + .awsui_divider_x7peu_1n0ne_98 {
174
+ .awsui_resizer_x7peu_5w5bo_118:not(#\9):hover + .awsui_divider_x7peu_5w5bo_98 {
178
175
  border-left: 2px solid var(--color-border-divider-active-k4haaf, #000716);
179
176
  }
180
- body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_1n0ne_118.awsui_has-focus_x7peu_1n0ne_153:not(#\9) {
177
+ body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_5w5bo_118.awsui_has-focus_x7peu_5w5bo_175:not(#\9) {
181
178
  position: relative;
182
179
  position: absolute;
183
180
  }
184
- body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_1n0ne_118.awsui_has-focus_x7peu_1n0ne_153:not(#\9) {
181
+ body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_5w5bo_118.awsui_has-focus_x7peu_5w5bo_175:not(#\9) {
185
182
  outline: 2px dotted transparent;
186
183
  outline-offset: calc(calc(var(--space-table-header-focus-outline-gutter-7js4en, 0px) - 2px) - 1px);
187
184
  }
188
- body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_1n0ne_118.awsui_has-focus_x7peu_1n0ne_153:not(#\9)::before {
185
+ body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_5w5bo_118.awsui_has-focus_x7peu_5w5bo_175:not(#\9)::before {
189
186
  content: " ";
190
187
  display: block;
191
188
  position: absolute;
@@ -197,7 +194,7 @@ body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_1n0ne_118.awsui_has-foc
197
194
  box-shadow: 0 0 0 2px var(--color-border-item-focused-b2ntyl, #0972d3);
198
195
  }
199
196
 
200
- .awsui_tracker_x7peu_1n0ne_173:not(#\9) {
197
+ .awsui_tracker_x7peu_5w5bo_195:not(#\9) {
201
198
  display: none;
202
199
  position: absolute;
203
200
  border-left: var(--border-divider-list-width-27y3k5, 1px) dashed var(--color-border-divider-active-k4haaf, #000716);
@@ -205,6 +202,6 @@ body[data-awsui-focus-visible=true] .awsui_resizer_x7peu_1n0ne_118.awsui_has-foc
205
202
  top: 0;
206
203
  bottom: 0;
207
204
  }
208
- .awsui_resize-active_x7peu_1n0ne_93 .awsui_tracker_x7peu_1n0ne_173:not(#\9) {
205
+ .awsui_resize-active_x7peu_5w5bo_93 .awsui_tracker_x7peu_5w5bo_195:not(#\9) {
209
206
  display: block;
210
207
  }
@@ -2,13 +2,13 @@
2
2
  // es-module interop with Babel and Typescript
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  module.exports.default = {
5
- "resize-active": "awsui_resize-active_x7peu_1n0ne_93",
6
- "resize-active-with-focus": "awsui_resize-active-with-focus_x7peu_1n0ne_93",
7
- "divider": "awsui_divider_x7peu_1n0ne_98",
8
- "divider-disabled": "awsui_divider-disabled_x7peu_1n0ne_111",
9
- "divider-active": "awsui_divider-active_x7peu_1n0ne_114",
10
- "resizer": "awsui_resizer_x7peu_1n0ne_118",
11
- "has-focus": "awsui_has-focus_x7peu_1n0ne_153",
12
- "tracker": "awsui_tracker_x7peu_1n0ne_173"
5
+ "resize-active": "awsui_resize-active_x7peu_5w5bo_93",
6
+ "resize-active-with-focus": "awsui_resize-active-with-focus_x7peu_5w5bo_93",
7
+ "divider": "awsui_divider_x7peu_5w5bo_98",
8
+ "divider-disabled": "awsui_divider-disabled_x7peu_5w5bo_111",
9
+ "divider-active": "awsui_divider-active_x7peu_5w5bo_114",
10
+ "resizer": "awsui_resizer_x7peu_5w5bo_118",
11
+ "has-focus": "awsui_has-focus_x7peu_5w5bo_175",
12
+ "tracker": "awsui_tracker_x7peu_5w5bo_195"
13
13
  };
14
14
 
@@ -1 +1 @@
1
- {"version":3,"file":"grid-navigation.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/grid-navigation.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAe,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAMhE;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,eA2B/G"}
1
+ {"version":3,"file":"grid-navigation.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/grid-navigation.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAe,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAWhE;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,eAoC/G"}
@@ -1,11 +1,13 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
+ import React from 'react';
3
4
  import { useEffect, useMemo } from 'react';
4
- import { defaultIsSuppressed, muteElementFocusables, restoreElementFocusables, getFirstFocusable, getFocusables, findTableRowByAriaRowIndex, findTableRowCellByAriaColIndex, setTabIndex, } from './utils';
5
+ import { defaultIsSuppressed, findTableRowByAriaRowIndex, findTableRowCellByAriaColIndex } from './utils';
5
6
  import { KeyCode } from '../../internal/keycode';
6
7
  import { useStableCallback } from '@cloudscape-design/component-toolkit/internal';
7
- import React from 'react';
8
8
  import { nodeBelongs } from '../../internal/utils/node-belongs';
9
+ import { getAllFocusables } from '../../internal/components/focus-lock/utils';
10
+ import { SingleTabStopNavigationContext, } from '../../internal/context/single-tab-stop-navigation-context';
9
11
  /**
10
12
  * Makes table navigable with keyboard commands.
11
13
  * See grid-navigation.md
@@ -31,7 +33,10 @@ export function GridNavigationProvider({ keyboardNavigation, pageSize, getTable,
31
33
  gridNavigation.refresh();
32
34
  }
33
35
  });
34
- return React.createElement(React.Fragment, null, children);
36
+ return (React.createElement(SingleTabStopNavigationContext.Provider, { value: {
37
+ navigationActive: keyboardNavigation,
38
+ registerFocusable: gridNavigation.registerFocusable,
39
+ } }, children));
35
40
  }
36
41
  /**
37
42
  * This helper encapsulates the grid navigation behaviors which are:
@@ -46,6 +51,19 @@ class GridNavigationProcessor {
46
51
  this._table = null;
47
52
  // State
48
53
  this.focusedCell = null;
54
+ this.focusables = new Set();
55
+ this.focusHandlers = new Map();
56
+ this.focusTarget = null;
57
+ this.registerFocusable = (focusable, changeHandler) => {
58
+ this.focusables.add(focusable);
59
+ this.focusHandlers.set(focusable, changeHandler);
60
+ changeHandler(this.focusTarget, this.isSuppressed(focusable.current));
61
+ return () => this.unregisterFocusable(focusable);
62
+ };
63
+ this.unregisterFocusable = (focusable) => {
64
+ this.focusables.delete(focusable);
65
+ this.focusHandlers.delete(focusable);
66
+ };
49
67
  this.onFocusin = (event) => {
50
68
  var _a;
51
69
  if (!(event.target instanceof HTMLElement)) {
@@ -56,11 +74,11 @@ class GridNavigationProcessor {
56
74
  return;
57
75
  }
58
76
  this.focusedCell = cell;
59
- this.ensureSingleFocusable();
77
+ this.updateFocusTarget();
60
78
  // Focusing on cell is not eligible when it contains focusable elements in the content.
61
79
  // If content focusables are available - move the focus to the first one.
62
80
  if (cell.element === cell.cellElement) {
63
- (_a = getFirstFocusable(cell.cellElement)) === null || _a === void 0 ? void 0 : _a.focus();
81
+ (_a = this.getFocusablesFrom(cell.cellElement)[0]) === null || _a === void 0 ? void 0 : _a.focus();
64
82
  }
65
83
  };
66
84
  this.onFocusout = () => {
@@ -91,8 +109,7 @@ class GridNavigationProcessor {
91
109
  const from = this.focusedCell;
92
110
  const minExtreme = Number.NEGATIVE_INFINITY;
93
111
  const maxExtreme = Number.POSITIVE_INFINITY;
94
- // Do not intercept any keys when the navigation is suppressed.
95
- if (this.isSuppressed(from.element)) {
112
+ if (this.isSuppressed(document.activeElement) || !this.isRegistered(document.activeElement)) {
96
113
  return;
97
114
  }
98
115
  switch (key) {
@@ -130,18 +147,27 @@ class GridNavigationProcessor {
130
147
  return;
131
148
  }
132
149
  };
150
+ this.getRegisteredElements = () => {
151
+ const registeredElements = new Set();
152
+ for (const focusable of this.focusables) {
153
+ if (focusable.current) {
154
+ registeredElements.add(focusable.current);
155
+ }
156
+ }
157
+ return registeredElements;
158
+ };
133
159
  }
134
160
  init(table) {
135
161
  this._table = table;
136
162
  this.table.addEventListener('focusin', this.onFocusin);
137
163
  this.table.addEventListener('focusout', this.onFocusout);
138
164
  this.table.addEventListener('keydown', this.onKeydown);
139
- this.ensureSingleFocusable();
165
+ this.updateFocusTarget();
140
166
  this.cleanup = () => {
141
167
  this.table.removeEventListener('focusin', this.onFocusin);
142
168
  this.table.removeEventListener('focusout', this.onFocusout);
143
169
  this.table.removeEventListener('keydown', this.onKeydown);
144
- restoreElementFocusables(this.table);
170
+ this.focusables.forEach(this.unregisterFocusable);
145
171
  };
146
172
  }
147
173
  cleanup() {
@@ -151,14 +177,16 @@ class GridNavigationProcessor {
151
177
  this._pageSize = pageSize;
152
178
  }
153
179
  refresh() {
154
- if (this._table) {
155
- // Update focused cell indices in case table rows, columns, or firstIndex change.
156
- if (this.focusedCell) {
157
- this.focusedCell = this.findFocusedCell(this.focusedCell.element);
180
+ // Timeout ensures the newly rendered content elements are registered.
181
+ setTimeout(() => {
182
+ if (this._table) {
183
+ // Update focused cell indices in case table rows, columns, or firstIndex change.
184
+ if (this.focusedCell) {
185
+ this.focusedCell = this.findFocusedCell(this.focusedCell.element);
186
+ }
187
+ this.updateFocusTarget();
158
188
  }
159
- // Ensure newly added elements if any are muted.
160
- this.ensureSingleFocusable();
161
- }
189
+ }, 0);
162
190
  }
163
191
  get pageSize() {
164
192
  return this._pageSize;
@@ -169,36 +197,40 @@ class GridNavigationProcessor {
169
197
  }
170
198
  return this._table;
171
199
  }
172
- isSuppressed(focusedElement) {
173
- return defaultIsSuppressed(focusedElement);
174
- }
175
200
  moveFocusBy(cell, delta) {
176
201
  var _a;
177
202
  (_a = this.getNextFocusable(cell, delta)) === null || _a === void 0 ? void 0 : _a.focus();
178
203
  }
179
- /**
180
- * Finds focused cell props corresponding the focused element inside the table.
181
- * The function relies on ARIA colindex/rowindex attributes being correctly applied.
182
- */
204
+ updateFocusTarget() {
205
+ this.focusTarget = this.getSingleFocusable();
206
+ this.focusables.forEach(focusable => {
207
+ const element = focusable.current;
208
+ const handler = this.focusHandlers.get(focusable);
209
+ handler(this.focusTarget, this.isSuppressed(element));
210
+ });
211
+ }
212
+ isSuppressed(element) {
213
+ return !element || defaultIsSuppressed(element);
214
+ }
215
+ isRegistered(element) {
216
+ return !element || this.getRegisteredElements().has(element);
217
+ }
183
218
  findFocusedCell(focusedElement) {
184
219
  var _a, _b;
185
220
  const cellElement = focusedElement.closest('td,th');
186
221
  const rowElement = cellElement === null || cellElement === void 0 ? void 0 : cellElement.closest('tr');
187
222
  if (!cellElement || !rowElement) {
188
- return null;
223
+ return this.focusedCell;
189
224
  }
190
225
  const colIndex = parseInt((_a = cellElement.getAttribute('aria-colindex')) !== null && _a !== void 0 ? _a : '');
191
226
  const rowIndex = parseInt((_b = rowElement.getAttribute('aria-rowindex')) !== null && _b !== void 0 ? _b : '');
192
227
  if (isNaN(colIndex) || isNaN(rowIndex)) {
193
- return null;
228
+ return this.focusedCell;
194
229
  }
195
- const cellFocusables = getFocusables(cellElement);
230
+ const cellFocusables = this.getFocusablesFrom(cellElement);
196
231
  const elementIndex = cellFocusables.indexOf(focusedElement);
197
232
  return { rowIndex, colIndex, rowElement, cellElement, element: focusedElement, elementIndex };
198
233
  }
199
- /**
200
- * Finds element to be focused next. The focus can transition between cells or interactive elements inside cells.
201
- */
202
234
  getNextFocusable(from, delta) {
203
235
  var _a;
204
236
  // Find next row to move focus into (can be null if the top/bottom is reached).
@@ -208,7 +240,7 @@ class GridNavigationProcessor {
208
240
  return null;
209
241
  }
210
242
  // Return next interactive cell content element if available.
211
- const cellFocusables = getFocusables(from.cellElement);
243
+ const cellFocusables = this.getFocusablesFrom(from.cellElement);
212
244
  const nextElementIndex = from.elementIndex + delta.x;
213
245
  if (delta.x && from.elementIndex !== -1 && 0 <= nextElementIndex && nextElementIndex < cellFocusables.length) {
214
246
  return cellFocusables[nextElementIndex];
@@ -224,27 +256,27 @@ class GridNavigationProcessor {
224
256
  return null;
225
257
  }
226
258
  // Return cell interactive content or the cell itself.
227
- const targetCellFocusables = getFocusables(targetCell);
259
+ const targetCellFocusables = this.getFocusablesFrom(targetCell);
228
260
  const focusIndex = delta.x < 0 ? targetCellFocusables.length - 1 : delta.x > 0 ? 0 : from.elementIndex;
229
261
  const focusTarget = (_a = targetCellFocusables[focusIndex]) !== null && _a !== void 0 ? _a : targetCell;
230
262
  return focusTarget;
231
263
  }
232
- /**
233
- * Makes the cell element, the first interactive element or the first cell of the table user-focusable.
234
- */
235
- ensureSingleFocusable() {
264
+ getSingleFocusable() {
236
265
  var _a;
237
- const cellSuppressed = this.focusedCell ? this.isSuppressed(this.focusedCell.element) : false;
238
- muteElementFocusables(this.table, cellSuppressed);
266
+ const cell = this.focusedCell;
239
267
  const firstTableCell = this.table.querySelector('td,th');
240
268
  // A single element of the table is made user-focusable.
241
269
  // It defaults to the first interactive element of the first cell or the first cell itself otherwise.
242
- let focusTarget = (_a = (firstTableCell && getFocusables(firstTableCell)[0])) !== null && _a !== void 0 ? _a : firstTableCell;
270
+ let focusTarget = (_a = (firstTableCell && this.getFocusablesFrom(firstTableCell)[0])) !== null && _a !== void 0 ? _a : firstTableCell;
243
271
  // When a navigation-focused element is present in the table it is used for user-navigation instead.
244
- if (this.focusedCell) {
245
- focusTarget = this.getNextFocusable(this.focusedCell, { x: 0, y: 0 });
272
+ if (cell) {
273
+ focusTarget = this.getNextFocusable(cell, { x: 0, y: 0 });
246
274
  }
247
- setTabIndex(focusTarget, 0);
275
+ return focusTarget;
276
+ }
277
+ getFocusablesFrom(target) {
278
+ const registeredElements = this.getRegisteredElements();
279
+ return getAllFocusables(target).filter(el => registeredElements.has(el));
248
280
  }
249
281
  }
250
282
  //# sourceMappingURL=grid-navigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid-navigation.js","sourceRoot":"lib/default/","sources":["table/table-role/grid-navigation.tsx"],"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 {\n defaultIsSuppressed,\n muteElementFocusables,\n restoreElementFocusables,\n getFirstFocusable,\n getFocusables,\n findTableRowByAriaRowIndex,\n findTableRowCellByAriaColIndex,\n setTabIndex,\n} from './utils';\nimport { FocusedCell, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { useStableCallback } from '@cloudscape-design/component-toolkit/internal';\nimport React from 'react';\nimport { nodeBelongs } from '../../internal/utils/node-belongs';\n\n/**\n * Makes table navigable with keyboard commands.\n * See grid-navigation.md\n */\nexport function GridNavigationProvider({ keyboardNavigation, pageSize, getTable, children }: GridNavigationProps) {\n const gridNavigation = useMemo(() => new GridNavigationProcessor(), []);\n\n const getTableStable = useStableCallback(getTable);\n\n // Initialize the processor with the table container assuming it is mounted synchronously and only once.\n useEffect(() => {\n if (keyboardNavigation) {\n const table = getTableStable();\n table && gridNavigation.init(table);\n }\n return () => gridNavigation.cleanup();\n }, [keyboardNavigation, gridNavigation, getTableStable]);\n\n // Notify the processor of the props change.\n useEffect(() => {\n gridNavigation.update({ pageSize });\n }, [gridNavigation, pageSize]);\n\n // Notify the processor of the new render.\n useEffect(() => {\n if (keyboardNavigation) {\n gridNavigation.refresh();\n }\n });\n\n return <>{children}</>;\n}\n\n/**\n * This helper encapsulates the grid navigation behaviors which are:\n * 1. Responding to keyboard commands and moving the focus accordingly;\n * 2. Muting table interactive elements for only one to be user-focusable at a time;\n * 3. Suppressing the above behaviors when focusing an element inside a dialog or when instructed explicitly.\n */\nclass GridNavigationProcessor {\n // Props\n private _pageSize = 0;\n private _table: null | HTMLTableElement = null;\n\n // State\n private focusedCell: null | FocusedCell = null;\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 this.ensureSingleFocusable();\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 restoreElementFocusables(this.table);\n };\n }\n\n public cleanup() {\n // Do nothing before initialized.\n }\n\n public update({ pageSize }: { pageSize: number }) {\n this._pageSize = pageSize;\n }\n\n public refresh() {\n if (this._table) {\n // Update focused cell indices in case table rows, columns, or firstIndex change.\n if (this.focusedCell) {\n this.focusedCell = this.findFocusedCell(this.focusedCell.element);\n }\n\n // Ensure newly added elements if any are muted.\n this.ensureSingleFocusable();\n }\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: GridNavigationProcessor is used before initialization.');\n }\n return this._table;\n }\n\n private isSuppressed(focusedElement: HTMLElement): boolean {\n return defaultIsSuppressed(focusedElement);\n }\n\n private onFocusin = (event: FocusEvent) => {\n if (!(event.target instanceof HTMLElement)) {\n return;\n }\n\n const cell = this.findFocusedCell(event.target);\n if (!cell) {\n return;\n }\n\n this.focusedCell = cell;\n\n this.ensureSingleFocusable();\n\n // Focusing on cell is not eligible when it contains focusable elements in the content.\n // If content focusables are available - move the focus to the first one.\n if (cell.element === cell.cellElement) {\n getFirstFocusable(cell.cellElement)?.focus();\n }\n };\n\n private onFocusout = () => {\n // When focus leaves the cell and the cell no longer belong to the table it indicates the focused element has been unmounted.\n // In that case the focus needs to be restored on the same coordinates.\n setTimeout(() => {\n if (this.focusedCell && !nodeBelongs(this.table, this.focusedCell.element)) {\n this.moveFocusBy(this.focusedCell, { x: 0, y: 0 });\n }\n }, 0);\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 // Do not intercept any keys when the navigation is suppressed.\n if (this.isSuppressed(from.element)) {\n return;\n }\n\n switch (key) {\n case KeyCode.up:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -1, x: 0 });\n\n case KeyCode.down:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 1, x: 0 });\n\n case KeyCode.left:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: -1 });\n\n case KeyCode.right:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: 1 });\n\n case KeyCode.pageUp:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -this.pageSize, x: 0 });\n\n case KeyCode.pageDown:\n event.preventDefault();\n return this.moveFocusBy(from, { y: this.pageSize, x: 0 });\n\n case KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: minExtreme });\n\n case KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: maxExtreme });\n\n case -KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: minExtreme, x: minExtreme });\n\n case -KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: maxExtreme, x: maxExtreme });\n\n default:\n return;\n }\n };\n\n private moveFocusBy(cell: FocusedCell, delta: { x: number; y: number }) {\n this.getNextFocusable(cell, delta)?.focus();\n }\n\n /**\n * Finds focused cell props corresponding the focused element inside the table.\n * The function relies on ARIA colindex/rowindex attributes being correctly applied.\n */\n private findFocusedCell(focusedElement: HTMLElement): null | FocusedCell {\n const cellElement = focusedElement.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(focusedElement);\n\n return { rowIndex, colIndex, rowElement, cellElement, element: focusedElement, elementIndex };\n }\n\n /**\n * Finds element to be focused next. The focus can transition between cells or interactive elements inside cells.\n */\n private getNextFocusable(from: FocusedCell, delta: { y: number; x: number }) {\n // Find next row to move focus into (can be null if the top/bottom is reached).\n const targetAriaRowIndex = from.rowIndex + delta.y;\n const targetRow = findTableRowByAriaRowIndex(this.table, targetAriaRowIndex, delta.y);\n if (!targetRow) {\n return null;\n }\n\n // Return next interactive cell content element if available.\n const cellFocusables = getFocusables(from.cellElement);\n const nextElementIndex = from.elementIndex + delta.x;\n if (delta.x && from.elementIndex !== -1 && 0 <= nextElementIndex && nextElementIndex < cellFocusables.length) {\n return cellFocusables[nextElementIndex];\n }\n\n // Find next cell to focus or move focus into (can be null if the left/right edge is reached).\n const targetAriaColIndex = from.colIndex + delta.x;\n const targetCell = findTableRowCellByAriaColIndex(targetRow, targetAriaColIndex, delta.x);\n if (!targetCell) {\n return null;\n }\n\n // When target cell matches the current cell it means we reached the left or right boundary.\n if (targetCell === from.cellElement && delta.x !== 0) {\n return null;\n }\n\n // Return cell interactive content or the cell itself.\n const targetCellFocusables = getFocusables(targetCell);\n const focusIndex = delta.x < 0 ? targetCellFocusables.length - 1 : delta.x > 0 ? 0 : from.elementIndex;\n const focusTarget = targetCellFocusables[focusIndex] ?? targetCell;\n return focusTarget;\n }\n\n /**\n * Makes the cell element, the first interactive element or the first cell of the table user-focusable.\n */\n private ensureSingleFocusable() {\n const cellSuppressed = this.focusedCell ? this.isSuppressed(this.focusedCell.element) : false;\n muteElementFocusables(this.table, cellSuppressed);\n\n const firstTableCell = this.table.querySelector('td,th') as null | HTMLTableCellElement;\n\n // A single element of the table is made user-focusable.\n // It defaults to the first interactive element of the first cell or the first cell itself otherwise.\n let focusTarget: null | HTMLElement = (firstTableCell && getFocusables(firstTableCell)[0]) ?? firstTableCell;\n\n // When a navigation-focused element is present in the table it is used for user-navigation instead.\n if (this.focusedCell) {\n focusTarget = this.getNextFocusable(this.focusedCell, { x: 0, y: 0 });\n }\n\n setTabIndex(focusTarget, 0);\n }\n}\n"]}
1
+ {"version":3,"file":"grid-navigation.js","sourceRoot":"lib/default/","sources":["table/table-role/grid-navigation.tsx"],"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 React from 'react';\nimport { useEffect, useMemo } from 'react';\nimport { defaultIsSuppressed, findTableRowByAriaRowIndex, findTableRowCellByAriaColIndex } from './utils';\nimport { FocusedCell, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { useStableCallback } from '@cloudscape-design/component-toolkit/internal';\nimport { nodeBelongs } from '../../internal/utils/node-belongs';\nimport { getAllFocusables } from '../../internal/components/focus-lock/utils';\nimport {\n SingleTabStopNavigationContext,\n FocusableDefinition,\n FocusableChangeHandler,\n} from '../../internal/context/single-tab-stop-navigation-context';\n\n/**\n * Makes table navigable with keyboard commands.\n * See grid-navigation.md\n */\nexport function GridNavigationProvider({ keyboardNavigation, pageSize, getTable, children }: GridNavigationProps) {\n const gridNavigation = useMemo(() => new GridNavigationProcessor(), []);\n\n const getTableStable = useStableCallback(getTable);\n\n // Initialize the processor with the table container assuming it is mounted synchronously and only once.\n useEffect(() => {\n if (keyboardNavigation) {\n const table = getTableStable();\n table && gridNavigation.init(table);\n }\n return () => gridNavigation.cleanup();\n }, [keyboardNavigation, gridNavigation, getTableStable]);\n\n // Notify the processor of the props change.\n useEffect(() => {\n gridNavigation.update({ pageSize });\n }, [gridNavigation, pageSize]);\n\n // Notify the processor of the new render.\n useEffect(() => {\n if (keyboardNavigation) {\n gridNavigation.refresh();\n }\n });\n\n return (\n <SingleTabStopNavigationContext.Provider\n value={{\n navigationActive: keyboardNavigation,\n registerFocusable: gridNavigation.registerFocusable,\n }}\n >\n {children}\n </SingleTabStopNavigationContext.Provider>\n );\n}\n\n/**\n * This helper encapsulates the grid navigation behaviors which are:\n * 1. Responding to keyboard commands and moving the focus accordingly;\n * 2. Muting table interactive elements for only one to be user-focusable at a time;\n * 3. Suppressing the above behaviors when focusing an element inside a dialog or when instructed explicitly.\n */\nclass GridNavigationProcessor {\n // Props\n private _pageSize = 0;\n private _table: null | HTMLTableElement = null;\n\n // State\n private focusedCell: null | FocusedCell = null;\n private focusables = new Set<FocusableDefinition>();\n private focusHandlers = new Map<FocusableDefinition, FocusableChangeHandler>();\n private focusTarget: null | Element = null;\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 this.updateFocusTarget();\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 this.focusables.forEach(this.unregisterFocusable);\n };\n }\n\n public cleanup() {\n // Do nothing before initialized.\n }\n\n public update({ pageSize }: { pageSize: number }) {\n this._pageSize = pageSize;\n }\n\n public refresh() {\n // Timeout ensures the newly rendered content elements are registered.\n setTimeout(() => {\n if (this._table) {\n // Update focused cell indices in case table rows, columns, or firstIndex change.\n if (this.focusedCell) {\n this.focusedCell = this.findFocusedCell(this.focusedCell.element);\n }\n this.updateFocusTarget();\n }\n }, 0);\n }\n\n public registerFocusable = (focusable: FocusableDefinition, changeHandler: FocusableChangeHandler) => {\n this.focusables.add(focusable);\n this.focusHandlers.set(focusable, changeHandler);\n changeHandler(this.focusTarget, this.isSuppressed(focusable.current));\n return () => this.unregisterFocusable(focusable);\n };\n\n public unregisterFocusable = (focusable: FocusableDefinition) => {\n this.focusables.delete(focusable);\n this.focusHandlers.delete(focusable);\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: GridNavigationProcessor is used before initialization.');\n }\n return this._table;\n }\n\n private onFocusin = (event: FocusEvent) => {\n if (!(event.target instanceof HTMLElement)) {\n return;\n }\n\n const cell = this.findFocusedCell(event.target);\n if (!cell) {\n return;\n }\n\n this.focusedCell = cell;\n\n this.updateFocusTarget();\n\n // Focusing on cell is not eligible when it contains focusable elements in the content.\n // If content focusables are available - move the focus to the first one.\n if (cell.element === cell.cellElement) {\n this.getFocusablesFrom(cell.cellElement)[0]?.focus();\n }\n };\n\n private onFocusout = () => {\n // When focus leaves the cell and the cell no longer belong to the table it indicates the focused element has been unmounted.\n // In that case the focus needs to be restored on the same coordinates.\n setTimeout(() => {\n if (this.focusedCell && !nodeBelongs(this.table, this.focusedCell.element)) {\n this.moveFocusBy(this.focusedCell, { x: 0, y: 0 });\n }\n }, 0);\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 if (this.isSuppressed(document.activeElement) || !this.isRegistered(document.activeElement)) {\n return;\n }\n\n switch (key) {\n case KeyCode.up:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -1, x: 0 });\n\n case KeyCode.down:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 1, x: 0 });\n\n case KeyCode.left:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: -1 });\n\n case KeyCode.right:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: 1 });\n\n case KeyCode.pageUp:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -this.pageSize, x: 0 });\n\n case KeyCode.pageDown:\n event.preventDefault();\n return this.moveFocusBy(from, { y: this.pageSize, x: 0 });\n\n case KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: minExtreme });\n\n case KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: maxExtreme });\n\n case -KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: minExtreme, x: minExtreme });\n\n case -KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: maxExtreme, x: maxExtreme });\n\n default:\n return;\n }\n };\n\n private moveFocusBy(cell: FocusedCell, delta: { x: number; y: number }) {\n this.getNextFocusable(cell, delta)?.focus();\n }\n\n private updateFocusTarget() {\n this.focusTarget = this.getSingleFocusable();\n this.focusables.forEach(focusable => {\n const element = focusable.current;\n const handler = this.focusHandlers.get(focusable)!;\n handler(this.focusTarget, this.isSuppressed(element));\n });\n }\n\n private isSuppressed(element: null | Element) {\n return !element || defaultIsSuppressed(element);\n }\n\n private isRegistered(element: null | Element) {\n return !element || this.getRegisteredElements().has(element);\n }\n\n private getRegisteredElements = (): Set<Element> => {\n const registeredElements = new Set<Element>();\n for (const focusable of this.focusables) {\n if (focusable.current) {\n registeredElements.add(focusable.current);\n }\n }\n return registeredElements;\n };\n\n private findFocusedCell(focusedElement: HTMLElement): null | FocusedCell {\n const cellElement = focusedElement.closest('td,th') as null | HTMLTableCellElement;\n const rowElement = cellElement?.closest('tr');\n\n if (!cellElement || !rowElement) {\n return this.focusedCell;\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 this.focusedCell;\n }\n\n const cellFocusables = this.getFocusablesFrom(cellElement);\n const elementIndex = cellFocusables.indexOf(focusedElement);\n\n return { rowIndex, colIndex, rowElement, cellElement, element: focusedElement, elementIndex };\n }\n\n private getNextFocusable(from: FocusedCell, delta: { y: number; x: number }) {\n // Find next row to move focus into (can be null if the top/bottom is reached).\n const targetAriaRowIndex = from.rowIndex + delta.y;\n const targetRow = findTableRowByAriaRowIndex(this.table, targetAriaRowIndex, delta.y);\n if (!targetRow) {\n return null;\n }\n\n // Return next interactive cell content element if available.\n const cellFocusables = this.getFocusablesFrom(from.cellElement);\n const nextElementIndex = from.elementIndex + delta.x;\n if (delta.x && from.elementIndex !== -1 && 0 <= nextElementIndex && nextElementIndex < cellFocusables.length) {\n return cellFocusables[nextElementIndex];\n }\n\n // Find next cell to focus or move focus into (can be null if the left/right edge is reached).\n const targetAriaColIndex = from.colIndex + delta.x;\n const targetCell = findTableRowCellByAriaColIndex(targetRow, targetAriaColIndex, delta.x);\n if (!targetCell) {\n return null;\n }\n\n // When target cell matches the current cell it means we reached the left or right boundary.\n if (targetCell === from.cellElement && delta.x !== 0) {\n return null;\n }\n\n // Return cell interactive content or the cell itself.\n const targetCellFocusables = this.getFocusablesFrom(targetCell);\n const focusIndex = delta.x < 0 ? targetCellFocusables.length - 1 : delta.x > 0 ? 0 : from.elementIndex;\n const focusTarget = targetCellFocusables[focusIndex] ?? targetCell;\n return focusTarget;\n }\n\n private getSingleFocusable() {\n const cell = this.focusedCell;\n const firstTableCell = this.table.querySelector('td,th') as null | HTMLTableCellElement;\n\n // A single element of the table is made user-focusable.\n // It defaults to the first interactive element of the first cell or the first cell itself otherwise.\n let focusTarget: null | HTMLElement =\n (firstTableCell && this.getFocusablesFrom(firstTableCell)[0]) ?? firstTableCell;\n\n // When a navigation-focused element is present in the table it is used for user-navigation instead.\n if (cell) {\n focusTarget = this.getNextFocusable(cell, { x: 0, y: 0 });\n }\n\n return focusTarget;\n }\n\n private getFocusablesFrom(target: HTMLElement) {\n const registeredElements = this.getRegisteredElements();\n return getAllFocusables(target).filter(el => registeredElements.has(el));\n }\n}\n"]}
@@ -1,22 +1,8 @@
1
- /**
2
- * Makes all element focusable children pseudo-focusable unless the grid navigation is suppressed.
3
- */
4
- export declare function muteElementFocusables(element: HTMLElement, suppressed: boolean): void;
5
- /**
6
- * This cleanup code ensures all cells are no longer focusable but the interactive elements are.
7
- * Currently there are no use cases for it as we don't expect the navigation to be used conditionally.
8
- */
9
- export declare function restoreElementFocusables(element: HTMLTableElement): void;
10
1
  /**
11
2
  * Returns true if the target element or one of its parents is a dialog or is marked with data-awsui-table-suppress-navigation attribute.
12
3
  * This is used to suppress navigation for interactive content without a need to use a custom suppression check.
13
4
  */
14
- export declare function defaultIsSuppressed(target: HTMLElement): boolean;
15
- /**
16
- * Returns actually focusable or pseudo-focusable elements to find navigation targets.
17
- */
18
- export declare function getFocusables(element: HTMLElement): HTMLElement[];
19
- export declare function getFirstFocusable(element: HTMLElement): HTMLElement | null;
5
+ export declare function defaultIsSuppressed(target: Element): boolean;
20
6
  /**
21
7
  * Finds the closest row to the targetAriaRowIndex+delta in the direction of delta.
22
8
  */
@@ -25,5 +11,4 @@ export declare function findTableRowByAriaRowIndex(table: HTMLTableElement, targ
25
11
  * Finds the closest column to the targetAriaColIndex+delta in the direction of delta.
26
12
  */
27
13
  export declare function findTableRowCellByAriaColIndex(tableRow: HTMLTableRowElement, targetAriaColIndex: number, delta: number): HTMLTableCellElement | null;
28
- export declare function setTabIndex(element: null | HTMLElement, tabIndex: number): void;
29
14
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/utils.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,QAiB9E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,QAQjE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,WAiBtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,iBAEjD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,sBAErD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,8BAqB5G;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,mBAAmB,EAC7B,kBAAkB,EAAE,MAAM,EAC1B,KAAK,EAAE,MAAM,+BAsBd;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,QAIxE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"lib/default/","sources":["table/table-role/utils.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,WAiBlD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,8BAqB5G;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,mBAAmB,EAC7B,kBAAkB,EAAE,MAAM,EAC1B,KAAK,EAAE,MAAM,+BAsBd"}
@@ -1,44 +1,5 @@
1
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { getFocusables as getActualFocusables } from '../../internal/components/focus-lock/utils';
4
- // For the grid to have a single Tab stop all interactive element indices are updated to be -999.
5
- // The elements having tab index -999 are eligible for keyboard navigation but not for Tab navigation.
6
- const PSEUDO_FOCUSABLE_TAB_INDEX = -999;
7
- const FOCUSABLES_SELECTOR = `[tabIndex="0"],[tabIndex="${PSEUDO_FOCUSABLE_TAB_INDEX}"]`;
8
- /**
9
- * Makes all element focusable children pseudo-focusable unless the grid navigation is suppressed.
10
- */
11
- export function muteElementFocusables(element, suppressed) {
12
- // When grid navigation is suppressed all interactive elements and all cells focus is unmuted to unblock Tab navigation.
13
- // Leaving the interactive widget using Tab navigation moves the focus to the current or adjacent cell and un-suppresses
14
- // the navigation when implemented correctly.
15
- if (suppressed) {
16
- for (const focusable of getFocusables(element)) {
17
- setTabIndex(focusable, 0);
18
- }
19
- return;
20
- }
21
- // Assigning pseudo-focusable tab index to all cells and all interactive elements makes them focusable with grid navigation.
22
- for (const focusable of getActualFocusables(element)) {
23
- if (focusable !== document.activeElement) {
24
- setTabIndex(focusable, PSEUDO_FOCUSABLE_TAB_INDEX);
25
- }
26
- }
27
- }
28
- /**
29
- * This cleanup code ensures all cells are no longer focusable but the interactive elements are.
30
- * Currently there are no use cases for it as we don't expect the navigation to be used conditionally.
31
- */
32
- export function restoreElementFocusables(element) {
33
- for (const focusable of getFocusables(element)) {
34
- if (focusable instanceof HTMLTableCellElement) {
35
- setTabIndex(focusable, -1);
36
- }
37
- else {
38
- setTabIndex(focusable, 0);
39
- }
40
- }
41
- }
42
3
  /**
43
4
  * Returns true if the target element or one of its parents is a dialog or is marked with data-awsui-table-suppress-navigation attribute.
44
5
  * This is used to suppress navigation for interactive content without a need to use a custom suppression check.
@@ -59,15 +20,6 @@ export function defaultIsSuppressed(target) {
59
20
  }
60
21
  return false;
61
22
  }
62
- /**
63
- * Returns actually focusable or pseudo-focusable elements to find navigation targets.
64
- */
65
- export function getFocusables(element) {
66
- return Array.from(element.querySelectorAll(FOCUSABLES_SELECTOR));
67
- }
68
- export function getFirstFocusable(element) {
69
- return element.querySelector(FOCUSABLES_SELECTOR);
70
- }
71
23
  /**
72
24
  * Finds the closest row to the targetAriaRowIndex+delta in the direction of delta.
73
25
  */
@@ -118,9 +70,4 @@ export function findTableRowCellByAriaColIndex(tableRow, targetAriaColIndex, del
118
70
  }
119
71
  return targetCell;
120
72
  }
121
- export function setTabIndex(element, tabIndex) {
122
- if (element && element.tabIndex !== tabIndex) {
123
- element.tabIndex = tabIndex;
124
- }
125
- }
126
73
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"lib/default/","sources":["table/table-role/utils.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 { getFocusables as getActualFocusables } from '../../internal/components/focus-lock/utils';\n\n// For the grid to have a single Tab stop all interactive element indices are updated to be -999.\n// The elements having tab index -999 are eligible for keyboard navigation but not for Tab navigation.\nconst PSEUDO_FOCUSABLE_TAB_INDEX = -999;\nconst FOCUSABLES_SELECTOR = `[tabIndex=\"0\"],[tabIndex=\"${PSEUDO_FOCUSABLE_TAB_INDEX}\"]`;\n\n/**\n * Makes all element focusable children pseudo-focusable unless the grid navigation is suppressed.\n */\nexport function muteElementFocusables(element: HTMLElement, suppressed: boolean) {\n // When grid navigation is suppressed all interactive elements and all cells focus is unmuted to unblock Tab navigation.\n // Leaving the interactive widget using Tab navigation moves the focus to the current or adjacent cell and un-suppresses\n // the navigation when implemented correctly.\n if (suppressed) {\n for (const focusable of getFocusables(element)) {\n setTabIndex(focusable, 0);\n }\n return;\n }\n\n // Assigning pseudo-focusable tab index to all cells and all interactive elements makes them focusable with grid navigation.\n for (const focusable of getActualFocusables(element)) {\n if (focusable !== document.activeElement) {\n setTabIndex(focusable, PSEUDO_FOCUSABLE_TAB_INDEX);\n }\n }\n}\n\n/**\n * This cleanup code ensures all cells are no longer focusable but the interactive elements are.\n * Currently there are no use cases for it as we don't expect the navigation to be used conditionally.\n */\nexport function restoreElementFocusables(element: HTMLTableElement) {\n for (const focusable of getFocusables(element)) {\n if (focusable instanceof HTMLTableCellElement) {\n setTabIndex(focusable, -1);\n } else {\n setTabIndex(focusable, 0);\n }\n }\n}\n\n/**\n * Returns true if the target element or one of its parents is a dialog or is marked with data-awsui-table-suppress-navigation attribute.\n * This is used to suppress navigation for interactive content without a need to use a custom suppression check.\n */\nexport function defaultIsSuppressed(target: HTMLElement) {\n let current: null | HTMLElement = target;\n while (current) {\n // Stop checking for parents upon reaching the cell element as the function only aims at the cell content.\n const tagName = current.tagName.toLowerCase();\n if (tagName === 'td' || tagName === 'th') {\n return false;\n }\n if (\n current.getAttribute('role') === 'dialog' ||\n current.getAttribute('data-awsui-table-suppress-navigation') === 'true'\n ) {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n}\n\n/**\n * Returns actually focusable or pseudo-focusable elements to find navigation targets.\n */\nexport function getFocusables(element: HTMLElement) {\n return Array.from(element.querySelectorAll(FOCUSABLES_SELECTOR)) as HTMLElement[];\n}\n\nexport function getFirstFocusable(element: HTMLElement) {\n return element.querySelector(FOCUSABLES_SELECTOR) as null | HTMLElement;\n}\n\n/**\n * Finds the closest row to the targetAriaRowIndex+delta in the direction of delta.\n */\nexport function findTableRowByAriaRowIndex(table: HTMLTableElement, targetAriaRowIndex: number, delta: number) {\n let targetRow: null | HTMLTableRowElement = null;\n const rowElements = Array.from(table.querySelectorAll('tr[aria-rowindex]'));\n if (delta < 0) {\n rowElements.reverse();\n }\n for (const element of rowElements) {\n const rowIndex = parseInt(element.getAttribute('aria-rowindex') ?? '');\n targetRow = element as HTMLTableRowElement;\n\n if (rowIndex === targetAriaRowIndex) {\n break;\n }\n if (delta >= 0 && rowIndex > targetAriaRowIndex) {\n break;\n }\n if (delta < 0 && rowIndex < targetAriaRowIndex) {\n break;\n }\n }\n return targetRow;\n}\n\n/**\n * Finds the closest column to the targetAriaColIndex+delta in the direction of delta.\n */\nexport function findTableRowCellByAriaColIndex(\n tableRow: HTMLTableRowElement,\n targetAriaColIndex: number,\n delta: number\n) {\n let targetCell: null | HTMLTableCellElement = null;\n const cellElements = Array.from(tableRow.querySelectorAll('td[aria-colindex],th[aria-colindex]'));\n if (delta < 0) {\n cellElements.reverse();\n }\n for (const element of cellElements) {\n const columnIndex = parseInt(element.getAttribute('aria-colindex') ?? '');\n targetCell = element as HTMLTableCellElement;\n\n if (columnIndex === targetAriaColIndex) {\n break;\n }\n if (delta >= 0 && columnIndex > targetAriaColIndex) {\n break;\n }\n if (delta < 0 && columnIndex < targetAriaColIndex) {\n break;\n }\n }\n return targetCell;\n}\n\nexport function setTabIndex(element: null | HTMLElement, tabIndex: number) {\n if (element && element.tabIndex !== tabIndex) {\n element.tabIndex = tabIndex;\n }\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"lib/default/","sources":["table/table-role/utils.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,OAAO,GAAmB,MAAM,CAAC;IACrC,OAAO,OAAO,EAAE;QACd,0GAA0G;QAC1G,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,EAAE;YACxC,OAAO,KAAK,CAAC;SACd;QACD,IACE,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,QAAQ;YACzC,OAAO,CAAC,YAAY,CAAC,sCAAsC,CAAC,KAAK,MAAM,EACvE;YACA,OAAO,IAAI,CAAC;SACb;QACD,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;KACjC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAuB,EAAE,kBAA0B,EAAE,KAAa;;IAC3G,IAAI,SAAS,GAA+B,IAAI,CAAC;IACjD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC5E,IAAI,KAAK,GAAG,CAAC,EAAE;QACb,WAAW,CAAC,OAAO,EAAE,CAAC;KACvB;IACD,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE;QACjC,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,mCAAI,EAAE,CAAC,CAAC;QACvE,SAAS,GAAG,OAA8B,CAAC;QAE3C,IAAI,QAAQ,KAAK,kBAAkB,EAAE;YACnC,MAAM;SACP;QACD,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ,GAAG,kBAAkB,EAAE;YAC/C,MAAM;SACP;QACD,IAAI,KAAK,GAAG,CAAC,IAAI,QAAQ,GAAG,kBAAkB,EAAE;YAC9C,MAAM;SACP;KACF;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAC5C,QAA6B,EAC7B,kBAA0B,EAC1B,KAAa;;IAEb,IAAI,UAAU,GAAgC,IAAI,CAAC;IACnD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,qCAAqC,CAAC,CAAC,CAAC;IAClG,IAAI,KAAK,GAAG,CAAC,EAAE;QACb,YAAY,CAAC,OAAO,EAAE,CAAC;KACxB;IACD,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE;QAClC,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,mCAAI,EAAE,CAAC,CAAC;QAC1E,UAAU,GAAG,OAA+B,CAAC;QAE7C,IAAI,WAAW,KAAK,kBAAkB,EAAE;YACtC,MAAM;SACP;QACD,IAAI,KAAK,IAAI,CAAC,IAAI,WAAW,GAAG,kBAAkB,EAAE;YAClD,MAAM;SACP;QACD,IAAI,KAAK,GAAG,CAAC,IAAI,WAAW,GAAG,kBAAkB,EAAE;YACjD,MAAM;SACP;KACF;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Returns true if the target element or one of its parents is a dialog or is marked with data-awsui-table-suppress-navigation attribute.\n * This is used to suppress navigation for interactive content without a need to use a custom suppression check.\n */\nexport function defaultIsSuppressed(target: Element) {\n let current: null | Element = target;\n while (current) {\n // Stop checking for parents upon reaching the cell element as the function only aims at the cell content.\n const tagName = current.tagName.toLowerCase();\n if (tagName === 'td' || tagName === 'th') {\n return false;\n }\n if (\n current.getAttribute('role') === 'dialog' ||\n current.getAttribute('data-awsui-table-suppress-navigation') === 'true'\n ) {\n return true;\n }\n current = current.parentElement;\n }\n return false;\n}\n\n/**\n * Finds the closest row to the targetAriaRowIndex+delta in the direction of delta.\n */\nexport function findTableRowByAriaRowIndex(table: HTMLTableElement, targetAriaRowIndex: number, delta: number) {\n let targetRow: null | HTMLTableRowElement = null;\n const rowElements = Array.from(table.querySelectorAll('tr[aria-rowindex]'));\n if (delta < 0) {\n rowElements.reverse();\n }\n for (const element of rowElements) {\n const rowIndex = parseInt(element.getAttribute('aria-rowindex') ?? '');\n targetRow = element as HTMLTableRowElement;\n\n if (rowIndex === targetAriaRowIndex) {\n break;\n }\n if (delta >= 0 && rowIndex > targetAriaRowIndex) {\n break;\n }\n if (delta < 0 && rowIndex < targetAriaRowIndex) {\n break;\n }\n }\n return targetRow;\n}\n\n/**\n * Finds the closest column to the targetAriaColIndex+delta in the direction of delta.\n */\nexport function findTableRowCellByAriaColIndex(\n tableRow: HTMLTableRowElement,\n targetAriaColIndex: number,\n delta: number\n) {\n let targetCell: null | HTMLTableCellElement = null;\n const cellElements = Array.from(tableRow.querySelectorAll('td[aria-colindex],th[aria-colindex]'));\n if (delta < 0) {\n cellElements.reverse();\n }\n for (const element of cellElements) {\n const columnIndex = parseInt(element.getAttribute('aria-colindex') ?? '');\n targetCell = element as HTMLTableCellElement;\n\n if (columnIndex === targetAriaColIndex) {\n break;\n }\n if (delta >= 0 && columnIndex > targetAriaColIndex) {\n break;\n }\n if (delta < 0 && columnIndex < targetAriaColIndex) {\n break;\n }\n }\n return targetCell;\n}\n"]}