@transferwise/components 0.0.0-experimental-af6dee0 → 0.0.0-experimental-199a021
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/avatarWrapper/AvatarWrapper.js +3 -4
- package/build/avatarWrapper/AvatarWrapper.js.map +1 -1
- package/build/avatarWrapper/AvatarWrapper.mjs +4 -5
- package/build/avatarWrapper/AvatarWrapper.mjs.map +1 -1
- package/build/button/LegacyButton.js.map +1 -1
- package/build/button/LegacyButton.mjs.map +1 -1
- package/build/common/hooks/useHasIntersected/useHasIntersected.js +6 -4
- package/build/common/hooks/useHasIntersected/useHasIntersected.js.map +1 -1
- package/build/common/hooks/useHasIntersected/useHasIntersected.mjs +6 -4
- package/build/common/hooks/useHasIntersected/useHasIntersected.mjs.map +1 -1
- package/build/common/liveRegion/LiveRegion.js +4 -1
- package/build/common/liveRegion/LiveRegion.js.map +1 -1
- package/build/common/liveRegion/LiveRegion.mjs +4 -1
- package/build/common/liveRegion/LiveRegion.mjs.map +1 -1
- package/build/dateInput/DateInput.js +10 -10
- package/build/dateInput/DateInput.js.map +1 -1
- package/build/dateInput/DateInput.mjs +10 -10
- package/build/dateInput/DateInput.mjs.map +1 -1
- package/build/dateLookup/monthCalendar/table/MonthCalendarTable.js +1 -1
- package/build/dateLookup/monthCalendar/table/MonthCalendarTable.js.map +1 -1
- package/build/dateLookup/monthCalendar/table/MonthCalendarTable.mjs +1 -1
- package/build/dateLookup/monthCalendar/table/MonthCalendarTable.mjs.map +1 -1
- package/build/dateLookup/yearCalendar/table/YearCalendarTable.js +1 -1
- package/build/dateLookup/yearCalendar/table/YearCalendarTable.js.map +1 -1
- package/build/dateLookup/yearCalendar/table/YearCalendarTable.mjs +1 -1
- package/build/dateLookup/yearCalendar/table/YearCalendarTable.mjs.map +1 -1
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.js.map +1 -1
- package/build/expressiveMoneyInput/ExpressiveMoneyInput.mjs.map +1 -1
- package/build/expressiveMoneyInput/amountInput/AmountInput.js +17 -11
- package/build/expressiveMoneyInput/amountInput/AmountInput.js.map +1 -1
- package/build/expressiveMoneyInput/amountInput/AmountInput.mjs +18 -12
- package/build/expressiveMoneyInput/amountInput/AmountInput.mjs.map +1 -1
- package/build/expressiveMoneyInput/hooks/useInputStyle.js +8 -6
- package/build/expressiveMoneyInput/hooks/useInputStyle.js.map +1 -1
- package/build/expressiveMoneyInput/hooks/useInputStyle.mjs +9 -7
- package/build/expressiveMoneyInput/hooks/useInputStyle.mjs.map +1 -1
- package/build/header/Header.js +1 -1
- package/build/header/Header.js.map +1 -1
- package/build/header/Header.mjs +1 -1
- package/build/header/Header.mjs.map +1 -1
- package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.js.map +1 -1
- package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.mjs.map +1 -1
- package/build/inputs/SelectInput/Options/SelectInputOptions.js +31 -22
- package/build/inputs/SelectInput/Options/SelectInputOptions.js.map +1 -1
- package/build/inputs/SelectInput/Options/SelectInputOptions.mjs +32 -23
- package/build/inputs/SelectInput/Options/SelectInputOptions.mjs.map +1 -1
- package/build/inputs/SelectInput/Popover/SelectInputPopover.js.map +1 -1
- package/build/inputs/SelectInput/Popover/SelectInputPopover.mjs.map +1 -1
- package/build/inputs/SelectInput/SelectInput.js +8 -6
- package/build/inputs/SelectInput/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput/SelectInput.mjs +9 -7
- package/build/inputs/SelectInput/SelectInput.mjs.map +1 -1
- package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.js.map +1 -1
- package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.mjs.map +1 -1
- package/build/loader/Loader.js +6 -16
- package/build/loader/Loader.js.map +1 -1
- package/build/loader/Loader.mjs +7 -17
- package/build/loader/Loader.mjs.map +1 -1
- package/build/main.css +4 -15
- package/build/nudge/Nudge.js +26 -15
- package/build/nudge/Nudge.js.map +1 -1
- package/build/nudge/Nudge.mjs +26 -15
- package/build/nudge/Nudge.mjs.map +1 -1
- package/build/phoneNumberInput/PhoneNumberInput.js +9 -12
- package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
- package/build/phoneNumberInput/PhoneNumberInput.mjs +9 -12
- package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
- package/build/promoCard/PromoCardGroup.js +34 -16
- package/build/promoCard/PromoCardGroup.js.map +1 -1
- package/build/promoCard/PromoCardGroup.mjs +35 -17
- package/build/promoCard/PromoCardGroup.mjs.map +1 -1
- package/build/segmentedControl/SegmentedControl.js +6 -1
- package/build/segmentedControl/SegmentedControl.js.map +1 -1
- package/build/segmentedControl/SegmentedControl.mjs +7 -2
- package/build/segmentedControl/SegmentedControl.mjs.map +1 -1
- package/build/styles/loader/Loader.css +4 -14
- package/build/styles/main.css +4 -15
- package/build/tabs/Tabs.js +1 -1
- package/build/tabs/Tabs.js.map +1 -1
- package/build/tabs/Tabs.mjs +1 -1
- package/build/tabs/Tabs.mjs.map +1 -1
- package/build/tooltip/Tooltip.js +6 -3
- package/build/tooltip/Tooltip.js.map +1 -1
- package/build/tooltip/Tooltip.mjs +6 -3
- package/build/tooltip/Tooltip.mjs.map +1 -1
- package/build/types/avatarWrapper/AvatarWrapper.d.ts.map +1 -1
- package/build/types/common/hooks/useHasIntersected/useHasIntersected.d.ts.map +1 -1
- package/build/types/common/liveRegion/LiveRegion.d.ts.map +1 -1
- package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
- package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.d.ts.map +1 -1
- package/build/types/expressiveMoneyInput/amountInput/AmountInput.d.ts.map +1 -1
- package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts +2 -2
- package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts.map +1 -1
- package/build/types/expressiveMoneyInput/hooks/useSelectionRange.d.ts.map +1 -1
- package/build/types/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.d.ts.map +1 -1
- package/build/types/inputs/SelectInput/Options/SelectInputOptions.d.ts.map +1 -1
- package/build/types/inputs/SelectInput/Popover/SelectInputPopover.d.ts.map +1 -1
- package/build/types/inputs/SelectInput/SelectInput.d.ts.map +1 -1
- package/build/types/loader/Loader.d.ts +1 -4
- package/build/types/loader/Loader.d.ts.map +1 -1
- package/build/types/nudge/Nudge.d.ts.map +1 -1
- package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
- package/build/types/promoCard/PromoCardGroup.d.ts.map +1 -1
- package/build/types/segmentedControl/SegmentedControl.d.ts.map +1 -1
- package/build/types/tooltip/Tooltip.d.ts.map +1 -1
- package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
- package/build/uploadInput/UploadInput.js +29 -28
- package/build/uploadInput/UploadInput.js.map +1 -1
- package/build/uploadInput/UploadInput.mjs +29 -28
- package/build/uploadInput/UploadInput.mjs.map +1 -1
- package/package.json +3 -3
- package/src/avatarWrapper/AvatarWrapper.tsx +5 -6
- package/src/button/LegacyButton.tsx +1 -1
- package/src/button/_stories/Button.test.story.tsx +3 -3
- package/src/common/hooks/useContainerSize.test.tsx +1 -1
- package/src/common/hooks/useHasIntersected/useHasIntersected.ts +12 -4
- package/src/common/liveRegion/LiveRegion.tsx +5 -2
- package/src/dateInput/DateInput.tsx +10 -10
- package/src/dateLookup/monthCalendar/table/MonthCalendarTable.tsx +1 -5
- package/src/dateLookup/yearCalendar/table/YearCalendarTable.tsx +1 -1
- package/src/expressiveMoneyInput/ExpressiveMoneyInput.tsx +1 -1
- package/src/expressiveMoneyInput/amountInput/AmountInput.tsx +22 -15
- package/src/expressiveMoneyInput/hooks/useInputStyle.ts +20 -8
- package/src/expressiveMoneyInput/hooks/useSelectionRange.ts +2 -0
- package/src/header/Header.tsx +2 -2
- package/src/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.tsx +4 -0
- package/src/inputs/SelectInput/Options/SelectInputOptions.tsx +39 -26
- package/src/inputs/SelectInput/Popover/SelectInputPopover.tsx +4 -0
- package/src/inputs/SelectInput/SelectInput.tsx +21 -15
- package/src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx +1 -1
- package/src/loader/Loader.css +4 -14
- package/src/loader/Loader.less +88 -54
- package/src/loader/Loader.story.tsx +0 -4
- package/src/loader/Loader.test.tsx +5 -20
- package/src/loader/Loader.tsx +7 -18
- package/src/main.css +4 -15
- package/src/nudge/Nudge.tsx +22 -19
- package/src/phoneNumberInput/PhoneNumberInput.tsx +11 -13
- package/src/promoCard/PromoCard.story.tsx +3 -3
- package/src/promoCard/PromoCardGroup.tsx +39 -21
- package/src/segmentedControl/SegmentedControl.tsx +7 -1
- package/src/select/Select.story.tsx +1 -1
- package/src/tabs/Tabs.tsx +1 -1
- package/src/tooltip/Tooltip.tsx +3 -0
- package/src/uploadInput/UploadInput.tsx +28 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n * @default []\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n * @default 'file'\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & {\n /** @default false */\n multiple?: UploadButtonProps['multiple'];\n /** @default ['.pdf,application/pdf', '.jpg,.jpeg,image/jpeg', '.png,image/png'] */\n fileTypes?: UploadButtonProps['fileTypes'];\n /** @default 5000 */\n sizeLimit?: UploadButtonProps['sizeLimit'];\n} & Pick<UploadButtonProps, 'disabled' | 'description' | 'id' | 'uploadButtonTitle'> & {\n onDownload?: UploadItemProps['onDownload'];\n } & CommonProps;\n\n/**\n * Interface representing a reference to an UploadItem component.\n * Provides a method to focus the UploadItem.\n */\ninterface UploadItemRef {\n /**\n * Focuses the UploadItem component.\n */\n focus: () => void;\n\n /**\n * Required id of the UploadItem component.\n */\n id: string | number;\n\n /**\n * Optional status of the UploadItem component.\n */\n status?: string;\n}\n\n/**\n * Generates a unique ID for a file based on its name, size, and the current timestamp\n */\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\n/**\n * The component allows users to upload files, manage the list of uploaded files,\n * and handle file validation and deletion.\n *\n * @param {UploadInputProps} props - The properties for the UploadInput component.\n *\n * @see {@link UploadInput} for further information.\n * @see {@link https://storybook.wise.design/?path=/docs/forms-uploadinput--docs|Storybook Wise Design}\n */\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [lastAttemptedDeleteId, setLastAttemptedDeleteId] = useState<string | number | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n let fileRefs: (HTMLDivElement | UploadItemRef | null)[] = [];\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function updateFileList(updateFn: (list: readonly UploadedFile[]) => readonly UploadedFile[]) {\n setUploadedFiles(updateFn);\n uploadedFilesListReference.current = updateFn(uploadedFilesListReference.current);\n }\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n updateFileList((list) => [...list, recentUploadedFile]);\n }\n\n function removeFileFromList(file: UploadedFile) {\n updateFileList((list) =>\n list.filter((fileInList) => file !== fileInList && file.id !== fileInList.id),\n );\n fileRefs = fileRefs.filter((ref) => ref && ref.id !== file.id);\n }\n\n function modifyFileInList(file: UploadedFile, updates: Partial<UploadedFile>) {\n updateFileList((list) =>\n list.map((fileInList) =>\n fileInList === file || fileInList.id === file.id ? { ...file, ...updates } : fileInList,\n ),\n );\n }\n\n const removeFile = async (file: UploadedFile) => {\n const { id, status } = file;\n fileRefs = fileRefs.filter((item) => item && item.id !== file.id);\n\n if (status === Status.FAILED) {\n removeFileFromList(file);\n return Promise.resolve();\n }\n\n if (onDeleteFile && id) {\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n return onDeleteFile(id)\n .then(() => {\n removeFileFromList(file);\n })\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n\n const failedUpload = {\n id: generateFileId(file),\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n const formData = new FormData();\n\n if (file) {\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n if (typeof sizeLimit === 'number' && !isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n const existingFile = uploadedFiles.find((f) => f.filename === file.name);\n if (existingFile) {\n removeFileFromList(existingFile);\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id: generateFileId(file),\n filename: file.name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n type NextFocusable =\n | HTMLDivElement\n | UploadItemRef\n | { ref: HTMLDivElement | UploadItemRef; target: 'button' | 'link' }\n | null;\n\n const [nextFocusable, setNextFocusable] = useState<NextFocusable>(uploadInputRef.current);\n\n const handleFocus = (fileId: string | number) => {\n fileRefs = fileRefs.filter((ref) => {\n return ref && ref.id !== markedFileForDelete?.id;\n });\n\n const filesCount = fileRefs.length;\n let next: UploadItemRef | HTMLDivElement | null = uploadInputRef.current;\n let focusTarget: 'button' | 'link' = 'button';\n\n // If there will be no files left after deletion, focus the upload button\n if (filesCount === 1) {\n next = uploadInputRef.current;\n setNextFocusable(next);\n return;\n }\n\n if (filesCount > 1) {\n const currentFileIndex = fileRefs.findIndex((file) => file?.id === fileId);\n const currentFileId = fileRefs?.[currentFileIndex]?.id;\n const lastFileId = fileRefs?.[filesCount - 1]?.id;\n\n // if last file, select a previous one\n if (currentFileId === lastFileId) {\n next = fileRefs[filesCount - 2];\n } else {\n next = fileRefs[currentFileIndex + 1];\n }\n\n // If next is an UploadItemRef, check if it has a URL (succeeded)\n if (next && 'status' in next) {\n // Find the file object for this ref\n const fileObj = uploadedFiles.find((f) => f.id === next?.id);\n if (\n fileObj &&\n (fileObj.status === Status.SUCCEEDED || fileObj.status === Status.DONE) &&\n fileObj.url\n ) {\n focusTarget = 'link';\n }\n }\n setNextFocusable(() => {\n if (next && typeof (next as UploadItemRef).focus === 'function') {\n return { ref: next, target: focusTarget };\n }\n return next;\n });\n }\n };\n\n const handleRefocus = () => {\n const focusTarget = nextFocusable;\n if (lastAttemptedDeleteId) {\n setLastAttemptedDeleteId(null);\n return;\n }\n if (focusTarget) {\n // If there are no files left, focus the upload button\n if (\n uploadedFiles.length === 0 &&\n uploadInputRef.current &&\n typeof uploadInputRef.current.focus === 'function'\n ) {\n setTimeout(() => {\n uploadInputRef.current!.focus();\n }, 0);\n } else if (\n typeof focusTarget === 'object' &&\n 'ref' in focusTarget &&\n focusTarget.ref &&\n typeof focusTarget.ref.focus === 'function'\n ) {\n setTimeout(() => {\n if (focusTarget.ref && typeof (focusTarget.ref as UploadItemRef).focus === 'function') {\n // @ts-expect-error: focus may not exist on all possible ref types, but is safe here\n (focusTarget.ref as UploadItemRef).focus(focusTarget.target);\n }\n }, 0);\n } else if (focusTarget && typeof (focusTarget as UploadItemRef).focus === 'function') {\n setTimeout(() => {\n (focusTarget as UploadItemRef).focus();\n }, 0);\n }\n }\n };\n\n return (\n <>\n <div\n role=\"group\"\n className={clsx('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n <div\n className=\"np-upload-input__section\"\n aria-live=\"polite\"\n aria-relevant=\"all\"\n role=\"region\"\n >\n {uploadedFiles.map((file, index) => (\n <UploadItem\n key={file.id}\n ref={(el: UploadItemRef | null) => {\n if (\n el &&\n el.id !== markedFileForDelete?.id &&\n !fileRefs.some((ref) => ref && ref.id === el.id) &&\n el.status !== 'processing'\n ) {\n fileRefs.push(el);\n }\n }}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? async () => {\n setLastAttemptedDeleteId(file.id);\n await removeFile(file);\n handleRefocus();\n }\n : () => {\n setLastAttemptedDeleteId(file.id);\n setMarkedFileForDelete(file);\n }\n }\n onDownload={onDownload}\n onFocus={() => handleFocus(file.id)}\n />\n ))}\n </div>\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <div className=\"np-upload-input__section np-upload-input__section--uploader\">\n <UploadButton\n ref={uploadInputRef}\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n withEntries={Boolean(uploadedFiles.length)}\n onChange={addFiles}\n />\n </div>\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n tabIndex={markedFileForDelete ? 0 : -1}\n onClick={() => {\n if (markedFileForDelete) {\n void removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n setLastAttemptedDeleteId(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onUnmount={handleRefocus}\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","lastAttemptedDeleteId","setLastAttemptedDeleteId","mounted","setMounted","formatMessage","useIntl","uploadInputRef","useRef","fileRefs","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","updateFileList","updateFn","current","addFileToList","recentUploadedFile","list","removeFileFromList","filter","fileInList","ref","modifyFileInList","updates","map","removeFile","status","item","FAILED","Promise","resolve","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","existingFile","find","f","append","pendingFile","url","useEffect","nextFocusable","setNextFocusable","handleFocus","fileId","filesCount","next","focusTarget","currentFileIndex","findIndex","currentFileId","lastFileId","fileObj","DONE","focus","target","handleRefocus","setTimeout","_jsxs","_Fragment","children","role","clsx","_jsx","index","UploadItem","el","some","push","singleFileUpload","canDelete","onDelete","onFocus","UploadButton","withEntries","Boolean","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","tabIndex","confirmText","deleteModalConfirmButtonText","onUnmount","onClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n * @default []\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n * @default 'file'\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & {\n /** @default false */\n multiple?: UploadButtonProps['multiple'];\n /** @default ['.pdf,application/pdf', '.jpg,.jpeg,image/jpeg', '.png,image/png'] */\n fileTypes?: UploadButtonProps['fileTypes'];\n /** @default 5000 */\n sizeLimit?: UploadButtonProps['sizeLimit'];\n} & Pick<UploadButtonProps, 'disabled' | 'description' | 'id' | 'uploadButtonTitle'> & {\n onDownload?: UploadItemProps['onDownload'];\n } & CommonProps;\n\n/**\n * Interface representing a reference to an UploadItem component.\n * Provides a method to focus the UploadItem.\n */\ninterface UploadItemRef {\n /**\n * Focuses the UploadItem component.\n */\n focus: () => void;\n\n /**\n * Required id of the UploadItem component.\n */\n id: string | number;\n\n /**\n * Optional status of the UploadItem component.\n */\n status?: string;\n}\n\n/**\n * Generates a unique ID for a file based on its name, size, and the current timestamp\n */\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\n/**\n * The component allows users to upload files, manage the list of uploaded files,\n * and handle file validation and deletion.\n *\n * @param {UploadInputProps} props - The properties for the UploadInput component.\n *\n * @see {@link UploadInput} for further information.\n * @see {@link https://storybook.wise.design/?path=/docs/forms-uploadinput--docs|Storybook Wise Design}\n */\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [lastAttemptedDeleteId, setLastAttemptedDeleteId] = useState<string | number | null>(null);\n const mountedRef = useRef(false);\n const { formatMessage } = useIntl();\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n const fileRefs = useRef<(HTMLDivElement | UploadItemRef | null)[]>([]);\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function updateFileList(updateFn: (list: readonly UploadedFile[]) => readonly UploadedFile[]) {\n setUploadedFiles(updateFn);\n uploadedFilesListReference.current = updateFn(uploadedFilesListReference.current);\n }\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n updateFileList((list) => [...list, recentUploadedFile]);\n }\n\n function removeFileFromList(file: UploadedFile) {\n updateFileList((list) =>\n list.filter((fileInList) => file !== fileInList && file.id !== fileInList.id),\n );\n fileRefs.current = fileRefs.current.filter((ref) => ref && ref.id !== file.id);\n }\n\n function modifyFileInList(file: UploadedFile, updates: Partial<UploadedFile>) {\n updateFileList((list) =>\n list.map((fileInList) =>\n fileInList === file || fileInList.id === file.id ? { ...file, ...updates } : fileInList,\n ),\n );\n }\n\n const removeFile = async (file: UploadedFile) => {\n const { id: fileId, status } = file;\n fileRefs.current = fileRefs.current.filter((item) => item && item.id !== file.id);\n\n if (status === Status.FAILED) {\n removeFileFromList(file);\n return Promise.resolve();\n }\n\n if (onDeleteFile && fileId) {\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n return onDeleteFile(fileId)\n .then(() => {\n removeFileFromList(file);\n })\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n\n const failedUpload = {\n id: generateFileId(file),\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n const formData = new FormData();\n\n if (file) {\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n }\n\n if (typeof sizeLimit === 'number' && !isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n }\n\n const existingFile = uploadedFiles.find((f) => f.filename === file.name);\n if (existingFile) {\n removeFileFromList(existingFile);\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id: generateFileId(file),\n filename: file.name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n // Skip onFilesChange call on initial mount, only call on updates\n if (!mountedRef.current) {\n mountedRef.current = true;\n return;\n }\n\n if (onFilesChange) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]);\n\n type NextFocusable =\n | HTMLDivElement\n | UploadItemRef\n | { ref: HTMLDivElement | UploadItemRef; target: 'button' | 'link' }\n | null;\n\n const [nextFocusable, setNextFocusable] = useState<NextFocusable>(null);\n\n const handleFocus = (fileId: string | number) => {\n fileRefs.current = fileRefs.current.filter((ref) => {\n return ref && ref.id !== markedFileForDelete?.id;\n });\n\n const filesCount = fileRefs.current.length;\n let next: UploadItemRef | HTMLDivElement | null = uploadInputRef.current;\n let focusTarget: 'button' | 'link' = 'button';\n\n // If there will be no files left after deletion, focus the upload button\n if (filesCount === 1) {\n next = uploadInputRef.current;\n setNextFocusable(next);\n return;\n }\n\n if (filesCount > 1) {\n const currentFileIndex = fileRefs.current.findIndex((file) => file?.id === fileId);\n const currentFileId = fileRefs.current?.[currentFileIndex]?.id;\n const lastFileId = fileRefs.current?.[filesCount - 1]?.id;\n\n // if last file, select a previous one\n if (currentFileId === lastFileId) {\n next = fileRefs.current[filesCount - 2];\n } else {\n next = fileRefs.current[currentFileIndex + 1];\n }\n\n // If next is an UploadItemRef, check if it has a URL (succeeded)\n if (next && 'status' in next) {\n // Find the file object for this ref\n const fileObj = uploadedFiles.find((f) => f.id === next?.id);\n if (\n fileObj &&\n (fileObj.status === Status.SUCCEEDED || fileObj.status === Status.DONE) &&\n fileObj.url\n ) {\n focusTarget = 'link';\n }\n }\n setNextFocusable(() => {\n if (next && typeof (next as UploadItemRef).focus === 'function') {\n return { ref: next, target: focusTarget };\n }\n return next;\n });\n }\n };\n\n const handleRefocus = () => {\n const focusTarget = nextFocusable;\n if (lastAttemptedDeleteId) {\n setLastAttemptedDeleteId(null);\n return;\n }\n if (focusTarget) {\n // If there are no files left, focus the upload button\n if (\n uploadedFiles.length === 0 &&\n uploadInputRef.current &&\n typeof uploadInputRef.current.focus === 'function'\n ) {\n setTimeout(() => {\n uploadInputRef.current?.focus();\n }, 0);\n } else if (\n typeof focusTarget === 'object' &&\n 'ref' in focusTarget &&\n focusTarget.ref &&\n typeof focusTarget.ref.focus === 'function'\n ) {\n setTimeout(() => {\n if (focusTarget.ref && typeof (focusTarget.ref as UploadItemRef).focus === 'function') {\n // @ts-expect-error: focus may not exist on all possible ref types, but is safe here\n (focusTarget.ref as UploadItemRef).focus(focusTarget.target);\n }\n }, 0);\n } else if (focusTarget && typeof (focusTarget as UploadItemRef).focus === 'function') {\n setTimeout(() => {\n (focusTarget as UploadItemRef).focus();\n }, 0);\n }\n }\n };\n\n return (\n <>\n <div\n role=\"group\"\n className={clsx('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n <div\n className=\"np-upload-input__section\"\n aria-live=\"polite\"\n aria-relevant=\"all\"\n role=\"region\"\n >\n {uploadedFiles.map((file) => (\n <UploadItem\n key={file.id}\n ref={(el: UploadItemRef | null) => {\n if (\n el &&\n el.id !== markedFileForDelete?.id &&\n !fileRefs.current.some((ref) => ref?.id === el.id) &&\n el.status !== 'processing'\n ) {\n fileRefs.current.push(el);\n }\n }}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? async () => {\n setLastAttemptedDeleteId(file.id);\n await removeFile(file);\n handleRefocus();\n }\n : () => {\n setLastAttemptedDeleteId(file.id);\n setMarkedFileForDelete(file);\n }\n }\n onDownload={onDownload}\n onFocus={() => handleFocus(file.id)}\n />\n ))}\n </div>\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <div className=\"np-upload-input__section np-upload-input__section--uploader\">\n <UploadButton\n ref={uploadInputRef}\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n // eslint-disable-next-line react-hooks/refs -- Function reads ref for file count check\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n withEntries={Boolean(uploadedFiles.length)}\n onChange={addFiles}\n />\n </div>\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n tabIndex={markedFileForDelete ? 0 : -1}\n onClick={() => {\n if (markedFileForDelete) {\n void removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n setLastAttemptedDeleteId(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onUnmount={handleRefocus}\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","lastAttemptedDeleteId","setLastAttemptedDeleteId","mountedRef","useRef","formatMessage","useIntl","uploadInputRef","fileRefs","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","updateFileList","updateFn","current","addFileToList","recentUploadedFile","list","removeFileFromList","filter","fileInList","ref","modifyFileInList","updates","map","removeFile","fileId","status","item","FAILED","Promise","resolve","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","existingFile","find","f","append","pendingFile","url","useEffect","nextFocusable","setNextFocusable","handleFocus","filesCount","next","focusTarget","currentFileIndex","findIndex","currentFileId","lastFileId","fileObj","DONE","focus","target","handleRefocus","setTimeout","_jsxs","_Fragment","children","role","clsx","_jsx","UploadItem","el","some","push","singleFileUpload","canDelete","onDelete","onFocus","UploadButton","withEntries","Boolean","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","tabIndex","confirmText","deleteModalConfirmButtonText","onUnmount","onClose"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqIA,SAASA,cAAcA,CAACC,IAAU,EAAA;EAChC,MAAM;IAAEC,IAAI;AAAEC,IAAAA;AAAI,GAAE,GAAGF,IAAI;EAC3B,MAAMG,eAAe,GAAG,IAAIC,IAAI,EAAE,CAACC,OAAO,EAAE;AAC5C,EAAA,OAAO,GAAGJ,IAAI,CAAA,CAAA,EAAIC,IAAI,CAAA,CAAA,EAAIC,eAAe,CAAA,CAAE;AAC7C;AAEA;;;;;;;;AAQG;AACH,MAAMG,WAAW,GAAGA,CAAC;AACnBC,EAAAA,KAAK,GAAG,EAAE;AACVC,EAAAA,aAAa,GAAG,MAAM;EACtBC,SAAS;EACTC,aAAa;EACbC,QAAQ;AACRC,EAAAA,QAAQ,GAAG,KAAK;AAChBC,EAAAA,SAAS,GAAGC,cAAc;AAC1BC,EAAAA,SAAS,GAAGC,kBAAkB;EAC9BC,WAAW;EACXC,YAAY;EACZC,YAAY;EACZC,iBAAiB;EACjBC,aAAa;EACbC,UAAU;EACVC,QAAQ;EACRC,oBAAoB;EACpBC,EAAE;EACFC,qBAAqB;AACrBC,EAAAA;AAAiB,CACA,KAAI;EACrB,MAAMC,eAAe,GAAGC,kBAAkB,CAAC;AAAEC,IAAAA,YAAY,EAAE;AAAI,GAAE,CAAC;EAClE,MAAM,CAACC,mBAAmB,EAAEC,sBAAsB,CAAC,GAAGC,QAAQ,CAAsB,IAAI,CAAC;EACzF,MAAM,CAACC,qBAAqB,EAAEC,wBAAwB,CAAC,GAAGF,QAAQ,CAAyB,IAAI,CAAC;AAChG,EAAA,MAAMG,UAAU,GAAGC,MAAM,CAAC,KAAK,CAAC;EAChC,MAAM;AAAEC,IAAAA;GAAe,GAAGC,OAAO,EAAE;AACnC,EAAA,MAAMC,cAAc,GAAGH,MAAM,CAA0B,IAAI,CAAC;AAC5D,EAAA,MAAMI,QAAQ,GAAGJ,MAAM,CAA4C,EAAE,CAAC;AAEtE,EAAA,MAAMK,iBAAiB,GAAG,IAAIC,GAAG,CAAC,CAACC,MAAM,CAACC,OAAO,EAAED,MAAM,CAACE,UAAU,CAAC,CAAC;EAEtE,MAAM,CAACC,aAAa,EAAEC,gBAAgB,CAAC,GAAGf,QAAQ,CAChDrB,QAAQ,IAAIL,KAAK,CAAC0C,MAAM,KAAK,CAAC,GAAG1C,KAAK,GAAG,CAACA,KAAK,CAAC,CAAC,CAAC,CAAC,CACpD;EAED,MAAM2C,0BAA0B,GAAGb,MAAM,CAACzB,QAAQ,IAAIL,KAAK,CAAC0C,MAAM,KAAK,CAAC,GAAG1C,KAAK,GAAG,CAACA,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EAE9F,SAAS4C,cAAcA,CAACC,QAAoE,EAAA;IAC1FJ,gBAAgB,CAACI,QAAQ,CAAC;IAC1BF,0BAA0B,CAACG,OAAO,GAAGD,QAAQ,CAACF,0BAA0B,CAACG,OAAO,CAAC;AACnF,EAAA;EAEA,SAASC,aAAaA,CAACC,kBAAgC,EAAA;IACrDJ,cAAc,CAAEK,IAAI,IAAK,CAAC,GAAGA,IAAI,EAAED,kBAAkB,CAAC,CAAC;AACzD,EAAA;EAEA,SAASE,kBAAkBA,CAACzD,IAAkB,EAAA;IAC5CmD,cAAc,CAAEK,IAAI,IAClBA,IAAI,CAACE,MAAM,CAAEC,UAAU,IAAK3D,IAAI,KAAK2D,UAAU,IAAI3D,IAAI,CAACyB,EAAE,KAAKkC,UAAU,CAAClC,EAAE,CAAC,CAC9E;IACDgB,QAAQ,CAACY,OAAO,GAAGZ,QAAQ,CAACY,OAAO,CAACK,MAAM,CAAEE,GAAG,IAAKA,GAAG,IAAIA,GAAG,CAACnC,EAAE,KAAKzB,IAAI,CAACyB,EAAE,CAAC;AAChF,EAAA;AAEA,EAAA,SAASoC,gBAAgBA,CAAC7D,IAAkB,EAAE8D,OAA8B,EAAA;IAC1EX,cAAc,CAAEK,IAAI,IAClBA,IAAI,CAACO,GAAG,CAAEJ,UAAU,IAClBA,UAAU,KAAK3D,IAAI,IAAI2D,UAAU,CAAClC,EAAE,KAAKzB,IAAI,CAACyB,EAAE,GAAG;AAAE,MAAA,GAAGzB,IAAI;MAAE,GAAG8D;KAAS,GAAGH,UAAU,CACxF,CACF;AACH,EAAA;AAEA,EAAA,MAAMK,UAAU,GAAG,MAAOhE,IAAkB,IAAI;IAC9C,MAAM;AAAEyB,MAAAA,EAAE,EAAEwC,MAAM;AAAEC,MAAAA;AAAM,KAAE,GAAGlE,IAAI;IACnCyC,QAAQ,CAACY,OAAO,GAAGZ,QAAQ,CAACY,OAAO,CAACK,MAAM,CAAES,IAAI,IAAKA,IAAI,IAAIA,IAAI,CAAC1C,EAAE,KAAKzB,IAAI,CAACyB,EAAE,CAAC;AAEjF,IAAA,IAAIyC,MAAM,KAAKtB,MAAM,CAACwB,MAAM,EAAE;MAC5BX,kBAAkB,CAACzD,IAAI,CAAC;AACxB,MAAA,OAAOqE,OAAO,CAACC,OAAO,EAAE;AAC1B,IAAA;IAEA,IAAInD,YAAY,IAAI8C,MAAM,EAAE;MAC1BJ,gBAAgB,CAAC7D,IAAI,EAAE;QAAEkE,MAAM,EAAEtB,MAAM,CAACE,UAAU;AAAEyB,QAAAA,KAAK,EAAEC;AAAS,OAAE,CAAC;AAEvE,MAAA,OAAOrD,YAAY,CAAC8C,MAAM,CAAC,CACxBQ,IAAI,CAAC,MAAK;QACThB,kBAAkB,CAACzD,IAAI,CAAC;AAC1B,MAAA,CAAC,CAAC,CACD0E,KAAK,CAAEH,KAAK,IAAI;QACfV,gBAAgB,CAAC7D,IAAI,EAAE;AAAEuE,UAAAA,KAAK,EAAEA;AAAoB,SAAE,CAAC;AACzD,MAAA,CAAC,CAAC;AACN,IAAA;EACF,CAAC;AAED,EAAA,SAASI,uBAAuBA,CAAC3E,IAAU,EAAE4E,cAAsB,EAAA;IACjE,MAAM;AAAE3E,MAAAA;AAAI,KAAE,GAAGD,IAAI;AAErB,IAAA,MAAM6E,YAAY,GAAG;AACnBpD,MAAAA,EAAE,EAAE1B,cAAc,CAACC,IAAI,CAAC;AACxB8E,MAAAA,QAAQ,EAAE7E,IAAI;MACdiE,MAAM,EAAEtB,MAAM,CAACwB,MAAM;AACrBG,MAAAA,KAAK,EAAEK;KACR;IAEDtB,aAAa,CAACuB,YAAY,CAAC;AAE3B,IAAA,IAAIzD,iBAAiB,EAAE;MACrBA,iBAAiB,CAACyD,YAAY,CAAC;AACjC,IAAA;AACF,EAAA;EAEA,SAASE,wBAAwBA,GAAA;AAC/B,IAAA,MAAMC,qBAAqB,GAAG,IAAIrC,GAAG,CAAC,CAACC,MAAM,CAACqC,SAAS,EAAErC,MAAM,CAACC,OAAO,CAAC,CAAC;IAEzE,MAAMqC,UAAU,GAAGhC,0BAA0B,CAACG,OAAO,CAACK,MAAM,CACzD1D,IAAI,IAAKA,IAAI,CAACkE,MAAM,IAAIc,qBAAqB,CAACG,GAAG,CAACnF,IAAI,CAACkE,MAAM,CAAC,CAChE;IACD,OAAOgB,UAAU,CAACjC,MAAM;AAC1B,EAAA;EAEA,SAASmC,8BAA8BA,GAAA;IACrC,IAAI,CAAC7D,QAAQ,EAAE;AACb,MAAA,OAAO,KAAK;AACd,IAAA;AAEA,IAAA,MAAM8D,kBAAkB,GAAGN,wBAAwB,EAAE;IACrD,OAAOM,kBAAkB,IAAI9D,QAAQ;AACvC,EAAA;EAEA,MAAM+D,QAAQ,GAAIC,aAAuB,IAAI;AAC3C,IAAA,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGD,aAAa,CAACtC,MAAM,EAAEuC,CAAC,IAAI,CAAC,EAAE;AAChD,MAAA,MAAMxF,IAAI,GAAGuF,aAAa,CAACpB,IAAI,CAACqB,CAAC,CAAC;AAElC,MAAA,MAAMC,QAAQ,GAAG,IAAIC,QAAQ,EAAE;AAE/B,MAAA,IAAI1F,IAAI,EAAE;AACR,QAAA,MAAM2F,gBAAgB,GAAG,OAAO9E,SAAS,KAAK,QAAQ,GAAGA,SAAS,GAAGA,SAAS,CAAC+E,IAAI,CAAC,GAAG,CAAC;AAExF,QAAA,IAAI,CAACC,WAAW,CAAC7F,IAAI,EAAE2F,gBAAgB,CAAC,EAAE;UACxChB,uBAAuB,CAAC3E,IAAI,EAAEsC,aAAa,CAACwD,QAAQ,CAACC,oBAAoB,CAAC,CAAC;AAC7E,QAAA;AAEA,QAAA,IAAI,OAAOhF,SAAS,KAAK,QAAQ,IAAI,CAACiF,WAAW,CAAChG,IAAI,EAAEe,SAAS,GAAG,IAAI,CAAC,EAAE;UACzE,MAAM6D,cAAc,GAAGlD,qBAAqB,IAAIY,aAAa,CAACwD,QAAQ,CAACG,cAAc,CAAC;AACtFtB,UAAAA,uBAAuB,CAAC3E,IAAI,EAAE4E,cAAc,CAAC;AAC/C,QAAA;QAEA,IAAIQ,8BAA8B,EAAE,EAAE;UACpC,MAAMR,cAAc,GAClBpD,oBAAoB,IACpBc,aAAa,CAACwD,QAAQ,CAACI,2BAA2B,EAAE;AAAEC,YAAAA,eAAe,EAAE5E;AAAQ,WAAE,CAAC;AACpFoD,UAAAA,uBAAuB,CAAC3E,IAAI,EAAE4E,cAAc,CAAC;AAC/C,QAAA;AAEA,QAAA,MAAMwB,YAAY,GAAGrD,aAAa,CAACsD,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACxB,QAAQ,KAAK9E,IAAI,CAACC,IAAI,CAAC;AACxE,QAAA,IAAImG,YAAY,EAAE;UAChB3C,kBAAkB,CAAC2C,YAAY,CAAC;AAClC,QAAA;AAEAX,QAAAA,QAAQ,CAACc,MAAM,CAAC/F,aAAa,EAAER,IAAI,CAAC;AACpC,QAAA,MAAMwG,WAAW,GAAG;AAClB/E,UAAAA,EAAE,EAAE1B,cAAc,CAACC,IAAI,CAAC;UACxB8E,QAAQ,EAAE9E,IAAI,CAACC,IAAI;UACnBiE,MAAM,EAAEtB,MAAM,CAACC;SAChB;QAEDS,aAAa,CAACkD,WAAW,CAAC;AAE1BtF,QAAAA,YAAY,CAACuE,QAAQ,CAAC,CACnBhB,IAAI,CAAC,CAAC;UAAEhD,EAAE;UAAEgF,GAAG;AAAElC,UAAAA;AAAK,SAAkB,KAAI;UAC3CV,gBAAgB,CAAC2C,WAAW,EAAE;YAAE/E,EAAE;YAAEgF,GAAG;YAAElC,KAAK;YAAEL,MAAM,EAAEtB,MAAM,CAACqC;AAAS,WAAE,CAAC;AAC7E,QAAA,CAAC,CAAC,CACDP,KAAK,CAAEH,KAAK,IAAI;UACfV,gBAAgB,CAAC2C,WAAW,EAAE;AAAEjC,YAAAA,KAAK,EAAEA,KAAoB;YAAEL,MAAM,EAAEtB,MAAM,CAACwB;AAAM,WAAE,CAAC;AACvF,QAAA,CAAC,CAAC;QAEJ,IAAI,CAACxD,QAAQ,EAAE;AACb,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;EACF,CAAC;AAED8F,EAAAA,SAAS,CAAC,MAAK;AACb;AACA,IAAA,IAAI,CAACtE,UAAU,CAACiB,OAAO,EAAE;MACvBjB,UAAU,CAACiB,OAAO,GAAG,IAAI;AACzB,MAAA;AACF,IAAA;AAEA,IAAA,IAAIhC,aAAa,EAAE;AACjBA,MAAAA,aAAa,CAAC,CAAC,GAAG0B,aAAa,CAAC,CAAC;AACnC,IAAA;AACF,EAAA,CAAC,EAAE,CAAC1B,aAAa,EAAE0B,aAAa,CAAC,CAAC;EAQlC,MAAM,CAAC4D,aAAa,EAAEC,gBAAgB,CAAC,GAAG3E,QAAQ,CAAgB,IAAI,CAAC;EAEvE,MAAM4E,WAAW,GAAI5C,MAAuB,IAAI;IAC9CxB,QAAQ,CAACY,OAAO,GAAGZ,QAAQ,CAACY,OAAO,CAACK,MAAM,CAAEE,GAAG,IAAI;MACjD,OAAOA,GAAG,IAAIA,GAAG,CAACnC,EAAE,KAAKM,mBAAmB,EAAEN,EAAE;AAClD,IAAA,CAAC,CAAC;AAEF,IAAA,MAAMqF,UAAU,GAAGrE,QAAQ,CAACY,OAAO,CAACJ,MAAM;AAC1C,IAAA,IAAI8D,IAAI,GAA0CvE,cAAc,CAACa,OAAO;IACxE,IAAI2D,WAAW,GAAsB,QAAQ;AAE7C;IACA,IAAIF,UAAU,KAAK,CAAC,EAAE;MACpBC,IAAI,GAAGvE,cAAc,CAACa,OAAO;MAC7BuD,gBAAgB,CAACG,IAAI,CAAC;AACtB,MAAA;AACF,IAAA;IAEA,IAAID,UAAU,GAAG,CAAC,EAAE;AAClB,MAAA,MAAMG,gBAAgB,GAAGxE,QAAQ,CAACY,OAAO,CAAC6D,SAAS,CAAElH,IAAI,IAAKA,IAAI,EAAEyB,EAAE,KAAKwC,MAAM,CAAC;MAClF,MAAMkD,aAAa,GAAG1E,QAAQ,CAACY,OAAO,GAAG4D,gBAAgB,CAAC,EAAExF,EAAE;MAC9D,MAAM2F,UAAU,GAAG3E,QAAQ,CAACY,OAAO,GAAGyD,UAAU,GAAG,CAAC,CAAC,EAAErF,EAAE;AAEzD;MACA,IAAI0F,aAAa,KAAKC,UAAU,EAAE;QAChCL,IAAI,GAAGtE,QAAQ,CAACY,OAAO,CAACyD,UAAU,GAAG,CAAC,CAAC;AACzC,MAAA,CAAC,MAAM;QACLC,IAAI,GAAGtE,QAAQ,CAACY,OAAO,CAAC4D,gBAAgB,GAAG,CAAC,CAAC;AAC/C,MAAA;AAEA;AACA,MAAA,IAAIF,IAAI,IAAI,QAAQ,IAAIA,IAAI,EAAE;AAC5B;AACA,QAAA,MAAMM,OAAO,GAAGtE,aAAa,CAACsD,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAAC7E,EAAE,KAAKsF,IAAI,EAAEtF,EAAE,CAAC;QAC5D,IACE4F,OAAO,KACNA,OAAO,CAACnD,MAAM,KAAKtB,MAAM,CAACqC,SAAS,IAAIoC,OAAO,CAACnD,MAAM,KAAKtB,MAAM,CAAC0E,IAAI,CAAC,IACvED,OAAO,CAACZ,GAAG,EACX;AACAO,UAAAA,WAAW,GAAG,MAAM;AACtB,QAAA;AACF,MAAA;AACAJ,MAAAA,gBAAgB,CAAC,MAAK;QACpB,IAAIG,IAAI,IAAI,OAAQA,IAAsB,CAACQ,KAAK,KAAK,UAAU,EAAE;UAC/D,OAAO;AAAE3D,YAAAA,GAAG,EAAEmD,IAAI;AAAES,YAAAA,MAAM,EAAER;WAAa;AAC3C,QAAA;AACA,QAAA,OAAOD,IAAI;AACb,MAAA,CAAC,CAAC;AACJ,IAAA;EACF,CAAC;EAED,MAAMU,aAAa,GAAGA,MAAK;IACzB,MAAMT,WAAW,GAAGL,aAAa;AACjC,IAAA,IAAIzE,qBAAqB,EAAE;MACzBC,wBAAwB,CAAC,IAAI,CAAC;AAC9B,MAAA;AACF,IAAA;AACA,IAAA,IAAI6E,WAAW,EAAE;AACf;AACA,MAAA,IACEjE,aAAa,CAACE,MAAM,KAAK,CAAC,IAC1BT,cAAc,CAACa,OAAO,IACtB,OAAOb,cAAc,CAACa,OAAO,CAACkE,KAAK,KAAK,UAAU,EAClD;AACAG,QAAAA,UAAU,CAAC,MAAK;AACdlF,UAAAA,cAAc,CAACa,OAAO,EAAEkE,KAAK,EAAE;QACjC,CAAC,EAAE,CAAC,CAAC;MACP,CAAC,MAAM,IACL,OAAOP,WAAW,KAAK,QAAQ,IAC/B,KAAK,IAAIA,WAAW,IACpBA,WAAW,CAACpD,GAAG,IACf,OAAOoD,WAAW,CAACpD,GAAG,CAAC2D,KAAK,KAAK,UAAU,EAC3C;AACAG,QAAAA,UAAU,CAAC,MAAK;AACd,UAAA,IAAIV,WAAW,CAACpD,GAAG,IAAI,OAAQoD,WAAW,CAACpD,GAAqB,CAAC2D,KAAK,KAAK,UAAU,EAAE;AACrF;YACCP,WAAW,CAACpD,GAAqB,CAAC2D,KAAK,CAACP,WAAW,CAACQ,MAAM,CAAC;AAC9D,UAAA;QACF,CAAC,EAAE,CAAC,CAAC;MACP,CAAC,MAAM,IAAIR,WAAW,IAAI,OAAQA,WAA6B,CAACO,KAAK,KAAK,UAAU,EAAE;AACpFG,QAAAA,UAAU,CAAC,MAAK;UACbV,WAA6B,CAACO,KAAK,EAAE;QACxC,CAAC,EAAE,CAAC,CAAC;AACP,MAAA;AACF,IAAA;EACF,CAAC;EAED,oBACEI,IAAA,CAAAC,QAAA,EAAA;AAAAC,IAAAA,QAAA,gBACEF,IAAA,CAAA,KAAA,EAAA;AACEG,MAAAA,IAAI,EAAC,OAAO;AACZrH,MAAAA,SAAS,EAAEsH,IAAI,CAAC,iBAAiB,EAAEtH,SAAS,EAAE;AAAEE,QAAAA;AAAQ,OAAE,CAAE;AAAA,MAAA,GACxDiB,eAAe;AAAAiG,MAAAA,QAAA,gBAEnBG,GAAA,CAAA,KAAA,EAAA;AACEvH,QAAAA,SAAS,EAAC,0BAA0B;AACpC,QAAA,WAAA,EAAU,QAAQ;AAClB,QAAA,eAAA,EAAc,KAAK;AACnBqH,QAAAA,IAAI,EAAC,QAAQ;QAAAD,QAAA,EAEZ9E,aAAa,CAACgB,GAAG,CAAE/D,IAAI,iBACtBgI,GAAA,CAACC,UAAU,EAAA;UAETrE,GAAG,EAAGsE,EAAwB,IAAI;AAChC,YAAA,IACEA,EAAE,IACFA,EAAE,CAACzG,EAAE,KAAKM,mBAAmB,EAAEN,EAAE,IACjC,CAACgB,QAAQ,CAACY,OAAO,CAAC8E,IAAI,CAAEvE,GAAG,IAAKA,GAAG,EAAEnC,EAAE,KAAKyG,EAAE,CAACzG,EAAE,CAAC,IAClDyG,EAAE,CAAChE,MAAM,KAAK,YAAY,EAC1B;AACAzB,cAAAA,QAAQ,CAACY,OAAO,CAAC+E,IAAI,CAACF,EAAE,CAAC;AAC3B,YAAA;UACF,CAAE;AACFlI,UAAAA,IAAI,EAAEA,IAAK;UACXqI,gBAAgB,EAAE,CAACzH,QAAS;AAC5B0H,UAAAA,SAAS,EACP,CAAC,CAAC,CAACnH,YAAY,IAAInB,IAAI,CAACkE,MAAM,KAAKtB,MAAM,CAACwB,MAAM,MAC/C,CAACpE,IAAI,CAACkE,MAAM,IAAI,CAACxB,iBAAiB,CAACyC,GAAG,CAACnF,IAAI,CAACkE,MAAM,CAAC,CACrD;UACDqE,QAAQ,EACNvI,IAAI,CAACkE,MAAM,KAAKtB,MAAM,CAACwB,MAAM,GACzB,YAAW;AACTjC,YAAAA,wBAAwB,CAACnC,IAAI,CAACyB,EAAE,CAAC;YACjC,MAAMuC,UAAU,CAAChE,IAAI,CAAC;AACtByH,YAAAA,aAAa,EAAE;AACjB,UAAA,CAAC,GACD,MAAK;AACHtF,YAAAA,wBAAwB,CAACnC,IAAI,CAACyB,EAAE,CAAC;YACjCO,sBAAsB,CAAChC,IAAI,CAAC;UAC9B,CACL;AACDsB,UAAAA,UAAU,EAAEA,UAAW;AACvBkH,UAAAA,OAAO,EAAEA,MAAM3B,WAAW,CAAC7G,IAAI,CAACyB,EAAE;SAAE,EA9B/BzB,IAAI,CAACyB,EA8B0B,CAEvC;AAAC,OACC,CACL,EAAC,CAACb,QAAQ,IAAK,CAACA,QAAQ,IAAI,CAACmC,aAAa,CAACE,MAAO,kBAChD+E,GAAA,CAAA,KAAA,EAAA;AAAKvH,QAAAA,SAAS,EAAC,6DAA6D;QAAAoH,QAAA,eAC1EG,GAAA,CAACS,YAAY,EAAA;AACX7E,UAAAA,GAAG,EAAEpB,cAAe;AACpBf,UAAAA,EAAE,EAAEA,EAAG;AACPE,UAAAA,iBAAiB,EAAEA;AACnB;AAAA;AACAhB,UAAAA,QAAQ,EAAEyE,8BAA8B,EAAE,IAAIzE,QAAS;AACvDC,UAAAA,QAAQ,EAAEA,QAAS;AACnBC,UAAAA,SAAS,EAAEA,SAAU;AACrBE,UAAAA,SAAS,EAAEA,SAAU;AACrBE,UAAAA,WAAW,EAAEA,WAAY;AACzBM,UAAAA,QAAQ,EAAEA,QAAS;AACnBmH,UAAAA,WAAW,EAAEC,OAAO,CAAC5F,aAAa,CAACE,MAAM,CAAE;AAC3C2F,UAAAA,QAAQ,EAAEtD;SAAS;AAEvB,OAAK,CACN;AAAA,KACE,CACL,eAAA0C,GAAA,CAACa,KAAK,EAAA;AACJC,MAAAA,KAAK,EACHpI,aAAa,EAAEoI,KAAK,KAAKtE,SAAS,GAC9B9D,aAAa,CAACoI,KAAK,GACnBxG,aAAa,CAACwD,QAAQ,CAACiD,gBAAgB,CAC5C;AACDC,MAAAA,IAAI,EACFtI,aAAa,EAAEsI,IAAI,KAAKxE,SAAS,GAC7B9D,aAAa,CAACsI,IAAI,GAClB1G,aAAa,CAACwD,QAAQ,CAACmD,eAAe,CAC3C;MACDC,IAAI,EAAE,CAAC,CAACnH,mBAAoB;MAC5BoH,MAAM,eACJxB,IAAA,CAAAC,QAAA,EAAA;QAAAC,QAAA,EAAA,cACEG,GAAA,CAACoB,MAAM,EAAA;UACLC,KAAK,EAAA,IAAA;UACLC,OAAO,EAAEA,MAAK;YACZtH,sBAAsB,CAAC,IAAI,CAAC;UAC9B,CAAE;UAAA6F,QAAA,EAEDnH,aAAa,EAAE6I,UAAU,IAAIjH,aAAa,CAACwD,QAAQ,CAAC0D,2BAA2B;AAAC,SAC3E,CACR,eAAAxB,GAAA,CAACoB,MAAM,EAAA;UACLC,KAAK,EAAA,IAAA;UACLI,QAAQ,EAAEC,QAAQ,CAACC,SAAU;UAC7BC,IAAI,EAAEC,WAAW,CAACC,QAAS;AAC3BC,UAAAA,QAAQ,EAAEhI,mBAAmB,GAAG,CAAC,GAAG,EAAG;UACvCuH,OAAO,EAAEA,MAAK;AACZ,YAAA,IAAIvH,mBAAmB,EAAE;cACvB,KAAKiC,UAAU,CAACjC,mBAAmB,CAAC;AACtC,YAAA;YACAC,sBAAsB,CAAC,IAAI,CAAC;YAC5BG,wBAAwB,CAAC,IAAI,CAAC;UAChC,CAAE;UAAA0F,QAAA,EAEDnH,aAAa,EAAEsJ,WAAW,IAAI1H,aAAa,CAACwD,QAAQ,CAACmE,4BAA4B;AAAC,SAC7E,CACV;AAAA,OAAA,CACD;AACDC,MAAAA,SAAS,EAAEzC,aAAc;MACzB0C,OAAO,EAAEA,MAAK;QACZnI,sBAAsB,CAAC,IAAI,CAAC;AAC9B,MAAA;AAAE,KAAA,CAEN;AAAA,GAAA,CAAG;AAEP;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/components",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-199a021",
|
|
4
4
|
"description": "Neptune React components",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"monaco-editor": "^0.55.1",
|
|
74
74
|
"monaco-editor-webpack-plugin": "^7.1.1",
|
|
75
75
|
"@wise/art": "^2.30.1",
|
|
76
|
-
"@wise/eslint-config": "^
|
|
76
|
+
"@wise/eslint-config": "^14.2.1",
|
|
77
77
|
"babel-plugin-formatjs": "^10.5.41",
|
|
78
78
|
"eslint": "^9.39.4",
|
|
79
79
|
"eslint-plugin-storybook": "^10.3.6",
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"storybook-addon-tag-badges": "^3.1.0",
|
|
92
92
|
"storybook-addon-test-codegen": "^3.0.1",
|
|
93
93
|
"@transferwise/less-config": "3.1.2",
|
|
94
|
-
"@wise/components-theming": "1.10.2",
|
|
95
94
|
"@transferwise/neptune-css": "14.27.1",
|
|
95
|
+
"@wise/components-theming": "1.10.2",
|
|
96
96
|
"@wise/wds-configs": "0.0.0"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Person, Briefcase as BriefcaseIcon } from '@transferwise/icons';
|
|
2
|
-
import { useState
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
|
|
4
4
|
import Avatar, { AvatarProps, AvatarType } from '../avatar';
|
|
5
5
|
import Badge, { BadgeProps } from '../badge';
|
|
@@ -91,11 +91,10 @@ const AvatarWrapper = ({
|
|
|
91
91
|
avatarProps,
|
|
92
92
|
badgeProps,
|
|
93
93
|
}: AvatarWrapperProps) => {
|
|
94
|
-
const [
|
|
95
|
-
const isBusinessProfile = profileType === ProfileType.BUSINESS;
|
|
94
|
+
const [errorUrl, setErrorUrl] = useState<string | undefined>(undefined);
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
const hasImageLoadError = errorUrl === url;
|
|
97
|
+
const isBusinessProfile = profileType === ProfileType.BUSINESS;
|
|
99
98
|
|
|
100
99
|
const getAvatarProps = () => {
|
|
101
100
|
let updatedAvatarProps = avatarProps;
|
|
@@ -105,7 +104,7 @@ const AvatarWrapper = ({
|
|
|
105
104
|
if (url && !hasImageLoadError) {
|
|
106
105
|
return {
|
|
107
106
|
type: AvatarType.THUMBNAIL,
|
|
108
|
-
children: <img src={url} alt="" onError={() =>
|
|
107
|
+
children: <img src={url} alt="" onError={() => setErrorUrl(url)} />,
|
|
109
108
|
...updatedAvatarProps,
|
|
110
109
|
};
|
|
111
110
|
}
|
|
@@ -51,7 +51,7 @@ export const AllVariants: Story = {
|
|
|
51
51
|
>
|
|
52
52
|
<Button
|
|
53
53
|
v2
|
|
54
|
-
priority={priority
|
|
54
|
+
priority={priority}
|
|
55
55
|
size={size}
|
|
56
56
|
addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
|
|
57
57
|
addonEnd={{ type: 'icon', value: <ArrowRight /> }}
|
|
@@ -62,7 +62,7 @@ export const AllVariants: Story = {
|
|
|
62
62
|
<Button
|
|
63
63
|
className="m-t-1 m-b-1"
|
|
64
64
|
v2
|
|
65
|
-
priority={priority
|
|
65
|
+
priority={priority}
|
|
66
66
|
size={size}
|
|
67
67
|
addonStart={{
|
|
68
68
|
type: 'avatar',
|
|
@@ -76,7 +76,7 @@ export const AllVariants: Story = {
|
|
|
76
76
|
</Button>
|
|
77
77
|
<Button
|
|
78
78
|
v2
|
|
79
|
-
priority={priority
|
|
79
|
+
priority={priority}
|
|
80
80
|
size={size}
|
|
81
81
|
addonStart={{ type: 'avatar', value: [{ asset: <Freeze /> }] }}
|
|
82
82
|
addonEnd={{ type: 'icon', value: <ArrowRight /> }}
|
|
@@ -22,7 +22,11 @@ export const useHasIntersected = ({
|
|
|
22
22
|
elRef: React.RefObject<HTMLElement>;
|
|
23
23
|
loading?: 'eager' | 'lazy';
|
|
24
24
|
}) => {
|
|
25
|
-
|
|
25
|
+
// Initialize as true if IntersectionObserver is not supported
|
|
26
|
+
// Note: We can't check elRef.current here as it may not be set yet on first render
|
|
27
|
+
const [hasIntersected, setHasIntersected] = useState(() => {
|
|
28
|
+
return typeof window === 'undefined' || !window.IntersectionObserver;
|
|
29
|
+
});
|
|
26
30
|
|
|
27
31
|
const { current } = elRef || {};
|
|
28
32
|
|
|
@@ -47,9 +51,13 @@ export const useHasIntersected = ({
|
|
|
47
51
|
let didCancel = false;
|
|
48
52
|
|
|
49
53
|
// Check if window is defined for SSR and Old browsers fallback
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
if (
|
|
55
|
+
typeof window !== 'undefined' &&
|
|
56
|
+
window.IntersectionObserver &&
|
|
57
|
+
isValidReference() &&
|
|
58
|
+
current &&
|
|
59
|
+
!didCancel
|
|
60
|
+
) {
|
|
53
61
|
observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
|
|
54
62
|
observer.observe(current);
|
|
55
63
|
}
|
|
@@ -86,12 +86,15 @@ export const LiveRegion = ({
|
|
|
86
86
|
(typeof children === 'string' || typeof children === 'number' ? children : undefined);
|
|
87
87
|
|
|
88
88
|
useEffect(() => {
|
|
89
|
-
setShouldAnnounce(false);
|
|
90
|
-
|
|
91
89
|
if (ariaLive === 'off') {
|
|
92
90
|
return;
|
|
93
91
|
}
|
|
94
92
|
|
|
93
|
+
// Reset announcement state, then schedule new announcement
|
|
94
|
+
// This two-step process ensures screen readers re-announce the content
|
|
95
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect -- Deliberately resetting state to force re-announcement for screen readers
|
|
96
|
+
setShouldAnnounce(false);
|
|
97
|
+
|
|
95
98
|
const timeoutId = window.setTimeout(
|
|
96
99
|
() => setShouldAnnounce(true),
|
|
97
100
|
scheduleAnnouncement(ariaLive),
|
|
@@ -134,10 +134,10 @@ const DateInput = ({
|
|
|
134
134
|
const monthBeforeDay = MDY.has(locale);
|
|
135
135
|
const yearFirst = YMD.has(locale);
|
|
136
136
|
|
|
137
|
-
dayLabel
|
|
138
|
-
monthLabel
|
|
139
|
-
yearLabel
|
|
140
|
-
|
|
137
|
+
const resolvedDayLabel = dayLabel || formatMessage(messages.dayLabel);
|
|
138
|
+
const resolvedMonthLabel = monthLabel || formatMessage(messages.monthLabel);
|
|
139
|
+
const resolvedYearLabel = yearLabel || formatMessage(messages.yearLabel);
|
|
140
|
+
const resolvedPlaceholders = {
|
|
141
141
|
day: placeholders?.day || formatMessage(messages.dayPlaceholder),
|
|
142
142
|
month: placeholders?.month || formatMessage(messages.monthLabel),
|
|
143
143
|
year: placeholders?.year || formatMessage(messages.yearPlaceholder),
|
|
@@ -186,14 +186,14 @@ const DateInput = ({
|
|
|
186
186
|
const getSelectElement = () => {
|
|
187
187
|
return (
|
|
188
188
|
<label className="d-flex flex-column">
|
|
189
|
-
<Body type={Typography.BODY_DEFAULT}>{
|
|
189
|
+
<Body type={Typography.BODY_DEFAULT}>{resolvedMonthLabel}</Body>
|
|
190
190
|
<SelectInput
|
|
191
191
|
triggerRef={monthRef}
|
|
192
192
|
id={`${id}:month`}
|
|
193
193
|
parentId={DATE_INPUT_PARENT_ID}
|
|
194
194
|
name="month"
|
|
195
195
|
disabled={disabled}
|
|
196
|
-
placeholder={
|
|
196
|
+
placeholder={resolvedPlaceholders.month}
|
|
197
197
|
items={Array.from({ length: 12 }, (_, index) => ({ type: 'option', value: index }))}
|
|
198
198
|
size={size}
|
|
199
199
|
value={month}
|
|
@@ -295,7 +295,7 @@ const DateInput = ({
|
|
|
295
295
|
return (
|
|
296
296
|
<div className="col-sm-3 tw-date--day">
|
|
297
297
|
<label>
|
|
298
|
-
<Body type={Typography.BODY_DEFAULT}>{
|
|
298
|
+
<Body type={Typography.BODY_DEFAULT}>{resolvedDayLabel}</Body>
|
|
299
299
|
<div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>
|
|
300
300
|
<Input
|
|
301
301
|
ref={dayRef}
|
|
@@ -306,7 +306,7 @@ const DateInput = ({
|
|
|
306
306
|
name="day"
|
|
307
307
|
autoComplete={dayAutoComplete}
|
|
308
308
|
value={displayDay || ''}
|
|
309
|
-
placeholder={
|
|
309
|
+
placeholder={resolvedPlaceholders.day}
|
|
310
310
|
disabled={disabled}
|
|
311
311
|
min={1}
|
|
312
312
|
max={31}
|
|
@@ -323,7 +323,7 @@ const DateInput = ({
|
|
|
323
323
|
return (
|
|
324
324
|
<div className="col-sm-4 tw-date--year">
|
|
325
325
|
<label>
|
|
326
|
-
<Body type={Typography.BODY_DEFAULT}>{
|
|
326
|
+
<Body type={Typography.BODY_DEFAULT}>{resolvedYearLabel}</Body>
|
|
327
327
|
<div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>
|
|
328
328
|
<Input
|
|
329
329
|
ref={yearRef}
|
|
@@ -333,7 +333,7 @@ const DateInput = ({
|
|
|
333
333
|
pattern="[0-9]*"
|
|
334
334
|
name="year"
|
|
335
335
|
autoComplete={yearAutoComplete}
|
|
336
|
-
placeholder={
|
|
336
|
+
placeholder={resolvedPlaceholders.year}
|
|
337
337
|
value={displayYear || ''}
|
|
338
338
|
disabled={disabled}
|
|
339
339
|
min={0}
|
|
@@ -43,11 +43,7 @@ const MonthCalendarTable = ({
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
const isActive = (month: number) => {
|
|
46
|
-
return !!(
|
|
47
|
-
selectedDate &&
|
|
48
|
-
month === selectedDate.getMonth() &&
|
|
49
|
-
viewYear === selectedDate.getFullYear()
|
|
50
|
-
);
|
|
46
|
+
return !!(month === selectedDate?.getMonth() && viewYear === selectedDate.getFullYear());
|
|
51
47
|
};
|
|
52
48
|
|
|
53
49
|
const isThisMonth = (month: number) => {
|
|
@@ -42,7 +42,7 @@ export const AmountInput = ({
|
|
|
42
42
|
const intl = useIntl();
|
|
43
43
|
const { focus, setFocus, visualFocus, setVisualFocus } = useFocus();
|
|
44
44
|
|
|
45
|
-
const [value, setValue] = useState<string>(
|
|
45
|
+
const [value, setValue] = useState<string>(() =>
|
|
46
46
|
amount
|
|
47
47
|
? getFormattedString({
|
|
48
48
|
value: amount,
|
|
@@ -51,6 +51,7 @@ export const AmountInput = ({
|
|
|
51
51
|
})
|
|
52
52
|
: '',
|
|
53
53
|
);
|
|
54
|
+
const prevAmountRef = useRef<string | number | null | undefined>(amount);
|
|
54
55
|
const numericValue = useMemo(() => {
|
|
55
56
|
return getUnformattedNumber({
|
|
56
57
|
value,
|
|
@@ -85,23 +86,28 @@ export const AmountInput = ({
|
|
|
85
86
|
const decimalMode = decimalSeparator && value.includes(decimalSeparator);
|
|
86
87
|
|
|
87
88
|
useEffect(() => {
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
if (prevAmountRef.current !== amount) {
|
|
90
|
+
prevAmountRef.current = amount;
|
|
91
|
+
|
|
92
|
+
// Only update the displayed value if not focused (preserve user input when focused)
|
|
93
|
+
if (!focus) {
|
|
94
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing external prop to internal state when unfocused
|
|
95
|
+
setValue(
|
|
96
|
+
amount
|
|
97
|
+
? getFormattedString({
|
|
98
|
+
value: amount,
|
|
99
|
+
currency,
|
|
100
|
+
locale: intl.locale,
|
|
101
|
+
})
|
|
102
|
+
: '',
|
|
103
|
+
);
|
|
104
|
+
}
|
|
98
105
|
}
|
|
99
|
-
|
|
100
|
-
}, [amount]);
|
|
106
|
+
}, [amount, focus, currency, intl.locale]);
|
|
101
107
|
|
|
102
108
|
useEffect(() => {
|
|
103
109
|
onFocusChange?.(visualFocus);
|
|
104
|
-
}, [visualFocus]);
|
|
110
|
+
}, [onFocusChange, visualFocus]);
|
|
105
111
|
|
|
106
112
|
const shouldReformatAfterUserInput = (newValue: string) => {
|
|
107
113
|
// don't reformat if formatting would wipe out user's input
|
|
@@ -246,6 +252,7 @@ export const AmountInput = ({
|
|
|
246
252
|
const addonContent = useMemo((): string | null | undefined => {
|
|
247
253
|
// because we're using a separate "addon" element for the placeholder decimals, there is a possibility that the input itself will become scrollable
|
|
248
254
|
// and the decimals will appear on top of the input. Safest thing to do is to just hide the addon if there is not enough room
|
|
255
|
+
// eslint-disable-next-line react-hooks/refs -- Reading layout dimensions for overflow detection
|
|
249
256
|
if (isInputPossiblyOverflowing({ ref, value })) {
|
|
250
257
|
return null;
|
|
251
258
|
}
|
|
@@ -284,7 +291,7 @@ export const AmountInput = ({
|
|
|
284
291
|
// whenever decimals are shown, we need to account for the full decimal part for the font size calculation
|
|
285
292
|
value: addonContent ? valueWithFullDecimals : value,
|
|
286
293
|
focus: visualFocus,
|
|
287
|
-
inputElement: ref
|
|
294
|
+
inputElement: ref,
|
|
288
295
|
loading,
|
|
289
296
|
});
|
|
290
297
|
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type CSSProperties,
|
|
3
|
+
type RefObject,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
2
9
|
import { Props as ExpressiveMoneyInputProps } from '../ExpressiveMoneyInput';
|
|
3
10
|
|
|
4
11
|
type InputStyleObject = {
|
|
5
12
|
value: string;
|
|
6
13
|
focus: boolean;
|
|
7
|
-
inputElement: HTMLInputElement | null;
|
|
14
|
+
inputElement: RefObject<HTMLInputElement> | null;
|
|
8
15
|
} & Pick<ExpressiveMoneyInputProps, 'loading'>;
|
|
9
16
|
|
|
10
17
|
export const useInputStyle = ({ value, focus, inputElement, loading }: InputStyleObject) => {
|
|
11
18
|
const initialRender = !useTimeout(300);
|
|
12
|
-
const inputWidth = useFirstDefinedValue(inputElement?.clientWidth, [
|
|
19
|
+
const inputWidth = useFirstDefinedValue(inputElement?.current?.clientWidth, [
|
|
20
|
+
inputElement?.current,
|
|
21
|
+
value,
|
|
22
|
+
]);
|
|
13
23
|
|
|
14
|
-
const getStyle = (): CSSProperties => {
|
|
24
|
+
const getStyle = useCallback((): CSSProperties => {
|
|
15
25
|
const fontSize = getFontSize(value, focus, inputWidth);
|
|
16
26
|
|
|
17
27
|
return {
|
|
@@ -23,13 +33,14 @@ export const useInputStyle = ({ value, focus, inputElement, loading }: InputStyl
|
|
|
23
33
|
transition: initialRender ? 'none' : undefined,
|
|
24
34
|
color: loading ? 'var(--color-interactive-secondary)' : undefined,
|
|
25
35
|
};
|
|
26
|
-
};
|
|
36
|
+
}, [value, focus, inputWidth, loading, initialRender]);
|
|
27
37
|
|
|
28
|
-
const [style, setStyle] = useState(getStyle());
|
|
38
|
+
const [style, setStyle] = useState<CSSProperties>(() => getStyle());
|
|
29
39
|
|
|
30
40
|
useLayoutEffect(() => {
|
|
41
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect -- Computing style based on layout measurements
|
|
31
42
|
setStyle(getStyle());
|
|
32
|
-
}, [value, focus, loading, inputWidth]);
|
|
43
|
+
}, [value, focus, loading, inputWidth, getStyle]);
|
|
33
44
|
|
|
34
45
|
return style;
|
|
35
46
|
};
|
|
@@ -60,10 +71,11 @@ const useFirstDefinedValue = (newValue: number | undefined, dependencies: unknow
|
|
|
60
71
|
|
|
61
72
|
useLayoutEffect(() => {
|
|
62
73
|
if (typeof newValue !== 'undefined' && typeof value === 'undefined') {
|
|
74
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect -- Lazy initialization from prop
|
|
63
75
|
setValue(newValue);
|
|
64
76
|
}
|
|
65
77
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
|
-
}, [...dependencies, value]);
|
|
78
|
+
}, [...dependencies, value, newValue]);
|
|
67
79
|
|
|
68
80
|
return value;
|
|
69
81
|
};
|
|
@@ -15,7 +15,9 @@ export const useSelectionRange = () => {
|
|
|
15
15
|
selection.current = undefined;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
// eslint-disable-next-line react-hooks/refs
|
|
18
19
|
return {
|
|
20
|
+
// eslint-disable-next-line react-hooks/refs
|
|
19
21
|
selection: selection.current,
|
|
20
22
|
handleSelect,
|
|
21
23
|
handleSelectionBlur,
|
package/src/header/Header.tsx
CHANGED
|
@@ -104,7 +104,7 @@ const Header: FunctionComponent<HeaderProps> = React.forwardRef(
|
|
|
104
104
|
useEffect(() => {
|
|
105
105
|
if (as === 'legend' && internalRef.current) {
|
|
106
106
|
const { parentElement } = internalRef.current;
|
|
107
|
-
if (
|
|
107
|
+
if (parentElement?.tagName.toLowerCase() !== 'fieldset') {
|
|
108
108
|
console.warn(
|
|
109
109
|
'Legends should be the first child in a fieldset, and this is not possible when including an action',
|
|
110
110
|
);
|
|
@@ -121,7 +121,7 @@ const Header: FunctionComponent<HeaderProps> = React.forwardRef(
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
return (
|
|
124
|
-
<div {...commonProps} {...props} ref={ref
|
|
124
|
+
<div {...commonProps} {...props} ref={ref}>
|
|
125
125
|
<Title as={as} type={levelTypography} className="np-header__title">
|
|
126
126
|
{title}
|
|
127
127
|
</Title>
|
|
@@ -65,10 +65,12 @@ export function SelectInputBottomSheet({
|
|
|
65
65
|
return (
|
|
66
66
|
<>
|
|
67
67
|
{open ? <PreventScroll /> : null}
|
|
68
|
+
{/* eslint-disable react-hooks/refs -- setReference is a callback ref from floating-ui, safe to pass during render */}
|
|
68
69
|
{renderTrigger?.({
|
|
69
70
|
ref: refs.setReference,
|
|
70
71
|
getInteractionProps: getReferenceProps,
|
|
71
72
|
})}
|
|
73
|
+
{/* eslint-enable react-hooks/refs */}
|
|
72
74
|
|
|
73
75
|
<FloatingPortal>
|
|
74
76
|
<ThemeProvider theme="personal" screenMode={theme === 'personal' ? screenMode : 'light'}>
|
|
@@ -94,6 +96,7 @@ export function SelectInputBottomSheet({
|
|
|
94
96
|
<Fragment
|
|
95
97
|
key={floatingKey} // Force inner state invalidation on open
|
|
96
98
|
>
|
|
99
|
+
{/* eslint-disable react-hooks/refs -- setFloating is a callback ref from floating-ui, safe to pass during render */}
|
|
97
100
|
<TransitionChild
|
|
98
101
|
ref={refs.setFloating}
|
|
99
102
|
as="div"
|
|
@@ -102,6 +105,7 @@ export function SelectInputBottomSheet({
|
|
|
102
105
|
leaveTo="np-bottom-sheet-v2-content--closed"
|
|
103
106
|
{...getFloatingProps()}
|
|
104
107
|
>
|
|
108
|
+
{/* eslint-enable react-hooks/refs */}
|
|
105
109
|
<div className="np-bottom-sheet-v2-header">
|
|
106
110
|
<CloseButton
|
|
107
111
|
size={Size.SMALL}
|