@cloudscape-design/components 3.0.1097 → 3.0.1099
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/internal/base-component/styles.scoped.css +1 -1
- package/internal/components/expand-toggle-button/index.d.ts +5 -1
- package/internal/components/expand-toggle-button/index.d.ts.map +1 -1
- package/internal/components/expand-toggle-button/index.js +2 -2
- package/internal/components/expand-toggle-button/index.js.map +1 -1
- package/internal/components/expand-toggle-button/styles.css.js +4 -3
- package/internal/components/expand-toggle-button/styles.scoped.css +13 -13
- package/internal/components/expand-toggle-button/styles.selectors.js +4 -3
- package/internal/components/structured-item/index.d.ts +5 -2
- package/internal/components/structured-item/index.d.ts.map +1 -1
- package/internal/components/structured-item/index.js +2 -2
- package/internal/components/structured-item/index.js.map +1 -1
- package/internal/environment.js +2 -2
- package/internal/environment.json +2 -2
- package/internal/manifest.json +1 -1
- package/package.json +1 -1
- package/tree-view/internal.d.ts.map +1 -1
- package/tree-view/internal.js +10 -4
- package/tree-view/internal.js.map +1 -1
- package/tree-view/keyboard-navigation/index.d.ts +33 -0
- package/tree-view/keyboard-navigation/index.d.ts.map +1 -0
- package/tree-view/keyboard-navigation/index.js +224 -0
- package/tree-view/keyboard-navigation/index.js.map +1 -0
- package/tree-view/keyboard-navigation/utils.d.ts +6 -0
- package/tree-view/keyboard-navigation/utils.d.ts.map +1 -0
- package/tree-view/keyboard-navigation/utils.js +40 -0
- package/tree-view/keyboard-navigation/utils.js.map +1 -0
- package/tree-view/styles.css.js +2 -2
- package/tree-view/styles.scoped.css +3 -2
- package/tree-view/styles.selectors.js +2 -2
- package/tree-view/tree-item/focus-target.d.ts +6 -0
- package/tree-view/tree-item/focus-target.d.ts.map +1 -0
- package/tree-view/tree-item/focus-target.js +11 -0
- package/tree-view/tree-item/focus-target.js.map +1 -0
- package/tree-view/tree-item/index.d.ts +5 -1
- package/tree-view/tree-item/index.d.ts.map +1 -1
- package/tree-view/tree-item/index.js +11 -9
- package/tree-view/tree-item/index.js.map +1 -1
- package/tree-view/tree-item/styles.css.js +9 -5
- package/tree-view/tree-item/styles.scoped.css +46 -11
- package/tree-view/tree-item/styles.selectors.js +9 -5
- package/tree-view/utils.d.ts +15 -0
- package/tree-view/utils.d.ts.map +1 -0
- package/tree-view/utils.js +20 -0
- package/tree-view/utils.js.map +1 -0
|
@@ -4,11 +4,15 @@ export declare function ExpandToggleButton({
|
|
|
4
4
|
onExpandableItemToggle,
|
|
5
5
|
expandButtonLabel,
|
|
6
6
|
collapseButtonLabel,
|
|
7
|
-
customIcon
|
|
7
|
+
customIcon,
|
|
8
|
+
className,
|
|
9
|
+
disableFocusHighlight
|
|
8
10
|
}: {
|
|
9
11
|
isExpanded?: boolean;
|
|
10
12
|
onExpandableItemToggle?: () => void;
|
|
11
13
|
expandButtonLabel?: string;
|
|
12
14
|
collapseButtonLabel?: string;
|
|
13
15
|
customIcon?: React.ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
disableFocusHighlight?: boolean;
|
|
14
18
|
}): JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/expand-toggle-button/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAStC,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/expand-toggle-button/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAStC,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,qBAAqB,GACtB,EAAE;IACD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,eAuBA"}
|
|
@@ -5,9 +5,9 @@ import clsx from 'clsx';
|
|
|
5
5
|
import { useSingleTabStopNavigation } from '@cloudscape-design/component-toolkit/internal';
|
|
6
6
|
import InternalIcon from '../../../icon/internal';
|
|
7
7
|
import styles from './styles.css.js';
|
|
8
|
-
export function ExpandToggleButton({ isExpanded, onExpandableItemToggle, expandButtonLabel, collapseButtonLabel, customIcon, }) {
|
|
8
|
+
export function ExpandToggleButton({ isExpanded, onExpandableItemToggle, expandButtonLabel, collapseButtonLabel, customIcon, className, disableFocusHighlight, }) {
|
|
9
9
|
const buttonRef = useRef(null);
|
|
10
10
|
const { tabIndex } = useSingleTabStopNavigation(buttonRef);
|
|
11
|
-
return (React.createElement("button", { type: "button", ref: buttonRef, tabIndex: tabIndex, "aria-label": isExpanded ? collapseButtonLabel : expandButtonLabel, "aria-expanded": isExpanded, className: styles['expand-toggle'], onClick: onExpandableItemToggle }, customIcon !== null && customIcon !== void 0 ? customIcon : (React.createElement(InternalIcon, { size: "small", name: "caret-down-filled", className: clsx(styles['expand-toggle-icon'], isExpanded && styles['expand-toggle-icon-expanded']) }))));
|
|
11
|
+
return (React.createElement("button", { type: "button", ref: buttonRef, tabIndex: tabIndex, "aria-label": isExpanded ? collapseButtonLabel : expandButtonLabel, "aria-expanded": isExpanded, className: clsx(styles['expand-toggle'], disableFocusHighlight && styles['disable-focus-highlight'], className), onClick: onExpandableItemToggle }, customIcon !== null && customIcon !== void 0 ? customIcon : (React.createElement(InternalIcon, { size: "small", name: "caret-down-filled", className: clsx(styles['expand-toggle-icon'], isExpanded && styles['expand-toggle-icon-expanded']) }))));
|
|
12
12
|
}
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/internal/components/expand-toggle-button/index.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAE3F,OAAO,YAAY,MAAM,wBAAwB,CAAC;AAElD,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAErC,MAAM,UAAU,kBAAkB,CAAC,EACjC,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/internal/components/expand-toggle-button/index.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAE3F,OAAO,YAAY,MAAM,wBAAwB,CAAC;AAElD,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAErC,MAAM,UAAU,kBAAkB,CAAC,EACjC,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,SAAS,EACT,qBAAqB,GAStB;IACC,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAClD,MAAM,EAAE,QAAQ,EAAE,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAE3D,OAAO,CACL,gCACE,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,QAAQ,gBACN,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,iBAAiB,mBACjD,UAAU,EACzB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,qBAAqB,IAAI,MAAM,CAAC,yBAAyB,CAAC,EAAE,SAAS,CAAC,EAC/G,OAAO,EAAE,sBAAsB,IAE9B,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,CACb,oBAAC,YAAY,IACX,IAAI,EAAC,OAAO,EACZ,IAAI,EAAC,mBAAmB,EACxB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,UAAU,IAAI,MAAM,CAAC,6BAA6B,CAAC,CAAC,GAClG,CACH,CACM,CACV,CAAC;AACJ,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport React, { useRef } from 'react';\nimport clsx from 'clsx';\n\nimport { useSingleTabStopNavigation } from '@cloudscape-design/component-toolkit/internal';\n\nimport InternalIcon from '../../../icon/internal';\n\nimport styles from './styles.css.js';\n\nexport function ExpandToggleButton({\n isExpanded,\n onExpandableItemToggle,\n expandButtonLabel,\n collapseButtonLabel,\n customIcon,\n className,\n disableFocusHighlight,\n}: {\n isExpanded?: boolean;\n onExpandableItemToggle?: () => void;\n expandButtonLabel?: string;\n collapseButtonLabel?: string;\n customIcon?: React.ReactNode;\n className?: string;\n disableFocusHighlight?: boolean;\n}) {\n const buttonRef = useRef<HTMLButtonElement>(null);\n const { tabIndex } = useSingleTabStopNavigation(buttonRef);\n\n return (\n <button\n type=\"button\"\n ref={buttonRef}\n tabIndex={tabIndex}\n aria-label={isExpanded ? collapseButtonLabel : expandButtonLabel}\n aria-expanded={isExpanded}\n className={clsx(styles['expand-toggle'], disableFocusHighlight && styles['disable-focus-highlight'], className)}\n onClick={onExpandableItemToggle}\n >\n {customIcon ?? (\n <InternalIcon\n size=\"small\"\n name=\"caret-down-filled\"\n className={clsx(styles['expand-toggle-icon'], isExpanded && styles['expand-toggle-icon-expanded'])}\n />\n )}\n </button>\n );\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
import './styles.scoped.css';
|
|
3
3
|
export default {
|
|
4
|
-
"expand-toggle-icon": "awsui_expand-toggle-
|
|
5
|
-
"expand-toggle-icon-expanded": "awsui_expand-toggle-icon-
|
|
6
|
-
"expand-toggle": "awsui_expand-
|
|
4
|
+
"expand-toggle-icon": "awsui_expand-toggle-icon_1xe88_1hyl4_153",
|
|
5
|
+
"expand-toggle-icon-expanded": "awsui_expand-toggle-icon-expanded_1xe88_1hyl4_174",
|
|
6
|
+
"expand-toggle": "awsui_expand-toggle_1xe88_1hyl4_153",
|
|
7
|
+
"disable-focus-highlight": "awsui_disable-focus-highlight_1xe88_1hyl4_225"
|
|
7
8
|
};
|
|
8
9
|
|
|
@@ -150,36 +150,36 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
|
|
|
150
150
|
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
151
151
|
SPDX-License-Identifier: Apache-2.0
|
|
152
152
|
*/
|
|
153
|
-
.awsui_expand-toggle-
|
|
153
|
+
.awsui_expand-toggle-icon_1xe88_1hyl4_153:not(#\9) {
|
|
154
154
|
transition: transform var(--motion-duration-rotate-90-lyzb0k, 135ms) var(--motion-easing-rotate-90-jhbqg9, cubic-bezier(0.165, 0.84, 0.44, 1));
|
|
155
155
|
}
|
|
156
156
|
@media (prefers-reduced-motion: reduce) {
|
|
157
|
-
.awsui_expand-toggle-
|
|
157
|
+
.awsui_expand-toggle-icon_1xe88_1hyl4_153:not(#\9) {
|
|
158
158
|
animation: none;
|
|
159
159
|
transition: none;
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
|
-
.awsui-motion-disabled .awsui_expand-toggle-
|
|
162
|
+
.awsui-motion-disabled .awsui_expand-toggle-icon_1xe88_1hyl4_153:not(#\9), .awsui-mode-entering .awsui_expand-toggle-icon_1xe88_1hyl4_153:not(#\9) {
|
|
163
163
|
animation: none;
|
|
164
164
|
transition: none;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
.awsui_expand-toggle-
|
|
167
|
+
.awsui_expand-toggle-icon_1xe88_1hyl4_153:not(#\9) {
|
|
168
168
|
transform: rotate(-90deg);
|
|
169
169
|
/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
|
|
170
170
|
}
|
|
171
|
-
.awsui_expand-toggle-
|
|
171
|
+
.awsui_expand-toggle-icon_1xe88_1hyl4_153:not(#\9):dir(rtl) {
|
|
172
172
|
transform: rotate(90deg);
|
|
173
173
|
}
|
|
174
|
-
.awsui_expand-toggle-icon-
|
|
174
|
+
.awsui_expand-toggle-icon-expanded_1xe88_1hyl4_174:not(#\9) {
|
|
175
175
|
transform: rotate(0deg);
|
|
176
176
|
/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
|
|
177
177
|
}
|
|
178
|
-
.awsui_expand-toggle-icon-
|
|
178
|
+
.awsui_expand-toggle-icon-expanded_1xe88_1hyl4_174:not(#\9):dir(rtl) {
|
|
179
179
|
transform: rotate(0deg);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
.awsui_expand-
|
|
182
|
+
.awsui_expand-toggle_1xe88_1hyl4_153:not(#\9) {
|
|
183
183
|
border-collapse: separate;
|
|
184
184
|
border-spacing: 0;
|
|
185
185
|
box-sizing: border-box;
|
|
@@ -222,14 +222,14 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
|
|
|
222
222
|
outline: 0;
|
|
223
223
|
color: var(--color-text-interactive-default-ugh9wp, #424650);
|
|
224
224
|
}
|
|
225
|
-
body[data-awsui-focus-visible=true] .awsui_expand-
|
|
225
|
+
body[data-awsui-focus-visible=true] .awsui_expand-toggle_1xe88_1hyl4_153:not(#\9):not(.awsui_disable-focus-highlight_1xe88_1hyl4_225):focus {
|
|
226
226
|
position: relative;
|
|
227
227
|
}
|
|
228
|
-
body[data-awsui-focus-visible=true] .awsui_expand-
|
|
228
|
+
body[data-awsui-focus-visible=true] .awsui_expand-toggle_1xe88_1hyl4_153:not(#\9):not(.awsui_disable-focus-highlight_1xe88_1hyl4_225):focus {
|
|
229
229
|
outline: 2px dotted transparent;
|
|
230
230
|
outline-offset: calc(var(--space-button-focus-outline-gutter-jj138g, 4px) - 1px);
|
|
231
231
|
}
|
|
232
|
-
body[data-awsui-focus-visible=true] .awsui_expand-
|
|
232
|
+
body[data-awsui-focus-visible=true] .awsui_expand-toggle_1xe88_1hyl4_153:not(#\9):not(.awsui_disable-focus-highlight_1xe88_1hyl4_225):focus::before {
|
|
233
233
|
content: " ";
|
|
234
234
|
display: block;
|
|
235
235
|
position: absolute;
|
|
@@ -243,9 +243,9 @@ body[data-awsui-focus-visible=true] .awsui_expand-toggle_1xe88_13yei_153:not(#\9
|
|
|
243
243
|
border-end-end-radius: var(--border-radius-control-default-focus-ring-1uabki, 4px);
|
|
244
244
|
box-shadow: 0 0 0 2px var(--color-border-item-focused-uk47pl, #006ce0);
|
|
245
245
|
}
|
|
246
|
-
.awsui_expand-
|
|
246
|
+
.awsui_expand-toggle_1xe88_1hyl4_153:not(#\9):hover {
|
|
247
247
|
color: var(--color-text-interactive-hover-6naf7i, #0f141a);
|
|
248
248
|
}
|
|
249
|
-
.awsui_expand-
|
|
249
|
+
.awsui_expand-toggle_1xe88_1hyl4_153:not(#\9):active {
|
|
250
250
|
color: var(--color-text-interactive-active-uoe6zi, #0f141a);
|
|
251
251
|
}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// es-module interop with Babel and Typescript
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
module.exports.default = {
|
|
5
|
-
"expand-toggle-icon": "awsui_expand-toggle-
|
|
6
|
-
"expand-toggle-icon-expanded": "awsui_expand-toggle-icon-
|
|
7
|
-
"expand-toggle": "awsui_expand-
|
|
5
|
+
"expand-toggle-icon": "awsui_expand-toggle-icon_1xe88_1hyl4_153",
|
|
6
|
+
"expand-toggle-icon-expanded": "awsui_expand-toggle-icon-expanded_1xe88_1hyl4_174",
|
|
7
|
+
"expand-toggle": "awsui_expand-toggle_1xe88_1hyl4_153",
|
|
8
|
+
"disable-focus-highlight": "awsui_disable-focus-highlight_1xe88_1hyl4_225"
|
|
8
9
|
};
|
|
9
10
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/structured-item/index.tsx"],"names":[],"mappings":";AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKnD,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAE/B,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,OAAO,EACP,IAAI,EACJ,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,WAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/structured-item/index.tsx"],"names":[],"mappings":";AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAKnD,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAE/B,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,OAAO,EACP,IAAI,EACJ,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,WAAkB,EAClB,SAAS,GACV,EAAE,mBAAmB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,eAa9C"}
|
|
@@ -4,8 +4,8 @@ import React from 'react';
|
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import styles from './styles.css.js';
|
|
6
6
|
import testClasses from './test-classes/styles.css.js';
|
|
7
|
-
export default function InternalStructuredItem({ content, icon, actions, secondaryContent, disablePaddings, wrapActions = true, }) {
|
|
8
|
-
return (React.createElement("div", { className: clsx(styles.root, testClasses.root, disablePaddings && styles['disable-paddings']) },
|
|
7
|
+
export default function InternalStructuredItem({ content, icon, actions, secondaryContent, disablePaddings, wrapActions = true, className, }) {
|
|
8
|
+
return (React.createElement("div", { className: clsx(styles.root, testClasses.root, disablePaddings && styles['disable-paddings'], className) },
|
|
9
9
|
icon && React.createElement("div", { className: clsx(styles.icon, testClasses.icon) }, icon),
|
|
10
10
|
React.createElement("div", { className: clsx(styles.main) },
|
|
11
11
|
React.createElement("div", { className: clsx(styles['content-wrap'], wrapActions && styles['wrap-actions']) },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/internal/components/structured-item/index.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,WAAW,MAAM,8BAA8B,CAAC;AAIvD,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,OAAO,EACP,IAAI,EACJ,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,WAAW,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/internal/components/structured-item/index.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,WAAW,MAAM,8BAA8B,CAAC;AAIvD,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAC7C,OAAO,EACP,IAAI,EACJ,OAAO,EACP,gBAAgB,EAChB,eAAe,EACf,WAAW,GAAG,IAAI,EAClB,SAAS,GACoC;IAC7C,OAAO,CACL,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,eAAe,IAAI,MAAM,CAAC,kBAAkB,CAAC,EAAE,SAAS,CAAC;QAC1G,IAAI,IAAI,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,IAAG,IAAI,CAAO;QAC1E,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YAC/B,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,WAAW,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC;gBACjF,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,IAAG,OAAO,CAAO;gBACzE,OAAO,IAAI,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,IAAG,OAAO,CAAO,CAClF;YACL,gBAAgB,IAAI,6BAAK,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,SAAS,CAAC,IAAG,gBAAgB,CAAO,CACxG,CACF,CACP,CAAC;AACJ,CAAC","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 { StructuredItemProps } from './interfaces';\n\nimport styles from './styles.css.js';\nimport testClasses from './test-classes/styles.css.js';\n\nexport { StructuredItemProps };\n\nexport default function InternalStructuredItem({\n content,\n icon,\n actions,\n secondaryContent,\n disablePaddings,\n wrapActions = true,\n className,\n}: StructuredItemProps & { className?: string }) {\n return (\n <div className={clsx(styles.root, testClasses.root, disablePaddings && styles['disable-paddings'], className)}>\n {icon && <div className={clsx(styles.icon, testClasses.icon)}>{icon}</div>}\n <div className={clsx(styles.main)}>\n <div className={clsx(styles['content-wrap'], wrapActions && styles['wrap-actions'])}>\n <div className={clsx(styles.content, testClasses.content)}>{content}</div>\n {actions && <div className={clsx(styles.actions, testClasses.actions)}>{actions}</div>}\n </div>\n {secondaryContent && <div className={clsx(styles.secondary, testClasses.secondary)}>{secondaryContent}</div>}\n </div>\n </div>\n );\n}\n"]}
|
package/internal/environment.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export var PACKAGE_SOURCE = "components";
|
|
2
|
-
export var PACKAGE_VERSION = "3.0.0 (
|
|
3
|
-
export var GIT_SHA = "
|
|
2
|
+
export var PACKAGE_VERSION = "3.0.0 (eae5d559)";
|
|
3
|
+
export var GIT_SHA = "eae5d559";
|
|
4
4
|
export var THEME = "open-source-visual-refresh";
|
|
5
5
|
export var SYSTEM = "console";
|
|
6
6
|
export var ALWAYS_VISUAL_REFRESH = true;
|
package/internal/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
"./internal/base-component/index.js",
|
|
152
152
|
"./internal/base-component/styles.css.js"
|
|
153
153
|
],
|
|
154
|
-
"version": "3.0.
|
|
154
|
+
"version": "3.0.1099",
|
|
155
155
|
"repository": {
|
|
156
156
|
"type": "git",
|
|
157
157
|
"url": "https://github.com/cloudscape-design/components.git"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../../src/tree-view/internal.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../../src/tree-view/internal.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQ7C,KAAK,qBAAqB,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,0BAA0B,CAAC;AAE9E,QAAA,MAAM,gBAAgB,kQAqErB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
package/tree-view/internal.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
import React from 'react';
|
|
4
|
+
import React, { useRef } from 'react';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { getBaseProps } from '../internal/base-component';
|
|
7
7
|
import { fireNonCancelableEvent } from '../internal/events';
|
|
8
8
|
import { useControllable } from '../internal/hooks/use-controllable';
|
|
9
|
+
import { KeyboardNavigationProvider } from './keyboard-navigation';
|
|
9
10
|
import InternalTreeItem from './tree-item';
|
|
11
|
+
import { getAllVisibleItemsIndices } from './utils';
|
|
10
12
|
import styles from './styles.css.js';
|
|
11
13
|
import testUtilStyles from './test-classes/styles.css.js';
|
|
12
14
|
const InternalTreeView = (_a) => {
|
|
@@ -17,6 +19,8 @@ const InternalTreeView = (_a) => {
|
|
|
17
19
|
controlledProp: 'expandedItems',
|
|
18
20
|
changeHandler: 'onItemToggle',
|
|
19
21
|
});
|
|
22
|
+
const treeViewRefObject = useRef(null);
|
|
23
|
+
const allVisibleItemsIndices = getAllVisibleItemsIndices({ items, expandedItems, getItemId, getItemChildren });
|
|
20
24
|
const onToggle = ({ id, item, expanded }) => {
|
|
21
25
|
if (expanded) {
|
|
22
26
|
setExpandedItems([...(expandedItems || []), id]);
|
|
@@ -27,9 +31,11 @@ const InternalTreeView = (_a) => {
|
|
|
27
31
|
fireNonCancelableEvent(onItemToggle, { id, item, expanded });
|
|
28
32
|
};
|
|
29
33
|
return (React.createElement("div", Object.assign({}, baseProps, { ref: __internalRootRef, className: clsx(baseProps.className, styles.root, testUtilStyles.root) }),
|
|
30
|
-
React.createElement(
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
React.createElement(KeyboardNavigationProvider, { getTreeView: () => treeViewRefObject.current },
|
|
35
|
+
React.createElement("ul", { role: "tree", ref: treeViewRefObject, className: clsx(styles.tree, testUtilStyles.tree), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby }, items.map((item, index) => {
|
|
36
|
+
const itemId = getItemId(item, index);
|
|
37
|
+
return (React.createElement(InternalTreeItem, { key: itemId, item: item, level: 1, index: index, expandedItems: expandedItems, i18nStrings: i18nStrings, onItemToggle: onToggle, renderItem: renderItem, getItemId: getItemId, getItemChildren: getItemChildren, renderItemToggleIcon: renderItemToggleIcon, allVisibleItemsIndices: allVisibleItemsIndices }));
|
|
38
|
+
})))));
|
|
33
39
|
};
|
|
34
40
|
export default InternalTreeView;
|
|
35
41
|
//# sourceMappingURL=internal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../../../src/tree-view/internal.tsx"],"names":[],"mappings":";AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../../../src/tree-view/internal.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 clsx from 'clsx';\n\nimport { getBaseProps } from '../internal/base-component';\nimport { fireNonCancelableEvent } from '../internal/events';\nimport { InternalBaseComponentProps } from '../internal/hooks/use-base-component';\nimport { useControllable } from '../internal/hooks/use-controllable';\nimport { TreeViewProps } from './interfaces';\nimport { KeyboardNavigationProvider } from './keyboard-navigation';\nimport InternalTreeItem from './tree-item';\nimport { getAllVisibleItemsIndices } from './utils';\n\nimport styles from './styles.css.js';\nimport testUtilStyles from './test-classes/styles.css.js';\n\ntype InternalTreeViewProps<T> = TreeViewProps<T> & InternalBaseComponentProps;\n\nconst InternalTreeView = <T,>({\n expandedItems: controlledExpandedItems,\n items,\n renderItem,\n getItemId,\n getItemChildren,\n onItemToggle,\n renderItemToggleIcon,\n ariaLabel,\n ariaLabelledby,\n ariaDescribedby,\n i18nStrings,\n __internalRootRef,\n ...rest\n}: InternalTreeViewProps<T>) => {\n const baseProps = getBaseProps(rest);\n\n const [expandedItems, setExpandedItems] = useControllable(controlledExpandedItems, onItemToggle, [], {\n componentName: 'TreeView',\n controlledProp: 'expandedItems',\n changeHandler: 'onItemToggle',\n });\n const treeViewRefObject = useRef(null);\n\n const allVisibleItemsIndices = getAllVisibleItemsIndices({ items, expandedItems, getItemId, getItemChildren });\n\n const onToggle = ({ id, item, expanded }: TreeViewProps.ItemToggleDetail<T>) => {\n if (expanded) {\n setExpandedItems([...(expandedItems || []), id]);\n } else {\n setExpandedItems((expandedItems || []).filter(expandedId => expandedId !== id));\n }\n fireNonCancelableEvent(onItemToggle, { id, item, expanded });\n };\n\n return (\n <div {...baseProps} ref={__internalRootRef} className={clsx(baseProps.className, styles.root, testUtilStyles.root)}>\n <KeyboardNavigationProvider getTreeView={() => treeViewRefObject.current}>\n <ul\n role=\"tree\"\n ref={treeViewRefObject}\n className={clsx(styles.tree, testUtilStyles.tree)}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-describedby={ariaDescribedby}\n >\n {items.map((item, index) => {\n const itemId = getItemId(item, index);\n return (\n <InternalTreeItem<T>\n key={itemId}\n item={item}\n level={1}\n index={index}\n expandedItems={expandedItems}\n i18nStrings={i18nStrings}\n onItemToggle={onToggle}\n renderItem={renderItem}\n getItemId={getItemId}\n getItemChildren={getItemChildren}\n renderItemToggleIcon={renderItemToggleIcon}\n allVisibleItemsIndices={allVisibleItemsIndices}\n />\n );\n })}\n </ul>\n </KeyboardNavigationProvider>\n </div>\n );\n};\n\nexport default InternalTreeView;\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SingleTabStopNavigationAPI } from '@cloudscape-design/component-toolkit/internal';
|
|
3
|
+
export declare function KeyboardNavigationProvider({
|
|
4
|
+
getTreeView,
|
|
5
|
+
children
|
|
6
|
+
}: {
|
|
7
|
+
getTreeView: () => null | HTMLUListElement;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}): JSX.Element;
|
|
10
|
+
export declare class KeyboardNavigationProcessor {
|
|
11
|
+
private _treeView;
|
|
12
|
+
private _navigationAPI;
|
|
13
|
+
private focusedTreeItem;
|
|
14
|
+
constructor(navigationAPI: {
|
|
15
|
+
current: null | SingleTabStopNavigationAPI;
|
|
16
|
+
});
|
|
17
|
+
init(treeView: HTMLUListElement): void;
|
|
18
|
+
cleanup: () => void;
|
|
19
|
+
refresh(): void;
|
|
20
|
+
onUnregisterActive: () => void;
|
|
21
|
+
getNextFocusTarget: () => HTMLElement | null;
|
|
22
|
+
private get treeView();
|
|
23
|
+
private getFocusablesFrom;
|
|
24
|
+
private isRegistered;
|
|
25
|
+
private updateFocusedTreeItem;
|
|
26
|
+
private onFocusin;
|
|
27
|
+
private onKeydown;
|
|
28
|
+
private getNextFocusableTreeItem;
|
|
29
|
+
private moveFocusInsideTreeItem;
|
|
30
|
+
private moveFocusBetweenTreeItems;
|
|
31
|
+
private moveFocusToTheLastElementInsideTreeItem;
|
|
32
|
+
private getNextFocusableTreeItemContent;
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tree-view/keyboard-navigation/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,OAAO,EACL,0BAA0B,EAE3B,MAAM,+CAA+C,CAAC;AAiBvD,wBAAgB,0BAA0B,CAAC,EACzC,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,MAAM,IAAI,GAAG,gBAAgB,CAAC;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,eA+BA;AASD,qBAAa,2BAA2B;IAEtC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,cAAc,CAAiD;IAGvE,OAAO,CAAC,eAAe,CAAgC;gBAE3C,aAAa,EAAE;QAAE,OAAO,EAAE,IAAI,GAAG,0BAA0B,CAAA;KAAE;IAIlE,IAAI,CAAC,QAAQ,EAAE,gBAAgB;IAY/B,OAAO,aAEZ;IAEK,OAAO;IAWP,kBAAkB,aAYvB;IAEK,kBAAkB,2BAkBvB;IAEF,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,SAAS,CAWf;IAEF,OAAO,CAAC,SAAS,CA0Cf;IAEF,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,uCAAuC;IAiB/C,OAAO,CAAC,+BAA+B;CA0BxC"}
|
|
@@ -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,6 @@
|
|
|
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;
|
|
@@ -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"]}
|
package/tree-view/styles.css.js
CHANGED
|
@@ -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
|
-
.
|
|
181
|
+
.awsui_root_18gnm_js2fw_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-pfm1nx, 4px);
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
.
|
|
218
|
+
.awsui_tree_18gnm_js2fw_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": "
|
|
6
|
-
"tree": "
|
|
5
|
+
"root": "awsui_root_18gnm_js2fw_181",
|
|
6
|
+
"tree": "awsui_tree_18gnm_js2fw_218"
|
|
7
7
|
};
|
|
8
8
|
|
|
@@ -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,6 +5,9 @@ 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
12
|
declare const InternalTreeItem: <T>({
|
|
10
13
|
item,
|
|
@@ -16,6 +19,7 @@ declare const InternalTreeItem: <T>({
|
|
|
16
19
|
renderItem,
|
|
17
20
|
getItemId,
|
|
18
21
|
getItemChildren,
|
|
19
|
-
onItemToggle
|
|
22
|
+
onItemToggle,
|
|
23
|
+
allVisibleItemsIndices
|
|
20
24
|
}: InternalTreeItemProps<T>) => JSX.Element;
|
|
21
25
|
export default InternalTreeItem;
|
|
@@ -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;
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
isExpanded && children.length && (React.createElement("ul", { className: styles['treeitem-group'] }, children.map((child, index) => {
|
|
36
|
-
|
|
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":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,sBAAsB,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
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-
|
|
5
|
-
"treeitem": "
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
4
|
+
"treeitem-group": "awsui_treeitem-group_1agpu_c0siv_185",
|
|
5
|
+
"treeitem": "awsui_treeitem_1agpu_c0siv_185",
|
|
6
|
+
"offset": "awsui_offset_1agpu_c0siv_202",
|
|
7
|
+
"treeitem-content-wrapper": "awsui_treeitem-content-wrapper_1agpu_c0siv_205",
|
|
8
|
+
"tree-item-focus-target": "awsui_tree-item-focus-target_1agpu_c0siv_210",
|
|
9
|
+
"expand-toggle-wrapper": "awsui_expand-toggle-wrapper_1agpu_c0siv_231",
|
|
10
|
+
"toggle": "awsui_toggle_1agpu_c0siv_236",
|
|
11
|
+
"structured-item-wrapper": "awsui_structured-item-wrapper_1agpu_c0siv_241",
|
|
12
|
+
"tree-item-structured-item": "awsui_tree-item-structured-item_1agpu_c0siv_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
|
-
|
|
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_c0siv_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
|
-
.
|
|
194
|
+
.awsui_treeitem_1agpu_c0siv_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
|
-
|
|
200
|
+
position: relative;
|
|
201
|
+
}
|
|
202
|
+
.awsui_treeitem_1agpu_c0siv_185.awsui_offset_1agpu_c0siv_202:not(#\9) {
|
|
203
|
+
margin-inline-start: 28px;
|
|
204
|
+
}
|
|
205
|
+
.awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205:not(#\9) {
|
|
194
206
|
display: grid;
|
|
195
207
|
grid-template-columns: 28px 1fr;
|
|
196
|
-
|
|
208
|
+
align-items: baseline;
|
|
209
|
+
}
|
|
210
|
+
body[data-awsui-focus-visible=true] .awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205:not(#\9):has(.awsui_tree-item-focus-target_1agpu_c0siv_210:focus) {
|
|
211
|
+
position: relative;
|
|
212
|
+
}
|
|
213
|
+
body[data-awsui-focus-visible=true] .awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205:not(#\9):has(.awsui_tree-item-focus-target_1agpu_c0siv_210:focus) {
|
|
214
|
+
outline: 2px dotted transparent;
|
|
215
|
+
outline-offset: calc(0px - 1px);
|
|
197
216
|
}
|
|
198
|
-
.
|
|
217
|
+
body[data-awsui-focus-visible=true] .awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205:not(#\9):has(.awsui_tree-item-focus-target_1agpu_c0siv_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-1uabki, 4px);
|
|
226
|
+
border-start-end-radius: var(--border-radius-control-default-focus-ring-1uabki, 4px);
|
|
227
|
+
border-end-start-radius: var(--border-radius-control-default-focus-ring-1uabki, 4px);
|
|
228
|
+
border-end-end-radius: var(--border-radius-control-default-focus-ring-1uabki, 4px);
|
|
229
|
+
box-shadow: 0 0 0 2px var(--color-border-item-focused-uk47pl, #006ce0);
|
|
230
|
+
}
|
|
231
|
+
.awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205 > .awsui_expand-toggle-wrapper_1agpu_c0siv_231:not(#\9) {
|
|
199
232
|
grid-column: 1;
|
|
200
233
|
grid-row: 1;
|
|
201
|
-
|
|
234
|
+
padding-inline-end: var(--space-scaled-xxs-pfm1nx, 4px);
|
|
202
235
|
}
|
|
203
|
-
.
|
|
236
|
+
.awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205 > .awsui_expand-toggle-wrapper_1agpu_c0siv_231 > .awsui_toggle_1agpu_c0siv_236:not(#\9) {
|
|
204
237
|
justify-self: center;
|
|
205
238
|
position: relative;
|
|
206
239
|
inset-block-start: 2px;
|
|
207
240
|
}
|
|
208
|
-
.
|
|
241
|
+
.awsui_treeitem_1agpu_c0siv_185 > .awsui_treeitem-content-wrapper_1agpu_c0siv_205 > .awsui_structured-item-wrapper_1agpu_c0siv_241:not(#\9) {
|
|
209
242
|
grid-column: 2;
|
|
210
243
|
grid-row: 1/span 2;
|
|
211
244
|
padding-block: var(--space-scaled-xxs-pfm1nx, 4px);
|
|
245
|
+
position: relative;
|
|
212
246
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
247
|
+
|
|
248
|
+
.awsui_tree-item-structured-item_1agpu_c0siv_248:not(#\9),
|
|
249
|
+
.awsui_tree-item-focus-target_1agpu_c0siv_210:not(#\9) {
|
|
250
|
+
/* used in keyboard navigation */
|
|
216
251
|
}
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
// es-module interop with Babel and Typescript
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
module.exports.default = {
|
|
5
|
-
"treeitem-group": "awsui_treeitem-
|
|
6
|
-
"treeitem": "
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
5
|
+
"treeitem-group": "awsui_treeitem-group_1agpu_c0siv_185",
|
|
6
|
+
"treeitem": "awsui_treeitem_1agpu_c0siv_185",
|
|
7
|
+
"offset": "awsui_offset_1agpu_c0siv_202",
|
|
8
|
+
"treeitem-content-wrapper": "awsui_treeitem-content-wrapper_1agpu_c0siv_205",
|
|
9
|
+
"tree-item-focus-target": "awsui_tree-item-focus-target_1agpu_c0siv_210",
|
|
10
|
+
"expand-toggle-wrapper": "awsui_expand-toggle-wrapper_1agpu_c0siv_231",
|
|
11
|
+
"toggle": "awsui_toggle_1agpu_c0siv_236",
|
|
12
|
+
"structured-item-wrapper": "awsui_structured-item-wrapper_1agpu_c0siv_241",
|
|
13
|
+
"tree-item-structured-item": "awsui_tree-item-structured-item_1agpu_c0siv_248"
|
|
10
14
|
};
|
|
11
15
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface IndicesByItemId {
|
|
2
|
+
[key: string]: number;
|
|
3
|
+
}
|
|
4
|
+
export declare function getAllVisibleItemsIndices<T>({
|
|
5
|
+
items,
|
|
6
|
+
expandedItems,
|
|
7
|
+
getItemId,
|
|
8
|
+
getItemChildren
|
|
9
|
+
}: {
|
|
10
|
+
items: ReadonlyArray<T>;
|
|
11
|
+
expandedItems?: ReadonlyArray<string>;
|
|
12
|
+
getItemId: (item: T, index: number) => string;
|
|
13
|
+
getItemChildren: (item: T, index: number) => ReadonlyArray<T> | undefined;
|
|
14
|
+
}): IndicesByItemId;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tree-view/utils.ts"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAGD,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,EAC3C,KAAK,EACL,aAAa,EACb,SAAS,EACT,eAAe,GAChB,EAAE;IACD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CAC3E,mBAoBA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// Flattens the items and assigns indices in ascending order for keyboard navigation
|
|
4
|
+
export function getAllVisibleItemsIndices({ items, expandedItems, getItemId, getItemChildren, }) {
|
|
5
|
+
const allIndicesByItemId = {};
|
|
6
|
+
let currentIndex = 0;
|
|
7
|
+
const traverse = (item, index) => {
|
|
8
|
+
const itemId = getItemId(item, index);
|
|
9
|
+
const children = getItemChildren(item, index);
|
|
10
|
+
allIndicesByItemId[itemId] = currentIndex;
|
|
11
|
+
currentIndex += 1;
|
|
12
|
+
const isExpanded = children && children.length > 0 && (expandedItems === null || expandedItems === void 0 ? void 0 : expandedItems.includes(itemId));
|
|
13
|
+
if (isExpanded) {
|
|
14
|
+
children.forEach((child, index) => traverse(child, index));
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
items.forEach((item, index) => traverse(item, index));
|
|
18
|
+
return allIndicesByItemId;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/tree-view/utils.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAMtC,oFAAoF;AACpF,MAAM,UAAU,yBAAyB,CAAI,EAC3C,KAAK,EACL,aAAa,EACb,SAAS,EACT,eAAe,GAMhB;IACC,MAAM,kBAAkB,GAAoB,EAAE,CAAC;IAC/C,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,MAAM,QAAQ,GAAG,CAAC,IAAO,EAAE,KAAa,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE9C,kBAAkB,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;QAC1C,YAAY,IAAI,CAAC,CAAC;QAElB,MAAM,UAAU,GAAG,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,KAAI,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,QAAQ,CAAC,MAAM,CAAC,CAAA,CAAC;QACtF,IAAI,UAAU,EAAE;YACd,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;SAC5D;IACH,CAAC,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtD,OAAO,kBAAkB,CAAC;AAC5B,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\ninterface IndicesByItemId {\n [key: string]: number;\n}\n\n// Flattens the items and assigns indices in ascending order for keyboard navigation\nexport function getAllVisibleItemsIndices<T>({\n items,\n expandedItems,\n getItemId,\n getItemChildren,\n}: {\n items: ReadonlyArray<T>;\n expandedItems?: ReadonlyArray<string>;\n getItemId: (item: T, index: number) => string;\n getItemChildren: (item: T, index: number) => ReadonlyArray<T> | undefined;\n}) {\n const allIndicesByItemId: IndicesByItemId = {};\n let currentIndex = 0;\n\n const traverse = (item: T, index: number) => {\n const itemId = getItemId(item, index);\n const children = getItemChildren(item, index);\n\n allIndicesByItemId[itemId] = currentIndex;\n currentIndex += 1;\n\n const isExpanded = children && children.length > 0 && expandedItems?.includes(itemId);\n if (isExpanded) {\n children.forEach((child, index) => traverse(child, index));\n }\n };\n\n items.forEach((item, index) => traverse(item, index));\n\n return allIndicesByItemId;\n}\n"]}
|