@transferwise/components 46.63.0 → 46.65.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 (93) hide show
  1. package/build/card/Card.js.map +1 -1
  2. package/build/card/Card.mjs.map +1 -1
  3. package/build/circularButton/CircularButton.js.map +1 -1
  4. package/build/circularButton/CircularButton.mjs.map +1 -1
  5. package/build/common/bottomSheet/BottomSheet.js +8 -2
  6. package/build/common/bottomSheet/BottomSheet.js.map +1 -1
  7. package/build/common/bottomSheet/BottomSheet.mjs +8 -2
  8. package/build/common/bottomSheet/BottomSheet.mjs.map +1 -1
  9. package/build/common/locale/index.js.map +1 -1
  10. package/build/common/locale/index.mjs.map +1 -1
  11. package/build/dateLookup/tableLink/TableLink.js.map +1 -1
  12. package/build/dateLookup/tableLink/TableLink.mjs.map +1 -1
  13. package/build/drawer/Drawer.js +5 -3
  14. package/build/drawer/Drawer.js.map +1 -1
  15. package/build/drawer/Drawer.mjs +5 -3
  16. package/build/drawer/Drawer.mjs.map +1 -1
  17. package/build/flowNavigation/FlowNavigation.js +1 -1
  18. package/build/flowNavigation/FlowNavigation.js.map +1 -1
  19. package/build/flowNavigation/FlowNavigation.mjs +1 -1
  20. package/build/flowNavigation/FlowNavigation.mjs.map +1 -1
  21. package/build/flowNavigation/animatedLabel/AnimatedLabel.js +89 -15
  22. package/build/flowNavigation/animatedLabel/AnimatedLabel.js.map +1 -1
  23. package/build/flowNavigation/animatedLabel/AnimatedLabel.mjs +90 -16
  24. package/build/flowNavigation/animatedLabel/AnimatedLabel.mjs.map +1 -1
  25. package/build/instructionsList/InstructionsList.js.map +1 -1
  26. package/build/instructionsList/InstructionsList.mjs.map +1 -1
  27. package/build/main.css +10 -1
  28. package/build/styles/flowNavigation/animatedLabel/AnimatedLabel.css +10 -1
  29. package/build/styles/main.css +10 -1
  30. package/build/switch/Switch.js +3 -27
  31. package/build/switch/Switch.js.map +1 -1
  32. package/build/switch/Switch.mjs +3 -27
  33. package/build/switch/Switch.mjs.map +1 -1
  34. package/build/types/card/Card.d.ts.map +1 -1
  35. package/build/types/circularButton/CircularButton.d.ts.map +1 -1
  36. package/build/types/common/bottomSheet/BottomSheet.d.ts +3 -3
  37. package/build/types/common/bottomSheet/BottomSheet.d.ts.map +1 -1
  38. package/build/types/drawer/Drawer.d.ts +4 -3
  39. package/build/types/drawer/Drawer.d.ts.map +1 -1
  40. package/build/types/flowNavigation/FlowNavigation.d.ts.map +1 -1
  41. package/build/types/flowNavigation/animatedLabel/AnimatedLabel.d.ts +3 -3
  42. package/build/types/flowNavigation/animatedLabel/AnimatedLabel.d.ts.map +1 -1
  43. package/build/types/instructionsList/InstructionsList.d.ts.map +1 -1
  44. package/build/types/switch/Switch.d.ts.map +1 -1
  45. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  46. package/build/types/uploadInput/uploadButton/UploadButton.d.ts +1 -1
  47. package/build/types/uploadInput/uploadButton/UploadButton.d.ts.map +1 -1
  48. package/build/types/uploadInput/uploadItem/UploadItem.d.ts +5 -1
  49. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  50. package/build/types/uploadInput/uploadItem/UploadItemLink.d.ts +5 -5
  51. package/build/types/uploadInput/uploadItem/UploadItemLink.d.ts.map +1 -1
  52. package/build/uploadInput/UploadInput.js +42 -11
  53. package/build/uploadInput/UploadInput.js.map +1 -1
  54. package/build/uploadInput/UploadInput.mjs +43 -12
  55. package/build/uploadInput/UploadInput.mjs.map +1 -1
  56. package/build/uploadInput/uploadButton/UploadButton.js +14 -7
  57. package/build/uploadInput/uploadButton/UploadButton.js.map +1 -1
  58. package/build/uploadInput/uploadButton/UploadButton.mjs +15 -8
  59. package/build/uploadInput/uploadButton/UploadButton.mjs.map +1 -1
  60. package/build/uploadInput/uploadItem/UploadItem.js +18 -3
  61. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  62. package/build/uploadInput/uploadItem/UploadItem.mjs +18 -3
  63. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  64. package/build/uploadInput/uploadItem/UploadItemLink.js +6 -3
  65. package/build/uploadInput/uploadItem/UploadItemLink.js.map +1 -1
  66. package/build/uploadInput/uploadItem/UploadItemLink.mjs +6 -3
  67. package/build/uploadInput/uploadItem/UploadItemLink.mjs.map +1 -1
  68. package/package.json +3 -3
  69. package/src/card/Card.spec.tsx +4 -5
  70. package/src/card/Card.story.tsx +4 -6
  71. package/src/card/Card.tsx +3 -2
  72. package/src/circularButton/CircularButton.tsx +1 -1
  73. package/src/common/bottomSheet/BottomSheet.tsx +13 -4
  74. package/src/common/locale/index.ts +1 -1
  75. package/src/dateLookup/tableLink/TableLink.tsx +15 -15
  76. package/src/drawer/Drawer.tsx +7 -5
  77. package/src/flowNavigation/FlowNavigation.story.js +69 -17
  78. package/src/flowNavigation/FlowNavigation.tsx +1 -5
  79. package/src/flowNavigation/animatedLabel/AnimatedLabel.css +10 -1
  80. package/src/flowNavigation/animatedLabel/AnimatedLabel.less +10 -1
  81. package/src/flowNavigation/animatedLabel/AnimatedLabel.spec.js +64 -27
  82. package/src/flowNavigation/animatedLabel/AnimatedLabel.tsx +102 -20
  83. package/src/instructionsList/InstructionsList.tsx +1 -4
  84. package/src/main.css +10 -1
  85. package/src/switch/Switch.story.tsx +4 -7
  86. package/src/switch/Switch.tsx +1 -24
  87. package/src/switch/__snapshots__/Switch.spec.tsx.snap +2 -44
  88. package/src/uploadInput/UploadInput.tests.story.tsx +7 -3
  89. package/src/uploadInput/UploadInput.tsx +50 -8
  90. package/src/uploadInput/uploadButton/UploadButton.tsx +163 -141
  91. package/src/uploadInput/uploadItem/UploadItem.tsx +146 -124
  92. package/src/uploadInput/uploadItem/UploadItemLink.tsx +23 -25
  93. package/src/flowNavigation/animatedLabel/__snapshots__/AnimatedLabel.spec.js.snap +0 -25
@@ -1 +1 @@
1
- {"version":3,"file":"UploadItem.mjs","sources":["../../../src/uploadInput/uploadItem/UploadItem.tsx"],"sourcesContent":["import { Bin, CheckCircleFill, CrossCircleFill } from '@transferwise/icons';\nimport { clsx } from 'clsx';\nimport { useIntl } from 'react-intl';\n\nimport Body from '../../body';\nimport { Size, Status, Typography, Sentiment } from '../../common';\nimport ProcessIndicator from '../../processIndicator/ProcessIndicator';\nimport StatusIcon from '../../statusIcon/StatusIcon';\nimport { UploadedFile, UploadError } from '../types';\n\nimport MESSAGES from './UploadItem.messages';\nimport { UploadItemLink } from './UploadItemLink';\n\nexport type UploadItemProps = React.JSX.IntrinsicAttributes & {\n file: UploadedFile;\n /**\n * Is this Item part of a multiple- or single-file UploadInput\n */\n singleFileUpload: boolean;\n canDelete: boolean;\n onDelete: () => void;\n\n /**\n * Callback to be called when the file link is clicked.\n * When provided, you need to manually trigger actions to load/download the file.\n *\n * @param file\n */\n onDownload?: (file: UploadedFile) => void;\n};\n\nexport enum TEST_IDS {\n uploadItem = 'uploadItem',\n mediaBody = 'mediaBody',\n}\n\nconst UploadItem = ({\n file,\n canDelete,\n onDelete,\n onDownload,\n singleFileUpload,\n}: UploadItemProps) => {\n const { formatMessage } = useIntl();\n const { status, filename, error, errors, url } = file;\n\n const isSucceeded = [Status.SUCCEEDED, undefined].includes(status) && !!url;\n\n /**\n * We're temporarily reverting to the regular icon components,\n * until the StatusIcon receives 24px sizing. Some misalignment\n * to be expected.\n */\n const getIcon = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return <CrossCircleFill size={24} className=\"emphasis--negative\" />;\n }\n\n let processIndicator: React.ReactNode;\n\n switch (status) {\n case Status.PROCESSING:\n case Status.PENDING:\n processIndicator = <ProcessIndicator size={Size.EXTRA_SMALL} status={Status.PROCESSING} />;\n break;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n processIndicator = <CheckCircleFill size={24} className=\"emphasis--positive\" />;\n }\n\n return processIndicator;\n };\n\n const getErrorMessage = (error?: UploadError) =>\n typeof error === 'object' ? error.message : error || formatMessage(MESSAGES.uploadingFailed);\n\n const getMultipleErrors = (errors?: UploadError[]) => {\n if (!errors?.length) {\n return null;\n }\n\n if (errors?.length === 1) {\n return getErrorMessage(errors[0]);\n }\n\n return (\n <ul className=\"np-upload-input-errors m-b-0\">\n {errors.map((error, index) => {\n // eslint-disable-next-line react/no-array-index-key\n return <li key={index}>{getErrorMessage(error)}</li>;\n })}\n </ul>\n );\n };\n\n const getDescription = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"text-negative\">\n {errors?.length ? getMultipleErrors(errors) : getErrorMessage(error)}\n </Body>\n );\n }\n\n switch (status) {\n case Status.PENDING:\n return <Body type={Typography.BODY_DEFAULT_BOLD}>{formatMessage(MESSAGES.uploading)}</Body>;\n case Status.PROCESSING:\n return <Body>{formatMessage(MESSAGES.deleting)}</Body>;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"text-positive\">\n {formatMessage(MESSAGES.uploaded)}\n </Body>\n );\n }\n };\n\n const getTitle = () => {\n return filename || formatMessage(MESSAGES.uploadedFile);\n };\n\n const onDownloadFile = (event: React.MouseEvent): void => {\n if (onDownload) {\n event.preventDefault();\n onDownload(file);\n }\n };\n\n return (\n <div\n className={clsx('np-upload-item', { 'np-upload-item--link': isSucceeded })}\n data-testid={TEST_IDS.uploadItem}\n >\n <div className=\"np-upload-item__body\">\n <UploadItemLink\n url={isSucceeded ? url : undefined}\n singleFileUpload={singleFileUpload}\n onDownload={onDownloadFile}\n >\n <div className=\"np-upload-button\" aria-live=\"polite\">\n <div className=\"media\">\n <div className=\"np-upload-icon media-left\">{getIcon()}</div>\n <div className=\"media-body text-xs-left\" data-testid={TEST_IDS.mediaBody}>\n <Body className=\"text-word-break d-block text-primary\">{getTitle()}</Body>\n {getDescription()}\n </div>\n </div>\n </div>\n </UploadItemLink>\n {canDelete && (\n <button\n aria-label={formatMessage(MESSAGES.removeFile, { filename })}\n className={clsx('btn', 'np-upload-item__remove-button', 'media-left', {\n 'np-upload-item--single-file': singleFileUpload,\n })}\n type=\"button\"\n onClick={() => onDelete()}\n >\n <Bin size={16} />\n </button>\n )}\n </div>\n </div>\n );\n};\n\nexport default UploadItem;\n"],"names":["TEST_IDS","UploadItem","file","canDelete","onDelete","onDownload","singleFileUpload","formatMessage","useIntl","status","filename","error","errors","url","isSucceeded","Status","SUCCEEDED","undefined","includes","getIcon","length","FAILED","_jsx","CrossCircleFill","size","className","processIndicator","PROCESSING","PENDING","ProcessIndicator","Size","EXTRA_SMALL","DONE","CheckCircleFill","getErrorMessage","message","MESSAGES","uploadingFailed","getMultipleErrors","children","map","index","getDescription","Body","type","Typography","BODY_DEFAULT_BOLD","uploading","deleting","uploaded","getTitle","uploadedFile","onDownloadFile","event","preventDefault","clsx","uploadItem","_jsxs","UploadItemLink","mediaBody","removeFile","onClick","Bin"],"mappings":"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"}
1
+ {"version":3,"file":"UploadItem.mjs","sources":["../../../src/uploadInput/uploadItem/UploadItem.tsx"],"sourcesContent":["import { Bin, CheckCircleFill, CrossCircleFill } from '@transferwise/icons';\nimport { clsx } from 'clsx';\nimport { forwardRef, useImperativeHandle, useRef } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Body from '../../body';\nimport { Size, Status, Typography, Sentiment } from '../../common';\nimport ProcessIndicator from '../../processIndicator/ProcessIndicator';\nimport StatusIcon from '../../statusIcon/StatusIcon';\nimport { UploadedFile, UploadError } from '../types';\n\nimport MESSAGES from './UploadItem.messages';\nimport { UploadItemLink } from './UploadItemLink';\n\nexport type UploadItemProps = React.JSX.IntrinsicAttributes & {\n file: UploadedFile;\n /**\n * Is this Item part of a multiple- or single-file UploadInput\n */\n singleFileUpload: boolean;\n canDelete: boolean;\n onDelete: () => void;\n\n /**\n * Callback to be called when the file link is clicked.\n * When provided, you need to manually trigger actions to load/download the file.\n *\n * @param file\n */\n onDownload?: (file: UploadedFile) => void;\n ref?: React.Ref<UploadItemRef>;\n};\n\ninterface UploadItemRef {\n focus: () => void;\n}\n\nexport enum TEST_IDS {\n uploadItem = 'uploadItem',\n mediaBody = 'mediaBody',\n}\n\nconst UploadItem = forwardRef<UploadItemRef, UploadItemProps>(\n ({ file, canDelete, onDelete, onDownload, singleFileUpload }, ref) => {\n const { formatMessage } = useIntl();\n const { status, filename, error, errors, url } = file;\n const linkRef = useRef<HTMLAnchorElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n useImperativeHandle<UploadItemRef, UploadItemRef>(ref, () => ({\n focus: (): void => {\n if (url) {\n linkRef.current?.focus();\n } else {\n buttonRef.current?.focus();\n }\n },\n }));\n\n const isSucceeded = [Status.SUCCEEDED, undefined].includes(status) && !!url;\n\n /**\n * We're temporarily reverting to the regular icon components,\n * until the StatusIcon receives 24px sizing. Some misalignment\n * to be expected.\n */\n const getIcon = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return <CrossCircleFill size={24} className=\"emphasis--negative\" />;\n }\n\n let processIndicator: React.ReactNode;\n\n switch (status) {\n case Status.PROCESSING:\n case Status.PENDING:\n processIndicator = (\n <ProcessIndicator size={Size.EXTRA_SMALL} status={Status.PROCESSING} />\n );\n break;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n processIndicator = <CheckCircleFill size={24} className=\"emphasis--positive\" />;\n }\n\n return processIndicator;\n };\n\n const getErrorMessage = (error?: UploadError) =>\n typeof error === 'object' ? error.message : error || formatMessage(MESSAGES.uploadingFailed);\n\n const getMultipleErrors = (errors?: UploadError[]) => {\n if (!errors?.length) {\n return null;\n }\n\n if (errors?.length === 1) {\n return getErrorMessage(errors[0]);\n }\n\n return (\n <ul className=\"np-upload-input-errors m-b-0\">\n {errors.map((error, index) => {\n // eslint-disable-next-line react/no-array-index-key\n return <li key={index}>{getErrorMessage(error)}</li>;\n })}\n </ul>\n );\n };\n\n const getDescription = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"text-negative\">\n {errors?.length ? getMultipleErrors(errors) : getErrorMessage(error)}\n </Body>\n );\n }\n\n switch (status) {\n case Status.PENDING:\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD}>{formatMessage(MESSAGES.uploading)}</Body>\n );\n case Status.PROCESSING:\n return <Body>{formatMessage(MESSAGES.deleting)}</Body>;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"text-positive\">\n {formatMessage(MESSAGES.uploaded)}\n </Body>\n );\n }\n };\n\n const getTitle = () => {\n return filename || formatMessage(MESSAGES.uploadedFile);\n };\n\n const onDownloadFile = (event: React.MouseEvent): void => {\n if (onDownload) {\n event.preventDefault();\n onDownload(file);\n }\n };\n\n return (\n <div\n className={clsx('np-upload-item', { 'np-upload-item--link': isSucceeded })}\n data-testid={TEST_IDS.uploadItem}\n >\n <div className=\"np-upload-item__body\">\n <UploadItemLink\n ref={linkRef}\n url={isSucceeded ? url : undefined}\n singleFileUpload={singleFileUpload}\n onDownload={onDownloadFile}\n >\n <div className=\"np-upload-button\" aria-live=\"polite\">\n <div className=\"media\">\n <div className=\"np-upload-icon media-left\">{getIcon()}</div>\n <div className=\"media-body text-xs-left\" data-testid={TEST_IDS.mediaBody}>\n <Body className=\"text-word-break d-block text-primary\">{getTitle()}</Body>\n {getDescription()}\n </div>\n </div>\n </div>\n </UploadItemLink>\n {canDelete && (\n <button\n ref={buttonRef}\n aria-label={formatMessage(MESSAGES.removeFile, { filename })}\n className={clsx('btn', 'np-upload-item__remove-button', 'media-left', {\n 'np-upload-item--single-file': singleFileUpload,\n })}\n type=\"button\"\n onClick={() => onDelete()}\n >\n <Bin size={16} />\n </button>\n )}\n </div>\n </div>\n );\n },\n);\n\nUploadItem.displayName = 'UploadItem';\n\nexport default UploadItem;\n"],"names":["TEST_IDS","UploadItem","forwardRef","file","canDelete","onDelete","onDownload","singleFileUpload","ref","formatMessage","useIntl","status","filename","error","errors","url","linkRef","useRef","buttonRef","useImperativeHandle","focus","current","isSucceeded","Status","SUCCEEDED","undefined","includes","getIcon","length","FAILED","_jsx","CrossCircleFill","size","className","processIndicator","PROCESSING","PENDING","ProcessIndicator","Size","EXTRA_SMALL","DONE","CheckCircleFill","getErrorMessage","message","MESSAGES","uploadingFailed","getMultipleErrors","children","map","index","getDescription","Body","type","Typography","BODY_DEFAULT_BOLD","uploading","deleting","uploaded","getTitle","uploadedFile","onDownloadFile","event","preventDefault","clsx","uploadItem","_jsxs","UploadItemLink","mediaBody","removeFile","onClick","Bin","displayName"],"mappings":"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"}
@@ -1,20 +1,23 @@
1
1
  'use strict';
2
2
 
3
+ var React = require('react');
3
4
  var clsx = require('clsx');
4
5
  var jsxRuntime = require('react/jsx-runtime');
5
6
 
6
- const UploadItemLink = ({
7
+ const UploadItemLink = /*#__PURE__*/React.forwardRef(({
7
8
  children,
8
9
  url,
9
10
  onDownload,
10
11
  singleFileUpload
11
- }) => {
12
+ }, ref) => {
12
13
  if (!url) {
13
14
  return /*#__PURE__*/jsxRuntime.jsx("div", {
15
+ ref: ref,
14
16
  children: children
15
17
  });
16
18
  }
17
19
  return /*#__PURE__*/jsxRuntime.jsx("a", {
20
+ ref: ref,
18
21
  href: url,
19
22
  target: "_blank",
20
23
  rel: "noopener noreferrer",
@@ -22,7 +25,7 @@ const UploadItemLink = ({
22
25
  onClick: onDownload,
23
26
  children: children
24
27
  });
25
- };
28
+ });
26
29
 
27
30
  exports.UploadItemLink = UploadItemLink;
28
31
  //# sourceMappingURL=UploadItemLink.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UploadItemLink.js","sources":["../../../src/uploadInput/uploadItem/UploadItemLink.tsx"],"sourcesContent":["import { PropsWithChildren, MouseEvent } from 'react';\nimport { clsx } from 'clsx';\n\ntype UploadItemLinkProps = PropsWithChildren<{\n url?: string;\n onDownload?: (event: MouseEvent) => void;\n singleFileUpload: boolean;\n}>;\n\nexport const UploadItemLink = ({\n children,\n url,\n onDownload,\n singleFileUpload,\n}: UploadItemLinkProps) => {\n if (!url) {\n return <div>{children}</div>;\n }\n\n return (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(\n 'np-upload-item__link',\n singleFileUpload ? 'np-upload-item--single-file' : '',\n )}\n onClick={onDownload}\n >\n {children}\n </a>\n );\n};\n"],"names":["UploadItemLink","children","url","onDownload","singleFileUpload","_jsx","href","target","rel","className","clsx","onClick"],"mappings":";;;;;AASO,MAAMA,cAAc,GAAGA,CAAC;EAC7BC,QAAQ;EACRC,GAAG;EACHC,UAAU;AACVC,EAAAA,gBAAAA;AAAgB,CACI,KAAI;EACxB,IAAI,CAACF,GAAG,EAAE;AACR,IAAA,oBAAOG,cAAA,CAAA,KAAA,EAAA;AAAAJ,MAAAA,QAAA,EAAMA,QAAAA;AAAQ,KAAM,CAAC,CAAA;AAC9B,GAAA;AAEA,EAAA,oBACEI,cAAA,CAAA,GAAA,EAAA;AACEC,IAAAA,IAAI,EAAEJ,GAAI;AACVK,IAAAA,MAAM,EAAC,QAAQ;AACfC,IAAAA,GAAG,EAAC,qBAAqB;IACzBC,SAAS,EAAEC,SAAI,CACb,sBAAsB,EACtBN,gBAAgB,GAAG,6BAA6B,GAAG,EAAE,CACrD;AACFO,IAAAA,OAAO,EAAER,UAAW;AAAAF,IAAAA,QAAA,EAEnBA,QAAAA;AAAQ,GACR,CAAC,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"UploadItemLink.js","sources":["../../../src/uploadInput/uploadItem/UploadItemLink.tsx"],"sourcesContent":["import { PropsWithChildren, MouseEvent, forwardRef } from 'react';\nimport { clsx } from 'clsx';\n\ntype UploadItemLinkProps = PropsWithChildren<{\n url?: string;\n onDownload?: (event: MouseEvent) => void;\n singleFileUpload: boolean;\n}>;\n\nexport const UploadItemLink = forwardRef<HTMLAnchorElement | HTMLDivElement, UploadItemLinkProps>(\n ({ children, url, onDownload, singleFileUpload }, ref) => {\n if (!url) {\n return <div ref={ref as React.RefObject<HTMLDivElement>}>{children}</div>;\n }\n\n return (\n <a\n ref={ref as React.RefObject<HTMLAnchorElement>}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(\n 'np-upload-item__link',\n singleFileUpload ? 'np-upload-item--single-file' : '',\n )}\n onClick={onDownload}\n >\n {children}\n </a>\n );\n },\n);\n"],"names":["UploadItemLink","forwardRef","children","url","onDownload","singleFileUpload","ref","_jsx","href","target","rel","className","clsx","onClick"],"mappings":";;;;;;AASaA,MAAAA,cAAc,gBAAGC,gBAAU,CACtC,CAAC;EAAEC,QAAQ;EAAEC,GAAG;EAAEC,UAAU;AAAEC,EAAAA,gBAAAA;CAAkB,EAAEC,GAAG,KAAI;EACvD,IAAI,CAACH,GAAG,EAAE;AACR,IAAA,oBAAOI,cAAA,CAAA,KAAA,EAAA;AAAKD,MAAAA,GAAG,EAAEA,GAAuC;AAAAJ,MAAAA,QAAA,EAAEA,QAAAA;AAAQ,KAAM,CAAC,CAAA;AAC3E,GAAA;AAEA,EAAA,oBACEK,cAAA,CAAA,GAAA,EAAA;AACED,IAAAA,GAAG,EAAEA,GAA0C;AAC/CE,IAAAA,IAAI,EAAEL,GAAI;AACVM,IAAAA,MAAM,EAAC,QAAQ;AACfC,IAAAA,GAAG,EAAC,qBAAqB;IACzBC,SAAS,EAAEC,SAAI,CACb,sBAAsB,EACtBP,gBAAgB,GAAG,6BAA6B,GAAG,EAAE,CACrD;AACFQ,IAAAA,OAAO,EAAET,UAAW;AAAAF,IAAAA,QAAA,EAEnBA,QAAAA;AAAQ,GACR,CAAC,CAAA;AAER,CAAC;;;;"}
@@ -1,18 +1,21 @@
1
+ import { forwardRef } from 'react';
1
2
  import { clsx } from 'clsx';
2
3
  import { jsx } from 'react/jsx-runtime';
3
4
 
4
- const UploadItemLink = ({
5
+ const UploadItemLink = /*#__PURE__*/forwardRef(({
5
6
  children,
6
7
  url,
7
8
  onDownload,
8
9
  singleFileUpload
9
- }) => {
10
+ }, ref) => {
10
11
  if (!url) {
11
12
  return /*#__PURE__*/jsx("div", {
13
+ ref: ref,
12
14
  children: children
13
15
  });
14
16
  }
15
17
  return /*#__PURE__*/jsx("a", {
18
+ ref: ref,
16
19
  href: url,
17
20
  target: "_blank",
18
21
  rel: "noopener noreferrer",
@@ -20,7 +23,7 @@ const UploadItemLink = ({
20
23
  onClick: onDownload,
21
24
  children: children
22
25
  });
23
- };
26
+ });
24
27
 
25
28
  export { UploadItemLink };
26
29
  //# sourceMappingURL=UploadItemLink.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"UploadItemLink.mjs","sources":["../../../src/uploadInput/uploadItem/UploadItemLink.tsx"],"sourcesContent":["import { PropsWithChildren, MouseEvent } from 'react';\nimport { clsx } from 'clsx';\n\ntype UploadItemLinkProps = PropsWithChildren<{\n url?: string;\n onDownload?: (event: MouseEvent) => void;\n singleFileUpload: boolean;\n}>;\n\nexport const UploadItemLink = ({\n children,\n url,\n onDownload,\n singleFileUpload,\n}: UploadItemLinkProps) => {\n if (!url) {\n return <div>{children}</div>;\n }\n\n return (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(\n 'np-upload-item__link',\n singleFileUpload ? 'np-upload-item--single-file' : '',\n )}\n onClick={onDownload}\n >\n {children}\n </a>\n );\n};\n"],"names":["UploadItemLink","children","url","onDownload","singleFileUpload","_jsx","href","target","rel","className","clsx","onClick"],"mappings":";;;AASO,MAAMA,cAAc,GAAGA,CAAC;EAC7BC,QAAQ;EACRC,GAAG;EACHC,UAAU;AACVC,EAAAA,gBAAAA;AAAgB,CACI,KAAI;EACxB,IAAI,CAACF,GAAG,EAAE;AACR,IAAA,oBAAOG,GAAA,CAAA,KAAA,EAAA;AAAAJ,MAAAA,QAAA,EAAMA,QAAAA;AAAQ,KAAM,CAAC,CAAA;AAC9B,GAAA;AAEA,EAAA,oBACEI,GAAA,CAAA,GAAA,EAAA;AACEC,IAAAA,IAAI,EAAEJ,GAAI;AACVK,IAAAA,MAAM,EAAC,QAAQ;AACfC,IAAAA,GAAG,EAAC,qBAAqB;IACzBC,SAAS,EAAEC,IAAI,CACb,sBAAsB,EACtBN,gBAAgB,GAAG,6BAA6B,GAAG,EAAE,CACrD;AACFO,IAAAA,OAAO,EAAER,UAAW;AAAAF,IAAAA,QAAA,EAEnBA,QAAAA;AAAQ,GACR,CAAC,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"UploadItemLink.mjs","sources":["../../../src/uploadInput/uploadItem/UploadItemLink.tsx"],"sourcesContent":["import { PropsWithChildren, MouseEvent, forwardRef } from 'react';\nimport { clsx } from 'clsx';\n\ntype UploadItemLinkProps = PropsWithChildren<{\n url?: string;\n onDownload?: (event: MouseEvent) => void;\n singleFileUpload: boolean;\n}>;\n\nexport const UploadItemLink = forwardRef<HTMLAnchorElement | HTMLDivElement, UploadItemLinkProps>(\n ({ children, url, onDownload, singleFileUpload }, ref) => {\n if (!url) {\n return <div ref={ref as React.RefObject<HTMLDivElement>}>{children}</div>;\n }\n\n return (\n <a\n ref={ref as React.RefObject<HTMLAnchorElement>}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={clsx(\n 'np-upload-item__link',\n singleFileUpload ? 'np-upload-item--single-file' : '',\n )}\n onClick={onDownload}\n >\n {children}\n </a>\n );\n },\n);\n"],"names":["UploadItemLink","forwardRef","children","url","onDownload","singleFileUpload","ref","_jsx","href","target","rel","className","clsx","onClick"],"mappings":";;;;AASaA,MAAAA,cAAc,gBAAGC,UAAU,CACtC,CAAC;EAAEC,QAAQ;EAAEC,GAAG;EAAEC,UAAU;AAAEC,EAAAA,gBAAAA;CAAkB,EAAEC,GAAG,KAAI;EACvD,IAAI,CAACH,GAAG,EAAE;AACR,IAAA,oBAAOI,GAAA,CAAA,KAAA,EAAA;AAAKD,MAAAA,GAAG,EAAEA,GAAuC;AAAAJ,MAAAA,QAAA,EAAEA,QAAAA;AAAQ,KAAM,CAAC,CAAA;AAC3E,GAAA;AAEA,EAAA,oBACEK,GAAA,CAAA,GAAA,EAAA;AACED,IAAAA,GAAG,EAAEA,GAA0C;AAC/CE,IAAAA,IAAI,EAAEL,GAAI;AACVM,IAAAA,MAAM,EAAC,QAAQ;AACfC,IAAAA,GAAG,EAAC,qBAAqB;IACzBC,SAAS,EAAEC,IAAI,CACb,sBAAsB,EACtBP,gBAAgB,GAAG,6BAA6B,GAAG,EAAE,CACrD;AACFQ,IAAAA,OAAO,EAAET,UAAW;AAAAF,IAAAA,QAAA,EAEnBA,QAAAA;AAAQ,GACR,CAAC,CAAA;AAER,CAAC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "46.63.0",
3
+ "version": "46.65.0",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -93,8 +93,8 @@
93
93
  "rollup-preserve-directives": "^1.1.1",
94
94
  "storybook": "^8.2.2",
95
95
  "@transferwise/less-config": "3.1.0",
96
- "@transferwise/neptune-css": "14.15.0",
97
- "@wise/components-theming": "1.6.0"
96
+ "@wise/components-theming": "1.6.0",
97
+ "@transferwise/neptune-css": "14.15.0"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "@transferwise/icons": "^3.7.0",
@@ -104,7 +104,6 @@ describe('Card', () => {
104
104
  expect(screen.getByTestId('chevron-up-icon')).toHaveClass(Position.BOTTOM);
105
105
  });
106
106
 
107
-
108
107
  describe('when collapsed', () => {
109
108
  const CONTENT = 'mock children';
110
109
 
@@ -116,8 +115,8 @@ describe('Card', () => {
116
115
  it('should render appropriate aria attributes', async () => {
117
116
  renderCard({ children: CONTENT });
118
117
  const button = screen.getByRole('button');
119
- expect(button).toHaveAttribute('aria-expanded', 'false')
120
- expect(button).not.toHaveAttribute('aria-controls')
118
+ expect(button).toHaveAttribute('aria-expanded', 'false');
119
+ expect(button).not.toHaveAttribute('aria-controls');
121
120
  });
122
121
  });
123
122
 
@@ -140,10 +139,10 @@ describe('Card', () => {
140
139
  });
141
140
 
142
141
  it('should render appropriate aria attributes', async () => {
143
- const {container} = renderCard(defaultProps);
142
+ const { container } = renderCard(defaultProps);
144
143
  const button = screen.getByRole('button');
145
144
  const controlledId = button.getAttribute('aria-controls');
146
- expect(button).toHaveAttribute('aria-expanded', 'true')
145
+ expect(button).toHaveAttribute('aria-expanded', 'true');
147
146
 
148
147
  const contentId = screen.getByText(defaultProps.children).getAttribute('id');
149
148
  expect(contentId).toBe(controlledId);
@@ -20,21 +20,19 @@ export default {
20
20
  tags: ['autodocs'],
21
21
  } satisfies Meta<typeof Card>;
22
22
 
23
-
24
23
  export const Basic: Story = {
25
24
  render: function Render(args) {
26
25
  const [isExpanded, setIsExpanded] = useState(false);
27
26
 
28
27
  const handleClick = (isCurrentExpanded: boolean) => {
29
- setIsExpanded(isCurrentExpanded)
28
+ setIsExpanded(isCurrentExpanded);
30
29
  args?.onClick?.(!isExpanded);
31
- }
30
+ };
32
31
 
33
32
  return <Card {...args} isExpanded={isExpanded} onClick={handleClick} />;
34
- }
33
+ },
35
34
  };
36
35
 
37
-
38
36
  export const Multiple: Story = {
39
37
  render: function Render(args) {
40
38
  const [expandedCardIndex, setExpandedCardIndex] = useState<number | null>(0);
@@ -66,5 +64,5 @@ export const Multiple: Story = {
66
64
  />
67
65
  </>
68
66
  );
69
- }
67
+ },
70
68
  };
package/src/card/Card.tsx CHANGED
@@ -44,7 +44,6 @@ const Card = forwardRef(function Card(
44
44
  const contentId = useId();
45
45
  const isExpandable = Boolean(children);
46
46
 
47
-
48
47
  return (
49
48
  <Element
50
49
  ref={reference}
@@ -68,7 +67,9 @@ const Card = forwardRef(function Card(
68
67
  content={details}
69
68
  showMediaAtAllSizes
70
69
  button={
71
- isExpandable ? <Chevron orientation={isExpanded ? Position.TOP : Position.BOTTOM} /> : null
70
+ isExpandable ? (
71
+ <Chevron orientation={isExpanded ? Position.TOP : Position.BOTTOM} />
72
+ ) : null
72
73
  }
73
74
  onClick={isExpandable ? () => onClick?.(!isExpanded) : undefined}
74
75
  />
@@ -3,7 +3,7 @@ import { cloneElement } from 'react';
3
3
 
4
4
  import Body from '../body/Body';
5
5
  import { typeClassMap, priorityClassMap } from '../button/classMap';
6
- import { ControlType, Priority , Typography } from '../common';
6
+ import { ControlType, Priority, Typography } from '../common';
7
7
 
8
8
  export interface CircularButtonProps {
9
9
  className?: string;
@@ -1,6 +1,7 @@
1
1
  import { clsx } from 'clsx';
2
2
  import {
3
3
  CSSProperties,
4
+ HTMLAttributes,
4
5
  PropsWithChildren,
5
6
  SyntheticEvent,
6
7
  useContext,
@@ -30,7 +31,8 @@ export type BottomSheetProps = PropsWithChildren<
30
31
  {
31
32
  onClose?: (event: Event | SyntheticEvent) => void;
32
33
  open: boolean;
33
- } & CommonProps
34
+ } & CommonProps &
35
+ Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby'>
34
36
  >;
35
37
 
36
38
  /**
@@ -39,7 +41,7 @@ export type BottomSheetProps = PropsWithChildren<
39
41
  * Neptune Web: https://transferwise.github.io/neptune-web/components/overlays/BottomSheet
40
42
  *
41
43
  */
42
- const BottomSheet = (props: BottomSheetProps) => {
44
+ const BottomSheet = ({ role = 'dialog', ...props }: BottomSheetProps) => {
43
45
  const bottomSheetReference = useRef<HTMLDivElement>(null);
44
46
  const topBarReference = useRef<HTMLDivElement>(null);
45
47
  const contentReference = useRef<HTMLDivElement>(null);
@@ -181,7 +183,13 @@ const BottomSheet = (props: BottomSheetProps) => {
181
183
  const overlayId = useContext(OverlayIdContext);
182
184
 
183
185
  return is400Zoom ? (
184
- <Drawer open={props.open} className={props.className} onClose={close}>
186
+ <Drawer
187
+ aria-labelledby={props['aria-labelledby']}
188
+ role={role}
189
+ open={props.open}
190
+ className={props.className}
191
+ onClose={close}
192
+ >
185
193
  {props.children}
186
194
  </Drawer>
187
195
  ) : (
@@ -195,7 +203,8 @@ const BottomSheet = (props: BottomSheetProps) => {
195
203
  {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
196
204
  <div
197
205
  id={overlayId}
198
- role="dialog"
206
+ aria-labelledby={props['aria-labelledby']}
207
+ role={role}
199
208
  aria-modal
200
209
  onTouchStart={onSwipeStart}
201
210
  onTouchMove={onSwipeMove}
@@ -79,7 +79,7 @@ export function getLangFromLocale(locale: string) {
79
79
  */
80
80
  export function getCountryFromLocale(locale: string) {
81
81
  const adjustedLocale = adjustLocale(locale);
82
- return adjustedLocale != null ? new Intl.Locale(adjustedLocale).region ?? null : null;
82
+ return adjustedLocale != null ? (new Intl.Locale(adjustedLocale).region ?? null) : null;
83
83
  }
84
84
 
85
85
  /**
@@ -56,21 +56,21 @@ const TableLink = ({
56
56
 
57
57
  return (
58
58
  <button
59
- ref={buttonRef}
60
- type="button"
61
- className={clsx(
62
- `tw-date-lookup-${type}-option np-text-body-default-bold`,
63
- { active: !!active },
64
- { today: !!today },
65
- )}
66
- disabled={disabled}
67
- tabIndex={autofocus ? 0 : -1}
68
- aria-label={calculateAriaLabel()}
69
- aria-pressed={active}
70
- onClick={onCalendarClick}
71
- >
72
- {title || item}
73
- </button>
59
+ ref={buttonRef}
60
+ type="button"
61
+ className={clsx(
62
+ `tw-date-lookup-${type}-option np-text-body-default-bold`,
63
+ { active: !!active },
64
+ { today: !!today },
65
+ )}
66
+ disabled={disabled}
67
+ tabIndex={autofocus ? 0 : -1}
68
+ aria-label={calculateAriaLabel()}
69
+ aria-pressed={active}
70
+ onClick={onCalendarClick}
71
+ >
72
+ {title || item}
73
+ </button>
74
74
  );
75
75
  };
76
76
 
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx';
2
- import { useContext, useId } from 'react';
2
+ import { HTMLAttributes, useContext, useId } from 'react';
3
3
 
4
4
  import { Position, Typography } from '../common';
5
5
  import { CloseButton } from '../common/closeButton';
@@ -10,7 +10,7 @@ import SlidingPanel from '../slidingPanel';
10
10
  import Title from '../title';
11
11
  import { logActionRequiredIf } from '../utilities';
12
12
 
13
- export interface DrawerProps {
13
+ export type DrawerProps = {
14
14
  /** The content to appear in the drawer body. */
15
15
  children?: React.ReactNode;
16
16
  className?: string;
@@ -24,7 +24,7 @@ export interface DrawerProps {
24
24
  position?: `${Position.LEFT | Position.RIGHT | Position.BOTTOM}`;
25
25
  /** The action to perform on close click. */
26
26
  onClose?: (event: KeyboardEvent | React.MouseEvent) => void;
27
- }
27
+ } & Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby'>;
28
28
 
29
29
  export default function Drawer({
30
30
  children,
@@ -34,6 +34,8 @@ export default function Drawer({
34
34
  onClose,
35
35
  open = false,
36
36
  position = 'right',
37
+ role = 'dialog',
38
+ 'aria-labelledby': ariaLabelledBy,
37
39
  }: DrawerProps) {
38
40
  logActionRequiredIf(
39
41
  'Drawer now expects `onClose`, and will soon make this prop required. Please update your usage to provide it.',
@@ -50,9 +52,9 @@ export default function Drawer({
50
52
  <SlidingPanel open={open} position={isMobile ? Position.BOTTOM : position}>
51
53
  <div
52
54
  id={overlayId}
53
- role="dialog"
55
+ role={role}
54
56
  aria-modal
55
- aria-labelledby={headerTitle ? titleId : undefined}
57
+ aria-labelledby={ariaLabelledBy || (headerTitle ? titleId : undefined)}
56
58
  className={clsx('np-drawer', className)}
57
59
  >
58
60
  <div
@@ -6,11 +6,14 @@ import Avatar, { AvatarType } from '../avatar';
6
6
  import AvatarWrapper from '../avatarWrapper';
7
7
  import Body from '../body';
8
8
  import Button from '../button';
9
- import { ProfileType, Size } from '../common';
9
+ import { ProfileType, Size, Typography } from '../common';
10
10
  import Logo from '../logo';
11
11
  import OverlayHeader from '../overlayHeader';
12
12
 
13
13
  import FlowNavigation from './FlowNavigation';
14
+ import { lorem10 } from '../test-utils';
15
+ import Display from '../display';
16
+ import Sticky from '../sticky';
14
17
 
15
18
  export default {
16
19
  component: FlowNavigation,
@@ -51,26 +54,12 @@ export const Variants = () => {
51
54
  steps={[
52
55
  {
53
56
  label: 'Amount',
54
- hoverLabel: (
55
- <>
56
- <div>
57
- <strong>100 GBP</strong>
58
- </div>
59
- 0.2351 ETH
60
- </>
61
- ),
57
+ hoverLabel: <strong>100 GBP</strong>,
62
58
  onClick: () => setActiveStep(0),
63
59
  },
64
60
  {
65
61
  label: 'You',
66
- hoverLabel: (
67
- <>
68
- <div>
69
- <strong>Elena Durante</strong>
70
- </div>
71
- elenadurante@test.com
72
- </>
73
- ),
62
+ hoverLabel: <>Elena Durante - elenadurante@test.com</>,
74
63
  onClick: () => setActiveStep(1),
75
64
  },
76
65
  { label: 'Recipient', hoverLabel: 'Daniele Tomboro', onClick: () => setActiveStep(2) },
@@ -201,6 +190,69 @@ export const Variants = () => {
201
190
  ) : null;
202
191
  };
203
192
 
193
+ export const SendFlow = () => {
194
+ const [activeStep, setActiveStep] = useState(2);
195
+ const steps = [
196
+ {
197
+ label: 'Recipient',
198
+ onClick: handleStepClick(0),
199
+ },
200
+ {
201
+ label: 'Amount',
202
+ hoverLabel: (
203
+ <>
204
+ You send 100 GBP <br />
205
+ You get 99.39 GBP{' '}
206
+ </>
207
+ ),
208
+ ...(activeStep > 1 && { onClick: handleStepClick(1) }),
209
+ },
210
+ {
211
+ label: 'Review',
212
+ ...(activeStep > 2 && { onClick: handleStepClick(2) }),
213
+ },
214
+ {
215
+ label: 'Pay',
216
+ ...(activeStep > 3 && { onClick: handleStepClick(3) }),
217
+ },
218
+ ];
219
+ function handleStepClick(step) {
220
+ return () => {
221
+ setActiveStep(step);
222
+ };
223
+ }
224
+ return (
225
+ <>
226
+ <FlowNavigation
227
+ avatar={
228
+ <Avatar type={AvatarType.ICON} size={Size.MEDIUM}>
229
+ <ProfileIcon />
230
+ </Avatar>
231
+ }
232
+ logo={<Logo />}
233
+ activeStep={activeStep}
234
+ steps={steps}
235
+ onClose={() => alert('close & move away')}
236
+ onGoBack={() => setActiveStep(activeStep > 0 ? activeStep - 1 : 0)}
237
+ />
238
+
239
+ <Body className="m-a-3">
240
+ <Display type={Typography.DISPLAY_SMALL}>{steps[activeStep].label} Step</Display>
241
+ <br />
242
+ {lorem10}
243
+ </Body>
244
+
245
+ <Sticky>
246
+ <div className="d-flex justify-content-center align-items-center p-a-3">
247
+ <Button disabled={activeStep === 3} block onClick={() => setActiveStep(activeStep + 1)}>
248
+ Continue
249
+ </Button>
250
+ </div>
251
+ </Sticky>
252
+ </>
253
+ );
254
+ };
255
+
204
256
  export const WithOverlayHeaderComparison = () => {
205
257
  const [activeStep, setActiveStep] = useState(4);
206
258
  const [closed, setClosed] = useState(false);
@@ -71,11 +71,7 @@ const FlowNavigation = ({
71
71
  <div className="np-flow-header__left">{logo}</div>
72
72
  )}
73
73
  {!screenSm && !done && (
74
- <AnimatedLabel
75
- className="m-x-1"
76
- labels={steps.map((step) => step.label)}
77
- activeLabel={activeStep}
78
- />
74
+ <AnimatedLabel className="m-x-1" steps={steps} activeLabel={activeStep} />
79
75
  )}
80
76
  </>
81
77
  }
@@ -11,7 +11,7 @@
11
11
  transform: translateX(-8px);
12
12
  transition: all 0.3s ease-in;
13
13
  }
14
- .np-animated-label--in {
14
+ .np-animated-label--active {
15
15
  height: auto;
16
16
  opacity: 1;
17
17
  position: relative;
@@ -19,3 +19,12 @@
19
19
  transform: translateX(0);
20
20
  transition: all 0.3s ease-in 0.3s;
21
21
  }
22
+ .np-animated-label-option {
23
+ border-radius: 10px;
24
+ border-radius: var(--radius-small);
25
+ }
26
+ .np-animated-label-option:not(.disabled):hover,
27
+ .np-animated-label-option:not(.disabled):focus-visible {
28
+ outline: var(--ring-outline-color) solid var(--ring-outline-width);
29
+ outline-offset: var(--ring-outline-offset);
30
+ }
@@ -1,4 +1,5 @@
1
1
  @import (reference) "../../../node_modules/@transferwise/neptune-css/src/less/addons/_spacing-utilities.less";
2
+ @import (reference) "../../../node_modules/@transferwise/neptune-css/src/less/ring.less";
2
3
 
3
4
  @transition-timing-function: ease-in-out;
4
5
  @transition-duration: 0.3s;
@@ -20,7 +21,7 @@
20
21
  transition: all @transition-duration ease-in;
21
22
  }
22
23
 
23
- &--in {
24
+ &--active {
24
25
  height: auto;
25
26
  opacity: 1;
26
27
  position: relative;
@@ -28,4 +29,12 @@
28
29
  transform: translateX(0);
29
30
  transition: all @transition-duration ease-in @transition-duration;
30
31
  }
32
+
33
+ &-option {
34
+ border-radius: var(--radius-small);
35
+ &:not(.disabled):hover,
36
+ &:not(.disabled):focus-visible {
37
+ .ring();
38
+ }
39
+ }
31
40
  }