smarthr-ui 97.0.0 → 98.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/lib/components/AppHeader/components/common/AppLauncherFeatures.cjs +1 -1
- package/lib/components/AppHeader/components/common/AppLauncherFeatures.js +1 -1
- package/lib/components/AppHeader/components/common/AppLauncherSortDropdown.cjs +1 -1
- package/lib/components/AppHeader/components/common/AppLauncherSortDropdown.js +1 -1
- package/lib/components/AppHeader/components/desktop/AppLauncher.cjs +5 -5
- package/lib/components/AppHeader/components/desktop/AppLauncher.cjs.map +1 -1
- package/lib/components/AppHeader/components/desktop/AppLauncher.js +5 -5
- package/lib/components/AppHeader/components/desktop/AppLauncher.js.map +1 -1
- package/lib/components/AppHeader/components/desktop/DesktopHeader.cjs +1 -1
- package/lib/components/AppHeader/components/desktop/DesktopHeader.js +1 -1
- package/lib/components/AppHeader/components/desktop/ReleaseNotesDropdown.cjs +1 -1
- package/lib/components/AppHeader/components/desktop/ReleaseNotesDropdown.js +1 -1
- package/lib/components/AppHeader/components/desktop/UserInfo.cjs +1 -1
- package/lib/components/AppHeader/components/desktop/UserInfo.js +1 -1
- package/lib/components/AppHeader/components/mobile/AppLauncher.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/AppLauncher.js +1 -1
- package/lib/components/AppHeader/components/mobile/AppLauncherFilterDropdown.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/AppLauncherFilterDropdown.js +1 -1
- package/lib/components/AppHeader/components/mobile/Help.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/Help.js +1 -1
- package/lib/components/AppHeader/components/mobile/LanguageSelector.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/LanguageSelector.js +1 -1
- package/lib/components/AppHeader/components/mobile/Menu.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/Menu.js +1 -1
- package/lib/components/AppHeader/components/mobile/MenuAccordion.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/MenuAccordion.js +1 -1
- package/lib/components/AppHeader/components/mobile/MenuDialog.cjs +2 -2
- package/lib/components/AppHeader/components/mobile/MenuDialog.js +2 -2
- package/lib/components/AppHeader/components/mobile/MenuSubHeading.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/MenuSubHeading.js +1 -1
- package/lib/components/AppHeader/components/mobile/ReleaseNote.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/ReleaseNote.js +1 -1
- package/lib/components/AppHeader/components/mobile/UserInfo.cjs +2 -2
- package/lib/components/AppHeader/components/mobile/UserInfo.js +2 -2
- package/lib/components/Browser/Browser.cjs +11 -7
- package/lib/components/Browser/Browser.cjs.map +1 -1
- package/lib/components/Browser/Browser.js +12 -8
- package/lib/components/Browser/Browser.js.map +1 -1
- package/lib/components/Calendar/Calendar.cjs +1 -1
- package/lib/components/Calendar/Calendar.js +1 -1
- package/lib/components/Calendar/CalendarTable.cjs +1 -1
- package/lib/components/Calendar/CalendarTable.js +1 -1
- package/lib/components/Calendar/YearPicker.cjs +1 -1
- package/lib/components/Calendar/YearPicker.js +1 -1
- package/lib/components/Combobox/ItemButton.cjs +27 -26
- package/lib/components/Combobox/ItemButton.cjs.map +1 -1
- package/lib/components/Combobox/ItemButton.js +28 -27
- package/lib/components/Combobox/ItemButton.js.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs +122 -134
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +123 -135
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.cjs +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.js +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +79 -46
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +81 -48
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
- package/lib/components/Combobox/useListbox.cjs +1 -1
- package/lib/components/Combobox/useListbox.js +1 -1
- package/lib/components/Combobox/useOptions.cjs +3 -1
- package/lib/components/Combobox/useOptions.cjs.map +1 -1
- package/lib/components/Combobox/useOptions.js +4 -2
- package/lib/components/Combobox/useOptions.js.map +1 -1
- package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.cjs +3 -3
- package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.cjs.map +1 -1
- package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.js +3 -3
- package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.js.map +1 -1
- package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs +3 -3
- package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs.map +1 -1
- package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js +3 -3
- package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js.map +1 -1
- package/lib/components/Dialog/ControlledMessageDialog/MessageDialogContentInner.cjs +1 -1
- package/lib/components/Dialog/ControlledMessageDialog/MessageDialogContentInner.js +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs +2 -2
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs.map +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js +2 -2
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js.map +1 -1
- package/lib/components/Dialog/DialogContentResponseStatusMessage.cjs +3 -8
- package/lib/components/Dialog/DialogContentResponseStatusMessage.cjs.map +1 -1
- package/lib/components/Dialog/DialogContentResponseStatusMessage.d.ts +1 -1
- package/lib/components/Dialog/DialogContentResponseStatusMessage.js +3 -8
- package/lib/components/Dialog/DialogContentResponseStatusMessage.js.map +1 -1
- package/lib/components/Dialog/FocusTrap.cjs +4 -1
- package/lib/components/Dialog/FocusTrap.cjs.map +1 -1
- package/lib/components/Dialog/FocusTrap.js +4 -1
- package/lib/components/Dialog/FocusTrap.js.map +1 -1
- package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs +1 -1
- package/lib/components/Dialog/ModelessDialog/ModelessDialog.js +1 -1
- package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs +9 -3
- package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs.map +1 -1
- package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js +9 -3
- package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js.map +1 -1
- package/lib/components/Disclosure/DisclosureTrigger.cjs +8 -4
- package/lib/components/Disclosure/DisclosureTrigger.cjs.map +1 -1
- package/lib/components/Disclosure/DisclosureTrigger.js +8 -4
- package/lib/components/Disclosure/DisclosureTrigger.js.map +1 -1
- package/lib/components/DropZone/DropZone.cjs +1 -1
- package/lib/components/DropZone/DropZone.js +1 -1
- package/lib/components/Dropdown/Dropdown.cjs +36 -34
- package/lib/components/Dropdown/Dropdown.cjs.map +1 -1
- package/lib/components/Dropdown/Dropdown.js +37 -35
- package/lib/components/Dropdown/Dropdown.js.map +1 -1
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs +1 -1
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js +1 -1
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs +3 -5
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs.map +1 -1
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.d.ts +1 -1
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js +3 -5
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js.map +1 -1
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs +1 -1
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.js +1 -1
- package/lib/components/ErrorScreen/AuthErrorScreen.cjs +1 -1
- package/lib/components/ErrorScreen/AuthErrorScreen.js +1 -1
- package/lib/components/ErrorScreen/ForbiddenErrorScreen.cjs +1 -1
- package/lib/components/ErrorScreen/ForbiddenErrorScreen.js +1 -1
- package/lib/components/ErrorScreen/NotFoundErrorScreen.cjs +1 -1
- package/lib/components/ErrorScreen/NotFoundErrorScreen.js +1 -1
- package/lib/components/ErrorScreen/UnauthorizedErrorScreen.cjs +1 -1
- package/lib/components/ErrorScreen/UnauthorizedErrorScreen.js +1 -1
- package/lib/components/FileViewer/FileViewer.cjs +35 -2
- package/lib/components/FileViewer/FileViewer.cjs.map +1 -1
- package/lib/components/FileViewer/FileViewer.js +37 -4
- package/lib/components/FileViewer/FileViewer.js.map +1 -1
- package/lib/components/FileViewer/PDFViewer.cjs +59 -2
- package/lib/components/FileViewer/PDFViewer.cjs.map +1 -1
- package/lib/components/FileViewer/PDFViewer.d.ts +6 -1
- package/lib/components/FileViewer/PDFViewer.js +60 -3
- package/lib/components/FileViewer/PDFViewer.js.map +1 -1
- package/lib/components/FileViewer/SearchController.cjs +105 -0
- package/lib/components/FileViewer/SearchController.cjs.map +1 -0
- package/lib/components/FileViewer/SearchController.d.ts +7 -0
- package/lib/components/FileViewer/SearchController.js +103 -0
- package/lib/components/FileViewer/SearchController.js.map +1 -0
- package/lib/components/FileViewer/buildCustomTextRenderer.cjs +55 -0
- package/lib/components/FileViewer/buildCustomTextRenderer.cjs.map +1 -0
- package/lib/components/FileViewer/buildCustomTextRenderer.d.ts +9 -0
- package/lib/components/FileViewer/buildCustomTextRenderer.js +50 -0
- package/lib/components/FileViewer/buildCustomTextRenderer.js.map +1 -0
- package/lib/components/FileViewer/types.d.ts +7 -0
- package/lib/components/FileViewer/usePDFSearch.cjs +148 -0
- package/lib/components/FileViewer/usePDFSearch.cjs.map +1 -0
- package/lib/components/FileViewer/usePDFSearch.d.ts +19 -0
- package/lib/components/FileViewer/usePDFSearch.js +143 -0
- package/lib/components/FileViewer/usePDFSearch.js.map +1 -0
- package/lib/components/FormControl/FormControl.cjs +2 -22
- package/lib/components/FormControl/FormControl.cjs.map +1 -1
- package/lib/components/FormControl/FormControl.js +2 -22
- package/lib/components/FormControl/FormControl.js.map +1 -1
- package/lib/components/Header/AppLauncher/AppLauncher.cjs +1 -1
- package/lib/components/Header/AppLauncher/AppLauncher.js +1 -1
- package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.cjs +1 -1
- package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.js +1 -1
- package/lib/components/Icon/FaIcon.js +1 -1
- package/lib/components/Icon/OpenInNewTabIcon.cjs +1 -1
- package/lib/components/Icon/OpenInNewTabIcon.js +1 -1
- package/lib/components/InformationPanel/InformationPanel.cjs +1 -1
- package/lib/components/InformationPanel/InformationPanel.js +1 -1
- package/lib/components/Input/SearchInput/SearchInputIcon.cjs +1 -1
- package/lib/components/Input/SearchInput/SearchInputIcon.js +1 -1
- package/lib/components/InputFile/InputFileMultiplyAppendable.cjs +1 -1
- package/lib/components/InputFile/InputFileMultiplyAppendable.js +1 -1
- package/lib/components/InputFile/InputFileNative.cjs +1 -1
- package/lib/components/InputFile/InputFileNative.js +1 -1
- package/lib/components/Layout/Cluster/Cluster.cjs +0 -1
- package/lib/components/Layout/Cluster/Cluster.cjs.map +1 -1
- package/lib/components/Layout/Cluster/Cluster.js +0 -1
- package/lib/components/Layout/Cluster/Cluster.js.map +1 -1
- package/lib/components/Layout/Container/Container.cjs +1 -5
- package/lib/components/Layout/Container/Container.cjs.map +1 -1
- package/lib/components/Layout/Container/Container.js +1 -5
- package/lib/components/Layout/Container/Container.js.map +1 -1
- package/lib/components/Layout/Stack/Stack.cjs +22 -22
- package/lib/components/Layout/Stack/Stack.cjs.map +1 -1
- package/lib/components/Layout/Stack/Stack.js +22 -22
- package/lib/components/Layout/Stack/Stack.js.map +1 -1
- package/lib/components/Loader/LoaderSpinner.cjs +1 -1
- package/lib/components/Loader/LoaderSpinner.js +1 -1
- package/lib/components/Pagination/Pagination.cjs +1 -1
- package/lib/components/Pagination/Pagination.js +1 -1
- package/lib/components/Pagination/PaginationItemButton.cjs +1 -1
- package/lib/components/Pagination/PaginationItemButton.js +1 -1
- package/lib/components/SideNav/SideNav.cjs +3 -22
- package/lib/components/SideNav/SideNav.cjs.map +1 -1
- package/lib/components/SideNav/SideNav.d.ts +2 -9
- package/lib/components/SideNav/SideNav.js +4 -23
- package/lib/components/SideNav/SideNav.js.map +1 -1
- package/lib/components/SideNav/SideNavContext.cjs +11 -0
- package/lib/components/SideNav/SideNavContext.cjs.map +1 -0
- package/lib/components/SideNav/SideNavContext.d.ts +7 -0
- package/lib/components/SideNav/SideNavContext.js +8 -0
- package/lib/components/SideNav/SideNavContext.js.map +1 -0
- package/lib/components/SideNav/SideNavItemButton.cjs +12 -7
- package/lib/components/SideNav/SideNavItemButton.cjs.map +1 -1
- package/lib/components/SideNav/SideNavItemButton.d.ts +5 -11
- package/lib/components/SideNav/SideNavItemButton.js +12 -7
- package/lib/components/SideNav/SideNavItemButton.js.map +1 -1
- package/lib/components/Table/Th.cjs +2 -2
- package/lib/components/Table/Th.cjs.map +1 -1
- package/lib/components/Table/Th.d.ts +0 -2
- package/lib/components/Table/Th.js +2 -2
- package/lib/components/Table/Th.js.map +1 -1
- package/lib/components/Table/ThCheckbox.cjs +1 -1
- package/lib/components/Table/ThCheckbox.js +1 -1
- package/lib/components/Table/ThSortButton.cjs +5 -6
- package/lib/components/Table/ThSortButton.cjs.map +1 -1
- package/lib/components/Table/ThSortButton.d.ts +1 -6
- package/lib/components/Table/ThSortButton.js +5 -6
- package/lib/components/Table/ThSortButton.js.map +1 -1
- package/lib/components/WarekiPicker/WarekiPicker.cjs +1 -1
- package/lib/components/WarekiPicker/WarekiPicker.js +1 -1
- package/lib/hooks/useLatest.cjs +33 -0
- package/lib/hooks/useLatest.cjs.map +1 -0
- package/lib/hooks/useLatest.d.ts +19 -0
- package/lib/hooks/useLatest.js +31 -0
- package/lib/hooks/useLatest.js.map +1 -0
- package/lib/index.cjs +1 -6
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +1 -4
- package/lib/index.js.map +1 -1
- package/lib/intl/Localizer.cjs +5 -1
- package/lib/intl/Localizer.cjs.map +1 -1
- package/lib/intl/Localizer.d.ts +1 -1
- package/lib/intl/Localizer.js +5 -1
- package/lib/intl/Localizer.js.map +1 -1
- package/lib/intl/locales/en_us.json.cjs +3 -0
- package/lib/intl/locales/en_us.json.cjs.map +1 -1
- package/lib/intl/locales/en_us.json.js +3 -0
- package/lib/intl/locales/en_us.json.js.map +1 -1
- package/lib/intl/locales/id_id.json.cjs +3 -0
- package/lib/intl/locales/id_id.json.cjs.map +1 -1
- package/lib/intl/locales/id_id.json.js +3 -0
- package/lib/intl/locales/id_id.json.js.map +1 -1
- package/lib/intl/locales/index.d.ts +27 -0
- package/lib/intl/locales/ja.cjs +3 -0
- package/lib/intl/locales/ja.cjs.map +1 -1
- package/lib/intl/locales/ja.d.ts +3 -0
- package/lib/intl/locales/ja.js +3 -0
- package/lib/intl/locales/ja.js.map +1 -1
- package/lib/intl/locales/ja.json.cjs +3 -0
- package/lib/intl/locales/ja.json.cjs.map +1 -1
- package/lib/intl/locales/ja.json.js +3 -0
- package/lib/intl/locales/ja.json.js.map +1 -1
- package/lib/intl/locales/ja_easy.json.cjs +3 -0
- package/lib/intl/locales/ja_easy.json.cjs.map +1 -1
- package/lib/intl/locales/ja_easy.json.js +3 -0
- package/lib/intl/locales/ja_easy.json.js.map +1 -1
- package/lib/intl/locales/ko_kr.json.cjs +3 -0
- package/lib/intl/locales/ko_kr.json.cjs.map +1 -1
- package/lib/intl/locales/ko_kr.json.js +3 -0
- package/lib/intl/locales/ko_kr.json.js.map +1 -1
- package/lib/intl/locales/pt_br.json.cjs +3 -0
- package/lib/intl/locales/pt_br.json.cjs.map +1 -1
- package/lib/intl/locales/pt_br.json.js +3 -0
- package/lib/intl/locales/pt_br.json.js.map +1 -1
- package/lib/intl/locales/vi_vn.json.cjs +3 -0
- package/lib/intl/locales/vi_vn.json.cjs.map +1 -1
- package/lib/intl/locales/vi_vn.json.js +3 -0
- package/lib/intl/locales/vi_vn.json.js.map +1 -1
- package/lib/intl/locales/zh_hans_cn.json.cjs +3 -0
- package/lib/intl/locales/zh_hans_cn.json.cjs.map +1 -1
- package/lib/intl/locales/zh_hans_cn.json.js +3 -0
- package/lib/intl/locales/zh_hans_cn.json.js.map +1 -1
- package/lib/intl/locales/zh_hant_tw.json.cjs +3 -0
- package/lib/intl/locales/zh_hant_tw.json.cjs.map +1 -1
- package/lib/intl/locales/zh_hant_tw.json.js +3 -0
- package/lib/intl/locales/zh_hant_tw.json.js.map +1 -1
- package/metadata.json +1 -1
- package/package.json +1 -1
- package/smarthr-ui.css +35 -98
- package/lib/hooks/useDecorators.cjs +0 -18
- package/lib/hooks/useDecorators.cjs.map +0 -1
- package/lib/hooks/useDecorators.d.ts +0 -6
- package/lib/hooks/useDecorators.js +0 -16
- package/lib/hooks/useDecorators.js.map +0 -1
- package/lib/hooks/useDevice/DeviceProvider.cjs +0 -37
- package/lib/hooks/useDevice/DeviceProvider.cjs.map +0 -1
- package/lib/hooks/useDevice/DeviceProvider.d.ts +0 -4
- package/lib/hooks/useDevice/DeviceProvider.js +0 -35
- package/lib/hooks/useDevice/DeviceProvider.js.map +0 -1
- package/lib/hooks/useDevice/index.cjs +0 -10
- package/lib/hooks/useDevice/index.cjs.map +0 -1
- package/lib/hooks/useDevice/index.d.ts +0 -2
- package/lib/hooks/useDevice/index.js +0 -3
- package/lib/hooks/useDevice/index.js.map +0 -1
- package/lib/hooks/useDevice/useDevice.cjs +0 -11
- package/lib/hooks/useDevice/useDevice.cjs.map +0 -1
- package/lib/hooks/useDevice/useDevice.d.ts +0 -4
- package/lib/hooks/useDevice/useDevice.js +0 -8
- package/lib/hooks/useDevice/useDevice.js.map +0 -1
|
@@ -5,7 +5,7 @@ import { useResponseStatus } from '../../../hooks/useResponseStatus.js';
|
|
|
5
5
|
import { Button } from '../../Button/Button.js';
|
|
6
6
|
import '../../Button/AnchorButton.js';
|
|
7
7
|
import '../../Button/UnstyledButton.js';
|
|
8
|
-
import
|
|
8
|
+
import '../../Layout/Stack/Stack.js';
|
|
9
9
|
import { Cluster } from '../../Layout/Cluster/Cluster.js';
|
|
10
10
|
import '../../Layout/Reel/Reel.js';
|
|
11
11
|
import '../../Layout/Sidebar/Sidebar.js';
|
|
@@ -73,7 +73,7 @@ const StepFormDialogContentInner = ({ children, heading, activeStep, contentBgCo
|
|
|
73
73
|
const calcedResponseStatus = useResponseStatus(responseStatus);
|
|
74
74
|
return (
|
|
75
75
|
// eslint-disable-next-line smarthr/a11y-prohibit-sectioning-content-in-form
|
|
76
|
-
jsx(Section, { children: jsx("form", { onSubmit: handleSubmitAction, children: jsxs("div", { className: classNames.wrapper, children: [jsx(DialogHeading, { id: heading.id, sub: heading.sub ? `${heading.sub}${stepText}` : undefined, text: heading.sub ? heading.text : `${heading.text}${stepText}` }), jsx(DialogBody, { contentPadding: contentPadding, contentBgColor: contentBgColor, ref: scrollerRef, children: children }), jsxs(
|
|
76
|
+
jsx(Section, { children: jsx("form", { onSubmit: handleSubmitAction, children: jsxs("div", { className: classNames.wrapper, children: [jsx(DialogHeading, { id: heading.id, sub: heading.sub ? `${heading.sub}${stepText}` : undefined, text: heading.sub ? heading.text : `${heading.text}${stepText}` }), jsx(DialogBody, { contentPadding: contentPadding, contentBgColor: contentBgColor, ref: scrollerRef, children: children }), jsxs("div", { className: classNames.actionArea, children: [jsxs(Cluster, { justify: "space-between", gap: { row: 0.5, column: 2 }, children: [!backButton.hidden && activeStep > 1 && (jsx(Button, { onClick: handleBackAction, variant: backButton.theme, disabled: backButton.disabled || calcedResponseStatus.isProcessing, className: "smarthr-ui-Dialog-backButton", children: backButton.text })), jsxs(Cluster, { gap: BUTTON_COLUMN_GAP, className: classNames.buttonArea, children: [!closeButton.hidden && (jsx(Button, { onClick: handleCloseAction, variant: closeButton.theme, disabled: closeButton.disabled || calcedResponseStatus.isProcessing, className: "smarthr-ui-Dialog-closeButton", children: closeButton.text })), !submitButton.hidden && (jsx(Button, { type: "submit", variant: submitButton.theme, disabled: submitButton.disabled, loading: calcedResponseStatus.isProcessing, className: "smarthr-ui-Dialog-actionButton", children: submitButton.text }))] })] }), jsx(DialogContentResponseStatusMessage, { responseStatus: calcedResponseStatus, className: classNames.message })] })] }) }) }));
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
export { StepFormDialogContentInner };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepFormDialogContentInner.js","sources":["../../../../src/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type FormEvent,\n type PropsWithChildren,\n useCallback,\n useContext,\n useMemo,\n} from 'react'\n\nimport { type ResponseStatus, useResponseStatus } from '../../../hooks/useResponseStatus'\nimport { Button } from '../../Button'\nimport { Cluster
|
|
1
|
+
{"version":3,"file":"StepFormDialogContentInner.js","sources":["../../../../src/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type FormEvent,\n type PropsWithChildren,\n useCallback,\n useContext,\n useMemo,\n} from 'react'\n\nimport { type ResponseStatus, useResponseStatus } from '../../../hooks/useResponseStatus'\nimport { Button } from '../../Button'\nimport { Cluster } from '../../Layout'\nimport { Section } from '../../SectioningContent'\nimport { DialogBody, type Props as DialogBodyProps } from '../DialogBody'\nimport { DialogContentResponseStatusMessage } from '../DialogContentResponseStatusMessage'\nimport { DialogHeading, type Props as DialogHeadingProps } from '../DialogHeading'\nimport { dialogContentInner } from '../dialogInnerStyle'\n\nimport { StepFormDialogContext, type StepItem } from './StepFormDialogProvider'\n\nimport type { useStepFormDialogButton } from './useStepFormDialogButton'\n\ntype StepFormHelpers = {\n /** 指定したステップに移動する関数 */\n goto: (nextStep: StepItem) => void\n /** ダイアログを閉じる関数 */\n close: () => void\n /** 現在のステップ情報 */\n currentStep: StepItem\n}\n\ntype CommonButtonType = ReturnType<typeof useStepFormDialogButton>\n\nexport type AbstractProps = PropsWithChildren<\n DialogBodyProps & {\n /** ダイアログタイトル */\n heading: DialogHeadingProps\n /** 現在のStepNo */\n activeStep: number\n /** submitボタン */\n submitButton: CommonButtonType\n /**\n * アクションボタンをクリックした時に発火するコールバック関数\n * @param e フォームイベント\n * @param helpers ステップ操作用のヘルパー関数群\n */\n onSubmit: (e: FormEvent<HTMLFormElement>, helpers: StepFormHelpers) => void\n /** キャンセルボタン */\n closeButton: CommonButtonType\n /** 戻るボタン */\n backButton: CommonButtonType\n }\n>\n\nexport type StepFormDialogContentInnerProps = AbstractProps & {\n firstStep: StepItem\n onClickClose: () => void\n responseStatus?: ResponseStatus\n /** ステップの総数 */\n stepLength: number\n onClickBack?: () => void\n}\n\nconst BUTTON_COLUMN_GAP = {\n row: 0.5,\n column: 1,\n} as const\n\nexport const StepFormDialogContentInner: FC<StepFormDialogContentInnerProps> = ({\n children,\n heading,\n activeStep,\n contentBgColor,\n contentPadding,\n submitButton,\n closeButton,\n backButton,\n stepLength,\n firstStep,\n onSubmit,\n onClickClose,\n responseStatus,\n onClickBack,\n}) => {\n const { currentStep, stepQueue, setCurrentStep, scrollerRef } = useContext(StepFormDialogContext)\n\n const handleCloseAction = useCallback(() => {\n onClickClose()\n setTimeout(() => {\n // HINT: ダイアログが閉じるtransitionが完了してから初期化をしている\n stepQueue.current = []\n setCurrentStep(firstStep)\n }, 300)\n }, [firstStep, stepQueue, setCurrentStep, onClickClose])\n\n const changeCurrentStep = useCallback(\n (step: Parameters<typeof setCurrentStep>[0]) => {\n setCurrentStep(step)\n\n // HINT: stepが切り替わるごとにbodyのscroll位置を先頭に戻す処理\n if (scrollerRef.current) {\n scrollerRef.current.scroll(0, 0)\n }\n },\n [setCurrentStep, scrollerRef],\n )\n\n const handleSubmitAction = useCallback(\n (e: FormEvent<HTMLFormElement>) => {\n e.preventDefault()\n // HINT: React Potals などで擬似的にformがネストしている場合など、stopPropagationを実行しないと\n // 親formが意図せずsubmitされてしまう場合がある\n e.stopPropagation()\n\n const helpers: StepFormHelpers = {\n goto: (nextStep: StepItem) => {\n stepQueue.current.push(currentStep)\n changeCurrentStep(nextStep)\n },\n close: handleCloseAction,\n currentStep,\n }\n\n onSubmit(e, helpers)\n },\n [currentStep, stepQueue, onSubmit, handleCloseAction, changeCurrentStep],\n )\n const handleBackAction = useCallback(() => {\n onClickBack?.()\n\n changeCurrentStep(stepQueue.current.pop() ?? firstStep)\n }, [firstStep, stepQueue, onClickBack, changeCurrentStep])\n\n const classNames = useMemo(() => {\n const { wrapper, actionArea, buttonArea, message } = dialogContentInner()\n\n return {\n wrapper: wrapper(),\n actionArea: actionArea(),\n buttonArea: buttonArea(),\n message: message(),\n }\n }, [])\n\n const stepText = stepLength > 1 ? `(${activeStep}/${stepLength})` : ''\n\n const calcedResponseStatus = useResponseStatus(responseStatus)\n\n return (\n // eslint-disable-next-line smarthr/a11y-prohibit-sectioning-content-in-form\n <Section>\n <form onSubmit={handleSubmitAction}>\n <div className={classNames.wrapper}>\n <DialogHeading\n id={heading.id}\n sub={heading.sub ? `${heading.sub}${stepText}` : undefined}\n text={heading.sub ? heading.text : `${heading.text}${stepText}`}\n />\n <DialogBody\n contentPadding={contentPadding}\n contentBgColor={contentBgColor}\n ref={scrollerRef}\n >\n {children}\n </DialogBody>\n <div className={classNames.actionArea}>\n <Cluster justify=\"space-between\" gap={{ row: 0.5, column: 2 }}>\n {!backButton.hidden && activeStep > 1 && (\n <Button\n onClick={handleBackAction}\n variant={backButton.theme}\n disabled={backButton.disabled || calcedResponseStatus.isProcessing}\n className=\"smarthr-ui-Dialog-backButton\"\n >\n {backButton.text}\n </Button>\n )}\n <Cluster gap={BUTTON_COLUMN_GAP} className={classNames.buttonArea}>\n {!closeButton.hidden && (\n <Button\n onClick={handleCloseAction}\n variant={closeButton.theme}\n disabled={closeButton.disabled || calcedResponseStatus.isProcessing}\n className=\"smarthr-ui-Dialog-closeButton\"\n >\n {closeButton.text}\n </Button>\n )}\n {!submitButton.hidden && (\n <Button\n type=\"submit\"\n variant={submitButton.theme}\n disabled={submitButton.disabled}\n loading={calcedResponseStatus.isProcessing}\n className=\"smarthr-ui-Dialog-actionButton\"\n >\n {submitButton.text}\n </Button>\n )}\n </Cluster>\n </Cluster>\n <DialogContentResponseStatusMessage\n responseStatus={calcedResponseStatus}\n className={classNames.message}\n />\n </div>\n </div>\n </form>\n </Section>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiEA;AACE;AACA;;AAGK;AAgBL;AAEA;AACE;;;AAGE;;;;AAKJ;;;AAKI;;;AAGF;AAIF;;;;;AAOI;AACE;AACE;;;AAGF;;;AAIF;AACF;AAGF;;;;AAMA;AACE;;;;;;;;AAUF;AAEA;;;AAIE;AA4DJ;;"}
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var React = require('react');
|
|
5
|
-
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
|
|
6
4
|
var components_ResponseMessage_ResponseMessage = require('../ResponseMessage/ResponseMessage.cjs');
|
|
7
5
|
|
|
8
|
-
const classNameGenerator = index.tv({
|
|
9
|
-
base: 'empty:!shr-mt-0',
|
|
10
|
-
});
|
|
11
6
|
const DialogContentResponseStatusMessage = ({ responseStatus, className }) => {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
7
|
+
const isError = responseStatus.message && responseStatus.status === 'error';
|
|
8
|
+
const isSuccess = responseStatus.message && responseStatus.status === 'success';
|
|
14
9
|
return (
|
|
15
10
|
/**
|
|
16
11
|
* ライブリージョンを条件付きでDOMに追加すると、支援技術に通知が正しく行われないことがあるため、常にDOM上に存在するようにしています
|
|
17
12
|
*
|
|
18
13
|
* @see https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-2/#make-sure-the-live-region-container-is-in-the-dom-as-early-as-possible
|
|
19
14
|
*/
|
|
20
|
-
jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className:
|
|
15
|
+
jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: isError ? `${className} shr-mt-0.5` : className, role: "alert", children: isError && jsxRuntime.jsx(components_ResponseMessage_ResponseMessage.ResponseMessage, { status: "error", children: responseStatus.message }) }), jsxRuntime.jsx("div", { className: isSuccess ? `${className} shr-mt-0.5` : className, role: "status", children: isSuccess && jsxRuntime.jsx(components_ResponseMessage_ResponseMessage.ResponseMessage, { status: "success", children: responseStatus.message }) })] }));
|
|
21
16
|
};
|
|
22
17
|
|
|
23
18
|
exports.DialogContentResponseStatusMessage = DialogContentResponseStatusMessage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogContentResponseStatusMessage.cjs","sources":["../../../src/components/Dialog/DialogContentResponseStatusMessage.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"DialogContentResponseStatusMessage.cjs","sources":["../../../src/components/Dialog/DialogContentResponseStatusMessage.tsx"],"sourcesContent":["import { ResponseMessage } from '../ResponseMessage'\n\nimport type { useResponseStatus } from '../../hooks/useResponseStatus'\nimport type { FC } from 'react'\n\nexport const DialogContentResponseStatusMessage: FC<{\n responseStatus: ReturnType<typeof useResponseStatus>\n className?: string\n}> = ({ responseStatus, className }) => {\n const isError = responseStatus.message && responseStatus.status === 'error'\n const isSuccess = responseStatus.message && responseStatus.status === 'success'\n\n return (\n /**\n * ライブリージョンを条件付きでDOMに追加すると、支援技術に通知が正しく行われないことがあるため、常にDOM上に存在するようにしています\n *\n * @see https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-2/#make-sure-the-live-region-container-is-in-the-dom-as-early-as-possible\n */\n <>\n <div className={isError ? `${className} shr-mt-0.5` : className} role=\"alert\">\n {isError && <ResponseMessage status=\"error\">{responseStatus.message}</ResponseMessage>}\n </div>\n <div className={isSuccess ? `${className} shr-mt-0.5` : className} role=\"status\">\n {isSuccess && <ResponseMessage status=\"success\">{responseStatus.message}</ResponseMessage>}\n </div>\n </>\n )\n}\n"],"names":["_jsxs","_Fragment","_jsx","ResponseMessage"],"mappings":";;;;;AAKO,MAAM,kCAAkC,GAG1C,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,KAAI;IACrC,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,OAAO;IAC3E,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,SAAS;IAE/E;AACE;;;;AAIG;AACH,IAAAA,eAAA,CAAAC,mBAAA,EAAA,EAAA,QAAA,EAAA,CACEC,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,OAAO,GAAG,CAAA,EAAG,SAAS,CAAA,WAAA,CAAa,GAAG,SAAS,EAAE,IAAI,EAAC,OAAO,EAAA,QAAA,EAC1E,OAAO,IAAIA,cAAA,CAACC,0DAAe,EAAA,EAAC,MAAM,EAAC,OAAO,EAAA,QAAA,EAAE,cAAc,CAAC,OAAO,GAAmB,EAAA,CAClF,EACND,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,SAAS,GAAG,CAAA,EAAG,SAAS,CAAA,WAAA,CAAa,GAAG,SAAS,EAAE,IAAI,EAAC,QAAQ,EAAA,QAAA,EAC7E,SAAS,IAAIA,cAAA,CAACC,0DAAe,EAAA,EAAC,MAAM,EAAC,SAAS,EAAA,QAAA,EAAE,cAAc,CAAC,OAAO,EAAA,CAAmB,EAAA,CACtF,CAAA,EAAA,CACL;AAEP;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type FC } from 'react';
|
|
2
1
|
import type { useResponseStatus } from '../../hooks/useResponseStatus';
|
|
2
|
+
import type { FC } from 'react';
|
|
3
3
|
export declare const DialogContentResponseStatusMessage: FC<{
|
|
4
4
|
responseStatus: ReturnType<typeof useResponseStatus>;
|
|
5
5
|
className?: string;
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
|
|
4
2
|
import { ResponseMessage } from '../ResponseMessage/ResponseMessage.js';
|
|
5
3
|
|
|
6
|
-
const classNameGenerator = ce({
|
|
7
|
-
base: 'empty:!shr-mt-0',
|
|
8
|
-
});
|
|
9
4
|
const DialogContentResponseStatusMessage = ({ responseStatus, className }) => {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
5
|
+
const isError = responseStatus.message && responseStatus.status === 'error';
|
|
6
|
+
const isSuccess = responseStatus.message && responseStatus.status === 'success';
|
|
12
7
|
return (
|
|
13
8
|
/**
|
|
14
9
|
* ライブリージョンを条件付きでDOMに追加すると、支援技術に通知が正しく行われないことがあるため、常にDOM上に存在するようにしています
|
|
15
10
|
*
|
|
16
11
|
* @see https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-2/#make-sure-the-live-region-container-is-in-the-dom-as-early-as-possible
|
|
17
12
|
*/
|
|
18
|
-
jsxs(Fragment, { children: [jsx("div", { className:
|
|
13
|
+
jsxs(Fragment, { children: [jsx("div", { className: isError ? `${className} shr-mt-0.5` : className, role: "alert", children: isError && jsx(ResponseMessage, { status: "error", children: responseStatus.message }) }), jsx("div", { className: isSuccess ? `${className} shr-mt-0.5` : className, role: "status", children: isSuccess && jsx(ResponseMessage, { status: "success", children: responseStatus.message }) })] }));
|
|
19
14
|
};
|
|
20
15
|
|
|
21
16
|
export { DialogContentResponseStatusMessage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogContentResponseStatusMessage.js","sources":["../../../src/components/Dialog/DialogContentResponseStatusMessage.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"DialogContentResponseStatusMessage.js","sources":["../../../src/components/Dialog/DialogContentResponseStatusMessage.tsx"],"sourcesContent":["import { ResponseMessage } from '../ResponseMessage'\n\nimport type { useResponseStatus } from '../../hooks/useResponseStatus'\nimport type { FC } from 'react'\n\nexport const DialogContentResponseStatusMessage: FC<{\n responseStatus: ReturnType<typeof useResponseStatus>\n className?: string\n}> = ({ responseStatus, className }) => {\n const isError = responseStatus.message && responseStatus.status === 'error'\n const isSuccess = responseStatus.message && responseStatus.status === 'success'\n\n return (\n /**\n * ライブリージョンを条件付きでDOMに追加すると、支援技術に通知が正しく行われないことがあるため、常にDOM上に存在するようにしています\n *\n * @see https://www.sarasoueidan.com/blog/accessible-notifications-with-aria-live-regions-part-2/#make-sure-the-live-region-container-is-in-the-dom-as-early-as-possible\n */\n <>\n <div className={isError ? `${className} shr-mt-0.5` : className} role=\"alert\">\n {isError && <ResponseMessage status=\"error\">{responseStatus.message}</ResponseMessage>}\n </div>\n <div className={isSuccess ? `${className} shr-mt-0.5` : className} role=\"status\">\n {isSuccess && <ResponseMessage status=\"success\">{responseStatus.message}</ResponseMessage>}\n </div>\n </>\n )\n}\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":";;;AAKO,MAAM,kCAAkC,GAG1C,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,KAAI;IACrC,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,OAAO;IAC3E,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,SAAS;IAE/E;AACE;;;;AAIG;AACH,IAAAA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACEC,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,OAAO,GAAG,CAAA,EAAG,SAAS,CAAA,WAAA,CAAa,GAAG,SAAS,EAAE,IAAI,EAAC,OAAO,EAAA,QAAA,EAC1E,OAAO,IAAIA,GAAA,CAAC,eAAe,EAAA,EAAC,MAAM,EAAC,OAAO,EAAA,QAAA,EAAE,cAAc,CAAC,OAAO,GAAmB,EAAA,CAClF,EACNA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,SAAS,GAAG,CAAA,EAAG,SAAS,CAAA,WAAA,CAAa,GAAG,SAAS,EAAE,IAAI,EAAC,QAAQ,EAAA,QAAA,EAC7E,SAAS,IAAIA,GAAA,CAAC,eAAe,EAAA,EAAC,MAAM,EAAC,SAAS,EAAA,QAAA,EAAE,cAAc,CAAC,OAAO,EAAA,CAAmB,EAAA,CACtF,CAAA,EAAA,CACL;AAEP;;;;"}
|
|
@@ -19,7 +19,10 @@ const FocusTrap = React.forwardRef(({ firstFocusTarget, children }, ref) => {
|
|
|
19
19
|
}));
|
|
20
20
|
React.useEffect(() => {
|
|
21
21
|
const handleKeyDown = (e) => {
|
|
22
|
-
|
|
22
|
+
// IME 変換中の Tab は変換候補の選択に使われるため、フォーカストラップの対象外にする。
|
|
23
|
+
// ここで preventDefault してしまうと、Dialog 内で日本語入力中に Tab を押しても
|
|
24
|
+
// 変換候補が確定されず、未確定文字列がそのまま入力されてしまう。
|
|
25
|
+
if (e.key !== 'Tab' || e.isComposing || innerRef.current === null) {
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
25
28
|
const tabbables = libs_tabbable.tabbable(innerRef.current).filter((elm) => elm.tabIndex >= 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocusTrap.cjs","sources":["../../../src/components/Dialog/FocusTrap.tsx"],"sourcesContent":["import {\n type PropsWithChildren,\n type RefObject,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react'\n\nimport { tabbable } from '../../libs/tabbable'\n\ntype Props = PropsWithChildren<{\n firstFocusTarget?: RefObject<HTMLElement>\n}>\n\nexport type FocusTrapRef = {\n focus: () => void\n}\n\nexport const FocusTrap = forwardRef<FocusTrapRef, Props>(({ firstFocusTarget, children }, ref) => {\n const innerRef = useRef<HTMLDivElement | null>(null)\n const dummyFocusRef = useRef<HTMLDivElement>(null)\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n },\n }))\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab' || innerRef.current === null) {\n return\n }\n\n const tabbables = tabbable(innerRef.current).filter((elm) => elm.tabIndex >= 0)\n\n if (tabbables.length === 0) {\n return\n }\n\n const firstTabbable = tabbables[0]\n const lastTabbable = tabbables[tabbables.length - 1]\n const currentFocused = tabbables.find((elm) => elm === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstTabbable || document.activeElement === dummyFocusRef.current) {\n e.preventDefault()\n lastTabbable.focus()\n }\n } else if (currentFocused === lastTabbable) {\n e.preventDefault()\n firstTabbable.focus()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [])\n\n useEffect(() => {\n const triggerElement = document.activeElement\n\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n\n return () => {\n // フォーカストラップ終了時にトリガにフォーカスを戻す\n if (triggerElement instanceof HTMLElement) {\n triggerElement.focus()\n }\n }\n }, [firstFocusTarget])\n\n return (\n <div ref={innerRef}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={dummyFocusRef} tabIndex={-1} />\n {children}\n </div>\n )\n})\n"],"names":["forwardRef","useRef","useImperativeHandle","useEffect","tabbable","_jsxs","_jsx"],"mappings":";;;;;;AAmBO,MAAM,SAAS,GAAGA,gBAAU,CAAsB,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAI;AAC/F,IAAA,MAAM,QAAQ,GAAGC,YAAM,CAAwB,IAAI,CAAC;AACpD,IAAA,MAAM,aAAa,GAAGA,YAAM,CAAiB,IAAI,CAAC;AAElD,IAAAC,yBAAmB,CAAC,GAAG,EAAE,OAAO;QAC9B,KAAK,EAAE,MAAK;AACV,YAAA,IAAI,gBAAgB,EAAE,OAAO,EAAE;AAC7B,gBAAA,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE;YAClC;iBAAO;AACL,gBAAA,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE;YAChC;QACF,CAAC;AACF,KAAA,CAAC,CAAC;IAEHC,eAAS,CAAC,MAAK;AACb,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI
|
|
1
|
+
{"version":3,"file":"FocusTrap.cjs","sources":["../../../src/components/Dialog/FocusTrap.tsx"],"sourcesContent":["import {\n type PropsWithChildren,\n type RefObject,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react'\n\nimport { tabbable } from '../../libs/tabbable'\n\ntype Props = PropsWithChildren<{\n firstFocusTarget?: RefObject<HTMLElement>\n}>\n\nexport type FocusTrapRef = {\n focus: () => void\n}\n\nexport const FocusTrap = forwardRef<FocusTrapRef, Props>(({ firstFocusTarget, children }, ref) => {\n const innerRef = useRef<HTMLDivElement | null>(null)\n const dummyFocusRef = useRef<HTMLDivElement>(null)\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n },\n }))\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // IME 変換中の Tab は変換候補の選択に使われるため、フォーカストラップの対象外にする。\n // ここで preventDefault してしまうと、Dialog 内で日本語入力中に Tab を押しても\n // 変換候補が確定されず、未確定文字列がそのまま入力されてしまう。\n if (e.key !== 'Tab' || e.isComposing || innerRef.current === null) {\n return\n }\n\n const tabbables = tabbable(innerRef.current).filter((elm) => elm.tabIndex >= 0)\n\n if (tabbables.length === 0) {\n return\n }\n\n const firstTabbable = tabbables[0]\n const lastTabbable = tabbables[tabbables.length - 1]\n const currentFocused = tabbables.find((elm) => elm === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstTabbable || document.activeElement === dummyFocusRef.current) {\n e.preventDefault()\n lastTabbable.focus()\n }\n } else if (currentFocused === lastTabbable) {\n e.preventDefault()\n firstTabbable.focus()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [])\n\n useEffect(() => {\n const triggerElement = document.activeElement\n\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n\n return () => {\n // フォーカストラップ終了時にトリガにフォーカスを戻す\n if (triggerElement instanceof HTMLElement) {\n triggerElement.focus()\n }\n }\n }, [firstFocusTarget])\n\n return (\n <div ref={innerRef}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={dummyFocusRef} tabIndex={-1} />\n {children}\n </div>\n )\n})\n"],"names":["forwardRef","useRef","useImperativeHandle","useEffect","tabbable","_jsxs","_jsx"],"mappings":";;;;;;AAmBO,MAAM,SAAS,GAAGA,gBAAU,CAAsB,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAI;AAC/F,IAAA,MAAM,QAAQ,GAAGC,YAAM,CAAwB,IAAI,CAAC;AACpD,IAAA,MAAM,aAAa,GAAGA,YAAM,CAAiB,IAAI,CAAC;AAElD,IAAAC,yBAAmB,CAAC,GAAG,EAAE,OAAO;QAC9B,KAAK,EAAE,MAAK;AACV,YAAA,IAAI,gBAAgB,EAAE,OAAO,EAAE;AAC7B,gBAAA,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE;YAClC;iBAAO;AACL,gBAAA,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE;YAChC;QACF,CAAC;AACF,KAAA,CAAC,CAAC;IAEHC,eAAS,CAAC,MAAK;AACb,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI;;;;AAIzC,YAAA,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,WAAW,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE;gBACjE;YACF;YAEA,MAAM,SAAS,GAAGC,sBAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;AAE/E,YAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC1B;YACF;AAEA,YAAA,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC;YAClC,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AACpD,YAAA,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;AAEhE,YAAA,IAAI,CAAC,CAAC,QAAQ,EAAE;AACd,gBAAA,IAAI,cAAc,KAAK,aAAa,IAAI,QAAQ,CAAC,aAAa,KAAK,aAAa,CAAC,OAAO,EAAE;oBACxF,CAAC,CAAC,cAAc,EAAE;oBAClB,YAAY,CAAC,KAAK,EAAE;gBACtB;YACF;AAAO,iBAAA,IAAI,cAAc,KAAK,YAAY,EAAE;gBAC1C,CAAC,CAAC,cAAc,EAAE;gBAClB,aAAa,CAAC,KAAK,EAAE;YACvB;AACF,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC;AAEjD,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC;AACtD,QAAA,CAAC;IACH,CAAC,EAAE,EAAE,CAAC;IAEND,eAAS,CAAC,MAAK;AACb,QAAA,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa;AAE7C,QAAA,IAAI,gBAAgB,EAAE,OAAO,EAAE;AAC7B,YAAA,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE;QAClC;aAAO;AACL,YAAA,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE;QAChC;AAEA,QAAA,OAAO,MAAK;;AAEV,YAAA,IAAI,cAAc,YAAY,WAAW,EAAE;gBACzC,cAAc,CAAC,KAAK,EAAE;YACxB;AACF,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAEtB,QACEE,yBAAK,GAAG,EAAE,QAAQ,EAAA,QAAA,EAAA,CAEhBC,cAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAA,CAAI,EACxC,QAAQ,CAAA,EAAA,CACL;AAEV,CAAC;;;;"}
|
|
@@ -17,7 +17,10 @@ const FocusTrap = forwardRef(({ firstFocusTarget, children }, ref) => {
|
|
|
17
17
|
}));
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
const handleKeyDown = (e) => {
|
|
20
|
-
|
|
20
|
+
// IME 変換中の Tab は変換候補の選択に使われるため、フォーカストラップの対象外にする。
|
|
21
|
+
// ここで preventDefault してしまうと、Dialog 内で日本語入力中に Tab を押しても
|
|
22
|
+
// 変換候補が確定されず、未確定文字列がそのまま入力されてしまう。
|
|
23
|
+
if (e.key !== 'Tab' || e.isComposing || innerRef.current === null) {
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
const tabbables = tabbable(innerRef.current).filter((elm) => elm.tabIndex >= 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocusTrap.js","sources":["../../../src/components/Dialog/FocusTrap.tsx"],"sourcesContent":["import {\n type PropsWithChildren,\n type RefObject,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react'\n\nimport { tabbable } from '../../libs/tabbable'\n\ntype Props = PropsWithChildren<{\n firstFocusTarget?: RefObject<HTMLElement>\n}>\n\nexport type FocusTrapRef = {\n focus: () => void\n}\n\nexport const FocusTrap = forwardRef<FocusTrapRef, Props>(({ firstFocusTarget, children }, ref) => {\n const innerRef = useRef<HTMLDivElement | null>(null)\n const dummyFocusRef = useRef<HTMLDivElement>(null)\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n },\n }))\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab' || innerRef.current === null) {\n return\n }\n\n const tabbables = tabbable(innerRef.current).filter((elm) => elm.tabIndex >= 0)\n\n if (tabbables.length === 0) {\n return\n }\n\n const firstTabbable = tabbables[0]\n const lastTabbable = tabbables[tabbables.length - 1]\n const currentFocused = tabbables.find((elm) => elm === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstTabbable || document.activeElement === dummyFocusRef.current) {\n e.preventDefault()\n lastTabbable.focus()\n }\n } else if (currentFocused === lastTabbable) {\n e.preventDefault()\n firstTabbable.focus()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [])\n\n useEffect(() => {\n const triggerElement = document.activeElement\n\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n\n return () => {\n // フォーカストラップ終了時にトリガにフォーカスを戻す\n if (triggerElement instanceof HTMLElement) {\n triggerElement.focus()\n }\n }\n }, [firstFocusTarget])\n\n return (\n <div ref={innerRef}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={dummyFocusRef} tabIndex={-1} />\n {children}\n </div>\n )\n})\n"],"names":["_jsxs","_jsx"],"mappings":";;;;AAmBO,MAAM,SAAS,GAAG,UAAU,CAAsB,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAI;AAC/F,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC;AACpD,IAAA,MAAM,aAAa,GAAG,MAAM,CAAiB,IAAI,CAAC;AAElD,IAAA,mBAAmB,CAAC,GAAG,EAAE,OAAO;QAC9B,KAAK,EAAE,MAAK;AACV,YAAA,IAAI,gBAAgB,EAAE,OAAO,EAAE;AAC7B,gBAAA,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE;YAClC;iBAAO;AACL,gBAAA,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE;YAChC;QACF,CAAC;AACF,KAAA,CAAC,CAAC;IAEH,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI
|
|
1
|
+
{"version":3,"file":"FocusTrap.js","sources":["../../../src/components/Dialog/FocusTrap.tsx"],"sourcesContent":["import {\n type PropsWithChildren,\n type RefObject,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react'\n\nimport { tabbable } from '../../libs/tabbable'\n\ntype Props = PropsWithChildren<{\n firstFocusTarget?: RefObject<HTMLElement>\n}>\n\nexport type FocusTrapRef = {\n focus: () => void\n}\n\nexport const FocusTrap = forwardRef<FocusTrapRef, Props>(({ firstFocusTarget, children }, ref) => {\n const innerRef = useRef<HTMLDivElement | null>(null)\n const dummyFocusRef = useRef<HTMLDivElement>(null)\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n },\n }))\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // IME 変換中の Tab は変換候補の選択に使われるため、フォーカストラップの対象外にする。\n // ここで preventDefault してしまうと、Dialog 内で日本語入力中に Tab を押しても\n // 変換候補が確定されず、未確定文字列がそのまま入力されてしまう。\n if (e.key !== 'Tab' || e.isComposing || innerRef.current === null) {\n return\n }\n\n const tabbables = tabbable(innerRef.current).filter((elm) => elm.tabIndex >= 0)\n\n if (tabbables.length === 0) {\n return\n }\n\n const firstTabbable = tabbables[0]\n const lastTabbable = tabbables[tabbables.length - 1]\n const currentFocused = tabbables.find((elm) => elm === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstTabbable || document.activeElement === dummyFocusRef.current) {\n e.preventDefault()\n lastTabbable.focus()\n }\n } else if (currentFocused === lastTabbable) {\n e.preventDefault()\n firstTabbable.focus()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [])\n\n useEffect(() => {\n const triggerElement = document.activeElement\n\n if (firstFocusTarget?.current) {\n firstFocusTarget.current.focus()\n } else {\n dummyFocusRef.current?.focus()\n }\n\n return () => {\n // フォーカストラップ終了時にトリガにフォーカスを戻す\n if (triggerElement instanceof HTMLElement) {\n triggerElement.focus()\n }\n }\n }, [firstFocusTarget])\n\n return (\n <div ref={innerRef}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={dummyFocusRef} tabIndex={-1} />\n {children}\n </div>\n )\n})\n"],"names":["_jsxs","_jsx"],"mappings":";;;;AAmBO,MAAM,SAAS,GAAG,UAAU,CAAsB,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAI;AAC/F,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC;AACpD,IAAA,MAAM,aAAa,GAAG,MAAM,CAAiB,IAAI,CAAC;AAElD,IAAA,mBAAmB,CAAC,GAAG,EAAE,OAAO;QAC9B,KAAK,EAAE,MAAK;AACV,YAAA,IAAI,gBAAgB,EAAE,OAAO,EAAE;AAC7B,gBAAA,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE;YAClC;iBAAO;AACL,gBAAA,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE;YAChC;QACF,CAAC;AACF,KAAA,CAAC,CAAC;IAEH,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,aAAa,GAAG,CAAC,CAAgB,KAAI;;;;AAIzC,YAAA,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,WAAW,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE;gBACjE;YACF;YAEA,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;AAE/E,YAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC1B;YACF;AAEA,YAAA,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC;YAClC,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AACpD,YAAA,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;AAEhE,YAAA,IAAI,CAAC,CAAC,QAAQ,EAAE;AACd,gBAAA,IAAI,cAAc,KAAK,aAAa,IAAI,QAAQ,CAAC,aAAa,KAAK,aAAa,CAAC,OAAO,EAAE;oBACxF,CAAC,CAAC,cAAc,EAAE;oBAClB,YAAY,CAAC,KAAK,EAAE;gBACtB;YACF;AAAO,iBAAA,IAAI,cAAc,KAAK,YAAY,EAAE;gBAC1C,CAAC,CAAC,cAAc,EAAE;gBAClB,aAAa,CAAC,KAAK,EAAE;YACvB;AACF,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC;AAEjD,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC;AACtD,QAAA,CAAC;IACH,CAAC,EAAE,EAAE,CAAC;IAEN,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa;AAE7C,QAAA,IAAI,gBAAgB,EAAE,OAAO,EAAE;AAC7B,YAAA,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE;QAClC;aAAO;AACL,YAAA,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE;QAChC;AAEA,QAAA,OAAO,MAAK;;AAEV,YAAA,IAAI,cAAc,YAAY,WAAW,EAAE;gBACzC,cAAc,CAAC,KAAK,EAAE;YACxB;AACF,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAEtB,QACEA,cAAK,GAAG,EAAE,QAAQ,EAAA,QAAA,EAAA,CAEhBC,GAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAA,CAAI,EACxC,QAAQ,CAAA,EAAA,CACL;AAEV,CAAC;;;;"}
|
|
@@ -8,7 +8,7 @@ var index = require('./../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss
|
|
|
8
8
|
var hooks_useHandleEscape = require('../../../hooks/useHandleEscape.cjs');
|
|
9
9
|
require('../../../intl/IntlProvider.cjs');
|
|
10
10
|
var intl_useIntl = require('../../../intl/useIntl.cjs');
|
|
11
|
-
require('
|
|
11
|
+
require('../../../intl/Localizer.cjs');
|
|
12
12
|
require('../../../_virtual/dayjs.min.cjs');
|
|
13
13
|
require('../../../intl/TimeFormatter.cjs');
|
|
14
14
|
var libs_debounce = require('../../../libs/debounce.cjs');
|
|
@@ -6,7 +6,7 @@ import { tv as ce } from './../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwi
|
|
|
6
6
|
import { useHandleEscape } from '../../../hooks/useHandleEscape.js';
|
|
7
7
|
import '../../../intl/IntlProvider.js';
|
|
8
8
|
import { useIntl } from '../../../intl/useIntl.js';
|
|
9
|
-
import '
|
|
9
|
+
import '../../../intl/Localizer.js';
|
|
10
10
|
import '../../../_virtual/dayjs.min.js';
|
|
11
11
|
import '../../../intl/TimeFormatter.js';
|
|
12
12
|
import { debounce } from '../../../libs/debounce.js';
|
|
@@ -37,9 +37,15 @@ const RemoteDialogTrigger = ({ targetId, children, onClick }) => {
|
|
|
37
37
|
// 現在の子要素に対して処理を実行
|
|
38
38
|
const setupElement = () => {
|
|
39
39
|
const element = getClickableElement();
|
|
40
|
-
if (element) {
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
if (!element) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
element.setAttribute('aria-haspopup', 'dialog');
|
|
44
|
+
element.setAttribute('aria-controls', targetId);
|
|
45
|
+
// Button は native disabled ではなく aria-disabled を使うため、
|
|
46
|
+
// 無効時はリスナーを貼らず Dialog が開かないようにする(DropdownTrigger と同じ)
|
|
47
|
+
if (!('disabled' in element && element.disabled) &&
|
|
48
|
+
element.getAttribute('aria-disabled') !== 'true') {
|
|
43
49
|
// HINT: DropdownCloser のonClickより先に実行するため、キャプチャフェーズで処理する
|
|
44
50
|
element.addEventListener('click', actualOnClick, CAPTURE_OPTION);
|
|
45
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteDialogTrigger.cjs","sources":["../../../../src/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type PropsWithChildren, useCallback, useEffect, useRef } from 'react'\n\nimport { TRIGGER_EVENT } from '../useRemoteTrigger'\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\nconst onClickRemoteDialogTrigger = (ariaControls: string) => {\n document.dispatchEvent(\n new CustomEvent(TRIGGER_EVENT, {\n detail: { id: ariaControls },\n }),\n )\n}\n\nexport const RemoteDialogTrigger: FC<\n PropsWithChildren<{\n targetId: string\n onClick?: (open: () => void) => void\n }>\n> = ({ targetId, children, onClick }) => {\n const ref = useRef<HTMLSpanElement | null>(null)\n const onClickRef = useRef(onClick)\n onClickRef.current = onClick\n\n const actualOnClick = useCallback((e: Event) => {\n // HINT: onClick内で非同期処理される場合、e.currentTargetがnullになってしまう可能性があるため\n // 先にariaControlsを取得しておく\n const ariaControls = (e.currentTarget as HTMLElement).getAttribute('aria-controls') as string\n\n if (onClickRef.current) {\n return onClickRef.current(() => {\n onClickRemoteDialogTrigger(ariaControls)\n })\n }\n\n onClickRemoteDialogTrigger(ariaControls)\n }, [])\n\n useEffect(() => {\n const currentRef = ref.current\n if (!currentRef) {\n return\n }\n\n const getClickableElement = () =>\n currentRef.querySelector<HTMLButtonElement | HTMLAnchorElement>('button, a')\n\n // 現在の子要素に対して処理を実行\n const setupElement = () => {\n const element = getClickableElement()\n if (element) {\n element.setAttribute('aria-haspopup', 'dialog')\n
|
|
1
|
+
{"version":3,"file":"RemoteDialogTrigger.cjs","sources":["../../../../src/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type PropsWithChildren, useCallback, useEffect, useRef } from 'react'\n\nimport { TRIGGER_EVENT } from '../useRemoteTrigger'\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\nconst onClickRemoteDialogTrigger = (ariaControls: string) => {\n document.dispatchEvent(\n new CustomEvent(TRIGGER_EVENT, {\n detail: { id: ariaControls },\n }),\n )\n}\n\nexport const RemoteDialogTrigger: FC<\n PropsWithChildren<{\n targetId: string\n onClick?: (open: () => void) => void\n }>\n> = ({ targetId, children, onClick }) => {\n const ref = useRef<HTMLSpanElement | null>(null)\n const onClickRef = useRef(onClick)\n onClickRef.current = onClick\n\n const actualOnClick = useCallback((e: Event) => {\n // HINT: onClick内で非同期処理される場合、e.currentTargetがnullになってしまう可能性があるため\n // 先にariaControlsを取得しておく\n const ariaControls = (e.currentTarget as HTMLElement).getAttribute('aria-controls') as string\n\n if (onClickRef.current) {\n return onClickRef.current(() => {\n onClickRemoteDialogTrigger(ariaControls)\n })\n }\n\n onClickRemoteDialogTrigger(ariaControls)\n }, [])\n\n useEffect(() => {\n const currentRef = ref.current\n if (!currentRef) {\n return\n }\n\n const getClickableElement = () =>\n currentRef.querySelector<HTMLButtonElement | HTMLAnchorElement>('button, a')\n\n // 現在の子要素に対して処理を実行\n const setupElement = () => {\n const element = getClickableElement()\n if (!element) {\n return\n }\n\n element.setAttribute('aria-haspopup', 'dialog')\n element.setAttribute('aria-controls', targetId)\n\n // Button は native disabled ではなく aria-disabled を使うため、\n // 無効時はリスナーを貼らず Dialog が開かないようにする(DropdownTrigger と同じ)\n if (\n !('disabled' in element && element.disabled) &&\n element.getAttribute('aria-disabled') !== 'true'\n ) {\n // HINT: DropdownCloser のonClickより先に実行するため、キャプチャフェーズで処理する\n element.addEventListener('click', actualOnClick, CAPTURE_OPTION)\n }\n }\n\n const clearEventListener = () => {\n // 既存のイベントリスナーをクリーンアップ\n const element = getClickableElement()\n if (element) {\n element.removeEventListener('click', actualOnClick, CAPTURE_OPTION)\n }\n }\n\n // 初回セットアップ\n setupElement()\n\n // MutationObserverでDOM変更を監視\n const observer = new MutationObserver(() => {\n clearEventListener()\n setupElement()\n })\n\n observer.observe(currentRef, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n observer.disconnect()\n clearEventListener()\n }\n }, [targetId, actualOnClick])\n\n return (\n <span className=\"smarthr-ui-RemoteDialogTrigger shr-contents\" ref={ref}>\n {children}\n </span>\n )\n}\n"],"names":[],"mappings":";;;;;;;AAMA;AACE;;AAGF;AACE;AAEI;AACD;AAEL;AAEO;AAML;AACA;AACA;AAEA;;;;AAKE;AACE;;AAEA;;;;;AAOF;;;;;;;AAUE;;;;AAKA;AACA;;;;;;;;AAWF;;;AAIE;;;;AAIF;;AAGA;;AAGA;AACE;AACA;AACF;AAEA;AACE;AACA;;AAEA;AACA;AACD;AAED;;AAEE;AACF;AACF;AAEA;AAKF;;"}
|
|
@@ -35,9 +35,15 @@ const RemoteDialogTrigger = ({ targetId, children, onClick }) => {
|
|
|
35
35
|
// 現在の子要素に対して処理を実行
|
|
36
36
|
const setupElement = () => {
|
|
37
37
|
const element = getClickableElement();
|
|
38
|
-
if (element) {
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
if (!element) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
element.setAttribute('aria-haspopup', 'dialog');
|
|
42
|
+
element.setAttribute('aria-controls', targetId);
|
|
43
|
+
// Button は native disabled ではなく aria-disabled を使うため、
|
|
44
|
+
// 無効時はリスナーを貼らず Dialog が開かないようにする(DropdownTrigger と同じ)
|
|
45
|
+
if (!('disabled' in element && element.disabled) &&
|
|
46
|
+
element.getAttribute('aria-disabled') !== 'true') {
|
|
41
47
|
// HINT: DropdownCloser のonClickより先に実行するため、キャプチャフェーズで処理する
|
|
42
48
|
element.addEventListener('click', actualOnClick, CAPTURE_OPTION);
|
|
43
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteDialogTrigger.js","sources":["../../../../src/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type PropsWithChildren, useCallback, useEffect, useRef } from 'react'\n\nimport { TRIGGER_EVENT } from '../useRemoteTrigger'\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\nconst onClickRemoteDialogTrigger = (ariaControls: string) => {\n document.dispatchEvent(\n new CustomEvent(TRIGGER_EVENT, {\n detail: { id: ariaControls },\n }),\n )\n}\n\nexport const RemoteDialogTrigger: FC<\n PropsWithChildren<{\n targetId: string\n onClick?: (open: () => void) => void\n }>\n> = ({ targetId, children, onClick }) => {\n const ref = useRef<HTMLSpanElement | null>(null)\n const onClickRef = useRef(onClick)\n onClickRef.current = onClick\n\n const actualOnClick = useCallback((e: Event) => {\n // HINT: onClick内で非同期処理される場合、e.currentTargetがnullになってしまう可能性があるため\n // 先にariaControlsを取得しておく\n const ariaControls = (e.currentTarget as HTMLElement).getAttribute('aria-controls') as string\n\n if (onClickRef.current) {\n return onClickRef.current(() => {\n onClickRemoteDialogTrigger(ariaControls)\n })\n }\n\n onClickRemoteDialogTrigger(ariaControls)\n }, [])\n\n useEffect(() => {\n const currentRef = ref.current\n if (!currentRef) {\n return\n }\n\n const getClickableElement = () =>\n currentRef.querySelector<HTMLButtonElement | HTMLAnchorElement>('button, a')\n\n // 現在の子要素に対して処理を実行\n const setupElement = () => {\n const element = getClickableElement()\n if (element) {\n element.setAttribute('aria-haspopup', 'dialog')\n
|
|
1
|
+
{"version":3,"file":"RemoteDialogTrigger.js","sources":["../../../../src/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type PropsWithChildren, useCallback, useEffect, useRef } from 'react'\n\nimport { TRIGGER_EVENT } from '../useRemoteTrigger'\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\nconst onClickRemoteDialogTrigger = (ariaControls: string) => {\n document.dispatchEvent(\n new CustomEvent(TRIGGER_EVENT, {\n detail: { id: ariaControls },\n }),\n )\n}\n\nexport const RemoteDialogTrigger: FC<\n PropsWithChildren<{\n targetId: string\n onClick?: (open: () => void) => void\n }>\n> = ({ targetId, children, onClick }) => {\n const ref = useRef<HTMLSpanElement | null>(null)\n const onClickRef = useRef(onClick)\n onClickRef.current = onClick\n\n const actualOnClick = useCallback((e: Event) => {\n // HINT: onClick内で非同期処理される場合、e.currentTargetがnullになってしまう可能性があるため\n // 先にariaControlsを取得しておく\n const ariaControls = (e.currentTarget as HTMLElement).getAttribute('aria-controls') as string\n\n if (onClickRef.current) {\n return onClickRef.current(() => {\n onClickRemoteDialogTrigger(ariaControls)\n })\n }\n\n onClickRemoteDialogTrigger(ariaControls)\n }, [])\n\n useEffect(() => {\n const currentRef = ref.current\n if (!currentRef) {\n return\n }\n\n const getClickableElement = () =>\n currentRef.querySelector<HTMLButtonElement | HTMLAnchorElement>('button, a')\n\n // 現在の子要素に対して処理を実行\n const setupElement = () => {\n const element = getClickableElement()\n if (!element) {\n return\n }\n\n element.setAttribute('aria-haspopup', 'dialog')\n element.setAttribute('aria-controls', targetId)\n\n // Button は native disabled ではなく aria-disabled を使うため、\n // 無効時はリスナーを貼らず Dialog が開かないようにする(DropdownTrigger と同じ)\n if (\n !('disabled' in element && element.disabled) &&\n element.getAttribute('aria-disabled') !== 'true'\n ) {\n // HINT: DropdownCloser のonClickより先に実行するため、キャプチャフェーズで処理する\n element.addEventListener('click', actualOnClick, CAPTURE_OPTION)\n }\n }\n\n const clearEventListener = () => {\n // 既存のイベントリスナーをクリーンアップ\n const element = getClickableElement()\n if (element) {\n element.removeEventListener('click', actualOnClick, CAPTURE_OPTION)\n }\n }\n\n // 初回セットアップ\n setupElement()\n\n // MutationObserverでDOM変更を監視\n const observer = new MutationObserver(() => {\n clearEventListener()\n setupElement()\n })\n\n observer.observe(currentRef, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n observer.disconnect()\n clearEventListener()\n }\n }, [targetId, actualOnClick])\n\n return (\n <span className=\"smarthr-ui-RemoteDialogTrigger shr-contents\" ref={ref}>\n {children}\n </span>\n )\n}\n"],"names":[],"mappings":";;;;;AAMA;AACE;;AAGF;AACE;AAEI;AACD;AAEL;AAEO;AAML;AACA;AACA;AAEA;;;;AAKE;AACE;;AAEA;;;;;AAOF;;;;;;;AAUE;;;;AAKA;AACA;;;;;;;;AAWF;;;AAIE;;;;AAIF;;AAGA;;AAGA;AACE;AACA;AACF;AAEA;AACE;AACA;;AAEA;AACA;AACD;AAED;;AAEE;AACF;AACF;AAEA;AAKF;;"}
|
|
@@ -36,10 +36,14 @@ const DisclosureTrigger = ({ targetId, children, onClick }) => {
|
|
|
36
36
|
}
|
|
37
37
|
button.setAttribute('aria-expanded', expanded.toString());
|
|
38
38
|
button.setAttribute('aria-controls', targetId);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
// Button は native disabled ではなく aria-disabled を使うため、
|
|
40
|
+
// 無効時はリスナーを貼らず開閉しないようにする(DropdownTrigger と同じ)
|
|
41
|
+
if (!button.disabled && button.getAttribute('aria-disabled') !== 'true') {
|
|
42
|
+
button.addEventListener('click', actualOnClick);
|
|
43
|
+
currentCleanup = () => {
|
|
44
|
+
button.removeEventListener('click', actualOnClick);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
43
47
|
};
|
|
44
48
|
setupButton();
|
|
45
49
|
const observer = new MutationObserver(setupButton);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DisclosureTrigger.cjs","sources":["../../../src/components/Disclosure/DisclosureTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type ReactElement, useCallback, useEffect, useRef } from 'react'\n\nimport { useDisclosure } from './useDisclosure'\n\ntype DisclosureTriggerNodeChildren = Omit<\n ReactElement,\n 'onClick' | 'aria-expanded' | 'aria-controls'\n>\ntype DisclosureTriggerFuncChildren = (args: { expanded: boolean }) => DisclosureTriggerNodeChildren\n\ntype DisclosureTriggerProps = {\n /** DisclosureContentのidと紐づける文字列 */\n targetId: string\n /** 開閉時のハンドラー */\n onClick?: (open: () => void, e: MouseEvent) => void\n children: DisclosureTriggerNodeChildren | DisclosureTriggerFuncChildren\n}\n\nexport const DisclosureTrigger: FC<DisclosureTriggerProps> = ({ targetId, children, onClick }) => {\n const [expanded, setExpanded] = useDisclosure(targetId)\n const ref = useRef<HTMLSpanElement | null>(null)\n\n const unstableRef = useRef({ onClick, setExpanded })\n unstableRef.current = { onClick, setExpanded }\n\n const actualOnClick = useCallback((e: MouseEvent) => {\n const toggleExpanded = () => {\n unstableRef.current.setExpanded((current) => !current)\n }\n\n if (unstableRef.current.onClick) {\n unstableRef.current.onClick(toggleExpanded, e)\n } else {\n toggleExpanded()\n }\n }, [])\n\n useEffect(() => {\n const wrapper = ref.current\n if (!wrapper) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = wrapper.querySelector('button')\n\n if (!button) {\n throw new Error('DisclosureTriggerのchildrenにbutton要素を設置してください')\n }\n\n button.setAttribute('aria-expanded', expanded.toString())\n button.setAttribute('aria-controls', targetId)\n button.addEventListener('click', actualOnClick)\n\n
|
|
1
|
+
{"version":3,"file":"DisclosureTrigger.cjs","sources":["../../../src/components/Disclosure/DisclosureTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type ReactElement, useCallback, useEffect, useRef } from 'react'\n\nimport { useDisclosure } from './useDisclosure'\n\ntype DisclosureTriggerNodeChildren = Omit<\n ReactElement,\n 'onClick' | 'aria-expanded' | 'aria-controls'\n>\ntype DisclosureTriggerFuncChildren = (args: { expanded: boolean }) => DisclosureTriggerNodeChildren\n\ntype DisclosureTriggerProps = {\n /** DisclosureContentのidと紐づける文字列 */\n targetId: string\n /** 開閉時のハンドラー */\n onClick?: (open: () => void, e: MouseEvent) => void\n children: DisclosureTriggerNodeChildren | DisclosureTriggerFuncChildren\n}\n\nexport const DisclosureTrigger: FC<DisclosureTriggerProps> = ({ targetId, children, onClick }) => {\n const [expanded, setExpanded] = useDisclosure(targetId)\n const ref = useRef<HTMLSpanElement | null>(null)\n\n const unstableRef = useRef({ onClick, setExpanded })\n unstableRef.current = { onClick, setExpanded }\n\n const actualOnClick = useCallback((e: MouseEvent) => {\n const toggleExpanded = () => {\n unstableRef.current.setExpanded((current) => !current)\n }\n\n if (unstableRef.current.onClick) {\n unstableRef.current.onClick(toggleExpanded, e)\n } else {\n toggleExpanded()\n }\n }, [])\n\n useEffect(() => {\n const wrapper = ref.current\n if (!wrapper) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = wrapper.querySelector('button')\n\n if (!button) {\n throw new Error('DisclosureTriggerのchildrenにbutton要素を設置してください')\n }\n\n button.setAttribute('aria-expanded', expanded.toString())\n button.setAttribute('aria-controls', targetId)\n\n // Button は native disabled ではなく aria-disabled を使うため、\n // 無効時はリスナーを貼らず開閉しないようにする(DropdownTrigger と同じ)\n if (!button.disabled && button.getAttribute('aria-disabled') !== 'true') {\n button.addEventListener('click', actualOnClick)\n\n currentCleanup = () => {\n button.removeEventListener('click', actualOnClick)\n }\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n observer.observe(wrapper, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n currentCleanup?.()\n observer.disconnect()\n }\n }, [expanded, targetId, actualOnClick])\n\n // HINT: 念の為spanに対して外部からstyleを当てられるようにしておく。\n // Fragmentにrefが渡せるようになったタイミングでclassNameも不要になる\n // TODO: 将来的にspan -> Fragmentに変更する\n return (\n <span className=\"smarthr-ui-DisclosureTriggerWrapper shr-contents\" ref={ref}>\n {children instanceof Function ? children({ expanded }) : children}\n </span>\n )\n}\n"],"names":[],"mappings":";;;;;;;AAoBO;;AAEL;;;AAKA;;AAEI;AACF;AAEA;;;;AAGE;;;;AAKF;;;;AAKA;;;;;;AASI;;;AAIF;;;AAIA;AACE;;AAGE;AACF;;AAEJ;AAEA;AAEA;AACA;AACE;AACA;;AAEA;AACA;AACD;AAED;;;AAGA;;;;;AAMF;AAKF;;"}
|
|
@@ -34,10 +34,14 @@ const DisclosureTrigger = ({ targetId, children, onClick }) => {
|
|
|
34
34
|
}
|
|
35
35
|
button.setAttribute('aria-expanded', expanded.toString());
|
|
36
36
|
button.setAttribute('aria-controls', targetId);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
// Button は native disabled ではなく aria-disabled を使うため、
|
|
38
|
+
// 無効時はリスナーを貼らず開閉しないようにする(DropdownTrigger と同じ)
|
|
39
|
+
if (!button.disabled && button.getAttribute('aria-disabled') !== 'true') {
|
|
40
|
+
button.addEventListener('click', actualOnClick);
|
|
41
|
+
currentCleanup = () => {
|
|
42
|
+
button.removeEventListener('click', actualOnClick);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
41
45
|
};
|
|
42
46
|
setupButton();
|
|
43
47
|
const observer = new MutationObserver(setupButton);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DisclosureTrigger.js","sources":["../../../src/components/Disclosure/DisclosureTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type ReactElement, useCallback, useEffect, useRef } from 'react'\n\nimport { useDisclosure } from './useDisclosure'\n\ntype DisclosureTriggerNodeChildren = Omit<\n ReactElement,\n 'onClick' | 'aria-expanded' | 'aria-controls'\n>\ntype DisclosureTriggerFuncChildren = (args: { expanded: boolean }) => DisclosureTriggerNodeChildren\n\ntype DisclosureTriggerProps = {\n /** DisclosureContentのidと紐づける文字列 */\n targetId: string\n /** 開閉時のハンドラー */\n onClick?: (open: () => void, e: MouseEvent) => void\n children: DisclosureTriggerNodeChildren | DisclosureTriggerFuncChildren\n}\n\nexport const DisclosureTrigger: FC<DisclosureTriggerProps> = ({ targetId, children, onClick }) => {\n const [expanded, setExpanded] = useDisclosure(targetId)\n const ref = useRef<HTMLSpanElement | null>(null)\n\n const unstableRef = useRef({ onClick, setExpanded })\n unstableRef.current = { onClick, setExpanded }\n\n const actualOnClick = useCallback((e: MouseEvent) => {\n const toggleExpanded = () => {\n unstableRef.current.setExpanded((current) => !current)\n }\n\n if (unstableRef.current.onClick) {\n unstableRef.current.onClick(toggleExpanded, e)\n } else {\n toggleExpanded()\n }\n }, [])\n\n useEffect(() => {\n const wrapper = ref.current\n if (!wrapper) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = wrapper.querySelector('button')\n\n if (!button) {\n throw new Error('DisclosureTriggerのchildrenにbutton要素を設置してください')\n }\n\n button.setAttribute('aria-expanded', expanded.toString())\n button.setAttribute('aria-controls', targetId)\n button.addEventListener('click', actualOnClick)\n\n
|
|
1
|
+
{"version":3,"file":"DisclosureTrigger.js","sources":["../../../src/components/Disclosure/DisclosureTrigger.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type ReactElement, useCallback, useEffect, useRef } from 'react'\n\nimport { useDisclosure } from './useDisclosure'\n\ntype DisclosureTriggerNodeChildren = Omit<\n ReactElement,\n 'onClick' | 'aria-expanded' | 'aria-controls'\n>\ntype DisclosureTriggerFuncChildren = (args: { expanded: boolean }) => DisclosureTriggerNodeChildren\n\ntype DisclosureTriggerProps = {\n /** DisclosureContentのidと紐づける文字列 */\n targetId: string\n /** 開閉時のハンドラー */\n onClick?: (open: () => void, e: MouseEvent) => void\n children: DisclosureTriggerNodeChildren | DisclosureTriggerFuncChildren\n}\n\nexport const DisclosureTrigger: FC<DisclosureTriggerProps> = ({ targetId, children, onClick }) => {\n const [expanded, setExpanded] = useDisclosure(targetId)\n const ref = useRef<HTMLSpanElement | null>(null)\n\n const unstableRef = useRef({ onClick, setExpanded })\n unstableRef.current = { onClick, setExpanded }\n\n const actualOnClick = useCallback((e: MouseEvent) => {\n const toggleExpanded = () => {\n unstableRef.current.setExpanded((current) => !current)\n }\n\n if (unstableRef.current.onClick) {\n unstableRef.current.onClick(toggleExpanded, e)\n } else {\n toggleExpanded()\n }\n }, [])\n\n useEffect(() => {\n const wrapper = ref.current\n if (!wrapper) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = wrapper.querySelector('button')\n\n if (!button) {\n throw new Error('DisclosureTriggerのchildrenにbutton要素を設置してください')\n }\n\n button.setAttribute('aria-expanded', expanded.toString())\n button.setAttribute('aria-controls', targetId)\n\n // Button は native disabled ではなく aria-disabled を使うため、\n // 無効時はリスナーを貼らず開閉しないようにする(DropdownTrigger と同じ)\n if (!button.disabled && button.getAttribute('aria-disabled') !== 'true') {\n button.addEventListener('click', actualOnClick)\n\n currentCleanup = () => {\n button.removeEventListener('click', actualOnClick)\n }\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n observer.observe(wrapper, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n currentCleanup?.()\n observer.disconnect()\n }\n }, [expanded, targetId, actualOnClick])\n\n // HINT: 念の為spanに対して外部からstyleを当てられるようにしておく。\n // Fragmentにrefが渡せるようになったタイミングでclassNameも不要になる\n // TODO: 将来的にspan -> Fragmentに変更する\n return (\n <span className=\"smarthr-ui-DisclosureTriggerWrapper shr-contents\" ref={ref}>\n {children instanceof Function ? children({ expanded }) : children}\n </span>\n )\n}\n"],"names":[],"mappings":";;;;;AAoBO;;AAEL;;;AAKA;;AAEI;AACF;AAEA;;;;AAGE;;;;AAKF;;;;AAKA;;;;;;AASI;;;AAIF;;;AAIA;AACE;;AAGE;AACF;;AAEJ;AAEA;AAEA;AACA;AACE;AACA;;AAEA;AACA;AACD;AAED;;;AAGA;;;;;AAMF;AAKF;;"}
|
|
@@ -6,7 +6,7 @@ var React = require('react');
|
|
|
6
6
|
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
|
|
7
7
|
require('../../intl/IntlProvider.cjs');
|
|
8
8
|
var intl_useIntl = require('../../intl/useIntl.cjs');
|
|
9
|
-
require('
|
|
9
|
+
require('../../intl/Localizer.cjs');
|
|
10
10
|
require('../../_virtual/dayjs.min.cjs');
|
|
11
11
|
require('../../intl/TimeFormatter.cjs');
|
|
12
12
|
var components_Button_Button = require('../Button/Button.cjs');
|
|
@@ -4,7 +4,7 @@ import { forwardRef, useRef, useState, useMemo, useImperativeHandle, useCallback
|
|
|
4
4
|
import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
|
|
5
5
|
import '../../intl/IntlProvider.js';
|
|
6
6
|
import { useIntl } from '../../intl/useIntl.js';
|
|
7
|
-
import '
|
|
7
|
+
import '../../intl/Localizer.js';
|
|
8
8
|
import '../../_virtual/dayjs.min.js';
|
|
9
9
|
import '../../intl/TimeFormatter.js';
|
|
10
10
|
import { Button } from '../Button/Button.js';
|
|
@@ -28,45 +28,27 @@ const Dropdown = ({ onOpen, onClose, children }) => {
|
|
|
28
28
|
const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } = hooks_usePortal.usePortal();
|
|
29
29
|
const triggerElementRef = React.useRef(null);
|
|
30
30
|
const contentId = React.useId();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}, [isChildPortal, portalRoot]);
|
|
31
|
+
const unstableRef = React.useRef({
|
|
32
|
+
active,
|
|
33
|
+
isPortalRootMounted,
|
|
34
|
+
onOpen,
|
|
35
|
+
onClose,
|
|
36
|
+
createPortal,
|
|
37
|
+
});
|
|
38
|
+
unstableRef.current = {
|
|
39
|
+
active,
|
|
40
|
+
isPortalRootMounted,
|
|
41
|
+
onOpen,
|
|
42
|
+
onClose,
|
|
43
|
+
createPortal,
|
|
44
|
+
};
|
|
46
45
|
// This is the root container of a dropdown content located in outside the DOM tree
|
|
47
46
|
const DropdownContentRoot = React.useMemo(() => {
|
|
48
|
-
const result = (props) => active ? createPortal(props.children) : null;
|
|
47
|
+
const result = (props) => unstableRef.current.active ? unstableRef.current.createPortal(props.children) : null;
|
|
49
48
|
// set the displayName explicit for DevTools
|
|
50
49
|
result.displayName = 'DropdownContentRoot';
|
|
51
50
|
return result;
|
|
52
|
-
}, [
|
|
53
|
-
const togglerRef = React.useRef({
|
|
54
|
-
isPortalRootMounted,
|
|
55
|
-
onOpen,
|
|
56
|
-
onClose,
|
|
57
|
-
});
|
|
58
|
-
React.useEffect(() => {
|
|
59
|
-
togglerRef.current = {
|
|
60
|
-
isPortalRootMounted,
|
|
61
|
-
onOpen,
|
|
62
|
-
onClose,
|
|
63
|
-
};
|
|
64
|
-
}, [isPortalRootMounted, onOpen, onClose]);
|
|
65
|
-
React.useEffect(() => {
|
|
66
|
-
if (togglerRef.current.isPortalRootMounted()) {
|
|
67
|
-
togglerRef.current[active ? 'onOpen' : 'onClose']?.();
|
|
68
|
-
}
|
|
69
|
-
}, [active]);
|
|
51
|
+
}, []);
|
|
70
52
|
const memoizedOnClickTrigger = React.useCallback((rect) => {
|
|
71
53
|
setActive((current) => {
|
|
72
54
|
const newActive = !current;
|
|
@@ -81,6 +63,26 @@ const Dropdown = ({ onOpen, onClose, children }) => {
|
|
|
81
63
|
// return focus to the Trigger
|
|
82
64
|
components_Dropdown_dropdownHelper.getFirstTabbable(triggerElementRef)?.focus();
|
|
83
65
|
}, []);
|
|
66
|
+
React.useEffect(() => {
|
|
67
|
+
if (portalRoot) {
|
|
68
|
+
portalRoot.setAttribute('id', contentId);
|
|
69
|
+
}
|
|
70
|
+
const onClickBody = (e) => {
|
|
71
|
+
// ignore events from events within DropdownTrigger and DropdownContent
|
|
72
|
+
if (!components_Dropdown_dropdownHelper.isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {
|
|
73
|
+
setActive(false);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
document.body.addEventListener('click', onClickBody, false);
|
|
77
|
+
return () => {
|
|
78
|
+
document.body.removeEventListener('click', onClickBody, false);
|
|
79
|
+
};
|
|
80
|
+
}, [isChildPortal, portalRoot, contentId]);
|
|
81
|
+
React.useEffect(() => {
|
|
82
|
+
if (unstableRef.current.isPortalRootMounted()) {
|
|
83
|
+
unstableRef.current[active ? 'onOpen' : 'onClose']?.();
|
|
84
|
+
}
|
|
85
|
+
}, [active]);
|
|
84
86
|
return (jsxRuntime.jsx(PortalParentProvider, { children: jsxRuntime.jsx(DropdownContext.Provider, { value: {
|
|
85
87
|
active,
|
|
86
88
|
triggerRect,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.cjs","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n type ReactNode,\n createContext,\n createRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { usePortal } from '../../hooks/usePortal'\n\nimport { type Rect, getFirstTabbable, isEventFromChild } from './dropdownHelper'\n\ntype Props = PropsWithChildren<{\n onOpen?: () => void\n onClose?: () => void\n}>\n\ntype DropdownContextType = {\n active: boolean\n triggerRect: Rect\n triggerElementRef: MutableRefObject<HTMLDivElement | null>\n rootTriggerRef: MutableRefObject<HTMLDivElement | null> | null\n memoizedOnClickTrigger: (rect: Rect) => void\n onClickCloser: () => void\n DropdownContentRoot: FC<{ children: ReactNode }>\n contentId: string\n}\n\nconst initialRect = { top: 0, right: 0, bottom: 0, left: 0 }\n\nexport const DropdownContext = createContext<DropdownContextType>({\n active: false,\n triggerRect: initialRect,\n triggerElementRef: createRef(),\n rootTriggerRef: null,\n memoizedOnClickTrigger: () => {\n /* noop */\n },\n onClickCloser: () => {\n /* noop */\n },\n DropdownContentRoot: () => null,\n contentId: '',\n})\n\nexport const Dropdown: FC<Props> = ({ onOpen, onClose, children }) => {\n const [active, setActive] = useState(false)\n const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)\n\n const { rootTriggerRef } = useContext(DropdownContext)\n const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } =\n usePortal()\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const contentId = useId()\n\n
|
|
1
|
+
{"version":3,"file":"Dropdown.cjs","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n type ReactNode,\n createContext,\n createRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { usePortal } from '../../hooks/usePortal'\n\nimport { type Rect, getFirstTabbable, isEventFromChild } from './dropdownHelper'\n\ntype Props = PropsWithChildren<{\n onOpen?: () => void\n onClose?: () => void\n}>\n\ntype DropdownContextType = {\n active: boolean\n triggerRect: Rect\n triggerElementRef: MutableRefObject<HTMLDivElement | null>\n rootTriggerRef: MutableRefObject<HTMLDivElement | null> | null\n memoizedOnClickTrigger: (rect: Rect) => void\n onClickCloser: () => void\n DropdownContentRoot: FC<{ children: ReactNode }>\n contentId: string\n}\n\nconst initialRect = { top: 0, right: 0, bottom: 0, left: 0 }\n\nexport const DropdownContext = createContext<DropdownContextType>({\n active: false,\n triggerRect: initialRect,\n triggerElementRef: createRef(),\n rootTriggerRef: null,\n memoizedOnClickTrigger: () => {\n /* noop */\n },\n onClickCloser: () => {\n /* noop */\n },\n DropdownContentRoot: () => null,\n contentId: '',\n})\n\nexport const Dropdown: FC<Props> = ({ onOpen, onClose, children }) => {\n const [active, setActive] = useState(false)\n const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)\n\n const { rootTriggerRef } = useContext(DropdownContext)\n const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } =\n usePortal()\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const contentId = useId()\n\n const unstableRef = useRef({\n active,\n isPortalRootMounted,\n onOpen,\n onClose,\n createPortal,\n })\n unstableRef.current = {\n active,\n isPortalRootMounted,\n onOpen,\n onClose,\n createPortal,\n }\n\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot = useMemo<FC<{ children: ReactNode }>>(() => {\n const result: FC<{ children: ReactNode }> = (props) =>\n unstableRef.current.active ? unstableRef.current.createPortal(props.children) : null\n\n // set the displayName explicit for DevTools\n result.displayName = 'DropdownContentRoot'\n\n return result\n }, [])\n\n const memoizedOnClickTrigger = useCallback((rect: Rect) => {\n setActive((current) => {\n const newActive = !current\n\n if (newActive) {\n setTriggerRect(rect)\n }\n\n return newActive\n })\n }, [])\n\n const onClickCloser = useCallback(() => {\n setActive(false)\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n }, [])\n\n useEffect(() => {\n if (portalRoot) {\n portalRoot.setAttribute('id', contentId)\n }\n\n const onClickBody = (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {\n setActive(false)\n }\n }\n\n document.body.addEventListener('click', onClickBody, false)\n\n return () => {\n document.body.removeEventListener('click', onClickBody, false)\n }\n }, [isChildPortal, portalRoot, contentId])\n\n useEffect(() => {\n if (unstableRef.current.isPortalRootMounted()) {\n unstableRef.current[active ? 'onOpen' : 'onClose']?.()\n }\n }, [active])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n memoizedOnClickTrigger,\n onClickCloser,\n DropdownContentRoot,\n contentId,\n }}\n >\n {children}\n </DropdownContext.Provider>\n </PortalParentProvider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAsCA;AAEO;AACL;AACA;;AAEA;;;;;;;AAOA;AACA;AACD;AAEM;;;;AAKL;AAGA;AACA;;;;;;;AAQC;;;;;;;;;AAUD;AACE;;AAIA;AAEA;;AAGF;AACE;AACE;;;;AAMA;AACF;;AAGF;;;AAIE;;;;AAKE;;AAGF;;AAEE;;;AAGF;;AAIA;;AAEA;;;AAIA;AACE;;AAEJ;;;;;AASQ;;;;;AAKD;AAMT;;;"}
|