@cloudscape-design/components-themeable 3.0.1106 → 3.0.1108

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 (49) hide show
  1. package/lib/internal/manifest.json +1 -1
  2. package/lib/internal/scss/internal/components/expand-toggle-button/styles.scss +6 -2
  3. package/lib/internal/scss/internal/generated/custom-css-properties/index.scss +1 -1
  4. package/lib/internal/scss/internal/styles/utils/styles-reset.scss +1 -0
  5. package/lib/internal/scss/tree-view/tree-item/styles.scss +38 -21
  6. package/lib/internal/template/internal/base-component/styles.scoped.css +1 -1
  7. package/lib/internal/template/internal/components/expand-toggle-button/index.d.ts +3 -1
  8. package/lib/internal/template/internal/components/expand-toggle-button/index.d.ts.map +1 -1
  9. package/lib/internal/template/internal/components/expand-toggle-button/index.js +2 -2
  10. package/lib/internal/template/internal/components/expand-toggle-button/index.js.map +1 -1
  11. package/lib/internal/template/internal/components/expand-toggle-button/styles.css.js +4 -3
  12. package/lib/internal/template/internal/components/expand-toggle-button/styles.scoped.css +13 -13
  13. package/lib/internal/template/internal/components/expand-toggle-button/styles.selectors.js +4 -3
  14. package/lib/internal/template/internal/components/structured-item/index.d.ts +3 -1
  15. package/lib/internal/template/internal/components/structured-item/index.d.ts.map +1 -1
  16. package/lib/internal/template/internal/components/structured-item/index.js +2 -2
  17. package/lib/internal/template/internal/components/structured-item/index.js.map +1 -1
  18. package/lib/internal/template/internal/environment.js +2 -2
  19. package/lib/internal/template/internal/environment.json +2 -2
  20. package/lib/internal/template/tree-view/internal.d.ts.map +1 -1
  21. package/lib/internal/template/tree-view/internal.js +10 -4
  22. package/lib/internal/template/tree-view/internal.js.map +1 -1
  23. package/lib/internal/template/tree-view/keyboard-navigation/index.d.ts +31 -0
  24. package/lib/internal/template/tree-view/keyboard-navigation/index.d.ts.map +1 -0
  25. package/lib/internal/template/tree-view/keyboard-navigation/index.js +224 -0
  26. package/lib/internal/template/tree-view/keyboard-navigation/index.js.map +1 -0
  27. package/lib/internal/template/tree-view/keyboard-navigation/utils.d.ts +7 -0
  28. package/lib/internal/template/tree-view/keyboard-navigation/utils.d.ts.map +1 -0
  29. package/lib/internal/template/tree-view/keyboard-navigation/utils.js +40 -0
  30. package/lib/internal/template/tree-view/keyboard-navigation/utils.js.map +1 -0
  31. package/lib/internal/template/tree-view/styles.css.js +2 -2
  32. package/lib/internal/template/tree-view/styles.scoped.css +3 -2
  33. package/lib/internal/template/tree-view/styles.selectors.js +2 -2
  34. package/lib/internal/template/tree-view/tree-item/focus-target.d.ts +5 -0
  35. package/lib/internal/template/tree-view/tree-item/focus-target.d.ts.map +1 -0
  36. package/lib/internal/template/tree-view/tree-item/focus-target.js +11 -0
  37. package/lib/internal/template/tree-view/tree-item/focus-target.js.map +1 -0
  38. package/lib/internal/template/tree-view/tree-item/index.d.ts +4 -1
  39. package/lib/internal/template/tree-view/tree-item/index.d.ts.map +1 -1
  40. package/lib/internal/template/tree-view/tree-item/index.js +11 -9
  41. package/lib/internal/template/tree-view/tree-item/index.js.map +1 -1
  42. package/lib/internal/template/tree-view/tree-item/styles.css.js +9 -5
  43. package/lib/internal/template/tree-view/tree-item/styles.scoped.css +46 -11
  44. package/lib/internal/template/tree-view/tree-item/styles.selectors.js +9 -5
  45. package/lib/internal/template/tree-view/utils.d.ts +11 -0
  46. package/lib/internal/template/tree-view/utils.d.ts.map +1 -0
  47. package/lib/internal/template/tree-view/utils.js +20 -0
  48. package/lib/internal/template/tree-view/utils.js.map +1 -0
  49. package/package.json +1 -1
@@ -0,0 +1,224 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import React, { useRef } from 'react';
4
+ import { useEffect, useMemo } from 'react';
5
+ import { useStableCallback } from '@cloudscape-design/component-toolkit/internal';
6
+ import { SingleTabStopNavigationProvider, } from '@cloudscape-design/component-toolkit/internal';
7
+ import { getAllFocusables } from '../../internal/components/focus-lock/utils';
8
+ import { KeyCode } from '../../internal/keycode';
9
+ import handleKey, { isEventLike } from '../../internal/utils/handle-key';
10
+ import { nodeBelongs } from '../../internal/utils/node-belongs';
11
+ import { findTreeItemByIndex, findTreeItemContentById, getClosestTreeItem, getToggleButtonOfTreeItem, isElementDisabled, isTreeItemToggle, } from './utils';
12
+ import treeItemStyles from '../tree-item/styles.css.js';
13
+ export function KeyboardNavigationProvider({ getTreeView, children, }) {
14
+ const navigationAPI = useRef(null);
15
+ const keyboardNavigation = useMemo(() => new KeyboardNavigationProcessor(navigationAPI), []);
16
+ const getTreeViewStable = useStableCallback(getTreeView);
17
+ // Initialize the processor with the treeView container assuming it is mounted synchronously and only once.
18
+ useEffect(() => {
19
+ const treeView = getTreeViewStable();
20
+ if (treeView) {
21
+ keyboardNavigation.init(treeView);
22
+ return keyboardNavigation.cleanup;
23
+ }
24
+ }, [keyboardNavigation, getTreeViewStable]);
25
+ // Notify the processor of the new render.
26
+ useEffect(() => {
27
+ keyboardNavigation.refresh();
28
+ });
29
+ return (React.createElement(SingleTabStopNavigationProvider, { ref: navigationAPI, getNextFocusTarget: keyboardNavigation.getNextFocusTarget, onUnregisterActive: keyboardNavigation.onUnregisterActive, navigationActive: true }, children));
30
+ }
31
+ export class KeyboardNavigationProcessor {
32
+ constructor(navigationAPI) {
33
+ // Props
34
+ this._treeView = null;
35
+ // State
36
+ this.focusedTreeItem = null;
37
+ this.cleanup = () => {
38
+ // Do nothing before initialized.
39
+ };
40
+ this.onUnregisterActive = () => {
41
+ // If the focused tree-item or tree-item focusable appears to be no longer attached to the tree-view we need to re-apply
42
+ // focus to a tree-item focusable with the same position or to the tree-item toggle.
43
+ // istanbul ignore next - tested via integration tests
44
+ if (this.treeView && this.focusedTreeItem && !nodeBelongs(this.treeView, this.focusedTreeItem.element)) {
45
+ const nextFocusableElement = this.getNextFocusableTreeItemContent(this.treeView, this.focusedTreeItem, 0);
46
+ if (nextFocusableElement) {
47
+ nextFocusableElement === null || nextFocusableElement === void 0 ? void 0 : nextFocusableElement.focus();
48
+ }
49
+ else {
50
+ this.moveFocusBetweenTreeItems(this.treeView, this.focusedTreeItem, 0);
51
+ }
52
+ }
53
+ };
54
+ this.getNextFocusTarget = () => {
55
+ if (!this.treeView) {
56
+ return null;
57
+ }
58
+ const treeItem = this.focusedTreeItem;
59
+ const firstTreeItemToggle = this.treeView.querySelector(`.${treeItemStyles['tree-item-focus-target']}`);
60
+ let focusTarget = firstTreeItemToggle;
61
+ // Focus on the element that was focused before.
62
+ if (treeItem) {
63
+ focusTarget = this.getNextFocusableTreeItem(this.treeView, treeItem, 0);
64
+ }
65
+ return focusTarget;
66
+ };
67
+ this.onFocusin = (treeView, event) => {
68
+ var _a;
69
+ if (!(event.target instanceof HTMLElement)) {
70
+ return;
71
+ }
72
+ this.updateFocusedTreeItem(treeView, event.target);
73
+ if (!this.focusedTreeItem) {
74
+ return;
75
+ }
76
+ (_a = this._navigationAPI.current) === null || _a === void 0 ? void 0 : _a.updateFocusTarget();
77
+ };
78
+ this.onKeydown = (treeView, event) => {
79
+ const keys = [
80
+ KeyCode.up,
81
+ KeyCode.down,
82
+ KeyCode.left,
83
+ KeyCode.right,
84
+ KeyCode.pageUp,
85
+ KeyCode.pageDown,
86
+ KeyCode.home,
87
+ KeyCode.end,
88
+ ];
89
+ if (!this.focusedTreeItem || !this.isRegistered(document.activeElement) || keys.indexOf(event.keyCode) === -1) {
90
+ return;
91
+ }
92
+ const from = this.focusedTreeItem;
93
+ if (isEventLike(event)) {
94
+ handleKey(event, {
95
+ onBlockStart: () => this.moveFocusBetweenTreeItems(treeView, from, -1, event),
96
+ onBlockEnd: () => this.moveFocusBetweenTreeItems(treeView, from, 1, event),
97
+ onInlineEnd: () => {
98
+ // If focus is on the toggle, move focus to the first element inside the tree-item
99
+ if (isTreeItemToggle(from.element)) {
100
+ return this.moveFocusInsideTreeItem(treeView, from, 0, event);
101
+ }
102
+ return this.moveFocusInsideTreeItem(treeView, from, 1, event);
103
+ },
104
+ onInlineStart: () => {
105
+ // If focus is on the toggle, move focus to the last element inside the tree-item
106
+ if (isTreeItemToggle(from.element)) {
107
+ return this.moveFocusToTheLastElementInsideTreeItem(treeView, from, event);
108
+ }
109
+ return this.moveFocusInsideTreeItem(treeView, from, -1, event);
110
+ },
111
+ onPageUp: () => this.moveFocusBetweenTreeItems(treeView, from, -10, event),
112
+ onPageDown: () => this.moveFocusBetweenTreeItems(treeView, from, 10, event),
113
+ onHome: () => this.moveFocusBetweenTreeItems(treeView, from, -Infinity, event),
114
+ onEnd: () => this.moveFocusBetweenTreeItems(treeView, from, Infinity, event),
115
+ });
116
+ }
117
+ };
118
+ this._navigationAPI = navigationAPI;
119
+ }
120
+ init(treeView) {
121
+ this._treeView = treeView;
122
+ const controller = new AbortController();
123
+ treeView.addEventListener('focusin', event => this.onFocusin(treeView, event), { signal: controller.signal });
124
+ treeView.addEventListener('keydown', event => this.onKeydown(treeView, event), { signal: controller.signal });
125
+ this.cleanup = () => {
126
+ controller.abort();
127
+ };
128
+ }
129
+ refresh() {
130
+ // Timeout ensures the newly rendered content elements are registered.
131
+ setTimeout(() => {
132
+ var _a, _b;
133
+ if (this.treeView) {
134
+ // Update focused tree-item in case tree-items change.
135
+ this.updateFocusedTreeItem(this.treeView, (_a = this.focusedTreeItem) === null || _a === void 0 ? void 0 : _a.element);
136
+ (_b = this._navigationAPI.current) === null || _b === void 0 ? void 0 : _b.updateFocusTarget();
137
+ }
138
+ }, 0);
139
+ }
140
+ get treeView() {
141
+ return this._treeView;
142
+ }
143
+ getFocusablesFrom(target) {
144
+ const isElementRegistered = (element) => { var _a; return (_a = this._navigationAPI.current) === null || _a === void 0 ? void 0 : _a.isRegistered(element); };
145
+ return getAllFocusables(target).filter(el => isElementRegistered(el) && !isElementDisabled(el));
146
+ }
147
+ isRegistered(element) {
148
+ var _a, _b;
149
+ return !element || ((_b = (_a = this._navigationAPI.current) === null || _a === void 0 ? void 0 : _a.isRegistered(element)) !== null && _b !== void 0 ? _b : false);
150
+ }
151
+ updateFocusedTreeItem(treeView, focusedElement) {
152
+ var _a;
153
+ if (!focusedElement) {
154
+ return;
155
+ }
156
+ const treeItem = getClosestTreeItem(focusedElement);
157
+ if (!treeItem) {
158
+ return;
159
+ }
160
+ const treeItemContent = findTreeItemContentById(treeView, treeItem.id);
161
+ this.focusedTreeItem = {
162
+ treeItemId: treeItem.id,
163
+ treeItemIndex: parseInt((_a = treeItem.getAttribute('data-awsui-tree-item-index')) !== null && _a !== void 0 ? _a : ''),
164
+ element: focusedElement,
165
+ elementIndex: treeItemContent ? this.getFocusablesFrom(treeItemContent).indexOf(focusedElement) : 0,
166
+ };
167
+ }
168
+ getNextFocusableTreeItem(treeView, from, by) {
169
+ const targetTreeItemIndex = from.treeItemIndex + by;
170
+ const targetTreeItem = findTreeItemByIndex(treeView, targetTreeItemIndex, by);
171
+ // Return the toggle of the tree-item
172
+ return getToggleButtonOfTreeItem(targetTreeItem);
173
+ }
174
+ moveFocusInsideTreeItem(treeView, from, by, event) {
175
+ const nextFocusableElement = this.getNextFocusableTreeItemContent(treeView, from, by);
176
+ if (nextFocusableElement) {
177
+ // Prevent default only if there are focusables inside
178
+ event === null || event === void 0 ? void 0 : event.preventDefault();
179
+ nextFocusableElement === null || nextFocusableElement === void 0 ? void 0 : nextFocusableElement.focus();
180
+ }
181
+ }
182
+ moveFocusBetweenTreeItems(treeView, from, by, event) {
183
+ event === null || event === void 0 ? void 0 : event.preventDefault();
184
+ const isToggleFocused = isTreeItemToggle(from.element);
185
+ // If toggle is not focused (focus is inside the tree-item),
186
+ // pressing up or down arrow keys should move focus to the toggle
187
+ const nextFocusableTreeItem = this.getNextFocusableTreeItem(treeView, from, isToggleFocused ? by : 0);
188
+ nextFocusableTreeItem === null || nextFocusableTreeItem === void 0 ? void 0 : nextFocusableTreeItem.focus();
189
+ }
190
+ moveFocusToTheLastElementInsideTreeItem(treeView, from, event) {
191
+ const treeItem = findTreeItemContentById(treeView, from.treeItemId);
192
+ if (!treeItem) {
193
+ return null;
194
+ }
195
+ const treeItemFocusables = this.getFocusablesFrom(treeItem);
196
+ const focusableElement = treeItemFocusables[treeItemFocusables.length - 1];
197
+ if (focusableElement) {
198
+ // Prevent default only if there are focusables inside
199
+ event === null || event === void 0 ? void 0 : event.preventDefault();
200
+ focusableElement === null || focusableElement === void 0 ? void 0 : focusableElement.focus();
201
+ }
202
+ }
203
+ getNextFocusableTreeItemContent(treeView, from, by) {
204
+ const treeItem = findTreeItemContentById(treeView, from.treeItemId);
205
+ if (!treeItem) {
206
+ return null;
207
+ }
208
+ const treeItemFocusables = this.getFocusablesFrom(treeItem);
209
+ const targetElementIndex = isTreeItemToggle(from.element) ? by : from.elementIndex + by;
210
+ // Move focus to the tree-item toggle if
211
+ // left arrow key is pressed while focused on the first element inside the tree-item, or
212
+ // right arrow key is pressed while focused on the last element inside the tree-item
213
+ const isTargetToggle = (from.elementIndex === 0 && by < 0) || (targetElementIndex === treeItemFocusables.length && by > 0);
214
+ if (isTargetToggle) {
215
+ return this.getNextFocusableTreeItem(treeView, from, 0);
216
+ }
217
+ const isValidIndex = targetElementIndex < treeItemFocusables.length;
218
+ if (isValidIndex) {
219
+ return treeItemFocusables[targetElementIndex];
220
+ }
221
+ return null;
222
+ }
223
+ }
224
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tree-view/keyboard-navigation/index.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\nimport React, { useRef } from 'react';\nimport { useEffect, useMemo } from 'react';\n\nimport { useStableCallback } from '@cloudscape-design/component-toolkit/internal';\nimport {\n SingleTabStopNavigationAPI,\n SingleTabStopNavigationProvider,\n} from '@cloudscape-design/component-toolkit/internal';\n\nimport { getAllFocusables } from '../../internal/components/focus-lock/utils';\nimport { KeyCode } from '../../internal/keycode';\nimport handleKey, { isEventLike } from '../../internal/utils/handle-key';\nimport { nodeBelongs } from '../../internal/utils/node-belongs';\nimport {\n findTreeItemByIndex,\n findTreeItemContentById,\n getClosestTreeItem,\n getToggleButtonOfTreeItem,\n isElementDisabled,\n isTreeItemToggle,\n} from './utils';\n\nimport treeItemStyles from '../tree-item/styles.css.js';\n\nexport function KeyboardNavigationProvider({\n getTreeView,\n children,\n}: {\n getTreeView: () => null | HTMLUListElement;\n children: React.ReactNode;\n}) {\n const navigationAPI = useRef<SingleTabStopNavigationAPI>(null);\n\n const keyboardNavigation = useMemo(() => new KeyboardNavigationProcessor(navigationAPI), []);\n\n const getTreeViewStable = useStableCallback(getTreeView);\n\n // Initialize the processor with the treeView container assuming it is mounted synchronously and only once.\n useEffect(() => {\n const treeView = getTreeViewStable();\n if (treeView) {\n keyboardNavigation.init(treeView);\n return keyboardNavigation.cleanup;\n }\n }, [keyboardNavigation, getTreeViewStable]);\n\n // Notify the processor of the new render.\n useEffect(() => {\n keyboardNavigation.refresh();\n });\n\n return (\n <SingleTabStopNavigationProvider\n ref={navigationAPI}\n getNextFocusTarget={keyboardNavigation.getNextFocusTarget}\n onUnregisterActive={keyboardNavigation.onUnregisterActive}\n navigationActive={true}\n >\n {children}\n </SingleTabStopNavigationProvider>\n );\n}\n\ninterface FocusedTreeItem {\n treeItemId: string;\n treeItemIndex: number;\n element: HTMLElement;\n elementIndex: number;\n}\n\nexport class KeyboardNavigationProcessor {\n // Props\n private _treeView: null | HTMLUListElement = null;\n private _navigationAPI: { current: null | SingleTabStopNavigationAPI };\n\n // State\n private focusedTreeItem: null | FocusedTreeItem = null;\n\n constructor(navigationAPI: { current: null | SingleTabStopNavigationAPI }) {\n this._navigationAPI = navigationAPI;\n }\n\n public init(treeView: HTMLUListElement) {\n this._treeView = treeView;\n const controller = new AbortController();\n\n treeView.addEventListener('focusin', event => this.onFocusin(treeView, event), { signal: controller.signal });\n treeView.addEventListener('keydown', event => this.onKeydown(treeView, event), { signal: controller.signal });\n\n this.cleanup = () => {\n controller.abort();\n };\n }\n\n public cleanup = () => {\n // Do nothing before initialized.\n };\n\n public refresh() {\n // Timeout ensures the newly rendered content elements are registered.\n setTimeout(() => {\n if (this.treeView) {\n // Update focused tree-item in case tree-items change.\n this.updateFocusedTreeItem(this.treeView, this.focusedTreeItem?.element);\n this._navigationAPI.current?.updateFocusTarget();\n }\n }, 0);\n }\n\n public onUnregisterActive = () => {\n // If the focused tree-item or tree-item focusable appears to be no longer attached to the tree-view we need to re-apply\n // focus to a tree-item focusable with the same position or to the tree-item toggle.\n // istanbul ignore next - tested via integration tests\n if (this.treeView && this.focusedTreeItem && !nodeBelongs(this.treeView, this.focusedTreeItem.element)) {\n const nextFocusableElement = this.getNextFocusableTreeItemContent(this.treeView, this.focusedTreeItem, 0);\n if (nextFocusableElement) {\n nextFocusableElement?.focus();\n } else {\n this.moveFocusBetweenTreeItems(this.treeView, this.focusedTreeItem, 0);\n }\n }\n };\n\n public getNextFocusTarget = () => {\n if (!this.treeView) {\n return null;\n }\n\n const treeItem = this.focusedTreeItem;\n const firstTreeItemToggle = this.treeView.querySelector(\n `.${treeItemStyles['tree-item-focus-target']}`\n ) as null | HTMLButtonElement;\n\n let focusTarget: null | HTMLElement = firstTreeItemToggle;\n\n // Focus on the element that was focused before.\n if (treeItem) {\n focusTarget = this.getNextFocusableTreeItem(this.treeView, treeItem, 0);\n }\n\n return focusTarget;\n };\n\n private get treeView(): null | HTMLUListElement {\n return this._treeView;\n }\n\n private getFocusablesFrom(target: HTMLElement) {\n const isElementRegistered = (element: Element) => this._navigationAPI.current?.isRegistered(element);\n return getAllFocusables(target).filter(el => isElementRegistered(el) && !isElementDisabled(el));\n }\n\n private isRegistered(element: null | Element): boolean {\n return !element || (this._navigationAPI.current?.isRegistered(element) ?? false);\n }\n\n private updateFocusedTreeItem(treeView: HTMLUListElement, focusedElement?: HTMLElement): void {\n if (!focusedElement) {\n return;\n }\n\n const treeItem = getClosestTreeItem(focusedElement);\n if (!treeItem) {\n return;\n }\n\n const treeItemContent = findTreeItemContentById(treeView, treeItem.id);\n\n this.focusedTreeItem = {\n treeItemId: treeItem.id,\n treeItemIndex: parseInt(treeItem.getAttribute('data-awsui-tree-item-index') ?? ''),\n element: focusedElement,\n elementIndex: treeItemContent ? this.getFocusablesFrom(treeItemContent).indexOf(focusedElement) : 0,\n };\n }\n\n private onFocusin = (treeView: HTMLUListElement, event: FocusEvent) => {\n if (!(event.target instanceof HTMLElement)) {\n return;\n }\n\n this.updateFocusedTreeItem(treeView, event.target);\n if (!this.focusedTreeItem) {\n return;\n }\n\n this._navigationAPI.current?.updateFocusTarget();\n };\n\n private onKeydown = (treeView: HTMLUListElement, event: KeyboardEvent) => {\n const keys = [\n KeyCode.up,\n KeyCode.down,\n KeyCode.left,\n KeyCode.right,\n KeyCode.pageUp,\n KeyCode.pageDown,\n KeyCode.home,\n KeyCode.end,\n ];\n\n if (!this.focusedTreeItem || !this.isRegistered(document.activeElement) || keys.indexOf(event.keyCode) === -1) {\n return;\n }\n\n const from = this.focusedTreeItem;\n\n if (isEventLike(event)) {\n handleKey(event, {\n onBlockStart: () => this.moveFocusBetweenTreeItems(treeView, from, -1, event),\n onBlockEnd: () => this.moveFocusBetweenTreeItems(treeView, from, 1, event),\n onInlineEnd: () => {\n // If focus is on the toggle, move focus to the first element inside the tree-item\n if (isTreeItemToggle(from.element)) {\n return this.moveFocusInsideTreeItem(treeView, from, 0, event);\n }\n return this.moveFocusInsideTreeItem(treeView, from, 1, event);\n },\n onInlineStart: () => {\n // If focus is on the toggle, move focus to the last element inside the tree-item\n if (isTreeItemToggle(from.element)) {\n return this.moveFocusToTheLastElementInsideTreeItem(treeView, from, event);\n }\n return this.moveFocusInsideTreeItem(treeView, from, -1, event);\n },\n onPageUp: () => this.moveFocusBetweenTreeItems(treeView, from, -10, event),\n onPageDown: () => this.moveFocusBetweenTreeItems(treeView, from, 10, event),\n onHome: () => this.moveFocusBetweenTreeItems(treeView, from, -Infinity, event),\n onEnd: () => this.moveFocusBetweenTreeItems(treeView, from, Infinity, event),\n });\n }\n };\n\n private getNextFocusableTreeItem(treeView: HTMLUListElement, from: FocusedTreeItem, by: number) {\n const targetTreeItemIndex = from.treeItemIndex + by;\n const targetTreeItem = findTreeItemByIndex(treeView, targetTreeItemIndex, by);\n\n // Return the toggle of the tree-item\n return getToggleButtonOfTreeItem(targetTreeItem);\n }\n\n private moveFocusInsideTreeItem(treeView: HTMLUListElement, from: FocusedTreeItem, by: number, event?: Event) {\n const nextFocusableElement = this.getNextFocusableTreeItemContent(treeView, from, by);\n\n if (nextFocusableElement) {\n // Prevent default only if there are focusables inside\n event?.preventDefault();\n nextFocusableElement?.focus();\n }\n }\n\n private moveFocusBetweenTreeItems(treeView: HTMLUListElement, from: FocusedTreeItem, by: number, event?: Event) {\n event?.preventDefault();\n const isToggleFocused = isTreeItemToggle(from.element);\n\n // If toggle is not focused (focus is inside the tree-item),\n // pressing up or down arrow keys should move focus to the toggle\n const nextFocusableTreeItem = this.getNextFocusableTreeItem(treeView, from, isToggleFocused ? by : 0);\n nextFocusableTreeItem?.focus();\n }\n\n private moveFocusToTheLastElementInsideTreeItem(treeView: HTMLUListElement, from: FocusedTreeItem, event?: Event) {\n const treeItem = findTreeItemContentById(treeView, from.treeItemId);\n if (!treeItem) {\n return null;\n }\n\n const treeItemFocusables = this.getFocusablesFrom(treeItem);\n\n const focusableElement = treeItemFocusables[treeItemFocusables.length - 1];\n\n if (focusableElement) {\n // Prevent default only if there are focusables inside\n event?.preventDefault();\n focusableElement?.focus();\n }\n }\n\n private getNextFocusableTreeItemContent(treeView: HTMLUListElement, from: FocusedTreeItem, by: number) {\n const treeItem = findTreeItemContentById(treeView, from.treeItemId);\n if (!treeItem) {\n return null;\n }\n\n const treeItemFocusables = this.getFocusablesFrom(treeItem);\n\n const targetElementIndex = isTreeItemToggle(from.element) ? by : from.elementIndex + by;\n\n // Move focus to the tree-item toggle if\n // left arrow key is pressed while focused on the first element inside the tree-item, or\n // right arrow key is pressed while focused on the last element inside the tree-item\n const isTargetToggle =\n (from.elementIndex === 0 && by < 0) || (targetElementIndex === treeItemFocusables.length && by > 0);\n if (isTargetToggle) {\n return this.getNextFocusableTreeItem(treeView, from, 0);\n }\n\n const isValidIndex = targetElementIndex < treeItemFocusables.length;\n if (isValidIndex) {\n return treeItemFocusables[targetElementIndex];\n }\n\n return null;\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export declare function getClosestTreeItem(element: Element): HTMLLIElement | null;
2
+ export declare function getToggleButtonOfTreeItem(treeItem: null | HTMLLIElement): HTMLElement | null;
3
+ export declare function isElementDisabled(element: HTMLElement): boolean;
4
+ export declare function findTreeItemByIndex(treeView: HTMLUListElement, targetTreeItemIndex: number, delta: number): HTMLLIElement | null;
5
+ export declare function findTreeItemContentById(treeView: HTMLUListElement, treeItemId: string): HTMLLIElement | null;
6
+ export declare function isTreeItemToggle(element: Element): boolean;
7
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/tree-view/keyboard-navigation/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,wBAElD;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,IAAI,GAAG,aAAa,sBAGvE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,WAKrD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,wBAiBzG;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,wBAKrF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,WAEhD"}
@@ -0,0 +1,40 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import treeItemStyles from '../tree-item/styles.css.js';
4
+ export function getClosestTreeItem(element) {
5
+ return element.closest('li[data-awsui-tree-item-index]');
6
+ }
7
+ export function getToggleButtonOfTreeItem(treeItem) {
8
+ const toggleElement = treeItem === null || treeItem === void 0 ? void 0 : treeItem.querySelector(`.${treeItemStyles['tree-item-focus-target']}`);
9
+ return toggleElement;
10
+ }
11
+ export function isElementDisabled(element) {
12
+ if (element instanceof HTMLButtonElement) {
13
+ return element.disabled;
14
+ }
15
+ return false;
16
+ }
17
+ export function findTreeItemByIndex(treeView, targetTreeItemIndex, delta) {
18
+ var _a;
19
+ let targetTreeItem = null;
20
+ const treeItemElements = Array.from(treeView.querySelectorAll('li[data-awsui-tree-item-index]'));
21
+ if (delta < 0) {
22
+ treeItemElements.reverse();
23
+ }
24
+ for (const element of treeItemElements) {
25
+ const elementIndex = parseInt((_a = element.getAttribute('data-awsui-tree-item-index')) !== null && _a !== void 0 ? _a : '');
26
+ targetTreeItem = element;
27
+ if (elementIndex === targetTreeItemIndex) {
28
+ break;
29
+ }
30
+ }
31
+ return targetTreeItem;
32
+ }
33
+ export function findTreeItemContentById(treeView, treeItemId) {
34
+ const treeItemContent = treeView.querySelector(`li[data-awsui-tree-item-index][id="${treeItemId}"] .${treeItemStyles['tree-item-structured-item']}`);
35
+ return treeItemContent;
36
+ }
37
+ export function isTreeItemToggle(element) {
38
+ return element.classList.contains(treeItemStyles['tree-item-focus-target']);
39
+ }
40
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/tree-view/keyboard-navigation/utils.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,cAAc,MAAM,4BAA4B,CAAC;AAExD,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAyB,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAA8B;IACtE,MAAM,aAAa,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,aAAa,CAAC,IAAI,cAAc,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO,aAAmC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAoB;IACpD,IAAI,OAAO,YAAY,iBAAiB,EAAE;QACxC,OAAO,OAAO,CAAC,QAAQ,CAAC;KACzB;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAA0B,EAAE,mBAA2B,EAAE,KAAa;;IACxG,IAAI,cAAc,GAAyB,IAAI,CAAC;IAChD,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAEjG,IAAI,KAAK,GAAG,CAAC,EAAE;QACb,gBAAgB,CAAC,OAAO,EAAE,CAAC;KAC5B;IAED,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE;QACtC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,YAAY,CAAC,4BAA4B,CAAC,mCAAI,EAAE,CAAC,CAAC;QACxF,cAAc,GAAG,OAAwB,CAAC;QAE1C,IAAI,YAAY,KAAK,mBAAmB,EAAE;YACxC,MAAM;SACP;KACF;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAA0B,EAAE,UAAkB;IACpF,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAC5C,sCAAsC,UAAU,OAAO,cAAc,CAAC,2BAA2B,CAAC,EAAE,CACrG,CAAC;IACF,OAAO,eAAuC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAC,CAAC;AAC9E,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport treeItemStyles from '../tree-item/styles.css.js';\n\nexport function getClosestTreeItem(element: Element) {\n return element.closest('li[data-awsui-tree-item-index]') as null | HTMLLIElement;\n}\n\nexport function getToggleButtonOfTreeItem(treeItem: null | HTMLLIElement) {\n const toggleElement = treeItem?.querySelector(`.${treeItemStyles['tree-item-focus-target']}`);\n return toggleElement as null | HTMLElement;\n}\n\nexport function isElementDisabled(element: HTMLElement) {\n if (element instanceof HTMLButtonElement) {\n return element.disabled;\n }\n return false;\n}\n\nexport function findTreeItemByIndex(treeView: HTMLUListElement, targetTreeItemIndex: number, delta: number) {\n let targetTreeItem: null | HTMLLIElement = null;\n const treeItemElements = Array.from(treeView.querySelectorAll('li[data-awsui-tree-item-index]'));\n\n if (delta < 0) {\n treeItemElements.reverse();\n }\n\n for (const element of treeItemElements) {\n const elementIndex = parseInt(element.getAttribute('data-awsui-tree-item-index') ?? '');\n targetTreeItem = element as HTMLLIElement;\n\n if (elementIndex === targetTreeItemIndex) {\n break;\n }\n }\n return targetTreeItem;\n}\n\nexport function findTreeItemContentById(treeView: HTMLUListElement, treeItemId: string) {\n const treeItemContent = treeView.querySelector(\n `li[data-awsui-tree-item-index][id=\"${treeItemId}\"] .${treeItemStyles['tree-item-structured-item']}`\n );\n return treeItemContent as null | HTMLLIElement;\n}\n\nexport function isTreeItemToggle(element: Element) {\n return element.classList.contains(treeItemStyles['tree-item-focus-target']);\n}\n"]}
@@ -1,7 +1,7 @@
1
1
 
2
2
  import './styles.scoped.css';
3
3
  export default {
4
- "root": "awsui_root_18gnm_13lqd_181",
5
- "tree": "awsui_tree_18gnm_13lqd_218"
4
+ "root": "awsui_root_18gnm_1d03e_181",
5
+ "tree": "awsui_tree_18gnm_1d03e_218"
6
6
  };
7
7
 
@@ -178,7 +178,7 @@
178
178
  */
179
179
  /* Style used for links in slots/components that are text heavy, to help links stand out among
180
180
  surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F73#description */
181
- .awsui_root_18gnm_13lqd_181:not(#\9) {
181
+ .awsui_root_18gnm_1d03e_181:not(#\9) {
182
182
  border-collapse: separate;
183
183
  border-spacing: 0;
184
184
  box-sizing: border-box;
@@ -215,7 +215,8 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
215
215
  padding-inline: var(--space-scaled-xxs-jatbiv, 4px);
216
216
  }
217
217
 
218
- .awsui_tree_18gnm_13lqd_218:not(#\9) {
218
+ .awsui_tree_18gnm_1d03e_218:not(#\9) {
219
+ list-style: none;
219
220
  margin-block: 0;
220
221
  margin-inline: 0;
221
222
  padding-block: 0;
@@ -2,7 +2,7 @@
2
2
  // es-module interop with Babel and Typescript
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  module.exports.default = {
5
- "root": "awsui_root_18gnm_13lqd_181",
6
- "tree": "awsui_tree_18gnm_13lqd_218"
5
+ "root": "awsui_root_18gnm_1d03e_181",
6
+ "tree": "awsui_tree_18gnm_1d03e_218"
7
7
  };
8
8
 
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ export default function FocusTarget({ ariaLabel }: {
3
+ ariaLabel?: string;
4
+ }): JSX.Element;
5
+ //# sourceMappingURL=focus-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-target.d.ts","sourceRoot":"","sources":["../../../../src/tree-view/tree-item/focus-target.tsx"],"names":[],"mappings":";AAQA,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,eAexE"}
@@ -0,0 +1,11 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import React, { useRef } from 'react';
4
+ import { useSingleTabStopNavigation } from '@cloudscape-design/component-toolkit/internal';
5
+ import styles from './styles.css.js';
6
+ export default function FocusTarget({ ariaLabel }) {
7
+ const divRef = useRef(null);
8
+ const { tabIndex } = useSingleTabStopNavigation(divRef);
9
+ return (React.createElement("div", { role: "group", ref: divRef, tabIndex: tabIndex, "aria-label": ariaLabel, className: styles['tree-item-focus-target'] }, null));
10
+ }
11
+ //# sourceMappingURL=focus-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-target.js","sourceRoot":"","sources":["../../../../src/tree-view/tree-item/focus-target.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAE3F,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAErC,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,SAAS,EAA0B;IACvE,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC5C,MAAM,EAAE,QAAQ,EAAE,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAExD,OAAO,CACL,6BACE,IAAI,EAAC,OAAO,EACZ,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,gBACN,SAAS,EACrB,SAAS,EAAE,MAAM,CAAC,wBAAwB,CAAC,IAE1C,IAAI,CACD,CACP,CAAC;AACJ,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport React, { useRef } from 'react';\n\nimport { useSingleTabStopNavigation } from '@cloudscape-design/component-toolkit/internal';\n\nimport styles from './styles.css.js';\n\nexport default function FocusTarget({ ariaLabel }: { ariaLabel?: string }) {\n const divRef = useRef<HTMLDivElement>(null);\n const { tabIndex } = useSingleTabStopNavigation(divRef);\n\n return (\n <div\n role=\"group\"\n ref={divRef}\n tabIndex={tabIndex}\n aria-label={ariaLabel}\n className={styles['tree-item-focus-target']}\n >\n {null}\n </div>\n );\n}\n"]}
@@ -5,7 +5,10 @@ interface InternalTreeItemProps<T> extends Pick<TreeViewProps, 'expandedItems' |
5
5
  index: number;
6
6
  level: number;
7
7
  onItemToggle: (detail: TreeViewProps.ItemToggleDetail<T>) => void;
8
+ allVisibleItemsIndices: {
9
+ [key: string]: number;
10
+ };
8
11
  }
9
- declare const InternalTreeItem: <T>({ item, index, level, i18nStrings, expandedItems, renderItemToggleIcon, renderItem, getItemId, getItemChildren, onItemToggle, }: InternalTreeItemProps<T>) => JSX.Element;
12
+ declare const InternalTreeItem: <T>({ item, index, level, i18nStrings, expandedItems, renderItemToggleIcon, renderItem, getItemId, getItemChildren, onItemToggle, allVisibleItemsIndices, }: InternalTreeItemProps<T>) => JSX.Element;
10
13
  export default InternalTreeItem;
11
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tree-view/tree-item/index.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK9C,UAAU,qBAAqB,CAAC,CAAC,CAC/B,SAAQ,IAAI,CACV,aAAa,EACb,eAAe,GAAG,YAAY,GAAG,WAAW,GAAG,iBAAiB,GAAG,sBAAsB,GAAG,aAAa,CAC1G;IACD,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,gBAAgB,+KAmGrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tree-view/tree-item/index.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAM9C,UAAU,qBAAqB,CAAC,CAAC,CAC/B,SAAQ,IAAI,CACV,aAAa,EACb,eAAe,GAAG,YAAY,GAAG,WAAW,GAAG,iBAAiB,GAAG,sBAAsB,GAAG,aAAa,CAC1G;IACD,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE,sBAAsB,EAAE;QACtB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;CACH;AAED,QAAA,MAAM,gBAAgB,uMA+GrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -6,9 +6,10 @@ import { useInternalI18n } from '../../i18n/context';
6
6
  import { ExpandToggleButton } from '../../internal/components/expand-toggle-button';
7
7
  import InternalStructuredItem from '../../internal/components/structured-item';
8
8
  import { joinStrings } from '../../internal/utils/strings';
9
+ import FocusTarget from './focus-target';
9
10
  import testUtilStyles from '../test-classes/styles.css.js';
10
11
  import styles from './styles.css.js';
11
- const InternalTreeItem = ({ item, index, level, i18nStrings, expandedItems = [], renderItemToggleIcon, renderItem, getItemId, getItemChildren, onItemToggle, }) => {
12
+ const InternalTreeItem = ({ item, index, level, i18nStrings, expandedItems = [], renderItemToggleIcon, renderItem, getItemId, getItemChildren, onItemToggle, allVisibleItemsIndices, }) => {
12
13
  var _a, _b;
13
14
  const i18n = useInternalI18n('tree-view');
14
15
  const { icon, content, secondaryContent, actions, announcementLabel } = renderItem(item, index);
@@ -26,14 +27,15 @@ const InternalTreeItem = ({ item, index, level, i18nStrings, expandedItems = [],
26
27
  : typeof content === 'string'
27
28
  ? content
28
29
  : '';
29
- // Role `treeitem` isn't used in the initial release per discussion with A11Y team. It requires focus management to be implemented so they will be added as a follow up together.
30
- return (React.createElement("li", { id: id, className: clsx(styles.treeitem, testUtilStyles.treeitem, isExpandable && [testUtilStyles.expandable], isExpanded && [testUtilStyles.expanded]), "aria-expanded": isExpandable ? isExpanded : undefined, "aria-level": level, "data-testid": `awsui-treeitem-${id}` },
31
- React.createElement("div", { className: styles['expand-toggle-wrapper'] }, isExpandable && (React.createElement("div", { className: styles.toggle },
32
- React.createElement(ExpandToggleButton, { isExpanded: isExpanded, customIcon: customIcon, expandButtonLabel: joinStrings(i18n('i18nStrings.expandButtonLabel', (_a = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.expandButtonLabel) === null || _a === void 0 ? void 0 : _a.call(i18nStrings, item)), itemLabelToAnnounce), collapseButtonLabel: joinStrings(i18n('i18nStrings.collapseButtonLabel', (_b = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.collapseButtonLabel) === null || _b === void 0 ? void 0 : _b.call(i18nStrings, item)), itemLabelToAnnounce), onExpandableItemToggle: () => onItemToggle({ id, item, expanded: !isExpanded }) })))),
33
- React.createElement("div", { className: styles['structured-item-wrapper'] },
34
- React.createElement(InternalStructuredItem, { icon: icon, content: content, secondaryContent: secondaryContent, actions: actions, wrapActions: false })),
35
- isExpanded && children.length && (React.createElement("ul", { className: styles['treeitem-group'] }, children.map((child, index) => {
36
- return (React.createElement(InternalTreeItem, { item: child, index: index, key: `${nextLevel}-${index}`, level: nextLevel, expandedItems: expandedItems, i18nStrings: i18nStrings, onItemToggle: onItemToggle, renderItem: renderItem, getItemId: getItemId, getItemChildren: getItemChildren, renderItemToggleIcon: renderItemToggleIcon }));
30
+ return (React.createElement("li", { role: "treeitem", id: id, className: clsx(styles.treeitem, testUtilStyles.treeitem, level > 1 && styles.offset, isExpandable && [testUtilStyles.expandable], isExpanded && [testUtilStyles.expanded]), "aria-expanded": isExpandable ? isExpanded : undefined, "aria-level": level, "data-testid": `awsui-treeitem-${id}`, "data-awsui-tree-item-index": allVisibleItemsIndices[id] },
31
+ React.createElement("div", { className: styles['treeitem-content-wrapper'] },
32
+ React.createElement("div", { className: styles['expand-toggle-wrapper'] },
33
+ React.createElement("div", { className: styles.toggle }, isExpandable ? (React.createElement(ExpandToggleButton, { isExpanded: isExpanded, customIcon: customIcon, expandButtonLabel: joinStrings(i18n('i18nStrings.expandButtonLabel', (_a = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.expandButtonLabel) === null || _a === void 0 ? void 0 : _a.call(i18nStrings, item)), itemLabelToAnnounce), collapseButtonLabel: joinStrings(i18n('i18nStrings.collapseButtonLabel', (_b = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.collapseButtonLabel) === null || _b === void 0 ? void 0 : _b.call(i18nStrings, item)), itemLabelToAnnounce), onExpandableItemToggle: () => onItemToggle({ id, item, expanded: !isExpanded }), className: styles['tree-item-focus-target'], disableFocusHighlight: true })) : (React.createElement(FocusTarget, { ariaLabel: itemLabelToAnnounce })))),
34
+ React.createElement("div", { className: styles['structured-item-wrapper'] },
35
+ React.createElement(InternalStructuredItem, { icon: icon, content: content, secondaryContent: secondaryContent, actions: actions, wrapActions: false, className: styles['tree-item-structured-item'] }))),
36
+ isExpanded && children.length && (React.createElement("ul", { role: "group", className: styles['treeitem-group'] }, children.map((child, index) => {
37
+ const itemId = getItemId(child, index);
38
+ return (React.createElement(InternalTreeItem, { item: child, index: index, key: itemId, level: nextLevel, expandedItems: expandedItems, i18nStrings: i18nStrings, onItemToggle: onItemToggle, renderItem: renderItem, getItemId: getItemId, getItemChildren: getItemChildren, renderItemToggleIcon: renderItemToggleIcon, allVisibleItemsIndices: allVisibleItemsIndices }));
37
39
  })))));
38
40
  };
39
41
  export default InternalTreeItem;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tree-view/tree-item/index.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\nimport React from 'react';\nimport clsx from 'clsx';\n\nimport { useInternalI18n } from '../../i18n/context';\nimport { ExpandToggleButton } from '../../internal/components/expand-toggle-button';\nimport InternalStructuredItem from '../../internal/components/structured-item';\nimport { joinStrings } from '../../internal/utils/strings';\nimport { TreeViewProps } from '../interfaces';\n\nimport testUtilStyles from '../test-classes/styles.css.js';\nimport styles from './styles.css.js';\n\ninterface InternalTreeItemProps<T>\n extends Pick<\n TreeViewProps,\n 'expandedItems' | 'renderItem' | 'getItemId' | 'getItemChildren' | 'renderItemToggleIcon' | 'i18nStrings'\n > {\n item: T;\n index: number;\n level: number;\n onItemToggle: (detail: TreeViewProps.ItemToggleDetail<T>) => void;\n}\n\nconst InternalTreeItem = <T,>({\n item,\n index,\n level,\n i18nStrings,\n expandedItems = [],\n renderItemToggleIcon,\n renderItem,\n getItemId,\n getItemChildren,\n onItemToggle,\n}: InternalTreeItemProps<T>) => {\n const i18n = useInternalI18n('tree-view');\n\n const { icon, content, secondaryContent, actions, announcementLabel } = renderItem(item, index);\n const id = getItemId(item, index);\n const children = getItemChildren(item, index) || [];\n const isExpandable = children.length > 0;\n const isExpanded = isExpandable && expandedItems.includes(id);\n const nextLevel = level + 1;\n\n let customIcon: React.ReactNode | undefined = undefined;\n if (isExpandable && renderItemToggleIcon) {\n customIcon = renderItemToggleIcon({ expanded: isExpanded });\n }\n\n const itemLabelToAnnounce = announcementLabel\n ? announcementLabel\n : typeof content === 'string'\n ? (content as string)\n : '';\n\n // Role `treeitem` isn't used in the initial release per discussion with A11Y team. It requires focus management to be implemented so they will be added as a follow up together.\n return (\n <li\n id={id}\n className={clsx(\n styles.treeitem,\n testUtilStyles.treeitem,\n isExpandable && [testUtilStyles.expandable],\n isExpanded && [testUtilStyles.expanded]\n )}\n aria-expanded={isExpandable ? isExpanded : undefined}\n aria-level={level}\n data-testid={`awsui-treeitem-${id}`}\n >\n <div className={styles['expand-toggle-wrapper']}>\n {isExpandable && (\n <div className={styles.toggle}>\n <ExpandToggleButton\n isExpanded={isExpanded}\n customIcon={customIcon}\n expandButtonLabel={joinStrings(\n i18n('i18nStrings.expandButtonLabel', i18nStrings?.expandButtonLabel?.(item)),\n itemLabelToAnnounce\n )}\n collapseButtonLabel={joinStrings(\n i18n('i18nStrings.collapseButtonLabel', i18nStrings?.collapseButtonLabel?.(item)),\n itemLabelToAnnounce\n )}\n onExpandableItemToggle={() => onItemToggle({ id, item, expanded: !isExpanded })}\n />\n </div>\n )}\n </div>\n\n <div className={styles['structured-item-wrapper']}>\n <InternalStructuredItem\n icon={icon}\n content={content}\n secondaryContent={secondaryContent}\n actions={actions}\n wrapActions={false}\n />\n </div>\n\n {isExpanded && children.length && (\n <ul className={styles['treeitem-group']}>\n {children.map((child, index) => {\n return (\n <InternalTreeItem\n item={child}\n index={index}\n key={`${nextLevel}-${index}`}\n level={nextLevel}\n expandedItems={expandedItems}\n i18nStrings={i18nStrings}\n onItemToggle={onItemToggle}\n renderItem={renderItem}\n getItemId={getItemId}\n getItemChildren={getItemChildren}\n renderItemToggleIcon={renderItemToggleIcon}\n />\n );\n })}\n </ul>\n )}\n </li>\n );\n};\n\nexport default InternalTreeItem;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tree-view/tree-item/index.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\nimport React from 'react';\nimport clsx from 'clsx';\n\nimport { useInternalI18n } from '../../i18n/context';\nimport { ExpandToggleButton } from '../../internal/components/expand-toggle-button';\nimport InternalStructuredItem from '../../internal/components/structured-item';\nimport { joinStrings } from '../../internal/utils/strings';\nimport { TreeViewProps } from '../interfaces';\nimport FocusTarget from './focus-target';\n\nimport testUtilStyles from '../test-classes/styles.css.js';\nimport styles from './styles.css.js';\n\ninterface InternalTreeItemProps<T>\n extends Pick<\n TreeViewProps,\n 'expandedItems' | 'renderItem' | 'getItemId' | 'getItemChildren' | 'renderItemToggleIcon' | 'i18nStrings'\n > {\n item: T;\n index: number;\n level: number;\n onItemToggle: (detail: TreeViewProps.ItemToggleDetail<T>) => void;\n allVisibleItemsIndices: {\n [key: string]: number;\n };\n}\n\nconst InternalTreeItem = <T,>({\n item,\n index,\n level,\n i18nStrings,\n expandedItems = [],\n renderItemToggleIcon,\n renderItem,\n getItemId,\n getItemChildren,\n onItemToggle,\n allVisibleItemsIndices,\n}: InternalTreeItemProps<T>) => {\n const i18n = useInternalI18n('tree-view');\n\n const { icon, content, secondaryContent, actions, announcementLabel } = renderItem(item, index);\n const id = getItemId(item, index);\n const children = getItemChildren(item, index) || [];\n const isExpandable = children.length > 0;\n const isExpanded = isExpandable && expandedItems.includes(id);\n const nextLevel = level + 1;\n\n let customIcon: React.ReactNode | undefined = undefined;\n if (isExpandable && renderItemToggleIcon) {\n customIcon = renderItemToggleIcon({ expanded: isExpanded });\n }\n\n const itemLabelToAnnounce = announcementLabel\n ? announcementLabel\n : typeof content === 'string'\n ? (content as string)\n : '';\n\n return (\n <li\n role=\"treeitem\"\n id={id}\n className={clsx(\n styles.treeitem,\n testUtilStyles.treeitem,\n level > 1 && styles.offset,\n isExpandable && [testUtilStyles.expandable],\n isExpanded && [testUtilStyles.expanded]\n )}\n aria-expanded={isExpandable ? isExpanded : undefined}\n aria-level={level}\n data-testid={`awsui-treeitem-${id}`}\n data-awsui-tree-item-index={allVisibleItemsIndices[id]}\n >\n <div className={styles['treeitem-content-wrapper']}>\n <div className={styles['expand-toggle-wrapper']}>\n <div className={styles.toggle}>\n {isExpandable ? (\n <ExpandToggleButton\n isExpanded={isExpanded}\n customIcon={customIcon}\n expandButtonLabel={joinStrings(\n i18n('i18nStrings.expandButtonLabel', i18nStrings?.expandButtonLabel?.(item)),\n itemLabelToAnnounce\n )}\n collapseButtonLabel={joinStrings(\n i18n('i18nStrings.collapseButtonLabel', i18nStrings?.collapseButtonLabel?.(item)),\n itemLabelToAnnounce\n )}\n onExpandableItemToggle={() => onItemToggle({ id, item, expanded: !isExpanded })}\n className={styles['tree-item-focus-target']}\n disableFocusHighlight={true}\n />\n ) : (\n <FocusTarget ariaLabel={itemLabelToAnnounce} />\n )}\n </div>\n </div>\n\n <div className={styles['structured-item-wrapper']}>\n <InternalStructuredItem\n icon={icon}\n content={content}\n secondaryContent={secondaryContent}\n actions={actions}\n wrapActions={false}\n className={styles['tree-item-structured-item']}\n />\n </div>\n </div>\n\n {isExpanded && children.length && (\n <ul role=\"group\" className={styles['treeitem-group']}>\n {children.map((child, index) => {\n const itemId = getItemId(child, index);\n return (\n <InternalTreeItem<T>\n item={child}\n index={index}\n key={itemId}\n level={nextLevel}\n expandedItems={expandedItems}\n i18nStrings={i18nStrings}\n onItemToggle={onItemToggle}\n renderItem={renderItem}\n getItemId={getItemId}\n getItemChildren={getItemChildren}\n renderItemToggleIcon={renderItemToggleIcon}\n allVisibleItemsIndices={allVisibleItemsIndices}\n />\n );\n })}\n </ul>\n )}\n </li>\n );\n};\n\nexport default InternalTreeItem;\n"]}
@@ -1,10 +1,14 @@
1
1
 
2
2
  import './styles.scoped.css';
3
3
  export default {
4
- "treeitem-group": "awsui_treeitem-group_1agpu_sttqi_181",
5
- "treeitem": "awsui_treeitem_1agpu_sttqi_181",
6
- "expand-toggle-wrapper": "awsui_expand-toggle-wrapper_1agpu_sttqi_198",
7
- "toggle": "awsui_toggle_1agpu_sttqi_203",
8
- "structured-item-wrapper": "awsui_structured-item-wrapper_1agpu_sttqi_208"
4
+ "treeitem-group": "awsui_treeitem-group_1agpu_1hpjs_185",
5
+ "treeitem": "awsui_treeitem_1agpu_1hpjs_185",
6
+ "offset": "awsui_offset_1agpu_1hpjs_202",
7
+ "treeitem-content-wrapper": "awsui_treeitem-content-wrapper_1agpu_1hpjs_205",
8
+ "tree-item-focus-target": "awsui_tree-item-focus-target_1agpu_1hpjs_210",
9
+ "expand-toggle-wrapper": "awsui_expand-toggle-wrapper_1agpu_1hpjs_231",
10
+ "toggle": "awsui_toggle_1agpu_1hpjs_236",
11
+ "structured-item-wrapper": "awsui_structured-item-wrapper_1agpu_1hpjs_241",
12
+ "tree-item-structured-item": "awsui_tree-item-structured-item_1agpu_1hpjs_248"
9
13
  };
10
14
 
@@ -178,39 +178,74 @@
178
178
  */
179
179
  /* Style used for links in slots/components that are text heavy, to help links stand out among
180
180
  surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F73#description */
181
- .awsui_treeitem-group_1agpu_sttqi_181:not(#\9) {
181
+ /*
182
+ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
183
+ SPDX-License-Identifier: Apache-2.0
184
+ */
185
+ .awsui_treeitem-group_1agpu_1hpjs_185:not(#\9) {
186
+ list-style: none;
182
187
  margin-block: 0;
183
188
  margin-inline: 0;
184
189
  padding-block: 0;
185
190
  padding-inline: 0;
191
+ position: relative;
186
192
  }
187
193
 
188
- .awsui_treeitem_1agpu_sttqi_181:not(#\9) {
194
+ .awsui_treeitem_1agpu_1hpjs_185:not(#\9) {
195
+ list-style: none;
189
196
  margin-block: 0;
190
197
  margin-inline: 0;
191
198
  padding-block: 0;
192
199
  padding-inline: 0;
193
- align-items: baseline;
200
+ position: relative;
201
+ }
202
+ .awsui_treeitem_1agpu_1hpjs_185.awsui_offset_1agpu_1hpjs_202:not(#\9) {
203
+ margin-inline-start: 28px;
204
+ }
205
+ .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205:not(#\9) {
194
206
  display: grid;
195
207
  grid-template-columns: 28px 1fr;
196
- grid-template-rows: auto auto auto;
208
+ align-items: baseline;
209
+ }
210
+ body[data-awsui-focus-visible=true] .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205:not(#\9):has(.awsui_tree-item-focus-target_1agpu_1hpjs_210:focus) {
211
+ position: relative;
212
+ }
213
+ body[data-awsui-focus-visible=true] .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205:not(#\9):has(.awsui_tree-item-focus-target_1agpu_1hpjs_210:focus) {
214
+ outline: 2px dotted transparent;
215
+ outline-offset: calc(0px - 1px);
197
216
  }
198
- .awsui_treeitem_1agpu_sttqi_181 > .awsui_expand-toggle-wrapper_1agpu_sttqi_198:not(#\9) {
217
+ body[data-awsui-focus-visible=true] .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205:not(#\9):has(.awsui_tree-item-focus-target_1agpu_1hpjs_210:focus)::before {
218
+ content: " ";
219
+ display: block;
220
+ position: absolute;
221
+ inset-inline-start: calc(-1 * 0px);
222
+ inset-block-start: calc(-1 * 0px);
223
+ inline-size: calc(100% + 0px + 0px);
224
+ block-size: calc(100% + 0px + 0px);
225
+ border-start-start-radius: var(--border-radius-control-default-focus-ring-9xsko1, 2px);
226
+ border-start-end-radius: var(--border-radius-control-default-focus-ring-9xsko1, 2px);
227
+ border-end-start-radius: var(--border-radius-control-default-focus-ring-9xsko1, 2px);
228
+ border-end-end-radius: var(--border-radius-control-default-focus-ring-9xsko1, 2px);
229
+ box-shadow: 0 0 0 2px var(--color-border-item-focused-r5f6xl, #0073bb);
230
+ }
231
+ .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205 > .awsui_expand-toggle-wrapper_1agpu_1hpjs_231:not(#\9) {
199
232
  grid-column: 1;
200
233
  grid-row: 1;
201
- margin-inline-end: var(--space-scaled-xxs-jatbiv, 4px);
234
+ padding-inline-end: var(--space-scaled-xxs-jatbiv, 4px);
202
235
  }
203
- .awsui_treeitem_1agpu_sttqi_181 > .awsui_expand-toggle-wrapper_1agpu_sttqi_198 > .awsui_toggle_1agpu_sttqi_203:not(#\9) {
236
+ .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205 > .awsui_expand-toggle-wrapper_1agpu_1hpjs_231 > .awsui_toggle_1agpu_1hpjs_236:not(#\9) {
204
237
  justify-self: center;
205
238
  position: relative;
206
239
  inset-block-start: 2px;
207
240
  }
208
- .awsui_treeitem_1agpu_sttqi_181 > .awsui_structured-item-wrapper_1agpu_sttqi_208:not(#\9) {
241
+ .awsui_treeitem_1agpu_1hpjs_185 > .awsui_treeitem-content-wrapper_1agpu_1hpjs_205 > .awsui_structured-item-wrapper_1agpu_1hpjs_241:not(#\9) {
209
242
  grid-column: 2;
210
243
  grid-row: 1/span 2;
211
244
  padding-block: var(--space-scaled-xxs-jatbiv, 4px);
245
+ position: relative;
212
246
  }
213
- .awsui_treeitem_1agpu_sttqi_181 > .awsui_treeitem-group_1agpu_sttqi_181:not(#\9) {
214
- grid-column: 2;
215
- grid-row: 3;
247
+
248
+ .awsui_tree-item-structured-item_1agpu_1hpjs_248:not(#\9),
249
+ .awsui_tree-item-focus-target_1agpu_1hpjs_210:not(#\9) {
250
+ /* used in keyboard navigation */
216
251
  }