@transferwise/components 0.0.0-experimental-dcb657b → 0.0.0-experimental-bb877d0

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.
@@ -39,22 +39,27 @@ function resolveType(type) {
39
39
  }
40
40
  }
41
41
  function Alert({
42
- arrow,
43
42
  action,
44
- children,
45
43
  className,
46
- dismissible,
47
44
  icon,
48
45
  statusIconLabel,
49
46
  onDismiss,
50
47
  message,
51
- size: size$1,
52
48
  title,
53
49
  type = 'neutral',
54
50
  variant = 'desktop',
55
- active = true,
56
- dynamicRender = false
51
+ arrow,
52
+ children,
53
+ size: size$1,
54
+ dismissible,
55
+ active,
56
+ dynamicRender
57
57
  }) {
58
+ React.useEffect(() => {
59
+ if (active !== undefined || dynamicRender !== undefined) {
60
+ logActionRequired.logActionRequired("Alert component doesn't support `active` or `dynamicRender` anymore, please remove that prop.");
61
+ }
62
+ }, [active, dynamicRender]);
58
63
  React.useEffect(() => {
59
64
  if (arrow !== undefined) {
60
65
  logActionRequired.logActionRequired("Alert component doesn't support 'arrow' anymore, use 'InlineAlert' instead.");
@@ -82,19 +87,18 @@ function Alert({
82
87
  }
83
88
  }, [resolvedType, type]);
84
89
  const [shouldFire, setShouldFire] = React.useState();
85
- const [shouldShow, setShouldShow] = React.useState();
90
+ const [shouldAnnounce, setShouldAnnounce] = React.useState(false);
86
91
  React.useEffect(() => {
87
- if (shouldShow === undefined && !dynamicRender || !active) {
88
- setShouldShow(active);
89
- } else {
90
- setTimeout(() => setShouldShow(active), constants.WDS_LIVE_REGION_DELAY_MS);
91
- }
92
- }, [active, shouldShow, dynamicRender]);
92
+ setTimeout(() => {
93
+ setShouldAnnounce(true);
94
+ }, constants.WDS_LIVE_REGION_DELAY_MS);
95
+ }, []);
93
96
  const closeButtonReference = React.useRef(null);
94
97
  return /*#__PURE__*/jsxRuntime.jsx("div", {
95
98
  role: resolvedType === sentiment.Sentiment.NEGATIVE ? 'alert' : 'status',
96
99
  className: "wds-alert__liveRegion",
97
- children: shouldShow && /*#__PURE__*/jsxRuntime.jsxs("div", {
100
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
101
+ "aria-hidden": shouldAnnounce ? undefined : 'true',
98
102
  className: clsx.clsx('alert d-flex', `alert-${resolvedType}`, arrow != null && alertArrowClassNames(arrow), className),
99
103
  "data-testid": "alert",
100
104
  onTouchStart: () => setShouldFire(true),
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.js","sources":["../../src/alert/Alert.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useState, useRef, useEffect } from 'react';\n\nimport Body from '../body/Body';\nimport {\n CloseButton,\n Sentiment,\n Size,\n Typography,\n Variant,\n WDS_LIVE_REGION_DELAY_MS,\n} from '../common';\n\nimport StatusIcon from '../statusIcon';\nimport Title from '../title/Title';\nimport { logActionRequired } from '../utilities';\n\nimport InlineMarkdown from './inlineMarkdown';\nimport { Action } from '../common/action/Action';\n\nexport type AlertAction = {\n 'aria-label'?: string;\n href?: string;\n target?: string;\n text: React.ReactNode;\n onClick?: () => void;\n};\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype AlertTypeDeprecated = `${Sentiment.SUCCESS | Sentiment.INFO | Sentiment.ERROR}`;\ntype AlertTypeResolved = `${\n | Sentiment.POSITIVE\n | Sentiment.NEUTRAL\n | Sentiment.WARNING\n | Sentiment.NEGATIVE}`;\nexport type AlertType = AlertTypeResolved | AlertTypeDeprecated;\n\nexport enum AlertArrowPosition {\n TOP_LEFT = 'up-left',\n TOP = 'up-center',\n TOP_RIGHT = 'up-right',\n BOTTOM_LEFT = 'down-left',\n BOTTOM = 'down-center',\n BOTTOM_RIGHT = 'down-right',\n}\n\nexport interface AlertProps {\n /** An optional call to action to sit under the main body of the alert. If your label is short, use aria-label to provide more context */\n action?: AlertAction;\n className?: string;\n /** An optional icon. If not provided, we will default the icon to something appropriate for the type */\n icon?: React.ReactNode;\n /**\n * Override for [StatusIcon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n statusIconLabel?: string;\n /** Title for the alert component */\n title?: string;\n /** The main body of the alert. Accepts plain text and bold words specified with **double stars */\n message?: string;\n /** The presence of the onDismiss handler will trigger the visibility of the close button */\n onDismiss?: React.MouseEventHandler<HTMLButtonElement>;\n /** The type dictates which icon and colour will be used */\n type?: AlertType;\n variant?: `${Variant}`;\n /**\n * Controls rendering of the Alert component. <br />\n * Toggle this prop instead using conditional rendering and logical AND (&&)\n * operator, to make the component work with screen readers.\n * */\n active?: boolean;\n /**\n * Toggle this prop when dealing with multiple, dynamic Alerts, to make them\n * work with screen readers. This is especially helpful for the BFF use cases.\n * */\n dynamicRender?: boolean;\n /** @deprecated Use `InlineAlert` instead. */\n arrow?: `${AlertArrowPosition}`;\n /** @deprecated Use `message` instead. Be aware `message` only accepts plain text or text with **bold** markdown. */\n children?: React.ReactNode;\n /** @deprecated Use `onDismiss` instead. */\n dismissible?: boolean;\n /** @deprecated Alert component doesn't support `size` anymore, please remove this prop. */\n size?: `${Size}`;\n}\n\nfunction resolveType(type: AlertType): AlertTypeResolved {\n switch (type) {\n case 'success':\n return 'positive';\n case 'info':\n return 'neutral';\n case 'error':\n return 'negative';\n default:\n return type;\n }\n}\n\nexport default function Alert({\n arrow,\n action,\n children,\n className,\n dismissible,\n icon,\n statusIconLabel,\n onDismiss,\n message,\n size,\n title,\n type = 'neutral',\n variant = 'desktop',\n active = true,\n dynamicRender = false,\n}: AlertProps) {\n useEffect(() => {\n if (arrow !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'arrow' anymore, use 'InlineAlert' instead.\",\n );\n }\n }, [arrow]);\n\n useEffect(() => {\n if (children !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'children' anymore, use 'message' instead.\",\n );\n }\n }, [children]);\n\n useEffect(() => {\n if (dismissible !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'dismissible' anymore, use 'onDismiss' instead.\",\n );\n }\n }, [dismissible]);\n\n useEffect(() => {\n if (size !== undefined) {\n logActionRequired(\"Alert component doesn't support 'size' anymore, please remove that prop.\");\n }\n }, [size]);\n\n const resolvedType = resolveType(type);\n useEffect(() => {\n if (resolvedType !== type) {\n logActionRequired(\n `Alert component has deprecated '${type}' value for the 'type' prop. Please use '${resolvedType}' instead.`,\n );\n }\n }, [resolvedType, type]);\n\n const [shouldFire, setShouldFire] = useState<boolean>();\n\n const [shouldShow, setShouldShow] = useState<boolean>();\n useEffect(() => {\n if ((shouldShow === undefined && !dynamicRender) || !active) {\n setShouldShow(active);\n } else {\n setTimeout(() => setShouldShow(active), WDS_LIVE_REGION_DELAY_MS);\n }\n }, [active, shouldShow, dynamicRender]);\n\n const closeButtonReference = useRef<HTMLButtonElement>(null);\n\n return (\n <div\n role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}\n className=\"wds-alert__liveRegion\"\n >\n {shouldShow && (\n <div\n className={clsx(\n 'alert d-flex',\n `alert-${resolvedType}`,\n arrow != null && alertArrowClassNames(arrow),\n className,\n )}\n data-testid=\"alert\"\n onTouchStart={() => setShouldFire(true)}\n onTouchEnd={(event) => {\n if (\n shouldFire &&\n action?.href &&\n // Check if current event is triggered from closeButton\n event.target instanceof Node &&\n closeButtonReference.current &&\n !closeButtonReference.current.contains(event.target)\n ) {\n if (action.target === '_blank') {\n window.top?.open(action.href);\n } else {\n window.top?.location.assign(action.href);\n }\n }\n setShouldFire(false);\n }}\n onTouchMove={() => setShouldFire(false)}\n >\n <div\n className={clsx('alert__content', 'd-flex', 'flex-grow-1', variant)}\n data-testid={variant}\n >\n {icon ? (\n <div className=\"alert__icon\">{icon}</div>\n ) : (\n <StatusIcon size={Size.LARGE} sentiment={resolvedType} iconLabel={statusIconLabel} />\n )}\n <div className=\"alert__message\">\n <div>\n {title && (\n <Title className=\"m-b-1\" type={Typography.TITLE_BODY}>\n {title}\n </Title>\n )}\n <Body as=\"span\" className=\"d-block\" type={Typography.BODY_LARGE}>\n {children || <InlineMarkdown>{message}</InlineMarkdown>}\n </Body>\n </div>\n {action && <Action action={action} variant=\"action-button\" className=\"m-t-1\" />}\n </div>\n </div>\n {onDismiss && (\n <CloseButton ref={closeButtonReference} className=\"m-l-2\" onClick={onDismiss} />\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction alertArrowClassNames(arrow: `${AlertArrowPosition}`) {\n switch (arrow) {\n case 'down-center':\n return 'arrow arrow-bottom arrow-center';\n case 'down-left':\n return 'arrow arrow-bottom arrow-left';\n case 'down-right':\n return 'arrow arrow-bottom arrow-right';\n case 'up-center':\n return 'arrow arrow-center';\n case 'up-right':\n return 'arrow arrow-right';\n case 'up-left':\n default:\n return 'arrow';\n }\n}\n"],"names":["AlertArrowPosition","resolveType","type","Alert","arrow","action","children","className","dismissible","icon","statusIconLabel","onDismiss","message","size","title","variant","active","dynamicRender","useEffect","undefined","logActionRequired","resolvedType","shouldFire","setShouldFire","useState","shouldShow","setShouldShow","setTimeout","WDS_LIVE_REGION_DELAY_MS","closeButtonReference","useRef","_jsx","role","Sentiment","NEGATIVE","_jsxs","clsx","alertArrowClassNames","onTouchStart","onTouchEnd","event","href","target","Node","current","contains","window","top","open","location","assign","onTouchMove","StatusIcon","Size","LARGE","sentiment","iconLabel","Title","Typography","TITLE_BODY","Body","as","BODY_LARGE","InlineMarkdown","Action","CloseButton","ref","onClick"],"mappings":"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"}
1
+ {"version":3,"file":"Alert.js","sources":["../../src/alert/Alert.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useState, useRef, useEffect } from 'react';\n\nimport Body from '../body/Body';\nimport {\n CloseButton,\n Sentiment,\n Size,\n Typography,\n Variant,\n WDS_LIVE_REGION_DELAY_MS,\n} from '../common';\n\nimport StatusIcon from '../statusIcon';\nimport Title from '../title/Title';\nimport { logActionRequired } from '../utilities';\n\nimport InlineMarkdown from './inlineMarkdown';\nimport { Action } from '../common/action/Action';\n\nexport type AlertAction = {\n 'aria-label'?: string;\n href?: string;\n target?: string;\n text: React.ReactNode;\n onClick?: () => void;\n};\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype AlertTypeDeprecated = `${Sentiment.SUCCESS | Sentiment.INFO | Sentiment.ERROR}`;\ntype AlertTypeResolved = `${\n | Sentiment.POSITIVE\n | Sentiment.NEUTRAL\n | Sentiment.WARNING\n | Sentiment.NEGATIVE}`;\nexport type AlertType = AlertTypeResolved | AlertTypeDeprecated;\n\nexport enum AlertArrowPosition {\n TOP_LEFT = 'up-left',\n TOP = 'up-center',\n TOP_RIGHT = 'up-right',\n BOTTOM_LEFT = 'down-left',\n BOTTOM = 'down-center',\n BOTTOM_RIGHT = 'down-right',\n}\n\nexport interface AlertProps {\n /** An optional call to action to sit under the main body of the alert. If your label is short, use aria-label to provide more context */\n action?: AlertAction;\n className?: string;\n /** An optional icon. If not provided, we will default the icon to something appropriate for the type */\n icon?: React.ReactNode;\n /**\n * Override for [StatusIcon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n statusIconLabel?: string;\n /** Title for the alert component */\n title?: string;\n /** The main body of the alert. Accepts plain text and bold words specified with **double stars */\n message?: string;\n /** The presence of the onDismiss handler will trigger the visibility of the close button */\n onDismiss?: React.MouseEventHandler<HTMLButtonElement>;\n /** The type dictates which icon and colour will be used */\n type?: AlertType;\n variant?: `${Variant}`;\n /** @deprecated Safe to remove */\n active?: boolean;\n /** @deprecated Safe to remove */\n dynamicRender?: boolean;\n /** @deprecated Use `InlineAlert` instead. */\n arrow?: `${AlertArrowPosition}`;\n /** @deprecated Use `message` instead. Be aware `message` only accepts plain text or text with **bold** markdown. */\n children?: React.ReactNode;\n /** @deprecated Use `onDismiss` instead. */\n dismissible?: boolean;\n /** @deprecated Alert component doesn't support `size` anymore, please remove this prop. */\n size?: `${Size}`;\n}\n\nfunction resolveType(type: AlertType): AlertTypeResolved {\n switch (type) {\n case 'success':\n return 'positive';\n case 'info':\n return 'neutral';\n case 'error':\n return 'negative';\n default:\n return type;\n }\n}\n\nexport default function Alert({\n action,\n className,\n icon,\n statusIconLabel,\n onDismiss,\n message,\n title,\n type = 'neutral',\n variant = 'desktop',\n arrow,\n children,\n size,\n dismissible,\n active,\n dynamicRender,\n}: AlertProps) {\n useEffect(() => {\n if (active !== undefined || dynamicRender !== undefined) {\n logActionRequired(\n \"Alert component doesn't support `active` or `dynamicRender` anymore, please remove that prop.\",\n );\n }\n }, [active, dynamicRender]);\n\n useEffect(() => {\n if (arrow !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'arrow' anymore, use 'InlineAlert' instead.\",\n );\n }\n }, [arrow]);\n\n useEffect(() => {\n if (children !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'children' anymore, use 'message' instead.\",\n );\n }\n }, [children]);\n\n useEffect(() => {\n if (dismissible !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'dismissible' anymore, use 'onDismiss' instead.\",\n );\n }\n }, [dismissible]);\n\n useEffect(() => {\n if (size !== undefined) {\n logActionRequired(\"Alert component doesn't support 'size' anymore, please remove that prop.\");\n }\n }, [size]);\n\n const resolvedType = resolveType(type);\n useEffect(() => {\n if (resolvedType !== type) {\n logActionRequired(\n `Alert component has deprecated '${type}' value for the 'type' prop. Please use '${resolvedType}' instead.`,\n );\n }\n }, [resolvedType, type]);\n\n const [shouldFire, setShouldFire] = useState<boolean>();\n\n const [shouldAnnounce, setShouldAnnounce] = useState<boolean>(false);\n useEffect(() => {\n setTimeout(() => {\n setShouldAnnounce(true);\n }, WDS_LIVE_REGION_DELAY_MS);\n }, []);\n\n const closeButtonReference = useRef<HTMLButtonElement>(null);\n\n return (\n <div\n role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}\n className=\"wds-alert__liveRegion\"\n >\n <div\n aria-hidden={shouldAnnounce ? undefined : 'true'}\n className={clsx(\n 'alert d-flex',\n `alert-${resolvedType}`,\n arrow != null && alertArrowClassNames(arrow),\n className,\n )}\n data-testid=\"alert\"\n onTouchStart={() => setShouldFire(true)}\n onTouchEnd={(event) => {\n if (\n shouldFire &&\n action?.href &&\n // Check if current event is triggered from closeButton\n event.target instanceof Node &&\n closeButtonReference.current &&\n !closeButtonReference.current.contains(event.target)\n ) {\n if (action.target === '_blank') {\n window.top?.open(action.href);\n } else {\n window.top?.location.assign(action.href);\n }\n }\n setShouldFire(false);\n }}\n onTouchMove={() => setShouldFire(false)}\n >\n <div\n className={clsx('alert__content', 'd-flex', 'flex-grow-1', variant)}\n data-testid={variant}\n >\n {icon ? (\n <div className=\"alert__icon\">{icon}</div>\n ) : (\n <StatusIcon size={Size.LARGE} sentiment={resolvedType} iconLabel={statusIconLabel} />\n )}\n <div className=\"alert__message\">\n <div>\n {title && (\n <Title className=\"m-b-1\" type={Typography.TITLE_BODY}>\n {title}\n </Title>\n )}\n <Body as=\"span\" className=\"d-block\" type={Typography.BODY_LARGE}>\n {children || <InlineMarkdown>{message}</InlineMarkdown>}\n </Body>\n </div>\n {action && <Action action={action} variant=\"action-button\" className=\"m-t-1\" />}\n </div>\n </div>\n {onDismiss && (\n <CloseButton ref={closeButtonReference} className=\"m-l-2\" onClick={onDismiss} />\n )}\n </div>\n </div>\n );\n}\n\nfunction alertArrowClassNames(arrow: `${AlertArrowPosition}`) {\n switch (arrow) {\n case 'down-center':\n return 'arrow arrow-bottom arrow-center';\n case 'down-left':\n return 'arrow arrow-bottom arrow-left';\n case 'down-right':\n return 'arrow arrow-bottom arrow-right';\n case 'up-center':\n return 'arrow arrow-center';\n case 'up-right':\n return 'arrow arrow-right';\n case 'up-left':\n default:\n return 'arrow';\n }\n}\n"],"names":["AlertArrowPosition","resolveType","type","Alert","action","className","icon","statusIconLabel","onDismiss","message","title","variant","arrow","children","size","dismissible","active","dynamicRender","useEffect","undefined","logActionRequired","resolvedType","shouldFire","setShouldFire","useState","shouldAnnounce","setShouldAnnounce","setTimeout","WDS_LIVE_REGION_DELAY_MS","closeButtonReference","useRef","_jsx","role","Sentiment","NEGATIVE","_jsxs","clsx","alertArrowClassNames","onTouchStart","onTouchEnd","event","href","target","Node","current","contains","window","top","open","location","assign","onTouchMove","StatusIcon","Size","LARGE","sentiment","iconLabel","Title","Typography","TITLE_BODY","Body","as","BODY_LARGE","InlineMarkdown","Action","CloseButton","ref","onClick"],"mappings":"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"}
@@ -35,22 +35,27 @@ function resolveType(type) {
35
35
  }
36
36
  }
37
37
  function Alert({
38
- arrow,
39
38
  action,
40
- children,
41
39
  className,
42
- dismissible,
43
40
  icon,
44
41
  statusIconLabel,
45
42
  onDismiss,
46
43
  message,
47
- size,
48
44
  title,
49
45
  type = 'neutral',
50
46
  variant = 'desktop',
51
- active = true,
52
- dynamicRender = false
47
+ arrow,
48
+ children,
49
+ size,
50
+ dismissible,
51
+ active,
52
+ dynamicRender
53
53
  }) {
54
+ useEffect(() => {
55
+ if (active !== undefined || dynamicRender !== undefined) {
56
+ logActionRequired("Alert component doesn't support `active` or `dynamicRender` anymore, please remove that prop.");
57
+ }
58
+ }, [active, dynamicRender]);
54
59
  useEffect(() => {
55
60
  if (arrow !== undefined) {
56
61
  logActionRequired("Alert component doesn't support 'arrow' anymore, use 'InlineAlert' instead.");
@@ -78,19 +83,18 @@ function Alert({
78
83
  }
79
84
  }, [resolvedType, type]);
80
85
  const [shouldFire, setShouldFire] = useState();
81
- const [shouldShow, setShouldShow] = useState();
86
+ const [shouldAnnounce, setShouldAnnounce] = useState(false);
82
87
  useEffect(() => {
83
- if (shouldShow === undefined && !dynamicRender || !active) {
84
- setShouldShow(active);
85
- } else {
86
- setTimeout(() => setShouldShow(active), WDS_LIVE_REGION_DELAY_MS);
87
- }
88
- }, [active, shouldShow, dynamicRender]);
88
+ setTimeout(() => {
89
+ setShouldAnnounce(true);
90
+ }, WDS_LIVE_REGION_DELAY_MS);
91
+ }, []);
89
92
  const closeButtonReference = useRef(null);
90
93
  return /*#__PURE__*/jsx("div", {
91
94
  role: resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status',
92
95
  className: "wds-alert__liveRegion",
93
- children: shouldShow && /*#__PURE__*/jsxs("div", {
96
+ children: /*#__PURE__*/jsxs("div", {
97
+ "aria-hidden": shouldAnnounce ? undefined : 'true',
94
98
  className: clsx('alert d-flex', `alert-${resolvedType}`, arrow != null && alertArrowClassNames(arrow), className),
95
99
  "data-testid": "alert",
96
100
  onTouchStart: () => setShouldFire(true),
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.mjs","sources":["../../src/alert/Alert.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useState, useRef, useEffect } from 'react';\n\nimport Body from '../body/Body';\nimport {\n CloseButton,\n Sentiment,\n Size,\n Typography,\n Variant,\n WDS_LIVE_REGION_DELAY_MS,\n} from '../common';\n\nimport StatusIcon from '../statusIcon';\nimport Title from '../title/Title';\nimport { logActionRequired } from '../utilities';\n\nimport InlineMarkdown from './inlineMarkdown';\nimport { Action } from '../common/action/Action';\n\nexport type AlertAction = {\n 'aria-label'?: string;\n href?: string;\n target?: string;\n text: React.ReactNode;\n onClick?: () => void;\n};\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype AlertTypeDeprecated = `${Sentiment.SUCCESS | Sentiment.INFO | Sentiment.ERROR}`;\ntype AlertTypeResolved = `${\n | Sentiment.POSITIVE\n | Sentiment.NEUTRAL\n | Sentiment.WARNING\n | Sentiment.NEGATIVE}`;\nexport type AlertType = AlertTypeResolved | AlertTypeDeprecated;\n\nexport enum AlertArrowPosition {\n TOP_LEFT = 'up-left',\n TOP = 'up-center',\n TOP_RIGHT = 'up-right',\n BOTTOM_LEFT = 'down-left',\n BOTTOM = 'down-center',\n BOTTOM_RIGHT = 'down-right',\n}\n\nexport interface AlertProps {\n /** An optional call to action to sit under the main body of the alert. If your label is short, use aria-label to provide more context */\n action?: AlertAction;\n className?: string;\n /** An optional icon. If not provided, we will default the icon to something appropriate for the type */\n icon?: React.ReactNode;\n /**\n * Override for [StatusIcon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n statusIconLabel?: string;\n /** Title for the alert component */\n title?: string;\n /** The main body of the alert. Accepts plain text and bold words specified with **double stars */\n message?: string;\n /** The presence of the onDismiss handler will trigger the visibility of the close button */\n onDismiss?: React.MouseEventHandler<HTMLButtonElement>;\n /** The type dictates which icon and colour will be used */\n type?: AlertType;\n variant?: `${Variant}`;\n /**\n * Controls rendering of the Alert component. <br />\n * Toggle this prop instead using conditional rendering and logical AND (&&)\n * operator, to make the component work with screen readers.\n * */\n active?: boolean;\n /**\n * Toggle this prop when dealing with multiple, dynamic Alerts, to make them\n * work with screen readers. This is especially helpful for the BFF use cases.\n * */\n dynamicRender?: boolean;\n /** @deprecated Use `InlineAlert` instead. */\n arrow?: `${AlertArrowPosition}`;\n /** @deprecated Use `message` instead. Be aware `message` only accepts plain text or text with **bold** markdown. */\n children?: React.ReactNode;\n /** @deprecated Use `onDismiss` instead. */\n dismissible?: boolean;\n /** @deprecated Alert component doesn't support `size` anymore, please remove this prop. */\n size?: `${Size}`;\n}\n\nfunction resolveType(type: AlertType): AlertTypeResolved {\n switch (type) {\n case 'success':\n return 'positive';\n case 'info':\n return 'neutral';\n case 'error':\n return 'negative';\n default:\n return type;\n }\n}\n\nexport default function Alert({\n arrow,\n action,\n children,\n className,\n dismissible,\n icon,\n statusIconLabel,\n onDismiss,\n message,\n size,\n title,\n type = 'neutral',\n variant = 'desktop',\n active = true,\n dynamicRender = false,\n}: AlertProps) {\n useEffect(() => {\n if (arrow !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'arrow' anymore, use 'InlineAlert' instead.\",\n );\n }\n }, [arrow]);\n\n useEffect(() => {\n if (children !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'children' anymore, use 'message' instead.\",\n );\n }\n }, [children]);\n\n useEffect(() => {\n if (dismissible !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'dismissible' anymore, use 'onDismiss' instead.\",\n );\n }\n }, [dismissible]);\n\n useEffect(() => {\n if (size !== undefined) {\n logActionRequired(\"Alert component doesn't support 'size' anymore, please remove that prop.\");\n }\n }, [size]);\n\n const resolvedType = resolveType(type);\n useEffect(() => {\n if (resolvedType !== type) {\n logActionRequired(\n `Alert component has deprecated '${type}' value for the 'type' prop. Please use '${resolvedType}' instead.`,\n );\n }\n }, [resolvedType, type]);\n\n const [shouldFire, setShouldFire] = useState<boolean>();\n\n const [shouldShow, setShouldShow] = useState<boolean>();\n useEffect(() => {\n if ((shouldShow === undefined && !dynamicRender) || !active) {\n setShouldShow(active);\n } else {\n setTimeout(() => setShouldShow(active), WDS_LIVE_REGION_DELAY_MS);\n }\n }, [active, shouldShow, dynamicRender]);\n\n const closeButtonReference = useRef<HTMLButtonElement>(null);\n\n return (\n <div\n role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}\n className=\"wds-alert__liveRegion\"\n >\n {shouldShow && (\n <div\n className={clsx(\n 'alert d-flex',\n `alert-${resolvedType}`,\n arrow != null && alertArrowClassNames(arrow),\n className,\n )}\n data-testid=\"alert\"\n onTouchStart={() => setShouldFire(true)}\n onTouchEnd={(event) => {\n if (\n shouldFire &&\n action?.href &&\n // Check if current event is triggered from closeButton\n event.target instanceof Node &&\n closeButtonReference.current &&\n !closeButtonReference.current.contains(event.target)\n ) {\n if (action.target === '_blank') {\n window.top?.open(action.href);\n } else {\n window.top?.location.assign(action.href);\n }\n }\n setShouldFire(false);\n }}\n onTouchMove={() => setShouldFire(false)}\n >\n <div\n className={clsx('alert__content', 'd-flex', 'flex-grow-1', variant)}\n data-testid={variant}\n >\n {icon ? (\n <div className=\"alert__icon\">{icon}</div>\n ) : (\n <StatusIcon size={Size.LARGE} sentiment={resolvedType} iconLabel={statusIconLabel} />\n )}\n <div className=\"alert__message\">\n <div>\n {title && (\n <Title className=\"m-b-1\" type={Typography.TITLE_BODY}>\n {title}\n </Title>\n )}\n <Body as=\"span\" className=\"d-block\" type={Typography.BODY_LARGE}>\n {children || <InlineMarkdown>{message}</InlineMarkdown>}\n </Body>\n </div>\n {action && <Action action={action} variant=\"action-button\" className=\"m-t-1\" />}\n </div>\n </div>\n {onDismiss && (\n <CloseButton ref={closeButtonReference} className=\"m-l-2\" onClick={onDismiss} />\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction alertArrowClassNames(arrow: `${AlertArrowPosition}`) {\n switch (arrow) {\n case 'down-center':\n return 'arrow arrow-bottom arrow-center';\n case 'down-left':\n return 'arrow arrow-bottom arrow-left';\n case 'down-right':\n return 'arrow arrow-bottom arrow-right';\n case 'up-center':\n return 'arrow arrow-center';\n case 'up-right':\n return 'arrow arrow-right';\n case 'up-left':\n default:\n return 'arrow';\n }\n}\n"],"names":["AlertArrowPosition","resolveType","type","Alert","arrow","action","children","className","dismissible","icon","statusIconLabel","onDismiss","message","size","title","variant","active","dynamicRender","useEffect","undefined","logActionRequired","resolvedType","shouldFire","setShouldFire","useState","shouldShow","setShouldShow","setTimeout","WDS_LIVE_REGION_DELAY_MS","closeButtonReference","useRef","_jsx","role","Sentiment","NEGATIVE","_jsxs","clsx","alertArrowClassNames","onTouchStart","onTouchEnd","event","href","target","Node","current","contains","window","top","open","location","assign","onTouchMove","StatusIcon","Size","LARGE","sentiment","iconLabel","Title","Typography","TITLE_BODY","Body","as","BODY_LARGE","InlineMarkdown","Action","CloseButton","ref","onClick"],"mappings":"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"}
1
+ {"version":3,"file":"Alert.mjs","sources":["../../src/alert/Alert.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useState, useRef, useEffect } from 'react';\n\nimport Body from '../body/Body';\nimport {\n CloseButton,\n Sentiment,\n Size,\n Typography,\n Variant,\n WDS_LIVE_REGION_DELAY_MS,\n} from '../common';\n\nimport StatusIcon from '../statusIcon';\nimport Title from '../title/Title';\nimport { logActionRequired } from '../utilities';\n\nimport InlineMarkdown from './inlineMarkdown';\nimport { Action } from '../common/action/Action';\n\nexport type AlertAction = {\n 'aria-label'?: string;\n href?: string;\n target?: string;\n text: React.ReactNode;\n onClick?: () => void;\n};\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype AlertTypeDeprecated = `${Sentiment.SUCCESS | Sentiment.INFO | Sentiment.ERROR}`;\ntype AlertTypeResolved = `${\n | Sentiment.POSITIVE\n | Sentiment.NEUTRAL\n | Sentiment.WARNING\n | Sentiment.NEGATIVE}`;\nexport type AlertType = AlertTypeResolved | AlertTypeDeprecated;\n\nexport enum AlertArrowPosition {\n TOP_LEFT = 'up-left',\n TOP = 'up-center',\n TOP_RIGHT = 'up-right',\n BOTTOM_LEFT = 'down-left',\n BOTTOM = 'down-center',\n BOTTOM_RIGHT = 'down-right',\n}\n\nexport interface AlertProps {\n /** An optional call to action to sit under the main body of the alert. If your label is short, use aria-label to provide more context */\n action?: AlertAction;\n className?: string;\n /** An optional icon. If not provided, we will default the icon to something appropriate for the type */\n icon?: React.ReactNode;\n /**\n * Override for [StatusIcon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n statusIconLabel?: string;\n /** Title for the alert component */\n title?: string;\n /** The main body of the alert. Accepts plain text and bold words specified with **double stars */\n message?: string;\n /** The presence of the onDismiss handler will trigger the visibility of the close button */\n onDismiss?: React.MouseEventHandler<HTMLButtonElement>;\n /** The type dictates which icon and colour will be used */\n type?: AlertType;\n variant?: `${Variant}`;\n /** @deprecated Safe to remove */\n active?: boolean;\n /** @deprecated Safe to remove */\n dynamicRender?: boolean;\n /** @deprecated Use `InlineAlert` instead. */\n arrow?: `${AlertArrowPosition}`;\n /** @deprecated Use `message` instead. Be aware `message` only accepts plain text or text with **bold** markdown. */\n children?: React.ReactNode;\n /** @deprecated Use `onDismiss` instead. */\n dismissible?: boolean;\n /** @deprecated Alert component doesn't support `size` anymore, please remove this prop. */\n size?: `${Size}`;\n}\n\nfunction resolveType(type: AlertType): AlertTypeResolved {\n switch (type) {\n case 'success':\n return 'positive';\n case 'info':\n return 'neutral';\n case 'error':\n return 'negative';\n default:\n return type;\n }\n}\n\nexport default function Alert({\n action,\n className,\n icon,\n statusIconLabel,\n onDismiss,\n message,\n title,\n type = 'neutral',\n variant = 'desktop',\n arrow,\n children,\n size,\n dismissible,\n active,\n dynamicRender,\n}: AlertProps) {\n useEffect(() => {\n if (active !== undefined || dynamicRender !== undefined) {\n logActionRequired(\n \"Alert component doesn't support `active` or `dynamicRender` anymore, please remove that prop.\",\n );\n }\n }, [active, dynamicRender]);\n\n useEffect(() => {\n if (arrow !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'arrow' anymore, use 'InlineAlert' instead.\",\n );\n }\n }, [arrow]);\n\n useEffect(() => {\n if (children !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'children' anymore, use 'message' instead.\",\n );\n }\n }, [children]);\n\n useEffect(() => {\n if (dismissible !== undefined) {\n logActionRequired(\n \"Alert component doesn't support 'dismissible' anymore, use 'onDismiss' instead.\",\n );\n }\n }, [dismissible]);\n\n useEffect(() => {\n if (size !== undefined) {\n logActionRequired(\"Alert component doesn't support 'size' anymore, please remove that prop.\");\n }\n }, [size]);\n\n const resolvedType = resolveType(type);\n useEffect(() => {\n if (resolvedType !== type) {\n logActionRequired(\n `Alert component has deprecated '${type}' value for the 'type' prop. Please use '${resolvedType}' instead.`,\n );\n }\n }, [resolvedType, type]);\n\n const [shouldFire, setShouldFire] = useState<boolean>();\n\n const [shouldAnnounce, setShouldAnnounce] = useState<boolean>(false);\n useEffect(() => {\n setTimeout(() => {\n setShouldAnnounce(true);\n }, WDS_LIVE_REGION_DELAY_MS);\n }, []);\n\n const closeButtonReference = useRef<HTMLButtonElement>(null);\n\n return (\n <div\n role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}\n className=\"wds-alert__liveRegion\"\n >\n <div\n aria-hidden={shouldAnnounce ? undefined : 'true'}\n className={clsx(\n 'alert d-flex',\n `alert-${resolvedType}`,\n arrow != null && alertArrowClassNames(arrow),\n className,\n )}\n data-testid=\"alert\"\n onTouchStart={() => setShouldFire(true)}\n onTouchEnd={(event) => {\n if (\n shouldFire &&\n action?.href &&\n // Check if current event is triggered from closeButton\n event.target instanceof Node &&\n closeButtonReference.current &&\n !closeButtonReference.current.contains(event.target)\n ) {\n if (action.target === '_blank') {\n window.top?.open(action.href);\n } else {\n window.top?.location.assign(action.href);\n }\n }\n setShouldFire(false);\n }}\n onTouchMove={() => setShouldFire(false)}\n >\n <div\n className={clsx('alert__content', 'd-flex', 'flex-grow-1', variant)}\n data-testid={variant}\n >\n {icon ? (\n <div className=\"alert__icon\">{icon}</div>\n ) : (\n <StatusIcon size={Size.LARGE} sentiment={resolvedType} iconLabel={statusIconLabel} />\n )}\n <div className=\"alert__message\">\n <div>\n {title && (\n <Title className=\"m-b-1\" type={Typography.TITLE_BODY}>\n {title}\n </Title>\n )}\n <Body as=\"span\" className=\"d-block\" type={Typography.BODY_LARGE}>\n {children || <InlineMarkdown>{message}</InlineMarkdown>}\n </Body>\n </div>\n {action && <Action action={action} variant=\"action-button\" className=\"m-t-1\" />}\n </div>\n </div>\n {onDismiss && (\n <CloseButton ref={closeButtonReference} className=\"m-l-2\" onClick={onDismiss} />\n )}\n </div>\n </div>\n );\n}\n\nfunction alertArrowClassNames(arrow: `${AlertArrowPosition}`) {\n switch (arrow) {\n case 'down-center':\n return 'arrow arrow-bottom arrow-center';\n case 'down-left':\n return 'arrow arrow-bottom arrow-left';\n case 'down-right':\n return 'arrow arrow-bottom arrow-right';\n case 'up-center':\n return 'arrow arrow-center';\n case 'up-right':\n return 'arrow arrow-right';\n case 'up-left':\n default:\n return 'arrow';\n }\n}\n"],"names":["AlertArrowPosition","resolveType","type","Alert","action","className","icon","statusIconLabel","onDismiss","message","title","variant","arrow","children","size","dismissible","active","dynamicRender","useEffect","undefined","logActionRequired","resolvedType","shouldFire","setShouldFire","useState","shouldAnnounce","setShouldAnnounce","setTimeout","WDS_LIVE_REGION_DELAY_MS","closeButtonReference","useRef","_jsx","role","Sentiment","NEGATIVE","_jsxs","clsx","alertArrowClassNames","onTouchStart","onTouchEnd","event","href","target","Node","current","contains","window","top","open","location","assign","onTouchMove","StatusIcon","Size","LARGE","sentiment","iconLabel","Title","Typography","TITLE_BODY","Body","as","BODY_LARGE","InlineMarkdown","Action","CloseButton","ref","onClick"],"mappings":"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"}
@@ -38,16 +38,9 @@ export interface AlertProps {
38
38
  /** The type dictates which icon and colour will be used */
39
39
  type?: AlertType;
40
40
  variant?: `${Variant}`;
41
- /**
42
- * Controls rendering of the Alert component. <br />
43
- * Toggle this prop instead using conditional rendering and logical AND (&&)
44
- * operator, to make the component work with screen readers.
45
- * */
41
+ /** @deprecated Safe to remove */
46
42
  active?: boolean;
47
- /**
48
- * Toggle this prop when dealing with multiple, dynamic Alerts, to make them
49
- * work with screen readers. This is especially helpful for the BFF use cases.
50
- * */
43
+ /** @deprecated Safe to remove */
51
44
  dynamicRender?: boolean;
52
45
  /** @deprecated Use `InlineAlert` instead. */
53
46
  arrow?: `${AlertArrowPosition}`;
@@ -58,6 +51,6 @@ export interface AlertProps {
58
51
  /** @deprecated Alert component doesn't support `size` anymore, please remove this prop. */
59
52
  size?: `${Size}`;
60
53
  }
61
- export default function Alert({ arrow, action, children, className, dismissible, icon, statusIconLabel, onDismiss, message, size, title, type, variant, active, dynamicRender, }: AlertProps): import("react").JSX.Element;
54
+ export default function Alert({ action, className, icon, statusIconLabel, onDismiss, message, title, type, variant, arrow, children, size, dismissible, active, dynamicRender, }: AlertProps): import("react").JSX.Element;
62
55
  export {};
63
56
  //# sourceMappingURL=Alert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../src/alert/Alert.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,SAAS,EACT,IAAI,EAEJ,OAAO,EAER,MAAM,WAAW,CAAC;AASnB,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,kDAAkD;AAClD,KAAK,mBAAmB,GAAG,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;AACrF,KAAK,iBAAiB,GAAG,GACrB,SAAS,CAAC,QAAQ,GAClB,SAAS,CAAC,OAAO,GACjB,SAAS,CAAC,OAAO,GACjB,SAAS,CAAC,QAAQ,EAAE,CAAC;AACzB,MAAM,MAAM,SAAS,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;AAEhE,oBAAY,kBAAkB;IAC5B,QAAQ,YAAY;IACpB,GAAG,cAAc;IACjB,SAAS,aAAa;IACtB,WAAW,cAAc;IACzB,MAAM,gBAAgB;IACtB,YAAY,eAAe;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,yIAAyI;IACzI,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wGAAwG;IACxG,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;SAGK;IACL,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACvD,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IACvB;;;;SAIK;IACL,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;SAGK;IACL,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAChC,oHAAoH;IACpH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;CAClB;AAeD,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,WAAW,EACX,IAAI,EACJ,eAAe,EACf,SAAS,EACT,OAAO,EACP,IAAI,EACJ,KAAK,EACL,IAAgB,EAChB,OAAmB,EACnB,MAAa,EACb,aAAqB,GACtB,EAAE,UAAU,+BAqHZ"}
1
+ {"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../src/alert/Alert.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,SAAS,EACT,IAAI,EAEJ,OAAO,EAER,MAAM,WAAW,CAAC;AASnB,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,kDAAkD;AAClD,KAAK,mBAAmB,GAAG,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;AACrF,KAAK,iBAAiB,GAAG,GACrB,SAAS,CAAC,QAAQ,GAClB,SAAS,CAAC,OAAO,GACjB,SAAS,CAAC,OAAO,GACjB,SAAS,CAAC,QAAQ,EAAE,CAAC;AACzB,MAAM,MAAM,SAAS,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;AAEhE,oBAAY,kBAAkB;IAC5B,QAAQ,YAAY;IACpB,GAAG,cAAc;IACjB,SAAS,aAAa;IACtB,WAAW,cAAc;IACzB,MAAM,gBAAgB;IACtB,YAAY,eAAe;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,yIAAyI;IACzI,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wGAAwG;IACxG,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;SAGK;IACL,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACvD,2DAA2D;IAC3D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IACvB,iCAAiC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAChC,oHAAoH;IACpH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;CAClB;AAeD,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAC5B,MAAM,EACN,SAAS,EACT,IAAI,EACJ,eAAe,EACf,SAAS,EACT,OAAO,EACP,KAAK,EACL,IAAgB,EAChB,OAAmB,EACnB,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,MAAM,EACN,aAAa,GACd,EAAE,UAAU,+BA0HZ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-dcb657b",
3
+ "version": "0.0.0-experimental-bb877d0",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -92,8 +92,8 @@
92
92
  "rollup-preserve-directives": "^1.1.1",
93
93
  "storybook": "^8.2.2",
94
94
  "@transferwise/less-config": "3.1.0",
95
- "@wise/components-theming": "1.6.1",
96
- "@transferwise/neptune-css": "14.19.1"
95
+ "@transferwise/neptune-css": "14.19.1",
96
+ "@wise/components-theming": "1.6.1"
97
97
  },
98
98
  "peerDependencies": {
99
99
  "@transferwise/icons": "^3.13.1",
@@ -42,7 +42,7 @@ export const SimpleTrigger: Story = {
42
42
  Trigger Alert
43
43
  </Button>
44
44
 
45
- <Alert {...args} active={isActive} className="m-t-4" />
45
+ {isActive && <Alert {...args} className="m-t-4" />}
46
46
  </>
47
47
  );
48
48
  },
@@ -79,14 +79,14 @@ export const ComplexTrigger: Story = {
79
79
  />
80
80
  </Field>
81
81
 
82
- <Alert {...args} active={isActive} className="m-t-2" />
82
+ {isActive && <Alert {...args} className="m-t-2" />}
83
83
  </>
84
84
  );
85
85
  },
86
86
  };
87
87
 
88
88
  export const BackendForFrontend: Story = {
89
- play: async ({ args, canvasElement }) => {
89
+ play: async ({ canvasElement }) => {
90
90
  const canvas = within(canvasElement);
91
91
  await expect(canvas.queryAllByRole('status')).toHaveLength(0);
92
92
  await expect(canvas.queryAllByRole('alert')).toHaveLength(0);
@@ -98,7 +98,6 @@ export const BackendForFrontend: Story = {
98
98
  await expect(canvas.getAllByRole('alert')).toHaveLength(1);
99
99
  },
100
100
  render: function Render() {
101
- const [isActive, setIsActive] = useState(false);
102
101
  const [alerts, setAlerts] = useState<AlertProps[]>([]);
103
102
 
104
103
  const getAlerts: () => AlertProps[] = () => [
@@ -121,18 +120,12 @@ export const BackendForFrontend: Story = {
121
120
 
122
121
  return (
123
122
  <>
124
- <Button
125
- htmlType="button"
126
- onClick={() => {
127
- setAlerts(getAlerts());
128
- setIsActive((current) => !current);
129
- }}
130
- >
123
+ <Button htmlType="button" onClick={() => setAlerts(getAlerts())}>
131
124
  Generate dynamic alerts
132
125
  </Button>
133
126
 
134
127
  {alerts.map((props) => (
135
- <Alert dynamicRender {...props} key={props.title} className="m-t-3" />
128
+ <Alert {...props} key={props.title} className="m-t-3" />
136
129
  ))}
137
130
  </>
138
131
  );
@@ -4,7 +4,14 @@ import { ThemeProvider } from '@wise/components-theming';
4
4
  import React from 'react';
5
5
 
6
6
  import { Sentiment, Size, Theme, Variant } from '../common';
7
- import { render, cleanup, screen, userEvent, fireEvent, mockMatchMedia } from '../test-utils';
7
+ import {
8
+ render,
9
+ cleanup,
10
+ screen,
11
+ userEvent as user,
12
+ fireEvent,
13
+ mockMatchMedia,
14
+ } from '../test-utils';
8
15
 
9
16
  import Alert, { AlertAction, AlertArrowPosition, AlertType } from './Alert';
10
17
 
@@ -25,6 +32,9 @@ describe('Alert', () => {
25
32
  let alert: HTMLElement;
26
33
  let closeButton: HTMLElement;
27
34
  let action: AlertAction;
35
+ const userEvent = user.setup({
36
+ advanceTimers: jest.advanceTimersByTimeAsync,
37
+ });
28
38
 
29
39
  const classForType = (type: AlertType) => `alert-${type}`;
30
40
 
@@ -39,7 +49,6 @@ describe('Alert', () => {
39
49
  });
40
50
 
41
51
  afterEach(() => {
42
- cleanup();
43
52
  jest.clearAllMocks();
44
53
  });
45
54
 
@@ -100,6 +109,24 @@ describe('Alert', () => {
100
109
  );
101
110
  });
102
111
 
112
+ it('active is ignored and a warning is logged', () => {
113
+ render(<Alert active message={message} />);
114
+
115
+ expect(screen.getByText(message)).toBeInTheDocument();
116
+ expect(mockedWarn).toHaveBeenCalledWith(
117
+ expect.stringMatching(/Alert component doesn't support `active`/),
118
+ );
119
+ });
120
+
121
+ it('dynamicRender is ignored and a warning is logged', () => {
122
+ render(<Alert dynamicRender message={message} />);
123
+
124
+ expect(screen.getByText(message)).toBeInTheDocument();
125
+ expect(mockedWarn).toHaveBeenCalledWith(
126
+ expect.stringMatching(/Alert component doesn't support.*?`dynamicRender`/),
127
+ );
128
+ });
129
+
103
130
  it('dismissible is ignored and a warning is logged', () => {
104
131
  ({ container } = render(<Alert dismissible message={message} />));
105
132
 
@@ -252,18 +279,17 @@ describe('Alert', () => {
252
279
  });
253
280
 
254
281
  describe('onDismiss', () => {
255
- it('renders the close button if onDismiss is provided', () => {
282
+ it('renders the close button if onDismiss is provided', async () => {
256
283
  render(<Alert message={message} onDismiss={jest.fn()} />);
257
-
258
- expect(screen.getByRole('button')).toBeInTheDocument();
284
+ const button = await screen.findByRole('button', { name: 'Close' });
285
+ expect(button).toBeEnabled();
259
286
  });
260
287
 
261
288
  it('calls onDismiss when the close button is clicked', async () => {
262
289
  const onDismiss = jest.fn();
263
-
264
290
  render(<Alert message={message} onDismiss={onDismiss} />);
265
-
266
- await userEvent.click(screen.getByRole('button'));
291
+ const button = await screen.findByRole('button', { name: 'Close' });
292
+ await userEvent.click(button);
267
293
 
268
294
  expect(onDismiss).toHaveBeenCalledTimes(1);
269
295
  });
@@ -477,28 +503,4 @@ describe('Alert', () => {
477
503
  expect(screen.getByTestId('status-icon')).toBeInTheDocument();
478
504
  });
479
505
  });
480
-
481
- describe('`active` prop', () => {
482
- it('should render wrapper and alert if `active` is unset', () => {
483
- render(<Alert message={message} />);
484
- expect(screen.getByRole('status')).toBeInTheDocument();
485
- expect(screen.getByText(message)).toBeInTheDocument();
486
- });
487
-
488
- it('should render wrapper and alert if `active={false}', () => {
489
- render(<Alert message={message} active={false} />);
490
- expect(screen.getByRole('status')).toBeInTheDocument();
491
- expect(screen.queryByText(message)).not.toBeInTheDocument();
492
- });
493
-
494
- it('should render wrapper and alert if `active` is set', () => {
495
- render(<Alert message={message} />);
496
- expect(screen.getByRole('status')).toBeInTheDocument();
497
- expect(screen.getByText(message)).toBeInTheDocument();
498
- });
499
- });
500
-
501
- describe('dynamicRender', () => {
502
- it('should', () => {});
503
- });
504
506
  });
@@ -12,7 +12,6 @@ export default {
12
12
  title: 'Feedback/Alert',
13
13
  args: {
14
14
  type: Sentiment.POSITIVE,
15
- active: true,
16
15
  message:
17
16
  'Payments sent to your bank details **today** might not arrive in time for the holidays.',
18
17
  },
@@ -106,30 +105,43 @@ export const WithTitle: Story = {
106
105
  };
107
106
 
108
107
  /**
109
- * For ARIA live region to function correctly with screen readers,
108
+ * For ARIA live region to function correctly with screen readers (SR),
110
109
  * the container with an appropriate ARIA role (in the case of this
111
110
  * component, it's `status` or `alert`) must be rendered first.
112
111
  * Once present in the accessibility tree (AT), its dynamic contents
113
112
  * will be announced correctly.
114
113
  *
115
- * Because of that, using logical AND (&&) operator is discouraged
116
- * and, instead, engineers should toggle the `active` prop which
117
- * provides that logic internally.
114
+ * It's not a problem if your page includes an Alert that is initially
115
+ * visible at the very first render, but if it appears as a result of
116
+ * user interaction or is async, e.g. BE-driven, then the screen reader
117
+ * might not announce it correctly. It becomes even more tricky if an
118
+ * Alert is triggerred by a component that causes refocusing or introduces
119
+ * many modifications to the AT, such as MoneyInput, for example, as that
120
+ * entirely hijacks screen-reader's attention and prevents it from
121
+ * announcing live region changes.
118
122
  *
119
- * We're additionally adding a small delay (175ms) between toggling
120
- * the `active` prop and actual DOM injection to compensate for some
121
- * common triggers like e.g. `SelectInput`. Those components affect
122
- * the AT and have programmatic focus control, which prevents the
123
- * screen readers from announcing simultaneous changes on the page.
123
+ * In order for this to work, we've introduced a simple mechanism which
124
+ * overcomes all of the above:
125
+ * 1. On the component mount, we render the live region wrapper.
126
+ * 2. We also render the actual Alert but set `aria-hidden` on it.
127
+ * 3. After 175ms, which has been confirmed as sufficient delay for
128
+ * the SRs to become responsive after trigger's activity, we remove the
129
+ * `aria-hidden` attribute, which, in turn, initiates the announcements.
130
+ *
131
+ * **NB:** While this approach has no visual side-effects (e.g. layout
132
+ * shift), it makes the Alert hidden from the assistive tech for 175ms.
133
+ * It's our belief that such short pause between announcements is
134
+ * negligible for the user.
124
135
  */
125
- export const ConditionallyRendered: Story = {
136
+ export const DynamicRender: Story = {
126
137
  render: function Render(args) {
127
- const [isActive, setIsActive] = useState(false);
138
+ const [isOneActive, setIsOneActive] = useState(false);
139
+ const [isTwoActive, setIsTwoActive] = useState(false);
128
140
  const [value, setValue] = useState<string>();
129
141
 
130
142
  return (
131
143
  <>
132
- <Button htmlType="button" onClick={() => setIsActive((current) => !current)}>
144
+ <Button htmlType="button" onClick={() => setIsOneActive(true)}>
133
145
  Trigger Alert
134
146
  </Button>
135
147
 
@@ -140,11 +152,16 @@ export const ConditionallyRendered: Story = {
140
152
  { type: 'option', value: 'two' },
141
153
  ]}
142
154
  onChange={setValue}
143
- onClose={() => setIsActive(value === 'two')}
155
+ onClose={() => setIsTwoActive(value === 'two')}
144
156
  />
145
157
  </Field>
146
158
 
147
- <Alert {...args} active={isActive} className="m-t-5" />
159
+ {isOneActive && <Alert {...args}>This Alert has a simple trigger.</Alert>}
160
+ {isTwoActive && (
161
+ <Alert {...args} type={Sentiment.WARNING}>
162
+ This Alert has a complex trigger.
163
+ </Alert>
164
+ )}
148
165
  </>
149
166
  );
150
167
  },
@@ -153,27 +170,33 @@ export const ConditionallyRendered: Story = {
153
170
  source: {
154
171
  code: `
155
172
  function Render(args) {
156
- const [isActive, setIsActive] = useState(false);
157
- const [value, setValue] = useState<string>();
173
+ const [isOneActive, setIsOneActive] = useState(false);
174
+ const [isTwoActive, setIsTwoActive] = useState(false);
175
+ const [value, setValue] = useState<string>();
158
176
 
159
177
  return (
160
178
  <>
161
- <Button htmlType="button" onClick={() => setIsActive((current) => !current)}>
179
+ <Button htmlType="button" onClick={() => setIsOneActive(true)}>
162
180
  Trigger Alert
163
181
  </Button>
164
182
 
165
- <Field label="Select 'two' to triger Alert" className="m-t-3">
183
+ <Field label="Select \`two\` to triger Alert" className="m-t-3">
166
184
  <SelectInput
167
185
  items={[
168
186
  { type: 'option', value: 'one' },
169
187
  { type: 'option', value: 'two' },
170
188
  ]}
171
189
  onChange={setValue}
172
- onClose={() => setIsActive(value === 'two')}
190
+ onClose={() => setIsTwoActive(value === 'two')}
173
191
  />
174
192
  </Field>
175
-
176
- <Alert {...args} active={isActive} className="m-t-5" />
193
+
194
+ {isOneActive && <Alert {...args}>This Alert has a simple trigger.</Alert>}
195
+ {isTwoActive && (
196
+ <Alert {...args} type={Sentiment.WARNING}>
197
+ This Alert has a complex trigger.
198
+ </Alert>
199
+ )}
177
200
  </>
178
201
  );
179
202
  }`,
@@ -204,18 +227,15 @@ const getAlerts = () => {
204
227
  };
205
228
 
206
229
  /**
207
- * When dealing with Backend for Frontend (BFF), sometimes it's not
208
- * just about conditional rendering but also the fact you don't
209
- * know how many `Alert`s you're going to get and when, so using
210
- * the `active` prop is not feasible.
211
- *
212
- * In those cases, the only way to support screen readers is by
213
- * forcing delayed render using the `dynamicRender` prop.
230
+ * Sometimes, especially when dealing with Backend for Frontend (BFF),
231
+ * it's not just about conditional rendering but also the fact that
232
+ * you don't know how many `Alert`s you'll need to render.
214
233
  *
215
- * **NB:** Screen readers do not guarantee the order in which they
216
- * read out multiple injected sibling nodes.
234
+ * If you have to inject multiple Alerts simultaneously into the page,
235
+ * please note that we currently have no means of guaranteeing the order
236
+ * in which they screen reader will read them out.
217
237
  */
218
- export const BackendForFrontend: Story = {
238
+ export const MultipleAlerts: Story = {
219
239
  render: function Render() {
220
240
  const [isActive, setIsActive] = useState(false);
221
241
  const [alerts, setAlerts] = useState<AlertProps[]>([]);
@@ -233,7 +253,7 @@ export const BackendForFrontend: Story = {
233
253
  </Button>
234
254
 
235
255
  {alerts.map((props) => (
236
- <Alert {...props} key={props.title} className="m-t-3" dynamicRender />
256
+ <Alert {...props} key={props.title} className="m-t-3" />
237
257
  ))}
238
258
  </>
239
259
  );
@@ -263,7 +283,6 @@ function Render() {
263
283
  {...props}
264
284
  key={props.title}
265
285
  className="m-t-3"
266
- dynamicRender
267
286
  />
268
287
  ))}
269
288
  </>
@@ -64,16 +64,9 @@ export interface AlertProps {
64
64
  /** The type dictates which icon and colour will be used */
65
65
  type?: AlertType;
66
66
  variant?: `${Variant}`;
67
- /**
68
- * Controls rendering of the Alert component. <br />
69
- * Toggle this prop instead using conditional rendering and logical AND (&&)
70
- * operator, to make the component work with screen readers.
71
- * */
67
+ /** @deprecated Safe to remove */
72
68
  active?: boolean;
73
- /**
74
- * Toggle this prop when dealing with multiple, dynamic Alerts, to make them
75
- * work with screen readers. This is especially helpful for the BFF use cases.
76
- * */
69
+ /** @deprecated Safe to remove */
77
70
  dynamicRender?: boolean;
78
71
  /** @deprecated Use `InlineAlert` instead. */
79
72
  arrow?: `${AlertArrowPosition}`;
@@ -99,22 +92,30 @@ function resolveType(type: AlertType): AlertTypeResolved {
99
92
  }
100
93
 
101
94
  export default function Alert({
102
- arrow,
103
95
  action,
104
- children,
105
96
  className,
106
- dismissible,
107
97
  icon,
108
98
  statusIconLabel,
109
99
  onDismiss,
110
100
  message,
111
- size,
112
101
  title,
113
102
  type = 'neutral',
114
103
  variant = 'desktop',
115
- active = true,
116
- dynamicRender = false,
104
+ arrow,
105
+ children,
106
+ size,
107
+ dismissible,
108
+ active,
109
+ dynamicRender,
117
110
  }: AlertProps) {
111
+ useEffect(() => {
112
+ if (active !== undefined || dynamicRender !== undefined) {
113
+ logActionRequired(
114
+ "Alert component doesn't support `active` or `dynamicRender` anymore, please remove that prop.",
115
+ );
116
+ }
117
+ }, [active, dynamicRender]);
118
+
118
119
  useEffect(() => {
119
120
  if (arrow !== undefined) {
120
121
  logActionRequired(
@@ -156,14 +157,12 @@ export default function Alert({
156
157
 
157
158
  const [shouldFire, setShouldFire] = useState<boolean>();
158
159
 
159
- const [shouldShow, setShouldShow] = useState<boolean>();
160
+ const [shouldAnnounce, setShouldAnnounce] = useState<boolean>(false);
160
161
  useEffect(() => {
161
- if ((shouldShow === undefined && !dynamicRender) || !active) {
162
- setShouldShow(active);
163
- } else {
164
- setTimeout(() => setShouldShow(active), WDS_LIVE_REGION_DELAY_MS);
165
- }
166
- }, [active, shouldShow, dynamicRender]);
162
+ setTimeout(() => {
163
+ setShouldAnnounce(true);
164
+ }, WDS_LIVE_REGION_DELAY_MS);
165
+ }, []);
167
166
 
168
167
  const closeButtonReference = useRef<HTMLButtonElement>(null);
169
168
 
@@ -172,63 +171,62 @@ export default function Alert({
172
171
  role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}
173
172
  className="wds-alert__liveRegion"
174
173
  >
175
- {shouldShow && (
176
- <div
177
- className={clsx(
178
- 'alert d-flex',
179
- `alert-${resolvedType}`,
180
- arrow != null && alertArrowClassNames(arrow),
181
- className,
182
- )}
183
- data-testid="alert"
184
- onTouchStart={() => setShouldFire(true)}
185
- onTouchEnd={(event) => {
186
- if (
187
- shouldFire &&
188
- action?.href &&
189
- // Check if current event is triggered from closeButton
190
- event.target instanceof Node &&
191
- closeButtonReference.current &&
192
- !closeButtonReference.current.contains(event.target)
193
- ) {
194
- if (action.target === '_blank') {
195
- window.top?.open(action.href);
196
- } else {
197
- window.top?.location.assign(action.href);
198
- }
174
+ <div
175
+ aria-hidden={shouldAnnounce ? undefined : 'true'}
176
+ className={clsx(
177
+ 'alert d-flex',
178
+ `alert-${resolvedType}`,
179
+ arrow != null && alertArrowClassNames(arrow),
180
+ className,
181
+ )}
182
+ data-testid="alert"
183
+ onTouchStart={() => setShouldFire(true)}
184
+ onTouchEnd={(event) => {
185
+ if (
186
+ shouldFire &&
187
+ action?.href &&
188
+ // Check if current event is triggered from closeButton
189
+ event.target instanceof Node &&
190
+ closeButtonReference.current &&
191
+ !closeButtonReference.current.contains(event.target)
192
+ ) {
193
+ if (action.target === '_blank') {
194
+ window.top?.open(action.href);
195
+ } else {
196
+ window.top?.location.assign(action.href);
199
197
  }
200
- setShouldFire(false);
201
- }}
202
- onTouchMove={() => setShouldFire(false)}
198
+ }
199
+ setShouldFire(false);
200
+ }}
201
+ onTouchMove={() => setShouldFire(false)}
202
+ >
203
+ <div
204
+ className={clsx('alert__content', 'd-flex', 'flex-grow-1', variant)}
205
+ data-testid={variant}
203
206
  >
204
- <div
205
- className={clsx('alert__content', 'd-flex', 'flex-grow-1', variant)}
206
- data-testid={variant}
207
- >
208
- {icon ? (
209
- <div className="alert__icon">{icon}</div>
210
- ) : (
211
- <StatusIcon size={Size.LARGE} sentiment={resolvedType} iconLabel={statusIconLabel} />
212
- )}
213
- <div className="alert__message">
214
- <div>
215
- {title && (
216
- <Title className="m-b-1" type={Typography.TITLE_BODY}>
217
- {title}
218
- </Title>
219
- )}
220
- <Body as="span" className="d-block" type={Typography.BODY_LARGE}>
221
- {children || <InlineMarkdown>{message}</InlineMarkdown>}
222
- </Body>
223
- </div>
224
- {action && <Action action={action} variant="action-button" className="m-t-1" />}
207
+ {icon ? (
208
+ <div className="alert__icon">{icon}</div>
209
+ ) : (
210
+ <StatusIcon size={Size.LARGE} sentiment={resolvedType} iconLabel={statusIconLabel} />
211
+ )}
212
+ <div className="alert__message">
213
+ <div>
214
+ {title && (
215
+ <Title className="m-b-1" type={Typography.TITLE_BODY}>
216
+ {title}
217
+ </Title>
218
+ )}
219
+ <Body as="span" className="d-block" type={Typography.BODY_LARGE}>
220
+ {children || <InlineMarkdown>{message}</InlineMarkdown>}
221
+ </Body>
225
222
  </div>
223
+ {action && <Action action={action} variant="action-button" className="m-t-1" />}
226
224
  </div>
227
- {onDismiss && (
228
- <CloseButton ref={closeButtonReference} className="m-l-2" onClick={onDismiss} />
229
- )}
230
225
  </div>
231
- )}
226
+ {onDismiss && (
227
+ <CloseButton ref={closeButtonReference} className="m-l-2" onClick={onDismiss} />
228
+ )}
229
+ </div>
232
230
  </div>
233
231
  );
234
232
  }