@transferwise/components 46.72.2 → 46.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/build/alert/Alert.js +12 -3
  2. package/build/alert/Alert.js.map +1 -1
  3. package/build/alert/Alert.mjs +12 -3
  4. package/build/alert/Alert.mjs.map +1 -1
  5. package/build/common/bottomSheet/BottomSheet.js +3 -1
  6. package/build/common/bottomSheet/BottomSheet.js.map +1 -1
  7. package/build/common/bottomSheet/BottomSheet.mjs +3 -1
  8. package/build/common/bottomSheet/BottomSheet.mjs.map +1 -1
  9. package/build/common/constants.js +15 -0
  10. package/build/common/constants.js.map +1 -0
  11. package/build/common/constants.mjs +13 -0
  12. package/build/common/constants.mjs.map +1 -0
  13. package/build/common/responsivePanel/ResponsivePanel.js +7 -1
  14. package/build/common/responsivePanel/ResponsivePanel.js.map +1 -1
  15. package/build/common/responsivePanel/ResponsivePanel.mjs +7 -1
  16. package/build/common/responsivePanel/ResponsivePanel.mjs.map +1 -1
  17. package/build/popover/Popover.js +6 -1
  18. package/build/popover/Popover.js.map +1 -1
  19. package/build/popover/Popover.mjs +7 -2
  20. package/build/popover/Popover.mjs.map +1 -1
  21. package/build/types/alert/Alert.d.ts.map +1 -1
  22. package/build/types/common/bottomSheet/BottomSheet.d.ts +1 -1
  23. package/build/types/common/bottomSheet/BottomSheet.d.ts.map +1 -1
  24. package/build/types/common/constants.d.ts +11 -0
  25. package/build/types/common/constants.d.ts.map +1 -0
  26. package/build/types/common/index.d.ts +2 -0
  27. package/build/types/common/responsivePanel/ResponsivePanel.d.ts.map +1 -1
  28. package/build/types/popover/Popover.d.ts +6 -4
  29. package/build/types/popover/Popover.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/src/alert/Alert.spec.story.tsx +87 -0
  32. package/src/alert/Alert.story.tsx +36 -6
  33. package/src/alert/Alert.tsx +20 -4
  34. package/src/common/bottomSheet/BottomSheet.tsx +4 -2
  35. package/src/common/constants.ts +11 -0
  36. package/src/common/index.js +2 -0
  37. package/src/common/responsivePanel/ResponsivePanel.tsx +13 -3
  38. package/src/popover/Popover.spec.tsx +64 -21
  39. package/src/popover/Popover.story.tsx +54 -42
  40. package/src/popover/Popover.tsx +12 -5
  41. package/src/popover/__snapshots__/Popover.spec.tsx.snap +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","sources":["../../src/popover/Popover.tsx"],"sourcesContent":["import { useTheme } from '@wise/components-theming';\nimport { clsx } from 'clsx';\nimport { useRef, useState, cloneElement, useEffect, isValidElement } from 'react';\n\nimport { Position, Typography } from '../common';\nimport ResponsivePanel from '../common/responsivePanel';\nimport Title from '../title';\nimport { logActionRequired } from '../utilities';\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype PopoverPreferredPlacementDeprecated =\n | `${Position.LEFT_TOP}`\n | `${Position.RIGHT_TOP}`\n | `${Position.BOTTOM_RIGHT}`\n | `${Position.BOTTOM_LEFT}`;\n\nexport type PopoverPreferredPlacement =\n | `${Position.TOP}`\n | `${Position.RIGHT}`\n | `${Position.BOTTOM}`\n | `${Position.LEFT}`\n | PopoverPreferredPlacementDeprecated;\n\nexport interface PopoverProps {\n children?: React.ReactNode;\n className?: string;\n content: React.ReactNode;\n preferredPlacement?: PopoverPreferredPlacement;\n onClose?: () => void;\n title?: React.ReactNode;\n}\n\nfunction resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {\n switch (preferredPlacement) {\n case 'left-top':\n case 'right-top':\n return 'top';\n case 'bottom-left':\n case 'bottom-right':\n return 'bottom';\n default:\n return preferredPlacement;\n }\n}\n\nexport default function Popover({\n children,\n className,\n content,\n preferredPlacement = Position.RIGHT,\n title,\n onClose,\n}: PopoverProps) {\n const resolvedPlacement = resolvePlacement(preferredPlacement);\n useEffect(() => {\n if (resolvedPlacement !== preferredPlacement) {\n logActionRequired(\n `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${resolvedPlacement} instead.`,\n );\n }\n }, [preferredPlacement, resolvedPlacement]);\n\n const anchorReference = useRef(null);\n const [open, setOpen] = useState(false);\n\n const handleOnClose = () => {\n setOpen(false);\n onClose?.();\n };\n\n return (\n <span className={clsx('np-popover', className)}>\n <span ref={anchorReference} className=\"d-inline-block\">\n {isValidElement<{ onClick?: () => void }>(children)\n ? cloneElement(children, {\n onClick: () => {\n children.props.onClick?.();\n setOpen((prevOpen) => !prevOpen);\n },\n })\n : children}\n </span>\n <ResponsivePanel\n open={open}\n anchorRef={anchorReference}\n position={resolvedPlacement}\n arrow\n className=\"np-popover__container\"\n onClose={handleOnClose}\n >\n <div className=\"np-popover__content np-text-default-body\">\n {title && (\n <Title type={Typography.TITLE_BODY} className=\"m-b-1\">\n {title}\n </Title>\n )}\n {content}\n </div>\n </ResponsivePanel>\n </span>\n );\n}\n"],"names":["resolvePlacement","preferredPlacement","Popover","children","className","content","Position","RIGHT","title","onClose","resolvedPlacement","useEffect","logActionRequired","anchorReference","useRef","open","setOpen","useState","handleOnClose","_jsxs","clsx","_jsx","ref","isValidElement","cloneElement","onClick","props","prevOpen","ResponsivePanel","anchorRef","position","arrow","Title","type","Typography","TITLE_BODY"],"mappings":";;;;;;;;;;;AAgCA,SAASA,gBAAgBA,CAACC,kBAA6C,EAAA;AACrE,EAAA,QAAQA,kBAAkB;AACxB,IAAA,KAAK,UAAU,CAAA;AACf,IAAA,KAAK,WAAW;AACd,MAAA,OAAO,KAAK,CAAA;AACd,IAAA,KAAK,aAAa,CAAA;AAClB,IAAA,KAAK,cAAc;AACjB,MAAA,OAAO,QAAQ,CAAA;AACjB,IAAA;AACE,MAAA,OAAOA,kBAAkB,CAAA;AAC7B,GAAA;AACF,CAAA;AAEwB,SAAAC,OAAOA,CAAC;EAC9BC,QAAQ;EACRC,SAAS;EACTC,OAAO;EACPJ,kBAAkB,GAAGK,iBAAQ,CAACC,KAAK;EACnCC,KAAK;AACLC,EAAAA,OAAAA;AACa,CAAA,EAAA;AACb,EAAA,MAAMC,iBAAiB,GAAGV,gBAAgB,CAACC,kBAAkB,CAAC,CAAA;AAC9DU,EAAAA,eAAS,CAAC,MAAK;IACb,IAAID,iBAAiB,KAAKT,kBAAkB,EAAE;AAC5CW,MAAAA,mCAAiB,CACf,CAA0BX,uBAAAA,EAAAA,kBAAkB,CAAwDS,qDAAAA,EAAAA,iBAAiB,WAAW,CACjI,CAAA;AACH,KAAA;AACF,GAAC,EAAE,CAACT,kBAAkB,EAAES,iBAAiB,CAAC,CAAC,CAAA;AAE3C,EAAA,MAAMG,eAAe,GAAGC,YAAM,CAAC,IAAI,CAAC,CAAA;EACpC,MAAM,CAACC,IAAI,EAAEC,OAAO,CAAC,GAAGC,cAAQ,CAAC,KAAK,CAAC,CAAA;EAEvC,MAAMC,aAAa,GAAGA,MAAK;IACzBF,OAAO,CAAC,KAAK,CAAC,CAAA;AACdP,IAAAA,OAAO,IAAI,CAAA;GACZ,CAAA;AAED,EAAA,oBACEU,eAAA,CAAA,MAAA,EAAA;AAAMf,IAAAA,SAAS,EAAEgB,SAAI,CAAC,YAAY,EAAEhB,SAAS,CAAE;AAAAD,IAAAA,QAAA,gBAC7CkB,cAAA,CAAA,MAAA,EAAA;AAAMC,MAAAA,GAAG,EAAET,eAAgB;AAACT,MAAAA,SAAS,EAAC,gBAAgB;MAAAD,QAAA,eACnDoB,oBAAc,CAA2BpB,QAAQ,CAAC,gBAC/CqB,kBAAY,CAACrB,QAAQ,EAAE;QACrBsB,OAAO,EAAEA,MAAK;AACZtB,UAAAA,QAAQ,CAACuB,KAAK,CAACD,OAAO,IAAI,CAAA;AAC1BT,UAAAA,OAAO,CAAEW,QAAQ,IAAK,CAACA,QAAQ,CAAC,CAAA;AAClC,SAAA;OACD,CAAC,GACFxB,QAAAA;AAAQ,KACR,CACN,eAAAkB,cAAA,CAACO,eAAe,EAAA;AACdb,MAAAA,IAAI,EAAEA,IAAK;AACXc,MAAAA,SAAS,EAAEhB,eAAgB;AAC3BiB,MAAAA,QAAQ,EAAEpB,iBAAkB;MAC5BqB,KAAK,EAAA,IAAA;AACL3B,MAAAA,SAAS,EAAC,uBAAuB;AACjCK,MAAAA,OAAO,EAAES,aAAc;AAAAf,MAAAA,QAAA,eAEvBgB,eAAA,CAAA,KAAA,EAAA;AAAKf,QAAAA,SAAS,EAAC,0CAA0C;AAAAD,QAAAA,QAAA,EACtDK,CAAAA,KAAK,iBACJa,cAAA,CAACW,KAAK,EAAA;UAACC,IAAI,EAAEC,qBAAU,CAACC,UAAW;AAAC/B,UAAAA,SAAS,EAAC,OAAO;AAAAD,UAAAA,QAAA,EAClDK,KAAAA;SACI,CACR,EACAH,OAAO,CAAA;OACL,CAAA;AACP,KAAiB,CACnB,CAAA;AAAA,GAAM,CAAC,CAAA;AAEX;;;;"}
1
+ {"version":3,"file":"Popover.js","sources":["../../src/popover/Popover.tsx"],"sourcesContent":["import { useTheme } from '@wise/components-theming';\nimport { clsx } from 'clsx';\nimport { useRef, useState, cloneElement, useEffect, isValidElement, useId } from 'react';\n\nimport { Position, Typography } from '../common';\nimport ResponsivePanel from '../common/responsivePanel';\nimport Title from '../title';\nimport { logActionRequired } from '../utilities';\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype PopoverPreferredPlacementDeprecated =\n | `${Position.LEFT_TOP}`\n | `${Position.RIGHT_TOP}`\n | `${Position.BOTTOM_RIGHT}`\n | `${Position.BOTTOM_LEFT}`;\n\nexport type PopoverPreferredPlacement =\n | `${Position.TOP}`\n | `${Position.RIGHT}`\n | `${Position.BOTTOM}`\n | `${Position.LEFT}`\n | PopoverPreferredPlacementDeprecated;\n\nexport interface PopoverProps {\n children?: React.ReactNode;\n title?: React.ReactNode;\n /** Screen-reader-friendly title. Must be provided if `title` prop is not set. */\n 'aria-label'?: string;\n preferredPlacement?: PopoverPreferredPlacement;\n content: React.ReactNode;\n onClose?: () => void;\n className?: string;\n}\n\nfunction resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {\n switch (preferredPlacement) {\n case 'left-top':\n case 'right-top':\n return 'top';\n case 'bottom-left':\n case 'bottom-right':\n return 'bottom';\n default:\n return preferredPlacement;\n }\n}\n\nexport default function Popover({\n children,\n className,\n content,\n preferredPlacement = Position.RIGHT,\n title,\n onClose,\n 'aria-label': ariaLabel,\n}: PopoverProps) {\n const titleId = useId();\n\n const resolvedPlacement = resolvePlacement(preferredPlacement);\n useEffect(() => {\n if (resolvedPlacement !== preferredPlacement) {\n logActionRequired(\n `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${resolvedPlacement} instead.`,\n );\n }\n }, [preferredPlacement, resolvedPlacement]);\n\n const anchorReference = useRef(null);\n const [open, setOpen] = useState(false);\n\n const handleOnClose = () => {\n setOpen(false);\n onClose?.();\n };\n\n return (\n <span className={clsx('np-popover', className)}>\n <span ref={anchorReference} className=\"d-inline-block\">\n {isValidElement<{ onClick?: () => void }>(children)\n ? cloneElement(children, {\n onClick: () => {\n children.props.onClick?.();\n setOpen((prevOpen) => !prevOpen);\n },\n })\n : children}\n </span>\n <ResponsivePanel\n aria-label={ariaLabel}\n aria-labelledby={title && !ariaLabel ? titleId : undefined}\n open={open}\n anchorRef={anchorReference}\n position={resolvedPlacement}\n arrow\n className=\"np-popover__container\"\n onClose={handleOnClose}\n >\n <div className=\"np-popover__content np-text-default-body\">\n {title && (\n <Title type={Typography.TITLE_BODY} id={titleId} className=\"m-b-1\">\n {title}\n </Title>\n )}\n {content}\n </div>\n </ResponsivePanel>\n </span>\n );\n}\n"],"names":["resolvePlacement","preferredPlacement","Popover","children","className","content","Position","RIGHT","title","onClose","ariaLabel","titleId","useId","resolvedPlacement","useEffect","logActionRequired","anchorReference","useRef","open","setOpen","useState","handleOnClose","_jsxs","clsx","_jsx","ref","isValidElement","cloneElement","onClick","props","prevOpen","ResponsivePanel","undefined","anchorRef","position","arrow","Title","type","Typography","TITLE_BODY","id"],"mappings":";;;;;;;;;;;AAkCA,SAASA,gBAAgBA,CAACC,kBAA6C,EAAA;AACrE,EAAA,QAAQA,kBAAkB;AACxB,IAAA,KAAK,UAAU,CAAA;AACf,IAAA,KAAK,WAAW;AACd,MAAA,OAAO,KAAK,CAAA;AACd,IAAA,KAAK,aAAa,CAAA;AAClB,IAAA,KAAK,cAAc;AACjB,MAAA,OAAO,QAAQ,CAAA;AACjB,IAAA;AACE,MAAA,OAAOA,kBAAkB,CAAA;AAC7B,GAAA;AACF,CAAA;AAEc,SAAUC,OAAOA,CAAC;EAC9BC,QAAQ;EACRC,SAAS;EACTC,OAAO;EACPJ,kBAAkB,GAAGK,iBAAQ,CAACC,KAAK;EACnCC,KAAK;EACLC,OAAO;AACP,EAAA,YAAY,EAAEC,SAAAA;AACD,CAAA,EAAA;AACb,EAAA,MAAMC,OAAO,GAAGC,WAAK,EAAE,CAAA;AAEvB,EAAA,MAAMC,iBAAiB,GAAGb,gBAAgB,CAACC,kBAAkB,CAAC,CAAA;AAC9Da,EAAAA,eAAS,CAAC,MAAK;IACb,IAAID,iBAAiB,KAAKZ,kBAAkB,EAAE;AAC5Cc,MAAAA,mCAAiB,CACf,CAA0Bd,uBAAAA,EAAAA,kBAAkB,CAAwDY,qDAAAA,EAAAA,iBAAiB,WAAW,CACjI,CAAA;AACH,KAAA;AACF,GAAC,EAAE,CAACZ,kBAAkB,EAAEY,iBAAiB,CAAC,CAAC,CAAA;AAE3C,EAAA,MAAMG,eAAe,GAAGC,YAAM,CAAC,IAAI,CAAC,CAAA;EACpC,MAAM,CAACC,IAAI,EAAEC,OAAO,CAAC,GAAGC,cAAQ,CAAC,KAAK,CAAC,CAAA;EAEvC,MAAMC,aAAa,GAAGA,MAAK;IACzBF,OAAO,CAAC,KAAK,CAAC,CAAA;AACdV,IAAAA,OAAO,IAAI,CAAA;GACZ,CAAA;AAED,EAAA,oBACEa,eAAA,CAAA,MAAA,EAAA;AAAMlB,IAAAA,SAAS,EAAEmB,SAAI,CAAC,YAAY,EAAEnB,SAAS,CAAE;AAAAD,IAAAA,QAAA,gBAC7CqB,cAAA,CAAA,MAAA,EAAA;AAAMC,MAAAA,GAAG,EAAET,eAAgB;AAACZ,MAAAA,SAAS,EAAC,gBAAgB;MAAAD,QAAA,eACnDuB,oBAAc,CAA2BvB,QAAQ,CAAC,gBAC/CwB,kBAAY,CAACxB,QAAQ,EAAE;QACrByB,OAAO,EAAEA,MAAK;AACZzB,UAAAA,QAAQ,CAAC0B,KAAK,CAACD,OAAO,IAAI,CAAA;AAC1BT,UAAAA,OAAO,CAAEW,QAAQ,IAAK,CAACA,QAAQ,CAAC,CAAA;AAClC,SAAA;OACD,CAAC,GACF3B,QAAAA;AAAQ,KACR,CACN,eAAAqB,cAAA,CAACO,eAAe,EAAA;AACd,MAAA,YAAA,EAAYrB,SAAU;AACtB,MAAA,iBAAA,EAAiBF,KAAK,IAAI,CAACE,SAAS,GAAGC,OAAO,GAAGqB,SAAU;AAC3Dd,MAAAA,IAAI,EAAEA,IAAK;AACXe,MAAAA,SAAS,EAAEjB,eAAgB;AAC3BkB,MAAAA,QAAQ,EAAErB,iBAAkB;MAC5BsB,KAAK,EAAA,IAAA;AACL/B,MAAAA,SAAS,EAAC,uBAAuB;AACjCK,MAAAA,OAAO,EAAEY,aAAc;AAAAlB,MAAAA,QAAA,eAEvBmB,eAAA,CAAA,KAAA,EAAA;AAAKlB,QAAAA,SAAS,EAAC,0CAA0C;AAAAD,QAAAA,QAAA,EACtDK,CAAAA,KAAK,iBACJgB,cAAA,CAACY,KAAK,EAAA;UAACC,IAAI,EAAEC,qBAAU,CAACC,UAAW;AAACC,UAAAA,EAAE,EAAE7B,OAAQ;AAACP,UAAAA,SAAS,EAAC,OAAO;AAAAD,UAAAA,QAAA,EAC/DK,KAAAA;SACI,CACR,EACAH,OAAO,CAAA;OACL,CAAA;AACP,KAAiB,CACnB,CAAA;AAAA,GAAM,CAAC,CAAA;AAEX;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx';
2
- import { useEffect, useRef, useState, isValidElement, cloneElement } from 'react';
2
+ import { useId, useEffect, useRef, useState, isValidElement, cloneElement } from 'react';
3
3
  import Title from '../title/Title.mjs';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
  import { logActionRequired } from '../utilities/logActionRequired.mjs';
@@ -25,8 +25,10 @@ function Popover({
25
25
  content,
26
26
  preferredPlacement = Position.RIGHT,
27
27
  title,
28
- onClose
28
+ onClose,
29
+ 'aria-label': ariaLabel
29
30
  }) {
31
+ const titleId = useId();
30
32
  const resolvedPlacement = resolvePlacement(preferredPlacement);
31
33
  useEffect(() => {
32
34
  if (resolvedPlacement !== preferredPlacement) {
@@ -51,6 +53,8 @@ function Popover({
51
53
  }
52
54
  }) : children
53
55
  }), /*#__PURE__*/jsx(ResponsivePanel, {
56
+ "aria-label": ariaLabel,
57
+ "aria-labelledby": title && !ariaLabel ? titleId : undefined,
54
58
  open: open,
55
59
  anchorRef: anchorReference,
56
60
  position: resolvedPlacement,
@@ -61,6 +65,7 @@ function Popover({
61
65
  className: "np-popover__content np-text-default-body",
62
66
  children: [title && /*#__PURE__*/jsx(Title, {
63
67
  type: Typography.TITLE_BODY,
68
+ id: titleId,
64
69
  className: "m-b-1",
65
70
  children: title
66
71
  }), content]
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.mjs","sources":["../../src/popover/Popover.tsx"],"sourcesContent":["import { useTheme } from '@wise/components-theming';\nimport { clsx } from 'clsx';\nimport { useRef, useState, cloneElement, useEffect, isValidElement } from 'react';\n\nimport { Position, Typography } from '../common';\nimport ResponsivePanel from '../common/responsivePanel';\nimport Title from '../title';\nimport { logActionRequired } from '../utilities';\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype PopoverPreferredPlacementDeprecated =\n | `${Position.LEFT_TOP}`\n | `${Position.RIGHT_TOP}`\n | `${Position.BOTTOM_RIGHT}`\n | `${Position.BOTTOM_LEFT}`;\n\nexport type PopoverPreferredPlacement =\n | `${Position.TOP}`\n | `${Position.RIGHT}`\n | `${Position.BOTTOM}`\n | `${Position.LEFT}`\n | PopoverPreferredPlacementDeprecated;\n\nexport interface PopoverProps {\n children?: React.ReactNode;\n className?: string;\n content: React.ReactNode;\n preferredPlacement?: PopoverPreferredPlacement;\n onClose?: () => void;\n title?: React.ReactNode;\n}\n\nfunction resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {\n switch (preferredPlacement) {\n case 'left-top':\n case 'right-top':\n return 'top';\n case 'bottom-left':\n case 'bottom-right':\n return 'bottom';\n default:\n return preferredPlacement;\n }\n}\n\nexport default function Popover({\n children,\n className,\n content,\n preferredPlacement = Position.RIGHT,\n title,\n onClose,\n}: PopoverProps) {\n const resolvedPlacement = resolvePlacement(preferredPlacement);\n useEffect(() => {\n if (resolvedPlacement !== preferredPlacement) {\n logActionRequired(\n `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${resolvedPlacement} instead.`,\n );\n }\n }, [preferredPlacement, resolvedPlacement]);\n\n const anchorReference = useRef(null);\n const [open, setOpen] = useState(false);\n\n const handleOnClose = () => {\n setOpen(false);\n onClose?.();\n };\n\n return (\n <span className={clsx('np-popover', className)}>\n <span ref={anchorReference} className=\"d-inline-block\">\n {isValidElement<{ onClick?: () => void }>(children)\n ? cloneElement(children, {\n onClick: () => {\n children.props.onClick?.();\n setOpen((prevOpen) => !prevOpen);\n },\n })\n : children}\n </span>\n <ResponsivePanel\n open={open}\n anchorRef={anchorReference}\n position={resolvedPlacement}\n arrow\n className=\"np-popover__container\"\n onClose={handleOnClose}\n >\n <div className=\"np-popover__content np-text-default-body\">\n {title && (\n <Title type={Typography.TITLE_BODY} className=\"m-b-1\">\n {title}\n </Title>\n )}\n {content}\n </div>\n </ResponsivePanel>\n </span>\n );\n}\n"],"names":["resolvePlacement","preferredPlacement","Popover","children","className","content","Position","RIGHT","title","onClose","resolvedPlacement","useEffect","logActionRequired","anchorReference","useRef","open","setOpen","useState","handleOnClose","_jsxs","clsx","_jsx","ref","isValidElement","cloneElement","onClick","props","prevOpen","ResponsivePanel","anchorRef","position","arrow","Title","type","Typography","TITLE_BODY"],"mappings":";;;;;;;;;AAgCA,SAASA,gBAAgBA,CAACC,kBAA6C,EAAA;AACrE,EAAA,QAAQA,kBAAkB;AACxB,IAAA,KAAK,UAAU,CAAA;AACf,IAAA,KAAK,WAAW;AACd,MAAA,OAAO,KAAK,CAAA;AACd,IAAA,KAAK,aAAa,CAAA;AAClB,IAAA,KAAK,cAAc;AACjB,MAAA,OAAO,QAAQ,CAAA;AACjB,IAAA;AACE,MAAA,OAAOA,kBAAkB,CAAA;AAC7B,GAAA;AACF,CAAA;AAEwB,SAAAC,OAAOA,CAAC;EAC9BC,QAAQ;EACRC,SAAS;EACTC,OAAO;EACPJ,kBAAkB,GAAGK,QAAQ,CAACC,KAAK;EACnCC,KAAK;AACLC,EAAAA,OAAAA;AACa,CAAA,EAAA;AACb,EAAA,MAAMC,iBAAiB,GAAGV,gBAAgB,CAACC,kBAAkB,CAAC,CAAA;AAC9DU,EAAAA,SAAS,CAAC,MAAK;IACb,IAAID,iBAAiB,KAAKT,kBAAkB,EAAE;AAC5CW,MAAAA,iBAAiB,CACf,CAA0BX,uBAAAA,EAAAA,kBAAkB,CAAwDS,qDAAAA,EAAAA,iBAAiB,WAAW,CACjI,CAAA;AACH,KAAA;AACF,GAAC,EAAE,CAACT,kBAAkB,EAAES,iBAAiB,CAAC,CAAC,CAAA;AAE3C,EAAA,MAAMG,eAAe,GAAGC,MAAM,CAAC,IAAI,CAAC,CAAA;EACpC,MAAM,CAACC,IAAI,EAAEC,OAAO,CAAC,GAAGC,QAAQ,CAAC,KAAK,CAAC,CAAA;EAEvC,MAAMC,aAAa,GAAGA,MAAK;IACzBF,OAAO,CAAC,KAAK,CAAC,CAAA;AACdP,IAAAA,OAAO,IAAI,CAAA;GACZ,CAAA;AAED,EAAA,oBACEU,IAAA,CAAA,MAAA,EAAA;AAAMf,IAAAA,SAAS,EAAEgB,IAAI,CAAC,YAAY,EAAEhB,SAAS,CAAE;AAAAD,IAAAA,QAAA,gBAC7CkB,GAAA,CAAA,MAAA,EAAA;AAAMC,MAAAA,GAAG,EAAET,eAAgB;AAACT,MAAAA,SAAS,EAAC,gBAAgB;MAAAD,QAAA,eACnDoB,cAAc,CAA2BpB,QAAQ,CAAC,gBAC/CqB,YAAY,CAACrB,QAAQ,EAAE;QACrBsB,OAAO,EAAEA,MAAK;AACZtB,UAAAA,QAAQ,CAACuB,KAAK,CAACD,OAAO,IAAI,CAAA;AAC1BT,UAAAA,OAAO,CAAEW,QAAQ,IAAK,CAACA,QAAQ,CAAC,CAAA;AAClC,SAAA;OACD,CAAC,GACFxB,QAAAA;AAAQ,KACR,CACN,eAAAkB,GAAA,CAACO,eAAe,EAAA;AACdb,MAAAA,IAAI,EAAEA,IAAK;AACXc,MAAAA,SAAS,EAAEhB,eAAgB;AAC3BiB,MAAAA,QAAQ,EAAEpB,iBAAkB;MAC5BqB,KAAK,EAAA,IAAA;AACL3B,MAAAA,SAAS,EAAC,uBAAuB;AACjCK,MAAAA,OAAO,EAAES,aAAc;AAAAf,MAAAA,QAAA,eAEvBgB,IAAA,CAAA,KAAA,EAAA;AAAKf,QAAAA,SAAS,EAAC,0CAA0C;AAAAD,QAAAA,QAAA,EACtDK,CAAAA,KAAK,iBACJa,GAAA,CAACW,KAAK,EAAA;UAACC,IAAI,EAAEC,UAAU,CAACC,UAAW;AAAC/B,UAAAA,SAAS,EAAC,OAAO;AAAAD,UAAAA,QAAA,EAClDK,KAAAA;SACI,CACR,EACAH,OAAO,CAAA;OACL,CAAA;AACP,KAAiB,CACnB,CAAA;AAAA,GAAM,CAAC,CAAA;AAEX;;;;"}
1
+ {"version":3,"file":"Popover.mjs","sources":["../../src/popover/Popover.tsx"],"sourcesContent":["import { useTheme } from '@wise/components-theming';\nimport { clsx } from 'clsx';\nimport { useRef, useState, cloneElement, useEffect, isValidElement, useId } from 'react';\n\nimport { Position, Typography } from '../common';\nimport ResponsivePanel from '../common/responsivePanel';\nimport Title from '../title';\nimport { logActionRequired } from '../utilities';\n\n/** @deprecated Use `\"top\" | \"bottom\"` instead. */\ntype PopoverPreferredPlacementDeprecated =\n | `${Position.LEFT_TOP}`\n | `${Position.RIGHT_TOP}`\n | `${Position.BOTTOM_RIGHT}`\n | `${Position.BOTTOM_LEFT}`;\n\nexport type PopoverPreferredPlacement =\n | `${Position.TOP}`\n | `${Position.RIGHT}`\n | `${Position.BOTTOM}`\n | `${Position.LEFT}`\n | PopoverPreferredPlacementDeprecated;\n\nexport interface PopoverProps {\n children?: React.ReactNode;\n title?: React.ReactNode;\n /** Screen-reader-friendly title. Must be provided if `title` prop is not set. */\n 'aria-label'?: string;\n preferredPlacement?: PopoverPreferredPlacement;\n content: React.ReactNode;\n onClose?: () => void;\n className?: string;\n}\n\nfunction resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {\n switch (preferredPlacement) {\n case 'left-top':\n case 'right-top':\n return 'top';\n case 'bottom-left':\n case 'bottom-right':\n return 'bottom';\n default:\n return preferredPlacement;\n }\n}\n\nexport default function Popover({\n children,\n className,\n content,\n preferredPlacement = Position.RIGHT,\n title,\n onClose,\n 'aria-label': ariaLabel,\n}: PopoverProps) {\n const titleId = useId();\n\n const resolvedPlacement = resolvePlacement(preferredPlacement);\n useEffect(() => {\n if (resolvedPlacement !== preferredPlacement) {\n logActionRequired(\n `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${resolvedPlacement} instead.`,\n );\n }\n }, [preferredPlacement, resolvedPlacement]);\n\n const anchorReference = useRef(null);\n const [open, setOpen] = useState(false);\n\n const handleOnClose = () => {\n setOpen(false);\n onClose?.();\n };\n\n return (\n <span className={clsx('np-popover', className)}>\n <span ref={anchorReference} className=\"d-inline-block\">\n {isValidElement<{ onClick?: () => void }>(children)\n ? cloneElement(children, {\n onClick: () => {\n children.props.onClick?.();\n setOpen((prevOpen) => !prevOpen);\n },\n })\n : children}\n </span>\n <ResponsivePanel\n aria-label={ariaLabel}\n aria-labelledby={title && !ariaLabel ? titleId : undefined}\n open={open}\n anchorRef={anchorReference}\n position={resolvedPlacement}\n arrow\n className=\"np-popover__container\"\n onClose={handleOnClose}\n >\n <div className=\"np-popover__content np-text-default-body\">\n {title && (\n <Title type={Typography.TITLE_BODY} id={titleId} className=\"m-b-1\">\n {title}\n </Title>\n )}\n {content}\n </div>\n </ResponsivePanel>\n </span>\n );\n}\n"],"names":["resolvePlacement","preferredPlacement","Popover","children","className","content","Position","RIGHT","title","onClose","ariaLabel","titleId","useId","resolvedPlacement","useEffect","logActionRequired","anchorReference","useRef","open","setOpen","useState","handleOnClose","_jsxs","clsx","_jsx","ref","isValidElement","cloneElement","onClick","props","prevOpen","ResponsivePanel","undefined","anchorRef","position","arrow","Title","type","Typography","TITLE_BODY","id"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../../src/alert/Alert.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAc,OAAO,EAAE,MAAM,WAAW,CAAC;AASjE,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,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,4LAA4L;IAC5L,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,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,SAAS,EACT,OAAO,EACP,IAAI,EACJ,KAAK,EACL,IAAgB,EAChB,OAAmB,EACnB,MAAa,GACd,EAAE,UAAU,+BAyGZ"}
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,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,4LAA4L;IAC5L,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,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,SAAS,EACT,OAAO,EACP,IAAI,EACJ,KAAK,EACL,IAAgB,EAChB,OAAmB,EACnB,MAAa,GACd,EAAE,UAAU,+BAkHZ"}
@@ -3,7 +3,7 @@ import { CommonProps } from '../commonProps';
3
3
  export type BottomSheetProps = PropsWithChildren<{
4
4
  onClose?: (event: Event | SyntheticEvent) => void;
5
5
  open: boolean;
6
- } & CommonProps & Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby'>>;
6
+ } & CommonProps & Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby' | 'aria-label'>>;
7
7
  /**
8
8
  * Neptune: https://transferwise.github.io/neptune/components/bottom-sheet/
9
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/common/bottomSheet/BottomSheet.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,cAAc,EAIf,MAAM,OAAO,CAAC;AAOf,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAa7C,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAC9C;IACE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,WAAW,GACb,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC,CACnE,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,WAAW,uBAAmC,gBAAgB,gCA2LnE,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"BottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/common/bottomSheet/BottomSheet.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,cAAc,EAIf,MAAM,OAAO,CAAC;AAOf,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAa7C,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAC9C;IACE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,WAAW,GACb,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,YAAY,CAAC,CAClF,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,WAAW,uBAAmC,gBAAgB,gCA6LnE,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This file holds repository-wide constants that are reusable by more than 1 component.
3
+ */
4
+ /**
5
+ * A delay [ms] after which it's OK to update a live region content,
6
+ * taking under consideration delayed programmatic refocusing
7
+ * of triggering components (e.g., SelectInput) and Accessibility
8
+ * Tree updates that prevent the screen reader announcements.
9
+ */
10
+ export declare const WDS_LIVE_REGION_DELAY_MS = 175;
11
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/common/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC"}
@@ -14,6 +14,7 @@ export * from "./locale";
14
14
  export * from "./commonProps";
15
15
  export * from "./initials";
16
16
  export * from "./colors";
17
+ export * from "./constants";
17
18
  export { Breakpoint } from "./propsValues/breakpoint";
18
19
  export { Type } from "./propsValues/type";
19
20
  export { DateMode } from "./propsValues/dateMode";
@@ -23,5 +24,6 @@ export { Sentiment } from "./propsValues/sentiment";
23
24
  export { Variant } from "./propsValues/variant";
24
25
  export { MarkdownNodeType } from "./propsValues/markdownNodeType";
25
26
  export { FileType } from "./fileType";
27
+ export { CloseButton } from "./closeButton";
26
28
  export { addNoScrollClass, removeNoScrollClass } from "./DOMOperations";
27
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResponsivePanel.d.ts","sourceRoot":"","sources":["../../../../src/common/responsivePanel/ResponsivePanel.tsx"],"names":[],"mappings":"AAQA,QAAA,MAAM,eAAe;;;;;;;;;;;mGAsCnB,CAAC;AAEH,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ResponsivePanel.d.ts","sourceRoot":"","sources":["../../../../src/common/responsivePanel/ResponsivePanel.tsx"],"names":[],"mappings":"AAOA,QAAA,MAAM,eAAe;;;;;;;;;;;mGAiDnB,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -4,12 +4,14 @@ type PopoverPreferredPlacementDeprecated = `${Position.LEFT_TOP}` | `${Position.
4
4
  export type PopoverPreferredPlacement = `${Position.TOP}` | `${Position.RIGHT}` | `${Position.BOTTOM}` | `${Position.LEFT}` | PopoverPreferredPlacementDeprecated;
5
5
  export interface PopoverProps {
6
6
  children?: React.ReactNode;
7
- className?: string;
8
- content: React.ReactNode;
7
+ title?: React.ReactNode;
8
+ /** Screen-reader-friendly title. Must be provided if `title` prop is not set. */
9
+ 'aria-label'?: string;
9
10
  preferredPlacement?: PopoverPreferredPlacement;
11
+ content: React.ReactNode;
10
12
  onClose?: () => void;
11
- title?: React.ReactNode;
13
+ className?: string;
12
14
  }
13
- export default function Popover({ children, className, content, preferredPlacement, title, onClose, }: PopoverProps): import("react").JSX.Element;
15
+ export default function Popover({ children, className, content, preferredPlacement, title, onClose, 'aria-label': ariaLabel, }: PopoverProps): import("react").JSX.Element;
14
16
  export {};
15
17
  //# sourceMappingURL=Popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../src/popover/Popover.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAc,MAAM,WAAW,CAAC;AAKjD,kDAAkD;AAClD,KAAK,mCAAmC,GACpC,GAAG,QAAQ,CAAC,QAAQ,EAAE,GACtB,GAAG,QAAQ,CAAC,SAAS,EAAE,GACvB,GAAG,QAAQ,CAAC,YAAY,EAAE,GAC1B,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAE9B,MAAM,MAAM,yBAAyB,GACjC,GAAG,QAAQ,CAAC,GAAG,EAAE,GACjB,GAAG,QAAQ,CAAC,KAAK,EAAE,GACnB,GAAG,QAAQ,CAAC,MAAM,EAAE,GACpB,GAAG,QAAQ,CAAC,IAAI,EAAE,GAClB,mCAAmC,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAeD,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,OAAO,EACP,kBAAmC,EACnC,KAAK,EACL,OAAO,GACR,EAAE,YAAY,+BAiDd"}
1
+ {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../src/popover/Popover.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAc,MAAM,WAAW,CAAC;AAKjD,kDAAkD;AAClD,KAAK,mCAAmC,GACpC,GAAG,QAAQ,CAAC,QAAQ,EAAE,GACtB,GAAG,QAAQ,CAAC,SAAS,EAAE,GACvB,GAAG,QAAQ,CAAC,YAAY,EAAE,GAC1B,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAE9B,MAAM,MAAM,yBAAyB,GACjC,GAAG,QAAQ,CAAC,GAAG,EAAE,GACjB,GAAG,QAAQ,CAAC,KAAK,EAAE,GACnB,GAAG,QAAQ,CAAC,MAAM,EAAE,GACpB,GAAG,QAAQ,CAAC,IAAI,EAAE,GAClB,mCAAmC,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAeD,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,OAAO,EACP,kBAAmC,EACnC,KAAK,EACL,OAAO,EACP,YAAY,EAAE,SAAS,GACxB,EAAE,YAAY,+BAqDd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "46.72.2",
3
+ "version": "46.74.0",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -0,0 +1,87 @@
1
+ import { useState } from 'react';
2
+ import { userEvent, within, expect, waitFor } from '@storybook/test';
3
+ import { Button, Field, SelectInput, Sentiment } from '..';
4
+ import Alert from './Alert';
5
+
6
+ import { Meta, StoryObj } from '@storybook/react';
7
+
8
+ const meta = {
9
+ title: 'Feedback/Alert/tests',
10
+ component: Alert,
11
+ argTypes: {},
12
+ args: {
13
+ type: Sentiment.POSITIVE,
14
+ active: true,
15
+ message: 'Payments sent to your bank details today might not arrive in time for the holidays.',
16
+ },
17
+ } satisfies Meta<typeof Alert>;
18
+ export default meta;
19
+
20
+ type Story = StoryObj<typeof meta>;
21
+
22
+ const wait = async (duration = 500) =>
23
+ new Promise<void>((resolve) => {
24
+ setTimeout(resolve, duration);
25
+ });
26
+
27
+ export const SimpleTrigger: Story = {
28
+ play: async ({ args, canvasElement }) => {
29
+ const canvas = within(canvasElement);
30
+ await wait();
31
+ await userEvent.tab();
32
+ await wait();
33
+ await userEvent.keyboard('{Enter}');
34
+
35
+ await waitFor(async () => expect(canvas.getByText(args.message || '')).toBeInTheDocument());
36
+ },
37
+ render: function Render(args) {
38
+ const [isActive, setIsActive] = useState(false);
39
+
40
+ return (
41
+ <>
42
+ <Button htmlType="button" onClick={() => setIsActive(true)}>
43
+ Trigger Alert
44
+ </Button>
45
+
46
+ <Alert {...args} active={isActive} className="m-t-4" />
47
+ </>
48
+ );
49
+ },
50
+ };
51
+
52
+ export const ComplexTrigger: Story = {
53
+ play: async ({ args, canvasElement }) => {
54
+ const canvas = within(canvasElement);
55
+ await wait();
56
+ await userEvent.tab();
57
+ await wait();
58
+ await userEvent.keyboard('{ArrowDown}');
59
+ await wait();
60
+ await userEvent.keyboard('{ArrowDown}');
61
+ await wait();
62
+ await userEvent.keyboard('{Enter}');
63
+
64
+ await waitFor(async () => expect(canvas.getByText(args.message || '')).toBeInTheDocument());
65
+ },
66
+ render: function Render(args) {
67
+ const [isActive, setIsActive] = useState(false);
68
+ const [value, setValue] = useState<string>();
69
+
70
+ return (
71
+ <>
72
+ <Field label="Select option to triger Alert">
73
+ <SelectInput
74
+ items={[
75
+ { type: 'option', value: 'one' },
76
+ { type: 'option', value: 'two' },
77
+ ]}
78
+ onChange={setValue}
79
+ onClose={() => setIsActive(Boolean(value))}
80
+ />
81
+ </Field>
82
+
83
+ <Alert {...args} active={isActive} className="m-t-2" />
84
+ </>
85
+ );
86
+ },
87
+ };
@@ -4,7 +4,7 @@ import { action } from '@storybook/addon-actions';
4
4
  import { ClockBorderless } from '@transferwise/icons';
5
5
 
6
6
  import { Sentiment } from '../common';
7
- import { Button } from '..';
7
+ import { Button, Field, SelectInput } from '..';
8
8
  import Alert, { AlertArrowPosition } from './Alert';
9
9
 
10
10
  export default {
@@ -109,23 +109,41 @@ export const WithTitle: Story = {
109
109
  * For ARIA live region to function correctly with screen readers,
110
110
  * the container with an appropriate ARIA role (in the case of this
111
111
  * component, it's `status` or `alert`) must be rendered first.
112
- * Once present in the accessibility tree, its dynamic contents
112
+ * Once present in the accessibility tree (AT), its dynamic contents
113
113
  * will be announced correctly.
114
114
  *
115
115
  * Because of that, using logical AND (&&) operator is discouraged
116
116
  * and, instead, engineers should toggle the `active` prop which
117
117
  * provides that logic internally.
118
+ *
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.
118
124
  */
119
125
  export const ConditionallyRendered: Story = {
120
126
  render: function Render(args) {
121
127
  const [isActive, setIsActive] = useState(false);
128
+ const [value, setValue] = useState<string>();
122
129
 
123
130
  return (
124
131
  <>
125
- <Button htmlType="button" onClick={() => setIsActive((value) => !value)}>
132
+ <Button htmlType="button" onClick={() => setIsActive((current) => !current)}>
126
133
  Trigger Alert
127
134
  </Button>
128
135
 
136
+ <Field label="Select `two` to triger Alert" className="m-t-3">
137
+ <SelectInput
138
+ items={[
139
+ { type: 'option', value: 'one' },
140
+ { type: 'option', value: 'two' },
141
+ ]}
142
+ onChange={setValue}
143
+ onClose={() => setIsActive(value === 'two')}
144
+ />
145
+ </Field>
146
+
129
147
  <Alert {...args} active={isActive} className="m-t-5" />
130
148
  </>
131
149
  );
@@ -134,18 +152,30 @@ export const ConditionallyRendered: Story = {
134
152
  docs: {
135
153
  source: {
136
154
  code: `
137
- function Render (args) {
155
+ function Render(args) {
138
156
  const [isActive, setIsActive] = useState(false);
157
+ const [value, setValue] = useState<string>();
139
158
 
140
159
  return (
141
160
  <>
142
- <Button htmlType="button" onClick={() => setIsActive(value => !value)}>
161
+ <Button htmlType="button" onClick={() => setIsActive((current) => !current)}>
143
162
  Trigger Alert
144
163
  </Button>
145
164
 
165
+ <Field label="Select 'two' to triger Alert" className="m-t-3">
166
+ <SelectInput
167
+ items={[
168
+ { type: 'option', value: 'one' },
169
+ { type: 'option', value: 'two' },
170
+ ]}
171
+ onChange={setValue}
172
+ onClose={() => setIsActive(value === 'two')}
173
+ />
174
+ </Field>
175
+
146
176
  <Alert {...args} active={isActive} className="m-t-5" />
147
177
  </>
148
- )
178
+ );
149
179
  }`,
150
180
  },
151
181
  },
@@ -2,8 +2,15 @@ import { clsx } from 'clsx';
2
2
  import { useState, useRef, useEffect } from 'react';
3
3
 
4
4
  import Body from '../body/Body';
5
- import { Sentiment, Size, Typography, Variant } from '../common';
6
- import { CloseButton } from '../common/closeButton';
5
+ import {
6
+ CloseButton,
7
+ Sentiment,
8
+ Size,
9
+ Typography,
10
+ Variant,
11
+ WDS_LIVE_REGION_DELAY_MS,
12
+ } from '../common';
13
+
7
14
  import StatusIcon from '../statusIcon';
8
15
  import Title from '../title/Title';
9
16
  import { logActionRequired } from '../utilities';
@@ -131,13 +138,22 @@ export default function Alert({
131
138
  }
132
139
  }, [resolvedType, type]);
133
140
 
134
- const [shouldFire, setShouldFire] = useState(false);
141
+ const [shouldFire, setShouldFire] = useState<boolean>();
142
+
143
+ const [shouldShow, setShouldShow] = useState<boolean>();
144
+ useEffect(() => {
145
+ if (shouldShow === undefined || !active) {
146
+ setShouldShow(active);
147
+ } else {
148
+ setTimeout(() => setShouldShow(active), WDS_LIVE_REGION_DELAY_MS);
149
+ }
150
+ }, [active, shouldShow]);
135
151
 
136
152
  const closeButtonReference = useRef<HTMLButtonElement>(null);
137
153
 
138
154
  return (
139
155
  <div role={resolvedType === Sentiment.NEGATIVE ? 'alert' : 'status'}>
140
- {active && (
156
+ {shouldShow && (
141
157
  <div
142
158
  className={clsx(
143
159
  'alert d-flex',
@@ -32,7 +32,7 @@ export type BottomSheetProps = PropsWithChildren<
32
32
  onClose?: (event: Event | SyntheticEvent) => void;
33
33
  open: boolean;
34
34
  } & CommonProps &
35
- Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby'>
35
+ Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby' | 'aria-label'>
36
36
  >;
37
37
 
38
38
  /**
@@ -185,6 +185,7 @@ const BottomSheet = ({ role = 'dialog', ...props }: BottomSheetProps) => {
185
185
  return is400Zoom ? (
186
186
  <Drawer
187
187
  aria-labelledby={props['aria-labelledby']}
188
+ aria-label={props['aria-label']}
188
189
  role={role}
189
190
  open={props.open}
190
191
  className={props.className}
@@ -203,7 +204,8 @@ const BottomSheet = ({ role = 'dialog', ...props }: BottomSheetProps) => {
203
204
  {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
204
205
  <div
205
206
  id={overlayId}
206
- aria-labelledby={props['aria-labelledby']}
207
+ aria-labelledby={props['aria-labelledby'] || undefined}
208
+ aria-label={props['aria-label'] || undefined}
207
209
  role={role}
208
210
  aria-modal
209
211
  onTouchStart={onSwipeStart}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This file holds repository-wide constants that are reusable by more than 1 component.
3
+ */
4
+
5
+ /**
6
+ * A delay [ms] after which it's OK to update a live region content,
7
+ * taking under consideration delayed programmatic refocusing
8
+ * of triggering components (e.g., SelectInput) and Accessibility
9
+ * Tree updates that prevent the screen reader announcements.
10
+ */
11
+ export const WDS_LIVE_REGION_DELAY_MS = 175;
@@ -25,3 +25,5 @@ export * from './locale';
25
25
  export * from './commonProps';
26
26
  export * from './initials';
27
27
  export * from './colors';
28
+ export * from './constants';
29
+ export { CloseButton } from './closeButton';
@@ -3,8 +3,7 @@ import { forwardRef } from 'react';
3
3
  import { Position } from '..';
4
4
  import BottomSheet from '../bottomSheet';
5
5
  import { useLayout } from '../hooks';
6
- import Panel from '../panel';
7
- import { PanelProps } from '../panel/Panel';
6
+ import Panel, { type PanelProps } from '../panel';
8
7
 
9
8
  const ResponsivePanel = forwardRef<HTMLDivElement, PanelProps>(function ResponsivePanel(
10
9
  {
@@ -17,13 +16,22 @@ const ResponsivePanel = forwardRef<HTMLDivElement, PanelProps>(function Responsi
17
16
  open = false,
18
17
  position = Position.BOTTOM,
19
18
  anchorWidth = false,
19
+ 'aria-label': ariaLabel,
20
+ 'aria-labelledby': ariaLabelledBy,
20
21
  }: PanelProps,
21
22
  reference,
22
23
  ) {
23
24
  const { isMobile } = useLayout();
24
25
  if (isMobile) {
25
26
  return (
26
- <BottomSheet key="bottomSheet" open={open} className={className} onClose={onClose}>
27
+ <BottomSheet
28
+ key="bottomSheet"
29
+ aria-label={ariaLabel}
30
+ aria-labelledby={ariaLabelledBy}
31
+ open={open}
32
+ className={className}
33
+ onClose={onClose}
34
+ >
27
35
  {children}
28
36
  </BottomSheet>
29
37
  );
@@ -38,6 +46,8 @@ const ResponsivePanel = forwardRef<HTMLDivElement, PanelProps>(function Responsi
38
46
  position={position}
39
47
  anchorWidth={anchorWidth}
40
48
  anchorRef={anchorRef}
49
+ aria-label={ariaLabel}
50
+ aria-labelledby={ariaLabelledBy}
41
51
  className={className}
42
52
  onClose={onClose}
43
53
  >
@@ -35,27 +35,70 @@ describe('Popover', () => {
35
35
  expect(getPanel()).toMatchSnapshot();
36
36
  });
37
37
 
38
- it('renders title', async () => {
39
- ({ container, rerender } = render(
40
- <Popover {...props}>
41
- <button type="button">Open</button>
42
- </Popover>,
43
- ));
44
-
45
- await userEvent.click(screen.getByText('Open'));
46
- await waitForPanel();
47
-
48
- expect(getTitle()).toBeInTheDocument();
49
-
50
- rerender(
51
- <Popover {...props} title={undefined}>
52
- <button type="button">Open</button>
53
- </Popover>,
54
- );
55
-
56
- await userEvent.click(screen.getByText('Open'));
57
-
58
- expect(getTitle()).not.toBeInTheDocument();
38
+ describe('title', () => {
39
+ it('renders title', async () => {
40
+ ({ container, rerender } = render(
41
+ <Popover {...props}>
42
+ <button type="button">Open</button>
43
+ </Popover>,
44
+ ));
45
+
46
+ await userEvent.click(screen.getByText('Open'));
47
+ await waitForPanel();
48
+
49
+ expect(getTitle()).toBeInTheDocument();
50
+
51
+ rerender(
52
+ <Popover {...props} title={undefined}>
53
+ <button type="button">Open</button>
54
+ </Popover>,
55
+ );
56
+
57
+ await userEvent.click(screen.getByText('Open'));
58
+
59
+ expect(getTitle()).not.toBeInTheDocument();
60
+ });
61
+
62
+ it('should uses `title` as the accessible name', async () => {
63
+ render(
64
+ <Popover {...props}>
65
+ <button type="button">Open</button>
66
+ </Popover>,
67
+ );
68
+
69
+ await userEvent.click(screen.getByText('Open'));
70
+ await waitForPanel();
71
+ });
72
+
73
+ describe('accessible name', () => {
74
+ const ACCESSIBLE_NAME = 'Accessible name';
75
+
76
+ it('should use `aria-label` as the accessible name', async () => {
77
+ render(
78
+ <Popover {...props} title={undefined} aria-label={ACCESSIBLE_NAME}>
79
+ <button type="button">Open</button>
80
+ </Popover>,
81
+ );
82
+
83
+ await userEvent.click(screen.getByText('Open'));
84
+ await waitForPanel();
85
+
86
+ expect(screen.getByRole('dialog', { name: ACCESSIBLE_NAME })).toBeInTheDocument();
87
+ });
88
+
89
+ it('should prioritise `aria-label` over `title` as the accessible name', async () => {
90
+ render(
91
+ <Popover {...props} aria-label={ACCESSIBLE_NAME}>
92
+ <button type="button">Open</button>
93
+ </Popover>,
94
+ );
95
+
96
+ await userEvent.click(screen.getByText('Open'));
97
+ await waitForPanel();
98
+
99
+ expect(screen.getByRole('dialog', { name: ACCESSIBLE_NAME })).toBeInTheDocument();
100
+ });
101
+ });
59
102
  });
60
103
 
61
104
  it('renders Panel onClick', async () => {