@transferwise/components 0.0.0-experimental-8f088b2 → 0.0.0-experimental-8dc58ec

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.
@@ -43,6 +43,7 @@ const CriticalBanner = ({
43
43
  media = {},
44
44
  action,
45
45
  actionSecondary,
46
+ animateEntry = true,
46
47
  expanded: expandedProp,
47
48
  onToggle,
48
49
  id,
@@ -141,7 +142,15 @@ const CriticalBanner = ({
141
142
  }),
142
143
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
143
144
  className: "wds-critical-banner-overhang-query",
144
- children: bannerSurface
145
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
146
+ className: clsx.clsx('wds-critical-banner__entry-mask', {
147
+ 'wds-critical-banner__entry-mask--animated': animateEntry
148
+ }),
149
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
150
+ className: "wds-critical-banner__entry-track",
151
+ children: bannerSurface
152
+ })
153
+ })
145
154
  })
146
155
  });
147
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CriticalBanner.js","sources":["../../../src/Prompt/CriticalBanner/CriticalBanner.tsx"],"sourcesContent":["import { ElementType, ReactNode, useId, useState } from 'react';\nimport { clsx } from 'clsx';\n\nimport Body from '../../Body';\nimport Button from '../../Button';\nimport Container from '../../Container';\nimport { Breakpoint, LiveRegion, Typography } from '../../common';\nimport { ButtonProps } from '../../Button/Button.types';\nimport { PrimitivePrompt, PrimitivePromptProps } from '../PrimitivePrompt';\n\nimport { renderPromptMedia, PromptMedia } from '../helpers/promptMedia';\nimport { ExpanderToggle } from '../common/Expander/Expander';\nimport { buildAnnouncementString } from './helpers';\nimport { useContainerSize } from '../../common/hooks/useContainerSize';\n\nexport type CriticalBannerProps = {\n title?: ReactNode;\n description: ReactNode;\n media?: PromptMedia;\n action?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n actionSecondary?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;\n /**\n * Controls whether the description and actions are visible, as a controlled component.\n * When collapsed with a title, only the title is shown.\n * When collapsed without a title, the description is trimmed to 2 lines.\n *\n * Note: On desktop (container width >= 768px), the banner is always expanded\n * regardless of this prop value.\n */\n expanded?: boolean;\n /**\n * Called when the user clicks the chevron toggle.\n * If not provided, the component will manage expanded state internally.\n */\n onToggle?: () => void;\n} & Pick<PrimitivePromptProps, 'id' | 'className' | 'data-testid'>;\n\n/**\n * A full-width, non-dismissible banner for critical messages such as account blocks or\n * time-sensitive actions that require immediate user attention.\n\n * @see {@link https://docs.wise.design/components/critical-banner Design Spec}\n */\nexport const CriticalBanner = ({\n sentiment = 'negative',\n title,\n description,\n media = {},\n action,\n actionSecondary,\n expanded: expandedProp,\n onToggle,\n id,\n className,\n 'data-testid': testId,\n}: CriticalBannerProps) => {\n const [containerRef, isDesktop] = useContainerSize(Breakpoint.MEDIUM);\n const isControlled = expandedProp !== undefined && onToggle !== undefined;\n const [internalExpanded, setInternalExpanded] = useState(true);\n const resolvedExpanded = isDesktop ? true : isControlled ? expandedProp : internalExpanded;\n const handleToggle = isControlled\n ? onToggle\n : () => setInternalExpanded((previousExpanded) => !previousExpanded);\n const hasActions = action ?? actionSecondary;\n const mediaId = useId();\n const titleId = useId();\n const descId = useId();\n\n const ariaLabelledByIds = [\n media['aria-hidden'] ? undefined : mediaId,\n !title ? undefined : titleId,\n ]\n .filter(Boolean)\n .join(' ');\n\n const bannerSurface = (\n <Container\n ref={containerRef}\n size=\"fluid\"\n as={PrimitivePrompt as ElementType}\n id={id}\n sentiment={sentiment}\n emphasis={sentiment === 'neutral' ? 'base' : 'elevated'}\n data-testid={testId}\n className={clsx(\n 'wds-critical-banner',\n 'wds-critical-banner-overhang',\n {\n 'wds-critical-banner--collapsed': !resolvedExpanded,\n 'wds-critical-banner--with-two-actions': !!actionSecondary,\n },\n className,\n )}\n media={renderPromptMedia({\n media,\n sentiment,\n mediaId,\n imgClassName: 'wds-critical-banner--media-image',\n })}\n actions={\n hasActions ? (\n <div aria-hidden={!resolvedExpanded ? true : undefined} style={{ display: 'contents' }}>\n {actionSecondary && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"secondary\"\n href={actionSecondary.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={actionSecondary?.onClick}\n >\n {actionSecondary.label}\n </Button>\n )}\n {action && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"primary\"\n href={action.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n )}\n </div>\n ) : undefined\n }\n role=\"region\"\n aria-labelledby={ariaLabelledByIds || undefined}\n aria-describedby={description ? descId : undefined}\n >\n <div className=\"wds-critical-banner__text-wrapper\">\n {title && (\n <Body\n id={titleId}\n type={Typography.BODY_LARGE_BOLD}\n className=\"wds-critical-banner__content wds-critical-banner__title\"\n >\n {title}\n </Body>\n )}\n {description && (\n <Body\n id={descId}\n className={clsx('wds-critical-banner__content', 'wds-critical-banner__description', {\n 'wds-critical-banner__description--with-title': !!title,\n })}\n >\n {description}\n </Body>\n )}\n </div>\n <ExpanderToggle\n expanded={resolvedExpanded}\n size={24}\n className=\"wds-critical-banner__toggle\"\n onToggle={handleToggle}\n />\n </Container>\n );\n\n return (\n <LiveRegion\n aria-live=\"assertive\"\n announceOnChange={buildAnnouncementString({\n title,\n description,\n expanded: resolvedExpanded,\n actionLabel: action?.label,\n actionSecondaryLabel: actionSecondary?.label,\n })}\n >\n <div className=\"wds-critical-banner-overhang-query\">{bannerSurface}</div>\n </LiveRegion>\n );\n};\n\nexport default CriticalBanner;\n"],"names":["CriticalBanner","sentiment","title","description","media","action","actionSecondary","expanded","expandedProp","onToggle","id","className","testId","containerRef","isDesktop","useContainerSize","Breakpoint","MEDIUM","isControlled","undefined","internalExpanded","setInternalExpanded","useState","resolvedExpanded","handleToggle","previousExpanded","hasActions","mediaId","useId","titleId","descId","ariaLabelledByIds","filter","Boolean","join","bannerSurface","_jsxs","Container","ref","size","as","PrimitivePrompt","emphasis","clsx","renderPromptMedia","imgClassName","actions","style","display","children","_jsx","Button","v2","priority","href","tabIndex","onClick","label","role","Body","type","Typography","BODY_LARGE_BOLD","ExpanderToggle","LiveRegion","announceOnChange","buildAnnouncementString","actionLabel","actionSecondaryLabel"],"mappings":"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"}
1
+ {"version":3,"file":"CriticalBanner.js","sources":["../../../src/Prompt/CriticalBanner/CriticalBanner.tsx"],"sourcesContent":["import { ElementType, ReactNode, useId, useState } from 'react';\nimport { clsx } from 'clsx';\n\nimport Body from '../../Body';\nimport Button from '../../Button';\nimport Container from '../../Container';\nimport { Breakpoint, LiveRegion, Typography } from '../../common';\nimport { ButtonProps } from '../../Button/Button.types';\nimport { PrimitivePrompt, PrimitivePromptProps } from '../PrimitivePrompt';\n\nimport { renderPromptMedia, PromptMedia } from '../helpers/promptMedia';\nimport { ExpanderToggle } from '../common/Expander/Expander';\nimport { buildAnnouncementString } from './helpers';\nimport { useContainerSize } from '../../common/hooks/useContainerSize';\n\nexport type CriticalBannerProps = {\n title?: ReactNode;\n description: ReactNode;\n media?: PromptMedia;\n action?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n actionSecondary?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;\n /**\n * Controls whether the banner plays its entry animation 500ms after mounting.\n * Expand and collapse animations are unaffected.\n */\n animateEntry?: boolean;\n /**\n * Controls whether the description and actions are visible, as a controlled component.\n * When collapsed with a title, only the title is shown.\n * When collapsed without a title, the description is trimmed to 2 lines.\n *\n * Note: On desktop (container width >= 768px), the banner is always expanded\n * regardless of this prop value.\n */\n expanded?: boolean;\n /**\n * Called when the user clicks the chevron toggle.\n * If not provided, the component will manage expanded state internally.\n */\n onToggle?: () => void;\n} & Pick<PrimitivePromptProps, 'id' | 'className' | 'data-testid'>;\n\n/**\n * A full-width, non-dismissible banner for critical messages such as account blocks or\n * time-sensitive actions that require immediate user attention.\n\n * @see {@link https://docs.wise.design/components/critical-banner Design Spec}\n */\nexport const CriticalBanner = ({\n sentiment = 'negative',\n title,\n description,\n media = {},\n action,\n actionSecondary,\n animateEntry = true,\n expanded: expandedProp,\n onToggle,\n id,\n className,\n 'data-testid': testId,\n}: CriticalBannerProps) => {\n const [containerRef, isDesktop] = useContainerSize(Breakpoint.MEDIUM);\n const isControlled = expandedProp !== undefined && onToggle !== undefined;\n const [internalExpanded, setInternalExpanded] = useState(true);\n const resolvedExpanded = isDesktop ? true : isControlled ? expandedProp : internalExpanded;\n const handleToggle = isControlled\n ? onToggle\n : () => setInternalExpanded((previousExpanded) => !previousExpanded);\n const hasActions = action ?? actionSecondary;\n const mediaId = useId();\n const titleId = useId();\n const descId = useId();\n\n const ariaLabelledByIds = [\n media['aria-hidden'] ? undefined : mediaId,\n !title ? undefined : titleId,\n ]\n .filter(Boolean)\n .join(' ');\n\n const bannerSurface = (\n <Container\n ref={containerRef}\n size=\"fluid\"\n as={PrimitivePrompt as ElementType}\n id={id}\n sentiment={sentiment}\n emphasis={sentiment === 'neutral' ? 'base' : 'elevated'}\n data-testid={testId}\n className={clsx(\n 'wds-critical-banner',\n 'wds-critical-banner-overhang',\n {\n 'wds-critical-banner--collapsed': !resolvedExpanded,\n 'wds-critical-banner--with-two-actions': !!actionSecondary,\n },\n className,\n )}\n media={renderPromptMedia({\n media,\n sentiment,\n mediaId,\n imgClassName: 'wds-critical-banner--media-image',\n })}\n actions={\n hasActions ? (\n <div aria-hidden={!resolvedExpanded ? true : undefined} style={{ display: 'contents' }}>\n {actionSecondary && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"secondary\"\n href={actionSecondary.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={actionSecondary?.onClick}\n >\n {actionSecondary.label}\n </Button>\n )}\n {action && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"primary\"\n href={action.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n )}\n </div>\n ) : undefined\n }\n role=\"region\"\n aria-labelledby={ariaLabelledByIds || undefined}\n aria-describedby={description ? descId : undefined}\n >\n <div className=\"wds-critical-banner__text-wrapper\">\n {title && (\n <Body\n id={titleId}\n type={Typography.BODY_LARGE_BOLD}\n className=\"wds-critical-banner__content wds-critical-banner__title\"\n >\n {title}\n </Body>\n )}\n {description && (\n <Body\n id={descId}\n className={clsx('wds-critical-banner__content', 'wds-critical-banner__description', {\n 'wds-critical-banner__description--with-title': !!title,\n })}\n >\n {description}\n </Body>\n )}\n </div>\n <ExpanderToggle\n expanded={resolvedExpanded}\n size={24}\n className=\"wds-critical-banner__toggle\"\n onToggle={handleToggle}\n />\n </Container>\n );\n\n return (\n <LiveRegion\n aria-live=\"assertive\"\n announceOnChange={buildAnnouncementString({\n title,\n description,\n expanded: resolvedExpanded,\n actionLabel: action?.label,\n actionSecondaryLabel: actionSecondary?.label,\n })}\n >\n <div className=\"wds-critical-banner-overhang-query\">\n <div\n className={clsx('wds-critical-banner__entry-mask', {\n 'wds-critical-banner__entry-mask--animated': animateEntry,\n })}\n >\n <div className=\"wds-critical-banner__entry-track\">{bannerSurface}</div>\n </div>\n </div>\n </LiveRegion>\n );\n};\n\nexport default CriticalBanner;\n"],"names":["CriticalBanner","sentiment","title","description","media","action","actionSecondary","animateEntry","expanded","expandedProp","onToggle","id","className","testId","containerRef","isDesktop","useContainerSize","Breakpoint","MEDIUM","isControlled","undefined","internalExpanded","setInternalExpanded","useState","resolvedExpanded","handleToggle","previousExpanded","hasActions","mediaId","useId","titleId","descId","ariaLabelledByIds","filter","Boolean","join","bannerSurface","_jsxs","Container","ref","size","as","PrimitivePrompt","emphasis","clsx","renderPromptMedia","imgClassName","actions","style","display","children","_jsx","Button","v2","priority","href","tabIndex","onClick","label","role","Body","type","Typography","BODY_LARGE_BOLD","ExpanderToggle","LiveRegion","announceOnChange","buildAnnouncementString","actionLabel","actionSecondaryLabel"],"mappings":"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"}
@@ -41,6 +41,7 @@ const CriticalBanner = ({
41
41
  media = {},
42
42
  action,
43
43
  actionSecondary,
44
+ animateEntry = true,
44
45
  expanded: expandedProp,
45
46
  onToggle,
46
47
  id,
@@ -139,7 +140,15 @@ const CriticalBanner = ({
139
140
  }),
140
141
  children: /*#__PURE__*/jsx("div", {
141
142
  className: "wds-critical-banner-overhang-query",
142
- children: bannerSurface
143
+ children: /*#__PURE__*/jsx("div", {
144
+ className: clsx('wds-critical-banner__entry-mask', {
145
+ 'wds-critical-banner__entry-mask--animated': animateEntry
146
+ }),
147
+ children: /*#__PURE__*/jsx("div", {
148
+ className: "wds-critical-banner__entry-track",
149
+ children: bannerSurface
150
+ })
151
+ })
143
152
  })
144
153
  });
145
154
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CriticalBanner.mjs","sources":["../../../src/Prompt/CriticalBanner/CriticalBanner.tsx"],"sourcesContent":["import { ElementType, ReactNode, useId, useState } from 'react';\nimport { clsx } from 'clsx';\n\nimport Body from '../../Body';\nimport Button from '../../Button';\nimport Container from '../../Container';\nimport { Breakpoint, LiveRegion, Typography } from '../../common';\nimport { ButtonProps } from '../../Button/Button.types';\nimport { PrimitivePrompt, PrimitivePromptProps } from '../PrimitivePrompt';\n\nimport { renderPromptMedia, PromptMedia } from '../helpers/promptMedia';\nimport { ExpanderToggle } from '../common/Expander/Expander';\nimport { buildAnnouncementString } from './helpers';\nimport { useContainerSize } from '../../common/hooks/useContainerSize';\n\nexport type CriticalBannerProps = {\n title?: ReactNode;\n description: ReactNode;\n media?: PromptMedia;\n action?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n actionSecondary?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;\n /**\n * Controls whether the description and actions are visible, as a controlled component.\n * When collapsed with a title, only the title is shown.\n * When collapsed without a title, the description is trimmed to 2 lines.\n *\n * Note: On desktop (container width >= 768px), the banner is always expanded\n * regardless of this prop value.\n */\n expanded?: boolean;\n /**\n * Called when the user clicks the chevron toggle.\n * If not provided, the component will manage expanded state internally.\n */\n onToggle?: () => void;\n} & Pick<PrimitivePromptProps, 'id' | 'className' | 'data-testid'>;\n\n/**\n * A full-width, non-dismissible banner for critical messages such as account blocks or\n * time-sensitive actions that require immediate user attention.\n\n * @see {@link https://docs.wise.design/components/critical-banner Design Spec}\n */\nexport const CriticalBanner = ({\n sentiment = 'negative',\n title,\n description,\n media = {},\n action,\n actionSecondary,\n expanded: expandedProp,\n onToggle,\n id,\n className,\n 'data-testid': testId,\n}: CriticalBannerProps) => {\n const [containerRef, isDesktop] = useContainerSize(Breakpoint.MEDIUM);\n const isControlled = expandedProp !== undefined && onToggle !== undefined;\n const [internalExpanded, setInternalExpanded] = useState(true);\n const resolvedExpanded = isDesktop ? true : isControlled ? expandedProp : internalExpanded;\n const handleToggle = isControlled\n ? onToggle\n : () => setInternalExpanded((previousExpanded) => !previousExpanded);\n const hasActions = action ?? actionSecondary;\n const mediaId = useId();\n const titleId = useId();\n const descId = useId();\n\n const ariaLabelledByIds = [\n media['aria-hidden'] ? undefined : mediaId,\n !title ? undefined : titleId,\n ]\n .filter(Boolean)\n .join(' ');\n\n const bannerSurface = (\n <Container\n ref={containerRef}\n size=\"fluid\"\n as={PrimitivePrompt as ElementType}\n id={id}\n sentiment={sentiment}\n emphasis={sentiment === 'neutral' ? 'base' : 'elevated'}\n data-testid={testId}\n className={clsx(\n 'wds-critical-banner',\n 'wds-critical-banner-overhang',\n {\n 'wds-critical-banner--collapsed': !resolvedExpanded,\n 'wds-critical-banner--with-two-actions': !!actionSecondary,\n },\n className,\n )}\n media={renderPromptMedia({\n media,\n sentiment,\n mediaId,\n imgClassName: 'wds-critical-banner--media-image',\n })}\n actions={\n hasActions ? (\n <div aria-hidden={!resolvedExpanded ? true : undefined} style={{ display: 'contents' }}>\n {actionSecondary && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"secondary\"\n href={actionSecondary.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={actionSecondary?.onClick}\n >\n {actionSecondary.label}\n </Button>\n )}\n {action && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"primary\"\n href={action.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n )}\n </div>\n ) : undefined\n }\n role=\"region\"\n aria-labelledby={ariaLabelledByIds || undefined}\n aria-describedby={description ? descId : undefined}\n >\n <div className=\"wds-critical-banner__text-wrapper\">\n {title && (\n <Body\n id={titleId}\n type={Typography.BODY_LARGE_BOLD}\n className=\"wds-critical-banner__content wds-critical-banner__title\"\n >\n {title}\n </Body>\n )}\n {description && (\n <Body\n id={descId}\n className={clsx('wds-critical-banner__content', 'wds-critical-banner__description', {\n 'wds-critical-banner__description--with-title': !!title,\n })}\n >\n {description}\n </Body>\n )}\n </div>\n <ExpanderToggle\n expanded={resolvedExpanded}\n size={24}\n className=\"wds-critical-banner__toggle\"\n onToggle={handleToggle}\n />\n </Container>\n );\n\n return (\n <LiveRegion\n aria-live=\"assertive\"\n announceOnChange={buildAnnouncementString({\n title,\n description,\n expanded: resolvedExpanded,\n actionLabel: action?.label,\n actionSecondaryLabel: actionSecondary?.label,\n })}\n >\n <div className=\"wds-critical-banner-overhang-query\">{bannerSurface}</div>\n </LiveRegion>\n );\n};\n\nexport default CriticalBanner;\n"],"names":["CriticalBanner","sentiment","title","description","media","action","actionSecondary","expanded","expandedProp","onToggle","id","className","testId","containerRef","isDesktop","useContainerSize","Breakpoint","MEDIUM","isControlled","undefined","internalExpanded","setInternalExpanded","useState","resolvedExpanded","handleToggle","previousExpanded","hasActions","mediaId","useId","titleId","descId","ariaLabelledByIds","filter","Boolean","join","bannerSurface","_jsxs","Container","ref","size","as","PrimitivePrompt","emphasis","clsx","renderPromptMedia","imgClassName","actions","style","display","children","_jsx","Button","v2","priority","href","tabIndex","onClick","label","role","Body","type","Typography","BODY_LARGE_BOLD","ExpanderToggle","LiveRegion","announceOnChange","buildAnnouncementString","actionLabel","actionSecondaryLabel"],"mappings":"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"}
1
+ {"version":3,"file":"CriticalBanner.mjs","sources":["../../../src/Prompt/CriticalBanner/CriticalBanner.tsx"],"sourcesContent":["import { ElementType, ReactNode, useId, useState } from 'react';\nimport { clsx } from 'clsx';\n\nimport Body from '../../Body';\nimport Button from '../../Button';\nimport Container from '../../Container';\nimport { Breakpoint, LiveRegion, Typography } from '../../common';\nimport { ButtonProps } from '../../Button/Button.types';\nimport { PrimitivePrompt, PrimitivePromptProps } from '../PrimitivePrompt';\n\nimport { renderPromptMedia, PromptMedia } from '../helpers/promptMedia';\nimport { ExpanderToggle } from '../common/Expander/Expander';\nimport { buildAnnouncementString } from './helpers';\nimport { useContainerSize } from '../../common/hooks/useContainerSize';\n\nexport type CriticalBannerProps = {\n title?: ReactNode;\n description: ReactNode;\n media?: PromptMedia;\n action?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n actionSecondary?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {\n label: ButtonProps['children'];\n };\n sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;\n /**\n * Controls whether the banner plays its entry animation 500ms after mounting.\n * Expand and collapse animations are unaffected.\n */\n animateEntry?: boolean;\n /**\n * Controls whether the description and actions are visible, as a controlled component.\n * When collapsed with a title, only the title is shown.\n * When collapsed without a title, the description is trimmed to 2 lines.\n *\n * Note: On desktop (container width >= 768px), the banner is always expanded\n * regardless of this prop value.\n */\n expanded?: boolean;\n /**\n * Called when the user clicks the chevron toggle.\n * If not provided, the component will manage expanded state internally.\n */\n onToggle?: () => void;\n} & Pick<PrimitivePromptProps, 'id' | 'className' | 'data-testid'>;\n\n/**\n * A full-width, non-dismissible banner for critical messages such as account blocks or\n * time-sensitive actions that require immediate user attention.\n\n * @see {@link https://docs.wise.design/components/critical-banner Design Spec}\n */\nexport const CriticalBanner = ({\n sentiment = 'negative',\n title,\n description,\n media = {},\n action,\n actionSecondary,\n animateEntry = true,\n expanded: expandedProp,\n onToggle,\n id,\n className,\n 'data-testid': testId,\n}: CriticalBannerProps) => {\n const [containerRef, isDesktop] = useContainerSize(Breakpoint.MEDIUM);\n const isControlled = expandedProp !== undefined && onToggle !== undefined;\n const [internalExpanded, setInternalExpanded] = useState(true);\n const resolvedExpanded = isDesktop ? true : isControlled ? expandedProp : internalExpanded;\n const handleToggle = isControlled\n ? onToggle\n : () => setInternalExpanded((previousExpanded) => !previousExpanded);\n const hasActions = action ?? actionSecondary;\n const mediaId = useId();\n const titleId = useId();\n const descId = useId();\n\n const ariaLabelledByIds = [\n media['aria-hidden'] ? undefined : mediaId,\n !title ? undefined : titleId,\n ]\n .filter(Boolean)\n .join(' ');\n\n const bannerSurface = (\n <Container\n ref={containerRef}\n size=\"fluid\"\n as={PrimitivePrompt as ElementType}\n id={id}\n sentiment={sentiment}\n emphasis={sentiment === 'neutral' ? 'base' : 'elevated'}\n data-testid={testId}\n className={clsx(\n 'wds-critical-banner',\n 'wds-critical-banner-overhang',\n {\n 'wds-critical-banner--collapsed': !resolvedExpanded,\n 'wds-critical-banner--with-two-actions': !!actionSecondary,\n },\n className,\n )}\n media={renderPromptMedia({\n media,\n sentiment,\n mediaId,\n imgClassName: 'wds-critical-banner--media-image',\n })}\n actions={\n hasActions ? (\n <div aria-hidden={!resolvedExpanded ? true : undefined} style={{ display: 'contents' }}>\n {actionSecondary && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"secondary\"\n href={actionSecondary.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={actionSecondary?.onClick}\n >\n {actionSecondary.label}\n </Button>\n )}\n {action && (\n // @ts-expect-error onClick type mismatch\n <Button\n v2\n size=\"md\"\n priority=\"primary\"\n href={action.href}\n tabIndex={resolvedExpanded ? undefined : -1}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n )}\n </div>\n ) : undefined\n }\n role=\"region\"\n aria-labelledby={ariaLabelledByIds || undefined}\n aria-describedby={description ? descId : undefined}\n >\n <div className=\"wds-critical-banner__text-wrapper\">\n {title && (\n <Body\n id={titleId}\n type={Typography.BODY_LARGE_BOLD}\n className=\"wds-critical-banner__content wds-critical-banner__title\"\n >\n {title}\n </Body>\n )}\n {description && (\n <Body\n id={descId}\n className={clsx('wds-critical-banner__content', 'wds-critical-banner__description', {\n 'wds-critical-banner__description--with-title': !!title,\n })}\n >\n {description}\n </Body>\n )}\n </div>\n <ExpanderToggle\n expanded={resolvedExpanded}\n size={24}\n className=\"wds-critical-banner__toggle\"\n onToggle={handleToggle}\n />\n </Container>\n );\n\n return (\n <LiveRegion\n aria-live=\"assertive\"\n announceOnChange={buildAnnouncementString({\n title,\n description,\n expanded: resolvedExpanded,\n actionLabel: action?.label,\n actionSecondaryLabel: actionSecondary?.label,\n })}\n >\n <div className=\"wds-critical-banner-overhang-query\">\n <div\n className={clsx('wds-critical-banner__entry-mask', {\n 'wds-critical-banner__entry-mask--animated': animateEntry,\n })}\n >\n <div className=\"wds-critical-banner__entry-track\">{bannerSurface}</div>\n </div>\n </div>\n </LiveRegion>\n );\n};\n\nexport default CriticalBanner;\n"],"names":["CriticalBanner","sentiment","title","description","media","action","actionSecondary","animateEntry","expanded","expandedProp","onToggle","id","className","testId","containerRef","isDesktop","useContainerSize","Breakpoint","MEDIUM","isControlled","undefined","internalExpanded","setInternalExpanded","useState","resolvedExpanded","handleToggle","previousExpanded","hasActions","mediaId","useId","titleId","descId","ariaLabelledByIds","filter","Boolean","join","bannerSurface","_jsxs","Container","ref","size","as","PrimitivePrompt","emphasis","clsx","renderPromptMedia","imgClassName","actions","style","display","children","_jsx","Button","v2","priority","href","tabIndex","onClick","label","role","Body","type","Typography","BODY_LARGE_BOLD","ExpanderToggle","LiveRegion","announceOnChange","buildAnnouncementString","actionLabel","actionSecondaryLabel"],"mappings":"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"}
package/build/main.css CHANGED
@@ -25129,6 +25129,35 @@ button.np-link {
25129
25129
  mask: var(--critical-banner-overhang-mask);
25130
25130
  }
25131
25131
  }
25132
+ .wds-critical-banner__entry-mask {
25133
+ display: grid;
25134
+ grid-template-rows: 1fr;
25135
+ overflow: visible;
25136
+ }
25137
+ .wds-critical-banner__entry-mask--animated {
25138
+ grid-template-rows: 0fr;
25139
+ overflow: hidden;
25140
+ animation: wds-critical-banner-reveal-height 400ms cubic-bezier(0.3, 0, 0.1, 1) 500ms both, wds-critical-banner-release-overflow 1ms linear 899ms both;
25141
+ }
25142
+ .wds-critical-banner__entry-track {
25143
+ min-block-size: 0;
25144
+ }
25145
+ @keyframes wds-critical-banner-reveal-height {
25146
+ from {
25147
+ grid-template-rows: 0fr;
25148
+ }
25149
+ to {
25150
+ grid-template-rows: 1fr;
25151
+ }
25152
+ }
25153
+ @keyframes wds-critical-banner-release-overflow {
25154
+ from {
25155
+ overflow: hidden;
25156
+ }
25157
+ to {
25158
+ overflow: visible;
25159
+ }
25160
+ }
25132
25161
  @media (prefers-reduced-motion: reduce) {
25133
25162
  .wds-critical-banner__description,
25134
25163
  .wds-critical-banner__title,
@@ -25136,6 +25165,11 @@ button.np-link {
25136
25165
  .wds-critical-banner__toggle {
25137
25166
  transition: none !important;
25138
25167
  }
25168
+ .wds-critical-banner__entry-mask--animated {
25169
+ animation: none;
25170
+ grid-template-rows: 1fr;
25171
+ overflow: visible;
25172
+ }
25139
25173
  }
25140
25174
  .wds-expander-toggle {
25141
25175
  align-self: flex-start;
@@ -155,6 +155,35 @@
155
155
  mask: var(--critical-banner-overhang-mask);
156
156
  }
157
157
  }
158
+ .wds-critical-banner__entry-mask {
159
+ display: grid;
160
+ grid-template-rows: 1fr;
161
+ overflow: visible;
162
+ }
163
+ .wds-critical-banner__entry-mask--animated {
164
+ grid-template-rows: 0fr;
165
+ overflow: hidden;
166
+ animation: wds-critical-banner-reveal-height 400ms cubic-bezier(0.3, 0, 0.1, 1) 500ms both, wds-critical-banner-release-overflow 1ms linear 899ms both;
167
+ }
168
+ .wds-critical-banner__entry-track {
169
+ min-block-size: 0;
170
+ }
171
+ @keyframes wds-critical-banner-reveal-height {
172
+ from {
173
+ grid-template-rows: 0fr;
174
+ }
175
+ to {
176
+ grid-template-rows: 1fr;
177
+ }
178
+ }
179
+ @keyframes wds-critical-banner-release-overflow {
180
+ from {
181
+ overflow: hidden;
182
+ }
183
+ to {
184
+ overflow: visible;
185
+ }
186
+ }
158
187
  @media (prefers-reduced-motion: reduce) {
159
188
  .wds-critical-banner__description,
160
189
  .wds-critical-banner__title,
@@ -162,4 +191,9 @@
162
191
  .wds-critical-banner__toggle {
163
192
  transition: none !important;
164
193
  }
194
+ .wds-critical-banner__entry-mask--animated {
195
+ animation: none;
196
+ grid-template-rows: 1fr;
197
+ overflow: visible;
198
+ }
165
199
  }
@@ -25129,6 +25129,35 @@ button.np-link {
25129
25129
  mask: var(--critical-banner-overhang-mask);
25130
25130
  }
25131
25131
  }
25132
+ .wds-critical-banner__entry-mask {
25133
+ display: grid;
25134
+ grid-template-rows: 1fr;
25135
+ overflow: visible;
25136
+ }
25137
+ .wds-critical-banner__entry-mask--animated {
25138
+ grid-template-rows: 0fr;
25139
+ overflow: hidden;
25140
+ animation: wds-critical-banner-reveal-height 400ms cubic-bezier(0.3, 0, 0.1, 1) 500ms both, wds-critical-banner-release-overflow 1ms linear 899ms both;
25141
+ }
25142
+ .wds-critical-banner__entry-track {
25143
+ min-block-size: 0;
25144
+ }
25145
+ @keyframes wds-critical-banner-reveal-height {
25146
+ from {
25147
+ grid-template-rows: 0fr;
25148
+ }
25149
+ to {
25150
+ grid-template-rows: 1fr;
25151
+ }
25152
+ }
25153
+ @keyframes wds-critical-banner-release-overflow {
25154
+ from {
25155
+ overflow: hidden;
25156
+ }
25157
+ to {
25158
+ overflow: visible;
25159
+ }
25160
+ }
25132
25161
  @media (prefers-reduced-motion: reduce) {
25133
25162
  .wds-critical-banner__description,
25134
25163
  .wds-critical-banner__title,
@@ -25136,6 +25165,11 @@ button.np-link {
25136
25165
  .wds-critical-banner__toggle {
25137
25166
  transition: none !important;
25138
25167
  }
25168
+ .wds-critical-banner__entry-mask--animated {
25169
+ animation: none;
25170
+ grid-template-rows: 1fr;
25171
+ overflow: visible;
25172
+ }
25139
25173
  }
25140
25174
  .wds-expander-toggle {
25141
25175
  align-self: flex-start;
@@ -11,7 +11,7 @@ export type BodyProps = HTMLAttributes<HTMLSpanElement | HTMLParagraphElement> &
11
11
  */
12
12
  preserveNewlines?: boolean;
13
13
  };
14
- declare const Body: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement | HTMLParagraphElement> & {
14
+ declare const Body: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement | HTMLSpanElement> & {
15
15
  /** @default 'body-default' */
16
16
  type?: BodyTypes;
17
17
  /** @default 'div' */
@@ -21,6 +21,6 @@ declare const Body: import("react").ForwardRefExoticComponent<HTMLAttributes<HTM
21
21
  * @default false
22
22
  */
23
23
  preserveNewlines?: boolean;
24
- } & import("react").RefAttributes<HTMLDivElement | HTMLSpanElement | HTMLParagraphElement | null>>;
24
+ } & import("react").RefAttributes<HTMLDivElement | HTMLParagraphElement | HTMLSpanElement | null>>;
25
25
  export default Body;
26
26
  //# sourceMappingURL=Body.d.ts.map
@@ -16,6 +16,6 @@ declare const IconButton: import("react").ForwardRefExoticComponent<{
16
16
  /** @default 'default' */
17
17
  type?: "default" | "negative";
18
18
  'data-testid'?: string;
19
- } & Pick<AnchorHTMLAttributes<HTMLAnchorElement>, "onClick" | "target" | "href"> & Pick<ButtonHTMLAttributes<HTMLButtonElement>, "disabled" | "onClick"> & Pick<HTMLAttributes<HTMLDivElement>, "children" | "className" | "id" | "tabIndex" | "role" | "aria-label"> & import("react").RefAttributes<unknown>>;
19
+ } & Pick<AnchorHTMLAttributes<HTMLAnchorElement>, "onClick" | "target" | "href"> & Pick<ButtonHTMLAttributes<HTMLButtonElement>, "disabled" | "onClick"> & Pick<HTMLAttributes<HTMLDivElement>, "id" | "className" | "tabIndex" | "role" | "aria-label" | "children"> & import("react").RefAttributes<unknown>>;
20
20
  export default IconButton;
21
21
  //# sourceMappingURL=IconButton.d.ts.map
@@ -55,6 +55,7 @@ declare const _default: import("react").FC<{
55
55
  selectProps?: Partial<SelectInputProps<CurrencyOptionItem>> | undefined;
56
56
  amount: number | null;
57
57
  searchPlaceholder?: string | undefined;
58
+ decimals?: number | undefined;
58
59
  currencies: readonly CurrencyItem[];
59
60
  selectedCurrency: CurrencyOptionItem;
60
61
  onCurrencyChange?: ((value: CurrencyOptionItem) => void) | undefined;
@@ -66,7 +67,6 @@ declare const _default: import("react").FC<{
66
67
  }) => void) | undefined;
67
68
  customActionLabel?: import("react").ReactNode;
68
69
  onCustomAction?: (() => void) | undefined;
69
- decimals?: number | undefined;
70
70
  }>;
71
71
  export default _default;
72
72
  //# sourceMappingURL=MoneyInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MoneyInput.d.ts","sourceRoot":"","sources":["../../../src/MoneyInput/MoneyInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAGL,SAAS,EACT,UAAU,EACV,SAAS,EAEV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAuB,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,EAKL,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAoDnE,MAAM,WAAW,eAAgB,SAAQ,qBAAqB;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IACpC,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3F,iBAAiB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kCAAkC,GAAG,eAAe,GAC9D,OAAO,CAAC,wBAAwB,CAAC,CAAC;;SA5B7B,MAAM;wBACS,MAAM;YAMnB,SAAS,GAAG,UAAU,GAAG,SAAS;kBAF3B,MAAM;iBAYP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;kBACrB,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;YAZnD,MAAM,GAAG,IAAI;wBAID,MAAM;gBARd,SAAS,YAAY,EAAE;sBACjB,kBAAkB;wBACjB,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI;sBAIrC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;sBAM9B,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI;;sBAEzE,MAAM,IAAI;eAQhB,MAAM;;AAyanB,wBAA2F"}
1
+ {"version":3,"file":"MoneyInput.d.ts","sourceRoot":"","sources":["../../../src/MoneyInput/MoneyInput.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAGL,SAAS,EACT,UAAU,EACV,SAAS,EAEV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAuB,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnF,OAAO,EAKL,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAO/B,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAoDnE,MAAM,WAAW,eAAgB,SAAQ,qBAAqB;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IACpC,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3F,iBAAiB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kCAAkC,GAAG,eAAe,GAC9D,OAAO,CAAC,wBAAwB,CAAC,CAAC;;SA5B7B,MAAM;wBACS,MAAM;YAMnB,SAAS,GAAG,UAAU,GAAG,SAAS;kBAF3B,MAAM;iBAYP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;kBACrB,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;YAZnD,MAAM,GAAG,IAAI;wBAID,MAAM;eAcf,MAAM;gBAtBL,SAAS,YAAY,EAAE;sBACjB,kBAAkB;wBACjB,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI;sBAIrC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;;sBAM9B,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,YAAY,EAAE,CAAA;KAAE,KAAK,IAAI;;sBAEzE,MAAM,IAAI;;AAib7B,wBAA2F"}
@@ -13,6 +13,11 @@ export type CriticalBannerProps = {
13
13
  label: ButtonProps['children'];
14
14
  };
15
15
  sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;
16
+ /**
17
+ * Controls whether the banner plays its entry animation 500ms after mounting.
18
+ * Expand and collapse animations are unaffected.
19
+ */
20
+ animateEntry?: boolean;
16
21
  /**
17
22
  * Controls whether the description and actions are visible, as a controlled component.
18
23
  * When collapsed with a title, only the title is shown.
@@ -34,6 +39,6 @@ export type CriticalBannerProps = {
34
39
 
35
40
  * @see {@link https://docs.wise.design/components/critical-banner Design Spec}
36
41
  */
37
- export declare const CriticalBanner: ({ sentiment, title, description, media, action, actionSecondary, expanded: expandedProp, onToggle, id, className, "data-testid": testId, }: CriticalBannerProps) => import("react").JSX.Element;
42
+ export declare const CriticalBanner: ({ sentiment, title, description, media, action, actionSecondary, animateEntry, expanded: expandedProp, onToggle, id, className, "data-testid": testId, }: CriticalBannerProps) => import("react").JSX.Element;
38
43
  export default CriticalBanner;
39
44
  //# sourceMappingURL=CriticalBanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CriticalBanner.d.ts","sourceRoot":"","sources":["../../../../src/Prompt/CriticalBanner/CriticalBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAmB,MAAM,OAAO,CAAC;AAOhE,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,gCA4HrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"CriticalBanner.d.ts","sourceRoot":"","sources":["../../../../src/Prompt/CriticalBanner/CriticalBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAmB,MAAM,OAAO,CAAC;AAOhE,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;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;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,0JAa5B,mBAAmB,gCAoIrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -10,7 +10,7 @@ export type TitleProps = LabelHTMLAttributes<HTMLHeadingElement | HTMLSpanElemen
10
10
  */
11
11
  type?: TitleTypes;
12
12
  };
13
- declare const Title: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<HTMLSpanElement | HTMLHeadingElement | HTMLLabelElement> & React.LiHTMLAttributes<HTMLLIElement> & {
13
+ declare const Title: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<HTMLHeadingElement | HTMLLabelElement | HTMLSpanElement> & React.LiHTMLAttributes<HTMLLIElement> & {
14
14
  /**
15
15
  * Default value will based one `type` prop
16
16
  */
@@ -19,6 +19,6 @@ declare const Title: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<H
19
19
  * Default value: {@link DEFAULT_TYPE}
20
20
  */
21
21
  type?: TitleTypes;
22
- } & React.RefAttributes<HTMLSpanElement | HTMLHeadingElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement>>;
22
+ } & React.RefAttributes<HTMLHeadingElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement | HTMLSpanElement>>;
23
23
  export default Title;
24
24
  //# sourceMappingURL=Title.d.ts.map
@@ -15,7 +15,7 @@ export default class UploadImageStep extends PureComponent<UploadImageStepProps>
15
15
  uploadInputRef: import("react").RefObject<HTMLInputElement>;
16
16
  onManualUpload: () => void;
17
17
  onKeyDown: (event: React.KeyboardEvent<HTMLLabelElement>) => void;
18
- getImage: () => number | true | import("react").JSX.Element | Iterable<import("react").ReactNode>;
18
+ getImage: () => number | true | Iterable<import("react").ReactNode> | import("react").JSX.Element;
19
19
  render(): import("react").JSX.Element;
20
20
  }
21
21
  //# sourceMappingURL=UploadImageStep.d.ts.map
@@ -5,5 +5,5 @@ export declare const UploadItemLink: import("react").ForwardRefExoticComponent<{
5
5
  singleFileUpload: boolean;
6
6
  } & {
7
7
  children?: import("react").ReactNode | undefined;
8
- } & import("react").RefAttributes<HTMLDivElement | HTMLAnchorElement>>;
8
+ } & import("react").RefAttributes<HTMLAnchorElement | HTMLDivElement>>;
9
9
  //# sourceMappingURL=UploadItemLink.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-8f088b2",
3
+ "version": "0.0.0-experimental-8dc58ec",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -155,6 +155,35 @@
155
155
  mask: var(--critical-banner-overhang-mask);
156
156
  }
157
157
  }
158
+ .wds-critical-banner__entry-mask {
159
+ display: grid;
160
+ grid-template-rows: 1fr;
161
+ overflow: visible;
162
+ }
163
+ .wds-critical-banner__entry-mask--animated {
164
+ grid-template-rows: 0fr;
165
+ overflow: hidden;
166
+ animation: wds-critical-banner-reveal-height 400ms cubic-bezier(0.3, 0, 0.1, 1) 500ms both, wds-critical-banner-release-overflow 1ms linear 899ms both;
167
+ }
168
+ .wds-critical-banner__entry-track {
169
+ min-block-size: 0;
170
+ }
171
+ @keyframes wds-critical-banner-reveal-height {
172
+ from {
173
+ grid-template-rows: 0fr;
174
+ }
175
+ to {
176
+ grid-template-rows: 1fr;
177
+ }
178
+ }
179
+ @keyframes wds-critical-banner-release-overflow {
180
+ from {
181
+ overflow: hidden;
182
+ }
183
+ to {
184
+ overflow: visible;
185
+ }
186
+ }
158
187
  @media (prefers-reduced-motion: reduce) {
159
188
  .wds-critical-banner__description,
160
189
  .wds-critical-banner__title,
@@ -162,4 +191,9 @@
162
191
  .wds-critical-banner__toggle {
163
192
  transition: none !important;
164
193
  }
194
+ .wds-critical-banner__entry-mask--animated {
195
+ animation: none;
196
+ grid-template-rows: 1fr;
197
+ overflow: visible;
198
+ }
165
199
  }
@@ -193,6 +193,45 @@
193
193
  }
194
194
  }
195
195
 
196
+ .wds-critical-banner__entry-mask {
197
+ display: grid;
198
+ grid-template-rows: 1fr;
199
+ overflow: visible;
200
+
201
+ // Clip only during the reveal, then release overflow so actions remain visible.
202
+ &--animated {
203
+ grid-template-rows: 0fr;
204
+ overflow: hidden;
205
+ animation:
206
+ wds-critical-banner-reveal-height 400ms cubic-bezier(0.3, 0, 0.1, 1) 500ms both,
207
+ wds-critical-banner-release-overflow 1ms linear 899ms both;
208
+ }
209
+ }
210
+
211
+ .wds-critical-banner__entry-track {
212
+ min-height: 0;
213
+ }
214
+
215
+ @keyframes wds-critical-banner-reveal-height {
216
+ from {
217
+ grid-template-rows: 0fr;
218
+ }
219
+
220
+ to {
221
+ grid-template-rows: 1fr;
222
+ }
223
+ }
224
+
225
+ @keyframes wds-critical-banner-release-overflow {
226
+ from {
227
+ overflow: hidden;
228
+ }
229
+
230
+ to {
231
+ overflow: visible;
232
+ }
233
+ }
234
+
196
235
  // Reduced motion support
197
236
  @media (prefers-reduced-motion: reduce) {
198
237
  .wds-critical-banner__description,
@@ -201,4 +240,10 @@
201
240
  .wds-critical-banner__toggle {
202
241
  transition: none !important;
203
242
  }
243
+
244
+ .wds-critical-banner__entry-mask--animated {
245
+ animation: none;
246
+ grid-template-rows: 1fr;
247
+ overflow: visible;
248
+ }
204
249
  }
@@ -15,7 +15,7 @@ describe('CriticalBanner', () => {
15
15
  resetLiveRegionAnnouncementQueue();
16
16
  });
17
17
 
18
- it('renders mobile overhang markup without entry animation markup', () => {
18
+ it('applies mobile overhang classes by default', () => {
19
19
  const { container } = render(
20
20
  <CriticalBanner {...defaultProps} data-testid="critical-banner" />,
21
21
  );
@@ -23,7 +23,30 @@ describe('CriticalBanner', () => {
23
23
  expect(screen.getByTestId('critical-banner')).toBeInTheDocument();
24
24
  expect(container.querySelector('.wds-critical-banner-overhang')).toBeInTheDocument();
25
25
  expect(container.querySelector('.wds-critical-banner-overhang-query')).toBeInTheDocument();
26
- expect(container.querySelector('.wds-critical-banner__entry-mask')).not.toBeInTheDocument();
27
- expect(container.querySelector('.wds-critical-banner__entry-track')).not.toBeInTheDocument();
26
+ });
27
+
28
+ it('applies the entry animation by default', () => {
29
+ const { container } = render(
30
+ <CriticalBanner {...defaultProps} data-testid="critical-banner" />,
31
+ );
32
+
33
+ expect(screen.getByTestId('critical-banner')).toBeInTheDocument();
34
+ expect(
35
+ container.querySelector('.wds-critical-banner__entry-mask--animated'),
36
+ ).toBeInTheDocument();
37
+ expect(container.querySelector('.wds-critical-banner__entry-track')).toBeInTheDocument();
38
+ });
39
+
40
+ it('can render without the entry animation', () => {
41
+ const { container } = render(
42
+ <CriticalBanner {...defaultProps} animateEntry={false} data-testid="critical-banner" />,
43
+ );
44
+
45
+ expect(screen.getByTestId('critical-banner')).toBeInTheDocument();
46
+ expect(container.querySelector('.wds-critical-banner__entry-mask')).toBeInTheDocument();
47
+ expect(
48
+ container.querySelector('.wds-critical-banner__entry-mask--animated'),
49
+ ).not.toBeInTheDocument();
50
+ expect(container.querySelector('.wds-critical-banner__entry-track')).toBeInTheDocument();
28
51
  });
29
52
  });
@@ -24,6 +24,11 @@ export type CriticalBannerProps = {
24
24
  label: ButtonProps['children'];
25
25
  };
26
26
  sentiment?: Exclude<PrimitivePromptProps['sentiment'], 'proposition'>;
27
+ /**
28
+ * Controls whether the banner plays its entry animation 500ms after mounting.
29
+ * Expand and collapse animations are unaffected.
30
+ */
31
+ animateEntry?: boolean;
27
32
  /**
28
33
  * Controls whether the description and actions are visible, as a controlled component.
29
34
  * When collapsed with a title, only the title is shown.
@@ -53,6 +58,7 @@ export const CriticalBanner = ({
53
58
  media = {},
54
59
  action,
55
60
  actionSecondary,
61
+ animateEntry = true,
56
62
  expanded: expandedProp,
57
63
  onToggle,
58
64
  id,
@@ -179,7 +185,15 @@ export const CriticalBanner = ({
179
185
  actionSecondaryLabel: actionSecondary?.label,
180
186
  })}
181
187
  >
182
- <div className="wds-critical-banner-overhang-query">{bannerSurface}</div>
188
+ <div className="wds-critical-banner-overhang-query">
189
+ <div
190
+ className={clsx('wds-critical-banner__entry-mask', {
191
+ 'wds-critical-banner__entry-mask--animated': animateEntry,
192
+ })}
193
+ >
194
+ <div className="wds-critical-banner__entry-track">{bannerSurface}</div>
195
+ </div>
196
+ </div>
183
197
  </LiveRegion>
184
198
  );
185
199
  };
@@ -66,7 +66,10 @@ Screen readers announce the banner content whenever:
66
66
 
67
67
  ## Reduced Motion
68
68
 
69
- `CriticalBanner` respects the user's reduced motion preference. When reduced motion is on, the component does not show the collapse and expand animation used when the user toggles the banner content.
69
+ `CriticalBanner` respects the user's reduced motion preference. When reduced motion is on, the component does not show:
70
+
71
+ - the entry animation that reveals the banner from above when it first appears
72
+ - the collapse and expand animation used when the user toggles the banner content
70
73
 
71
74
  The same content is still rendered and announced. Reduced motion only removes the visual movement.
72
75
 
@@ -28,6 +28,7 @@ const meta = {
28
28
  action: { label: 'Verify now', onClick: fn() },
29
29
  actionSecondary: undefined,
30
30
  media: undefined,
31
+ animateEntry: true,
31
32
  id: undefined,
32
33
  className: undefined,
33
34
  'data-testid': undefined,
@@ -47,6 +48,7 @@ const meta = {
47
48
  table: { type: { summary: 'ReactNode' } },
48
49
  },
49
50
  expanded: { control: 'boolean' },
51
+ animateEntry: { control: 'boolean' },
50
52
  media: {
51
53
  control: false,
52
54
  description: 'Replaces the default Status Icon with a custom image or AvatarView.',
@@ -131,12 +133,28 @@ const hiddenArgTypes = {
131
133
  actionSecondary: { table: { disable: true } },
132
134
  media: { table: { disable: true } },
133
135
  expanded: { table: { disable: true } },
136
+ animateEntry: { table: { disable: true } },
134
137
  onToggle: { table: { disable: true } },
135
138
  id: { table: { disable: true } },
136
139
  className: { table: { disable: true } },
137
140
  'data-testid': { table: { disable: true } },
138
141
  } as const;
139
142
 
143
+ const AnimatedEntryPreview = (args: CriticalBannerProps) => {
144
+ const [bannerInstance, setBannerInstance] = useState(0);
145
+
146
+ return (
147
+ <>
148
+ <CriticalBanner key={bannerInstance} {...args} />
149
+ <div className="p-t-3">
150
+ <Button block v2 onClick={() => setBannerInstance((current) => current + 1)}>
151
+ Replay
152
+ </Button>
153
+ </div>
154
+ </>
155
+ );
156
+ };
157
+
140
158
  /** Renders children inside an iframe that inherits the parent page's stylesheets. */
141
159
  function IframeContainer({ width, children }: { width: number; children: ReactNode }) {
142
160
  const iframeRef = useRef<HTMLIFrameElement>(null);
@@ -585,6 +603,40 @@ export const MobileOverhang: Story = {
585
603
  },
586
604
  };
587
605
 
606
+ /** The banner waits 500ms, then reveals from above when it enters the page. */
607
+ export const AnimatedEntry: Story = {
608
+ args: {
609
+ title: 'Your account is restricted.',
610
+ description: 'Review your personal details to get your account active again.',
611
+ action: { label: 'Review details', onClick: fn() },
612
+ },
613
+ argTypes: hiddenArgTypes,
614
+ render: (args) => <AnimatedEntryPreview {...args} />,
615
+ parameters: {
616
+ layout: 'fullscreen',
617
+ docs: {
618
+ canvas: { sourceState: 'hidden' },
619
+ },
620
+ },
621
+ };
622
+
623
+ /** The banner can mount immediately without replaying its entry animation. */
624
+ export const WithoutEntryAnimation: Story = {
625
+ args: {
626
+ animateEntry: false,
627
+ title: 'Your account is restricted.',
628
+ description: 'Review your personal details to get your account active again.',
629
+ action: { label: 'Review details', onClick: fn() },
630
+ },
631
+ argTypes: hiddenArgTypes,
632
+ parameters: {
633
+ layout: 'fullscreen',
634
+ docs: {
635
+ canvas: { sourceState: 'hidden' },
636
+ },
637
+ },
638
+ };
639
+
588
640
  /**
589
641
  * The text container is capped at 480px for optimal readability, even though
590
642
  * the banner itself stretches to the full available width.
@@ -22,6 +22,7 @@ const wait = async (ms: number) =>
22
22
  });
23
23
 
24
24
  const ANIMATION_DURATION = 200; // 150ms animation + 50ms buffer
25
+ const ENTRY_ANIMATION_DURATION = 950; // 500ms delay + 400ms animation + 50ms buffer
25
26
 
26
27
  const longDescription =
27
28
  'We have detected unusual activity on your account that does not match your typical usage patterns. To protect your funds and personal information, we have temporarily restricted access. Please verify your identity to restore full access to your account.';
@@ -151,7 +152,7 @@ export const MobileVariants: Story = {
151
152
  ...withVariantConfig(['mobile']),
152
153
  };
153
154
 
154
- /** Neutral background regression test with page content scrolled under the mobile overhang. */
155
+ /** Neutral background regression test with page content scrolled under the sticky banner. */
155
156
  export const BackgroundIsNotTransparent: Story = {
156
157
  args: {
157
158
  sentiment: 'neutral',
@@ -198,6 +199,7 @@ export const BackgroundIsNotTransparent: Story = {
198
199
 
199
200
  if (scrollContainer) {
200
201
  scrollContainer.scrollTop = 250;
202
+ await wait(ENTRY_ANIMATION_DURATION);
201
203
  }
202
204
  },
203
205
  ...withVariantConfig(['mobile'], {
@@ -207,6 +209,25 @@ export const BackgroundIsNotTransparent: Story = {
207
209
  }),
208
210
  };
209
211
 
212
+ /** Mobile entry animation visual regression test. */
213
+ export const AnimatedEntryMobile: Story = {
214
+ render: function Render() {
215
+ return (
216
+ <CriticalBanner
217
+ sentiment="negative"
218
+ title="Your account is restricted."
219
+ description="Review your personal details to get your account active again."
220
+ action={{ label: 'Review details', onClick: fn() }}
221
+ />
222
+ );
223
+ },
224
+ ...withVariantConfig(['mobile'], {
225
+ parameters: {
226
+ chromatic: { pauseAnimationAtEnd: true },
227
+ },
228
+ }),
229
+ };
230
+
210
231
  /**
211
232
  * Tests keyboard navigation and interaction:
212
233
  * - Tab focuses the first chevron toggle button
package/src/main.css CHANGED
@@ -25129,6 +25129,35 @@ button.np-link {
25129
25129
  mask: var(--critical-banner-overhang-mask);
25130
25130
  }
25131
25131
  }
25132
+ .wds-critical-banner__entry-mask {
25133
+ display: grid;
25134
+ grid-template-rows: 1fr;
25135
+ overflow: visible;
25136
+ }
25137
+ .wds-critical-banner__entry-mask--animated {
25138
+ grid-template-rows: 0fr;
25139
+ overflow: hidden;
25140
+ animation: wds-critical-banner-reveal-height 400ms cubic-bezier(0.3, 0, 0.1, 1) 500ms both, wds-critical-banner-release-overflow 1ms linear 899ms both;
25141
+ }
25142
+ .wds-critical-banner__entry-track {
25143
+ min-block-size: 0;
25144
+ }
25145
+ @keyframes wds-critical-banner-reveal-height {
25146
+ from {
25147
+ grid-template-rows: 0fr;
25148
+ }
25149
+ to {
25150
+ grid-template-rows: 1fr;
25151
+ }
25152
+ }
25153
+ @keyframes wds-critical-banner-release-overflow {
25154
+ from {
25155
+ overflow: hidden;
25156
+ }
25157
+ to {
25158
+ overflow: visible;
25159
+ }
25160
+ }
25132
25161
  @media (prefers-reduced-motion: reduce) {
25133
25162
  .wds-critical-banner__description,
25134
25163
  .wds-critical-banner__title,
@@ -25136,6 +25165,11 @@ button.np-link {
25136
25165
  .wds-critical-banner__toggle {
25137
25166
  transition: none !important;
25138
25167
  }
25168
+ .wds-critical-banner__entry-mask--animated {
25169
+ animation: none;
25170
+ grid-template-rows: 1fr;
25171
+ overflow: visible;
25172
+ }
25139
25173
  }
25140
25174
  .wds-expander-toggle {
25141
25175
  align-self: flex-start;