@cloudscape-design/components-themeable 3.0.747 → 3.0.749
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/lib/internal/manifest.json +1 -1
- package/lib/internal/scss/table/body-cell/styles.scss +9 -4
- package/lib/internal/scss/table/header-cell/styles.scss +11 -8
- package/lib/internal/template/file-upload/internal.d.ts.map +1 -1
- package/lib/internal/template/file-upload/internal.js +15 -8
- package/lib/internal/template/file-upload/internal.js.map +1 -1
- package/lib/internal/template/internal/components/focus-lock/utils.d.ts +1 -0
- package/lib/internal/template/internal/components/focus-lock/utils.d.ts.map +1 -1
- package/lib/internal/template/internal/components/focus-lock/utils.js +3 -0
- package/lib/internal/template/internal/components/focus-lock/utils.js.map +1 -1
- package/lib/internal/template/internal/components/token-list/index.d.ts +1 -1
- package/lib/internal/template/internal/components/token-list/index.d.ts.map +1 -1
- package/lib/internal/template/internal/components/token-list/index.js +3 -5
- package/lib/internal/template/internal/components/token-list/index.js.map +1 -1
- package/lib/internal/template/internal/components/token-list/interfaces.d.ts +0 -1
- package/lib/internal/template/internal/components/token-list/interfaces.d.ts.map +1 -1
- package/lib/internal/template/internal/components/token-list/interfaces.js.map +1 -1
- package/lib/internal/template/internal/environment.js +1 -1
- package/lib/internal/template/internal/environment.json +1 -1
- package/lib/internal/template/internal/hooks/use-list-focus-controller.d.ts +11 -0
- package/lib/internal/template/internal/hooks/use-list-focus-controller.d.ts.map +1 -0
- package/lib/internal/template/internal/hooks/use-list-focus-controller.js +62 -0
- package/lib/internal/template/internal/hooks/use-list-focus-controller.js.map +1 -0
- package/lib/internal/template/internal/plugins/controllers/app-layout-widget.js +1 -1
- package/lib/internal/template/internal/plugins/controllers/app-layout-widget.js.map +1 -1
- package/lib/internal/template/property-filter/filtering-token/index.d.ts.map +1 -1
- package/lib/internal/template/property-filter/filtering-token/index.js +20 -6
- package/lib/internal/template/property-filter/filtering-token/index.js.map +1 -1
- package/lib/internal/template/property-filter/internal.d.ts.map +1 -1
- package/lib/internal/template/property-filter/internal.js +16 -6
- package/lib/internal/template/property-filter/internal.js.map +1 -1
- package/lib/internal/template/property-filter/token-editor.d.ts.map +1 -1
- package/lib/internal/template/property-filter/token-editor.js +18 -3
- package/lib/internal/template/property-filter/token-editor.js.map +1 -1
- package/lib/internal/template/space-between/internal.d.ts +3 -4
- package/lib/internal/template/space-between/internal.d.ts.map +1 -1
- package/lib/internal/template/space-between/internal.js +9 -6
- package/lib/internal/template/space-between/internal.js.map +1 -1
- package/lib/internal/template/table/body-cell/styles.css.js +47 -47
- package/lib/internal/template/table/body-cell/styles.scoped.css +394 -311
- package/lib/internal/template/table/body-cell/styles.selectors.js +47 -47
- package/lib/internal/template/table/header-cell/styles.css.js +26 -26
- package/lib/internal/template/table/header-cell/styles.scoped.css +72 -72
- package/lib/internal/template/table/header-cell/styles.selectors.js +26 -26
- package/lib/internal/template/token-group/internal.d.ts.map +1 -1
- package/lib/internal/template/token-group/internal.js +17 -6
- package/lib/internal/template/token-group/internal.js.map +1 -1
- package/package.json +1 -1
- package/lib/internal/template/internal/components/token-list/token-focus-controller.d.ts +0 -5
- package/lib/internal/template/internal/components/token-list/token-focus-controller.d.ts.map +0 -1
- package/lib/internal/template/internal/components/token-list/token-focus-controller.js +0 -43
- package/lib/internal/template/internal/components/token-list/token-focus-controller.js.map +0 -1
|
@@ -8,25 +8,36 @@ import Option from '../internal/components/option';
|
|
|
8
8
|
import TokenList from '../internal/components/token-list';
|
|
9
9
|
import { fireNonCancelableEvent } from '../internal/events';
|
|
10
10
|
import checkControlled from '../internal/hooks/check-controlled';
|
|
11
|
+
import { useListFocusController } from '../internal/hooks/use-list-focus-controller';
|
|
12
|
+
import { useMergeRefs } from '../internal/hooks/use-merge-refs';
|
|
11
13
|
import { Token } from './token';
|
|
14
|
+
import tokenListStyles from '../internal/components/token-list/styles.css.js';
|
|
12
15
|
import styles from './styles.css.js';
|
|
13
16
|
export default function InternalTokenGroup(_a) {
|
|
14
17
|
var { alignment, items, onDismiss, limit, i18nStrings, disableOuterPadding, limitShowFewerAriaLabel, limitShowMoreAriaLabel, readOnly, __internalRootRef } = _a, props = __rest(_a, ["alignment", "items", "onDismiss", "limit", "i18nStrings", "disableOuterPadding", "limitShowFewerAriaLabel", "limitShowMoreAriaLabel", "readOnly", "__internalRootRef"]);
|
|
15
18
|
checkControlled('TokenGroup', 'items', items, 'onDismiss', onDismiss);
|
|
16
|
-
const [
|
|
19
|
+
const [nextFocusIndex, setNextFocusIndex] = useState(null);
|
|
20
|
+
const onFocusMoved = () => setNextFocusIndex(null);
|
|
21
|
+
const tokenListRef = useListFocusController({
|
|
22
|
+
nextFocusIndex,
|
|
23
|
+
onFocusMoved,
|
|
24
|
+
listItemSelector: `.${tokenListStyles['list-item']}`,
|
|
25
|
+
showMoreSelector: `.${tokenListStyles.toggle}`,
|
|
26
|
+
});
|
|
17
27
|
const baseProps = getBaseProps(props);
|
|
18
28
|
const hasItems = items.length > 0;
|
|
19
|
-
|
|
29
|
+
const mergedRef = useMergeRefs(__internalRootRef, tokenListRef);
|
|
30
|
+
return (React.createElement("div", Object.assign({}, baseProps, { className: clsx(baseProps.className, styles.root, hasItems && styles['has-items'], disableOuterPadding && styles['no-padding']), ref: mergedRef }),
|
|
20
31
|
React.createElement(TokenList, { alignment: alignment, items: items, limit: limit, renderItem: (item, itemIndex) => (React.createElement(Token, { ariaLabel: item.label, dismissLabel: item.dismissLabel, onDismiss: () => {
|
|
21
32
|
fireNonCancelableEvent(onDismiss, { itemIndex });
|
|
22
|
-
|
|
33
|
+
setNextFocusIndex(itemIndex);
|
|
23
34
|
}, disabled: item.disabled, readOnly: readOnly },
|
|
24
|
-
React.createElement(Option, { option: item, isGenericGroup: false }))), i18nStrings: i18nStrings, limitShowFewerAriaLabel: limitShowFewerAriaLabel, limitShowMoreAriaLabel: limitShowMoreAriaLabel,
|
|
35
|
+
React.createElement(Option, { option: item, isGenericGroup: false }))), i18nStrings: i18nStrings, limitShowFewerAriaLabel: limitShowFewerAriaLabel, limitShowMoreAriaLabel: limitShowMoreAriaLabel, onExpandedClick: isExpanded => {
|
|
25
36
|
if (isExpanded && limit) {
|
|
26
|
-
|
|
37
|
+
setNextFocusIndex(limit);
|
|
27
38
|
}
|
|
28
39
|
else {
|
|
29
|
-
|
|
40
|
+
setNextFocusIndex(null);
|
|
30
41
|
}
|
|
31
42
|
} })));
|
|
32
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../../../src/token-group/internal.tsx"],"names":[],"mappings":";AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,MAAM,MAAM,+BAA+B,CAAC;AACnD,OAAO,SAAS,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,eAAe,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../../../src/token-group/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, { useState } from 'react';\nimport clsx from 'clsx';\n\nimport { getBaseProps } from '../internal/base-component';\nimport Option from '../internal/components/option';\nimport TokenList from '../internal/components/token-list';\nimport { fireNonCancelableEvent } from '../internal/events';\nimport checkControlled from '../internal/hooks/check-controlled';\nimport { InternalBaseComponentProps } from '../internal/hooks/use-base-component';\nimport { useListFocusController } from '../internal/hooks/use-list-focus-controller';\nimport { useMergeRefs } from '../internal/hooks/use-merge-refs';\nimport { SomeRequired } from '../internal/types';\nimport { TokenGroupProps } from './interfaces';\nimport { Token } from './token';\n\nimport tokenListStyles from '../internal/components/token-list/styles.css.js';\nimport styles from './styles.css.js';\n\ntype InternalTokenGroupProps = SomeRequired<TokenGroupProps, 'items' | 'alignment'> & InternalBaseComponentProps;\n\nexport default function InternalTokenGroup({\n alignment,\n items,\n onDismiss,\n limit,\n i18nStrings,\n disableOuterPadding,\n limitShowFewerAriaLabel,\n limitShowMoreAriaLabel,\n readOnly,\n __internalRootRef,\n ...props\n}: InternalTokenGroupProps) {\n checkControlled('TokenGroup', 'items', items, 'onDismiss', onDismiss);\n\n const [nextFocusIndex, setNextFocusIndex] = useState<null | number>(null);\n const onFocusMoved = () => setNextFocusIndex(null);\n const tokenListRef = useListFocusController({\n nextFocusIndex,\n onFocusMoved,\n listItemSelector: `.${tokenListStyles['list-item']}`,\n showMoreSelector: `.${tokenListStyles.toggle}`,\n });\n\n const baseProps = getBaseProps(props);\n const hasItems = items.length > 0;\n const mergedRef = useMergeRefs(__internalRootRef, tokenListRef);\n return (\n <div\n {...baseProps}\n className={clsx(\n baseProps.className,\n styles.root,\n hasItems && styles['has-items'],\n disableOuterPadding && styles['no-padding']\n )}\n ref={mergedRef}\n >\n <TokenList\n alignment={alignment}\n items={items}\n limit={limit}\n renderItem={(item, itemIndex) => (\n <Token\n ariaLabel={item.label}\n dismissLabel={item.dismissLabel}\n onDismiss={() => {\n fireNonCancelableEvent(onDismiss, { itemIndex });\n setNextFocusIndex(itemIndex);\n }}\n disabled={item.disabled}\n readOnly={readOnly}\n >\n <Option option={item} isGenericGroup={false} />\n </Token>\n )}\n i18nStrings={i18nStrings}\n limitShowFewerAriaLabel={limitShowFewerAriaLabel}\n limitShowMoreAriaLabel={limitShowMoreAriaLabel}\n onExpandedClick={isExpanded => {\n if (isExpanded && limit) {\n setNextFocusIndex(limit);\n } else {\n setNextFocusIndex(null);\n }\n }}\n />\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED
package/lib/internal/template/internal/components/token-list/token-focus-controller.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-focus-controller.d.ts","sourceRoot":"","sources":["../../../../../src/internal/components/token-list/token-focus-controller.tsx"],"names":[],"mappings":";AAYA,wBAAgB,uBAAuB,CAAC,EAAE,oBAAoB,EAAE,EAAE;IAAE,oBAAoB,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,6CAqCzG"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { useEffect, useRef } from 'react';
|
|
4
|
-
import { getFirstFocusable } from '../focus-lock/utils.js';
|
|
5
|
-
import styles from './styles.css.js';
|
|
6
|
-
const tokenSelector = `.${styles['list-item']}`;
|
|
7
|
-
const toggleButtonSelector = `.${styles.toggle}`;
|
|
8
|
-
export function useTokenFocusController({ moveFocusNextToIndex }) {
|
|
9
|
-
const tokenListRef = useRef(null);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
var _a, _b;
|
|
12
|
-
if (moveFocusNextToIndex === undefined || moveFocusNextToIndex === null || tokenListRef.current === null) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const tokenElements = tokenListRef.current.querySelectorAll(tokenSelector);
|
|
16
|
-
const toggleButton = tokenListRef.current.querySelector(toggleButtonSelector);
|
|
17
|
-
let closestPrevIndex = Number.NEGATIVE_INFINITY;
|
|
18
|
-
let closestNextIndex = Number.POSITIVE_INFINITY;
|
|
19
|
-
for (let activeIndex = 0; activeIndex < tokenElements.length; activeIndex++) {
|
|
20
|
-
if (activeIndex < moveFocusNextToIndex) {
|
|
21
|
-
closestPrevIndex =
|
|
22
|
-
moveFocusNextToIndex - activeIndex < moveFocusNextToIndex - closestPrevIndex ? activeIndex : closestPrevIndex;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
closestNextIndex =
|
|
26
|
-
activeIndex - moveFocusNextToIndex < closestNextIndex - moveFocusNextToIndex ? activeIndex : closestNextIndex;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
const nextElement = tokenElements[closestNextIndex];
|
|
30
|
-
const prevElement = tokenElements[closestPrevIndex];
|
|
31
|
-
if (nextElement instanceof HTMLElement) {
|
|
32
|
-
(_a = getFirstFocusable(nextElement)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
33
|
-
}
|
|
34
|
-
else if (prevElement instanceof HTMLElement) {
|
|
35
|
-
(_b = getFirstFocusable(prevElement)) === null || _b === void 0 ? void 0 : _b.focus();
|
|
36
|
-
}
|
|
37
|
-
else if (toggleButton instanceof HTMLElement) {
|
|
38
|
-
toggleButton.focus();
|
|
39
|
-
}
|
|
40
|
-
}, [moveFocusNextToIndex]);
|
|
41
|
-
return tokenListRef;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=token-focus-controller.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-focus-controller.js","sourceRoot":"","sources":["../../../../../src/internal/components/token-list/token-focus-controller.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAErC,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;AAChD,MAAM,oBAAoB,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;AAEjD,MAAM,UAAU,uBAAuB,CAAC,EAAE,oBAAoB,EAA4C;IACxG,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAElD,SAAS,CAAC,GAAG,EAAE;;QACb,IAAI,oBAAoB,KAAK,SAAS,IAAI,oBAAoB,KAAK,IAAI,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,EAAE;YACxG,OAAO;SACR;QAED,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;QAE9E,IAAI,gBAAgB,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAChD,IAAI,gBAAgB,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAEhD,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;YAC3E,IAAI,WAAW,GAAG,oBAAoB,EAAE;gBACtC,gBAAgB;oBACd,oBAAoB,GAAG,WAAW,GAAG,oBAAoB,GAAG,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC;aACjH;iBAAM;gBACL,gBAAgB;oBACd,WAAW,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC;aACjH;SACF;QAED,MAAM,WAAW,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAEpD,IAAI,WAAW,YAAY,WAAW,EAAE;YACtC,MAAA,iBAAiB,CAAC,WAAW,CAAC,0CAAE,KAAK,EAAE,CAAC;SACzC;aAAM,IAAI,WAAW,YAAY,WAAW,EAAE;YAC7C,MAAA,iBAAiB,CAAC,WAAW,CAAC,0CAAE,KAAK,EAAE,CAAC;SACzC;aAAM,IAAI,YAAY,YAAY,WAAW,EAAE;YAC9C,YAAY,CAAC,KAAK,EAAE,CAAC;SACtB;IACH,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAE3B,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useEffect, useRef } from 'react';\n\nimport { getFirstFocusable } from '../focus-lock/utils.js';\n\nimport styles from './styles.css.js';\n\nconst tokenSelector = `.${styles['list-item']}`;\nconst toggleButtonSelector = `.${styles.toggle}`;\n\nexport function useTokenFocusController({ moveFocusNextToIndex }: { moveFocusNextToIndex?: null | number }) {\n const tokenListRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (moveFocusNextToIndex === undefined || moveFocusNextToIndex === null || tokenListRef.current === null) {\n return;\n }\n\n const tokenElements = tokenListRef.current.querySelectorAll(tokenSelector);\n const toggleButton = tokenListRef.current.querySelector(toggleButtonSelector);\n\n let closestPrevIndex = Number.NEGATIVE_INFINITY;\n let closestNextIndex = Number.POSITIVE_INFINITY;\n\n for (let activeIndex = 0; activeIndex < tokenElements.length; activeIndex++) {\n if (activeIndex < moveFocusNextToIndex) {\n closestPrevIndex =\n moveFocusNextToIndex - activeIndex < moveFocusNextToIndex - closestPrevIndex ? activeIndex : closestPrevIndex;\n } else {\n closestNextIndex =\n activeIndex - moveFocusNextToIndex < closestNextIndex - moveFocusNextToIndex ? activeIndex : closestNextIndex;\n }\n }\n\n const nextElement = tokenElements[closestNextIndex];\n const prevElement = tokenElements[closestPrevIndex];\n\n if (nextElement instanceof HTMLElement) {\n getFirstFocusable(nextElement)?.focus();\n } else if (prevElement instanceof HTMLElement) {\n getFirstFocusable(prevElement)?.focus();\n } else if (toggleButton instanceof HTMLElement) {\n toggleButton.focus();\n }\n }, [moveFocusNextToIndex]);\n\n return tokenListRef;\n}\n"]}
|