@transferwise/components 0.0.0-experimental-fa9fbe9 → 0.0.0-experimental-162ecb1
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/hooks/useResizeObserver.js +3 -3
- package/build/common/hooks/useResizeObserver.js.map +1 -1
- package/build/common/hooks/useResizeObserver.mjs +3 -3
- package/build/common/hooks/useResizeObserver.mjs.map +1 -1
- package/build/criticalBanner/CriticalCommsBanner.js +0 -3
- package/build/criticalBanner/CriticalCommsBanner.js.map +1 -1
- package/build/criticalBanner/CriticalCommsBanner.mjs +0 -3
- package/build/criticalBanner/CriticalCommsBanner.mjs.map +1 -1
- package/build/field/Field.js +2 -3
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.mjs +2 -3
- package/build/field/Field.mjs.map +1 -1
- package/build/i18n/en.json +0 -2
- package/build/i18n/en.json.js +0 -2
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +0 -2
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/index.js +0 -2
- package/build/index.js.map +1 -1
- package/build/index.mjs +0 -1
- package/build/index.mjs.map +1 -1
- package/build/listItem/Prompt/ListItemPrompt.js +2 -3
- package/build/listItem/Prompt/ListItemPrompt.js.map +1 -1
- package/build/listItem/Prompt/ListItemPrompt.mjs +2 -3
- package/build/listItem/Prompt/ListItemPrompt.mjs.map +1 -1
- package/build/logo/Logo.js +70 -25
- package/build/logo/Logo.js.map +1 -1
- package/build/logo/Logo.mjs +72 -27
- package/build/logo/Logo.mjs.map +1 -1
- package/build/logo/logo-assets.js +68 -97
- package/build/logo/logo-assets.js.map +1 -1
- package/build/logo/logo-assets.mjs +62 -90
- package/build/logo/logo-assets.mjs.map +1 -1
- package/build/main.css +32 -224
- package/build/prompt/ActionPrompt/ActionPrompt.js +40 -8
- package/build/prompt/ActionPrompt/ActionPrompt.js.map +1 -1
- package/build/prompt/ActionPrompt/ActionPrompt.mjs +40 -8
- package/build/prompt/ActionPrompt/ActionPrompt.mjs.map +1 -1
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.js +4 -11
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.js.map +1 -1
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.mjs +4 -11
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.mjs.map +1 -1
- package/build/styles/logo/Logo.css +3 -24
- package/build/styles/main.css +32 -224
- package/build/table/Table.js +6 -5
- package/build/table/Table.js.map +1 -1
- package/build/table/Table.mjs +6 -5
- package/build/table/Table.mjs.map +1 -1
- package/build/typeahead/Typeahead.js +2 -3
- package/build/typeahead/Typeahead.js.map +1 -1
- package/build/typeahead/Typeahead.mjs +2 -3
- package/build/typeahead/Typeahead.mjs.map +1 -1
- package/build/types/common/hooks/useResizeObserver.d.ts +1 -1
- package/build/types/common/hooks/useResizeObserver.d.ts.map +1 -1
- package/build/types/criticalBanner/CriticalCommsBanner.d.ts +0 -3
- package/build/types/criticalBanner/CriticalCommsBanner.d.ts.map +1 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/logo/Logo.d.ts +32 -1
- package/build/types/logo/Logo.d.ts.map +1 -1
- package/build/types/logo/logo-assets.d.ts +33 -9
- package/build/types/logo/logo-assets.d.ts.map +1 -1
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts +11 -2
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts.map +1 -1
- package/build/types/prompt/PrimitivePrompt/PrimitivePrompt.d.ts +3 -35
- package/build/types/prompt/PrimitivePrompt/PrimitivePrompt.d.ts.map +1 -1
- package/build/types/prompt/index.d.ts +0 -2
- package/build/types/prompt/index.d.ts.map +1 -1
- package/build/types/table/Table.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +0 -4
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/common/bottomSheet/BottomSheet.test.story.tsx +6 -5
- package/src/common/hooks/useResizeObserver.ts +2 -3
- package/src/criticalBanner/CriticalCommsBanner.story.tsx +0 -4
- package/src/criticalBanner/CriticalCommsBanner.test.story.tsx +1 -1
- package/src/criticalBanner/CriticalCommsBanner.tsx +0 -3
- package/src/i18n/en.json +0 -2
- package/src/index.ts +2 -2
- package/src/logo/Logo.css +3 -24
- package/src/logo/Logo.less +3 -30
- package/src/logo/Logo.story.tsx +123 -89
- package/src/logo/Logo.test.story.tsx +12 -23
- package/src/logo/Logo.tsx +87 -28
- package/src/logo/logo-assets.tsx +36 -92
- package/src/main.css +32 -224
- package/src/main.less +1 -3
- package/src/prompt/ActionPrompt/ActionPrompt.tsx +62 -9
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.tsx +40 -56
- package/src/prompt/index.ts +0 -4
- package/src/sentimentSurface/SentimentSurface.story.tsx +17 -43
- package/src/table/Table.story.tsx +1 -1
- package/src/table/Table.tsx +6 -5
- package/build/common/hooks/useContainerSize.js +0 -30
- package/build/common/hooks/useContainerSize.js.map +0 -1
- package/build/common/hooks/useContainerSize.mjs +0 -28
- package/build/common/hooks/useContainerSize.mjs.map +0 -1
- package/build/prompt/CriticalBanner/CriticalBanner.js +0 -142
- package/build/prompt/CriticalBanner/CriticalBanner.js.map +0 -1
- package/build/prompt/CriticalBanner/CriticalBanner.mjs +0 -140
- package/build/prompt/CriticalBanner/CriticalBanner.mjs.map +0 -1
- package/build/prompt/CriticalBanner/helpers.js +0 -29
- package/build/prompt/CriticalBanner/helpers.js.map +0 -1
- package/build/prompt/CriticalBanner/helpers.mjs +0 -26
- package/build/prompt/CriticalBanner/helpers.mjs.map +0 -1
- package/build/prompt/common/Expander/Expander.js +0 -35
- package/build/prompt/common/Expander/Expander.js.map +0 -1
- package/build/prompt/common/Expander/Expander.messages.js +0 -17
- package/build/prompt/common/Expander/Expander.messages.js.map +0 -1
- package/build/prompt/common/Expander/Expander.messages.mjs +0 -13
- package/build/prompt/common/Expander/Expander.messages.mjs.map +0 -1
- package/build/prompt/common/Expander/Expander.mjs +0 -33
- package/build/prompt/common/Expander/Expander.mjs.map +0 -1
- package/build/prompt/helpers/promptMedia.js +0 -52
- package/build/prompt/helpers/promptMedia.js.map +0 -1
- package/build/prompt/helpers/promptMedia.mjs +0 -50
- package/build/prompt/helpers/promptMedia.mjs.map +0 -1
- package/build/styles/prompt/CriticalBanner/CriticalBanner.css +0 -134
- package/build/styles/prompt/CriticalBanner/CriticalBanner.vars.css +0 -0
- package/build/styles/prompt/common/Expander/Expander.css +0 -8
- package/build/types/common/hooks/useContainerSize.d.ts +0 -14
- package/build/types/common/hooks/useContainerSize.d.ts.map +0 -1
- package/build/types/prompt/CriticalBanner/CriticalBanner.d.ts +0 -39
- package/build/types/prompt/CriticalBanner/CriticalBanner.d.ts.map +0 -1
- package/build/types/prompt/CriticalBanner/helpers.d.ts +0 -18
- package/build/types/prompt/CriticalBanner/helpers.d.ts.map +0 -1
- package/build/types/prompt/CriticalBanner/index.d.ts +0 -3
- package/build/types/prompt/CriticalBanner/index.d.ts.map +0 -1
- package/build/types/prompt/common/Expander/Expander.d.ts +0 -20
- package/build/types/prompt/common/Expander/Expander.d.ts.map +0 -1
- package/build/types/prompt/common/Expander/Expander.messages.d.ts +0 -14
- package/build/types/prompt/common/Expander/Expander.messages.d.ts.map +0 -1
- package/build/types/prompt/helpers/promptMedia.d.ts +0 -22
- package/build/types/prompt/helpers/promptMedia.d.ts.map +0 -1
- package/src/common/hooks/useContainerSize.test.tsx +0 -121
- package/src/common/hooks/useContainerSize.ts +0 -32
- package/src/prompt/CriticalBanner/CriticalBanner.accessibility.docs.mdx +0 -113
- package/src/prompt/CriticalBanner/CriticalBanner.css +0 -134
- package/src/prompt/CriticalBanner/CriticalBanner.less +0 -155
- package/src/prompt/CriticalBanner/CriticalBanner.story.tsx +0 -635
- package/src/prompt/CriticalBanner/CriticalBanner.test.story.tsx +0 -422
- package/src/prompt/CriticalBanner/CriticalBanner.tsx +0 -178
- package/src/prompt/CriticalBanner/CriticalBanner.vars.css +0 -0
- package/src/prompt/CriticalBanner/CriticalBanner.vars.less +0 -6
- package/src/prompt/CriticalBanner/helpers.ts +0 -39
- package/src/prompt/CriticalBanner/index.ts +0 -2
- package/src/prompt/common/Expander/Expander.css +0 -8
- package/src/prompt/common/Expander/Expander.less +0 -9
- package/src/prompt/common/Expander/Expander.messages.ts +0 -14
- package/src/prompt/common/Expander/Expander.test.tsx +0 -167
- package/src/prompt/common/Expander/Expander.tsx +0 -83
- package/src/prompt/helpers/promptMedia.tsx +0 -79
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { GiftBox } from '@transferwise/icons';
|
|
2
|
-
import AvatarView from '../../avatarView/AvatarView.mjs';
|
|
3
|
-
import Image from '../../image/Image.mjs';
|
|
4
|
-
import StatusIcon from '../../statusIcon/StatusIcon.mjs';
|
|
5
|
-
import { jsx } from 'react/jsx-runtime';
|
|
6
|
-
|
|
7
|
-
function renderPromptMedia({
|
|
8
|
-
media,
|
|
9
|
-
sentiment,
|
|
10
|
-
mediaId,
|
|
11
|
-
imgClassName
|
|
12
|
-
}) {
|
|
13
|
-
if (media?.imgSrc) {
|
|
14
|
-
return /*#__PURE__*/jsx(Image, {
|
|
15
|
-
id: mediaId,
|
|
16
|
-
src: media.imgSrc,
|
|
17
|
-
className: imgClassName,
|
|
18
|
-
alt: media['aria-label'] ?? ''
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
if (media?.avatar) {
|
|
22
|
-
const badge = media.avatar.badge ? media.avatar.badge : sentiment === 'proposition' ? {} : {
|
|
23
|
-
status: sentiment
|
|
24
|
-
};
|
|
25
|
-
return /*#__PURE__*/jsx(AvatarView, {
|
|
26
|
-
...media.avatar,
|
|
27
|
-
badge: badge,
|
|
28
|
-
"aria-label": media['aria-label'],
|
|
29
|
-
"aria-hidden": media['aria-hidden'],
|
|
30
|
-
id: mediaId,
|
|
31
|
-
size: 48,
|
|
32
|
-
children: media.avatar.asset
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
return sentiment === 'proposition' ? /*#__PURE__*/jsx(AvatarView, {
|
|
36
|
-
id: mediaId,
|
|
37
|
-
size: 48,
|
|
38
|
-
"aria-label": media['aria-label'],
|
|
39
|
-
"aria-hidden": media['aria-hidden'],
|
|
40
|
-
children: /*#__PURE__*/jsx(GiftBox, {})
|
|
41
|
-
}) : /*#__PURE__*/jsx(StatusIcon, {
|
|
42
|
-
id: mediaId,
|
|
43
|
-
size: 48,
|
|
44
|
-
sentiment: sentiment,
|
|
45
|
-
iconLabel: media['aria-hidden'] ? null : media['aria-label']
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export { renderPromptMedia };
|
|
50
|
-
//# sourceMappingURL=promptMedia.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"promptMedia.mjs","sources":["../../../src/prompt/helpers/promptMedia.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport { GiftBox } from '@transferwise/icons';\n\nimport AvatarView, { AvatarViewProps } from '../../avatarView';\nimport Image from '../../image';\nimport StatusIcon from '../../statusIcon';\nimport { BadgeAssetsProps } from '../../badge';\nimport { PrimitivePromptProps } from '../PrimitivePrompt';\n\nexport type PromptMedia = {\n imgSrc?: string;\n avatar?: Pick<AvatarViewProps, 'imgSrc' | 'profileName' | 'profileType'> & {\n asset?: AvatarViewProps['children'];\n badge?: Pick<BadgeAssetsProps, 'flagCode'>;\n };\n 'aria-label'?: string;\n 'aria-hidden'?: boolean;\n};\n\ntype RenderPromptMediaOptions = {\n media: PromptMedia;\n sentiment: PrimitivePromptProps['sentiment'];\n mediaId: string;\n imgClassName: string;\n};\n\nexport function renderPromptMedia({\n media,\n sentiment,\n mediaId,\n imgClassName,\n}: RenderPromptMediaOptions): ReactNode {\n if (media?.imgSrc) {\n return (\n <Image\n id={mediaId}\n src={media.imgSrc}\n className={imgClassName}\n alt={media['aria-label'] ?? ''}\n />\n );\n }\n if (media?.avatar) {\n const badge = media.avatar.badge\n ? media.avatar.badge\n : sentiment === 'proposition'\n ? {}\n : { status: sentiment };\n return (\n <AvatarView\n {...media.avatar}\n badge={badge}\n aria-label={media['aria-label']}\n aria-hidden={media['aria-hidden']}\n id={mediaId}\n size={48}\n >\n {media.avatar.asset}\n </AvatarView>\n );\n }\n return sentiment === 'proposition' ? (\n <AvatarView\n id={mediaId}\n size={48}\n aria-label={media['aria-label']}\n aria-hidden={media['aria-hidden']}\n >\n <GiftBox />\n </AvatarView>\n ) : (\n <StatusIcon\n id={mediaId}\n size={48}\n sentiment={sentiment}\n iconLabel={media['aria-hidden'] ? null : media['aria-label']}\n />\n );\n}\n"],"names":["renderPromptMedia","media","sentiment","mediaId","imgClassName","imgSrc","_jsx","Image","id","src","className","alt","avatar","badge","status","AvatarView","size","children","asset","GiftBox","StatusIcon","iconLabel"],"mappings":";;;;;;AA0BM,SAAUA,iBAAiBA,CAAC;EAChCC,KAAK;EACLC,SAAS;EACTC,OAAO;AACPC,EAAAA;AAAY,CACa,EAAA;EACzB,IAAIH,KAAK,EAAEI,MAAM,EAAE;IACjB,oBACEC,GAAA,CAACC,KAAK,EAAA;AACJC,MAAAA,EAAE,EAAEL,OAAQ;MACZM,GAAG,EAAER,KAAK,CAACI,MAAO;AAClBK,MAAAA,SAAS,EAAEN,YAAa;AACxBO,MAAAA,GAAG,EAAEV,KAAK,CAAC,YAAY,CAAC,IAAI;AAAG,KAAA,CAC/B;AAEN,EAAA;EACA,IAAIA,KAAK,EAAEW,MAAM,EAAE;IACjB,MAAMC,KAAK,GAAGZ,KAAK,CAACW,MAAM,CAACC,KAAK,GAC5BZ,KAAK,CAACW,MAAM,CAACC,KAAK,GAClBX,SAAS,KAAK,aAAa,GACzB,EAAE,GACF;AAAEY,MAAAA,MAAM,EAAEZ;KAAW;IAC3B,oBACEI,GAAA,CAACS,UAAU,EAAA;MAAA,GACLd,KAAK,CAACW,MAAM;AAChBC,MAAAA,KAAK,EAAEA,KAAM;MACb,YAAA,EAAYZ,KAAK,CAAC,YAAY,CAAE;MAChC,aAAA,EAAaA,KAAK,CAAC,aAAa,CAAE;AAClCO,MAAAA,EAAE,EAAEL,OAAQ;AACZa,MAAAA,IAAI,EAAE,EAAG;AAAAC,MAAAA,QAAA,EAERhB,KAAK,CAACW,MAAM,CAACM;AAAK,KACT,CAAC;AAEjB,EAAA;AACA,EAAA,OAAOhB,SAAS,KAAK,aAAa,gBAChCI,GAAA,CAACS,UAAU,EAAA;AACTP,IAAAA,EAAE,EAAEL,OAAQ;AACZa,IAAAA,IAAI,EAAE,EAAG;IACT,YAAA,EAAYf,KAAK,CAAC,YAAY,CAAE;IAChC,aAAA,EAAaA,KAAK,CAAC,aAAa,CAAE;AAAAgB,IAAAA,QAAA,eAElCX,GAAA,CAACa,OAAO,EAAA,EAAA;AACV,GAAY,CAAC,gBAEbb,GAAA,CAACc,UAAU,EAAA;AACTZ,IAAAA,EAAE,EAAEL,OAAQ;AACZa,IAAAA,IAAI,EAAE,EAAG;AACTd,IAAAA,SAAS,EAAEA,SAAU;IACrBmB,SAAS,EAAEpB,KAAK,CAAC,aAAa,CAAC,GAAG,IAAI,GAAGA,KAAK,CAAC,YAAY;AAAE,GAAA,CAEhE;AACH;;;;"}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
.wds-critical-banner {
|
|
2
|
-
--Prompt-padding: var(--size-16);
|
|
3
|
-
--Prompt-actions-gap: var(--size-8);
|
|
4
|
-
--Prompt-gap: var(--size-10) var(--size-16);
|
|
5
|
-
--Prompt-border-radius: 0;
|
|
6
|
-
container-type: inline-size;
|
|
7
|
-
--critical-banner-easing: cubic-bezier(0.9, 0, 0.7, 1);
|
|
8
|
-
--critical-banner-duration: 150ms;
|
|
9
|
-
/* Override PrimitivePrompt's --screen-sm-max actions behaviour:
|
|
10
|
-
actions only go full-width below mobile-max token (container query) */
|
|
11
|
-
}
|
|
12
|
-
.wds-critical-banner--media-image {
|
|
13
|
-
width: 48px;
|
|
14
|
-
width: var(--size-48);
|
|
15
|
-
height: 48px;
|
|
16
|
-
height: var(--size-48);
|
|
17
|
-
-o-object-fit: contain;
|
|
18
|
-
object-fit: contain;
|
|
19
|
-
}
|
|
20
|
-
.wds-critical-banner__title {
|
|
21
|
-
display: -webkit-box;
|
|
22
|
-
-webkit-line-clamp: 8;
|
|
23
|
-
line-clamp: 8;
|
|
24
|
-
-webkit-box-orient: vertical;
|
|
25
|
-
max-height: 192px;
|
|
26
|
-
overflow: hidden;
|
|
27
|
-
transition: max-height var(--critical-banner-duration) var(--critical-banner-easing);
|
|
28
|
-
}
|
|
29
|
-
.wds-critical-banner--collapsed .wds-critical-banner__title {
|
|
30
|
-
-webkit-line-clamp: 2;
|
|
31
|
-
line-clamp: 2;
|
|
32
|
-
max-height: 48px;
|
|
33
|
-
}
|
|
34
|
-
.wds-critical-banner__description {
|
|
35
|
-
max-height: 30vh;
|
|
36
|
-
opacity: 1;
|
|
37
|
-
overflow: hidden;
|
|
38
|
-
transition: max-height var(--critical-banner-duration) var(--critical-banner-easing), opacity var(--critical-banner-duration) var(--critical-banner-easing);
|
|
39
|
-
}
|
|
40
|
-
.wds-critical-banner--collapsed .wds-critical-banner__description--with-title {
|
|
41
|
-
max-height: 0;
|
|
42
|
-
opacity: 0;
|
|
43
|
-
}
|
|
44
|
-
.wds-critical-banner--collapsed .wds-critical-banner__description:not(.wds-critical-banner__description--with-title) {
|
|
45
|
-
display: -webkit-box;
|
|
46
|
-
-webkit-line-clamp: 2;
|
|
47
|
-
line-clamp: 2;
|
|
48
|
-
-webkit-box-orient: vertical;
|
|
49
|
-
overflow: hidden;
|
|
50
|
-
}
|
|
51
|
-
.wds-critical-banner .wds-prompt__content-wrapper {
|
|
52
|
-
grid-template-columns: auto 1fr auto;
|
|
53
|
-
align-items: flex-start;
|
|
54
|
-
transition: row-gap var(--critical-banner-duration) var(--critical-banner-easing);
|
|
55
|
-
}
|
|
56
|
-
.wds-critical-banner--collapsed .wds-prompt__content-wrapper {
|
|
57
|
-
row-gap: 0;
|
|
58
|
-
}
|
|
59
|
-
.wds-critical-banner__text-wrapper {
|
|
60
|
-
position: relative;
|
|
61
|
-
display: flex;
|
|
62
|
-
flex-direction: column;
|
|
63
|
-
justify-content: center;
|
|
64
|
-
align-items: flex-start;
|
|
65
|
-
text-align: start;
|
|
66
|
-
min-width: 0;
|
|
67
|
-
max-width: 480px;
|
|
68
|
-
height: 100%;
|
|
69
|
-
padding-top: 3px;
|
|
70
|
-
}
|
|
71
|
-
@media (max-width: 320px) {
|
|
72
|
-
.wds-critical-banner__text-wrapper {
|
|
73
|
-
padding-top: 0;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
@container (--screen-400-zoom) {
|
|
77
|
-
.wds-critical-banner__text-wrapper {
|
|
78
|
-
padding-top: 0px;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
.wds-critical-banner--collapsed .wds-critical-banner__title,
|
|
82
|
-
.wds-critical-banner--collapsed .wds-critical-banner__description {
|
|
83
|
-
transform: translateY(0);
|
|
84
|
-
}
|
|
85
|
-
.wds-critical-banner__toggle {
|
|
86
|
-
flex-shrink: 0;
|
|
87
|
-
transition: transform var(--critical-banner-duration) var(--critical-banner-easing);
|
|
88
|
-
}
|
|
89
|
-
.wds-critical-banner__toggle--collapsed {
|
|
90
|
-
transform: rotate(180deg);
|
|
91
|
-
}
|
|
92
|
-
@container (min-width: 768px) {
|
|
93
|
-
.wds-critical-banner__toggle {
|
|
94
|
-
display: none;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
.wds-critical-banner .wds-prompt__actions-wrapper {
|
|
98
|
-
grid-column-start: 2;
|
|
99
|
-
grid-column-end: 3;
|
|
100
|
-
max-height: 200px;
|
|
101
|
-
opacity: 1;
|
|
102
|
-
overflow: visible;
|
|
103
|
-
}
|
|
104
|
-
@container (max-width: 600px) {
|
|
105
|
-
.wds-critical-banner .wds-prompt__actions-wrapper {
|
|
106
|
-
grid-column: span 3;
|
|
107
|
-
width: 100%;
|
|
108
|
-
}
|
|
109
|
-
.wds-critical-banner .wds-prompt__actions-wrapper .wds-Button {
|
|
110
|
-
flex: 1 1 100%;
|
|
111
|
-
width: 100%;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
.wds-critical-banner--collapsed .wds-prompt__actions-wrapper {
|
|
115
|
-
max-height: 0;
|
|
116
|
-
opacity: 0;
|
|
117
|
-
overflow: hidden;
|
|
118
|
-
pointer-events: none;
|
|
119
|
-
}
|
|
120
|
-
@container (max-width: 600px) {
|
|
121
|
-
.wds-critical-banner--with-two-actions .wds-prompt__actions-wrapper .wds-Button {
|
|
122
|
-
flex: 1 1 calc(50% - (var(--Prompt-actions-gap) / 2));
|
|
123
|
-
min-width: -moz-fit-content;
|
|
124
|
-
min-width: fit-content;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
@media (prefers-reduced-motion: reduce) {
|
|
128
|
-
.wds-critical-banner__description,
|
|
129
|
-
.wds-critical-banner__title,
|
|
130
|
-
.wds-critical-banner .wds-prompt__content-wrapper,
|
|
131
|
-
.wds-critical-banner__toggle {
|
|
132
|
-
transition: none !important;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
File without changes
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook that returns a ref and a boolean indicating if the container
|
|
3
|
-
* has a width >= the specified breakpoint.
|
|
4
|
-
*
|
|
5
|
-
* Useful for synchronizing React state with CSS container queries.
|
|
6
|
-
*
|
|
7
|
-
* Uses content-box measurements to match CSS container query behavior
|
|
8
|
-
* (excludes padding and border).
|
|
9
|
-
*
|
|
10
|
-
* @param breakpoint - Minimum width in pixels
|
|
11
|
-
* @returns [ref, isAboveBreakpoint] tuple
|
|
12
|
-
*/
|
|
13
|
-
export declare function useContainerSize(breakpoint: number): [React.RefObject<HTMLDivElement>, boolean];
|
|
14
|
-
//# sourceMappingURL=useContainerSize.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useContainerSize.d.ts","sourceRoot":"","sources":["../../../../src/common/hooks/useContainerSize.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,CAe/F"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { ButtonProps } from '../../button/Button.types';
|
|
3
|
-
import { PrimitivePromptProps } from '../PrimitivePrompt';
|
|
4
|
-
import { PromptMedia } from '../helpers/promptMedia';
|
|
5
|
-
export type CriticalBannerProps = {
|
|
6
|
-
title?: ReactNode;
|
|
7
|
-
description: ReactNode;
|
|
8
|
-
media?: PromptMedia;
|
|
9
|
-
action?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {
|
|
10
|
-
label: ButtonProps['children'];
|
|
11
|
-
};
|
|
12
|
-
actionSecondary?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {
|
|
13
|
-
label: ButtonProps['children'];
|
|
14
|
-
};
|
|
15
|
-
sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;
|
|
16
|
-
/**
|
|
17
|
-
* Controls whether the description and actions are visible, as a controlled component.
|
|
18
|
-
* When collapsed with a title, only the title is shown.
|
|
19
|
-
* When collapsed without a title, the description is trimmed to 2 lines.
|
|
20
|
-
*
|
|
21
|
-
* Note: On desktop (container width >= 768px), the banner is always expanded
|
|
22
|
-
* regardless of this prop value.
|
|
23
|
-
*/
|
|
24
|
-
expanded?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Called when the user clicks the chevron toggle.
|
|
27
|
-
* If not provided, the component will manage expanded state internally.
|
|
28
|
-
*/
|
|
29
|
-
onToggle?: () => void;
|
|
30
|
-
} & Pick<PrimitivePromptProps, 'id' | 'className' | 'data-testid'>;
|
|
31
|
-
/**
|
|
32
|
-
* A full-width, non-dismissible banner for critical messages such as account blocks or
|
|
33
|
-
* time-sensitive actions that require immediate user attention.
|
|
34
|
-
|
|
35
|
-
* @see {@link https://wise.design/components/critical-banner Design Spec}
|
|
36
|
-
*/
|
|
37
|
-
export declare const CriticalBanner: ({ sentiment, title, description, media, action, actionSecondary, expanded: expandedProp, onToggle, id, className, "data-testid": testId, }: CriticalBannerProps) => import("react").JSX.Element;
|
|
38
|
-
export default CriticalBanner;
|
|
39
|
-
//# sourceMappingURL=CriticalBanner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CriticalBanner.d.ts","sourceRoot":"","sources":["../../../../src/prompt/CriticalBanner/CriticalBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA8B,MAAM,OAAO,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAmB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAqB,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAKxE,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,GAAG;QAC1D,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;KAChC,CAAC;IACF,eAAe,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,GAAG;QACnE,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;KAChC,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,CAAC;IACtE;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,GAAG,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,WAAW,GAAG,aAAa,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,4IAY5B,mBAAmB,gCAoHrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Helper to extract string from ReactNode for announcements.
|
|
4
|
-
* Complex ReactNodes (JSX elements) return empty string.
|
|
5
|
-
*/
|
|
6
|
-
export declare const getStringValue: (node: ReactNode) => string;
|
|
7
|
-
/**
|
|
8
|
-
* Builds the announcement string from visible content only.
|
|
9
|
-
* Content visibility depends on expanded state and presence of title.
|
|
10
|
-
*/
|
|
11
|
-
export declare const buildAnnouncementString: ({ title, description, expanded, actionLabel, actionSecondaryLabel, }: {
|
|
12
|
-
title?: ReactNode;
|
|
13
|
-
description?: ReactNode;
|
|
14
|
-
expanded: boolean;
|
|
15
|
-
actionLabel?: ReactNode;
|
|
16
|
-
actionSecondaryLabel?: ReactNode;
|
|
17
|
-
}) => string;
|
|
18
|
-
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/prompt/CriticalBanner/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,MAKhD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAI,sEAMrC;IACD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,oBAAoB,CAAC,EAAE,SAAS,CAAC;CAClC,KAAG,MASH,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/prompt/CriticalBanner/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export type ExpanderState = {
|
|
2
|
-
expanded: boolean;
|
|
3
|
-
toggle: () => void;
|
|
4
|
-
setExpanded: (expanded: boolean) => void;
|
|
5
|
-
};
|
|
6
|
-
export declare function useExpanderState(initialExpanded?: boolean): ExpanderState;
|
|
7
|
-
export declare function shouldShowWhenExpanded({ expanded, hasContent, alwaysShow, }: {
|
|
8
|
-
expanded: boolean;
|
|
9
|
-
hasContent: boolean;
|
|
10
|
-
alwaysShow?: boolean;
|
|
11
|
-
}): boolean;
|
|
12
|
-
export type ExpanderToggleProps = {
|
|
13
|
-
expanded: boolean;
|
|
14
|
-
onToggle?: () => void;
|
|
15
|
-
size?: 16 | 24 | 32 | 40 | 48 | 56 | 72;
|
|
16
|
-
className?: string;
|
|
17
|
-
'data-testid'?: string;
|
|
18
|
-
};
|
|
19
|
-
export declare const ExpanderToggle: ({ expanded, onToggle, size, className, "data-testid": testId, }: ExpanderToggleProps) => import("react").JSX.Element;
|
|
20
|
-
//# sourceMappingURL=Expander.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Expander.d.ts","sourceRoot":"","sources":["../../../../../src/prompt/common/Expander/Expander.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,CAAC;AAGF,wBAAgB,gBAAgB,CAAC,eAAe,UAAO,GAAG,aAAa,CAYtE;AAGD,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,UAAU,EACV,UAAkB,GACnB,EAAE;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAMV;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAGF,eAAO,MAAM,cAAc,GAAI,iEAM5B,mBAAmB,gCAsBrB,CAAC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
expandAriaLabel: {
|
|
3
|
-
id: string;
|
|
4
|
-
defaultMessage: string;
|
|
5
|
-
description: string;
|
|
6
|
-
};
|
|
7
|
-
collapseAriaLabel: {
|
|
8
|
-
id: string;
|
|
9
|
-
defaultMessage: string;
|
|
10
|
-
description: string;
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export default _default;
|
|
14
|
-
//# sourceMappingURL=Expander.messages.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Expander.messages.d.ts","sourceRoot":"","sources":["../../../../../src/prompt/common/Expander/Expander.messages.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,wBAWG"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { AvatarViewProps } from '../../avatarView';
|
|
3
|
-
import { BadgeAssetsProps } from '../../badge';
|
|
4
|
-
import { PrimitivePromptProps } from '../PrimitivePrompt';
|
|
5
|
-
export type PromptMedia = {
|
|
6
|
-
imgSrc?: string;
|
|
7
|
-
avatar?: Pick<AvatarViewProps, 'imgSrc' | 'profileName' | 'profileType'> & {
|
|
8
|
-
asset?: AvatarViewProps['children'];
|
|
9
|
-
badge?: Pick<BadgeAssetsProps, 'flagCode'>;
|
|
10
|
-
};
|
|
11
|
-
'aria-label'?: string;
|
|
12
|
-
'aria-hidden'?: boolean;
|
|
13
|
-
};
|
|
14
|
-
type RenderPromptMediaOptions = {
|
|
15
|
-
media: PromptMedia;
|
|
16
|
-
sentiment: PrimitivePromptProps['sentiment'];
|
|
17
|
-
mediaId: string;
|
|
18
|
-
imgClassName: string;
|
|
19
|
-
};
|
|
20
|
-
export declare function renderPromptMedia({ media, sentiment, mediaId, imgClassName, }: RenderPromptMediaOptions): ReactNode;
|
|
21
|
-
export {};
|
|
22
|
-
//# sourceMappingURL=promptMedia.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"promptMedia.d.ts","sourceRoot":"","sources":["../../../../src/prompt/helpers/promptMedia.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGlC,OAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAG/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,aAAa,GAAG,aAAa,CAAC,GAAG;QACzE,KAAK,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;QACpC,KAAK,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;KAC5C,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAS,EACT,OAAO,EACP,YAAY,GACb,EAAE,wBAAwB,GAAG,SAAS,CA+CtC"}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import React, { act } from 'react';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
3
|
-
|
|
4
|
-
import { mockResizeObserver } from '../../test-utils/window-mock';
|
|
5
|
-
|
|
6
|
-
import { useContainerSize } from './useContainerSize';
|
|
7
|
-
|
|
8
|
-
mockResizeObserver();
|
|
9
|
-
|
|
10
|
-
describe('useContainerSize', () => {
|
|
11
|
-
let resizeObserverCallback: ResizeObserverCallback | null = null;
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
resizeObserverCallback = null;
|
|
15
|
-
|
|
16
|
-
// Capture the ResizeObserver callback for testing
|
|
17
|
-
const OriginalResizeObserver = global.ResizeObserver;
|
|
18
|
-
global.ResizeObserver = jest.fn().mockImplementation((callback: ResizeObserverCallback) => {
|
|
19
|
-
resizeObserverCallback = callback;
|
|
20
|
-
const instance = new OriginalResizeObserver(callback);
|
|
21
|
-
return instance;
|
|
22
|
-
}) as unknown as typeof ResizeObserver;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// Helper to create a test component
|
|
26
|
-
function TestComponent({
|
|
27
|
-
breakpoint,
|
|
28
|
-
onStateChange,
|
|
29
|
-
}: {
|
|
30
|
-
breakpoint: number;
|
|
31
|
-
onStateChange: (state: boolean) => void;
|
|
32
|
-
}) {
|
|
33
|
-
const [ref, isAboveBreakpoint] = useContainerSize(breakpoint);
|
|
34
|
-
|
|
35
|
-
// Call the callback whenever state changes
|
|
36
|
-
React.useEffect(() => {
|
|
37
|
-
onStateChange(isAboveBreakpoint);
|
|
38
|
-
}, [isAboveBreakpoint, onStateChange]);
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<div ref={ref} data-testid="container">
|
|
42
|
-
Test
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Helper to simulate container resize
|
|
48
|
-
function simulateResize(width: number, options?: { noBorderBoxSize?: boolean }) {
|
|
49
|
-
const container = screen.getByTestId('container');
|
|
50
|
-
|
|
51
|
-
act(() => {
|
|
52
|
-
if (resizeObserverCallback) {
|
|
53
|
-
const entry = {
|
|
54
|
-
target: container,
|
|
55
|
-
borderBoxSize: options?.noBorderBoxSize
|
|
56
|
-
? undefined
|
|
57
|
-
: [{ inlineSize: width, blockSize: 100 }],
|
|
58
|
-
contentRect: {
|
|
59
|
-
width,
|
|
60
|
-
height: 100,
|
|
61
|
-
x: 0,
|
|
62
|
-
y: 0,
|
|
63
|
-
top: 0,
|
|
64
|
-
right: width,
|
|
65
|
-
bottom: 100,
|
|
66
|
-
left: 0,
|
|
67
|
-
toJSON: () => ({}),
|
|
68
|
-
},
|
|
69
|
-
contentBoxSize: [{ inlineSize: width, blockSize: 100 }],
|
|
70
|
-
devicePixelContentBoxSize: [{ inlineSize: width, blockSize: 100 }],
|
|
71
|
-
} as ResizeObserverEntry;
|
|
72
|
-
|
|
73
|
-
resizeObserverCallback([entry], {} as ResizeObserver);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
it('returns initial state as false', () => {
|
|
79
|
-
const onStateChange = jest.fn();
|
|
80
|
-
render(<TestComponent breakpoint={480} onStateChange={onStateChange} />);
|
|
81
|
-
|
|
82
|
-
// Initial call with false
|
|
83
|
-
expect(onStateChange).toHaveBeenCalledWith(false);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('updates to true when container width is above breakpoint', () => {
|
|
87
|
-
const onStateChange = jest.fn();
|
|
88
|
-
render(<TestComponent breakpoint={480} onStateChange={onStateChange} />);
|
|
89
|
-
|
|
90
|
-
simulateResize(600);
|
|
91
|
-
expect(onStateChange).toHaveBeenCalledWith(true);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('remains false when container width is below breakpoint', () => {
|
|
95
|
-
const onStateChange = jest.fn();
|
|
96
|
-
render(<TestComponent breakpoint={480} onStateChange={onStateChange} />);
|
|
97
|
-
|
|
98
|
-
simulateResize(400);
|
|
99
|
-
expect(onStateChange).toHaveBeenCalledWith(false);
|
|
100
|
-
expect(onStateChange).not.toHaveBeenCalledWith(true);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('returns true when container width equals breakpoint', () => {
|
|
104
|
-
const onStateChange = jest.fn();
|
|
105
|
-
render(<TestComponent breakpoint={480} onStateChange={onStateChange} />);
|
|
106
|
-
|
|
107
|
-
simulateResize(480);
|
|
108
|
-
expect(onStateChange).toHaveBeenCalledWith(true);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('updates state when container crosses breakpoint from below to above', () => {
|
|
112
|
-
const onStateChange = jest.fn();
|
|
113
|
-
render(<TestComponent breakpoint={480} onStateChange={onStateChange} />);
|
|
114
|
-
|
|
115
|
-
simulateResize(400);
|
|
116
|
-
expect(onStateChange).toHaveBeenCalledWith(false);
|
|
117
|
-
|
|
118
|
-
simulateResize(600);
|
|
119
|
-
expect(onStateChange).toHaveBeenCalledWith(true);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { useRef, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import { useResizeObserver } from './useResizeObserver';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Hook that returns a ref and a boolean indicating if the container
|
|
7
|
-
* has a width >= the specified breakpoint.
|
|
8
|
-
*
|
|
9
|
-
* Useful for synchronizing React state with CSS container queries.
|
|
10
|
-
*
|
|
11
|
-
* Uses content-box measurements to match CSS container query behavior
|
|
12
|
-
* (excludes padding and border).
|
|
13
|
-
*
|
|
14
|
-
* @param breakpoint - Minimum width in pixels
|
|
15
|
-
* @returns [ref, isAboveBreakpoint] tuple
|
|
16
|
-
*/
|
|
17
|
-
export function useContainerSize(breakpoint: number): [React.RefObject<HTMLDivElement>, boolean] {
|
|
18
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
19
|
-
const [isAboveBreakpoint, setIsAboveBreakpoint] = useState(false);
|
|
20
|
-
|
|
21
|
-
useResizeObserver(
|
|
22
|
-
ref,
|
|
23
|
-
(entry) => {
|
|
24
|
-
// Use contentRect.width to match CSS container query box model (content-box)
|
|
25
|
-
const inlineSize = entry.contentRect.width;
|
|
26
|
-
setIsAboveBreakpoint(inlineSize >= breakpoint);
|
|
27
|
-
},
|
|
28
|
-
'content-box',
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
return [ref, isAboveBreakpoint];
|
|
32
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { Meta, Source, Canvas } from '@storybook/addon-docs/blocks';
|
|
2
|
-
import * as CriticalBannerStories from './CriticalBanner.story';
|
|
3
|
-
|
|
4
|
-
<Meta title="Prompts/CriticalBanner/Accessibility" tags={['new']} />
|
|
5
|
-
|
|
6
|
-
# Accessibility
|
|
7
|
-
|
|
8
|
-
Under the hood, `CriticalBanner` is marked as `role="region"` for a section of content that users might want to navigate to directly.
|
|
9
|
-
|
|
10
|
-
By default, it's labelled by the `title` and described by the `description`.
|
|
11
|
-
|
|
12
|
-
## Announcement Behavior
|
|
13
|
-
|
|
14
|
-
`CriticalBanner` is designed for critical messages that require immediate attention. It always uses **`aria-live="assertive"`** to immediately interrupt and announce changes to screen readers.
|
|
15
|
-
|
|
16
|
-
Unlike `InfoPrompt` which offers configurable politeness levels, `CriticalBanner` is always assertive because it communicates critical, time-sensitive information that users must be aware of immediately.
|
|
17
|
-
|
|
18
|
-
### What Gets Announced
|
|
19
|
-
|
|
20
|
-
The component intelligently announces only **visible content**, respecting the collapsed/expanded state:
|
|
21
|
-
|
|
22
|
-
- **Collapsed with title**: Announces title only (description is hidden)
|
|
23
|
-
- **Collapsed without title**: Announces description only (visible up to 2 lines)
|
|
24
|
-
- **Expanded**: Announces title, description, and action button labels (all visible)
|
|
25
|
-
|
|
26
|
-
<Source
|
|
27
|
-
dark
|
|
28
|
-
code={`
|
|
29
|
-
// Collapsed with title - announces: "Your account requires verification"
|
|
30
|
-
<CriticalBanner
|
|
31
|
-
title="Your account requires verification"
|
|
32
|
-
description="Please verify your identity to continue"
|
|
33
|
-
action={{ label: "Verify now", onClick: handleVerify }}
|
|
34
|
-
expanded={false}
|
|
35
|
-
onToggle={handleToggle}
|
|
36
|
-
/>
|
|
37
|
-
|
|
38
|
-
// Expanded - announces: "Your account requires verification | Please verify your identity to continue | Verify now | Learn more"
|
|
39
|
-
|
|
40
|
-
<CriticalBanner
|
|
41
|
-
title="Your account requires verification"
|
|
42
|
-
description="Please verify your identity to continue"
|
|
43
|
-
action={{ label: 'Verify now', onClick: handleVerify }}
|
|
44
|
-
actionSecondary={{ label: 'Learn more', onClick: handleLearnMore }}
|
|
45
|
-
expanded={true}
|
|
46
|
-
onToggle={handleToggle}
|
|
47
|
-
/>
|
|
48
|
-
|
|
49
|
-
// Collapsed without title - announces: "Your verification is pending..."
|
|
50
|
-
|
|
51
|
-
<CriticalBanner
|
|
52
|
-
description="Your verification is pending. We'll notify you once complete."
|
|
53
|
-
expanded={false}
|
|
54
|
-
onToggle={handleToggle}
|
|
55
|
-
/>
|
|
56
|
-
`}
|
|
57
|
-
/>
|
|
58
|
-
|
|
59
|
-
### When Announcements Trigger
|
|
60
|
-
|
|
61
|
-
Screen readers announce the banner content whenever:
|
|
62
|
-
|
|
63
|
-
- The banner first appears in the DOM
|
|
64
|
-
- The user toggles between collapsed and expanded states
|
|
65
|
-
- The content (title, description, or action labels) changes
|
|
66
|
-
|
|
67
|
-
## Media
|
|
68
|
-
|
|
69
|
-
Custom media icons should include their own accessibility attributes. Use the `title` prop on icons to provide accessible names for screen readers:
|
|
70
|
-
|
|
71
|
-
<Source
|
|
72
|
-
dark
|
|
73
|
-
code={`
|
|
74
|
-
import { Bank, AlertCircle } from '@transferwise/icons';
|
|
75
|
-
|
|
76
|
-
<CriticalBanner
|
|
77
|
-
title="Bank connection required"
|
|
78
|
-
description="Connect your bank account to continue"
|
|
79
|
-
media={{ avatar: { asset: <Bank title="Bank account" /> } }}
|
|
80
|
-
action={{ label: 'Connect now', onClick: handleConnect }}
|
|
81
|
-
expanded={false}
|
|
82
|
-
onToggle={handleToggle}
|
|
83
|
-
/>
|
|
84
|
-
|
|
85
|
-
<CriticalBanner
|
|
86
|
-
title="Verification required"
|
|
87
|
-
description="We need to verify your identity"
|
|
88
|
-
media={{ avatar: { asset: <AlertCircle title="Alert" /> } }}
|
|
89
|
-
action={{ label: "Start verification", onClick: handleVerify }}
|
|
90
|
-
expanded={false}
|
|
91
|
-
onToggle={handleToggle}
|
|
92
|
-
/>
|
|
93
|
-
`}
|
|
94
|
-
/>
|
|
95
|
-
|
|
96
|
-
Alternatively, you can use `media['aria-label']` to provide a label for custom images:
|
|
97
|
-
|
|
98
|
-
<Source
|
|
99
|
-
dark
|
|
100
|
-
code={`
|
|
101
|
-
<CriticalBanner
|
|
102
|
-
title="Card blocked"
|
|
103
|
-
description="Your card has been blocked for security reasons"
|
|
104
|
-
media={{
|
|
105
|
-
imgSrc: '/wise-card.svg',
|
|
106
|
-
'aria-label': 'Wise debit card'
|
|
107
|
-
}}
|
|
108
|
-
action={{ label: "Unblock card", onClick: handleUnblock }}
|
|
109
|
-
expanded={false}
|
|
110
|
-
onToggle={handleToggle}
|
|
111
|
-
/>
|
|
112
|
-
`}
|
|
113
|
-
/>
|