@transferwise/components 46.131.1 → 46.132.0
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/build/common/liveRegion/LiveRegion.js +46 -7
- package/build/common/liveRegion/LiveRegion.js.map +1 -1
- package/build/common/liveRegion/LiveRegion.mjs +46 -7
- package/build/common/liveRegion/LiveRegion.mjs.map +1 -1
- package/build/flowNavigation/FlowNavigation.js +1 -0
- package/build/flowNavigation/FlowNavigation.js.map +1 -1
- package/build/flowNavigation/FlowNavigation.mjs +1 -0
- package/build/flowNavigation/FlowNavigation.mjs.map +1 -1
- package/build/main.css +52 -1
- package/build/overlayHeader/OverlayHeader.js +1 -0
- package/build/overlayHeader/OverlayHeader.js.map +1 -1
- package/build/overlayHeader/OverlayHeader.mjs +1 -0
- package/build/overlayHeader/OverlayHeader.mjs.map +1 -1
- package/build/prompt/InfoPrompt/InfoPrompt.js +2 -0
- package/build/prompt/InfoPrompt/InfoPrompt.js.map +1 -1
- package/build/prompt/InfoPrompt/InfoPrompt.mjs +2 -0
- package/build/prompt/InfoPrompt/InfoPrompt.mjs.map +1 -1
- package/build/styles/common/liveRegion/LiveRegion.css +3 -0
- package/build/styles/css/neptune.css +48 -1
- package/build/styles/main.css +52 -1
- package/build/styles/styles/less/neptune.css +48 -1
- package/build/types/common/liveRegion/LiveRegion.d.ts +5 -2
- package/build/types/common/liveRegion/LiveRegion.d.ts.map +1 -1
- package/build/types/prompt/InfoPrompt/InfoPrompt.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/alert/Alert.story.tsx +0 -6
- package/src/button/_stories/Button.story.tsx +0 -5
- package/src/checkboxButton/CheckboxButton.story.tsx +0 -1
- package/src/circularButton/CircularButton.story.tsx +0 -1
- package/src/common/liveRegion/LiveRegion.css +3 -0
- package/src/common/liveRegion/LiveRegion.less +3 -0
- package/src/common/liveRegion/LiveRegion.test.tsx +69 -2
- package/src/common/liveRegion/LiveRegion.tsx +77 -8
- package/src/dateLookup/DateLookup.test.story.tsx +0 -7
- package/src/dateLookup/DateLookup.test.tsx +22 -0
- package/src/display/Display.story.tsx +15 -1
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.story.tsx +0 -1
- package/src/header/Header.story.tsx +0 -5
- package/src/inputWithDisplayFormat/InputWithDisplayFormat.story.tsx +0 -1
- package/src/inputs/SelectInput/_stories/SelectInput.docs.mdx +62 -0
- package/src/inputs/SelectInput/_stories/SelectInput.story.tsx +796 -220
- package/src/inputs/SelectInput/_stories/SelectInput.test.story.tsx +433 -4
- package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.story.tsx +0 -5
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +0 -5
- package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +0 -5
- package/src/listItem/Button/ListItemButton.story.tsx +0 -5
- package/src/listItem/Checkbox/ListItemCheckbox.story.tsx +0 -5
- package/src/listItem/IconButton/ListItemIconButton.story.tsx +0 -5
- package/src/listItem/Image/ListItemImage.story.tsx +0 -5
- package/src/listItem/Navigation/ListItemNavigation.story.tsx +0 -5
- package/src/listItem/Prompt/ListItemPrompt.story.tsx +1 -5
- package/src/listItem/Radio/ListItemRadio.story.tsx +0 -5
- package/src/listItem/Switch/ListItemSwitch.story.tsx +0 -5
- package/src/listItem/_stories/ListItem.disabled.story.tsx +0 -1
- package/src/listItem/_stories/ListItem.scenarios.story.tsx +0 -1
- package/src/listItem/_stories/ListItem.story.tsx +0 -5
- package/src/main.css +52 -1
- package/src/main.less +1 -0
- package/src/modal/Modal.story.tsx +0 -1
- package/src/popover/Popover.story.tsx +0 -1
- package/src/prompt/ActionPrompt/ActionPrompt.story.tsx +0 -5
- package/src/prompt/InfoPrompt/InfoPrompt.story.tsx +0 -5
- package/src/prompt/InfoPrompt/InfoPrompt.test.story.tsx +142 -5
- package/src/prompt/InfoPrompt/InfoPrompt.test.tsx +11 -6
- package/src/prompt/InfoPrompt/InfoPrompt.tsx +2 -1
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +0 -5
- package/src/provider/theme/ThemeProvider.story.tsx +8 -0
- package/src/sentimentSurface/SentimentSurface.story.tsx +0 -5
- package/src/sticky/Sticky.story.tsx +0 -1
- package/src/styles/less/core/_typography.less +15 -2
- package/src/styles/less/neptune.css +48 -1
- package/src/tokens/tokens.story.tsx +1 -1
|
@@ -3492,10 +3492,57 @@ a,
|
|
|
3492
3492
|
.np-text-display-large,
|
|
3493
3493
|
.np-text-display-medium,
|
|
3494
3494
|
.np-text-display-small {
|
|
3495
|
-
font-family:
|
|
3495
|
+
font-family: 'Wise Sans', 'Inter', sans-serif;
|
|
3496
|
+
font-family: var(--font-family-display);
|
|
3496
3497
|
font-synthesis: none;
|
|
3497
3498
|
}
|
|
3498
3499
|
|
|
3500
|
+
:lang(ja) .display-1,
|
|
3501
|
+
:lang(ja) .display-2,
|
|
3502
|
+
:lang(ja) .display-3,
|
|
3503
|
+
:lang(ja) .display-4,
|
|
3504
|
+
:lang(ja) .display-5,
|
|
3505
|
+
:lang(ja) .np-text-display-extra-large,
|
|
3506
|
+
:lang(ja) .np-text-display-large,
|
|
3507
|
+
:lang(ja) .np-text-display-medium,
|
|
3508
|
+
:lang(ja) .np-text-display-small,
|
|
3509
|
+
:lang(th) .display-1,
|
|
3510
|
+
:lang(th) .display-2,
|
|
3511
|
+
:lang(th) .display-3,
|
|
3512
|
+
:lang(th) .display-4,
|
|
3513
|
+
:lang(th) .display-5,
|
|
3514
|
+
:lang(th) .np-text-display-extra-large,
|
|
3515
|
+
:lang(th) .np-text-display-large,
|
|
3516
|
+
:lang(th) .np-text-display-medium,
|
|
3517
|
+
:lang(th) .np-text-display-small,
|
|
3518
|
+
:lang(zh-CN) .display-1,
|
|
3519
|
+
:lang(zh-CN) .display-2,
|
|
3520
|
+
:lang(zh-CN) .display-3,
|
|
3521
|
+
:lang(zh-CN) .display-4,
|
|
3522
|
+
:lang(zh-CN) .display-5,
|
|
3523
|
+
:lang(zh-CN) .np-text-display-extra-large,
|
|
3524
|
+
:lang(zh-CN) .np-text-display-large,
|
|
3525
|
+
:lang(zh-CN) .np-text-display-medium,
|
|
3526
|
+
:lang(zh-CN) .np-text-display-small,
|
|
3527
|
+
:lang(zh-HK) .display-1,
|
|
3528
|
+
:lang(zh-HK) .display-2,
|
|
3529
|
+
:lang(zh-HK) .display-3,
|
|
3530
|
+
:lang(zh-HK) .display-4,
|
|
3531
|
+
:lang(zh-HK) .display-5,
|
|
3532
|
+
:lang(zh-HK) .np-text-display-extra-large,
|
|
3533
|
+
:lang(zh-HK) .np-text-display-large,
|
|
3534
|
+
:lang(zh-HK) .np-text-display-medium,
|
|
3535
|
+
:lang(zh-HK) .np-text-display-small {
|
|
3536
|
+
/**
|
|
3537
|
+
* Wise Sans covers extended Latin glyphs for logged-in experiences and a small subset
|
|
3538
|
+
* of Japanese ones for the logged out ones (exposed by the Editorial DS). Unfortunately,
|
|
3539
|
+
* font files are browser-cached and we carried over to launchpad, where it causes issues
|
|
3540
|
+
* for unsupported locales, especially those that share glyphs, like Japanese and Chinese.
|
|
3541
|
+
*/
|
|
3542
|
+
font-family: 'Inter', Helvetica, Arial, sans-serif;
|
|
3543
|
+
font-family: var(--font-family-regular);
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3499
3546
|
/* DEPRECATED(.np-text-display-extra-large): use .np-text-display-large instead */
|
|
3500
3547
|
|
|
3501
3548
|
.np-text-display-extra-large,
|
package/build/styles/main.css
CHANGED
|
@@ -3492,10 +3492,57 @@ a,
|
|
|
3492
3492
|
.np-text-display-large,
|
|
3493
3493
|
.np-text-display-medium,
|
|
3494
3494
|
.np-text-display-small {
|
|
3495
|
-
font-family:
|
|
3495
|
+
font-family: 'Wise Sans', 'Inter', sans-serif;
|
|
3496
|
+
font-family: var(--font-family-display);
|
|
3496
3497
|
font-synthesis: none;
|
|
3497
3498
|
}
|
|
3498
3499
|
|
|
3500
|
+
:lang(ja) .display-1,
|
|
3501
|
+
:lang(ja) .display-2,
|
|
3502
|
+
:lang(ja) .display-3,
|
|
3503
|
+
:lang(ja) .display-4,
|
|
3504
|
+
:lang(ja) .display-5,
|
|
3505
|
+
:lang(ja) .np-text-display-extra-large,
|
|
3506
|
+
:lang(ja) .np-text-display-large,
|
|
3507
|
+
:lang(ja) .np-text-display-medium,
|
|
3508
|
+
:lang(ja) .np-text-display-small,
|
|
3509
|
+
:lang(th) .display-1,
|
|
3510
|
+
:lang(th) .display-2,
|
|
3511
|
+
:lang(th) .display-3,
|
|
3512
|
+
:lang(th) .display-4,
|
|
3513
|
+
:lang(th) .display-5,
|
|
3514
|
+
:lang(th) .np-text-display-extra-large,
|
|
3515
|
+
:lang(th) .np-text-display-large,
|
|
3516
|
+
:lang(th) .np-text-display-medium,
|
|
3517
|
+
:lang(th) .np-text-display-small,
|
|
3518
|
+
:lang(zh-CN) .display-1,
|
|
3519
|
+
:lang(zh-CN) .display-2,
|
|
3520
|
+
:lang(zh-CN) .display-3,
|
|
3521
|
+
:lang(zh-CN) .display-4,
|
|
3522
|
+
:lang(zh-CN) .display-5,
|
|
3523
|
+
:lang(zh-CN) .np-text-display-extra-large,
|
|
3524
|
+
:lang(zh-CN) .np-text-display-large,
|
|
3525
|
+
:lang(zh-CN) .np-text-display-medium,
|
|
3526
|
+
:lang(zh-CN) .np-text-display-small,
|
|
3527
|
+
:lang(zh-HK) .display-1,
|
|
3528
|
+
:lang(zh-HK) .display-2,
|
|
3529
|
+
:lang(zh-HK) .display-3,
|
|
3530
|
+
:lang(zh-HK) .display-4,
|
|
3531
|
+
:lang(zh-HK) .display-5,
|
|
3532
|
+
:lang(zh-HK) .np-text-display-extra-large,
|
|
3533
|
+
:lang(zh-HK) .np-text-display-large,
|
|
3534
|
+
:lang(zh-HK) .np-text-display-medium,
|
|
3535
|
+
:lang(zh-HK) .np-text-display-small {
|
|
3536
|
+
/**
|
|
3537
|
+
* Wise Sans covers extended Latin glyphs for logged-in experiences and a small subset
|
|
3538
|
+
* of Japanese ones for the logged out ones (exposed by the Editorial DS). Unfortunately,
|
|
3539
|
+
* font files are browser-cached and we carried over to launchpad, where it causes issues
|
|
3540
|
+
* for unsupported locales, especially those that share glyphs, like Japanese and Chinese.
|
|
3541
|
+
*/
|
|
3542
|
+
font-family: 'Inter', Helvetica, Arial, sans-serif;
|
|
3543
|
+
font-family: var(--font-family-regular);
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3499
3546
|
/* DEPRECATED(.np-text-display-extra-large): use .np-text-display-large instead */
|
|
3500
3547
|
|
|
3501
3548
|
.np-text-display-extra-large,
|
|
@@ -28096,6 +28143,10 @@ a[data-toggle="tooltip"] {
|
|
|
28096
28143
|
--Card-padding: var(--size-16);
|
|
28097
28144
|
}
|
|
28098
28145
|
|
|
28146
|
+
.wds-LiveRegion {
|
|
28147
|
+
width: 100%;
|
|
28148
|
+
}
|
|
28149
|
+
|
|
28099
28150
|
.np-bottom-sheet {
|
|
28100
28151
|
border-radius: 10px 10px 0 0;
|
|
28101
28152
|
}
|
|
@@ -3492,10 +3492,57 @@ a,
|
|
|
3492
3492
|
.np-text-display-large,
|
|
3493
3493
|
.np-text-display-medium,
|
|
3494
3494
|
.np-text-display-small {
|
|
3495
|
-
font-family:
|
|
3495
|
+
font-family: 'Wise Sans', 'Inter', sans-serif;
|
|
3496
|
+
font-family: var(--font-family-display);
|
|
3496
3497
|
font-synthesis: none;
|
|
3497
3498
|
}
|
|
3498
3499
|
|
|
3500
|
+
:lang(ja) .display-1,
|
|
3501
|
+
:lang(ja) .display-2,
|
|
3502
|
+
:lang(ja) .display-3,
|
|
3503
|
+
:lang(ja) .display-4,
|
|
3504
|
+
:lang(ja) .display-5,
|
|
3505
|
+
:lang(ja) .np-text-display-extra-large,
|
|
3506
|
+
:lang(ja) .np-text-display-large,
|
|
3507
|
+
:lang(ja) .np-text-display-medium,
|
|
3508
|
+
:lang(ja) .np-text-display-small,
|
|
3509
|
+
:lang(th) .display-1,
|
|
3510
|
+
:lang(th) .display-2,
|
|
3511
|
+
:lang(th) .display-3,
|
|
3512
|
+
:lang(th) .display-4,
|
|
3513
|
+
:lang(th) .display-5,
|
|
3514
|
+
:lang(th) .np-text-display-extra-large,
|
|
3515
|
+
:lang(th) .np-text-display-large,
|
|
3516
|
+
:lang(th) .np-text-display-medium,
|
|
3517
|
+
:lang(th) .np-text-display-small,
|
|
3518
|
+
:lang(zh-CN) .display-1,
|
|
3519
|
+
:lang(zh-CN) .display-2,
|
|
3520
|
+
:lang(zh-CN) .display-3,
|
|
3521
|
+
:lang(zh-CN) .display-4,
|
|
3522
|
+
:lang(zh-CN) .display-5,
|
|
3523
|
+
:lang(zh-CN) .np-text-display-extra-large,
|
|
3524
|
+
:lang(zh-CN) .np-text-display-large,
|
|
3525
|
+
:lang(zh-CN) .np-text-display-medium,
|
|
3526
|
+
:lang(zh-CN) .np-text-display-small,
|
|
3527
|
+
:lang(zh-HK) .display-1,
|
|
3528
|
+
:lang(zh-HK) .display-2,
|
|
3529
|
+
:lang(zh-HK) .display-3,
|
|
3530
|
+
:lang(zh-HK) .display-4,
|
|
3531
|
+
:lang(zh-HK) .display-5,
|
|
3532
|
+
:lang(zh-HK) .np-text-display-extra-large,
|
|
3533
|
+
:lang(zh-HK) .np-text-display-large,
|
|
3534
|
+
:lang(zh-HK) .np-text-display-medium,
|
|
3535
|
+
:lang(zh-HK) .np-text-display-small {
|
|
3536
|
+
/**
|
|
3537
|
+
* Wise Sans covers extended Latin glyphs for logged-in experiences and a small subset
|
|
3538
|
+
* of Japanese ones for the logged out ones (exposed by the Editorial DS). Unfortunately,
|
|
3539
|
+
* font files are browser-cached and we carried over to launchpad, where it causes issues
|
|
3540
|
+
* for unsupported locales, especially those that share glyphs, like Japanese and Chinese.
|
|
3541
|
+
*/
|
|
3542
|
+
font-family: 'Inter', Helvetica, Arial, sans-serif;
|
|
3543
|
+
font-family: var(--font-family-regular);
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3499
3546
|
/* DEPRECATED(.np-text-display-extra-large): use .np-text-display-large instead */
|
|
3500
3547
|
|
|
3501
3548
|
.np-text-display-extra-large,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
2
|
export type AriaLive = 'off' | 'polite' | 'assertive';
|
|
3
|
+
export declare const resetLiveRegionAnnouncementQueue: () => void;
|
|
3
4
|
export interface LiveRegionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-live' | 'aria-atomic'> {
|
|
4
5
|
/**
|
|
5
6
|
* Determines urgency: 'assertive' interrupts, 'polite' waits for idle, 'off' disables live region.
|
|
6
7
|
*/
|
|
7
8
|
'aria-live': AriaLive;
|
|
9
|
+
/** Optional stable key that triggers a new announcement when it changes. */
|
|
10
|
+
announceOnChange?: string | number;
|
|
8
11
|
/** Test ID for testing tools */
|
|
9
12
|
'data-testid'?: string;
|
|
10
13
|
children?: ReactNode;
|
|
@@ -14,10 +17,10 @@ export interface LiveRegionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'r
|
|
|
14
17
|
*
|
|
15
18
|
* - `aria-live="polite"` → `role="status"`
|
|
16
19
|
* - `aria-live="assertive"` → `role="alert"`
|
|
17
|
-
* - `aria-live="off"` → no live region
|
|
20
|
+
* - `aria-live="off"` → no live region (renders children unwrapped)
|
|
18
21
|
*
|
|
19
22
|
* The `role` prop is intentionally excluded from the public API
|
|
20
23
|
* to prevent mismatches between `aria-live` and `role`.
|
|
21
24
|
*/
|
|
22
|
-
export declare const LiveRegion: ({ "aria-live": ariaLive, children, ...props }: LiveRegionProps) => import("react").JSX.Element;
|
|
25
|
+
export declare const LiveRegion: ({ "aria-live": ariaLive, announceOnChange, children, className, ...props }: LiveRegionProps) => import("react").JSX.Element;
|
|
23
26
|
//# sourceMappingURL=LiveRegion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveRegion.d.ts","sourceRoot":"","sources":["../../../../src/common/liveRegion/LiveRegion.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LiveRegion.d.ts","sourceRoot":"","sources":["../../../../src/common/liveRegion/LiveRegion.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvD,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAC;AA6BtD,eAAO,MAAM,gCAAgC,QAAO,IAGnD,CAAC;AAaF,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,cAAc,CAAC,cAAc,CAAC,EAC9B,MAAM,GAAG,WAAW,GAAG,aAAa,CACrC;IACC;;OAEG;IACH,WAAW,EAAE,QAAQ,CAAC;IACtB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,gCAAgC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GAAI,4EAMxB,eAAe,gCAoCjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfoPrompt.d.ts","sourceRoot":"","sources":["../../../../src/prompt/InfoPrompt/InfoPrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI5E,OAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAmB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,GAAG;IAC9E;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC,GAChG,IAAI,CAAC,oBAAoB,EAAE,aAAa,CAAC,GAAG;IAC1C;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC;CACxB,CAAC;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,GAAI,wIAWxB,eAAe,
|
|
1
|
+
{"version":3,"file":"InfoPrompt.d.ts","sourceRoot":"","sources":["../../../../src/prompt/InfoPrompt/InfoPrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI5E,OAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAmB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,GAAG;IAC9E;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC,GAChG,IAAI,CAAC,oBAAoB,EAAE,aAAa,CAAC,GAAG;IAC1C;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC;CACxB,CAAC;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,GAAI,wIAWxB,eAAe,gCA6EjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/components",
|
|
3
|
-
"version": "46.
|
|
3
|
+
"version": "46.132.0",
|
|
4
4
|
"description": "Neptune React components",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"storybook-addon-tag-badges": "^3.0.6",
|
|
88
88
|
"storybook-addon-test-codegen": "^3.0.1",
|
|
89
89
|
"@transferwise/less-config": "3.1.2",
|
|
90
|
-
"@transferwise/neptune-css": "14.27.
|
|
90
|
+
"@transferwise/neptune-css": "14.27.1",
|
|
91
91
|
"@wise/components-theming": "1.10.1",
|
|
92
92
|
"@wise/wds-configs": "0.0.0"
|
|
93
93
|
},
|
|
@@ -1,23 +1,43 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import {
|
|
1
|
+
import { act, render, screen } from '@testing-library/react';
|
|
2
|
+
import { WDS_LIVE_REGION_DELAY_MS } from '../constants';
|
|
3
|
+
import { LiveRegion, LiveRegionProps, resetLiveRegionAnnouncementQueue } from './LiveRegion';
|
|
3
4
|
|
|
4
5
|
describe('LiveRegion', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.useFakeTimers();
|
|
8
|
+
resetLiveRegionAnnouncementQueue();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
jest.clearAllTimers();
|
|
13
|
+
jest.useRealTimers();
|
|
14
|
+
});
|
|
15
|
+
|
|
5
16
|
const renderLiveRegion = (props: Partial<LiveRegionProps> & Pick<LiveRegionProps, 'aria-live'>) =>
|
|
6
17
|
render(<LiveRegion {...props}>{props.children ?? 'Live content'}</LiveRegion>);
|
|
7
18
|
|
|
19
|
+
const enableLiveRegion = (delay = WDS_LIVE_REGION_DELAY_MS) => {
|
|
20
|
+
act(() => {
|
|
21
|
+
jest.advanceTimersByTime(delay);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
8
25
|
describe('when aria-live is "polite"', () => {
|
|
9
26
|
it('renders with role="status"', () => {
|
|
10
27
|
renderLiveRegion({ 'aria-live': 'polite' });
|
|
28
|
+
enableLiveRegion();
|
|
11
29
|
expect(screen.getByRole('status')).toBeInTheDocument();
|
|
12
30
|
});
|
|
13
31
|
|
|
14
32
|
it('sets aria-live="polite"', () => {
|
|
15
33
|
renderLiveRegion({ 'aria-live': 'polite' });
|
|
34
|
+
enableLiveRegion();
|
|
16
35
|
expect(screen.getByRole('status')).toHaveAttribute('aria-live', 'polite');
|
|
17
36
|
});
|
|
18
37
|
|
|
19
38
|
it('sets aria-atomic="true"', () => {
|
|
20
39
|
renderLiveRegion({ 'aria-live': 'polite' });
|
|
40
|
+
enableLiveRegion();
|
|
21
41
|
expect(screen.getByRole('status')).toHaveAttribute('aria-atomic', 'true');
|
|
22
42
|
});
|
|
23
43
|
});
|
|
@@ -25,32 +45,79 @@ describe('LiveRegion', () => {
|
|
|
25
45
|
describe('when aria-live is "assertive"', () => {
|
|
26
46
|
it('renders with role="alert"', () => {
|
|
27
47
|
renderLiveRegion({ 'aria-live': 'assertive' });
|
|
48
|
+
enableLiveRegion();
|
|
28
49
|
expect(screen.getByRole('alert')).toBeInTheDocument();
|
|
29
50
|
});
|
|
30
51
|
|
|
31
52
|
it('sets aria-live="assertive"', () => {
|
|
32
53
|
renderLiveRegion({ 'aria-live': 'assertive' });
|
|
54
|
+
enableLiveRegion();
|
|
33
55
|
expect(screen.getByRole('alert')).toHaveAttribute('aria-live', 'assertive');
|
|
34
56
|
});
|
|
35
57
|
|
|
36
58
|
it('sets aria-atomic="true"', () => {
|
|
37
59
|
renderLiveRegion({ 'aria-live': 'assertive' });
|
|
60
|
+
enableLiveRegion();
|
|
38
61
|
expect(screen.getByRole('alert')).toHaveAttribute('aria-atomic', 'true');
|
|
39
62
|
});
|
|
40
63
|
});
|
|
41
64
|
|
|
65
|
+
it('delays live-region activation before the configured timeout', () => {
|
|
66
|
+
renderLiveRegion({ 'aria-live': 'polite', children: 'Delayed content' });
|
|
67
|
+
|
|
68
|
+
const liveRegion = screen.getByRole('status');
|
|
69
|
+
expect(liveRegion).toBeInTheDocument();
|
|
70
|
+
expect(liveRegion.firstElementChild).toHaveAttribute('aria-hidden', 'true');
|
|
71
|
+
|
|
72
|
+
enableLiveRegion(WDS_LIVE_REGION_DELAY_MS - 1);
|
|
73
|
+
expect(liveRegion.firstElementChild).toHaveAttribute('aria-hidden', 'true');
|
|
74
|
+
|
|
75
|
+
enableLiveRegion(1);
|
|
76
|
+
expect(liveRegion.firstElementChild).not.toHaveAttribute('aria-hidden');
|
|
77
|
+
expect(liveRegion).toHaveTextContent('Delayed content');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('queues multiple assertive regions so each one gets announced', () => {
|
|
81
|
+
render(
|
|
82
|
+
<>
|
|
83
|
+
<LiveRegion aria-live="assertive">First prompt</LiveRegion>
|
|
84
|
+
<LiveRegion aria-live="assertive">Second prompt</LiveRegion>
|
|
85
|
+
</>,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const liveRegions = screen.getAllByRole('alert');
|
|
89
|
+
expect(liveRegions).toHaveLength(2);
|
|
90
|
+
expect(liveRegions[0].firstElementChild).toHaveAttribute('aria-hidden', 'true');
|
|
91
|
+
expect(liveRegions[1].firstElementChild).toHaveAttribute('aria-hidden', 'true');
|
|
92
|
+
|
|
93
|
+
enableLiveRegion();
|
|
94
|
+
const firstEnabledLiveRegions = screen.getAllByRole('alert');
|
|
95
|
+
expect(firstEnabledLiveRegions[0].firstElementChild).not.toHaveAttribute('aria-hidden');
|
|
96
|
+
expect(firstEnabledLiveRegions[1].firstElementChild).toHaveAttribute('aria-hidden', 'true');
|
|
97
|
+
expect(firstEnabledLiveRegions[0]).toHaveTextContent('First prompt');
|
|
98
|
+
|
|
99
|
+
enableLiveRegion();
|
|
100
|
+
const secondEnabledLiveRegions = screen.getAllByRole('alert');
|
|
101
|
+
expect(secondEnabledLiveRegions[1].firstElementChild).not.toHaveAttribute('aria-hidden');
|
|
102
|
+
expect(secondEnabledLiveRegions[0]).toHaveTextContent('First prompt');
|
|
103
|
+
expect(secondEnabledLiveRegions[1]).toHaveTextContent('Second prompt');
|
|
104
|
+
});
|
|
105
|
+
|
|
42
106
|
it('renders children', () => {
|
|
43
107
|
renderLiveRegion({ 'aria-live': 'polite', children: 'Transfer sent' });
|
|
108
|
+
enableLiveRegion();
|
|
44
109
|
expect(screen.getByText('Transfer sent')).toBeInTheDocument();
|
|
45
110
|
});
|
|
46
111
|
|
|
47
112
|
it('passes additional HTML attributes to the wrapper div', () => {
|
|
48
113
|
renderLiveRegion({ 'aria-live': 'polite', className: 'custom' });
|
|
114
|
+
enableLiveRegion();
|
|
49
115
|
expect(screen.getByRole('status')).toHaveClass('custom');
|
|
50
116
|
});
|
|
51
117
|
|
|
52
118
|
it('supports data-testid prop', () => {
|
|
53
119
|
renderLiveRegion({ 'aria-live': 'polite', 'data-testid': 'live-region' });
|
|
120
|
+
enableLiveRegion();
|
|
54
121
|
expect(screen.getByTestId('live-region')).toBeInTheDocument();
|
|
55
122
|
});
|
|
56
123
|
});
|
|
@@ -1,11 +1,52 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
1
2
|
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import { WDS_LIVE_REGION_DELAY_MS } from '../constants';
|
|
5
|
+
|
|
6
|
+
export type AriaLive = 'off' | 'polite' | 'assertive';
|
|
7
|
+
|
|
8
|
+
type LivePoliteness = Exclude<AriaLive, 'off'>;
|
|
9
|
+
|
|
10
|
+
const LIVE_REGION_ROLE_BY_POLITENESS: Record<LivePoliteness, 'status' | 'alert'> = {
|
|
4
11
|
assertive: 'alert',
|
|
5
12
|
polite: 'status',
|
|
6
|
-
}
|
|
13
|
+
};
|
|
7
14
|
|
|
8
|
-
|
|
15
|
+
let nextPoliteAnnouncementAt = 0;
|
|
16
|
+
let nextAssertiveAnnouncementAt = 0;
|
|
17
|
+
|
|
18
|
+
const getNextAnnouncementAt = (politeness: LivePoliteness): number => {
|
|
19
|
+
if (politeness === 'polite') {
|
|
20
|
+
return nextPoliteAnnouncementAt;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return nextAssertiveAnnouncementAt;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const setNextAnnouncementAt = (politeness: LivePoliteness, value: number): void => {
|
|
27
|
+
if (politeness === 'polite') {
|
|
28
|
+
nextPoliteAnnouncementAt = value;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
nextAssertiveAnnouncementAt = value;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const resetLiveRegionAnnouncementQueue = (): void => {
|
|
36
|
+
nextPoliteAnnouncementAt = 0;
|
|
37
|
+
nextAssertiveAnnouncementAt = 0;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const calcAnnouncementDelayMs = (politeness: LivePoliteness, now: number): number => {
|
|
41
|
+
return Math.max(now + WDS_LIVE_REGION_DELAY_MS, getNextAnnouncementAt(politeness)) - now;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const scheduleAnnouncement = (politeness: LivePoliteness): number => {
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
const delayMs = calcAnnouncementDelayMs(politeness, now);
|
|
47
|
+
setNextAnnouncementAt(politeness, now + delayMs + WDS_LIVE_REGION_DELAY_MS);
|
|
48
|
+
return delayMs;
|
|
49
|
+
};
|
|
9
50
|
|
|
10
51
|
export interface LiveRegionProps extends Omit<
|
|
11
52
|
HTMLAttributes<HTMLDivElement>,
|
|
@@ -15,6 +56,8 @@ export interface LiveRegionProps extends Omit<
|
|
|
15
56
|
* Determines urgency: 'assertive' interrupts, 'polite' waits for idle, 'off' disables live region.
|
|
16
57
|
*/
|
|
17
58
|
'aria-live': AriaLive;
|
|
59
|
+
/** Optional stable key that triggers a new announcement when it changes. */
|
|
60
|
+
announceOnChange?: string | number;
|
|
18
61
|
/** Test ID for testing tools */
|
|
19
62
|
'data-testid'?: string;
|
|
20
63
|
children?: ReactNode;
|
|
@@ -25,25 +68,51 @@ export interface LiveRegionProps extends Omit<
|
|
|
25
68
|
*
|
|
26
69
|
* - `aria-live="polite"` → `role="status"`
|
|
27
70
|
* - `aria-live="assertive"` → `role="alert"`
|
|
28
|
-
* - `aria-live="off"` → no live region
|
|
71
|
+
* - `aria-live="off"` → no live region (renders children unwrapped)
|
|
29
72
|
*
|
|
30
73
|
* The `role` prop is intentionally excluded from the public API
|
|
31
74
|
* to prevent mismatches between `aria-live` and `role`.
|
|
32
75
|
*/
|
|
33
|
-
export const LiveRegion = ({
|
|
76
|
+
export const LiveRegion = ({
|
|
77
|
+
'aria-live': ariaLive,
|
|
78
|
+
announceOnChange,
|
|
79
|
+
children,
|
|
80
|
+
className,
|
|
81
|
+
...props
|
|
82
|
+
}: LiveRegionProps) => {
|
|
83
|
+
const [shouldAnnounce, setShouldAnnounce] = useState(false);
|
|
84
|
+
const announcementTrigger =
|
|
85
|
+
announceOnChange ??
|
|
86
|
+
(typeof children === 'string' || typeof children === 'number' ? children : undefined);
|
|
87
|
+
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
setShouldAnnounce(false);
|
|
90
|
+
|
|
91
|
+
if (ariaLive === 'off') {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const timeoutId = window.setTimeout(
|
|
96
|
+
() => setShouldAnnounce(true),
|
|
97
|
+
scheduleAnnouncement(ariaLive),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return () => window.clearTimeout(timeoutId);
|
|
101
|
+
}, [ariaLive, announcementTrigger]);
|
|
102
|
+
|
|
34
103
|
if (ariaLive === 'off') {
|
|
35
104
|
return <>{children}</>;
|
|
36
105
|
}
|
|
37
106
|
|
|
38
107
|
return (
|
|
39
108
|
<div
|
|
40
|
-
role={
|
|
109
|
+
role={LIVE_REGION_ROLE_BY_POLITENESS[ariaLive]}
|
|
41
110
|
aria-live={ariaLive}
|
|
42
111
|
aria-atomic="true"
|
|
43
|
-
|
|
112
|
+
className={`wds-LiveRegion ${className ?? ''}`}
|
|
44
113
|
{...props}
|
|
45
114
|
>
|
|
46
|
-
{children}
|
|
115
|
+
<div aria-hidden={shouldAnnounce ? undefined : 'true'}>{children}</div>
|
|
47
116
|
</div>
|
|
48
117
|
);
|
|
49
118
|
};
|
|
@@ -83,13 +83,6 @@ FocusOnSelectedDay.play = async () => {
|
|
|
83
83
|
await userEvent.keyboard(' ');
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
-
export const FocusOnToday = Template.bind({});
|
|
87
|
-
FocusOnToday.args = { ...props, value: null };
|
|
88
|
-
FocusOnToday.play = async () => {
|
|
89
|
-
await userEvent.tab();
|
|
90
|
-
await userEvent.keyboard(' ');
|
|
91
|
-
};
|
|
92
|
-
|
|
93
86
|
export const FocusOnFirstNonDisabledDate = Template.bind({});
|
|
94
87
|
FocusOnFirstNonDisabledDate.args = {
|
|
95
88
|
...props,
|
|
@@ -247,6 +247,28 @@ describe('DateLookup (events)', () => {
|
|
|
247
247
|
const min = new Date(2018, 11, 26);
|
|
248
248
|
const max = new Date(2018, 11, 28);
|
|
249
249
|
|
|
250
|
+
it('focuses on today when value is null', async () => {
|
|
251
|
+
const today = new Date();
|
|
252
|
+
const todayDateLabel = today.toLocaleDateString('en-GB', {
|
|
253
|
+
day: 'numeric',
|
|
254
|
+
month: 'numeric',
|
|
255
|
+
year: 'numeric',
|
|
256
|
+
});
|
|
257
|
+
const expectedHeaderText = today.toLocaleDateString('en-GB', {
|
|
258
|
+
month: 'long',
|
|
259
|
+
year: 'numeric',
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
render(<DateLookup value={null} onChange={jest.fn()} />);
|
|
263
|
+
await user.click(screen.getByRole('button'));
|
|
264
|
+
const todayButton = screen.getByLabelText(todayDateLabel);
|
|
265
|
+
|
|
266
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
267
|
+
expect(screen.getByText(expectedHeaderText)).toBeInTheDocument();
|
|
268
|
+
expect(todayButton).toHaveClass('today');
|
|
269
|
+
expect(todayButton).toHaveFocus();
|
|
270
|
+
});
|
|
271
|
+
|
|
250
272
|
describe('when not clearable', () => {
|
|
251
273
|
let handleChange: jest.Mock;
|
|
252
274
|
|
|
@@ -14,6 +14,8 @@ export const Basic = () => {
|
|
|
14
14
|
const DE = 'äöüßabcdefghijklmnopqrstuvwxyz';
|
|
15
15
|
const UA = 'Ми будуємо найбільш міжнародний рахунок у світі';
|
|
16
16
|
const JA = 'ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてで';
|
|
17
|
+
const ZN =
|
|
18
|
+
'的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年样能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去最性性齉龘龘靐齉爩鱻猋驫麤籲爨癵驫鲙鬯鬻厵纛';
|
|
17
19
|
return (
|
|
18
20
|
<>
|
|
19
21
|
<div lang="en">
|
|
@@ -77,7 +79,7 @@ export const Basic = () => {
|
|
|
77
79
|
</div>
|
|
78
80
|
<hr />
|
|
79
81
|
<div lang="ja">
|
|
80
|
-
<h1>
|
|
82
|
+
<h1>Japanese</h1>
|
|
81
83
|
Large
|
|
82
84
|
<Display type={Typography.DISPLAY_LARGE}>{JA}</Display>
|
|
83
85
|
<hr />
|
|
@@ -87,6 +89,18 @@ export const Basic = () => {
|
|
|
87
89
|
Small
|
|
88
90
|
<Display type={Typography.DISPLAY_SMALL}>{JA}</Display>
|
|
89
91
|
</div>
|
|
92
|
+
<hr />
|
|
93
|
+
<div lang="zh-CN">
|
|
94
|
+
<h1>Simplified Chinese</h1>
|
|
95
|
+
Large
|
|
96
|
+
<Display type={Typography.DISPLAY_LARGE}>{ZN}</Display>
|
|
97
|
+
<hr />
|
|
98
|
+
Medium
|
|
99
|
+
<Display type={Typography.DISPLAY_MEDIUM}>{ZN}</Display>
|
|
100
|
+
<hr />
|
|
101
|
+
Small
|
|
102
|
+
<Display type={Typography.DISPLAY_SMALL}>{ZN}</Display>
|
|
103
|
+
</div>
|
|
90
104
|
</>
|
|
91
105
|
);
|
|
92
106
|
};
|