@cloudscape-design/components-themeable 3.0.1232 → 3.0.1233
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/internal/generated/custom-css-properties/index.scss +1 -1
- package/lib/internal/template/internal/base-component/styles.scoped.css +1 -1
- package/lib/internal/template/internal/environment.js +2 -2
- package/lib/internal/template/internal/environment.json +2 -2
- package/lib/internal/template/live-region/controller.d.ts +1 -1
- package/lib/internal/template/live-region/controller.d.ts.map +1 -1
- package/lib/internal/template/live-region/controller.js +17 -5
- package/lib/internal/template/live-region/controller.js.map +1 -1
- package/lib/internal/template/live-region/internal.js +4 -4
- package/lib/internal/template/live-region/internal.js.map +1 -1
- package/package.json +1 -1
|
@@ -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 (e658be3e)";
|
|
3
|
+
export var GIT_SHA = "e658be3e";
|
|
4
4
|
export var THEME = "open-source-visual-refresh";
|
|
5
5
|
export var SYSTEM = "core";
|
|
6
6
|
export var ALWAYS_VISUAL_REFRESH = true;
|
|
@@ -18,6 +18,7 @@ export declare class LiveRegionController {
|
|
|
18
18
|
private _element;
|
|
19
19
|
private _timeoutId;
|
|
20
20
|
private _lastAnnouncement;
|
|
21
|
+
private _contentChangedSinceLastAnnouncement;
|
|
21
22
|
private _addedTerminalPeriod;
|
|
22
23
|
private _nextAnnouncement;
|
|
23
24
|
constructor(politeness: 'polite' | 'assertive', delay?: number);
|
|
@@ -27,7 +28,6 @@ export declare class LiveRegionController {
|
|
|
27
28
|
destroy(): void;
|
|
28
29
|
announce({ message, forceReannounce }: {
|
|
29
30
|
message?: string;
|
|
30
|
-
delay?: number;
|
|
31
31
|
forceReannounce?: boolean;
|
|
32
32
|
}): void;
|
|
33
33
|
private _updateElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/live-region/controller.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,qBAAa,oBAAoB;
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/live-region/controller.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,qBAAa,oBAAoB;aAgBb,UAAU,EAAE,QAAQ,GAAG,WAAW;aAClC,KAAK;IAhBvB;;;;OAIG;IACH,OAAc,YAAY,SAAK;IAE/B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,oCAAoC,CAAS;IACrD,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,iBAAiB,CAAM;gBAGb,UAAU,EAAE,QAAQ,GAAG,WAAW,EAClC,KAAK,SAAoC;IAS3D;;OAEG;IACH,OAAO;IAQP,QAAQ,CAAC,EAAE,OAAO,EAAE,eAAuB,EAAE,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE;IA4B9F,OAAO,CAAC,cAAc;CAsBvB"}
|
|
@@ -14,6 +14,7 @@ export class LiveRegionController {
|
|
|
14
14
|
constructor(politeness, delay = LiveRegionController.defaultDelay) {
|
|
15
15
|
this.politeness = politeness;
|
|
16
16
|
this.delay = delay;
|
|
17
|
+
this._contentChangedSinceLastAnnouncement = false;
|
|
17
18
|
this._addedTerminalPeriod = false;
|
|
18
19
|
this._nextAnnouncement = '';
|
|
19
20
|
this._element = document.createElement('div');
|
|
@@ -34,13 +35,23 @@ export class LiveRegionController {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
announce({ message, forceReannounce = false }) {
|
|
38
|
+
var _a;
|
|
39
|
+
const trimmedMessage = (_a = message === null || message === void 0 ? void 0 : message.trim()) !== null && _a !== void 0 ? _a : '';
|
|
40
|
+
// If the message before and after the throttle period is the same, we shouldn't
|
|
41
|
+
// announce anything. But if the component was rerendered with different content
|
|
42
|
+
// in the meantime, it's an indication that state changed enough that the same
|
|
43
|
+
// message should be reannounced.
|
|
44
|
+
if (trimmedMessage !== this._lastAnnouncement) {
|
|
45
|
+
this._contentChangedSinceLastAnnouncement = true;
|
|
46
|
+
}
|
|
47
|
+
this._nextAnnouncement = trimmedMessage;
|
|
48
|
+
// We're done with internal state updates. If there's nothing to actually announce, bail.
|
|
37
49
|
if (!message) {
|
|
38
50
|
return;
|
|
39
51
|
}
|
|
40
|
-
|
|
52
|
+
// If the delay is 0, just skip the timeout shenanigans and update the
|
|
53
|
+
// element synchronously. Great for tests.
|
|
41
54
|
if (this.delay === 0 || forceReannounce) {
|
|
42
|
-
// If the delay is 0, just skip the timeout shenanigans and update the
|
|
43
|
-
// element synchronously. Great for tests.
|
|
44
55
|
return this._updateElement(forceReannounce);
|
|
45
56
|
}
|
|
46
57
|
if (this._timeoutId === undefined) {
|
|
@@ -55,7 +66,7 @@ export class LiveRegionController {
|
|
|
55
66
|
this._element.textContent = this._nextAnnouncement;
|
|
56
67
|
this._addedTerminalPeriod = false;
|
|
57
68
|
}
|
|
58
|
-
else if (forceReannounce) {
|
|
69
|
+
else if (forceReannounce || this._contentChangedSinceLastAnnouncement) {
|
|
59
70
|
// A (generally) safe way of forcing re-announcements is toggling the
|
|
60
71
|
// terminal period. If we only keep adding periods, it's going to be
|
|
61
72
|
// eventually interpreted as an ellipsis.
|
|
@@ -65,6 +76,7 @@ export class LiveRegionController {
|
|
|
65
76
|
// Track the announced text for deduplication.
|
|
66
77
|
this._lastAnnouncement = this._nextAnnouncement;
|
|
67
78
|
// Reset the state for the next announcement.
|
|
79
|
+
this._contentChangedSinceLastAnnouncement = false;
|
|
68
80
|
this._timeoutId = undefined;
|
|
69
81
|
}
|
|
70
82
|
}
|
|
@@ -73,5 +85,5 @@ export class LiveRegionController {
|
|
|
73
85
|
* During internal unit testing, you can import this and explicitly set it to
|
|
74
86
|
* 0 to make the live region update the DOM without waiting for a timer.
|
|
75
87
|
*/
|
|
76
|
-
LiveRegionController.defaultDelay =
|
|
88
|
+
LiveRegionController.defaultDelay = 1;
|
|
77
89
|
//# sourceMappingURL=controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../src/live-region/controller.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,cAAc,MAAM,8BAA8B,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,OAAO,oBAAoB;
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../src/live-region/controller.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport styles from './styles.css.js';\nimport testUtilStyles from './test-classes/styles.css.js';\n\n/**\n * The controller that manages a single live region container. It has a timer\n * to make sure announcements are throttled correctly. It can also make sure\n * that a message is announced again even if it matches the previous content\n * of the live region.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions\n */\nexport class LiveRegionController {\n /**\n * The default delay for announcements when no delay is explicitly provided.\n * During internal unit testing, you can import this and explicitly set it to\n * 0 to make the live region update the DOM without waiting for a timer.\n */\n public static defaultDelay = 1;\n\n private _element: HTMLElement;\n private _timeoutId: number | undefined;\n private _lastAnnouncement: string | undefined;\n private _contentChangedSinceLastAnnouncement = false;\n private _addedTerminalPeriod = false;\n private _nextAnnouncement = '';\n\n constructor(\n public readonly politeness: 'polite' | 'assertive',\n public readonly delay = LiveRegionController.defaultDelay\n ) {\n this._element = document.createElement('div');\n this._element.className = `${styles.announcer} ${testUtilStyles.announcer}`;\n this._element.setAttribute('aria-live', this.politeness);\n this._element.setAttribute('aria-atomic', 'true');\n document.body.appendChild(this._element);\n }\n\n /**\n * Reset the state of the controller and clear any active announcements.\n */\n destroy() {\n this._element?.remove();\n if (this._timeoutId !== undefined) {\n clearTimeout(this._timeoutId);\n this._timeoutId = undefined;\n }\n }\n\n announce({ message, forceReannounce = false }: { message?: string; forceReannounce?: boolean }) {\n const trimmedMessage = message?.trim() ?? '';\n\n // If the message before and after the throttle period is the same, we shouldn't\n // announce anything. But if the component was rerendered with different content\n // in the meantime, it's an indication that state changed enough that the same\n // message should be reannounced.\n if (trimmedMessage !== this._lastAnnouncement) {\n this._contentChangedSinceLastAnnouncement = true;\n }\n this._nextAnnouncement = trimmedMessage;\n\n // We're done with internal state updates. If there's nothing to actually announce, bail.\n if (!message) {\n return;\n }\n\n // If the delay is 0, just skip the timeout shenanigans and update the\n // element synchronously. Great for tests.\n if (this.delay === 0 || forceReannounce) {\n return this._updateElement(forceReannounce);\n }\n\n if (this._timeoutId === undefined) {\n this._timeoutId = setTimeout(() => this._updateElement(false), this.delay * 1000);\n }\n }\n\n private _updateElement(forceReannounce: boolean) {\n if (this._nextAnnouncement !== this._lastAnnouncement) {\n // The aria-atomic does not work properly in Voice Over, causing\n // certain parts of the content to be ignored. To fix that,\n // we assign the source text content as a single node.\n this._element.textContent = this._nextAnnouncement;\n this._addedTerminalPeriod = false;\n } else if (forceReannounce || this._contentChangedSinceLastAnnouncement) {\n // A (generally) safe way of forcing re-announcements is toggling the\n // terminal period. If we only keep adding periods, it's going to be\n // eventually interpreted as an ellipsis.\n this._element.textContent = this._nextAnnouncement + (this._addedTerminalPeriod ? '' : '.');\n this._addedTerminalPeriod = !this._addedTerminalPeriod;\n }\n\n // Track the announced text for deduplication.\n this._lastAnnouncement = this._nextAnnouncement;\n\n // Reset the state for the next announcement.\n this._contentChangedSinceLastAnnouncement = false;\n this._timeoutId = undefined;\n }\n}\n"]}
|
|
@@ -26,13 +26,13 @@ export default React.forwardRef(function InternalLiveRegion({ assertive = false,
|
|
|
26
26
|
// server.
|
|
27
27
|
const liveRegionControllerRef = useRef();
|
|
28
28
|
useEffect(() => {
|
|
29
|
-
const liveRegionController = new LiveRegionController(assertive ? 'assertive' : 'polite');
|
|
29
|
+
const liveRegionController = new LiveRegionController(assertive ? 'assertive' : 'polite', delay);
|
|
30
30
|
liveRegionControllerRef.current = liveRegionController;
|
|
31
31
|
return () => {
|
|
32
32
|
liveRegionController.destroy();
|
|
33
33
|
liveRegionControllerRef.current = undefined;
|
|
34
34
|
};
|
|
35
|
-
}, [assertive]);
|
|
35
|
+
}, [assertive, delay]);
|
|
36
36
|
const getContent = () => {
|
|
37
37
|
if (sources) {
|
|
38
38
|
return getSourceContent(sources);
|
|
@@ -45,12 +45,12 @@ export default React.forwardRef(function InternalLiveRegion({ assertive = false,
|
|
|
45
45
|
// message against the previous announcement internally.
|
|
46
46
|
useEffect(() => {
|
|
47
47
|
var _a;
|
|
48
|
-
(_a = liveRegionControllerRef.current) === null || _a === void 0 ? void 0 : _a.announce({ message: getContent()
|
|
48
|
+
(_a = liveRegionControllerRef.current) === null || _a === void 0 ? void 0 : _a.announce({ message: getContent() });
|
|
49
49
|
});
|
|
50
50
|
useImperativeHandle(ref, () => ({
|
|
51
51
|
reannounce() {
|
|
52
52
|
var _a;
|
|
53
|
-
(_a = liveRegionControllerRef.current) === null || _a === void 0 ? void 0 : _a.announce({ message: getContent(),
|
|
53
|
+
(_a = liveRegionControllerRef.current) === null || _a === void 0 ? void 0 : _a.announce({ message: getContent(), forceReannounce: true });
|
|
54
54
|
},
|
|
55
55
|
}));
|
|
56
56
|
return (React.createElement(TagName, { ref: mergedRef, ...baseProps, className: clsx(styles.root, testUtilStyles.root, className), hidden: hidden }, children));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../../../src/live-region/internal.tsx"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACtE,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,cAAc,MAAM,8BAA8B,CAAC;AA8B1D,eAAe,KAAK,CAAC,UAAU,CAAC,SAAS,kBAAkB,CACzD,EACE,SAAS,GAAG,KAAK,EACjB,MAAM,GAAG,KAAK,EACd,OAAO,EAAE,OAAO,GAAG,KAAK,EACxB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,SAAS,EACT,GAAG,SAAS,EACY,EAC1B,GAAqC;IAErC,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,MAAM,CAAmC,IAAI,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAE/D,SAAS,CAAC,GAAG,EAAE;QACb,oEAAoE;QACpE,yEAAyE;QACzE,qEAAqE;QACrE,mEAAmE;QACnE,iDAAiD;QACjD,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACxB,WAAW,CAAC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;QACrC,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,6EAA6E;IAC7E,gFAAgF;IAChF,UAAU;IACV,MAAM,uBAAuB,GAAG,MAAM,EAAoC,CAAC;IAC3E,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../../../src/live-region/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\n\nimport React, { useEffect, useImperativeHandle, useRef } from 'react';\nimport clsx from 'clsx';\n\nimport { useMergeRefs } from '@cloudscape-design/component-toolkit/internal';\n\nimport { getBaseProps } from '../internal/base-component';\nimport { InternalBaseComponentProps } from '../internal/hooks/use-base-component';\nimport { LiveRegionController } from './controller';\nimport { LiveRegionProps } from './interfaces';\n\nimport styles from './styles.css.js';\nimport testUtilStyles from './test-classes/styles.css.js';\n\ninterface InternalLiveRegionProps extends InternalBaseComponentProps, LiveRegionProps {\n /**\n * The delay between each announcement from this live region. You should\n * leave this set to the default unless this live region is commonly\n * interrupted by other actions (like text entry in text filtering).\n */\n delay?: number;\n\n /**\n * Use a list of strings and/or refs to existing elements for building the\n * announcement text. If this property is set, `children` and `message` will\n * be ignored.\n */\n sources?: ReadonlyArray<string | React.RefObject<HTMLElement> | undefined>;\n}\n\nexport interface InternalLiveRegionRef {\n /**\n * Force the live region to announce the message, even if it's the same as\n * the previously announced message.\n *\n * This is useful when making status updates after a change (e.g. filtering)\n * where the new message might be the same as the old one, but the announcement\n * also serves to tell screen reader users that the action was performed.\n */\n reannounce(): void;\n}\n\nexport default React.forwardRef(function InternalLiveRegion(\n {\n assertive = false,\n hidden = false,\n tagName: TagName = 'div',\n delay,\n sources,\n children,\n __internalRootRef,\n className,\n ...restProps\n }: InternalLiveRegionProps,\n ref: React.Ref<InternalLiveRegionRef>\n) {\n const baseProps = getBaseProps(restProps);\n const childrenRef = useRef<HTMLSpanElement & HTMLDivElement>(null);\n const mergedRef = useMergeRefs(childrenRef, __internalRootRef);\n\n useEffect(() => {\n // We have to do this because `inert` isn't properly supported until\n // React 19 and this seems much more maintainable than version detection.\n // `inert` is better than `hidden` because it also blocks pointer and\n // focus events as well as hiding the contents from screen readers.\n // https://github.com/facebook/react/issues/17157\n if (childrenRef.current) {\n childrenRef.current.inert = hidden;\n }\n }, [hidden]);\n\n // Initialize the live region controller inside an effect. We have to do this\n // because the controller depends on DOM elements, which aren't available on the\n // server.\n const liveRegionControllerRef = useRef<LiveRegionController | undefined>();\n useEffect(() => {\n const liveRegionController = new LiveRegionController(assertive ? 'assertive' : 'polite', delay);\n liveRegionControllerRef.current = liveRegionController;\n return () => {\n liveRegionController.destroy();\n liveRegionControllerRef.current = undefined;\n };\n }, [assertive, delay]);\n\n const getContent = () => {\n if (sources) {\n return getSourceContent(sources);\n }\n if (childrenRef.current) {\n return extractTextContent(childrenRef.current);\n }\n };\n\n // Call the controller on every render. The controller will deduplicate the\n // message against the previous announcement internally.\n useEffect(() => {\n liveRegionControllerRef.current?.announce({ message: getContent() });\n });\n\n useImperativeHandle(ref, () => ({\n reannounce() {\n liveRegionControllerRef.current?.announce({ message: getContent(), forceReannounce: true });\n },\n }));\n\n return (\n <TagName\n ref={mergedRef}\n {...baseProps}\n className={clsx(styles.root, testUtilStyles.root, className)}\n hidden={hidden}\n >\n {children}\n </TagName>\n );\n});\n\nconst processNode = (childNode: Node): string => {\n if (childNode.nodeType === Node.TEXT_NODE) {\n return childNode.textContent || '';\n }\n\n if (childNode.nodeType === Node.ELEMENT_NODE) {\n return extractTextContent(childNode as HTMLElement);\n }\n\n return '';\n};\n\nexport function extractTextContent(node: HTMLElement): string {\n // We use the text content of the node as the announcement text.\n // This only extracts text content from the node including all its children which is enough for now.\n // To make it more powerful, it is possible to create a more sophisticated extractor with respect to\n // ARIA properties to ignore aria-hidden nodes and read ARIA labels from the live content.\n if (!node || !node?.childNodes?.length) {\n return '';\n }\n\n return Array.from(node.childNodes, processNode).join(' ').replace(/\\s+/g, ' ').trim();\n}\n\nfunction getSourceContent(source: ReadonlyArray<string | React.RefObject<HTMLElement> | undefined>): string {\n return source\n .map(item => {\n if (!item || typeof item === 'string') {\n return item;\n }\n if (item.current) {\n return extractTextContent(item.current);\n }\n })\n .filter(Boolean)\n .join(' ');\n}\n"]}
|