@flipdish/portal-library 8.0.2 → 8.1.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.
- package/README.md +7 -1
- package/dist/components/FlipdishLogoLoader/index.cjs.js +1 -1
- package/dist/components/FlipdishLogoLoader/index.cjs.js.map +1 -1
- package/dist/components/FlipdishLogoLoader/index.d.ts +2 -2
- package/dist/components/FlipdishLogoLoader/index.js +1 -1
- package/dist/components/FlipdishLogoLoader/index.js.map +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.cjs.js +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.cjs.js.map +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.js +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.js.map +1 -1
- package/dist/components/Form/GenericFormContainer/index.cjs.js +1 -1
- package/dist/components/Form/GenericFormContainer/index.cjs.js.map +1 -1
- package/dist/components/Form/GenericFormContainer/index.js +1 -1
- package/dist/components/Form/GenericFormContainer/index.js.map +1 -1
- package/dist/components/Form/GenericTextField/index.cjs.js +1 -1
- package/dist/components/Form/GenericTextField/index.cjs.js.map +1 -1
- package/dist/components/Form/GenericTextField/index.d.ts +2 -2
- package/dist/components/Form/GenericTextField/index.js +1 -1
- package/dist/components/Form/GenericTextField/index.js.map +1 -1
- package/dist/components/PageLayout/index.cjs.js +1 -1
- package/dist/components/PageLayout/index.cjs.js.map +1 -1
- package/dist/components/PageLayout/index.js +1 -1
- package/dist/components/PageLayout/index.js.map +1 -1
- package/dist/components/atoms/BadgeCount/index.cjs.js +1 -1
- package/dist/components/atoms/BadgeCount/index.cjs.js.map +1 -1
- package/dist/components/atoms/BadgeCount/index.d.ts +2 -2
- package/dist/components/atoms/BadgeCount/index.js +1 -1
- package/dist/components/atoms/BadgeCount/index.js.map +1 -1
- package/dist/components/atoms/BadgeDot/index.cjs.js +1 -1
- package/dist/components/atoms/BadgeDot/index.cjs.js.map +1 -1
- package/dist/components/atoms/BadgeDot/index.d.ts +2 -2
- package/dist/components/atoms/BadgeDot/index.js +1 -1
- package/dist/components/atoms/BadgeDot/index.js.map +1 -1
- package/dist/components/atoms/BreadCrumbs/index.cjs.js +1 -1
- package/dist/components/atoms/BreadCrumbs/index.cjs.js.map +1 -1
- package/dist/components/atoms/BreadCrumbs/index.d.ts +5 -5
- package/dist/components/atoms/BreadCrumbs/index.js +1 -1
- package/dist/components/atoms/BreadCrumbs/index.js.map +1 -1
- package/dist/components/atoms/Card/index.d.ts +1 -1
- package/dist/components/atoms/Checkbox/index.js +1 -1
- package/dist/components/atoms/IconButton/index.cjs.js +1 -1
- package/dist/components/atoms/IconButton/index.cjs.js.map +1 -1
- package/dist/components/atoms/IconButton/index.js +1 -1
- package/dist/components/atoms/IconButton/index.js.map +1 -1
- package/dist/components/atoms/IconContainer/index.cjs.js +1 -1
- package/dist/components/atoms/IconContainer/index.cjs.js.map +1 -1
- package/dist/components/atoms/IconContainer/index.d.ts +9 -9
- package/dist/components/atoms/IconContainer/index.js +1 -1
- package/dist/components/atoms/IconContainer/index.js.map +1 -1
- package/dist/components/atoms/LinearProgress/index.cjs.js +1 -1
- package/dist/components/atoms/LinearProgress/index.cjs.js.map +1 -1
- package/dist/components/atoms/LinearProgress/index.d.ts +2 -0
- package/dist/components/atoms/LinearProgress/index.js +1 -1
- package/dist/components/atoms/LinearProgress/index.js.map +1 -1
- package/dist/components/atoms/Switch/index.cjs.js +1 -1
- package/dist/components/atoms/Switch/index.cjs.js.map +1 -1
- package/dist/components/atoms/Switch/index.d.ts +13 -2
- package/dist/components/atoms/Switch/index.js +1 -1
- package/dist/components/atoms/Switch/index.js.map +1 -1
- package/dist/components/atoms/Tab/index.cjs.js +1 -1
- package/dist/components/atoms/Tab/index.cjs.js.map +1 -1
- package/dist/components/atoms/Tab/index.d.ts +6 -5
- package/dist/components/atoms/Tab/index.js +1 -1
- package/dist/components/atoms/Tab/index.js.map +1 -1
- package/dist/components/atoms/Tag/index.cjs.js +1 -1
- package/dist/components/atoms/Tag/index.cjs.js.map +1 -1
- package/dist/components/atoms/Tag/index.js +1 -1
- package/dist/components/atoms/Tag/index.js.map +1 -1
- package/dist/components/molecules/Alert/index.cjs.js +1 -1
- package/dist/components/molecules/Alert/index.cjs.js.map +1 -1
- package/dist/components/molecules/Alert/index.d.ts +35 -16
- package/dist/components/molecules/Alert/index.js +1 -1
- package/dist/components/molecules/Alert/index.js.map +1 -1
- package/dist/components/molecules/AlertSnackbar/index.cjs.js +1 -1
- package/dist/components/molecules/AlertSnackbar/index.cjs.js.map +1 -1
- package/dist/components/molecules/AlertSnackbar/index.d.ts +4 -4
- package/dist/components/molecules/AlertSnackbar/index.js +1 -1
- package/dist/components/molecules/AlertSnackbar/index.js.map +1 -1
- package/dist/components/molecules/Autocomplete/index.cjs.js +1 -1
- package/dist/components/molecules/Autocomplete/index.cjs.js.map +1 -1
- package/dist/components/molecules/Autocomplete/index.js +1 -1
- package/dist/components/molecules/Autocomplete/index.js.map +1 -1
- package/dist/components/molecules/EmptyState/index.cjs.js +1 -1
- package/dist/components/molecules/EmptyState/index.cjs.js.map +1 -1
- package/dist/components/molecules/EmptyState/index.js +1 -1
- package/dist/components/molecules/EmptyState/index.js.map +1 -1
- package/dist/components/molecules/FlipdishStaffContainer/index.cjs.js +1 -1
- package/dist/components/molecules/FlipdishStaffContainer/index.cjs.js.map +1 -1
- package/dist/components/molecules/FlipdishStaffContainer/index.js +1 -1
- package/dist/components/molecules/FlipdishStaffContainer/index.js.map +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBody/index.cjs.js +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBody/index.cjs.js.map +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBody/index.js +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBody/index.js.map +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBodyRow/index.cjs.js +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBodyRow/index.cjs.js.map +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBodyRow/index.js +1 -1
- package/dist/components/molecules/GenericTable/GenericTableBodyRow/index.js.map +1 -1
- package/dist/components/molecules/GenericTable/index.cjs.js +1 -1
- package/dist/components/molecules/GenericTable/index.cjs.js.map +1 -1
- package/dist/components/molecules/GenericTable/index.js +3 -3
- package/dist/components/molecules/GenericTable/index.js.map +1 -1
- package/dist/components/molecules/Modal/index.cjs.js +1 -1
- package/dist/components/molecules/Modal/index.cjs.js.map +1 -1
- package/dist/components/molecules/Modal/index.d.ts +2 -2
- package/dist/components/molecules/Modal/index.js +1 -1
- package/dist/components/molecules/Modal/index.js.map +1 -1
- package/dist/components/molecules/Pagination/index.cjs.js +1 -1
- package/dist/components/molecules/Pagination/index.cjs.js.map +1 -1
- package/dist/components/molecules/Pagination/index.js +1 -1
- package/dist/components/molecules/Pagination/index.js.map +1 -1
- package/dist/components/molecules/ProgressStepper/index.cjs.js +1 -1
- package/dist/components/molecules/ProgressStepper/index.cjs.js.map +1 -1
- package/dist/components/molecules/ProgressStepper/index.js +1 -1
- package/dist/components/molecules/ProgressStepper/index.js.map +1 -1
- package/dist/components/molecules/RadioGroup/index.cjs.js +1 -1
- package/dist/components/molecules/RadioGroup/index.cjs.js.map +1 -1
- package/dist/components/molecules/RadioGroup/index.js +1 -1
- package/dist/components/molecules/RadioGroup/index.js.map +1 -1
- package/dist/components/molecules/Rating/index.cjs.js +1 -1
- package/dist/components/molecules/Rating/index.cjs.js.map +1 -1
- package/dist/components/molecules/Rating/index.js +1 -1
- package/dist/components/molecules/Rating/index.js.map +1 -1
- package/dist/components/molecules/TextBlock/index.cjs.js +1 -1
- package/dist/components/molecules/TextBlock/index.cjs.js.map +1 -1
- package/dist/components/molecules/TextBlock/index.d.ts +1 -1
- package/dist/components/molecules/TextBlock/index.js +1 -1
- package/dist/components/molecules/TextBlock/index.js.map +1 -1
- package/dist/components/organisms/FileUpload/components/FileDropZone.cjs.js +1 -1
- package/dist/components/organisms/FileUpload/components/FileDropZone.cjs.js.map +1 -1
- package/dist/components/organisms/FileUpload/components/FileDropZone.js +1 -1
- package/dist/components/organisms/FileUpload/components/FileDropZone.js.map +1 -1
- package/dist/components/organisms/ImageUploadWidget/components/ImageDropZone.cjs.js +1 -1
- package/dist/components/organisms/ImageUploadWidget/components/ImageDropZone.cjs.js.map +1 -1
- package/dist/components/organisms/ImageUploadWidget/components/ImageDropZone.js +1 -1
- package/dist/components/organisms/ImageUploadWidget/components/ImageDropZone.js.map +1 -1
- package/dist/components/organisms/ImageUploadWidget/index.cjs.js +1 -1
- package/dist/components/organisms/ImageUploadWidget/index.cjs.js.map +1 -1
- package/dist/components/organisms/ImageUploadWidget/index.js +1 -1
- package/dist/components/organisms/ImageUploadWidget/index.js.map +1 -1
- package/dist/mocks/msw/handlers.cjs.js +1 -1
- package/dist/mocks/msw/handlers.d.ts +1 -1
- package/dist/mocks/msw/handlers.js +1 -1
- package/dist/mocks/msw/server.cjs.js +1 -1
- package/dist/mocks/msw/server.d.ts +1 -1
- package/dist/mocks/msw/server.js +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/HttpResponse.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/HttpResponse.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/SetupApi.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/SetupApi.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/HttpHandler.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/HttpHandler.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/RequestHandler.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/RequestHandler.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/http.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/http.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/index.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/index.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/isCommonAssetRequest.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/isCommonAssetRequest.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/HttpResponse/decorators.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/HttpResponse/decorators.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/cookieStore.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/cookieStore.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/executeHandlers.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/executeHandlers.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/handleRequest.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/handleRequest.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/Disposable.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/Disposable.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/checkGlobals.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/checkGlobals.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/devUtils.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/devUtils.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/getCallFrame.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/getCallFrame.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isHandlerKind.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isHandlerKind.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isIterable.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isIterable.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isObject.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isObject.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isStringEqual.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isStringEqual.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/jsonParse.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/jsonParse.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/mergeRight.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/mergeRight.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/pipeEvents.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/pipeEvents.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/toReadonlyArray.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/toReadonlyArray.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getStatusCodeColor.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getStatusCodeColor.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getTimestamp.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getTimestamp.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeRequest.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeRequest.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeResponse.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeResponse.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/matchRequestUrl.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/matchRequestUrl.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/normalizePath.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/normalizePath.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/getRequestCookies.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/getRequestCookies.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/onUnhandledRequest.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/onUnhandledRequest.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/storeResponseCookies.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/storeResponseCookies.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/toPublicUrl.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/toPublicUrl.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/cleanUrl.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/cleanUrl.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/getAbsoluteUrl.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/getAbsoluteUrl.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/isAbsoluteUrl.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/isAbsoluteUrl.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/handleWebSocketEvent.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/handleWebSocketEvent.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/webSocketInterceptor.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/webSocketInterceptor.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/node/index.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/node/index.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/cookie.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/cookie.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/statuses.cjs.js.map +1 -1
- package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/statuses.js.map +1 -1
- package/dist/themes/flipdishPublicTheme.cjs.js +1 -1
- package/dist/themes/flipdishPublicTheme.cjs.js.map +1 -1
- package/dist/themes/flipdishPublicTheme.js +1 -1
- package/dist/themes/flipdishPublicTheme.js.map +1 -1
- package/dist/themes/overrides/autocompleteOverrides.js +1 -1
- package/dist/themes/overrides/chipOverrides.js +1 -1
- package/dist/themes/overrides/formControlLabelOverrides.js +1 -1
- package/dist/themes/overrides/formHelperTextOverrides.js +1 -1
- package/dist/themes/overrides/formLabelOverrides.js +1 -1
- package/dist/themes/overrides/inputBaseOverrides.js +1 -1
- package/dist/themes/overrides/inputLabelOverrides.js +1 -1
- package/dist/themes/overrides/listItemTextOverrides.js +1 -1
- package/dist/themes/overrides/listSubheaderOverrides.js +1 -1
- package/dist/themes/overrides/menuItemOverrides.js +1 -1
- package/package.json +1 -1
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/HttpResponse-CVs3ngx3.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/HttpResponse.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/HttpResponse.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/SetupApi.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/SetupApi.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/SetupApi.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/HttpHandler.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/HttpHandler.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/HttpHandler.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/RequestHandler.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/RequestHandler.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/handlers/WebSocketHandler.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/http.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/http.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/index.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/index.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/isCommonAssetRequest.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/isCommonAssetRequest.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/sharedOptions.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/typeUtils.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/HttpResponse/decorators.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/HttpResponse/decorators.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/cookieStore.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/cookieStore.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/executeHandlers.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/executeHandlers.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/handleRequest.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/handleRequest.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/Disposable.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/Disposable.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/Disposable.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/checkGlobals.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/checkGlobals.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/devUtils.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/devUtils.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/getCallFrame.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/getCallFrame.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isHandlerKind.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isHandlerKind.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isIterable.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isIterable.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isIterable.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isObject.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isObject.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isStringEqual.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/isStringEqual.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/jsonParse.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/jsonParse.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/mergeRight.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/mergeRight.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/pipeEvents.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/pipeEvents.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/toReadonlyArray.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/internal/toReadonlyArray.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getStatusCodeColor.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getStatusCodeColor.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getTimestamp.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/getTimestamp.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeRequest.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeRequest.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeResponse.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/logging/serializeResponse.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/matchRequestUrl.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/matchRequestUrl.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/matchRequestUrl.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/normalizePath.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/matching/normalizePath.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/getRequestCookies.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/getRequestCookies.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/onUnhandledRequest.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/onUnhandledRequest.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/onUnhandledRequest.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/storeResponseCookies.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/storeResponseCookies.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/toPublicUrl.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/request/toPublicUrl.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/cleanUrl.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/cleanUrl.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/getAbsoluteUrl.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/getAbsoluteUrl.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/isAbsoluteUrl.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/utils/url/isAbsoluteUrl.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/handleWebSocketEvent.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/handleWebSocketEvent.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/webSocketInterceptor.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/core/ws/webSocketInterceptor.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/node/index.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/node/index.d.d.ts +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/node/index.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/cookie.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/cookie.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/statuses.cjs.js +0 -0
- /package/dist/node_modules/.pnpm/{msw@2.12.7_@types_node@20.19.28_typescript@5.4.5 → msw@2.12.7_@types_node@20.19.30_typescript@5.4.5}/node_modules/msw/lib/shims/statuses.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/AlertSnackbar/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo, useCallback, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Snackbar from '@mui/material/Snackbar';\nimport { styled, type Theme } from '@mui/material/styles';\n\nimport CancelIcon from '@fd/icons/Cancel';\nimport DiamondIcon from '@fd/icons/Diamond';\n\nimport Button from '../../atoms/Button';\nimport type { ButtonType } from '../../atoms/Button/getButtonStyles';\nimport ButtonGroup from '../ButtonGroup';\n\n/** Action button configuration */\nexport interface ActionButton {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n 'data-testid'?: string;\n}\n\n/** Text link configuration */\nexport interface TextLink {\n /** Text label for the link */\n label: string;\n /** Callback function when the link is clicked */\n onClick: () => void;\n /** Test ID for the link */\n 'data-testid'?: string;\n}\n\n/** Props for the AlertSnackbar component */\nexport interface AlertSnackbarProps {\n /** Content of the alert snackbar */\n content: string;\n /** Callback function when the alert snackbar is closed */\n onClose?: () => void;\n /** Action buttons configuration - supports Primary, Secondary, Tertiary buttons via ButtonGroup */\n actions?: ActionButton[];\n /** Text link configuration - separate from action buttons */\n textLink?: TextLink;\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n /** Whether the snackbar is open */\n open?: boolean;\n /** Duration in milliseconds the snackbar should be displayed */\n autoHideDuration?: number;\n}\n\nconst getDefaultColors = (theme: Theme) => {\n return {\n bg: theme.palette.semantic.fill['fill-strong'],\n text: theme.palette.semantic.text['text-inverse-strong'],\n border: theme.palette.semantic.stroke['stroke-strong'],\n };\n};\n\nconst getDefaultIconColor = (theme: Theme): string => {\n return theme.palette.semantic.icon['icon-inverse-strong'];\n};\n\nconst StyledContent = styled(Box)(({ theme }) => {\n const colors = getDefaultColors(theme);\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(3),\n padding: theme.spacing(1.5, 2),\n backgroundColor: colors.bg,\n color: colors.text,\n border: `1px solid ${colors.border}`,\n borderRadius: theme.radius['radius-8'],\n role: 'alert',\n };\n});\n\nconst StyledText = styled(Box)(({ theme }) => ({\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n flexShrink: 1,\n minWidth: 0,\n}));\n\nconst StyledIcon = styled(Box)({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n});\n\nconst StyledIconWrapper = styled(StyledIcon)(({ theme }) => ({\n color: getDefaultIconColor(theme),\n}));\n\nconst StyledContentLeft = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flex: 1,\n minWidth: 0,\n}));\n\nconst StyledActions = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n alignItems: 'center',\n flexShrink: 0,\n}));\n\nconst StyledCloseButton = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n color: 'inherit',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: theme.spacing(0.5),\n margin: theme.spacing(0, -0.5),\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledTextLink = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n textDecoration: 'underline',\n textUnderlineOffset: '25%',\n textUnderlinePosition: 'from-font',\n cursor: 'pointer',\n color: 'inherit',\n padding: 0,\n whiteSpace: 'nowrap',\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n borderRadius: theme.radius['radius-8'],\n },\n}));\n\nconst SnackbarPaper = styled(Box)({\n maxWidth: '60vw',\n});\n\n/**\n * AlertSnackbar component is used to display important notifications to users.\n * It can include optional action buttons (via ButtonGroup supporting Primary, Secondary, Tertiary variants)\n * and/or a text link component.\n * The component wraps MUI's Snackbar component to provide a consistent,\n * accessible notification experience. It is wrapped with React.memo to optimize\n * performance by preventing unnecessary re-renders when props haven't changed.\n * Uses semantic design tokens for colors and typography to ensure proper light/dark mode support.\n */\nconst AlertSnackbar = memo(\n ({\n content,\n onClose,\n className,\n 'data-testid': dataTestId,\n actions,\n textLink,\n open: controlledOpen,\n autoHideDuration = 5000,\n }: AlertSnackbarProps) => {\n // Use internal state when not controlled\n const [internalOpen, setInternalOpen] = useState(controlledOpen ?? true);\n // When controlled (open prop is defined), use it; otherwise use internal state\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n const handleClose = useCallback(\n (_event?: Event | React.SyntheticEvent, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n // Update internal state for uncontrolled mode\n if (controlledOpen === undefined) {\n setInternalOpen(false);\n }\n // Call external callback if provided\n onClose?.();\n },\n [onClose, controlledOpen],\n );\n\n const renderActions = (): React.ReactNode => {\n if (!actions || actions.length === 0) {\n return undefined;\n }\n\n // Sort actions: Tertiary (left), Secondary (middle), Primary (right)\n const sortedActions = [...actions].sort((a, b) => {\n const orderMap: Record<ButtonType, number> = {\n tertiary: 0,\n secondary: 1,\n primary: 2,\n };\n const aType = a.type ?? 'primary';\n const bType = b.type ?? 'primary';\n return orderMap[aType] - orderMap[bType];\n });\n\n return (\n <ButtonGroup align=\"right\" size=\"small\">\n {sortedActions.map((action) => {\n const actionTestId =\n action['data-testid'] ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <Button\n key={actionTestId}\n aria-label={action.label}\n data-testid={actionTestId}\n fdKey={action.label}\n onClick={() => {\n action.onClick();\n handleClose();\n }}\n tone=\"inverse\"\n variant={action.type ?? 'primary'}\n >\n {action.label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n };\n\n const renderTextLink = (): React.ReactNode => {\n if (!textLink) {\n return undefined;\n }\n\n const linkTestId =\n textLink['data-testid'] ?? `text-link-${textLink.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <StyledTextLink\n aria-label={textLink.label}\n data-testid={linkTestId}\n onClick={() => {\n textLink.onClick();\n handleClose();\n }}\n type=\"button\"\n >\n {textLink.label}\n </StyledTextLink>\n );\n };\n\n return (\n <Snackbar\n anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}\n autoHideDuration={autoHideDuration}\n className={className}\n data-testid={dataTestId}\n onClose={handleClose}\n open={isOpen}\n >\n <SnackbarPaper>\n <StyledContent role=\"alert\">\n <StyledContentLeft>\n <StyledIconWrapper>\n <DiamondIcon />\n </StyledIconWrapper>\n <StyledText>{content}</StyledText>\n </StyledContentLeft>\n <StyledActions>\n {textLink && renderTextLink()}\n {actions && actions.length > 0 && renderActions()}\n {onClose && (\n <StyledCloseButton\n aria-label=\"Close notification\"\n onClick={handleClose}\n type=\"button\"\n >\n <CancelIcon />\n </StyledCloseButton>\n )}\n </StyledActions>\n </StyledContent>\n </SnackbarPaper>\n </Snackbar>\n );\n },\n);\n\nAlertSnackbar.displayName = 'AlertSnackbar';\n\nexport default AlertSnackbar;\n"],"names":["getDefaultIconColor","theme","palette","semantic","icon","StyledContent","styled","Box","colors","bg","fill","text","border","stroke","getDefaultColors","display","alignItems","justifyContent","gap","spacing","padding","backgroundColor","color","borderRadius","radius","role","StyledText","fontSize","typography","b1Weak","lineHeight","fontFamily","fontWeight","letterSpacing","flexShrink","minWidth","StyledIcon","StyledIconWrapper","StyledContentLeft","flex","StyledActions","StyledCloseButton","background","cursor","margin","opacity","outline","outlineOffset","StyledTextLink","textDecoration","textUnderlineOffset","textUnderlinePosition","whiteSpace","SnackbarPaper","maxWidth","AlertSnackbar","memo","content","onClose","className","dataTestId","actions","textLink","open","controlledOpen","autoHideDuration","internalOpen","setInternalOpen","useState","isOpen","undefined","handleClose","useCallback","_event","reason","_jsx","Snackbar","anchorOrigin","horizontal","vertical","children","_jsxs","DiamondIcon","linkTestId","label","replace","toLowerCase","onClick","type","renderTextLink","length","sortedActions","sort","a","b","orderMap","tertiary","secondary","primary","aType","bType","ButtonGroup","align","size","map","action","actionTestId","Button","fdKey","tone","variant","renderActions","CancelIcon","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/AlertSnackbar/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo, useCallback, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Snackbar from '@mui/material/Snackbar';\nimport { styled, type Theme } from '@mui/material/styles';\n\nimport CancelIcon from '@fd/icons/Cancel';\nimport DiamondIcon from '@fd/icons/Diamond';\n\nimport Button from '../../atoms/Button';\nimport type { ButtonType } from '../../atoms/Button/getButtonStyles';\nimport ButtonGroup from '../ButtonGroup';\n\n/** Action button configuration */\nexport interface ActionButton {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n fdKey?: string;\n}\n\n/** Text link configuration */\nexport interface TextLink {\n /** Text label for the link */\n label: string;\n /** Callback function when the link is clicked */\n onClick: () => void;\n /** Test ID for the link */\n fdKey?: string;\n}\n\n/** Props for the AlertSnackbar component */\nexport interface AlertSnackbarProps {\n /** Content of the alert snackbar */\n content: string;\n /** Callback function when the alert snackbar is closed */\n onClose?: () => void;\n /** Action buttons configuration - supports Primary, Secondary, Tertiary buttons via ButtonGroup */\n actions?: ActionButton[];\n /** Text link configuration - separate from action buttons */\n textLink?: TextLink;\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n fdKey?: string;\n /** Whether the snackbar is open */\n open?: boolean;\n /** Duration in milliseconds the snackbar should be displayed */\n autoHideDuration?: number;\n}\n\nconst getDefaultColors = (theme: Theme) => {\n return {\n bg: theme.palette.semantic.fill['fill-strong'],\n text: theme.palette.semantic.text['text-inverse-strong'],\n border: theme.palette.semantic.stroke['stroke-strong'],\n };\n};\n\nconst getDefaultIconColor = (theme: Theme): string => {\n return theme.palette.semantic.icon['icon-inverse-strong'];\n};\n\nconst StyledContent = styled(Box)(({ theme }) => {\n const colors = getDefaultColors(theme);\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(3),\n padding: theme.spacing(1.5, 2),\n backgroundColor: colors.bg,\n color: colors.text,\n border: `1px solid ${colors.border}`,\n borderRadius: theme.radius['radius-8'],\n role: 'alert',\n };\n});\n\nconst StyledText = styled(Box)(({ theme }) => ({\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n flexShrink: 1,\n minWidth: 0,\n}));\n\nconst StyledIcon = styled(Box)({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n});\n\nconst StyledIconWrapper = styled(StyledIcon)(({ theme }) => ({\n color: getDefaultIconColor(theme),\n}));\n\nconst StyledContentLeft = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flex: 1,\n minWidth: 0,\n}));\n\nconst StyledActions = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n alignItems: 'center',\n flexShrink: 0,\n}));\n\nconst StyledCloseButton = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n color: 'inherit',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: theme.spacing(0.5),\n margin: theme.spacing(0, -0.5),\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledTextLink = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n textDecoration: 'underline',\n textUnderlineOffset: '25%',\n textUnderlinePosition: 'from-font',\n cursor: 'pointer',\n color: 'inherit',\n padding: 0,\n whiteSpace: 'nowrap',\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n borderRadius: theme.radius['radius-8'],\n },\n}));\n\nconst SnackbarPaper = styled(Box)({\n maxWidth: '60vw',\n});\n\n/**\n * AlertSnackbar component is used to display important notifications to users.\n * It can include optional action buttons (via ButtonGroup supporting Primary, Secondary, Tertiary variants)\n * and/or a text link component.\n * The component wraps MUI's Snackbar component to provide a consistent,\n * accessible notification experience. It is wrapped with React.memo to optimize\n * performance by preventing unnecessary re-renders when props haven't changed.\n * Uses semantic design tokens for colors and typography to ensure proper light/dark mode support.\n */\nconst AlertSnackbar = memo(\n ({\n content,\n onClose,\n className,\n fdKey,\n actions,\n textLink,\n open: controlledOpen,\n autoHideDuration = 5000,\n }: AlertSnackbarProps) => {\n // Use internal state when not controlled\n const [internalOpen, setInternalOpen] = useState(controlledOpen ?? true);\n // When controlled (open prop is defined), use it; otherwise use internal state\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n const handleClose = useCallback(\n (_event?: Event | React.SyntheticEvent, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n // Update internal state for uncontrolled mode\n if (controlledOpen === undefined) {\n setInternalOpen(false);\n }\n // Call external callback if provided\n onClose?.();\n },\n [onClose, controlledOpen],\n );\n\n const renderActions = (): React.ReactNode => {\n if (!actions || actions.length === 0) {\n return undefined;\n }\n\n // Sort actions: Tertiary (left), Secondary (middle), Primary (right)\n const sortedActions = [...actions].sort((a, b) => {\n const orderMap: Record<ButtonType, number> = {\n tertiary: 0,\n secondary: 1,\n primary: 2,\n };\n const aType = a.type ?? 'primary';\n const bType = b.type ?? 'primary';\n return orderMap[aType] - orderMap[bType];\n });\n\n return (\n <ButtonGroup align=\"right\" size=\"small\">\n {sortedActions.map((action) => {\n const actionTestId =\n action.fdKey ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <Button\n key={actionTestId}\n aria-label={action.label}\n fdKey={actionTestId}\n onClick={() => {\n action.onClick();\n handleClose();\n }}\n tone=\"inverse\"\n variant={action.type ?? 'primary'}\n >\n {action.label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n };\n\n const renderTextLink = (): React.ReactNode => {\n if (!textLink) {\n return undefined;\n }\n\n const linkTestId = textLink.fdKey ?? `text-link-${textLink.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <StyledTextLink\n aria-label={textLink.label}\n data-fd={linkTestId}\n onClick={() => {\n textLink.onClick();\n handleClose();\n }}\n type=\"button\"\n >\n {textLink.label}\n </StyledTextLink>\n );\n };\n\n return (\n <Snackbar\n anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}\n autoHideDuration={autoHideDuration}\n className={className}\n data-fd={fdKey}\n onClose={handleClose}\n open={isOpen}\n >\n <SnackbarPaper>\n <StyledContent role=\"alert\">\n <StyledContentLeft>\n <StyledIconWrapper>\n <DiamondIcon />\n </StyledIconWrapper>\n <StyledText>{content}</StyledText>\n </StyledContentLeft>\n <StyledActions>\n {textLink && renderTextLink()}\n {actions && actions.length > 0 && renderActions()}\n {onClose && (\n <StyledCloseButton aria-label=\"Close notification\" onClick={handleClose} type=\"button\">\n <CancelIcon />\n </StyledCloseButton>\n )}\n </StyledActions>\n </StyledContent>\n </SnackbarPaper>\n </Snackbar>\n );\n },\n);\n\nAlertSnackbar.displayName = 'AlertSnackbar';\n\nexport default AlertSnackbar;\n"],"names":["getDefaultIconColor","theme","palette","semantic","icon","StyledContent","styled","Box","colors","bg","fill","text","border","stroke","getDefaultColors","display","alignItems","justifyContent","gap","spacing","padding","backgroundColor","color","borderRadius","radius","role","StyledText","fontSize","typography","b1Weak","lineHeight","fontFamily","fontWeight","letterSpacing","flexShrink","minWidth","StyledIcon","StyledIconWrapper","StyledContentLeft","flex","StyledActions","StyledCloseButton","background","cursor","margin","opacity","outline","outlineOffset","StyledTextLink","textDecoration","textUnderlineOffset","textUnderlinePosition","whiteSpace","SnackbarPaper","maxWidth","AlertSnackbar","memo","content","onClose","className","fdKey","actions","textLink","open","controlledOpen","autoHideDuration","internalOpen","setInternalOpen","useState","isOpen","undefined","handleClose","useCallback","_event","reason","_jsx","Snackbar","anchorOrigin","horizontal","vertical","children","_jsxs","DiamondIcon","linkTestId","label","replace","toLowerCase","onClick","type","renderTextLink","length","sortedActions","sort","a","b","orderMap","tertiary","secondary","primary","aType","bType","ButtonGroup","align","size","map","action","actionTestId","Button","tone","variant","renderActions","CancelIcon","displayName"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ interface ActionButton {
|
|
|
11
11
|
/** Callback function when the action button is clicked */
|
|
12
12
|
onClick: () => void;
|
|
13
13
|
/** Test ID for the action button */
|
|
14
|
-
|
|
14
|
+
fdKey?: string;
|
|
15
15
|
}
|
|
16
16
|
/** Text link configuration */
|
|
17
17
|
interface TextLink {
|
|
@@ -20,7 +20,7 @@ interface TextLink {
|
|
|
20
20
|
/** Callback function when the link is clicked */
|
|
21
21
|
onClick: () => void;
|
|
22
22
|
/** Test ID for the link */
|
|
23
|
-
|
|
23
|
+
fdKey?: string;
|
|
24
24
|
}
|
|
25
25
|
/** Props for the AlertSnackbar component */
|
|
26
26
|
interface AlertSnackbarProps {
|
|
@@ -35,7 +35,7 @@ interface AlertSnackbarProps {
|
|
|
35
35
|
/** Additional CSS class names */
|
|
36
36
|
className?: string;
|
|
37
37
|
/** Test ID for testing and automation */
|
|
38
|
-
|
|
38
|
+
fdKey?: string;
|
|
39
39
|
/** Whether the snackbar is open */
|
|
40
40
|
open?: boolean;
|
|
41
41
|
/** Duration in milliseconds the snackbar should be displayed */
|
|
@@ -50,7 +50,7 @@ interface AlertSnackbarProps {
|
|
|
50
50
|
* performance by preventing unnecessary re-renders when props haven't changed.
|
|
51
51
|
* Uses semantic design tokens for colors and typography to ensure proper light/dark mode support.
|
|
52
52
|
*/
|
|
53
|
-
declare const AlertSnackbar: react.MemoExoticComponent<({ content, onClose, className,
|
|
53
|
+
declare const AlertSnackbar: react.MemoExoticComponent<({ content, onClose, className, fdKey, actions, textLink, open: controlledOpen, autoHideDuration, }: AlertSnackbarProps) => react_jsx_runtime.JSX.Element>;
|
|
54
54
|
|
|
55
55
|
export { AlertSnackbar as default };
|
|
56
56
|
export type { ActionButton, AlertSnackbarProps, TextLink };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{memo as
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{memo as n,useState as i,useCallback as r}from"react";import o from"@mui/material/Box";import a from"@mui/material/Snackbar";import{styled as l}from"@mui/material/styles";import s from"../../../icons/Cancel/index.js";import c from"../../../icons/Diamond/index.js";import{Button as p}from"../../atoms/Button/index.js";import d from"../ButtonGroup/index.js";const m=e=>e.palette.semantic.icon["icon-inverse-strong"],f=l(o)((({theme:e})=>{const t=(e=>({bg:e.palette.semantic.fill["fill-strong"],text:e.palette.semantic.text["text-inverse-strong"],border:e.palette.semantic.stroke["stroke-strong"]}))(e);return{display:"flex",alignItems:"center",justifyContent:"space-between",gap:e.spacing(3),padding:e.spacing(1.5,2),backgroundColor:t.bg,color:t.text,border:`1px solid ${t.border}`,borderRadius:e.radius["radius-8"],role:"alert"}})),g=l(o)((({theme:e})=>({fontSize:e.typography.b1Weak.fontSize,lineHeight:e.typography.b1Weak.lineHeight,fontFamily:e.typography.b1Weak.fontFamily,fontWeight:e.typography.b1Weak.fontWeight,letterSpacing:e.typography.b1Weak.letterSpacing,flexShrink:1,minWidth:0}))),h=l(o)({display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}),y=l(h)((({theme:e})=>({color:m(e)}))),u=l(o)((({theme:e})=>({display:"flex",alignItems:"center",gap:e.spacing(1),flex:1,minWidth:0}))),b=l(o)((({theme:e})=>({display:"flex",gap:e.spacing(1),alignItems:"center",flexShrink:0}))),k=l("button")((({theme:e})=>({background:"none",border:"none",color:"inherit",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",padding:e.spacing(.5),margin:e.spacing(0,-.5),"&:hover":{opacity:.8},"&:focus":{outline:`2px solid ${e.palette.semantic.stroke["stroke-focus"]}`,outlineOffset:"2px"}}))),x=l("button")((({theme:e})=>({background:"none",border:"none",fontSize:e.typography.b1Weak.fontSize,lineHeight:e.typography.b1Weak.lineHeight,fontFamily:e.typography.b1Weak.fontFamily,fontWeight:e.typography.b1Weak.fontWeight,letterSpacing:e.typography.b1Weak.letterSpacing,textDecoration:"underline",textUnderlineOffset:"25%",textUnderlinePosition:"from-font",cursor:"pointer",color:"inherit",padding:0,whiteSpace:"nowrap","&:hover":{opacity:.8},"&:focus":{outline:`2px solid ${e.palette.semantic.stroke["stroke-focus"]}`,outlineOffset:"2px",borderRadius:e.radius["radius-8"]}}))),W=l(o)({maxWidth:"60vw"}),C=n((({content:n,onClose:o,className:l,fdKey:m,actions:h,textLink:C,open:S,autoHideDuration:v=5e3})=>{const[j,w]=i(S??!0),z=void 0!==S?S:j,H=r(((e,t)=>{"clickaway"!==t&&(void 0===S&&w(!1),o?.())}),[o,S]);return e(a,{anchorOrigin:{horizontal:"center",vertical:"bottom"},autoHideDuration:v,className:l,"data-fd":m,onClose:H,open:z,children:e(W,{children:t(f,{role:"alert",children:[t(u,{children:[e(y,{children:e(c,{})}),e(g,{children:n})]}),t(b,{children:[C&&(()=>{if(!C)return;const t=C.fdKey??`text-link-${C.label.replace(/\s+/g,"-").toLowerCase()}`;return e(x,{"aria-label":C.label,"data-fd":t,onClick:()=>{C.onClick(),H()},type:"button",children:C.label})})(),h&&h.length>0&&(()=>{if(!h||0===h.length)return;const t=[...h].sort(((e,t)=>{const n={tertiary:0,secondary:1,primary:2},i=e.type??"primary",r=t.type??"primary";return n[i]-n[r]}));return e(d,{align:"right",size:"small",children:t.map((t=>{const n=t.fdKey??`action-button-${t.label.replace(/\s+/g,"-").toLowerCase()}`;return e(p,{"aria-label":t.label,fdKey:n,onClick:()=>{t.onClick(),H()},tone:"inverse",variant:t.type??"primary",children:t.label},n)}))})})(),o&&e(k,{"aria-label":"Close notification",onClick:H,type:"button",children:e(s,{})})]})]})})})}));C.displayName="AlertSnackbar";export{C as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/AlertSnackbar/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo, useCallback, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Snackbar from '@mui/material/Snackbar';\nimport { styled, type Theme } from '@mui/material/styles';\n\nimport CancelIcon from '@fd/icons/Cancel';\nimport DiamondIcon from '@fd/icons/Diamond';\n\nimport Button from '../../atoms/Button';\nimport type { ButtonType } from '../../atoms/Button/getButtonStyles';\nimport ButtonGroup from '../ButtonGroup';\n\n/** Action button configuration */\nexport interface ActionButton {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n 'data-testid'?: string;\n}\n\n/** Text link configuration */\nexport interface TextLink {\n /** Text label for the link */\n label: string;\n /** Callback function when the link is clicked */\n onClick: () => void;\n /** Test ID for the link */\n 'data-testid'?: string;\n}\n\n/** Props for the AlertSnackbar component */\nexport interface AlertSnackbarProps {\n /** Content of the alert snackbar */\n content: string;\n /** Callback function when the alert snackbar is closed */\n onClose?: () => void;\n /** Action buttons configuration - supports Primary, Secondary, Tertiary buttons via ButtonGroup */\n actions?: ActionButton[];\n /** Text link configuration - separate from action buttons */\n textLink?: TextLink;\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n /** Whether the snackbar is open */\n open?: boolean;\n /** Duration in milliseconds the snackbar should be displayed */\n autoHideDuration?: number;\n}\n\nconst getDefaultColors = (theme: Theme) => {\n return {\n bg: theme.palette.semantic.fill['fill-strong'],\n text: theme.palette.semantic.text['text-inverse-strong'],\n border: theme.palette.semantic.stroke['stroke-strong'],\n };\n};\n\nconst getDefaultIconColor = (theme: Theme): string => {\n return theme.palette.semantic.icon['icon-inverse-strong'];\n};\n\nconst StyledContent = styled(Box)(({ theme }) => {\n const colors = getDefaultColors(theme);\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(3),\n padding: theme.spacing(1.5, 2),\n backgroundColor: colors.bg,\n color: colors.text,\n border: `1px solid ${colors.border}`,\n borderRadius: theme.radius['radius-8'],\n role: 'alert',\n };\n});\n\nconst StyledText = styled(Box)(({ theme }) => ({\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n flexShrink: 1,\n minWidth: 0,\n}));\n\nconst StyledIcon = styled(Box)({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n});\n\nconst StyledIconWrapper = styled(StyledIcon)(({ theme }) => ({\n color: getDefaultIconColor(theme),\n}));\n\nconst StyledContentLeft = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flex: 1,\n minWidth: 0,\n}));\n\nconst StyledActions = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n alignItems: 'center',\n flexShrink: 0,\n}));\n\nconst StyledCloseButton = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n color: 'inherit',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: theme.spacing(0.5),\n margin: theme.spacing(0, -0.5),\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledTextLink = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n textDecoration: 'underline',\n textUnderlineOffset: '25%',\n textUnderlinePosition: 'from-font',\n cursor: 'pointer',\n color: 'inherit',\n padding: 0,\n whiteSpace: 'nowrap',\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n borderRadius: theme.radius['radius-8'],\n },\n}));\n\nconst SnackbarPaper = styled(Box)({\n maxWidth: '60vw',\n});\n\n/**\n * AlertSnackbar component is used to display important notifications to users.\n * It can include optional action buttons (via ButtonGroup supporting Primary, Secondary, Tertiary variants)\n * and/or a text link component.\n * The component wraps MUI's Snackbar component to provide a consistent,\n * accessible notification experience. It is wrapped with React.memo to optimize\n * performance by preventing unnecessary re-renders when props haven't changed.\n * Uses semantic design tokens for colors and typography to ensure proper light/dark mode support.\n */\nconst AlertSnackbar = memo(\n ({\n content,\n onClose,\n className,\n 'data-testid': dataTestId,\n actions,\n textLink,\n open: controlledOpen,\n autoHideDuration = 5000,\n }: AlertSnackbarProps) => {\n // Use internal state when not controlled\n const [internalOpen, setInternalOpen] = useState(controlledOpen ?? true);\n // When controlled (open prop is defined), use it; otherwise use internal state\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n const handleClose = useCallback(\n (_event?: Event | React.SyntheticEvent, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n // Update internal state for uncontrolled mode\n if (controlledOpen === undefined) {\n setInternalOpen(false);\n }\n // Call external callback if provided\n onClose?.();\n },\n [onClose, controlledOpen],\n );\n\n const renderActions = (): React.ReactNode => {\n if (!actions || actions.length === 0) {\n return undefined;\n }\n\n // Sort actions: Tertiary (left), Secondary (middle), Primary (right)\n const sortedActions = [...actions].sort((a, b) => {\n const orderMap: Record<ButtonType, number> = {\n tertiary: 0,\n secondary: 1,\n primary: 2,\n };\n const aType = a.type ?? 'primary';\n const bType = b.type ?? 'primary';\n return orderMap[aType] - orderMap[bType];\n });\n\n return (\n <ButtonGroup align=\"right\" size=\"small\">\n {sortedActions.map((action) => {\n const actionTestId =\n action['data-testid'] ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <Button\n key={actionTestId}\n aria-label={action.label}\n data-testid={actionTestId}\n fdKey={action.label}\n onClick={() => {\n action.onClick();\n handleClose();\n }}\n tone=\"inverse\"\n variant={action.type ?? 'primary'}\n >\n {action.label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n };\n\n const renderTextLink = (): React.ReactNode => {\n if (!textLink) {\n return undefined;\n }\n\n const linkTestId =\n textLink['data-testid'] ?? `text-link-${textLink.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <StyledTextLink\n aria-label={textLink.label}\n data-testid={linkTestId}\n onClick={() => {\n textLink.onClick();\n handleClose();\n }}\n type=\"button\"\n >\n {textLink.label}\n </StyledTextLink>\n );\n };\n\n return (\n <Snackbar\n anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}\n autoHideDuration={autoHideDuration}\n className={className}\n data-testid={dataTestId}\n onClose={handleClose}\n open={isOpen}\n >\n <SnackbarPaper>\n <StyledContent role=\"alert\">\n <StyledContentLeft>\n <StyledIconWrapper>\n <DiamondIcon />\n </StyledIconWrapper>\n <StyledText>{content}</StyledText>\n </StyledContentLeft>\n <StyledActions>\n {textLink && renderTextLink()}\n {actions && actions.length > 0 && renderActions()}\n {onClose && (\n <StyledCloseButton\n aria-label=\"Close notification\"\n onClick={handleClose}\n type=\"button\"\n >\n <CancelIcon />\n </StyledCloseButton>\n )}\n </StyledActions>\n </StyledContent>\n </SnackbarPaper>\n </Snackbar>\n );\n },\n);\n\nAlertSnackbar.displayName = 'AlertSnackbar';\n\nexport default AlertSnackbar;\n"],"names":["getDefaultIconColor","theme","palette","semantic","icon","StyledContent","styled","Box","colors","bg","fill","text","border","stroke","getDefaultColors","display","alignItems","justifyContent","gap","spacing","padding","backgroundColor","color","borderRadius","radius","role","StyledText","fontSize","typography","b1Weak","lineHeight","fontFamily","fontWeight","letterSpacing","flexShrink","minWidth","StyledIcon","StyledIconWrapper","StyledContentLeft","flex","StyledActions","StyledCloseButton","background","cursor","margin","opacity","outline","outlineOffset","StyledTextLink","textDecoration","textUnderlineOffset","textUnderlinePosition","whiteSpace","SnackbarPaper","maxWidth","AlertSnackbar","memo","content","onClose","className","dataTestId","actions","textLink","open","controlledOpen","autoHideDuration","internalOpen","setInternalOpen","useState","isOpen","undefined","handleClose","useCallback","_event","reason","_jsx","Snackbar","anchorOrigin","horizontal","vertical","children","_jsxs","DiamondIcon","linkTestId","label","replace","toLowerCase","onClick","type","renderTextLink","length","sortedActions","sort","a","b","orderMap","tertiary","secondary","primary","aType","bType","ButtonGroup","align","size","map","action","actionTestId","Button","fdKey","tone","variant","renderActions","CancelIcon","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/AlertSnackbar/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo, useCallback, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Snackbar from '@mui/material/Snackbar';\nimport { styled, type Theme } from '@mui/material/styles';\n\nimport CancelIcon from '@fd/icons/Cancel';\nimport DiamondIcon from '@fd/icons/Diamond';\n\nimport Button from '../../atoms/Button';\nimport type { ButtonType } from '../../atoms/Button/getButtonStyles';\nimport ButtonGroup from '../ButtonGroup';\n\n/** Action button configuration */\nexport interface ActionButton {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n fdKey?: string;\n}\n\n/** Text link configuration */\nexport interface TextLink {\n /** Text label for the link */\n label: string;\n /** Callback function when the link is clicked */\n onClick: () => void;\n /** Test ID for the link */\n fdKey?: string;\n}\n\n/** Props for the AlertSnackbar component */\nexport interface AlertSnackbarProps {\n /** Content of the alert snackbar */\n content: string;\n /** Callback function when the alert snackbar is closed */\n onClose?: () => void;\n /** Action buttons configuration - supports Primary, Secondary, Tertiary buttons via ButtonGroup */\n actions?: ActionButton[];\n /** Text link configuration - separate from action buttons */\n textLink?: TextLink;\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n fdKey?: string;\n /** Whether the snackbar is open */\n open?: boolean;\n /** Duration in milliseconds the snackbar should be displayed */\n autoHideDuration?: number;\n}\n\nconst getDefaultColors = (theme: Theme) => {\n return {\n bg: theme.palette.semantic.fill['fill-strong'],\n text: theme.palette.semantic.text['text-inverse-strong'],\n border: theme.palette.semantic.stroke['stroke-strong'],\n };\n};\n\nconst getDefaultIconColor = (theme: Theme): string => {\n return theme.palette.semantic.icon['icon-inverse-strong'];\n};\n\nconst StyledContent = styled(Box)(({ theme }) => {\n const colors = getDefaultColors(theme);\n return {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(3),\n padding: theme.spacing(1.5, 2),\n backgroundColor: colors.bg,\n color: colors.text,\n border: `1px solid ${colors.border}`,\n borderRadius: theme.radius['radius-8'],\n role: 'alert',\n };\n});\n\nconst StyledText = styled(Box)(({ theme }) => ({\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n flexShrink: 1,\n minWidth: 0,\n}));\n\nconst StyledIcon = styled(Box)({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n});\n\nconst StyledIconWrapper = styled(StyledIcon)(({ theme }) => ({\n color: getDefaultIconColor(theme),\n}));\n\nconst StyledContentLeft = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flex: 1,\n minWidth: 0,\n}));\n\nconst StyledActions = styled(Box)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(1),\n alignItems: 'center',\n flexShrink: 0,\n}));\n\nconst StyledCloseButton = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n color: 'inherit',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: theme.spacing(0.5),\n margin: theme.spacing(0, -0.5),\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledTextLink = styled('button')(({ theme }) => ({\n background: 'none',\n border: 'none',\n fontSize: theme.typography.b1Weak.fontSize,\n lineHeight: theme.typography.b1Weak.lineHeight,\n fontFamily: theme.typography.b1Weak.fontFamily,\n fontWeight: theme.typography.b1Weak.fontWeight,\n letterSpacing: theme.typography.b1Weak.letterSpacing,\n textDecoration: 'underline',\n textUnderlineOffset: '25%',\n textUnderlinePosition: 'from-font',\n cursor: 'pointer',\n color: 'inherit',\n padding: 0,\n whiteSpace: 'nowrap',\n '&:hover': {\n opacity: 0.8,\n },\n '&:focus': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n borderRadius: theme.radius['radius-8'],\n },\n}));\n\nconst SnackbarPaper = styled(Box)({\n maxWidth: '60vw',\n});\n\n/**\n * AlertSnackbar component is used to display important notifications to users.\n * It can include optional action buttons (via ButtonGroup supporting Primary, Secondary, Tertiary variants)\n * and/or a text link component.\n * The component wraps MUI's Snackbar component to provide a consistent,\n * accessible notification experience. It is wrapped with React.memo to optimize\n * performance by preventing unnecessary re-renders when props haven't changed.\n * Uses semantic design tokens for colors and typography to ensure proper light/dark mode support.\n */\nconst AlertSnackbar = memo(\n ({\n content,\n onClose,\n className,\n fdKey,\n actions,\n textLink,\n open: controlledOpen,\n autoHideDuration = 5000,\n }: AlertSnackbarProps) => {\n // Use internal state when not controlled\n const [internalOpen, setInternalOpen] = useState(controlledOpen ?? true);\n // When controlled (open prop is defined), use it; otherwise use internal state\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n const handleClose = useCallback(\n (_event?: Event | React.SyntheticEvent, reason?: string) => {\n if (reason === 'clickaway') {\n return;\n }\n // Update internal state for uncontrolled mode\n if (controlledOpen === undefined) {\n setInternalOpen(false);\n }\n // Call external callback if provided\n onClose?.();\n },\n [onClose, controlledOpen],\n );\n\n const renderActions = (): React.ReactNode => {\n if (!actions || actions.length === 0) {\n return undefined;\n }\n\n // Sort actions: Tertiary (left), Secondary (middle), Primary (right)\n const sortedActions = [...actions].sort((a, b) => {\n const orderMap: Record<ButtonType, number> = {\n tertiary: 0,\n secondary: 1,\n primary: 2,\n };\n const aType = a.type ?? 'primary';\n const bType = b.type ?? 'primary';\n return orderMap[aType] - orderMap[bType];\n });\n\n return (\n <ButtonGroup align=\"right\" size=\"small\">\n {sortedActions.map((action) => {\n const actionTestId =\n action.fdKey ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <Button\n key={actionTestId}\n aria-label={action.label}\n fdKey={actionTestId}\n onClick={() => {\n action.onClick();\n handleClose();\n }}\n tone=\"inverse\"\n variant={action.type ?? 'primary'}\n >\n {action.label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n };\n\n const renderTextLink = (): React.ReactNode => {\n if (!textLink) {\n return undefined;\n }\n\n const linkTestId = textLink.fdKey ?? `text-link-${textLink.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <StyledTextLink\n aria-label={textLink.label}\n data-fd={linkTestId}\n onClick={() => {\n textLink.onClick();\n handleClose();\n }}\n type=\"button\"\n >\n {textLink.label}\n </StyledTextLink>\n );\n };\n\n return (\n <Snackbar\n anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}\n autoHideDuration={autoHideDuration}\n className={className}\n data-fd={fdKey}\n onClose={handleClose}\n open={isOpen}\n >\n <SnackbarPaper>\n <StyledContent role=\"alert\">\n <StyledContentLeft>\n <StyledIconWrapper>\n <DiamondIcon />\n </StyledIconWrapper>\n <StyledText>{content}</StyledText>\n </StyledContentLeft>\n <StyledActions>\n {textLink && renderTextLink()}\n {actions && actions.length > 0 && renderActions()}\n {onClose && (\n <StyledCloseButton aria-label=\"Close notification\" onClick={handleClose} type=\"button\">\n <CancelIcon />\n </StyledCloseButton>\n )}\n </StyledActions>\n </StyledContent>\n </SnackbarPaper>\n </Snackbar>\n );\n },\n);\n\nAlertSnackbar.displayName = 'AlertSnackbar';\n\nexport default AlertSnackbar;\n"],"names":["getDefaultIconColor","theme","palette","semantic","icon","StyledContent","styled","Box","colors","bg","fill","text","border","stroke","getDefaultColors","display","alignItems","justifyContent","gap","spacing","padding","backgroundColor","color","borderRadius","radius","role","StyledText","fontSize","typography","b1Weak","lineHeight","fontFamily","fontWeight","letterSpacing","flexShrink","minWidth","StyledIcon","StyledIconWrapper","StyledContentLeft","flex","StyledActions","StyledCloseButton","background","cursor","margin","opacity","outline","outlineOffset","StyledTextLink","textDecoration","textUnderlineOffset","textUnderlinePosition","whiteSpace","SnackbarPaper","maxWidth","AlertSnackbar","memo","content","onClose","className","fdKey","actions","textLink","open","controlledOpen","autoHideDuration","internalOpen","setInternalOpen","useState","isOpen","undefined","handleClose","useCallback","_event","reason","_jsx","Snackbar","anchorOrigin","horizontal","vertical","children","_jsxs","DiamondIcon","linkTestId","label","replace","toLowerCase","onClick","type","renderTextLink","length","sortedActions","sort","a","b","orderMap","tertiary","secondary","primary","aType","bType","ButtonGroup","align","size","map","action","actionTestId","Button","tone","variant","renderActions","CancelIcon","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),i=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),i=require("react/jsx-runtime"),s=require("@mui/material/Autocomplete"),t=require("@mui/material/Box"),r=require("@mui/material/InputAdornment"),n=require("@mui/material/styles"),l=require("../../atoms/Badge/index.cjs.js"),o=require("../../atoms/CircularProgress/index.cjs.js"),a=require("../../atoms/MenuItem/index.cjs.js"),d=require("../../atoms/Tag/index.cjs.js"),u=require("../../atoms/TextField/index.cjs.js"),c=require("../../atoms/VisuallyHidden/index.cjs.js"),p=require("../Tooltip/index.cjs.js"),h=require("../../../icons/ArrowDown01/index.cjs.js"),m=require("../../../icons/ArrowUp01/index.cjs.js"),x=require("../../../icons/Cancel/index.cjs.js"),j=require("../../../icons/Search/index.cjs.js"),g=require("../../../providers/TranslationProvider.cjs.js"),y=require("../../../utilities/stringUtilities.cjs.js"),b=require("./hooks/useDynamicLimitTags.cjs.js"),f=require("./hooks/useShortcutHotkey.cjs.js");const T=s,q=n.styled(T,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({width:e?"100%":"min(364px, 100%)"}))),v=n.styled(r,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:i=!1})=>({"&.MuiInputAdornment-positionEnd":{margin:0},"& svg":{color:i?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),k=n.styled(t)((({theme:e})=>({alignItems:"center",display:"flex",gap:e.spacing(1)}))),I=n.styled("span")((()=>({display:"inline-flex",".Mui-focused &":{display:"none"}}))),P=({ariaLabel:s,className:t,disabled:r=!1,errorText:n,fdKey:T,fullWidth:P=!1,helperText:C,label:A,loading:O=!1,multiple:S=!1,onChange:_,onInputChange:E,options:F=[],placeholder:M,required:W=!1,shortcutHotkey:w=!1,type:B="search",value:D})=>{const H=e.useRef(null),[L,V]=e.useState(""),[z,K]=e.useState(!1),{translate:N}=g.useTranslation(),R=S?Array.isArray(D)?D:null==D?[]:[D]:Array.isArray(D)?D.length>0?D[0]:null:D??null,U="search"===B,$="combobox"===B,G=(Boolean(L)||Boolean(R))&&!r,J=U&&w&&!R&&!r,Q=c.useVisuallyHiddenId(),X=e.useCallback((()=>{H.current?.focus()}),[]),{hotkeyText:Y}=f.useShortcutHotkey({enabled:J,onTrigger:X}),{rootRef:Z,limitTags:ee}=b.useDynamicLimitTags({chipMax:130,gap:4,horizontalPadding:32,reservedPx:U?120:90});e.useEffect((()=>{z&&(r&&K(!1),U&&0===F.length&&K(!1))}),[z,r,U,F.length]);const ie=e=>{r||U&&0===F.length||K(void 0===e?e=>!e:e)};return i.jsxs(i.Fragment,{children:[i.jsx(q,{ref:Z,className:t,clearIcon:i.jsx(x,{size:"md"}),clearText:N("Clear_selection"),disableClearable:!G,disableCloseOnSelect:S,disabled:r,filterOptions:U?e=>e:void 0,forcePopupIcon:$,freeSolo:U,fullWidth:P,getOptionKey:e=>"string"==typeof e?e:String(e.value),getOptionLabel:e=>"string"==typeof e?e:e.label,inputValue:L,isOptionEqualToValue:(e,i)=>null!=i&&("string"==typeof i?e.label===i||String(e.value)===i:e.value===i.value),limitTags:ee,loading:O,loadingText:`${N("Loading")}...`,multiple:S,noOptionsText:N("No_options"),onChange:(e,i,s,t)=>{_&&_(e,i,s,t)},onClose:()=>ie(!1),onInputChange:(e,i,s)=>{V(i),E&&E(e,i,s)},onOpen:()=>ie(!0),open:z,openText:N("Open_popup"),options:F,popupIcon:$?i.jsx(v,{disabled:r,position:"end",children:z?i.jsx(m,{}):i.jsx(h,{})}):null,renderInput:e=>{const t=Array.isArray(F)&&F.length>0,a=$||U&&t,d=[e.inputProps["aria-describedby"],J?Q:void 0].filter(Boolean).join(" ")||void 0;return i.jsx(u.TextField,{disabled:r,errorText:n,fdKey:T,fullWidth:P,helperText:C,inputRef:H,label:A,placeholder:M,required:W,slotProps:{input:{...e.InputProps,endAdornment:i.jsxs(i.Fragment,{children:[i.jsxs(k,{children:[O?i.jsx(o.CircularProgress,{size:"small"}):null,J?i.jsx(I,{children:i.jsx(l.Badge,{label:Y,size:"small",tone:"neutral"})}):null]}),e.InputProps.endAdornment]}),startAdornment:i.jsxs(i.Fragment,{children:[U?i.jsx(v,{disabled:r,position:"start",children:i.jsx(j,{"aria-hidden":"true","data-fd":"search-icon"})}):null,e.InputProps.startAdornment]})},htmlInput:{...e.inputProps,id:T,"aria-label":U&&!A?s:void 0,"aria-describedby":d,...!a&&{role:"searchbox","aria-autocomplete":"none","aria-invalid":n||W?e.inputProps["aria-invalid"]:void 0}}}})},renderOption:(i,s,t)=>{const{key:r,onClick:n,...l}=i;return S?e.createElement(a.MenuItem,{...l,key:r,checked:t.selected,label:s.label,onCheckedChange:(e,i)=>{n?.(i)},type:"checkbox"}):e.createElement(a.MenuItem,{...l,key:r,label:s.label,onClick:n,selected:t.selected,type:"text"})},renderTags:(e,s)=>e.map(((e,t)=>{const{key:r,onDelete:n,...l}=s({index:t}),o="string"==typeof e?e:e.label,a=y.truncateWithEllipsis(o,13,{includeEllipsisInLimit:!0}),u=a.endsWith("..."),c=r??`tag-${"string"==typeof e?e:e.value}`;return u?i.jsx(p.Tooltip,{title:o,children:i.jsx("span",{...l,children:i.jsx(d.Tag,{label:a,onDismiss:n})})},c):i.jsx("span",{...l,children:i.jsx(d.Tag,{label:a,onDismiss:n})},c)})),slotProps:{popupIndicator:{onClick:e=>{r||(e.stopPropagation(),ie())}}},value:R}),J&&i.jsx(c.VisuallyHidden,{fdKey:"autocomplete-shortcut-hotkey",id:Q,children:N("Press_hotkey_to_focus_search",{hotkey:Y})})]})};exports.Autocomplete=P,exports.default=P;
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Autocomplete/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport MuiAutocomplete, {\n type AutocompleteChangeDetails,\n type AutocompleteChangeReason,\n type AutocompleteInputChangeReason,\n type AutocompleteProps as MuiAutocompleteProps,\n type AutocompleteRenderGetTagProps,\n type AutocompleteRenderInputParams,\n type AutocompleteRenderOptionState,\n type AutocompleteValue,\n} from '@mui/material/Autocomplete';\nimport Box from '@mui/material/Box';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport { styled } from '@mui/material/styles';\n\nimport Badge from '@fd/components/atoms/Badge';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport MenuItem from '@fd/components/atoms/MenuItem';\nimport Tag from '@fd/components/atoms/Tag';\nimport TextField, { type TextFieldProps } from '@fd/components/atoms/TextField';\nimport VisuallyHidden, { useVisuallyHiddenId } from '@fd/components/atoms/VisuallyHidden';\nimport Tooltip from '@fd/components/molecules/Tooltip';\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelIcon from '@fd/icons/Cancel';\nimport SearchIcon from '@fd/icons/Search';\nimport { useTranslation } from '@fd/providers/TranslationProvider';\nimport { truncateWithEllipsis } from '@fd/utilities/stringUtilities';\n\nimport { useDynamicLimitTags } from './hooks/useDynamicLimitTags';\nimport { useShortcutHotkey } from './hooks/useShortcutHotkey';\n\n// Bind flags to MuiAutocomplete\ntype MuiCustomAutocompleteProps<\n M extends boolean = boolean, // Multiple\n DC extends boolean = boolean, // DisableClearable\n FS extends boolean = boolean, // FreeSolo\n> = MuiAutocompleteProps<AutocompleteOption, M, DC, FS>;\n\n/**\n * Represents an option in the Autocomplete dropdown.\n */\nexport interface AutocompleteOption {\n /** The label to display in the dropdown option. */\n label: string;\n /** The value to store in the dropdown option. */\n value: number | string;\n}\n\n/**\n * Props for the Autocomplete component.\n * Supports both single and multiple selection modes with optional search functionality.\n */\nexport interface AutocompleteProps extends Omit<\n TextFieldProps,\n 'endAdornment' | 'multiline' | 'onChange' | 'options' | 'startAdornment'\n> {\n /** Aria-label for the input when no label is provided. */\n ariaLabel?: string;\n /** Shows a loading indicator inside the input (e.g., while fetching). */\n loading?: boolean;\n /** Enables selection of multiple options and shows checkboxes and tags for selected values. */\n multiple?: MuiCustomAutocompleteProps['multiple'];\n /** Called when the selected value(s) change. */\n onChange: MuiCustomAutocompleteProps['onChange'];\n /** Called when the input text changes (typing or programmatic updates). */\n onInputChange?: MuiCustomAutocompleteProps['onInputChange'];\n /** Options to display in the dropdown list. */\n options: AutocompleteOption[];\n /** Shows the keyboard shortcut badge (Cmd/Ctrl + K) and enables focusing via the shortcut when in search mode. */\n shortcutHotkey?: boolean;\n /** Visual behavior: 'search' shows a leading search icon; 'combobox' shows a popup button. */\n type?: 'combobox' | 'search';\n /** Controlled value (single option, array for multiple, or null). */\n value: MuiCustomAutocompleteProps['value'];\n}\n\n// Bind flags to MuiAutocomplete, see MuiCustomAutocompleteProps for more details\nconst MuiCustomAutocomplete = MuiAutocomplete<AutocompleteOption, boolean, boolean, boolean>;\nconst StyledAutocomplete = styled(MuiCustomAutocomplete, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n width: fullWidth ? '100%' : 'min(364px, 100%)',\n}));\n\nconst StyledInputAdornment = styled(MuiInputAdornment, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n '&.MuiInputAdornment-positionEnd': {\n margin: 0,\n },\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledEndAdornmentContainer = styled(Box)(({ theme }) => ({\n alignItems: 'center',\n display: 'flex',\n gap: theme.spacing(1),\n}));\n\nconst ShortcutBadgeWrapper = styled('span')(() => ({\n display: 'inline-flex',\n\n // hide when input root is focused\n '.Mui-focused &': {\n display: 'none',\n },\n}));\n\n/**\n * A customizable Autocomplete component supporting search and combobox modes.\n * Supports single and multiple selection with dynamic tag rendering and optional loading states.\n *\n * @param props - The component props\n * @returns The rendered Autocomplete component\n */\nexport const Autocomplete = ({\n ariaLabel,\n className,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n loading = false,\n multiple = false,\n onChange,\n onInputChange,\n options = [],\n placeholder,\n required = false,\n shortcutHotkey = false,\n type = 'search',\n value,\n}: AutocompleteProps): JSX.Element => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [inputText, setInputText] = useState<string>('');\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const { translate } = useTranslation();\n\n /**\n * Normalizes the value prop for MUI Autocomplete.\n * Handles both single and multiple selection modes, ensuring the value\n * format matches the mode (array for multiple, single value/null for single).\n *\n * @returns Normalized value compatible with MUI Autocomplete\n */\n const getValue = (): AutocompleteProps['value'] => {\n // Multiple value selection\n if (multiple) {\n if (Array.isArray(value)) return value;\n if (value === null || value === undefined) return [];\n return [value as AutocompleteOption];\n }\n\n // Single value selection\n if (Array.isArray(value)) return value.length > 0 ? value[0] : null;\n return value ?? null;\n };\n\n const normalizedValue = getValue();\n const isSearch = type === 'search';\n const isCombobox = type === 'combobox';\n const isClearable = (Boolean(inputText) || Boolean(normalizedValue)) && !disabled;\n const isShortcutHotkeyEnabled = isSearch && shortcutHotkey && !normalizedValue && !disabled;\n const screenReaderOnlyId = useVisuallyHiddenId();\n\n const handleShortcutHotkeyFocus = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Hotkey handling and display for Cmd/Ctrl + K\n const { hotkeyText } = useShortcutHotkey({\n enabled: isShortcutHotkeyEnabled,\n onTrigger: handleShortcutHotkeyFocus,\n });\n\n // Dynamic limit tags calculation\n const { rootRef, limitTags } = useDynamicLimitTags({\n chipMax: 130,\n gap: 4,\n horizontalPadding: 32,\n reservedPx: isSearch ? 120 : 90,\n });\n\n /**\n * Close the dropdown (if open) when:\n * - the component is dynamically disabled.\n * - if search mode and no options are provided.\n */\n useEffect(() => {\n if (!isOpen) return;\n if (disabled) setIsOpen(false);\n if (isSearch && options.length === 0) setIsOpen(false);\n }, [isOpen, disabled, isSearch, options.length]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when:\n * - the component is disabled.\n * - if search mode and no options are provided.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) return;\n if (isSearch && options.length === 0) return;\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const renderSearchIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"start\">\n <SearchIcon aria-hidden=\"true\" data-testid=\"search-icon\" />\n </StyledInputAdornment>\n );\n };\n\n const renderPopupIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"end\">\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledInputAdornment>\n );\n };\n\n const renderShortcutHotkey = (): JSX.Element => {\n return (\n <ShortcutBadgeWrapper>\n <Badge label={hotkeyText} size=\"small\" tone=\"neutral\" />\n </ShortcutBadgeWrapper>\n );\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n return (\n <StyledEndAdornmentContainer>\n {loading ? <CircularProgress size=\"small\" /> : null}\n {isShortcutHotkeyEnabled ? renderShortcutHotkey() : null}\n </StyledEndAdornmentContainer>\n );\n };\n\n const renderInputField = (params: AutocompleteRenderInputParams): JSX.Element => {\n const hasOptions = Array.isArray(options) && options.length > 0;\n const showPopup = isCombobox || (isSearch && hasOptions);\n const ariaDescribedBy =\n [params.inputProps['aria-describedby'], isShortcutHotkeyEnabled ? screenReaderOnlyId : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <TextField\n disabled={disabled}\n errorText={errorText}\n fdKey={fdKey}\n fullWidth={fullWidth}\n helperText={helperText}\n inputRef={inputRef}\n label={label}\n placeholder={placeholder}\n required={required}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: (\n <>\n {renderEndAdornment()}\n {params.InputProps.endAdornment}\n </>\n ),\n startAdornment: (\n <>\n {isSearch ? renderSearchIcon() : null}\n {params.InputProps.startAdornment}\n </>\n ),\n },\n htmlInput: {\n ...params.inputProps,\n id: fdKey,\n 'aria-label': isSearch && !label ? ariaLabel : undefined,\n 'aria-describedby': ariaDescribedBy,\n // If the popup is not shown, hide the autocomplete listbox functionality from screen readers\n ...(!showPopup && {\n role: 'searchbox',\n 'aria-autocomplete': 'none',\n 'aria-invalid': !errorText && !required ? undefined : params.inputProps['aria-invalid'],\n }),\n },\n }}\n />\n );\n };\n\n const renderMenuOption = (\n optionProps: React.HTMLAttributes<HTMLLIElement> & { key: React.Key },\n option: AutocompleteOption,\n state: AutocompleteRenderOptionState,\n ): JSX.Element => {\n const { key, onClick, ...rest } = optionProps;\n\n if (multiple) {\n return (\n <MenuItem\n {...rest}\n key={key}\n checked={state.selected}\n label={option.label}\n onCheckedChange={(_checked, e) => {\n onClick?.(e as React.MouseEvent<HTMLLIElement, MouseEvent>);\n }}\n type=\"checkbox\"\n />\n );\n }\n\n return (\n <MenuItem\n {...rest}\n key={key}\n label={option.label}\n onClick={onClick}\n selected={state.selected}\n type=\"text\"\n />\n );\n };\n\n const renderSelectedTags = (\n selected: AutocompleteOption[],\n getTagProps: AutocompleteRenderGetTagProps,\n ): React.ReactNode =>\n selected.map((tag, index) => {\n const { key, onDelete, ...tagProps } = getTagProps({ index });\n const rawLabel = typeof tag === 'string' ? tag : tag.label;\n const label = truncateWithEllipsis(rawLabel, 13, { includeEllipsisInLimit: true });\n const isTruncated = label.endsWith('...');\n const tagKey = key ?? `tag-${typeof tag === 'string' ? tag : tag.value}`;\n\n if (isTruncated) {\n return (\n <Tooltip key={tagKey} title={rawLabel}>\n <span {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n </Tooltip>\n );\n }\n\n return (\n <span key={tagKey} {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n );\n });\n\n const handlePopupIndicatorClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n const handleChange = (\n event: React.SyntheticEvent,\n value: AutocompleteValue<AutocompleteOption, boolean, boolean, boolean>,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<AutocompleteOption>,\n ): void => {\n if (!onChange) {\n return;\n }\n onChange(event, value, reason, details);\n };\n\n const handleInputChange = (\n event: React.SyntheticEvent,\n value: string,\n reason: AutocompleteInputChangeReason,\n ): void => {\n setInputText(value);\n if (!onInputChange) {\n return;\n }\n onInputChange(event, value, reason);\n };\n\n /**\n * Returns all options without filtering for search mode.\n * Disables MUI's built-in client-side filtering when type is 'search'.\n */\n const disableClientFilter = (opts: AutocompleteOption[]): AutocompleteOption[] => opts;\n\n /**\n * Extracts the display label from an option.\n * Supports both object options and freeSolo string values.\n */\n const getOptionLabel = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : option.label;\n };\n\n /**\n * Provides a stable unique key for each option to optimize DOM reconciliation.\n */\n const getOptionKey = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : String(option.value);\n };\n\n /**\n * Determines equality between an option and the current value.\n * Handles both freeSolo string values and object options to prevent selection glitches.\n */\n const getIsOptionEqualToValue = (a: AutocompleteOption, b: AutocompleteOption): boolean => {\n if (b === null || b === undefined) {\n return false;\n }\n return typeof b === 'string' ? a.label === b || String(a.value) === b : a.value === b.value;\n };\n\n return (\n <>\n <StyledAutocomplete\n ref={rootRef}\n className={className}\n clearIcon={<CancelIcon size=\"md\" />}\n clearText={translate('Clear_selection')}\n disableClearable={!isClearable}\n disableCloseOnSelect={multiple}\n disabled={disabled}\n filterOptions={isSearch ? disableClientFilter : undefined}\n forcePopupIcon={isCombobox}\n freeSolo={isSearch}\n fullWidth={fullWidth}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n inputValue={inputText}\n isOptionEqualToValue={getIsOptionEqualToValue}\n limitTags={limitTags}\n loading={loading}\n loadingText={`${translate('Loading')}...`}\n multiple={multiple}\n noOptionsText={translate('No_options')}\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onInputChange={handleInputChange}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n openText={translate('Open_popup')}\n options={options}\n popupIcon={isCombobox ? renderPopupIcon() : null}\n renderInput={renderInputField}\n renderOption={renderMenuOption}\n renderTags={renderSelectedTags}\n slotProps={{\n popupIndicator: {\n onClick: handlePopupIndicatorClick,\n },\n }}\n value={normalizedValue}\n />\n\n {isShortcutHotkeyEnabled && (\n <VisuallyHidden fdKey=\"autocomplete-shortcut-hotkey\" id={screenReaderOnlyId}>\n {translate('Press_hotkey_to_focus_search', { hotkey: hotkeyText })}\n </VisuallyHidden>\n )}\n </>\n );\n};\n\nexport default Autocomplete;\n"],"names":["MuiCustomAutocomplete","StyledAutocomplete","styled","shouldForwardProp","prop","fullWidth","width","StyledInputAdornment","MuiInputAdornment","theme","disabled","margin","color","palette","semantic","icon","StyledEndAdornmentContainer","Box","alignItems","display","gap","spacing","ShortcutBadgeWrapper","Autocomplete","ariaLabel","className","errorText","fdKey","helperText","label","loading","multiple","onChange","onInputChange","options","placeholder","required","shortcutHotkey","type","value","inputRef","useRef","inputText","setInputText","useState","isOpen","setIsOpen","translate","useTranslation","normalizedValue","Array","isArray","length","isSearch","isCombobox","isClearable","Boolean","isShortcutHotkeyEnabled","screenReaderOnlyId","useVisuallyHiddenId","handleShortcutHotkeyFocus","useCallback","current","focus","hotkeyText","useShortcutHotkey","enabled","onTrigger","rootRef","limitTags","useDynamicLimitTags","chipMax","horizontalPadding","reservedPx","useEffect","toggleOpen","open","undefined","prevOpen","_jsxs","_Fragment","children","_jsx","ref","clearIcon","CancelIcon","size","clearText","disableClearable","disableCloseOnSelect","filterOptions","opts","forcePopupIcon","freeSolo","getOptionKey","option","String","getOptionLabel","inputValue","isOptionEqualToValue","a","b","loadingText","noOptionsText","event","reason","details","onClose","onOpen","openText","popupIcon","position","ArrowUp01Icon","ArrowDown01Icon","renderInput","params","hasOptions","showPopup","ariaDescribedBy","inputProps","filter","join","TextField","slotProps","input","InputProps","endAdornment","CircularProgress","Badge","tone","startAdornment","SearchIcon","htmlInput","id","role","renderOption","optionProps","state","key","onClick","rest","_createElement","MenuItem","checked","selected","onCheckedChange","_checked","e","renderTags","getTagProps","map","tag","index","onDelete","tagProps","rawLabel","truncateWithEllipsis","includeEllipsisInLimit","isTruncated","endsWith","tagKey","Tooltip","title","Tag","onDismiss","popupIndicator","stopPropagation","VisuallyHidden","hotkey"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Autocomplete/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport MuiAutocomplete, {\n type AutocompleteChangeDetails,\n type AutocompleteChangeReason,\n type AutocompleteInputChangeReason,\n type AutocompleteProps as MuiAutocompleteProps,\n type AutocompleteRenderGetTagProps,\n type AutocompleteRenderInputParams,\n type AutocompleteRenderOptionState,\n type AutocompleteValue,\n} from '@mui/material/Autocomplete';\nimport Box from '@mui/material/Box';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport { styled } from '@mui/material/styles';\n\nimport Badge from '@fd/components/atoms/Badge';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport MenuItem from '@fd/components/atoms/MenuItem';\nimport Tag from '@fd/components/atoms/Tag';\nimport TextField, { type TextFieldProps } from '@fd/components/atoms/TextField';\nimport VisuallyHidden, { useVisuallyHiddenId } from '@fd/components/atoms/VisuallyHidden';\nimport Tooltip from '@fd/components/molecules/Tooltip';\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelIcon from '@fd/icons/Cancel';\nimport SearchIcon from '@fd/icons/Search';\nimport { useTranslation } from '@fd/providers/TranslationProvider';\nimport { truncateWithEllipsis } from '@fd/utilities/stringUtilities';\n\nimport { useDynamicLimitTags } from './hooks/useDynamicLimitTags';\nimport { useShortcutHotkey } from './hooks/useShortcutHotkey';\n\n// Bind flags to MuiAutocomplete\ntype MuiCustomAutocompleteProps<\n M extends boolean = boolean, // Multiple\n DC extends boolean = boolean, // DisableClearable\n FS extends boolean = boolean, // FreeSolo\n> = MuiAutocompleteProps<AutocompleteOption, M, DC, FS>;\n\n/**\n * Represents an option in the Autocomplete dropdown.\n */\nexport interface AutocompleteOption {\n /** The label to display in the dropdown option. */\n label: string;\n /** The value to store in the dropdown option. */\n value: number | string;\n}\n\n/**\n * Props for the Autocomplete component.\n * Supports both single and multiple selection modes with optional search functionality.\n */\nexport interface AutocompleteProps extends Omit<\n TextFieldProps,\n 'endAdornment' | 'multiline' | 'onChange' | 'options' | 'startAdornment'\n> {\n /** Aria-label for the input when no label is provided. */\n ariaLabel?: string;\n /** Shows a loading indicator inside the input (e.g., while fetching). */\n loading?: boolean;\n /** Enables selection of multiple options and shows checkboxes and tags for selected values. */\n multiple?: MuiCustomAutocompleteProps['multiple'];\n /** Called when the selected value(s) change. */\n onChange: MuiCustomAutocompleteProps['onChange'];\n /** Called when the input text changes (typing or programmatic updates). */\n onInputChange?: MuiCustomAutocompleteProps['onInputChange'];\n /** Options to display in the dropdown list. */\n options: AutocompleteOption[];\n /** Shows the keyboard shortcut badge (Cmd/Ctrl + K) and enables focusing via the shortcut when in search mode. */\n shortcutHotkey?: boolean;\n /** Visual behavior: 'search' shows a leading search icon; 'combobox' shows a popup button. */\n type?: 'combobox' | 'search';\n /** Controlled value (single option, array for multiple, or null). */\n value: MuiCustomAutocompleteProps['value'];\n}\n\n// Bind flags to MuiAutocomplete, see MuiCustomAutocompleteProps for more details\nconst MuiCustomAutocomplete = MuiAutocomplete<AutocompleteOption, boolean, boolean, boolean>;\nconst StyledAutocomplete = styled(MuiCustomAutocomplete, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n width: fullWidth ? '100%' : 'min(364px, 100%)',\n}));\n\nconst StyledInputAdornment = styled(MuiInputAdornment, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n '&.MuiInputAdornment-positionEnd': {\n margin: 0,\n },\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledEndAdornmentContainer = styled(Box)(({ theme }) => ({\n alignItems: 'center',\n display: 'flex',\n gap: theme.spacing(1),\n}));\n\nconst ShortcutBadgeWrapper = styled('span')(() => ({\n display: 'inline-flex',\n\n // hide when input root is focused\n '.Mui-focused &': {\n display: 'none',\n },\n}));\n\n/**\n * A customizable Autocomplete component supporting search and combobox modes.\n * Supports single and multiple selection with dynamic tag rendering and optional loading states.\n *\n * @param props - The component props\n * @returns The rendered Autocomplete component\n */\nexport const Autocomplete = ({\n ariaLabel,\n className,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n loading = false,\n multiple = false,\n onChange,\n onInputChange,\n options = [],\n placeholder,\n required = false,\n shortcutHotkey = false,\n type = 'search',\n value,\n}: AutocompleteProps): JSX.Element => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [inputText, setInputText] = useState<string>('');\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const { translate } = useTranslation();\n\n /**\n * Normalizes the value prop for MUI Autocomplete.\n * Handles both single and multiple selection modes, ensuring the value\n * format matches the mode (array for multiple, single value/null for single).\n *\n * @returns Normalized value compatible with MUI Autocomplete\n */\n const getValue = (): AutocompleteProps['value'] => {\n // Multiple value selection\n if (multiple) {\n if (Array.isArray(value)) return value;\n if (value === null || value === undefined) return [];\n return [value as AutocompleteOption];\n }\n\n // Single value selection\n if (Array.isArray(value)) return value.length > 0 ? value[0] : null;\n return value ?? null;\n };\n\n const normalizedValue = getValue();\n const isSearch = type === 'search';\n const isCombobox = type === 'combobox';\n const isClearable = (Boolean(inputText) || Boolean(normalizedValue)) && !disabled;\n const isShortcutHotkeyEnabled = isSearch && shortcutHotkey && !normalizedValue && !disabled;\n const screenReaderOnlyId = useVisuallyHiddenId();\n\n const handleShortcutHotkeyFocus = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Hotkey handling and display for Cmd/Ctrl + K\n const { hotkeyText } = useShortcutHotkey({\n enabled: isShortcutHotkeyEnabled,\n onTrigger: handleShortcutHotkeyFocus,\n });\n\n // Dynamic limit tags calculation\n const { rootRef, limitTags } = useDynamicLimitTags({\n chipMax: 130,\n gap: 4,\n horizontalPadding: 32,\n reservedPx: isSearch ? 120 : 90,\n });\n\n /**\n * Close the dropdown (if open) when:\n * - the component is dynamically disabled.\n * - if search mode and no options are provided.\n */\n useEffect(() => {\n if (!isOpen) return;\n if (disabled) setIsOpen(false);\n if (isSearch && options.length === 0) setIsOpen(false);\n }, [isOpen, disabled, isSearch, options.length]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when:\n * - the component is disabled.\n * - if search mode and no options are provided.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) return;\n if (isSearch && options.length === 0) return;\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const renderSearchIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"start\">\n <SearchIcon aria-hidden=\"true\" data-fd=\"search-icon\" />\n </StyledInputAdornment>\n );\n };\n\n const renderPopupIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"end\">\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledInputAdornment>\n );\n };\n\n const renderShortcutHotkey = (): JSX.Element => {\n return (\n <ShortcutBadgeWrapper>\n <Badge label={hotkeyText} size=\"small\" tone=\"neutral\" />\n </ShortcutBadgeWrapper>\n );\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n return (\n <StyledEndAdornmentContainer>\n {loading ? <CircularProgress size=\"small\" /> : null}\n {isShortcutHotkeyEnabled ? renderShortcutHotkey() : null}\n </StyledEndAdornmentContainer>\n );\n };\n\n const renderInputField = (params: AutocompleteRenderInputParams): JSX.Element => {\n const hasOptions = Array.isArray(options) && options.length > 0;\n const showPopup = isCombobox || (isSearch && hasOptions);\n const ariaDescribedBy =\n [params.inputProps['aria-describedby'], isShortcutHotkeyEnabled ? screenReaderOnlyId : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <TextField\n disabled={disabled}\n errorText={errorText}\n fdKey={fdKey}\n fullWidth={fullWidth}\n helperText={helperText}\n inputRef={inputRef}\n label={label}\n placeholder={placeholder}\n required={required}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: (\n <>\n {renderEndAdornment()}\n {params.InputProps.endAdornment}\n </>\n ),\n startAdornment: (\n <>\n {isSearch ? renderSearchIcon() : null}\n {params.InputProps.startAdornment}\n </>\n ),\n },\n htmlInput: {\n ...params.inputProps,\n id: fdKey,\n 'aria-label': isSearch && !label ? ariaLabel : undefined,\n 'aria-describedby': ariaDescribedBy,\n // If the popup is not shown, hide the autocomplete listbox functionality from screen readers\n ...(!showPopup && {\n role: 'searchbox',\n 'aria-autocomplete': 'none',\n 'aria-invalid': !errorText && !required ? undefined : params.inputProps['aria-invalid'],\n }),\n },\n }}\n />\n );\n };\n\n const renderMenuOption = (\n optionProps: React.HTMLAttributes<HTMLLIElement> & { key: React.Key },\n option: AutocompleteOption,\n state: AutocompleteRenderOptionState,\n ): JSX.Element => {\n const { key, onClick, ...rest } = optionProps;\n\n if (multiple) {\n return (\n <MenuItem\n {...rest}\n key={key}\n checked={state.selected}\n label={option.label}\n onCheckedChange={(_checked, e) => {\n onClick?.(e as React.MouseEvent<HTMLLIElement, MouseEvent>);\n }}\n type=\"checkbox\"\n />\n );\n }\n\n return (\n <MenuItem\n {...rest}\n key={key}\n label={option.label}\n onClick={onClick}\n selected={state.selected}\n type=\"text\"\n />\n );\n };\n\n const renderSelectedTags = (\n selected: AutocompleteOption[],\n getTagProps: AutocompleteRenderGetTagProps,\n ): React.ReactNode =>\n selected.map((tag, index) => {\n const { key, onDelete, ...tagProps } = getTagProps({ index });\n const rawLabel = typeof tag === 'string' ? tag : tag.label;\n const label = truncateWithEllipsis(rawLabel, 13, { includeEllipsisInLimit: true });\n const isTruncated = label.endsWith('...');\n const tagKey = key ?? `tag-${typeof tag === 'string' ? tag : tag.value}`;\n\n if (isTruncated) {\n return (\n <Tooltip key={tagKey} title={rawLabel}>\n <span {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n </Tooltip>\n );\n }\n\n return (\n <span key={tagKey} {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n );\n });\n\n const handlePopupIndicatorClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n const handleChange = (\n event: React.SyntheticEvent,\n value: AutocompleteValue<AutocompleteOption, boolean, boolean, boolean>,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<AutocompleteOption>,\n ): void => {\n if (!onChange) {\n return;\n }\n onChange(event, value, reason, details);\n };\n\n const handleInputChange = (\n event: React.SyntheticEvent,\n value: string,\n reason: AutocompleteInputChangeReason,\n ): void => {\n setInputText(value);\n if (!onInputChange) {\n return;\n }\n onInputChange(event, value, reason);\n };\n\n /**\n * Returns all options without filtering for search mode.\n * Disables MUI's built-in client-side filtering when type is 'search'.\n */\n const disableClientFilter = (opts: AutocompleteOption[]): AutocompleteOption[] => opts;\n\n /**\n * Extracts the display label from an option.\n * Supports both object options and freeSolo string values.\n */\n const getOptionLabel = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : option.label;\n };\n\n /**\n * Provides a stable unique key for each option to optimize DOM reconciliation.\n */\n const getOptionKey = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : String(option.value);\n };\n\n /**\n * Determines equality between an option and the current value.\n * Handles both freeSolo string values and object options to prevent selection glitches.\n */\n const getIsOptionEqualToValue = (a: AutocompleteOption, b: AutocompleteOption): boolean => {\n if (b === null || b === undefined) {\n return false;\n }\n return typeof b === 'string' ? a.label === b || String(a.value) === b : a.value === b.value;\n };\n\n return (\n <>\n <StyledAutocomplete\n ref={rootRef}\n className={className}\n clearIcon={<CancelIcon size=\"md\" />}\n clearText={translate('Clear_selection')}\n disableClearable={!isClearable}\n disableCloseOnSelect={multiple}\n disabled={disabled}\n filterOptions={isSearch ? disableClientFilter : undefined}\n forcePopupIcon={isCombobox}\n freeSolo={isSearch}\n fullWidth={fullWidth}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n inputValue={inputText}\n isOptionEqualToValue={getIsOptionEqualToValue}\n limitTags={limitTags}\n loading={loading}\n loadingText={`${translate('Loading')}...`}\n multiple={multiple}\n noOptionsText={translate('No_options')}\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onInputChange={handleInputChange}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n openText={translate('Open_popup')}\n options={options}\n popupIcon={isCombobox ? renderPopupIcon() : null}\n renderInput={renderInputField}\n renderOption={renderMenuOption}\n renderTags={renderSelectedTags}\n slotProps={{\n popupIndicator: {\n onClick: handlePopupIndicatorClick,\n },\n }}\n value={normalizedValue}\n />\n\n {isShortcutHotkeyEnabled && (\n <VisuallyHidden fdKey=\"autocomplete-shortcut-hotkey\" id={screenReaderOnlyId}>\n {translate('Press_hotkey_to_focus_search', { hotkey: hotkeyText })}\n </VisuallyHidden>\n )}\n </>\n );\n};\n\nexport default Autocomplete;\n"],"names":["MuiCustomAutocomplete","StyledAutocomplete","styled","shouldForwardProp","prop","fullWidth","width","StyledInputAdornment","MuiInputAdornment","theme","disabled","margin","color","palette","semantic","icon","StyledEndAdornmentContainer","Box","alignItems","display","gap","spacing","ShortcutBadgeWrapper","Autocomplete","ariaLabel","className","errorText","fdKey","helperText","label","loading","multiple","onChange","onInputChange","options","placeholder","required","shortcutHotkey","type","value","inputRef","useRef","inputText","setInputText","useState","isOpen","setIsOpen","translate","useTranslation","normalizedValue","Array","isArray","length","isSearch","isCombobox","isClearable","Boolean","isShortcutHotkeyEnabled","screenReaderOnlyId","useVisuallyHiddenId","handleShortcutHotkeyFocus","useCallback","current","focus","hotkeyText","useShortcutHotkey","enabled","onTrigger","rootRef","limitTags","useDynamicLimitTags","chipMax","horizontalPadding","reservedPx","useEffect","toggleOpen","open","undefined","prevOpen","_jsxs","_Fragment","children","_jsx","ref","clearIcon","CancelIcon","size","clearText","disableClearable","disableCloseOnSelect","filterOptions","opts","forcePopupIcon","freeSolo","getOptionKey","option","String","getOptionLabel","inputValue","isOptionEqualToValue","a","b","loadingText","noOptionsText","event","reason","details","onClose","onOpen","openText","popupIcon","position","ArrowUp01Icon","ArrowDown01Icon","renderInput","params","hasOptions","showPopup","ariaDescribedBy","inputProps","filter","join","TextField","slotProps","input","InputProps","endAdornment","CircularProgress","Badge","tone","startAdornment","SearchIcon","htmlInput","id","role","renderOption","optionProps","state","key","onClick","rest","_createElement","MenuItem","checked","selected","onCheckedChange","_checked","e","renderTags","getTagProps","map","tag","index","onDelete","tagProps","rawLabel","truncateWithEllipsis","includeEllipsisInLimit","isTruncated","endsWith","tagKey","Tooltip","title","Tag","onDismiss","popupIndicator","stopPropagation","VisuallyHidden","hotkey"],"mappings":"2+BA+EA,MAAMA,EAAqB,EACrBC,EAAqBC,EAAAA,OAAOF,EAAuB,CACvDG,kBAAoBC,GAAkB,cAATA,GADJF,EAEC,EAAGG,aAAY,MAAO,CAChDC,MAAOD,EAAY,OAAS,uBAGxBE,EAAuBL,EAAAA,OAAOM,EAAmB,CACrDL,kBAAoBC,GAAkB,aAATA,GADFF,EAEF,EAAGO,QAAOC,YAAW,MAAO,CACrD,kCAAmC,CACjCC,OAAQ,GAGV,QAAS,CACPC,MAAOF,EACHD,EAAMI,QAAQC,SAASC,KAAK,iBAC5BN,EAAMI,QAAQC,SAASC,KAAK,oBAI9BC,EAA8Bd,EAAAA,OAAOe,EAAPf,EAAY,EAAGO,YAAO,CACxDS,WAAY,SACZC,QAAS,OACTC,IAAKX,EAAMY,QAAQ,OAGfC,EAAuBpB,EAAAA,OAAO,OAAPA,EAAe,KAAA,CAC1CiB,QAAS,cAGT,iBAAkB,CAChBA,QAAS,YAWAI,EAAe,EAC1BC,YACAC,YACAf,YAAW,EACXgB,YACAC,QACAtB,aAAY,EACZuB,aACAC,QACAC,WAAU,EACVC,YAAW,EACXC,WACAC,gBACAC,UAAU,GACVC,cACAC,YAAW,EACXC,kBAAiB,EACjBC,OAAO,SACPC,YAEA,MAAMC,EAAWC,EAAAA,OAAyB,OACnCC,EAAWC,GAAgBC,EAAAA,SAAiB,KAC5CC,EAAQC,GAAaF,EAAAA,UAAkB,IAExCG,UAAEA,GAAcC,mBAsBhBC,EAXAlB,EACEmB,MAAMC,QAAQZ,GAAeA,EAC7BA,QAA8C,GAC3C,CAACA,GAINW,MAAMC,QAAQZ,GAAeA,EAAMa,OAAS,EAAIb,EAAM,GAAK,KACxDA,GAAS,KAIZc,EAAoB,WAATf,EACXgB,EAAsB,aAAThB,EACbiB,GAAeC,QAAQd,IAAcc,QAAQP,MAAsBvC,EACnE+C,EAA0BJ,GAAYhB,IAAmBY,IAAoBvC,EAC7EgD,EAAqBC,EAAAA,sBAErBC,EAA4BC,EAAAA,aAAY,KAC5CrB,EAASsB,SAASC,UACjB,KAGGC,WAAEA,GAAeC,oBAAkB,CACvCC,QAAST,EACTU,UAAWP,KAIPQ,QAAEA,EAAOC,UAAEA,IAAcC,sBAAoB,CACjDC,QAAS,IACTnD,IAAK,EACLoD,kBAAmB,GACnBC,WAAYpB,EAAW,IAAM,KAQ/BqB,EAAAA,WAAU,KACH7B,IACDnC,GAAUoC,GAAU,GACpBO,GAA+B,IAAnBnB,EAAQkB,QAAcN,GAAU,MAC/C,CAACD,EAAQnC,EAAU2C,EAAUnB,EAAQkB,SAUxC,MAAMuB,GAAcC,IACdlE,GACA2C,GAA+B,IAAnBnB,EAAQkB,QAOxBN,OALa+B,IAATD,EAKOE,IAAcA,EAJbF,IA2Nd,OACEG,EAAAA,KAAAC,WAAA,CAAAC,SAAA,CACEC,MAACjF,EAAkB,CACjBkF,IAAKf,EACL3C,UAAWA,EACX2D,UAAWF,EAAAA,IAACG,EAAU,CAACC,KAAK,OAC5BC,UAAWxC,EAAU,mBACrByC,kBAAmBjC,EACnBkC,qBAAsB1D,EACtBrB,SAAUA,EACVgF,cAAerC,EAtCQsC,GAAqDA,OAsC5Bd,EAChDe,eAAgBtC,EAChBuC,SAAUxC,EACVhD,UAAWA,EACXyF,aA7BgBC,GACK,iBAAXA,EAAsBA,EAASC,OAAOD,EAAOxD,OA6BvD0D,eArCkBF,GACG,iBAAXA,EAAsBA,EAASA,EAAOlE,MAqChDqE,WAAYxD,EACZyD,qBAxB0B,CAACC,EAAuBC,IAClDA,UAGgB,iBAANA,EAAiBD,EAAEvE,QAAUwE,GAAKL,OAAOI,EAAE7D,SAAW8D,EAAID,EAAE7D,QAAU8D,EAAE9D,OAqBlF8B,UAAWA,GACXvC,QAASA,EACTwE,YAAa,GAAGvD,EAAU,gBAC1BhB,SAAUA,EACVwE,cAAexD,EAAU,cACzBf,SA/Ee,CACnBwE,EACAjE,EACAkE,EACAC,KAEK1E,GAGLA,EAASwE,EAAOjE,EAAOkE,EAAQC,IAuE3BC,QAAS,IAAMhC,IAAW,GAC1B1C,cArEoB,CACxBuE,EACAjE,EACAkE,KAEA9D,EAAaJ,GACRN,GAGLA,EAAcuE,EAAOjE,EAAOkE,IA6DxBG,OAAQ,IAAMjC,IAAW,GACzBC,KAAM/B,EACNgE,SAAU9D,EAAU,cACpBb,QAASA,EACT4E,UAAWxD,EAxOb4B,EAAAA,IAAC3E,EAAoB,CAACG,SAAUA,EAAUqG,SAAS,MAAK9B,SACrDpC,EAASqC,EAAAA,IAAC8B,EAAa,IAAM9B,EAAAA,IAAC+B,EAAe,CAAA,KAuOF,KAC5CC,YAlNoBC,IACxB,MAAMC,EAAalE,MAAMC,QAAQjB,IAAYA,EAAQkB,OAAS,EACxDiE,EAAY/D,GAAeD,GAAY+D,EACvCE,EACJ,CAACH,EAAOI,WAAW,oBAAqB9D,EAA0BC,OAAqBmB,GACpF2C,OAAOhE,SACPiE,KAAK,WAAQ5C,EAElB,OACEK,EAAAA,IAACwC,aACChH,SAAUA,EACVgB,UAAWA,EACXC,MAAOA,EACPtB,UAAWA,EACXuB,WAAYA,EACZY,SAAUA,EACVX,MAAOA,EACPM,YAAaA,EACbC,SAAUA,EACVuF,UAAW,CACTC,MAAO,IACFT,EAAOU,WACVC,aACE/C,EAAAA,KAAAC,WAAA,CAAAC,SAAA,CA9BRF,EAAAA,KAAC/D,EAA2B,CAAAiE,SAAA,CACzBnD,EAAUoD,EAAAA,IAAC6C,mBAAgB,CAACzC,KAAK,UAAa,KAC9C7B,EAVHyB,EAAAA,IAAC5D,EAAoB,CAAA2D,SACnBC,EAAAA,IAAC8C,EAAAA,MAAK,CAACnG,MAAOmC,EAAYsB,KAAK,QAAQ2C,KAAK,cASQ,QA8B3Cd,EAAOU,WAAWC,gBAGvBI,eACEnD,EAAAA,KAAAC,EAAAA,SAAA,CAAAC,SAAA,CACG5B,EA7DX6B,EAAAA,IAAC3E,EAAoB,CAACG,SAAUA,EAAUqG,SAAS,QAAO9B,SACxDC,EAAAA,IAACiD,EAAU,CAAA,cAAa,iBAAe,kBA4DE,KAChChB,EAAOU,WAAWK,mBAIzBE,UAAW,IACNjB,EAAOI,WACVc,GAAI1G,EACJ,aAAc0B,IAAaxB,EAAQL,OAAYqD,EAC/C,mBAAoByC,MAEfD,GAAa,CAChBiB,KAAM,YACN,oBAAqB,OACrB,eAAiB5G,GAAcU,EAAuB+E,EAAOI,WAAW,qBAA9B1C,QAuKhD0D,aA/JmB,CACvBC,EACAzC,EACA0C,KAEA,MAAMC,IAAEA,EAAGC,QAAEA,KAAYC,GAASJ,EAElC,OAAIzG,EAEA8G,EAAAA,cAACC,EAAAA,SAAQ,IACHF,EACJF,IAAKA,EACLK,QAASN,EAAMO,SACfnH,MAAOkE,EAAOlE,MACdoH,gBAAiB,CAACC,EAAUC,KAC1BR,IAAUQ,IAEZ7G,KAAK,aAMTuG,EAAAA,cAACC,EAAAA,SAAQ,IACHF,EACJF,IAAKA,EACL7G,MAAOkE,EAAOlE,MACd8G,QAASA,EACTK,SAAUP,EAAMO,SAChB1G,KAAK,UAmIL8G,WA9HqB,CACzBJ,EACAK,IAEAL,EAASM,KAAI,CAACC,EAAKC,KACjB,MAAMd,IAAEA,EAAGe,SAAEA,KAAaC,GAAaL,EAAY,CAAEG,UAC/CG,EAA0B,iBAARJ,EAAmBA,EAAMA,EAAI1H,MAC/CA,EAAQ+H,EAAAA,qBAAqBD,EAAU,GAAI,CAAEE,wBAAwB,IACrEC,EAAcjI,EAAMkI,SAAS,OAC7BC,EAAStB,GAAO,OAAsB,iBAARa,EAAmBA,EAAMA,EAAIhH,QAEjE,OAAIuH,EAEA5E,EAAAA,IAAC+E,UAAO,CAAcC,MAAOP,EAAQ1E,SACnCC,EAAAA,IAAA,OAAA,IAAUwE,EAAQzE,SAChBC,MAACiF,EAAAA,IAAG,CAACtI,MAAOA,EAAOuI,UAAWX,OAFpBO,GAShB9E,EAAAA,IAAA,OAAA,IAAuBwE,WACrBxE,EAAAA,IAACiF,EAAAA,KAAItI,MAAOA,EAAOuI,UAAWX,KADrBO,MAyGXrC,UAAW,CACT0C,eAAgB,CACd1B,QArGyBnC,IAC7B9F,IAIJ8F,EAAM8D,kBACN3F,SAkGIpC,MAAOU,IAGRQ,GACCyB,EAAAA,IAACqF,EAAAA,eAAc,CAAC5I,MAAM,+BAA+B0G,GAAI3E,EAAkBuB,SACxElC,EAAU,+BAAgC,CAAEyH,OAAQxG"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useRef as e,useState as o,useCallback as i,useEffect as t,createElement as r}from"react";import{jsxs as n,Fragment as l,jsx as a}from"react/jsx-runtime";import s from"@mui/material/Autocomplete";import d from"@mui/material/Box";import p from"@mui/material/InputAdornment";import{styled as m}from"@mui/material/styles";import{Badge as c}from"../../atoms/Badge/index.js";import{CircularProgress as u}from"../../atoms/CircularProgress/index.js";import{MenuItem as h}from"../../atoms/MenuItem/index.js";import{Tag as f}from"../../atoms/Tag/index.js";import{TextField as g}from"../../atoms/TextField/index.js";import{useVisuallyHiddenId as y,VisuallyHidden as b}from"../../atoms/VisuallyHidden/index.js";import{Tooltip as x}from"../Tooltip/index.js";import v from"../../../icons/ArrowDown01/index.js";import T from"../../../icons/ArrowUp01/index.js";import k from"../../../icons/Cancel/index.js";import j from"../../../icons/Search/index.js";import{useTranslation as P}from"../../../providers/TranslationProvider.js";import{truncateWithEllipsis as I}from"../../../utilities/stringUtilities.js";import{useDynamicLimitTags as A}from"./hooks/useDynamicLimitTags.js";import{useShortcutHotkey as C}from"./hooks/useShortcutHotkey.js";const O=m(s,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({width:e?"100%":"min(364px, 100%)"}))),_=m(p,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:o=!1})=>({"&.MuiInputAdornment-positionEnd":{margin:0},"& svg":{color:o?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),w=m(d)((({theme:e})=>({alignItems:"center",display:"flex",gap:e.spacing(1)}))),S=m("span")((()=>({display:"inline-flex",".Mui-focused &":{display:"none"}}))),W=({ariaLabel:s,className:d,disabled:p=!1,errorText:m,fdKey:W,fullWidth:B=!1,helperText:D,label:L,loading:z=!1,multiple:K=!1,onChange:M,onInputChange:q,options:E=[],placeholder:F,required:H=!1,shortcutHotkey:N=!1,type:V="search",value:R})=>{const U=e(null),[$,G]=o(""),[J,Q]=o(!1),{translate:X}=P(),Y=K?Array.isArray(R)?R:null==R?[]:[R]:Array.isArray(R)?R.length>0?R[0]:null:R??null,Z="search"===V,ee="combobox"===V,oe=(Boolean($)||Boolean(Y))&&!p,ie=Z&&N&&!Y&&!p,te=y(),re=i((()=>{U.current?.focus()}),[]),{hotkeyText:ne}=C({enabled:ie,onTrigger:re}),{rootRef:le,limitTags:ae}=A({chipMax:130,gap:4,horizontalPadding:32,reservedPx:Z?120:90});t((()=>{J&&(p&&Q(!1),Z&&0===E.length&&Q(!1))}),[J,p,Z,E.length]);const se=e=>{p||Z&&0===E.length||Q(void 0===e?e=>!e:e)};return n(l,{children:[a(O,{ref:le,className:d,clearIcon:a(k,{size:"md"}),clearText:X("Clear_selection"),disableClearable:!oe,disableCloseOnSelect:K,disabled:p,filterOptions:Z?e=>e:void 0,forcePopupIcon:ee,freeSolo:Z,fullWidth:B,getOptionKey:e=>"string"==typeof e?e:String(e.value),getOptionLabel:e=>"string"==typeof e?e:e.label,inputValue:$,isOptionEqualToValue:(e,o)=>null!=o&&("string"==typeof o?e.label===o||String(e.value)===o:e.value===o.value),limitTags:ae,loading:z,loadingText:`${X("Loading")}...`,multiple:K,noOptionsText:X("No_options"),onChange:(e,o,i,t)=>{M&&M(e,o,i,t)},onClose:()=>se(!1),onInputChange:(e,o,i)=>{G(o),q&&q(e,o,i)},onOpen:()=>se(!0),open:J,openText:X("Open_popup"),options:E,popupIcon:ee?a(_,{disabled:p,position:"end",children:a(J?T:v,{})}):null,renderInput:e=>{const o=Array.isArray(E)&&E.length>0,i=ee||Z&&o,t=[e.inputProps["aria-describedby"],ie?te:void 0].filter(Boolean).join(" ")||void 0;return a(g,{disabled:p,errorText:m,fdKey:W,fullWidth:B,helperText:D,inputRef:U,label:L,placeholder:F,required:H,slotProps:{input:{...e.InputProps,endAdornment:n(l,{children:[n(w,{children:[z?a(u,{size:"small"}):null,ie?a(S,{children:a(c,{label:ne,size:"small",tone:"neutral"})}):null]}),e.InputProps.endAdornment]}),startAdornment:n(l,{children:[Z?a(_,{disabled:p,position:"start",children:a(j,{"aria-hidden":"true","data-
|
|
1
|
+
import{useRef as e,useState as o,useCallback as i,useEffect as t,createElement as r}from"react";import{jsxs as n,Fragment as l,jsx as a}from"react/jsx-runtime";import s from"@mui/material/Autocomplete";import d from"@mui/material/Box";import p from"@mui/material/InputAdornment";import{styled as m}from"@mui/material/styles";import{Badge as c}from"../../atoms/Badge/index.js";import{CircularProgress as u}from"../../atoms/CircularProgress/index.js";import{MenuItem as h}from"../../atoms/MenuItem/index.js";import{Tag as f}from"../../atoms/Tag/index.js";import{TextField as g}from"../../atoms/TextField/index.js";import{useVisuallyHiddenId as y,VisuallyHidden as b}from"../../atoms/VisuallyHidden/index.js";import{Tooltip as x}from"../Tooltip/index.js";import v from"../../../icons/ArrowDown01/index.js";import T from"../../../icons/ArrowUp01/index.js";import k from"../../../icons/Cancel/index.js";import j from"../../../icons/Search/index.js";import{useTranslation as P}from"../../../providers/TranslationProvider.js";import{truncateWithEllipsis as I}from"../../../utilities/stringUtilities.js";import{useDynamicLimitTags as A}from"./hooks/useDynamicLimitTags.js";import{useShortcutHotkey as C}from"./hooks/useShortcutHotkey.js";const O=m(s,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({width:e?"100%":"min(364px, 100%)"}))),_=m(p,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:o=!1})=>({"&.MuiInputAdornment-positionEnd":{margin:0},"& svg":{color:o?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),w=m(d)((({theme:e})=>({alignItems:"center",display:"flex",gap:e.spacing(1)}))),S=m("span")((()=>({display:"inline-flex",".Mui-focused &":{display:"none"}}))),W=({ariaLabel:s,className:d,disabled:p=!1,errorText:m,fdKey:W,fullWidth:B=!1,helperText:D,label:L,loading:z=!1,multiple:K=!1,onChange:M,onInputChange:q,options:E=[],placeholder:F,required:H=!1,shortcutHotkey:N=!1,type:V="search",value:R})=>{const U=e(null),[$,G]=o(""),[J,Q]=o(!1),{translate:X}=P(),Y=K?Array.isArray(R)?R:null==R?[]:[R]:Array.isArray(R)?R.length>0?R[0]:null:R??null,Z="search"===V,ee="combobox"===V,oe=(Boolean($)||Boolean(Y))&&!p,ie=Z&&N&&!Y&&!p,te=y(),re=i((()=>{U.current?.focus()}),[]),{hotkeyText:ne}=C({enabled:ie,onTrigger:re}),{rootRef:le,limitTags:ae}=A({chipMax:130,gap:4,horizontalPadding:32,reservedPx:Z?120:90});t((()=>{J&&(p&&Q(!1),Z&&0===E.length&&Q(!1))}),[J,p,Z,E.length]);const se=e=>{p||Z&&0===E.length||Q(void 0===e?e=>!e:e)};return n(l,{children:[a(O,{ref:le,className:d,clearIcon:a(k,{size:"md"}),clearText:X("Clear_selection"),disableClearable:!oe,disableCloseOnSelect:K,disabled:p,filterOptions:Z?e=>e:void 0,forcePopupIcon:ee,freeSolo:Z,fullWidth:B,getOptionKey:e=>"string"==typeof e?e:String(e.value),getOptionLabel:e=>"string"==typeof e?e:e.label,inputValue:$,isOptionEqualToValue:(e,o)=>null!=o&&("string"==typeof o?e.label===o||String(e.value)===o:e.value===o.value),limitTags:ae,loading:z,loadingText:`${X("Loading")}...`,multiple:K,noOptionsText:X("No_options"),onChange:(e,o,i,t)=>{M&&M(e,o,i,t)},onClose:()=>se(!1),onInputChange:(e,o,i)=>{G(o),q&&q(e,o,i)},onOpen:()=>se(!0),open:J,openText:X("Open_popup"),options:E,popupIcon:ee?a(_,{disabled:p,position:"end",children:a(J?T:v,{})}):null,renderInput:e=>{const o=Array.isArray(E)&&E.length>0,i=ee||Z&&o,t=[e.inputProps["aria-describedby"],ie?te:void 0].filter(Boolean).join(" ")||void 0;return a(g,{disabled:p,errorText:m,fdKey:W,fullWidth:B,helperText:D,inputRef:U,label:L,placeholder:F,required:H,slotProps:{input:{...e.InputProps,endAdornment:n(l,{children:[n(w,{children:[z?a(u,{size:"small"}):null,ie?a(S,{children:a(c,{label:ne,size:"small",tone:"neutral"})}):null]}),e.InputProps.endAdornment]}),startAdornment:n(l,{children:[Z?a(_,{disabled:p,position:"start",children:a(j,{"aria-hidden":"true","data-fd":"search-icon"})}):null,e.InputProps.startAdornment]})},htmlInput:{...e.inputProps,id:W,"aria-label":Z&&!L?s:void 0,"aria-describedby":t,...!i&&{role:"searchbox","aria-autocomplete":"none","aria-invalid":m||H?e.inputProps["aria-invalid"]:void 0}}}})},renderOption:(e,o,i)=>{const{key:t,onClick:n,...l}=e;return r(h,K?{...l,key:t,checked:i.selected,label:o.label,onCheckedChange:(e,o)=>{n?.(o)},type:"checkbox"}:{...l,key:t,label:o.label,onClick:n,selected:i.selected,type:"text"})},renderTags:(e,o)=>e.map(((e,i)=>{const{key:t,onDelete:r,...n}=o({index:i}),l="string"==typeof e?e:e.label,s=I(l,13,{includeEllipsisInLimit:!0}),d=s.endsWith("..."),p=t??`tag-${"string"==typeof e?e:e.value}`;return d?a(x,{title:l,children:a("span",{...n,children:a(f,{label:s,onDismiss:r})})},p):a("span",{...n,children:a(f,{label:s,onDismiss:r})},p)})),slotProps:{popupIndicator:{onClick:e=>{p||(e.stopPropagation(),se())}}},value:Y}),ie&&a(b,{fdKey:"autocomplete-shortcut-hotkey",id:te,children:X("Press_hotkey_to_focus_search",{hotkey:ne})})]})};export{W as Autocomplete,W as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/Autocomplete/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport MuiAutocomplete, {\n type AutocompleteChangeDetails,\n type AutocompleteChangeReason,\n type AutocompleteInputChangeReason,\n type AutocompleteProps as MuiAutocompleteProps,\n type AutocompleteRenderGetTagProps,\n type AutocompleteRenderInputParams,\n type AutocompleteRenderOptionState,\n type AutocompleteValue,\n} from '@mui/material/Autocomplete';\nimport Box from '@mui/material/Box';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport { styled } from '@mui/material/styles';\n\nimport Badge from '@fd/components/atoms/Badge';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport MenuItem from '@fd/components/atoms/MenuItem';\nimport Tag from '@fd/components/atoms/Tag';\nimport TextField, { type TextFieldProps } from '@fd/components/atoms/TextField';\nimport VisuallyHidden, { useVisuallyHiddenId } from '@fd/components/atoms/VisuallyHidden';\nimport Tooltip from '@fd/components/molecules/Tooltip';\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelIcon from '@fd/icons/Cancel';\nimport SearchIcon from '@fd/icons/Search';\nimport { useTranslation } from '@fd/providers/TranslationProvider';\nimport { truncateWithEllipsis } from '@fd/utilities/stringUtilities';\n\nimport { useDynamicLimitTags } from './hooks/useDynamicLimitTags';\nimport { useShortcutHotkey } from './hooks/useShortcutHotkey';\n\n// Bind flags to MuiAutocomplete\ntype MuiCustomAutocompleteProps<\n M extends boolean = boolean, // Multiple\n DC extends boolean = boolean, // DisableClearable\n FS extends boolean = boolean, // FreeSolo\n> = MuiAutocompleteProps<AutocompleteOption, M, DC, FS>;\n\n/**\n * Represents an option in the Autocomplete dropdown.\n */\nexport interface AutocompleteOption {\n /** The label to display in the dropdown option. */\n label: string;\n /** The value to store in the dropdown option. */\n value: number | string;\n}\n\n/**\n * Props for the Autocomplete component.\n * Supports both single and multiple selection modes with optional search functionality.\n */\nexport interface AutocompleteProps extends Omit<\n TextFieldProps,\n 'endAdornment' | 'multiline' | 'onChange' | 'options' | 'startAdornment'\n> {\n /** Aria-label for the input when no label is provided. */\n ariaLabel?: string;\n /** Shows a loading indicator inside the input (e.g., while fetching). */\n loading?: boolean;\n /** Enables selection of multiple options and shows checkboxes and tags for selected values. */\n multiple?: MuiCustomAutocompleteProps['multiple'];\n /** Called when the selected value(s) change. */\n onChange: MuiCustomAutocompleteProps['onChange'];\n /** Called when the input text changes (typing or programmatic updates). */\n onInputChange?: MuiCustomAutocompleteProps['onInputChange'];\n /** Options to display in the dropdown list. */\n options: AutocompleteOption[];\n /** Shows the keyboard shortcut badge (Cmd/Ctrl + K) and enables focusing via the shortcut when in search mode. */\n shortcutHotkey?: boolean;\n /** Visual behavior: 'search' shows a leading search icon; 'combobox' shows a popup button. */\n type?: 'combobox' | 'search';\n /** Controlled value (single option, array for multiple, or null). */\n value: MuiCustomAutocompleteProps['value'];\n}\n\n// Bind flags to MuiAutocomplete, see MuiCustomAutocompleteProps for more details\nconst MuiCustomAutocomplete = MuiAutocomplete<AutocompleteOption, boolean, boolean, boolean>;\nconst StyledAutocomplete = styled(MuiCustomAutocomplete, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n width: fullWidth ? '100%' : 'min(364px, 100%)',\n}));\n\nconst StyledInputAdornment = styled(MuiInputAdornment, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n '&.MuiInputAdornment-positionEnd': {\n margin: 0,\n },\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledEndAdornmentContainer = styled(Box)(({ theme }) => ({\n alignItems: 'center',\n display: 'flex',\n gap: theme.spacing(1),\n}));\n\nconst ShortcutBadgeWrapper = styled('span')(() => ({\n display: 'inline-flex',\n\n // hide when input root is focused\n '.Mui-focused &': {\n display: 'none',\n },\n}));\n\n/**\n * A customizable Autocomplete component supporting search and combobox modes.\n * Supports single and multiple selection with dynamic tag rendering and optional loading states.\n *\n * @param props - The component props\n * @returns The rendered Autocomplete component\n */\nexport const Autocomplete = ({\n ariaLabel,\n className,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n loading = false,\n multiple = false,\n onChange,\n onInputChange,\n options = [],\n placeholder,\n required = false,\n shortcutHotkey = false,\n type = 'search',\n value,\n}: AutocompleteProps): JSX.Element => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [inputText, setInputText] = useState<string>('');\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const { translate } = useTranslation();\n\n /**\n * Normalizes the value prop for MUI Autocomplete.\n * Handles both single and multiple selection modes, ensuring the value\n * format matches the mode (array for multiple, single value/null for single).\n *\n * @returns Normalized value compatible with MUI Autocomplete\n */\n const getValue = (): AutocompleteProps['value'] => {\n // Multiple value selection\n if (multiple) {\n if (Array.isArray(value)) return value;\n if (value === null || value === undefined) return [];\n return [value as AutocompleteOption];\n }\n\n // Single value selection\n if (Array.isArray(value)) return value.length > 0 ? value[0] : null;\n return value ?? null;\n };\n\n const normalizedValue = getValue();\n const isSearch = type === 'search';\n const isCombobox = type === 'combobox';\n const isClearable = (Boolean(inputText) || Boolean(normalizedValue)) && !disabled;\n const isShortcutHotkeyEnabled = isSearch && shortcutHotkey && !normalizedValue && !disabled;\n const screenReaderOnlyId = useVisuallyHiddenId();\n\n const handleShortcutHotkeyFocus = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Hotkey handling and display for Cmd/Ctrl + K\n const { hotkeyText } = useShortcutHotkey({\n enabled: isShortcutHotkeyEnabled,\n onTrigger: handleShortcutHotkeyFocus,\n });\n\n // Dynamic limit tags calculation\n const { rootRef, limitTags } = useDynamicLimitTags({\n chipMax: 130,\n gap: 4,\n horizontalPadding: 32,\n reservedPx: isSearch ? 120 : 90,\n });\n\n /**\n * Close the dropdown (if open) when:\n * - the component is dynamically disabled.\n * - if search mode and no options are provided.\n */\n useEffect(() => {\n if (!isOpen) return;\n if (disabled) setIsOpen(false);\n if (isSearch && options.length === 0) setIsOpen(false);\n }, [isOpen, disabled, isSearch, options.length]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when:\n * - the component is disabled.\n * - if search mode and no options are provided.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) return;\n if (isSearch && options.length === 0) return;\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const renderSearchIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"start\">\n <SearchIcon aria-hidden=\"true\" data-testid=\"search-icon\" />\n </StyledInputAdornment>\n );\n };\n\n const renderPopupIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"end\">\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledInputAdornment>\n );\n };\n\n const renderShortcutHotkey = (): JSX.Element => {\n return (\n <ShortcutBadgeWrapper>\n <Badge label={hotkeyText} size=\"small\" tone=\"neutral\" />\n </ShortcutBadgeWrapper>\n );\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n return (\n <StyledEndAdornmentContainer>\n {loading ? <CircularProgress size=\"small\" /> : null}\n {isShortcutHotkeyEnabled ? renderShortcutHotkey() : null}\n </StyledEndAdornmentContainer>\n );\n };\n\n const renderInputField = (params: AutocompleteRenderInputParams): JSX.Element => {\n const hasOptions = Array.isArray(options) && options.length > 0;\n const showPopup = isCombobox || (isSearch && hasOptions);\n const ariaDescribedBy =\n [params.inputProps['aria-describedby'], isShortcutHotkeyEnabled ? screenReaderOnlyId : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <TextField\n disabled={disabled}\n errorText={errorText}\n fdKey={fdKey}\n fullWidth={fullWidth}\n helperText={helperText}\n inputRef={inputRef}\n label={label}\n placeholder={placeholder}\n required={required}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: (\n <>\n {renderEndAdornment()}\n {params.InputProps.endAdornment}\n </>\n ),\n startAdornment: (\n <>\n {isSearch ? renderSearchIcon() : null}\n {params.InputProps.startAdornment}\n </>\n ),\n },\n htmlInput: {\n ...params.inputProps,\n id: fdKey,\n 'aria-label': isSearch && !label ? ariaLabel : undefined,\n 'aria-describedby': ariaDescribedBy,\n // If the popup is not shown, hide the autocomplete listbox functionality from screen readers\n ...(!showPopup && {\n role: 'searchbox',\n 'aria-autocomplete': 'none',\n 'aria-invalid': !errorText && !required ? undefined : params.inputProps['aria-invalid'],\n }),\n },\n }}\n />\n );\n };\n\n const renderMenuOption = (\n optionProps: React.HTMLAttributes<HTMLLIElement> & { key: React.Key },\n option: AutocompleteOption,\n state: AutocompleteRenderOptionState,\n ): JSX.Element => {\n const { key, onClick, ...rest } = optionProps;\n\n if (multiple) {\n return (\n <MenuItem\n {...rest}\n key={key}\n checked={state.selected}\n label={option.label}\n onCheckedChange={(_checked, e) => {\n onClick?.(e as React.MouseEvent<HTMLLIElement, MouseEvent>);\n }}\n type=\"checkbox\"\n />\n );\n }\n\n return (\n <MenuItem\n {...rest}\n key={key}\n label={option.label}\n onClick={onClick}\n selected={state.selected}\n type=\"text\"\n />\n );\n };\n\n const renderSelectedTags = (\n selected: AutocompleteOption[],\n getTagProps: AutocompleteRenderGetTagProps,\n ): React.ReactNode =>\n selected.map((tag, index) => {\n const { key, onDelete, ...tagProps } = getTagProps({ index });\n const rawLabel = typeof tag === 'string' ? tag : tag.label;\n const label = truncateWithEllipsis(rawLabel, 13, { includeEllipsisInLimit: true });\n const isTruncated = label.endsWith('...');\n const tagKey = key ?? `tag-${typeof tag === 'string' ? tag : tag.value}`;\n\n if (isTruncated) {\n return (\n <Tooltip key={tagKey} title={rawLabel}>\n <span {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n </Tooltip>\n );\n }\n\n return (\n <span key={tagKey} {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n );\n });\n\n const handlePopupIndicatorClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n const handleChange = (\n event: React.SyntheticEvent,\n value: AutocompleteValue<AutocompleteOption, boolean, boolean, boolean>,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<AutocompleteOption>,\n ): void => {\n if (!onChange) {\n return;\n }\n onChange(event, value, reason, details);\n };\n\n const handleInputChange = (\n event: React.SyntheticEvent,\n value: string,\n reason: AutocompleteInputChangeReason,\n ): void => {\n setInputText(value);\n if (!onInputChange) {\n return;\n }\n onInputChange(event, value, reason);\n };\n\n /**\n * Returns all options without filtering for search mode.\n * Disables MUI's built-in client-side filtering when type is 'search'.\n */\n const disableClientFilter = (opts: AutocompleteOption[]): AutocompleteOption[] => opts;\n\n /**\n * Extracts the display label from an option.\n * Supports both object options and freeSolo string values.\n */\n const getOptionLabel = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : option.label;\n };\n\n /**\n * Provides a stable unique key for each option to optimize DOM reconciliation.\n */\n const getOptionKey = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : String(option.value);\n };\n\n /**\n * Determines equality between an option and the current value.\n * Handles both freeSolo string values and object options to prevent selection glitches.\n */\n const getIsOptionEqualToValue = (a: AutocompleteOption, b: AutocompleteOption): boolean => {\n if (b === null || b === undefined) {\n return false;\n }\n return typeof b === 'string' ? a.label === b || String(a.value) === b : a.value === b.value;\n };\n\n return (\n <>\n <StyledAutocomplete\n ref={rootRef}\n className={className}\n clearIcon={<CancelIcon size=\"md\" />}\n clearText={translate('Clear_selection')}\n disableClearable={!isClearable}\n disableCloseOnSelect={multiple}\n disabled={disabled}\n filterOptions={isSearch ? disableClientFilter : undefined}\n forcePopupIcon={isCombobox}\n freeSolo={isSearch}\n fullWidth={fullWidth}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n inputValue={inputText}\n isOptionEqualToValue={getIsOptionEqualToValue}\n limitTags={limitTags}\n loading={loading}\n loadingText={`${translate('Loading')}...`}\n multiple={multiple}\n noOptionsText={translate('No_options')}\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onInputChange={handleInputChange}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n openText={translate('Open_popup')}\n options={options}\n popupIcon={isCombobox ? renderPopupIcon() : null}\n renderInput={renderInputField}\n renderOption={renderMenuOption}\n renderTags={renderSelectedTags}\n slotProps={{\n popupIndicator: {\n onClick: handlePopupIndicatorClick,\n },\n }}\n value={normalizedValue}\n />\n\n {isShortcutHotkeyEnabled && (\n <VisuallyHidden fdKey=\"autocomplete-shortcut-hotkey\" id={screenReaderOnlyId}>\n {translate('Press_hotkey_to_focus_search', { hotkey: hotkeyText })}\n </VisuallyHidden>\n )}\n </>\n );\n};\n\nexport default Autocomplete;\n"],"names":["StyledAutocomplete","styled","shouldForwardProp","prop","fullWidth","width","StyledInputAdornment","MuiInputAdornment","theme","disabled","margin","color","palette","semantic","icon","StyledEndAdornmentContainer","Box","alignItems","display","gap","spacing","ShortcutBadgeWrapper","Autocomplete","ariaLabel","className","errorText","fdKey","helperText","label","loading","multiple","onChange","onInputChange","options","placeholder","required","shortcutHotkey","type","value","inputRef","useRef","inputText","setInputText","useState","isOpen","setIsOpen","translate","useTranslation","normalizedValue","Array","isArray","length","isSearch","isCombobox","isClearable","Boolean","isShortcutHotkeyEnabled","screenReaderOnlyId","useVisuallyHiddenId","handleShortcutHotkeyFocus","useCallback","current","focus","hotkeyText","useShortcutHotkey","enabled","onTrigger","rootRef","limitTags","useDynamicLimitTags","chipMax","horizontalPadding","reservedPx","useEffect","toggleOpen","open","undefined","prevOpen","_jsxs","_Fragment","children","_jsx","ref","clearIcon","CancelIcon","size","clearText","disableClearable","disableCloseOnSelect","filterOptions","opts","forcePopupIcon","freeSolo","getOptionKey","option","String","getOptionLabel","inputValue","isOptionEqualToValue","a","b","loadingText","noOptionsText","event","reason","details","onClose","onOpen","openText","popupIcon","position","ArrowUp01Icon","ArrowDown01Icon","renderInput","params","hasOptions","showPopup","ariaDescribedBy","inputProps","filter","join","TextField","slotProps","input","InputProps","endAdornment","CircularProgress","Badge","tone","startAdornment","SearchIcon","htmlInput","id","role","renderOption","optionProps","state","key","onClick","rest","_createElement","MenuItem","checked","selected","onCheckedChange","_checked","e","renderTags","getTagProps","map","tag","index","onDelete","tagProps","rawLabel","truncateWithEllipsis","includeEllipsisInLimit","isTruncated","endsWith","tagKey","Tooltip","title","Tag","onDismiss","popupIndicator","stopPropagation","VisuallyHidden","hotkey"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/Autocomplete/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport MuiAutocomplete, {\n type AutocompleteChangeDetails,\n type AutocompleteChangeReason,\n type AutocompleteInputChangeReason,\n type AutocompleteProps as MuiAutocompleteProps,\n type AutocompleteRenderGetTagProps,\n type AutocompleteRenderInputParams,\n type AutocompleteRenderOptionState,\n type AutocompleteValue,\n} from '@mui/material/Autocomplete';\nimport Box from '@mui/material/Box';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport { styled } from '@mui/material/styles';\n\nimport Badge from '@fd/components/atoms/Badge';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport MenuItem from '@fd/components/atoms/MenuItem';\nimport Tag from '@fd/components/atoms/Tag';\nimport TextField, { type TextFieldProps } from '@fd/components/atoms/TextField';\nimport VisuallyHidden, { useVisuallyHiddenId } from '@fd/components/atoms/VisuallyHidden';\nimport Tooltip from '@fd/components/molecules/Tooltip';\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelIcon from '@fd/icons/Cancel';\nimport SearchIcon from '@fd/icons/Search';\nimport { useTranslation } from '@fd/providers/TranslationProvider';\nimport { truncateWithEllipsis } from '@fd/utilities/stringUtilities';\n\nimport { useDynamicLimitTags } from './hooks/useDynamicLimitTags';\nimport { useShortcutHotkey } from './hooks/useShortcutHotkey';\n\n// Bind flags to MuiAutocomplete\ntype MuiCustomAutocompleteProps<\n M extends boolean = boolean, // Multiple\n DC extends boolean = boolean, // DisableClearable\n FS extends boolean = boolean, // FreeSolo\n> = MuiAutocompleteProps<AutocompleteOption, M, DC, FS>;\n\n/**\n * Represents an option in the Autocomplete dropdown.\n */\nexport interface AutocompleteOption {\n /** The label to display in the dropdown option. */\n label: string;\n /** The value to store in the dropdown option. */\n value: number | string;\n}\n\n/**\n * Props for the Autocomplete component.\n * Supports both single and multiple selection modes with optional search functionality.\n */\nexport interface AutocompleteProps extends Omit<\n TextFieldProps,\n 'endAdornment' | 'multiline' | 'onChange' | 'options' | 'startAdornment'\n> {\n /** Aria-label for the input when no label is provided. */\n ariaLabel?: string;\n /** Shows a loading indicator inside the input (e.g., while fetching). */\n loading?: boolean;\n /** Enables selection of multiple options and shows checkboxes and tags for selected values. */\n multiple?: MuiCustomAutocompleteProps['multiple'];\n /** Called when the selected value(s) change. */\n onChange: MuiCustomAutocompleteProps['onChange'];\n /** Called when the input text changes (typing or programmatic updates). */\n onInputChange?: MuiCustomAutocompleteProps['onInputChange'];\n /** Options to display in the dropdown list. */\n options: AutocompleteOption[];\n /** Shows the keyboard shortcut badge (Cmd/Ctrl + K) and enables focusing via the shortcut when in search mode. */\n shortcutHotkey?: boolean;\n /** Visual behavior: 'search' shows a leading search icon; 'combobox' shows a popup button. */\n type?: 'combobox' | 'search';\n /** Controlled value (single option, array for multiple, or null). */\n value: MuiCustomAutocompleteProps['value'];\n}\n\n// Bind flags to MuiAutocomplete, see MuiCustomAutocompleteProps for more details\nconst MuiCustomAutocomplete = MuiAutocomplete<AutocompleteOption, boolean, boolean, boolean>;\nconst StyledAutocomplete = styled(MuiCustomAutocomplete, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n width: fullWidth ? '100%' : 'min(364px, 100%)',\n}));\n\nconst StyledInputAdornment = styled(MuiInputAdornment, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n '&.MuiInputAdornment-positionEnd': {\n margin: 0,\n },\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledEndAdornmentContainer = styled(Box)(({ theme }) => ({\n alignItems: 'center',\n display: 'flex',\n gap: theme.spacing(1),\n}));\n\nconst ShortcutBadgeWrapper = styled('span')(() => ({\n display: 'inline-flex',\n\n // hide when input root is focused\n '.Mui-focused &': {\n display: 'none',\n },\n}));\n\n/**\n * A customizable Autocomplete component supporting search and combobox modes.\n * Supports single and multiple selection with dynamic tag rendering and optional loading states.\n *\n * @param props - The component props\n * @returns The rendered Autocomplete component\n */\nexport const Autocomplete = ({\n ariaLabel,\n className,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n loading = false,\n multiple = false,\n onChange,\n onInputChange,\n options = [],\n placeholder,\n required = false,\n shortcutHotkey = false,\n type = 'search',\n value,\n}: AutocompleteProps): JSX.Element => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [inputText, setInputText] = useState<string>('');\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const { translate } = useTranslation();\n\n /**\n * Normalizes the value prop for MUI Autocomplete.\n * Handles both single and multiple selection modes, ensuring the value\n * format matches the mode (array for multiple, single value/null for single).\n *\n * @returns Normalized value compatible with MUI Autocomplete\n */\n const getValue = (): AutocompleteProps['value'] => {\n // Multiple value selection\n if (multiple) {\n if (Array.isArray(value)) return value;\n if (value === null || value === undefined) return [];\n return [value as AutocompleteOption];\n }\n\n // Single value selection\n if (Array.isArray(value)) return value.length > 0 ? value[0] : null;\n return value ?? null;\n };\n\n const normalizedValue = getValue();\n const isSearch = type === 'search';\n const isCombobox = type === 'combobox';\n const isClearable = (Boolean(inputText) || Boolean(normalizedValue)) && !disabled;\n const isShortcutHotkeyEnabled = isSearch && shortcutHotkey && !normalizedValue && !disabled;\n const screenReaderOnlyId = useVisuallyHiddenId();\n\n const handleShortcutHotkeyFocus = useCallback(() => {\n inputRef.current?.focus();\n }, []);\n\n // Hotkey handling and display for Cmd/Ctrl + K\n const { hotkeyText } = useShortcutHotkey({\n enabled: isShortcutHotkeyEnabled,\n onTrigger: handleShortcutHotkeyFocus,\n });\n\n // Dynamic limit tags calculation\n const { rootRef, limitTags } = useDynamicLimitTags({\n chipMax: 130,\n gap: 4,\n horizontalPadding: 32,\n reservedPx: isSearch ? 120 : 90,\n });\n\n /**\n * Close the dropdown (if open) when:\n * - the component is dynamically disabled.\n * - if search mode and no options are provided.\n */\n useEffect(() => {\n if (!isOpen) return;\n if (disabled) setIsOpen(false);\n if (isSearch && options.length === 0) setIsOpen(false);\n }, [isOpen, disabled, isSearch, options.length]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when:\n * - the component is disabled.\n * - if search mode and no options are provided.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) return;\n if (isSearch && options.length === 0) return;\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const renderSearchIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"start\">\n <SearchIcon aria-hidden=\"true\" data-fd=\"search-icon\" />\n </StyledInputAdornment>\n );\n };\n\n const renderPopupIcon = (): JSX.Element => {\n return (\n <StyledInputAdornment disabled={disabled} position=\"end\">\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledInputAdornment>\n );\n };\n\n const renderShortcutHotkey = (): JSX.Element => {\n return (\n <ShortcutBadgeWrapper>\n <Badge label={hotkeyText} size=\"small\" tone=\"neutral\" />\n </ShortcutBadgeWrapper>\n );\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n return (\n <StyledEndAdornmentContainer>\n {loading ? <CircularProgress size=\"small\" /> : null}\n {isShortcutHotkeyEnabled ? renderShortcutHotkey() : null}\n </StyledEndAdornmentContainer>\n );\n };\n\n const renderInputField = (params: AutocompleteRenderInputParams): JSX.Element => {\n const hasOptions = Array.isArray(options) && options.length > 0;\n const showPopup = isCombobox || (isSearch && hasOptions);\n const ariaDescribedBy =\n [params.inputProps['aria-describedby'], isShortcutHotkeyEnabled ? screenReaderOnlyId : undefined]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <TextField\n disabled={disabled}\n errorText={errorText}\n fdKey={fdKey}\n fullWidth={fullWidth}\n helperText={helperText}\n inputRef={inputRef}\n label={label}\n placeholder={placeholder}\n required={required}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: (\n <>\n {renderEndAdornment()}\n {params.InputProps.endAdornment}\n </>\n ),\n startAdornment: (\n <>\n {isSearch ? renderSearchIcon() : null}\n {params.InputProps.startAdornment}\n </>\n ),\n },\n htmlInput: {\n ...params.inputProps,\n id: fdKey,\n 'aria-label': isSearch && !label ? ariaLabel : undefined,\n 'aria-describedby': ariaDescribedBy,\n // If the popup is not shown, hide the autocomplete listbox functionality from screen readers\n ...(!showPopup && {\n role: 'searchbox',\n 'aria-autocomplete': 'none',\n 'aria-invalid': !errorText && !required ? undefined : params.inputProps['aria-invalid'],\n }),\n },\n }}\n />\n );\n };\n\n const renderMenuOption = (\n optionProps: React.HTMLAttributes<HTMLLIElement> & { key: React.Key },\n option: AutocompleteOption,\n state: AutocompleteRenderOptionState,\n ): JSX.Element => {\n const { key, onClick, ...rest } = optionProps;\n\n if (multiple) {\n return (\n <MenuItem\n {...rest}\n key={key}\n checked={state.selected}\n label={option.label}\n onCheckedChange={(_checked, e) => {\n onClick?.(e as React.MouseEvent<HTMLLIElement, MouseEvent>);\n }}\n type=\"checkbox\"\n />\n );\n }\n\n return (\n <MenuItem\n {...rest}\n key={key}\n label={option.label}\n onClick={onClick}\n selected={state.selected}\n type=\"text\"\n />\n );\n };\n\n const renderSelectedTags = (\n selected: AutocompleteOption[],\n getTagProps: AutocompleteRenderGetTagProps,\n ): React.ReactNode =>\n selected.map((tag, index) => {\n const { key, onDelete, ...tagProps } = getTagProps({ index });\n const rawLabel = typeof tag === 'string' ? tag : tag.label;\n const label = truncateWithEllipsis(rawLabel, 13, { includeEllipsisInLimit: true });\n const isTruncated = label.endsWith('...');\n const tagKey = key ?? `tag-${typeof tag === 'string' ? tag : tag.value}`;\n\n if (isTruncated) {\n return (\n <Tooltip key={tagKey} title={rawLabel}>\n <span {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n </Tooltip>\n );\n }\n\n return (\n <span key={tagKey} {...tagProps}>\n <Tag label={label} onDismiss={onDelete} />\n </span>\n );\n });\n\n const handlePopupIndicatorClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n const handleChange = (\n event: React.SyntheticEvent,\n value: AutocompleteValue<AutocompleteOption, boolean, boolean, boolean>,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<AutocompleteOption>,\n ): void => {\n if (!onChange) {\n return;\n }\n onChange(event, value, reason, details);\n };\n\n const handleInputChange = (\n event: React.SyntheticEvent,\n value: string,\n reason: AutocompleteInputChangeReason,\n ): void => {\n setInputText(value);\n if (!onInputChange) {\n return;\n }\n onInputChange(event, value, reason);\n };\n\n /**\n * Returns all options without filtering for search mode.\n * Disables MUI's built-in client-side filtering when type is 'search'.\n */\n const disableClientFilter = (opts: AutocompleteOption[]): AutocompleteOption[] => opts;\n\n /**\n * Extracts the display label from an option.\n * Supports both object options and freeSolo string values.\n */\n const getOptionLabel = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : option.label;\n };\n\n /**\n * Provides a stable unique key for each option to optimize DOM reconciliation.\n */\n const getOptionKey = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : String(option.value);\n };\n\n /**\n * Determines equality between an option and the current value.\n * Handles both freeSolo string values and object options to prevent selection glitches.\n */\n const getIsOptionEqualToValue = (a: AutocompleteOption, b: AutocompleteOption): boolean => {\n if (b === null || b === undefined) {\n return false;\n }\n return typeof b === 'string' ? a.label === b || String(a.value) === b : a.value === b.value;\n };\n\n return (\n <>\n <StyledAutocomplete\n ref={rootRef}\n className={className}\n clearIcon={<CancelIcon size=\"md\" />}\n clearText={translate('Clear_selection')}\n disableClearable={!isClearable}\n disableCloseOnSelect={multiple}\n disabled={disabled}\n filterOptions={isSearch ? disableClientFilter : undefined}\n forcePopupIcon={isCombobox}\n freeSolo={isSearch}\n fullWidth={fullWidth}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n inputValue={inputText}\n isOptionEqualToValue={getIsOptionEqualToValue}\n limitTags={limitTags}\n loading={loading}\n loadingText={`${translate('Loading')}...`}\n multiple={multiple}\n noOptionsText={translate('No_options')}\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onInputChange={handleInputChange}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n openText={translate('Open_popup')}\n options={options}\n popupIcon={isCombobox ? renderPopupIcon() : null}\n renderInput={renderInputField}\n renderOption={renderMenuOption}\n renderTags={renderSelectedTags}\n slotProps={{\n popupIndicator: {\n onClick: handlePopupIndicatorClick,\n },\n }}\n value={normalizedValue}\n />\n\n {isShortcutHotkeyEnabled && (\n <VisuallyHidden fdKey=\"autocomplete-shortcut-hotkey\" id={screenReaderOnlyId}>\n {translate('Press_hotkey_to_focus_search', { hotkey: hotkeyText })}\n </VisuallyHidden>\n )}\n </>\n );\n};\n\nexport default Autocomplete;\n"],"names":["StyledAutocomplete","styled","shouldForwardProp","prop","fullWidth","width","StyledInputAdornment","MuiInputAdornment","theme","disabled","margin","color","palette","semantic","icon","StyledEndAdornmentContainer","Box","alignItems","display","gap","spacing","ShortcutBadgeWrapper","Autocomplete","ariaLabel","className","errorText","fdKey","helperText","label","loading","multiple","onChange","onInputChange","options","placeholder","required","shortcutHotkey","type","value","inputRef","useRef","inputText","setInputText","useState","isOpen","setIsOpen","translate","useTranslation","normalizedValue","Array","isArray","length","isSearch","isCombobox","isClearable","Boolean","isShortcutHotkeyEnabled","screenReaderOnlyId","useVisuallyHiddenId","handleShortcutHotkeyFocus","useCallback","current","focus","hotkeyText","useShortcutHotkey","enabled","onTrigger","rootRef","limitTags","useDynamicLimitTags","chipMax","horizontalPadding","reservedPx","useEffect","toggleOpen","open","undefined","prevOpen","_jsxs","_Fragment","children","_jsx","ref","clearIcon","CancelIcon","size","clearText","disableClearable","disableCloseOnSelect","filterOptions","opts","forcePopupIcon","freeSolo","getOptionKey","option","String","getOptionLabel","inputValue","isOptionEqualToValue","a","b","loadingText","noOptionsText","event","reason","details","onClose","onOpen","openText","popupIcon","position","ArrowUp01Icon","ArrowDown01Icon","renderInput","params","hasOptions","showPopup","ariaDescribedBy","inputProps","filter","join","TextField","slotProps","input","InputProps","endAdornment","CircularProgress","Badge","tone","startAdornment","SearchIcon","htmlInput","id","role","renderOption","optionProps","state","key","onClick","rest","_createElement","MenuItem","checked","selected","onCheckedChange","_checked","e","renderTags","getTagProps","map","tag","index","onDelete","tagProps","rawLabel","truncateWithEllipsis","includeEllipsisInLimit","isTruncated","endsWith","tagKey","Tooltip","title","Tag","onDismiss","popupIndicator","stopPropagation","VisuallyHidden","hotkey"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),t=require("@mui/material/Box"),i=require("@mui/material/styles"),l=require("@mui/material/Typography"),r=require("../../atoms/Button/index.cjs.js"),a=require("../../atoms/IconContainer/index.cjs.js"),n=require("../ButtonGroup/index.cjs.js");const s=i.styled(t,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:t})=>({display:"flex",flexDirection:"column",alignItems:"flex-start",gap:e.spacing(3),width:t?"100%":"536px"}))),o=i.styled(t)((()=>({display:"flex",justifyContent:"flex-end",width:"100%"}))),d=i.styled(t)((({theme:e})=>({display:"flex",flexDirection:"column",alignItems:"flex-start",gap:e.spacing(1)}))),c=i.styled(l)((({theme:e})=>({color:e.palette.semantic.text["text-weak"]}))),u=({title:t,description:i,icon:u,actionButtons:x,fullWidth:m=!1})=>e.jsxs(s,{"data-
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),t=require("@mui/material/Box"),i=require("@mui/material/styles"),l=require("@mui/material/Typography"),r=require("../../atoms/Button/index.cjs.js"),a=require("../../atoms/IconContainer/index.cjs.js"),n=require("../ButtonGroup/index.cjs.js");const s=i.styled(t,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:t})=>({display:"flex",flexDirection:"column",alignItems:"flex-start",gap:e.spacing(3),width:t?"100%":"536px"}))),o=i.styled(t)((()=>({display:"flex",justifyContent:"flex-end",width:"100%"}))),d=i.styled(t)((({theme:e})=>({display:"flex",flexDirection:"column",alignItems:"flex-start",gap:e.spacing(1)}))),c=i.styled(l)((({theme:e})=>({color:e.palette.semantic.text["text-weak"]}))),u=({title:t,description:i,icon:u,actionButtons:x,fullWidth:m=!1})=>e.jsxs(s,{"data-fd":"empty-state-container",fullWidth:m,children:[u?e.jsx(a,{fdKey:"empty-state-icon-container",icon:u,style:"filled",tone:"neutral"}):null,e.jsxs(d,{children:[e.jsx(l,{variant:"h3Strong",children:t}),e.jsx(c,{variant:"b1Weak",children:i})]}),(()=>{if(x)return Array.isArray(x)?e.jsx(n,{align:"right",layout:"horizontal",order:"default",size:"medium",children:x.map((t=>{const i=`action-button-${t.label.replace(/\s+/g,"-").toLowerCase()}`;return e.jsx(r.Button,{fdKey:t.label,onClick:t.onClick,variant:t.variant,children:t.label},i)}))}):e.jsx(o,{children:e.jsx(r.Button,{fdKey:x.label,onClick:x.onClick,variant:x.variant,children:x.label})})})()]});exports.EmptyState=u,exports.default=u;
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/EmptyState/index.tsx"],"sourcesContent":["import Box from '@mui/material/Box';\nimport { styled } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\n\nimport Button from '@fd/components/atoms/Button';\nimport type { ButtonType } from '@fd/components/atoms/Button/getButtonStyles';\nimport IconContainer from '@fd/components/atoms/IconContainer';\n\nimport ButtonGroup from '../ButtonGroup';\n\n/** Action button configuration */\nexport interface ActionButton {\n /** Text label for the action button */\n label: string;\n /** Visual variant of the action button */\n variant?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n}\n\n/** EmptyState component props */\nexport interface EmptyStateProps {\n /** Main heading text of the empty state */\n title: string;\n /** Detailed description text of the empty state */\n description: string;\n /** Icon to display */\n icon?: React.ReactNode;\n /** Action buttons to display */\n actionButtons?: ActionButton | ActionButton[];\n /** Whether the empty state should be full width */\n fullWidth?: boolean;\n}\n\nconst StyledContainer = styled(Box, { shouldForwardProp: (prop) => prop !== 'fullWidth' })<{\n fullWidth?: boolean;\n}>(({ theme, fullWidth }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: theme.spacing(3),\n width: fullWidth ? '100%' : '536px',\n}));\n\nconst StyledOneActionButtonContainer = styled(Box)(() => ({\n display: 'flex',\n justifyContent: 'flex-end',\n width: '100%',\n}));\n\nconst StyledTextContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: theme.spacing(1),\n}));\n\nconst StyledDescription = styled(Typography)(({ theme }) => ({\n color: theme.palette.semantic.text['text-weak'],\n}));\n\n/**\n * EmptyState component is used when a table, list, or chart has no data to display.\n *\n * @param props - The component props\n * @returns The empty state component\n */\n\nexport const EmptyState = ({\n title,\n description,\n icon,\n actionButtons,\n fullWidth = false,\n}: EmptyStateProps): JSX.Element => {\n const renderActions = (): React.ReactNode => {\n if (!actionButtons) {\n return undefined;\n }\n\n if (Array.isArray(actionButtons)) {\n return (\n <ButtonGroup align=\"right\" layout=\"horizontal\" order=\"default\" size=\"medium\">\n {actionButtons.map((button) => {\n const key = `action-button-${button.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <Button key={key} fdKey={button.label} onClick={button.onClick} variant={button.variant}>\n {button.label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n }\n\n return (\n <StyledOneActionButtonContainer>\n <Button fdKey={actionButtons.label} onClick={actionButtons.onClick} variant={actionButtons.variant}>\n {actionButtons.label}\n </Button>\n </StyledOneActionButtonContainer>\n );\n };\n\n const renderIcon = (): React.ReactNode => {\n if (!icon) {\n return null;\n }\n\n return
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/EmptyState/index.tsx"],"sourcesContent":["import Box from '@mui/material/Box';\nimport { styled } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\n\nimport Button from '@fd/components/atoms/Button';\nimport type { ButtonType } from '@fd/components/atoms/Button/getButtonStyles';\nimport IconContainer from '@fd/components/atoms/IconContainer';\n\nimport ButtonGroup from '../ButtonGroup';\n\n/** Action button configuration */\nexport interface ActionButton {\n /** Text label for the action button */\n label: string;\n /** Visual variant of the action button */\n variant?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n}\n\n/** EmptyState component props */\nexport interface EmptyStateProps {\n /** Main heading text of the empty state */\n title: string;\n /** Detailed description text of the empty state */\n description: string;\n /** Icon to display */\n icon?: React.ReactNode;\n /** Action buttons to display */\n actionButtons?: ActionButton | ActionButton[];\n /** Whether the empty state should be full width */\n fullWidth?: boolean;\n}\n\nconst StyledContainer = styled(Box, { shouldForwardProp: (prop) => prop !== 'fullWidth' })<{\n fullWidth?: boolean;\n}>(({ theme, fullWidth }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: theme.spacing(3),\n width: fullWidth ? '100%' : '536px',\n}));\n\nconst StyledOneActionButtonContainer = styled(Box)(() => ({\n display: 'flex',\n justifyContent: 'flex-end',\n width: '100%',\n}));\n\nconst StyledTextContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: theme.spacing(1),\n}));\n\nconst StyledDescription = styled(Typography)(({ theme }) => ({\n color: theme.palette.semantic.text['text-weak'],\n}));\n\n/**\n * EmptyState component is used when a table, list, or chart has no data to display.\n *\n * @param props - The component props\n * @returns The empty state component\n */\n\nexport const EmptyState = ({\n title,\n description,\n icon,\n actionButtons,\n fullWidth = false,\n}: EmptyStateProps): JSX.Element => {\n const renderActions = (): React.ReactNode => {\n if (!actionButtons) {\n return undefined;\n }\n\n if (Array.isArray(actionButtons)) {\n return (\n <ButtonGroup align=\"right\" layout=\"horizontal\" order=\"default\" size=\"medium\">\n {actionButtons.map((button) => {\n const key = `action-button-${button.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <Button key={key} fdKey={button.label} onClick={button.onClick} variant={button.variant}>\n {button.label}\n </Button>\n );\n })}\n </ButtonGroup>\n );\n }\n\n return (\n <StyledOneActionButtonContainer>\n <Button fdKey={actionButtons.label} onClick={actionButtons.onClick} variant={actionButtons.variant}>\n {actionButtons.label}\n </Button>\n </StyledOneActionButtonContainer>\n );\n };\n\n const renderIcon = (): React.ReactNode => {\n if (!icon) {\n return null;\n }\n\n return <IconContainer fdKey=\"empty-state-icon-container\" icon={icon} style=\"filled\" tone=\"neutral\" />;\n };\n\n return (\n <StyledContainer data-fd=\"empty-state-container\" fullWidth={fullWidth}>\n {renderIcon()}\n <StyledTextContainer>\n <Typography variant=\"h3Strong\">{title}</Typography>\n <StyledDescription variant=\"b1Weak\">{description}</StyledDescription>\n </StyledTextContainer>\n {renderActions()}\n </StyledContainer>\n );\n};\n\nexport default EmptyState;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","alignItems","gap","spacing","width","StyledOneActionButtonContainer","justifyContent","StyledTextContainer","StyledDescription","Typography","color","palette","semantic","text","EmptyState","title","description","icon","actionButtons","_jsxs","children","_jsx","IconContainer","fdKey","style","tone","variant","Array","isArray","ButtonGroup","align","layout","order","size","map","button","key","label","replace","toLowerCase","Button","onClick","renderActions"],"mappings":"wVAkCA,MAAMA,EAAkBC,EAAAA,OAAOC,EAAK,CAAEC,kBAAoBC,GAAkB,cAATA,GAA3CH,EAErB,EAAGI,QAAOC,gBAAW,CACtBC,QAAS,OACTC,cAAe,SACfC,WAAY,aACZC,IAAKL,EAAMM,QAAQ,GACnBC,MAAON,EAAY,OAAS,YAGxBO,EAAiCZ,EAAAA,OAAOC,EAAPD,EAAY,KAAA,CACjDM,QAAS,OACTO,eAAgB,WAChBF,MAAO,WAGHG,EAAsBd,EAAAA,OAAOC,EAAPD,EAAY,EAAGI,YAAO,CAChDE,QAAS,OACTC,cAAe,SACfC,WAAY,aACZC,IAAKL,EAAMM,QAAQ,OAGfK,EAAoBf,EAAAA,OAAOgB,EAAPhB,EAAmB,EAAGI,YAAO,CACrDa,MAAOb,EAAMc,QAAQC,SAASC,KAAK,iBAUxBC,EAAa,EACxBC,QACAC,cACAC,OACAC,gBACApB,aAAY,KAyCVqB,EAAAA,KAAC3B,aAAwB,wBAAwBM,UAAWA,EAASsB,SAAA,CARhEH,EAIEI,MAACC,EAAa,CAACC,MAAM,6BAA6BN,KAAMA,EAAMO,MAAM,SAASC,KAAK,YAHhF,KASPN,EAAAA,KAACZ,EAAmB,CAAAa,SAAA,CAClBC,EAAAA,IAACZ,EAAU,CAACiB,QAAQ,oBAAYX,IAChCM,EAAAA,IAACb,GAAkBkB,QAAQ,SAAQN,SAAEJ,OA3CrB,MACpB,GAAKE,EAIL,OAAIS,MAAMC,QAAQV,GAEdG,EAAAA,IAACQ,EAAW,CAACC,MAAM,QAAQC,OAAO,aAAaC,MAAM,UAAUC,KAAK,SAAQb,SACzEF,EAAcgB,KAAKC,IAClB,MAAMC,EAAM,iBAAiBD,EAAOE,MAAMC,QAAQ,OAAQ,KAAKC,gBAE/D,OACElB,EAAAA,IAACmB,EAAAA,OAAM,CAAWjB,MAAOY,EAAOE,MAAOI,QAASN,EAAOM,QAASf,QAASS,EAAOT,QAAON,SACpFe,EAAOE,OADGD,QAUrBf,EAAAA,IAAChB,EAA8B,CAAAe,SAC7BC,EAAAA,IAACmB,SAAM,CAACjB,MAAOL,EAAcmB,MAAOI,QAASvB,EAAcuB,QAASf,QAASR,EAAcQ,QAAON,SAC/FF,EAAcmB,WAqBlBK"}
|