smarthr-ui 99.3.2 → 99.4.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/_virtual/plugin.cjs +1 -1
- package/lib/_virtual/plugin.js +1 -1
- package/lib/components/AccordionPanel/AccordionPanel.cjs +1 -1
- package/lib/components/AccordionPanel/AccordionPanel.js +1 -1
- package/lib/components/AccordionPanel/AccordionPanelContent.cjs +1 -1
- package/lib/components/AccordionPanel/AccordionPanelContent.js +1 -1
- package/lib/components/AccordionPanel/AccordionPanelItem.cjs +1 -1
- package/lib/components/AccordionPanel/AccordionPanelItem.js +1 -1
- package/lib/components/AccordionPanel/AccordionPanelTrigger.cjs +1 -1
- package/lib/components/AccordionPanel/AccordionPanelTrigger.js +1 -1
- 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/common/CommonButton.cjs +1 -1
- package/lib/components/AppHeader/components/common/CommonButton.js +1 -1
- package/lib/components/AppHeader/components/desktop/AppLauncher.cjs +3 -3
- package/lib/components/AppHeader/components/desktop/AppLauncher.cjs.map +1 -1
- package/lib/components/AppHeader/components/desktop/AppLauncher.js +3 -3
- 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/Navigation.cjs +1 -1
- package/lib/components/AppHeader/components/desktop/Navigation.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 +3 -3
- package/lib/components/AppHeader/components/mobile/AppLauncher.cjs.map +1 -1
- package/lib/components/AppHeader/components/mobile/AppLauncher.js +3 -3
- package/lib/components/AppHeader/components/mobile/AppLauncher.js.map +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/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/MenuDialog.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/MenuDialog.js +1 -1
- package/lib/components/AppHeader/components/mobile/MobileHeader.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/MobileHeader.cjs.map +1 -1
- package/lib/components/AppHeader/components/mobile/MobileHeader.js +1 -1
- package/lib/components/AppHeader/components/mobile/MobileHeader.js.map +1 -1
- package/lib/components/AppHeader/components/mobile/Navigation.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/Navigation.js +1 -1
- package/lib/components/AppHeader/components/mobile/NavigationItem.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/NavigationItem.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/TenantSelector.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/TenantSelector.js +1 -1
- package/lib/components/AppHeader/components/mobile/UserInfo.cjs +1 -1
- package/lib/components/AppHeader/components/mobile/UserInfo.js +1 -1
- package/lib/components/AppHeader/hooks/useAppLauncher.cjs +10 -2
- package/lib/components/AppHeader/hooks/useAppLauncher.cjs.map +1 -1
- package/lib/components/AppHeader/hooks/useAppLauncher.d.ts +1 -0
- package/lib/components/AppHeader/hooks/useAppLauncher.js +10 -2
- package/lib/components/AppHeader/hooks/useAppLauncher.js.map +1 -1
- package/lib/components/AppNavi/AppNavi.cjs +1 -1
- package/lib/components/AppNavi/AppNavi.js +1 -1
- package/lib/components/AppNavi/AppNaviAnchor.cjs +1 -1
- package/lib/components/AppNavi/AppNaviAnchor.js +1 -1
- package/lib/components/AppNavi/AppNaviButton.cjs +1 -1
- package/lib/components/AppNavi/AppNaviButton.js +1 -1
- package/lib/components/AppNavi/AppNaviCustomTag.cjs +1 -1
- package/lib/components/AppNavi/AppNaviCustomTag.js +1 -1
- package/lib/components/AppNavi/AppNaviDropdown.cjs +1 -1
- package/lib/components/AppNavi/AppNaviDropdown.js +1 -1
- package/lib/components/AppNavi/AppNaviDropdownMenuButton.cjs +1 -1
- package/lib/components/AppNavi/AppNaviDropdownMenuButton.js +1 -1
- package/lib/components/AppNavi/itemClassNameGenerator.cjs +1 -1
- package/lib/components/AppNavi/itemClassNameGenerator.js +1 -1
- package/lib/components/Badge/Badge.cjs +1 -1
- package/lib/components/Badge/Badge.js +1 -1
- package/lib/components/BottomFixedArea/BottomFixedArea.cjs +1 -1
- package/lib/components/BottomFixedArea/BottomFixedArea.js +1 -1
- package/lib/components/Browser/Browser.cjs +1 -1
- package/lib/components/Browser/Browser.js +1 -1
- package/lib/components/Browser/BrowserColumn.cjs +1 -1
- package/lib/components/Browser/BrowserColumn.js +1 -1
- package/lib/components/Browser/BrowserItem.cjs +1 -1
- package/lib/components/Browser/BrowserItem.js +1 -1
- package/lib/components/Button/AnchorButton.cjs +1 -1
- package/lib/components/Button/AnchorButton.js +1 -1
- package/lib/components/Button/Button.cjs +1 -1
- package/lib/components/Button/Button.js +1 -1
- package/lib/components/Button/DisabledReason.cjs +1 -1
- package/lib/components/Button/DisabledReason.js +1 -1
- package/lib/components/Button/UnstyledButton.cjs +1 -1
- package/lib/components/Button/UnstyledButton.js +1 -1
- package/lib/components/Button/useButtonWrapper.cjs +1 -1
- package/lib/components/Button/useButtonWrapper.js +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/Checkbox/Checkbox.cjs +1 -1
- package/lib/components/Checkbox/Checkbox.js +1 -1
- package/lib/components/Chip/Chip.cjs +1 -1
- package/lib/components/Chip/Chip.js +1 -1
- package/lib/components/Combobox/ItemButton.cjs +1 -1
- package/lib/components/Combobox/ItemButton.js +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs +15 -5
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +16 -6
- 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 +7 -3
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +8 -4
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
- package/lib/components/Combobox/useListbox.cjs +8 -4
- package/lib/components/Combobox/useListbox.cjs.map +1 -1
- package/lib/components/Combobox/useListbox.js +8 -4
- package/lib/components/Combobox/useListbox.js.map +1 -1
- package/lib/components/DatePicker/DatePicker.cjs +7 -3
- package/lib/components/DatePicker/DatePicker.cjs.map +1 -1
- package/lib/components/DatePicker/DatePicker.js +7 -3
- package/lib/components/DatePicker/DatePicker.js.map +1 -1
- package/lib/components/DefinitionList/DefinitionList.cjs +1 -1
- package/lib/components/DefinitionList/DefinitionList.js +1 -1
- package/lib/components/DefinitionList/DefinitionListItem.cjs +8 -9
- package/lib/components/DefinitionList/DefinitionListItem.cjs.map +1 -1
- package/lib/components/DefinitionList/DefinitionListItem.js +8 -9
- package/lib/components/DefinitionList/DefinitionListItem.js.map +1 -1
- package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs +1 -1
- package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs +32 -4
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs.map +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.d.ts +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js +29 -1
- package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js.map +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs.map +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.d.ts +1 -2
- package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js.map +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/type.cjs +3 -0
- package/lib/components/Dialog/ControlledStepFormDialog/type.cjs.map +1 -0
- package/lib/components/Dialog/ControlledStepFormDialog/type.d.ts +25 -0
- package/lib/components/Dialog/ControlledStepFormDialog/type.js +2 -0
- package/lib/components/Dialog/ControlledStepFormDialog/type.js.map +1 -0
- package/lib/components/Dialog/DialogBody.cjs +1 -1
- package/lib/components/Dialog/DialogBody.js +1 -1
- package/lib/components/Dialog/DialogContentInner.cjs +1 -1
- package/lib/components/Dialog/DialogContentInner.js +1 -1
- package/lib/components/Dialog/DialogOverlap.cjs +1 -1
- package/lib/components/Dialog/DialogOverlap.js +1 -1
- package/lib/components/Dialog/FocusTrap.cjs +61 -44
- package/lib/components/Dialog/FocusTrap.cjs.map +1 -1
- package/lib/components/Dialog/FocusTrap.js +62 -45
- 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/useRemoteTrigger.cjs +20 -10
- package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.cjs.map +1 -1
- package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.d.ts +1 -1
- package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.js +20 -10
- package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.js.map +1 -1
- package/lib/components/Dialog/dialogInnerStyle.cjs +1 -1
- package/lib/components/Dialog/dialogInnerStyle.js +1 -1
- package/lib/components/Disclosure/useDisclosure.cjs +6 -3
- package/lib/components/Disclosure/useDisclosure.cjs.map +1 -1
- package/lib/components/Disclosure/useDisclosure.js +6 -3
- package/lib/components/Disclosure/useDisclosure.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 +20 -9
- package/lib/components/Dropdown/Dropdown.cjs.map +1 -1
- package/lib/components/Dropdown/Dropdown.js +20 -9
- package/lib/components/Dropdown/Dropdown.js.map +1 -1
- package/lib/components/Dropdown/DropdownCloser.cjs +1 -1
- package/lib/components/Dropdown/DropdownCloser.js +1 -1
- package/lib/components/Dropdown/DropdownContentInner.cjs +79 -3
- package/lib/components/Dropdown/DropdownContentInner.cjs.map +1 -1
- package/lib/components/Dropdown/DropdownContentInner.js +81 -5
- package/lib/components/Dropdown/DropdownContentInner.js.map +1 -1
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs +70 -3
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs.map +1 -1
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js +71 -4
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js.map +1 -1
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuGroup.cjs +1 -1
- package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuGroup.js +1 -1
- package/lib/components/Dropdown/DropdownTrigger.cjs +1 -1
- package/lib/components/Dropdown/DropdownTrigger.js +1 -1
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs +1 -1
- package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js +1 -1
- package/lib/components/Dropdown/SortDropdown/SortDropdown.cjs +68 -14
- package/lib/components/Dropdown/SortDropdown/SortDropdown.cjs.map +1 -1
- package/lib/components/Dropdown/SortDropdown/SortDropdown.js +69 -15
- package/lib/components/Dropdown/SortDropdown/SortDropdown.js.map +1 -1
- package/lib/components/ErrorScreen/ErrorScreen.cjs +1 -1
- package/lib/components/ErrorScreen/ErrorScreen.js +1 -1
- package/lib/components/FileViewer/PDFViewer.cjs +27 -26
- package/lib/components/FileViewer/PDFViewer.cjs.map +1 -1
- package/lib/components/FileViewer/PDFViewer.js +28 -27
- package/lib/components/FileViewer/PDFViewer.js.map +1 -1
- package/lib/components/FileViewer/SearchController.cjs +1 -1
- package/lib/components/FileViewer/SearchController.js +1 -1
- package/lib/components/FloatArea/FloatArea.cjs +26 -85
- package/lib/components/FloatArea/FloatArea.cjs.map +1 -1
- package/lib/components/FloatArea/FloatArea.js +26 -85
- package/lib/components/FloatArea/FloatArea.js.map +1 -1
- package/lib/components/FormControl/FormControl.cjs +60 -41
- package/lib/components/FormControl/FormControl.cjs.map +1 -1
- package/lib/components/FormControl/FormControl.js +60 -41
- package/lib/components/FormControl/FormControl.js.map +1 -1
- package/lib/components/Header/AppLauncher/AppLauncher.cjs +5 -5
- package/lib/components/Header/AppLauncher/AppLauncher.cjs.map +1 -1
- package/lib/components/Header/AppLauncher/AppLauncher.js +5 -5
- package/lib/components/Header/AppLauncher/AppLauncher.js.map +1 -1
- package/lib/components/Header/Header.cjs +1 -1
- package/lib/components/Header/Header.js +1 -1
- package/lib/components/Header/HeaderDropdownMenuButton.cjs +1 -1
- package/lib/components/Header/HeaderDropdownMenuButton.js +1 -1
- package/lib/components/Header/HeaderLink.cjs +1 -1
- package/lib/components/Header/HeaderLink.js +1 -1
- package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.cjs +1 -1
- package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.js +1 -1
- package/lib/components/Heading/Heading.cjs +1 -1
- package/lib/components/Heading/Heading.js +1 -1
- package/lib/components/Heading/PageHeading/PageHeading.cjs +43 -27
- package/lib/components/Heading/PageHeading/PageHeading.cjs.map +1 -1
- package/lib/components/Heading/PageHeading/PageHeading.js +44 -28
- package/lib/components/Heading/PageHeading/PageHeading.js.map +1 -1
- package/lib/components/Icon/generateIcon.cjs +1 -1
- package/lib/components/Icon/generateIcon.js +1 -1
- package/lib/components/InformationPanel/InformationPanel.cjs +7 -7
- package/lib/components/InformationPanel/InformationPanel.cjs.map +1 -1
- package/lib/components/InformationPanel/InformationPanel.js +8 -8
- package/lib/components/InformationPanel/InformationPanel.js.map +1 -1
- package/lib/components/Input/CurrencyInput/CurrencyInput.cjs +17 -16
- package/lib/components/Input/CurrencyInput/CurrencyInput.cjs.map +1 -1
- package/lib/components/Input/CurrencyInput/CurrencyInput.js +18 -17
- package/lib/components/Input/CurrencyInput/CurrencyInput.js.map +1 -1
- package/lib/components/Input/Input.cjs +15 -16
- package/lib/components/Input/Input.cjs.map +1 -1
- package/lib/components/Input/Input.js +16 -17
- package/lib/components/Input/Input.js.map +1 -1
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.cjs +3 -3
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.cjs.map +1 -1
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.js +3 -3
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.js.map +1 -1
- package/lib/components/Input/SearchInput/SearchInput.cjs +10 -3
- package/lib/components/Input/SearchInput/SearchInput.cjs.map +1 -1
- package/lib/components/Input/SearchInput/SearchInput.js +10 -3
- package/lib/components/Input/SearchInput/SearchInput.js.map +1 -1
- package/lib/components/InputFile/style.cjs +1 -1
- package/lib/components/InputFile/style.js +1 -1
- package/lib/components/Layout/Center/Center.cjs +1 -1
- package/lib/components/Layout/Center/Center.js +1 -1
- package/lib/components/Layout/Cluster/Cluster.cjs +1 -1
- package/lib/components/Layout/Cluster/Cluster.js +1 -1
- package/lib/components/Layout/Container/Container.cjs +1 -1
- package/lib/components/Layout/Container/Container.js +1 -1
- package/lib/components/Layout/Reel/Reel.cjs +1 -1
- package/lib/components/Layout/Reel/Reel.js +1 -1
- package/lib/components/Layout/Sidebar/Sidebar.cjs +1 -1
- package/lib/components/Layout/Sidebar/Sidebar.js +1 -1
- package/lib/components/Layout/Stack/Stack.cjs +1 -1
- package/lib/components/Layout/Stack/Stack.js +1 -1
- package/lib/components/LineClamp/LineClamp.cjs +1 -1
- package/lib/components/LineClamp/LineClamp.js +1 -1
- package/lib/components/Loader/Loader.cjs +1 -1
- package/lib/components/Loader/Loader.js +1 -1
- package/lib/components/Loader/LoaderSpinner.cjs +1 -1
- package/lib/components/Loader/LoaderSpinner.js +1 -1
- package/lib/components/NotificationBar/NotificationBar.cjs +1 -1
- package/lib/components/NotificationBar/NotificationBar.js +1 -1
- package/lib/components/PageCounter/PageCounter.cjs +1 -1
- package/lib/components/PageCounter/PageCounter.js +1 -1
- package/lib/components/Pagination/Pagination.cjs +1 -1
- package/lib/components/Pagination/Pagination.js +1 -1
- package/lib/components/Panel/Groupbox/Groupbox.cjs +1 -1
- package/lib/components/Panel/Groupbox/Groupbox.js +1 -1
- package/lib/components/Panel/Panel.cjs +1 -1
- package/lib/components/Panel/Panel.js +1 -1
- package/lib/components/Picker/style.cjs +1 -1
- package/lib/components/Picker/style.js +1 -1
- package/lib/components/RadioButton/RadioButton.cjs +1 -1
- package/lib/components/RadioButton/RadioButton.js +1 -1
- package/lib/components/RadioButtonPanel/RadioButtonPanel.cjs +5 -4
- package/lib/components/RadioButtonPanel/RadioButtonPanel.cjs.map +1 -1
- package/lib/components/RadioButtonPanel/RadioButtonPanel.js +6 -5
- package/lib/components/RadioButtonPanel/RadioButtonPanel.js.map +1 -1
- package/lib/components/ResponseMessage/ResponseMessage.cjs +1 -1
- package/lib/components/ResponseMessage/ResponseMessage.js +1 -1
- package/lib/components/Scroller/Scroller.cjs +23 -13
- package/lib/components/Scroller/Scroller.cjs.map +1 -1
- package/lib/components/Scroller/Scroller.js +24 -14
- package/lib/components/Scroller/Scroller.js.map +1 -1
- package/lib/components/SegmentedControl/SegmentedControl.cjs +30 -23
- package/lib/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
- package/lib/components/SegmentedControl/SegmentedControl.js +31 -24
- package/lib/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/lib/components/Select/Select.cjs +1 -1
- package/lib/components/Select/Select.js +1 -1
- package/lib/components/SideMenu/SideMenu.cjs +1 -1
- package/lib/components/SideMenu/SideMenu.js +1 -1
- package/lib/components/SideMenu/SideMenuGroup.cjs +1 -1
- package/lib/components/SideMenu/SideMenuGroup.js +1 -1
- package/lib/components/SideMenu/SideMenuItem.cjs +1 -1
- package/lib/components/SideMenu/SideMenuItem.js +1 -1
- package/lib/components/SideNav/SideNav.cjs +1 -1
- package/lib/components/SideNav/SideNav.js +1 -1
- package/lib/components/SideNav/SideNavItemButton.cjs +1 -1
- package/lib/components/SideNav/SideNavItemButton.js +1 -1
- package/lib/components/SmartHRLogo/SmartHRLogo.cjs +1 -1
- package/lib/components/SmartHRLogo/SmartHRLogo.js +1 -1
- package/lib/components/SpreadsheetTable/SpreadsheetTable.cjs +1 -1
- package/lib/components/SpreadsheetTable/SpreadsheetTable.js +1 -1
- package/lib/components/StatusLabel/StatusLabel.cjs +1 -1
- package/lib/components/StatusLabel/StatusLabel.js +1 -1
- package/lib/components/Stepper/HorizontalStepItem.cjs +1 -1
- package/lib/components/Stepper/HorizontalStepItem.js +1 -1
- package/lib/components/Stepper/StepCounter.cjs +1 -1
- package/lib/components/Stepper/StepCounter.js +1 -1
- package/lib/components/Stepper/StepStatusIcon.cjs +1 -1
- package/lib/components/Stepper/StepStatusIcon.js +1 -1
- package/lib/components/Stepper/Stepper.cjs +1 -1
- package/lib/components/Stepper/Stepper.js +1 -1
- package/lib/components/Stepper/VerticalStepItem.cjs +1 -1
- package/lib/components/Stepper/VerticalStepItem.js +1 -1
- package/lib/components/Switch/Switch.cjs +1 -1
- package/lib/components/Switch/Switch.js +1 -1
- package/lib/components/TabBar/TabBar.cjs +1 -1
- package/lib/components/TabBar/TabBar.js +1 -1
- package/lib/components/TabBar/TabItem.cjs +1 -1
- package/lib/components/TabBar/TabItem.js +1 -1
- package/lib/components/Table/BulkActionRow.cjs +1 -1
- package/lib/components/Table/BulkActionRow.js +1 -1
- package/lib/components/Table/EmptyTableBody.cjs +1 -1
- package/lib/components/Table/EmptyTableBody.js +1 -1
- package/lib/components/Table/Table.cjs +1 -1
- package/lib/components/Table/Table.js +1 -1
- package/lib/components/Table/TableReel.cjs +1 -1
- package/lib/components/Table/TableReel.js +1 -1
- package/lib/components/Table/Td.cjs +1 -1
- package/lib/components/Table/Td.js +1 -1
- package/lib/components/Table/TdCheckbox.cjs +1 -1
- package/lib/components/Table/TdCheckbox.js +1 -1
- package/lib/components/Table/TdRadioButton.cjs +1 -1
- package/lib/components/Table/TdRadioButton.js +1 -1
- package/lib/components/Table/Th.cjs +1 -1
- package/lib/components/Table/Th.js +1 -1
- package/lib/components/Table/ThCheckbox.cjs +1 -1
- package/lib/components/Table/ThCheckbox.js +1 -1
- package/lib/components/Table/ThSortButton.cjs +1 -1
- package/lib/components/Table/ThSortButton.js +1 -1
- package/lib/components/Table/reelShadowStyle.cjs +1 -1
- package/lib/components/Table/reelShadowStyle.js +1 -1
- package/lib/components/Text/Text.cjs +1 -1
- package/lib/components/Text/Text.js +1 -1
- package/lib/components/TextLink/TextLink.cjs +1 -1
- package/lib/components/TextLink/TextLink.js +1 -1
- package/lib/components/TextLink/UpwardLink/UpwardLink.cjs +1 -1
- package/lib/components/TextLink/UpwardLink/UpwardLink.js +1 -1
- package/lib/components/Textarea/Textarea.cjs +1 -1
- package/lib/components/Textarea/Textarea.js +1 -1
- package/lib/components/Timeline/Timeline.cjs +1 -1
- package/lib/components/Timeline/Timeline.js +1 -1
- package/lib/components/Timeline/TimelineItem.cjs +1 -1
- package/lib/components/Timeline/TimelineItem.js +1 -1
- package/lib/components/Tooltip/ControlledTooltip.cjs +1 -1
- package/lib/components/Tooltip/ControlledTooltip.js +1 -1
- package/lib/components/Tooltip/Tooltip.cjs +1 -1
- package/lib/components/Tooltip/Tooltip.js +1 -1
- package/lib/components/Tooltip/TooltipPortal.cjs +1 -1
- package/lib/components/Tooltip/TooltipPortal.js +1 -1
- package/lib/components/VisuallyHiddenText/VisuallyHiddenText.cjs +1 -1
- package/lib/components/VisuallyHiddenText/VisuallyHiddenText.js +1 -1
- package/lib/configureTwMerge.cjs +1 -1
- package/lib/configureTwMerge.js +1 -1
- package/lib/hooks/useAnimationFrame.cjs +40 -0
- package/lib/hooks/useAnimationFrame.cjs.map +1 -0
- package/lib/hooks/useAnimationFrame.d.ts +19 -0
- package/lib/hooks/useAnimationFrame.js +38 -0
- package/lib/hooks/useAnimationFrame.js.map +1 -0
- package/lib/hooks/useLatest.cjs +1 -2
- package/lib/hooks/useLatest.cjs.map +1 -1
- package/lib/hooks/useLatest.js +1 -2
- package/lib/hooks/useLatest.js.map +1 -1
- package/lib/hooks/useMediaQueries/useMediaQueries.cjs +41 -29
- package/lib/hooks/useMediaQueries/useMediaQueries.cjs.map +1 -1
- package/lib/hooks/useMediaQueries/useMediaQueries.js +42 -30
- package/lib/hooks/useMediaQueries/useMediaQueries.js.map +1 -1
- package/lib/hooks/useMergeRefs.cjs +56 -0
- package/lib/hooks/useMergeRefs.cjs.map +1 -0
- package/lib/hooks/useMergeRefs.d.ts +18 -0
- package/lib/hooks/useMergeRefs.js +54 -0
- package/lib/hooks/useMergeRefs.js.map +1 -0
- package/lib/hooks/useOnce.cjs +42 -0
- package/lib/hooks/useOnce.cjs.map +1 -0
- package/lib/hooks/useOnce.d.ts +19 -0
- package/lib/hooks/useOnce.js +40 -0
- package/lib/hooks/useOnce.js.map +1 -0
- package/lib/hooks/useSV/useSV.cjs +1 -1
- package/lib/hooks/useSV/useSV.js +1 -1
- package/lib/index.cjs +2 -0
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/{components/Input/CurrencyInput/currencyInputHelper.js → libs/formatNumericString.cjs} +11 -3
- package/lib/libs/formatNumericString.cjs.map +1 -0
- package/lib/libs/formatNumericString.d.ts +7 -0
- package/lib/{components/Input/CurrencyInput/currencyInputHelper.cjs → libs/formatNumericString.js} +9 -5
- package/lib/libs/formatNumericString.js.map +1 -0
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/chunk-I2QGXAA3.cjs.map +1 -0
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/chunk-I2QGXAA3.js.map +1 -0
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs.map +1 -0
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js.map +1 -0
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.cjs.map +1 -0
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.js.map +1 -0
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.cjs.map +1 -0
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.js.map +1 -0
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.cjs.map +1 -0
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.js.map +1 -0
- package/metadata.json +1 -1
- package/package.json +1 -1
- package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.cjs +0 -36
- package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.cjs.map +0 -1
- package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.d.ts +0 -32
- package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.js +0 -34
- package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.js.map +0 -1
- package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.cjs +0 -78
- package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.cjs.map +0 -1
- package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.d.ts +0 -3
- package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.js +0 -76
- package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.js.map +0 -1
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs +0 -136
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs.map +0 -1
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.d.ts +0 -34
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.js +0 -134
- package/lib/components/Dropdown/SortDropdown/useSortDropdown.js.map +0 -1
- package/lib/components/Dropdown/useKeyboardNavigation.cjs +0 -90
- package/lib/components/Dropdown/useKeyboardNavigation.cjs.map +0 -1
- package/lib/components/Dropdown/useKeyboardNavigation.d.ts +0 -2
- package/lib/components/Dropdown/useKeyboardNavigation.js +0 -88
- package/lib/components/Dropdown/useKeyboardNavigation.js.map +0 -1
- package/lib/components/Input/CurrencyInput/currencyInputHelper.cjs.map +0 -1
- package/lib/components/Input/CurrencyInput/currencyInputHelper.d.ts +0 -1
- package/lib/components/Input/CurrencyInput/currencyInputHelper.js.map +0 -1
- package/lib/components/Input/SearchInput/SearchInputIcon.cjs +0 -18
- package/lib/components/Input/SearchInput/SearchInputIcon.cjs.map +0 -1
- package/lib/components/Input/SearchInput/SearchInputIcon.d.ts +0 -1
- package/lib/components/Input/SearchInput/SearchInputIcon.js +0 -16
- package/lib/components/Input/SearchInput/SearchInputIcon.js.map +0 -1
- package/lib/libs/object.cjs +0 -8
- package/lib/libs/object.cjs.map +0 -1
- package/lib/libs/object.d.ts +0 -6
- package/lib/libs/object.js +0 -5
- package/lib/libs/object.js.map +0 -1
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/chunk-I2QGXAA3.cjs.map +0 -1
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/chunk-I2QGXAA3.js.map +0 -1
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs.map +0 -1
- package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js.map +0 -1
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.cjs.map +0 -1
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.js.map +0 -1
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.cjs.map +0 -1
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.js.map +0 -1
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.cjs.map +0 -1
- package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.js.map +0 -1
- /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/chunk-I2QGXAA3.cjs +0 -0
- /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/chunk-I2QGXAA3.js +0 -0
- /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/index.cjs +0 -0
- /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/index.js +0 -0
- /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/public/create-plugin.cjs +0 -0
- /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/public/create-plugin.js +0 -0
- /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/util/createPlugin.cjs +0 -0
- /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/util/createPlugin.js +0 -0
- /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/plugin.cjs +0 -0
- /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/plugin.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useListbox.js","sources":["../../../src/components/Combobox/useListbox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n memo,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useEnhancedEffect } from '../../hooks/useEnhancedEffect'\nimport { useLatest } from '../../hooks/useLatest'\nimport { usePortal } from '../../hooks/usePortal'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Localizer } from '../../intl'\nimport { findDelegateTarget } from '../../libs/delegate'\nimport { FaCircleInfoIcon } from '../Icon'\nimport { Loader } from '../Loader'\nimport { Scroller } from '../Scroller'\nimport { Text } from '../Text'\nimport { VisuallyHiddenText } from '../VisuallyHiddenText'\n\nimport { ItemButton } from './ItemButton'\n\nimport type { ComboboxItem, ComboboxOption } from './types'\n\ntype Props<T> = {\n options: Array<ComboboxOption<T>>\n dropdownHelpMessage?: ReactNode\n dropdownWidth?: string | number\n onAdd?: (label: string) => void\n onSelect: (item: ComboboxItem<T>) => void\n isExpanded: boolean\n isLoading?: boolean\n triggerRef: RefObject<HTMLElement>\n /** 検索結果が0件の時に表示するコンテンツ */\n noResultText?: ReactNode\n}\n\ntype Rect = {\n top: number\n left: number\n height?: number\n}\n\nconst KEY_DOWN_REGEX = /^(Arrow)?Down$/\nconst KEY_UP_REGEX = /^(Arrow)?Up/\n\nconst OPTION_INCREMENT_AMOUNT = 100\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'shr-absolute',\n dropdownList: [\n 'smarthr-ui-Combobox-dropdownList',\n 'shr-absolute shr-z-overlap shr-box-border shr-min-w-full shr-rounded-m shr-bg-white shr-py-0.5 shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',\n /* 縦スクロールに気づきやすくするために8個目のアイテムが半分見切れるように max-height を算出\n = (アイテムのフォントサイズ + アイテムの上下padding) * 7.5 + コンテナの上padding */\n 'shr-max-h-[calc((theme(fontSize.base)_+_theme(spacing[0.5])_*_2)_*_7.5_+_theme(spacing[0.5]))]',\n 'aria-hidden:shr-hidden',\n ],\n helpMessage:\n 'shr-whitespace-[initial] shr-border-b-shorthand shr-mx-0.5 shr-mb-0.5 shr-mt-0 shr-px-0.5 shr-pb-0.5 shr-pt-0 shr-text-sm',\n loaderWrapper: 'shr-flex shr-items-center shr-justify-center shr-p-1',\n noItems: 'smarthr-ui-Combobox-noItems shr-my-0 shr-bg-white shr-px-1 shr-py-0.5 shr-text-base',\n },\n})\n\nconst CLASS_NAMES = (() => {\n const { wrapper, dropdownList, helpMessage, loaderWrapper, noItems } = classNameGenerator()\n\n return {\n wrapper: wrapper(),\n dropdownList: dropdownList(),\n helpMessage: helpMessage(),\n loaderWrapper: loaderWrapper(),\n noItems: noItems(),\n }\n})()\n\nexport const useListbox = <T,>({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect,\n isExpanded,\n isLoading,\n triggerRef,\n noResultText,\n}: Props<T>) => {\n const listBoxId = useId()\n\n const [navigationType, setNavigationType] = useState<'pointer' | 'key'>('pointer')\n const [activeOption, setActiveOption] = useState<ComboboxOption<T> | null>(null)\n const [listBoxRect, setListBoxRect] = useState<Rect>({\n top: 0,\n left: 0,\n })\n // HINT: calculateRectで同時に計算するとwidthの幅が変更されるタイミングの問題でlistBoxHeightが変化する場合がある\n const [triggerWidth, setTriggerWidth] = useState(0)\n\n const listBoxRef = useRef<HTMLDivElement>(null)\n const activeRef = useRef<HTMLButtonElement>(null)\n\n const theme = useTheme()\n\n const latest = useLatest({ onAdd, onSelect, activeOption, options, triggerRef, theme })\n const hasOnAdd = !!onAdd\n\n const functions = useMemo(() => {\n const moveActiveOptionIndex = (currentActive: ComboboxOption<T> | null, delta: -1 | 1) => {\n if (latest.options.every((option) => option.item.disabled)) {\n return\n }\n\n const currentActiveIndex =\n currentActive === null\n ? -1\n : latest.options.findIndex((option) => option.id === currentActive.id)\n let nextIndex = 0\n\n if (currentActiveIndex !== -1) {\n nextIndex = (currentActiveIndex + delta + latest.options.length) % latest.options.length\n } else if (delta !== 1) {\n nextIndex = latest.options.length - 1\n }\n\n const nextActive = latest.options[nextIndex]\n\n if (nextActive) {\n if (nextActive.item.disabled) {\n moveActiveOptionIndex(nextActive, delta)\n } else {\n setActiveOption(nextActive)\n }\n }\n }\n\n return {\n calculateRect: () => {\n if (!listBoxRef.current || !latest.triggerRef.current) {\n return\n }\n const rect = latest.triggerRef.current.getBoundingClientRect()\n const bottomSpace = window.innerHeight - rect.bottom\n const topSpace = rect.top\n const listBoxHeight = Math.min(\n listBoxRef.current.scrollHeight,\n parseInt(getComputedStyle(listBoxRef.current).maxHeight, 10),\n )\n const offset = 2\n\n let top = 0\n let height: number | undefined = undefined\n\n if (bottomSpace >= listBoxHeight) {\n // 下側に十分なスペースがある場合は下側に通常表示\n top = rect.top + rect.height - offset + window.pageYOffset\n } else if (topSpace >= listBoxHeight) {\n // 上側に十分なスペースがある場合は上側に通常表示\n top = rect.top - listBoxHeight + offset + window.pageYOffset\n } else if (topSpace > bottomSpace) {\n // 上下に十分なスペースがなく、上側の方がスペースが大きい場合は上側に縮めて表示\n top = rect.top - topSpace + offset + window.pageYOffset\n height = topSpace\n } else {\n // 下側に縮めて表示\n top = rect.top + rect.height - offset + window.pageYOffset\n height = bottomSpace\n }\n\n // HINT: dropdownWidth は 'auto' や '%' などの CSS 値を取りうるため、算出済みの幅を実測して判定する\n const listBoxWidth = listBoxRef.current.getBoundingClientRect().width\n // ドロップダウンの幅は maxWidth でビューポート右端から余白分を残すよう制限しているため、位置の判定にも同じ余白を使う\n const viewportMargin = parseInt(latest.theme.spacingByChar(0.5), 10)\n // 入力欄の左端を起点に右方向へ表示する場合に使える幅\n const rightSpace = window.innerWidth - rect.left - viewportMargin\n // 入力欄の右端を起点に左方向へ表示する場合に使える幅\n const leftSpace = rect.right\n\n // ビューポートの左端を基準に計算\n let left = window.pageXOffset\n\n if (listBoxWidth <= rightSpace) {\n // 右側に十分なスペースがある場合は入力欄の左端に揃えて通常表示\n left += rect.left\n } else if (listBoxWidth <= leftSpace) {\n // 左側に収まる場合は入力欄の右端に揃えて表示\n left += rect.right - listBoxWidth\n }\n\n setListBoxRect({\n top,\n left,\n height,\n })\n setTriggerWidth(rect.width)\n },\n handleKeyDownListBox: (e: KeyboardEvent<HTMLElement>) => {\n setNavigationType('key')\n\n if (KEY_DOWN_REGEX.test(e.key)) {\n e.stopPropagation()\n moveActiveOptionIndex(latest.activeOption, 1)\n } else if (KEY_UP_REGEX.test(e.key)) {\n e.stopPropagation()\n moveActiveOptionIndex(latest.activeOption, -1)\n } else if (e.key === 'Enter') {\n if (latest.activeOption === null) {\n return\n }\n\n e.stopPropagation()\n\n if (!latest.activeOption.isNew) {\n latest.onSelect(latest.activeOption.item)\n } else if (latest.onAdd) {\n latest.onAdd(latest.activeOption.item.value)\n }\n } else {\n setActiveOption(null)\n }\n },\n handleAdd: hasOnAdd\n ? (option: ComboboxOption<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n latest.onAdd!(option.item.value)\n })\n }\n : undefined,\n handleSelect: (option: ComboboxOption<T>) => {\n latest.onSelect(option.item)\n },\n handleHoverOption: (option: ComboboxOption<T>) => {\n setNavigationType('pointer')\n setActiveOption(option)\n },\n }\n }, [hasOnAdd, latest])\n\n useEffect(() => {\n // props の変更によって activeOption の状態が変わりうるので、実態を反映する\n setActiveOption((current) => {\n if (current === null) {\n return null\n }\n\n return options.find((option) => current.id === option.id) ?? null\n })\n }, [options])\n\n useEffect(() => {\n // actionOption の要素が表示される位置までリストボックス内をスクロールさせる\n if (\n !activeRef.current ||\n !listBoxRef.current ||\n activeOption === null ||\n navigationType !== 'key'\n ) {\n return\n }\n\n const activeRect = activeRef.current.getBoundingClientRect()\n const containerRect = listBoxRef.current.getBoundingClientRect()\n\n if (activeRect.top < containerRect.top) {\n listBoxRef.current.scrollTop -= containerRect.top - activeRect.top\n } else if (activeRect.bottom > containerRect.bottom) {\n listBoxRef.current.scrollTop += activeRect.bottom - containerRect.bottom\n }\n }, [activeOption, navigationType])\n\n useEnhancedEffect(() => {\n // 閉じたときに activeOption を初期化\n if (!isExpanded) {\n return setActiveOption(null)\n }\n\n functions.calculateRect()\n\n const scrollOption = { capture: true, passive: true }\n window.addEventListener('scroll', functions.calculateRect, scrollOption)\n window.addEventListener('resize', functions.calculateRect, { passive: true })\n\n return () => {\n window.removeEventListener('scroll', functions.calculateRect, scrollOption)\n window.removeEventListener('resize', functions.calculateRect)\n }\n // HINT: optionsが変わる場合メニューのサイズが変わる可能性がある\n }, [isExpanded, options, functions])\n\n return {\n listBoxProps: {\n activeOptionId: activeOption?.id,\n options,\n isExpanded,\n isLoading,\n dropdownHelpMessage,\n noResultText,\n listBoxId,\n listBoxRef,\n handleAdd: functions.handleAdd,\n handleHoverOption: functions.handleHoverOption,\n handleSelect: functions.handleSelect,\n activeRef,\n listBoxRect,\n triggerWidth,\n dropdownWidth,\n },\n activeOption,\n handleKeyDownListBox: functions.handleKeyDownListBox,\n listBoxId,\n listBoxRef,\n }\n}\n\ntype ListBoxProps<T> = {\n activeOptionId: string | undefined\n options: Array<ComboboxOption<T>>\n isExpanded: boolean\n isLoading?: boolean\n noResultText?: ReactNode\n dropdownHelpMessage?: ReactNode\n listBoxId: string\n listBoxRef: RefObject<HTMLDivElement>\n handleAdd: ((option: ComboboxOption<T>) => void) | undefined\n handleHoverOption: (option: ComboboxOption<T>) => void\n handleSelect: (option: ComboboxOption<T>) => void\n activeRef: RefObject<HTMLButtonElement>\n listBoxRect: { top: number; left: number; height?: number }\n triggerWidth: number\n dropdownWidth?: string | number\n}\n\nexport const ListBox = memo(\n <T,>({\n activeOptionId,\n options,\n isExpanded,\n isLoading,\n noResultText,\n dropdownHelpMessage,\n listBoxId,\n listBoxRef,\n handleAdd,\n handleHoverOption,\n handleSelect,\n activeRef,\n listBoxRect,\n triggerWidth,\n dropdownWidth,\n }: ListBoxProps<T>) => {\n const { createPortal } = usePortal()\n const theme = useTheme()\n\n const minLength = useMemo(\n () =>\n (activeOptionId === undefined ? 0 : options.findIndex((o) => o.id === activeOptionId)) + 1,\n [activeOptionId, options],\n )\n const [currentItemLength, setCurrentItemLength] = useState(() =>\n Math.max(OPTION_INCREMENT_AMOUNT, minLength),\n )\n const items = useMemo(() => options.slice(0, currentItemLength), [currentItemLength, options])\n\n const styles = useMemo(() => {\n const { top, left, height } = listBoxRect\n const dropdownListWidth = dropdownWidth || triggerWidth\n\n return {\n wrapper: {\n top: `${top}px`,\n left: `${left}px`,\n width: `${triggerWidth}px`,\n },\n dropdownList: {\n width:\n typeof dropdownListWidth === 'string' ? dropdownListWidth : `${dropdownListWidth}px`,\n /* HINT: left に依存させると、算出した幅がさらに maxWidth を縮めて再計算の度に幅が縮んでいくため、\n ビューポート幅のみから算出する */\n maxWidth: `calc(100vw - ${theme.spacingByChar(0.5)})`,\n height: height ? `${height}px` : undefined,\n },\n }\n }, [listBoxRect, triggerWidth, dropdownWidth, theme])\n\n const latest = useLatest({ handleAdd, handleHoverOption, handleSelect, options, minLength })\n\n const functions = useMemo(() => {\n const resolveOption = (e: MouseEvent) => {\n const el = findDelegateTarget<HTMLButtonElement>(e, 'button[role=\"option\"]')\n if (!el || el.disabled) return null\n return latest.options.find((o) => o.id === el.id) ?? null\n }\n\n return {\n handleDelegateClick: (e: MouseEvent) => {\n const option = resolveOption(e)\n if (option) {\n if (option.isNew) {\n latest.handleAdd?.(option)\n } else {\n latest.handleSelect(option)\n }\n }\n },\n handleDelegateMouseOver: (e: MouseEvent) => {\n const option = resolveOption(e)\n if (option) {\n latest.handleHoverOption(option)\n }\n },\n handleIntersect: () => {\n setCurrentItemLength((current) =>\n Math.max(current + OPTION_INCREMENT_AMOUNT, latest.minLength),\n )\n },\n }\n }, [latest])\n\n useEffect(() => {\n setCurrentItemLength((current) => Math.max(current, minLength))\n }, [minLength])\n\n return createPortal(\n <div className={CLASS_NAMES.wrapper} style={styles.wrapper}>\n {isExpanded && isLoading && (\n <VisuallyHiddenText role=\"status\">\n <Localizer id=\"smarthr-ui/Combobox/loadingText\" defaultText=\"処理中\" />\n </VisuallyHiddenText>\n )}\n <Scroller\n id={listBoxId}\n ref={listBoxRef}\n role=\"listbox\"\n aria-hidden={!isExpanded}\n className={CLASS_NAMES.dropdownList}\n style={styles.dropdownList}\n onMouseOver={functions.handleDelegateMouseOver}\n onClick={functions.handleDelegateClick}\n >\n {dropdownHelpMessage && (\n <Text\n className={CLASS_NAMES.helpMessage}\n icon={<FaCircleInfoIcon color=\"TEXT_GREY\" />}\n as=\"p\"\n >\n {dropdownHelpMessage}\n </Text>\n )}\n {isExpanded ? (\n isLoading ? (\n <div className={CLASS_NAMES.loaderWrapper}>\n <Loader aria-hidden />\n </div>\n ) : options.length === 0 ? (\n <p role=\"alert\" aria-live=\"polite\" className={CLASS_NAMES.noItems}>\n {noResultText ?? (\n <Localizer\n id=\"smarthr-ui/Combobox/noResultsText\"\n defaultText=\"一致する選択肢がありません。\"\n />\n )}\n </p>\n ) : (\n items.map(({ item: { label, disabled }, id, ...optionRest }) => (\n <ItemButton\n {...optionRest}\n label={label}\n disabled={disabled}\n key={id}\n id={id}\n activeRef={id === activeOptionId ? activeRef : undefined}\n />\n ))\n )\n ) : null}\n {currentItemLength < options.length && (\n <Intersection handleIntersect={functions.handleIntersect} />\n )}\n </Scroller>\n </div>,\n )\n },\n) as <T>(props: ListBoxProps<T>) => ReactNode\n\nconst Intersection = memo<{ handleIntersect: () => void }>(({ handleIntersect }) => {\n const ref = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const target = ref.current\n\n if (target === null) {\n return\n }\n\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) {\n handleIntersect()\n }\n })\n\n observer.observe(target)\n\n return () => observer.disconnect()\n }, [handleIntersect])\n\n return <div ref={ref} />\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAmDA;AACA;AAEA;AAEA;AACE;AACE;AACA;;;AAGE;AAC0D;;;AAG3D;AACD;AAEA;AACA;AACD;AACF;AAED;AACE;;;;;;;;AASF;AAEO;AAWL;;;AAIA;AACE;AACA;AACD;;;AAID;AACA;AAEA;AAEA;AACA;AAEA;AACE;AACE;;;AAIA;;;;AAMA;AACE;;AACK;;;;;AAOL;AACE;;;;;;AAKN;;;AAII;;;;;AAKA;;;;;AAUA;;AAEE;;AACK;;AAEL;;AACK;;AAEL;;;;;AAIA;;;;;;AAOF;;;;AAIA;;AAGA;AAEA;;AAEE;;AACK;;AAEL;;AAGF;;;;AAIC;AACD;;AAEF;;;;AAKI;;;;;;AAIK;AACL;;;;AAMA;;;AAEO;;;;;;;;AAOX;AACE;;;;;AAKI;;AAEJ;AACF;AACE;;AAEF;;;;;AAKJ;;;AAIE;AACE;AACE;;AAGF;AACF;AACF;;;;;AAOI;;;;;;;AAUA;;;AAEA;;AAEJ;;;;AAKI;;;;;AAOF;AAEA;;;AAGA;;;;AAKA;;;;;;;;;;;;;;;;AAgBC;;;;;;AAML;AAoBO;AAkBH;AACA;AAEA;;;AAUA;;AAEE;;AAGE;;;;AAIC;AACD;AACE;AAEA;AACkB;;;AAGnB;;;AAIL;AAEA;AACE;;AAEE;AAAwB;;AAE1B;;AAGE;AACE;;AAEE;AACE;;;AAEA;;;;AAIN;AACE;;AAEE;;;;AAIF;;;AAKN;;AAGE;AACF;AAEA;AA2DF;AAGF;AACE;;AAGE;AAEA;;;;AAKE;AACE;;AAEJ;AAEA;AAEA;AACF;AAEA;AACF;;"}
|
|
1
|
+
{"version":3,"file":"useListbox.js","sources":["../../../src/components/Combobox/useListbox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n memo,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useAnimationFrame } from '../../hooks/useAnimationFrame'\nimport { useEnhancedEffect } from '../../hooks/useEnhancedEffect'\nimport { useLatest } from '../../hooks/useLatest'\nimport { usePortal } from '../../hooks/usePortal'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Localizer } from '../../intl'\nimport { findDelegateTarget } from '../../libs/delegate'\nimport { FaCircleInfoIcon } from '../Icon'\nimport { Loader } from '../Loader'\nimport { Scroller } from '../Scroller'\nimport { Text } from '../Text'\nimport { VisuallyHiddenText } from '../VisuallyHiddenText'\n\nimport { ItemButton } from './ItemButton'\n\nimport type { ComboboxItem, ComboboxOption } from './types'\n\ntype Props<T> = {\n options: Array<ComboboxOption<T>>\n dropdownHelpMessage?: ReactNode\n dropdownWidth?: string | number\n onAdd?: (label: string) => void\n onSelect: (item: ComboboxItem<T>) => void\n isExpanded: boolean\n isLoading?: boolean\n triggerRef: RefObject<HTMLElement>\n /** 検索結果が0件の時に表示するコンテンツ */\n noResultText?: ReactNode\n}\n\ntype Rect = {\n top: number\n left: number\n height?: number\n}\n\nconst KEY_DOWN_REGEX = /^(Arrow)?Down$/\nconst KEY_UP_REGEX = /^(Arrow)?Up/\n\nconst OPTION_INCREMENT_AMOUNT = 100\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'shr-absolute',\n dropdownList: [\n 'smarthr-ui-Combobox-dropdownList',\n 'shr-absolute shr-z-overlap shr-box-border shr-min-w-full shr-rounded-m shr-bg-white shr-py-0.5 shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',\n /* 縦スクロールに気づきやすくするために8個目のアイテムが半分見切れるように max-height を算出\n = (アイテムのフォントサイズ + アイテムの上下padding) * 7.5 + コンテナの上padding */\n 'shr-max-h-[calc((theme(fontSize.base)_+_theme(spacing[0.5])_*_2)_*_7.5_+_theme(spacing[0.5]))]',\n 'aria-hidden:shr-hidden',\n ],\n helpMessage:\n 'shr-whitespace-[initial] shr-border-b-shorthand shr-mx-0.5 shr-mb-0.5 shr-mt-0 shr-px-0.5 shr-pb-0.5 shr-pt-0 shr-text-sm',\n loaderWrapper: 'shr-flex shr-items-center shr-justify-center shr-p-1',\n noItems: 'smarthr-ui-Combobox-noItems shr-my-0 shr-bg-white shr-px-1 shr-py-0.5 shr-text-base',\n },\n})\n\nconst CLASS_NAMES = (() => {\n const { wrapper, dropdownList, helpMessage, loaderWrapper, noItems } = classNameGenerator()\n\n return {\n wrapper: wrapper(),\n dropdownList: dropdownList(),\n helpMessage: helpMessage(),\n loaderWrapper: loaderWrapper(),\n noItems: noItems(),\n }\n})()\n\nexport const useListbox = <T,>({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect,\n isExpanded,\n isLoading,\n triggerRef,\n noResultText,\n}: Props<T>) => {\n const listBoxId = useId()\n\n const [navigationType, setNavigationType] = useState<'pointer' | 'key'>('pointer')\n const [activeOption, setActiveOption] = useState<ComboboxOption<T> | null>(null)\n const [listBoxRect, setListBoxRect] = useState<Rect>({\n top: 0,\n left: 0,\n })\n // HINT: calculateRectで同時に計算するとwidthの幅が変更されるタイミングの問題でlistBoxHeightが変化する場合がある\n const [triggerWidth, setTriggerWidth] = useState(0)\n\n const listBoxRef = useRef<HTMLDivElement>(null)\n const activeRef = useRef<HTMLButtonElement>(null)\n\n const theme = useTheme()\n\n const addFrame = useAnimationFrame()\n\n const latest = useLatest({ onAdd, onSelect, activeOption, options, triggerRef, theme, addFrame })\n const hasOnAdd = !!onAdd\n\n const functions = useMemo(() => {\n const moveActiveOptionIndex = (currentActive: ComboboxOption<T> | null, delta: -1 | 1) => {\n if (latest.options.every((option) => option.item.disabled)) {\n return\n }\n\n const currentActiveIndex =\n currentActive === null\n ? -1\n : latest.options.findIndex((option) => option.id === currentActive.id)\n let nextIndex = 0\n\n if (currentActiveIndex !== -1) {\n nextIndex = (currentActiveIndex + delta + latest.options.length) % latest.options.length\n } else if (delta !== 1) {\n nextIndex = latest.options.length - 1\n }\n\n const nextActive = latest.options[nextIndex]\n\n if (nextActive) {\n if (nextActive.item.disabled) {\n moveActiveOptionIndex(nextActive, delta)\n } else {\n setActiveOption(nextActive)\n }\n }\n }\n\n return {\n calculateRect: () => {\n if (!listBoxRef.current || !latest.triggerRef.current) {\n return\n }\n const rect = latest.triggerRef.current.getBoundingClientRect()\n const bottomSpace = window.innerHeight - rect.bottom\n const topSpace = rect.top\n const listBoxHeight = Math.min(\n listBoxRef.current.scrollHeight,\n parseInt(getComputedStyle(listBoxRef.current).maxHeight, 10),\n )\n const offset = 2\n\n let top = 0\n let height: number | undefined = undefined\n\n if (bottomSpace >= listBoxHeight) {\n // 下側に十分なスペースがある場合は下側に通常表示\n top = rect.top + rect.height - offset + window.pageYOffset\n } else if (topSpace >= listBoxHeight) {\n // 上側に十分なスペースがある場合は上側に通常表示\n top = rect.top - listBoxHeight + offset + window.pageYOffset\n } else if (topSpace > bottomSpace) {\n // 上下に十分なスペースがなく、上側の方がスペースが大きい場合は上側に縮めて表示\n top = rect.top - topSpace + offset + window.pageYOffset\n height = topSpace\n } else {\n // 下側に縮めて表示\n top = rect.top + rect.height - offset + window.pageYOffset\n height = bottomSpace\n }\n\n // HINT: dropdownWidth は 'auto' や '%' などの CSS 値を取りうるため、算出済みの幅を実測して判定する\n const listBoxWidth = listBoxRef.current.getBoundingClientRect().width\n // ドロップダウンの幅は maxWidth でビューポート右端から余白分を残すよう制限しているため、位置の判定にも同じ余白を使う\n const viewportMargin = parseInt(latest.theme.spacingByChar(0.5), 10)\n // 入力欄の左端を起点に右方向へ表示する場合に使える幅\n const rightSpace = window.innerWidth - rect.left - viewportMargin\n // 入力欄の右端を起点に左方向へ表示する場合に使える幅\n const leftSpace = rect.right\n\n // ビューポートの左端を基準に計算\n let left = window.pageXOffset\n\n if (listBoxWidth <= rightSpace) {\n // 右側に十分なスペースがある場合は入力欄の左端に揃えて通常表示\n left += rect.left\n } else if (listBoxWidth <= leftSpace) {\n // 左側に収まる場合は入力欄の右端に揃えて表示\n left += rect.right - listBoxWidth\n }\n\n setListBoxRect({\n top,\n left,\n height,\n })\n setTriggerWidth(rect.width)\n },\n handleKeyDownListBox: (e: KeyboardEvent<HTMLElement>) => {\n setNavigationType('key')\n\n if (KEY_DOWN_REGEX.test(e.key)) {\n e.stopPropagation()\n moveActiveOptionIndex(latest.activeOption, 1)\n } else if (KEY_UP_REGEX.test(e.key)) {\n e.stopPropagation()\n moveActiveOptionIndex(latest.activeOption, -1)\n } else if (e.key === 'Enter') {\n if (latest.activeOption === null) {\n return\n }\n\n e.stopPropagation()\n\n if (!latest.activeOption.isNew) {\n latest.onSelect(latest.activeOption.item)\n } else if (latest.onAdd) {\n latest.onAdd(latest.activeOption.item.value)\n }\n } else {\n setActiveOption(null)\n }\n },\n handleAdd: hasOnAdd\n ? (option: ComboboxOption<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // 処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n latest.addFrame.request(() => {\n latest.onAdd!(option.item.value)\n })\n }\n : undefined,\n handleSelect: (option: ComboboxOption<T>) => {\n latest.onSelect(option.item)\n },\n handleHoverOption: (option: ComboboxOption<T>) => {\n setNavigationType('pointer')\n setActiveOption(option)\n },\n }\n }, [hasOnAdd, latest])\n\n // TODO: callbackRefにまとめ直したい\n useEffect(() => addFrame.cancel, [addFrame.cancel])\n\n useEffect(() => {\n // props の変更によって activeOption の状態が変わりうるので、実態を反映する\n setActiveOption((current) => {\n if (current === null) {\n return null\n }\n\n return options.find((option) => current.id === option.id) ?? null\n })\n }, [options])\n\n useEffect(() => {\n // actionOption の要素が表示される位置までリストボックス内をスクロールさせる\n if (\n !activeRef.current ||\n !listBoxRef.current ||\n activeOption === null ||\n navigationType !== 'key'\n ) {\n return\n }\n\n const activeRect = activeRef.current.getBoundingClientRect()\n const containerRect = listBoxRef.current.getBoundingClientRect()\n\n if (activeRect.top < containerRect.top) {\n listBoxRef.current.scrollTop -= containerRect.top - activeRect.top\n } else if (activeRect.bottom > containerRect.bottom) {\n listBoxRef.current.scrollTop += activeRect.bottom - containerRect.bottom\n }\n }, [activeOption, navigationType])\n\n useEnhancedEffect(() => {\n // 閉じたときに activeOption を初期化\n if (!isExpanded) {\n return setActiveOption(null)\n }\n\n functions.calculateRect()\n\n const scrollOption = { capture: true, passive: true }\n window.addEventListener('scroll', functions.calculateRect, scrollOption)\n window.addEventListener('resize', functions.calculateRect, { passive: true })\n\n return () => {\n window.removeEventListener('scroll', functions.calculateRect, scrollOption)\n window.removeEventListener('resize', functions.calculateRect)\n }\n // HINT: optionsが変わる場合メニューのサイズが変わる可能性がある\n }, [isExpanded, options, functions])\n\n return {\n listBoxProps: {\n activeOptionId: activeOption?.id,\n options,\n isExpanded,\n isLoading,\n dropdownHelpMessage,\n noResultText,\n listBoxId,\n listBoxRef,\n handleAdd: functions.handleAdd,\n handleHoverOption: functions.handleHoverOption,\n handleSelect: functions.handleSelect,\n activeRef,\n listBoxRect,\n triggerWidth,\n dropdownWidth,\n },\n activeOption,\n handleKeyDownListBox: functions.handleKeyDownListBox,\n listBoxId,\n listBoxRef,\n }\n}\n\ntype ListBoxProps<T> = {\n activeOptionId: string | undefined\n options: Array<ComboboxOption<T>>\n isExpanded: boolean\n isLoading?: boolean\n noResultText?: ReactNode\n dropdownHelpMessage?: ReactNode\n listBoxId: string\n listBoxRef: RefObject<HTMLDivElement>\n handleAdd: ((option: ComboboxOption<T>) => void) | undefined\n handleHoverOption: (option: ComboboxOption<T>) => void\n handleSelect: (option: ComboboxOption<T>) => void\n activeRef: RefObject<HTMLButtonElement>\n listBoxRect: { top: number; left: number; height?: number }\n triggerWidth: number\n dropdownWidth?: string | number\n}\n\nexport const ListBox = memo(\n <T,>({\n activeOptionId,\n options,\n isExpanded,\n isLoading,\n noResultText,\n dropdownHelpMessage,\n listBoxId,\n listBoxRef,\n handleAdd,\n handleHoverOption,\n handleSelect,\n activeRef,\n listBoxRect,\n triggerWidth,\n dropdownWidth,\n }: ListBoxProps<T>) => {\n const { createPortal } = usePortal()\n const theme = useTheme()\n\n const minLength = useMemo(\n () =>\n (activeOptionId === undefined ? 0 : options.findIndex((o) => o.id === activeOptionId)) + 1,\n [activeOptionId, options],\n )\n const [currentItemLength, setCurrentItemLength] = useState(() =>\n Math.max(OPTION_INCREMENT_AMOUNT, minLength),\n )\n const items = useMemo(() => options.slice(0, currentItemLength), [currentItemLength, options])\n\n const styles = useMemo(() => {\n const { top, left, height } = listBoxRect\n const dropdownListWidth = dropdownWidth || triggerWidth\n\n return {\n wrapper: {\n top: `${top}px`,\n left: `${left}px`,\n width: `${triggerWidth}px`,\n },\n dropdownList: {\n width:\n typeof dropdownListWidth === 'string' ? dropdownListWidth : `${dropdownListWidth}px`,\n /* HINT: left に依存させると、算出した幅がさらに maxWidth を縮めて再計算の度に幅が縮んでいくため、\n ビューポート幅のみから算出する */\n maxWidth: `calc(100vw - ${theme.spacingByChar(0.5)})`,\n height: height ? `${height}px` : undefined,\n },\n }\n }, [listBoxRect, triggerWidth, dropdownWidth, theme])\n\n const latest = useLatest({ handleAdd, handleHoverOption, handleSelect, options, minLength })\n\n const functions = useMemo(() => {\n const resolveOption = (e: MouseEvent) => {\n const el = findDelegateTarget<HTMLButtonElement>(e, 'button[role=\"option\"]')\n if (!el || el.disabled) return null\n return latest.options.find((o) => o.id === el.id) ?? null\n }\n\n return {\n handleDelegateClick: (e: MouseEvent) => {\n const option = resolveOption(e)\n if (option) {\n if (option.isNew) {\n latest.handleAdd?.(option)\n } else {\n latest.handleSelect(option)\n }\n }\n },\n handleDelegateMouseOver: (e: MouseEvent) => {\n const option = resolveOption(e)\n if (option) {\n latest.handleHoverOption(option)\n }\n },\n handleIntersect: () => {\n setCurrentItemLength((current) =>\n Math.max(current + OPTION_INCREMENT_AMOUNT, latest.minLength),\n )\n },\n }\n }, [latest])\n\n useEffect(() => {\n setCurrentItemLength((current) => Math.max(current, minLength))\n }, [minLength])\n\n return createPortal(\n <div className={CLASS_NAMES.wrapper} style={styles.wrapper}>\n {isExpanded && isLoading && (\n <VisuallyHiddenText role=\"status\">\n <Localizer id=\"smarthr-ui/Combobox/loadingText\" defaultText=\"処理中\" />\n </VisuallyHiddenText>\n )}\n <Scroller\n id={listBoxId}\n ref={listBoxRef}\n role=\"listbox\"\n aria-hidden={!isExpanded}\n className={CLASS_NAMES.dropdownList}\n style={styles.dropdownList}\n onMouseOver={functions.handleDelegateMouseOver}\n onClick={functions.handleDelegateClick}\n >\n {dropdownHelpMessage && (\n <Text\n className={CLASS_NAMES.helpMessage}\n icon={<FaCircleInfoIcon color=\"TEXT_GREY\" />}\n as=\"p\"\n >\n {dropdownHelpMessage}\n </Text>\n )}\n {isExpanded ? (\n isLoading ? (\n <div className={CLASS_NAMES.loaderWrapper}>\n <Loader aria-hidden />\n </div>\n ) : options.length === 0 ? (\n <p role=\"alert\" aria-live=\"polite\" className={CLASS_NAMES.noItems}>\n {noResultText ?? (\n <Localizer\n id=\"smarthr-ui/Combobox/noResultsText\"\n defaultText=\"一致する選択肢がありません。\"\n />\n )}\n </p>\n ) : (\n items.map(({ item: { label, disabled }, id, ...optionRest }) => (\n <ItemButton\n {...optionRest}\n label={label}\n disabled={disabled}\n key={id}\n id={id}\n activeRef={id === activeOptionId ? activeRef : undefined}\n />\n ))\n )\n ) : null}\n {currentItemLength < options.length && (\n <Intersection handleIntersect={functions.handleIntersect} />\n )}\n </Scroller>\n </div>,\n )\n },\n) as <T>(props: ListBoxProps<T>) => ReactNode\n\nconst Intersection = memo<{ handleIntersect: () => void }>(({ handleIntersect }) => {\n const ref = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const target = ref.current\n\n if (target === null) {\n return\n }\n\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) {\n handleIntersect()\n }\n })\n\n observer.observe(target)\n\n return () => observer.disconnect()\n }, [handleIntersect])\n\n return <div ref={ref} />\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAoDA;AACA;AAEA;AAEA;AACE;AACE;AACA;;;AAGE;AAC0D;;;AAG3D;AACD;AAEA;AACA;AACD;AACF;AAED;AACE;;;;;;;;AASF;AAEO;AAWL;;;AAIA;AACE;AACA;AACD;;;AAID;AACA;AAEA;AAEA;;AAGA;AAEA;AACE;AACE;;;AAIA;;;;AAMA;AACE;;AACK;;;;;AAOL;AACE;;;;;;AAKN;;;AAII;;;;;AAKA;;;;;AAUA;;AAEE;;AACK;;AAEL;;AACK;;AAEL;;;;;AAIA;;;;;;AAOF;;;;AAIA;;AAGA;AAEA;;AAEE;;AACK;;AAEL;;AAGF;;;;AAIC;AACD;;AAEF;;;;AAKI;;;;;;AAIK;AACL;;;;AAMA;;;AAEO;;;;;;;;AAOX;AACE;;;AAGI;;AAEA;;AAEJ;AACF;AACE;;AAEF;;;;;AAKJ;;AAGA;;;AAIE;AACE;AACE;;AAGF;AACF;AACF;;;;;AAOI;;;;;;;AAUA;;;AAEA;;AAEJ;;;;AAKI;;;;;AAOF;AAEA;;;AAGA;;;;AAKA;;;;;;;;;;;;;;;;AAgBC;;;;;;AAML;AAoBO;AAkBH;AACA;AAEA;;;AAUA;;AAEE;;AAGE;;;;AAIC;AACD;AACE;AAEA;AACkB;;;AAGnB;;;AAIL;AAEA;AACE;;AAEE;AAAwB;;AAE1B;;AAGE;AACE;;AAEE;AACE;;;AAEA;;;;AAIN;AACE;;AAEE;;;;AAIF;;;AAKN;;AAGE;AACF;AAEA;AA2DF;AAGF;AACE;;AAGE;AAEA;;;;AAKE;AACE;;AAEJ;AAEA;AAEA;AACF;AAEA;AACF;;"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var dayjs_min = require('../../_virtual/dayjs.min.cjs');
|
|
6
6
|
var React = require('react');
|
|
7
|
-
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@
|
|
7
|
+
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
|
|
8
|
+
var hooks_useAnimationFrame = require('../../hooks/useAnimationFrame.cjs');
|
|
8
9
|
var hooks_useLatest = require('../../hooks/useLatest.cjs');
|
|
9
10
|
var hooks_useOuterClick = require('../../hooks/useOuterClick.cjs');
|
|
10
11
|
var hooks_useTheme = require('../../hooks/useTheme.cjs');
|
|
@@ -56,6 +57,7 @@ const DatePicker = React.forwardRef(({ value, name, from = DEFAULT_FROM, to, dis
|
|
|
56
57
|
const [alternativeFormat, setAlternativeFormat] = React.useState(null);
|
|
57
58
|
const calenderId = React.useId();
|
|
58
59
|
const [selectedDate, setSelectedDate] = React.useState(() => parseStringDate(value, parseInput));
|
|
60
|
+
const closeFrame = hooks_useAnimationFrame.useAnimationFrame();
|
|
59
61
|
const latest = hooks_useLatest.useLatest({
|
|
60
62
|
onChange,
|
|
61
63
|
onChangeDate,
|
|
@@ -65,6 +67,7 @@ const DatePicker = React.forwardRef(({ value, name, from = DEFAULT_FROM, to, dis
|
|
|
65
67
|
onBlur,
|
|
66
68
|
isInputFocused,
|
|
67
69
|
selectedDate,
|
|
70
|
+
closeFrame,
|
|
68
71
|
});
|
|
69
72
|
const functions = React.useMemo(() => {
|
|
70
73
|
const dateToString = (date) => latest.formatDate ? latest.formatDate(date) : DEFAULT_DATE_TO_STRING(date);
|
|
@@ -136,7 +139,7 @@ const DatePicker = React.forwardRef(({ value, name, from = DEFAULT_FROM, to, dis
|
|
|
136
139
|
if (ESCAPE_KEY_REGEX.test(e.key)) {
|
|
137
140
|
e.stopPropagation();
|
|
138
141
|
// delay hiding calendar because calendar will be displayed when input is focused
|
|
139
|
-
|
|
142
|
+
latest.closeFrame.request(closeCalendar);
|
|
140
143
|
if (inputRef.current)
|
|
141
144
|
inputRef.current.focus();
|
|
142
145
|
}
|
|
@@ -155,7 +158,7 @@ const DatePicker = React.forwardRef(({ value, name, from = DEFAULT_FROM, to, dis
|
|
|
155
158
|
handleSelectDateCalendar: (e, selected) => {
|
|
156
159
|
updateDate(e, selected);
|
|
157
160
|
// delay hiding calendar because calendar will be displayed when input is focused
|
|
158
|
-
|
|
161
|
+
latest.closeFrame.request(closeCalendar);
|
|
159
162
|
if (inputRef.current)
|
|
160
163
|
inputRef.current.focus();
|
|
161
164
|
},
|
|
@@ -223,6 +226,7 @@ const DatePicker = React.forwardRef(({ value, name, from = DEFAULT_FROM, to, dis
|
|
|
223
226
|
window.addEventListener('keydown', handleKeyDown);
|
|
224
227
|
return () => {
|
|
225
228
|
window.removeEventListener('keydown', handleKeyDown);
|
|
229
|
+
latest.closeFrame.cancel();
|
|
226
230
|
};
|
|
227
231
|
}, [functions, latest]);
|
|
228
232
|
const caretIconColor = isInputFocused || isCalendarShown
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.cjs","sources":["../../../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["'use client'\n\nimport dayjs from 'dayjs'\nimport {\n type ChangeEvent,\n type ComponentProps,\n type ComponentPropsWithRef,\n type MouseEvent,\n type ReactNode,\n forwardRef,\n memo,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useOuterClick } from '../../hooks/useOuterClick'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Calendar } from '../Calendar'\nimport { FaCalendarDaysIcon } from '../Icon'\nimport { Input } from '../Input'\n\nimport { Portal } from './Portal'\nimport { parseJpnDateString } from './datePickerHelper'\n\ntype ChangeLikeEvent = ChangeEvent | React.KeyboardEvent | MouseEvent\ntype BaseProps = {\n /** input 要素の `value` 属性の値 */\n value?: string | null\n /** input 要素の `name` 属性の値 */\n name?: string\n /** 選択可能な期間の開始日 */\n from?: Date\n /** 選択可能な期間の終了日 */\n to?: Date\n /** フォームを無効にするかどうか */\n disabled?: boolean\n /**\n * placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** 入力を独自にパースする場合に、パース処理を記述する関数 */\n parseInput?: (input: string) => Date | null\n /** 表示する日付を独自にフォーマットする場合に、フォーマット処理を記述する関数 */\n formatDate?: (date: Date | null) => string\n /** 入出力用文字列と併記する別フォーマット処理を記述する関数 */\n showAlternative?: (date: Date | null) => ReactNode\n /** @deprecated onChangeDate は非推奨です。onChange を使ってください。 */\n onChangeDate?: (date: Date | null, value: string, other: { errors: string[] }) => void\n /** 選択された日付が変わった時に発火するコールバック関数 */\n onChange?: (\n e: ChangeEvent<HTMLInputElement>,\n other: { date: Date | null; formatValue: string; errors: string[] },\n ) => void\n}\ntype Props = BaseProps &\n Omit<\n ComponentPropsWithRef<'input'>,\n | keyof BaseProps\n | 'type'\n | 'onChange'\n | 'onKeyPress'\n | 'onFocus'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-haspopup'\n >\n\nexport const DEFAULT_FROM = new Date(1900, 0, 1)\n\nconst classNameGenerator = tv({\n slots: {\n container: 'smarthr-ui-DatePicker shr-inline-block',\n inputSuffixLayout: 'shr-box-border shr-h-full shr-py-0.5',\n inputSuffixWrapper:\n 'shr-border-l-shorthand shr-box-border shr-flex shr-h-full shr-items-center shr-justify-center shr-ps-0.5 shr-text-base',\n inputSuffixText: 'shr-text-gray shr-me-0.5 shr-text-sm',\n },\n})\n\nconst DEFAULT_DATE_TO_STRING_FORMAT = 'YYYY/MM/DD'\nconst DEFAULT_DATE_TO_STRING = (d: Date | null) =>\n d ? dayjs(d).format(DEFAULT_DATE_TO_STRING_FORMAT) : ''\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\n\nconst parseStringDate = (\n str: string | null | undefined,\n parseInputFn: ((input: string) => Date | null) | undefined,\n) => {\n if (!str) return null\n return parseInputFn ? parseInputFn(str) : parseJpnDateString(str)\n}\n\n/** @deprecated DatePicker は非推奨です。Input[type=date] を使ってください。 */\nexport const DatePicker = forwardRef<HTMLInputElement, Props>(\n (\n {\n value,\n name,\n from = DEFAULT_FROM,\n to,\n disabled,\n width,\n error,\n className,\n parseInput,\n formatDate,\n showAlternative,\n onChangeDate,\n onChange,\n onBlur,\n ...rest\n },\n ref,\n ) => {\n const theme = useTheme()\n const classNames = useMemo(() => {\n const { container, inputSuffixLayout, inputSuffixWrapper, inputSuffixText } =\n classNameGenerator()\n\n return {\n container: container({ className }),\n inputSuffixLayout: inputSuffixLayout(),\n inputSuffixWrapper: inputSuffixWrapper(),\n inputSuffixText: inputSuffixText(),\n }\n }, [className])\n\n const [isInputFocused, setIsInputFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const inputWrapperRef = useRef<HTMLDivElement>(null)\n const calendarPortalRef = useRef<HTMLDivElement>(null)\n const [inputRect, setInputRect] = useState<DOMRect | null>(null)\n const [isCalendarShown, setIsCalendarShown] = useState(false)\n const [alternativeFormat, setAlternativeFormat] = useState<null | ReactNode>(null)\n const calenderId = useId()\n\n const [selectedDate, setSelectedDate] = useState<Date | null>(() =>\n parseStringDate(value, parseInput),\n )\n\n const latest = useLatest({\n onChange,\n onChangeDate,\n parseInput,\n formatDate,\n showAlternative,\n onBlur,\n isInputFocused,\n selectedDate,\n })\n\n const functions = useMemo(() => {\n const dateToString = (date: Date | null) =>\n latest.formatDate ? latest.formatDate(date) : DEFAULT_DATE_TO_STRING(date)\n\n const dateToAlternativeFormat = (d: Date | null) => {\n if (!latest.showAlternative) return null\n return d ? latest.showAlternative(d) : null\n }\n\n const stringToDate = (str: string | null | undefined) =>\n parseStringDate(str, latest.parseInput)\n\n const updateDate = (e: ChangeLikeEvent, newDate: Date | null) => {\n if (\n !inputRef.current ||\n newDate === latest.selectedDate ||\n (newDate && latest.selectedDate && newDate.getTime() === latest.selectedDate.getTime())\n ) {\n // Do not update date if the new date is same with the old one.\n return\n }\n\n const isValid = !newDate || dayjs(newDate).isValid()\n const errors: string[] = []\n\n if (!isValid) {\n errors.push('INVALID_DATE')\n }\n\n const nextDate = isValid ? newDate : null\n const formatValue = dateToString(nextDate)\n\n inputRef.current.value = formatValue\n setAlternativeFormat(dateToAlternativeFormat(nextDate))\n setSelectedDate(nextDate)\n\n if (latest.onChange) {\n e.preventDefault()\n e.stopPropagation()\n\n const event = new Event('change', { bubbles: true })\n const input = inputRef.current\n\n input.dispatchEvent(event)\n latest.onChange(\n // HINT: 型問題のため別途オブジェクトをイベントに見立てる\n {\n stopPropagation: () => {\n event.stopPropagation()\n },\n preventDefault: () => {\n event.preventDefault()\n },\n target: input,\n currentTarget: input,\n } as ChangeEvent<HTMLInputElement>,\n { date: nextDate, formatValue, errors },\n )\n } else if (latest.onChangeDate) {\n latest.onChangeDate(nextDate, formatValue, { errors })\n }\n }\n\n const closeCalendar = () => setIsCalendarShown(false)\n\n const openCalendar = () => {\n if (inputWrapperRef.current) {\n setIsCalendarShown(true)\n setInputRect(inputWrapperRef.current.getBoundingClientRect())\n }\n }\n\n return {\n stringToDate,\n dateToString,\n dateToAlternativeFormat,\n closeCalendar,\n openCalendar,\n handleBlur: (e: React.FocusEvent<HTMLInputElement>) => {\n setIsInputFocused(false)\n updateDate(e, e.target.value ? stringToDate(e.target.value) : null)\n latest.onBlur?.(e)\n },\n handleDelegateKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n // delay hiding calendar because calendar will be displayed when input is focused\n requestAnimationFrame(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n }\n },\n handleKeyPressInput: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n const isExpanded = e.currentTarget.getAttribute('aria-expanded') === 'true'\n ;(isExpanded ? closeCalendar : openCalendar)()\n updateDate(e, stringToDate(e.currentTarget.value))\n }\n },\n handleFocusInput: () => {\n setIsInputFocused(true)\n openCalendar()\n },\n handleSelectDateCalendar: (e: ChangeLikeEvent, selected: Date | null) => {\n updateDate(e, selected)\n // delay hiding calendar because calendar will be displayed when input is focused\n requestAnimationFrame(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n },\n }\n }, [latest])\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => inputRef.current,\n [],\n )\n\n useEffect(() => {\n if (value === undefined || !inputRef.current) {\n return\n }\n\n /**\n * Do not format the given value in the following cases\n * - while input element is focused.\n * - if the given value is not date formattable.\n */\n if (!isInputFocused) {\n const newDate = functions.stringToDate(value)\n\n if (newDate && dayjs(newDate).isValid()) {\n inputRef.current.value = functions.dateToString(newDate)\n setAlternativeFormat(functions.dateToAlternativeFormat(newDate))\n setSelectedDate(newDate)\n\n return\n }\n\n setSelectedDate(null)\n }\n\n inputRef.current.value = value || ''\n }, [value, isInputFocused, functions])\n\n useOuterClick([inputWrapperRef, calendarPortalRef], functions.closeCalendar)\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!inputRef.current || !calendarPortalRef.current || e.key !== 'Tab') {\n return\n }\n\n const calendarButtons = calendarPortalRef.current.querySelectorAll('button')\n\n if (calendarButtons.length === 0) {\n return\n }\n\n const firstCalendarButton = calendarButtons[0]\n\n if (latest.isInputFocused) {\n if (e.shiftKey) {\n // move focus from Input to previous elements of DatePicker\n functions.closeCalendar()\n\n return\n }\n\n // move focus from Input to Calendar\n e.preventDefault()\n firstCalendarButton.focus()\n\n return\n }\n\n const calendarButtonAry = Array.from(calendarButtons)\n const currentFocused = calendarButtonAry.find((button) => button === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstCalendarButton) {\n // move focus from Calendar to Input\n inputRef.current.focus()\n e.preventDefault()\n }\n } else if (currentFocused === calendarButtonAry.at(-1)) {\n // move focus from Calendar to next elements of DatePicker\n inputRef.current.focus()\n functions.closeCalendar()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [functions, latest])\n\n const caretIconColor =\n isInputFocused || isCalendarShown\n ? theme.textColor.black\n : disabled\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n return (\n // eslint-disable-next-line smarthr/best-practice-for-interactive-element\n <div\n onClick={!isCalendarShown && !disabled ? functions.openCalendar : undefined}\n onKeyDown={isCalendarShown ? functions.handleDelegateKeyDown : undefined}\n role=\"presentation\"\n className={classNames.container}\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n }}\n >\n <div ref={inputWrapperRef}>\n <Input\n {...rest}\n data-smarthr-ui-input=\"true\"\n width=\"100%\"\n name={name}\n onChange={isCalendarShown ? functions.closeCalendar : undefined}\n onKeyPress={functions.handleKeyPressInput}\n onFocus={functions.handleFocusInput}\n onBlur={functions.handleBlur}\n suffix={\n <InputSuffixIcon\n alternativeFormat={showAlternative ? alternativeFormat : null}\n caretIconColor={caretIconColor}\n classNames={classNames}\n />\n }\n disabled={disabled}\n error={error}\n ref={inputRef}\n className=\"smarthr-ui-DatePicker-inputContainer\"\n aria-expanded={isCalendarShown}\n aria-controls={calenderId}\n aria-haspopup={true}\n />\n </div>\n {isCalendarShown && inputRect && (\n <Portal inputRect={inputRect} ref={calendarPortalRef}>\n <Calendar\n id={calenderId}\n value={selectedDate || undefined}\n from={from}\n to={to}\n onSelectDate={functions.handleSelectDateCalendar}\n />\n </Portal>\n )}\n </div>\n )\n },\n)\n\nconst InputSuffixIcon = memo<{\n classNames: { inputSuffixLayout: string; inputSuffixWrapper: string; inputSuffixText: string }\n alternativeFormat: null | ReactNode\n caretIconColor: ComponentProps<typeof FaCalendarDaysIcon>['color']\n}>(({ classNames, alternativeFormat, caretIconColor }) => (\n <span className={classNames.inputSuffixLayout}>\n <span className={classNames.inputSuffixWrapper}>\n {alternativeFormat && <span className={classNames.inputSuffixText}>{alternativeFormat}</span>}\n <FaCalendarDaysIcon color={caretIconColor} />\n </span>\n </span>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA6EO;AAEP;AACE;AACE;AACA;AACA;AAEA;AACD;AACF;AAED;AACA;AAEA;AAEA;AAIE;AAAU;AACV;AACF;AAEA;;AAsBI;AACA;AACE;;AAIE;;;;;AAKJ;;AAGA;AACA;AACA;;;;AAIA;AAEA;;;;;;;;;;AAaC;AAED;;AAIE;;AAC+B;AAC7B;AACF;AAEA;AAGA;;;AAII;;;;AAMF;;;AAIE;;;AAIF;AAEA;AACA;;AAGA;;;AAIE;AACA;AAEA;AACA;;AAEE;;;;;;;AAOE;AACA;;;AAIC;;;AAGT;;;AAKE;;;;AAIF;;;;;;;AAQE;;;AAGE;;AAEF;;;;;;AAM0B;;;AAG1B;AACE;AACE;;AAEA;;;;;AAKF;;AAEF;AACE;;;;AAIsB;;;AAG5B;AAEA;;;;;AAWE;;;;AAIG;;;;;;;;;;;;;;;AAqBH;AACE;;;;AAMA;;;AAIA;AAEA;AACE;;;;;;;;;;;AAeF;AAEA;AACE;;AAEE;;;;;;AAKF;;;AAGJ;AAEA;AAEA;AACE;AACF;AACF;AAEA;AAEI;AACA;AACE;AACA;;;AAIJ;AAMI;AACD;AAyCP;AAGF;;;"}
|
|
1
|
+
{"version":3,"file":"DatePicker.cjs","sources":["../../../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["'use client'\n\nimport dayjs from 'dayjs'\nimport {\n type ChangeEvent,\n type ComponentProps,\n type ComponentPropsWithRef,\n type MouseEvent,\n type ReactNode,\n forwardRef,\n memo,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useAnimationFrame } from '../../hooks/useAnimationFrame'\nimport { useLatest } from '../../hooks/useLatest'\nimport { useOuterClick } from '../../hooks/useOuterClick'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Calendar } from '../Calendar'\nimport { FaCalendarDaysIcon } from '../Icon'\nimport { Input } from '../Input'\n\nimport { Portal } from './Portal'\nimport { parseJpnDateString } from './datePickerHelper'\n\ntype ChangeLikeEvent = ChangeEvent | React.KeyboardEvent | MouseEvent\ntype BaseProps = {\n /** input 要素の `value` 属性の値 */\n value?: string | null\n /** input 要素の `name` 属性の値 */\n name?: string\n /** 選択可能な期間の開始日 */\n from?: Date\n /** 選択可能な期間の終了日 */\n to?: Date\n /** フォームを無効にするかどうか */\n disabled?: boolean\n /**\n * placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** 入力を独自にパースする場合に、パース処理を記述する関数 */\n parseInput?: (input: string) => Date | null\n /** 表示する日付を独自にフォーマットする場合に、フォーマット処理を記述する関数 */\n formatDate?: (date: Date | null) => string\n /** 入出力用文字列と併記する別フォーマット処理を記述する関数 */\n showAlternative?: (date: Date | null) => ReactNode\n /** @deprecated onChangeDate は非推奨です。onChange を使ってください。 */\n onChangeDate?: (date: Date | null, value: string, other: { errors: string[] }) => void\n /** 選択された日付が変わった時に発火するコールバック関数 */\n onChange?: (\n e: ChangeEvent<HTMLInputElement>,\n other: { date: Date | null; formatValue: string; errors: string[] },\n ) => void\n}\ntype Props = BaseProps &\n Omit<\n ComponentPropsWithRef<'input'>,\n | keyof BaseProps\n | 'type'\n | 'onChange'\n | 'onKeyPress'\n | 'onFocus'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-haspopup'\n >\n\nexport const DEFAULT_FROM = new Date(1900, 0, 1)\n\nconst classNameGenerator = tv({\n slots: {\n container: 'smarthr-ui-DatePicker shr-inline-block',\n inputSuffixLayout: 'shr-box-border shr-h-full shr-py-0.5',\n inputSuffixWrapper:\n 'shr-border-l-shorthand shr-box-border shr-flex shr-h-full shr-items-center shr-justify-center shr-ps-0.5 shr-text-base',\n inputSuffixText: 'shr-text-gray shr-me-0.5 shr-text-sm',\n },\n})\n\nconst DEFAULT_DATE_TO_STRING_FORMAT = 'YYYY/MM/DD'\nconst DEFAULT_DATE_TO_STRING = (d: Date | null) =>\n d ? dayjs(d).format(DEFAULT_DATE_TO_STRING_FORMAT) : ''\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\n\nconst parseStringDate = (\n str: string | null | undefined,\n parseInputFn: ((input: string) => Date | null) | undefined,\n) => {\n if (!str) return null\n return parseInputFn ? parseInputFn(str) : parseJpnDateString(str)\n}\n\n/** @deprecated DatePicker は非推奨です。Input[type=date] を使ってください。 */\nexport const DatePicker = forwardRef<HTMLInputElement, Props>(\n (\n {\n value,\n name,\n from = DEFAULT_FROM,\n to,\n disabled,\n width,\n error,\n className,\n parseInput,\n formatDate,\n showAlternative,\n onChangeDate,\n onChange,\n onBlur,\n ...rest\n },\n ref,\n ) => {\n const theme = useTheme()\n const classNames = useMemo(() => {\n const { container, inputSuffixLayout, inputSuffixWrapper, inputSuffixText } =\n classNameGenerator()\n\n return {\n container: container({ className }),\n inputSuffixLayout: inputSuffixLayout(),\n inputSuffixWrapper: inputSuffixWrapper(),\n inputSuffixText: inputSuffixText(),\n }\n }, [className])\n\n const [isInputFocused, setIsInputFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const inputWrapperRef = useRef<HTMLDivElement>(null)\n const calendarPortalRef = useRef<HTMLDivElement>(null)\n const [inputRect, setInputRect] = useState<DOMRect | null>(null)\n const [isCalendarShown, setIsCalendarShown] = useState(false)\n const [alternativeFormat, setAlternativeFormat] = useState<null | ReactNode>(null)\n const calenderId = useId()\n\n const [selectedDate, setSelectedDate] = useState<Date | null>(() =>\n parseStringDate(value, parseInput),\n )\n\n const closeFrame = useAnimationFrame()\n\n const latest = useLatest({\n onChange,\n onChangeDate,\n parseInput,\n formatDate,\n showAlternative,\n onBlur,\n isInputFocused,\n selectedDate,\n closeFrame,\n })\n\n const functions = useMemo(() => {\n const dateToString = (date: Date | null) =>\n latest.formatDate ? latest.formatDate(date) : DEFAULT_DATE_TO_STRING(date)\n\n const dateToAlternativeFormat = (d: Date | null) => {\n if (!latest.showAlternative) return null\n return d ? latest.showAlternative(d) : null\n }\n\n const stringToDate = (str: string | null | undefined) =>\n parseStringDate(str, latest.parseInput)\n\n const updateDate = (e: ChangeLikeEvent, newDate: Date | null) => {\n if (\n !inputRef.current ||\n newDate === latest.selectedDate ||\n (newDate && latest.selectedDate && newDate.getTime() === latest.selectedDate.getTime())\n ) {\n // Do not update date if the new date is same with the old one.\n return\n }\n\n const isValid = !newDate || dayjs(newDate).isValid()\n const errors: string[] = []\n\n if (!isValid) {\n errors.push('INVALID_DATE')\n }\n\n const nextDate = isValid ? newDate : null\n const formatValue = dateToString(nextDate)\n\n inputRef.current.value = formatValue\n setAlternativeFormat(dateToAlternativeFormat(nextDate))\n setSelectedDate(nextDate)\n\n if (latest.onChange) {\n e.preventDefault()\n e.stopPropagation()\n\n const event = new Event('change', { bubbles: true })\n const input = inputRef.current\n\n input.dispatchEvent(event)\n latest.onChange(\n // HINT: 型問題のため別途オブジェクトをイベントに見立てる\n {\n stopPropagation: () => {\n event.stopPropagation()\n },\n preventDefault: () => {\n event.preventDefault()\n },\n target: input,\n currentTarget: input,\n } as ChangeEvent<HTMLInputElement>,\n { date: nextDate, formatValue, errors },\n )\n } else if (latest.onChangeDate) {\n latest.onChangeDate(nextDate, formatValue, { errors })\n }\n }\n\n const closeCalendar = () => setIsCalendarShown(false)\n\n const openCalendar = () => {\n if (inputWrapperRef.current) {\n setIsCalendarShown(true)\n setInputRect(inputWrapperRef.current.getBoundingClientRect())\n }\n }\n\n return {\n stringToDate,\n dateToString,\n dateToAlternativeFormat,\n closeCalendar,\n openCalendar,\n handleBlur: (e: React.FocusEvent<HTMLInputElement>) => {\n setIsInputFocused(false)\n updateDate(e, e.target.value ? stringToDate(e.target.value) : null)\n latest.onBlur?.(e)\n },\n handleDelegateKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n // delay hiding calendar because calendar will be displayed when input is focused\n latest.closeFrame.request(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n }\n },\n handleKeyPressInput: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n const isExpanded = e.currentTarget.getAttribute('aria-expanded') === 'true'\n ;(isExpanded ? closeCalendar : openCalendar)()\n updateDate(e, stringToDate(e.currentTarget.value))\n }\n },\n handleFocusInput: () => {\n setIsInputFocused(true)\n openCalendar()\n },\n handleSelectDateCalendar: (e: ChangeLikeEvent, selected: Date | null) => {\n updateDate(e, selected)\n // delay hiding calendar because calendar will be displayed when input is focused\n latest.closeFrame.request(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n },\n }\n }, [latest])\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => inputRef.current,\n [],\n )\n\n useEffect(() => {\n if (value === undefined || !inputRef.current) {\n return\n }\n\n /**\n * Do not format the given value in the following cases\n * - while input element is focused.\n * - if the given value is not date formattable.\n */\n if (!isInputFocused) {\n const newDate = functions.stringToDate(value)\n\n if (newDate && dayjs(newDate).isValid()) {\n inputRef.current.value = functions.dateToString(newDate)\n setAlternativeFormat(functions.dateToAlternativeFormat(newDate))\n setSelectedDate(newDate)\n\n return\n }\n\n setSelectedDate(null)\n }\n\n inputRef.current.value = value || ''\n }, [value, isInputFocused, functions])\n\n useOuterClick([inputWrapperRef, calendarPortalRef], functions.closeCalendar)\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!inputRef.current || !calendarPortalRef.current || e.key !== 'Tab') {\n return\n }\n\n const calendarButtons = calendarPortalRef.current.querySelectorAll('button')\n\n if (calendarButtons.length === 0) {\n return\n }\n\n const firstCalendarButton = calendarButtons[0]\n\n if (latest.isInputFocused) {\n if (e.shiftKey) {\n // move focus from Input to previous elements of DatePicker\n functions.closeCalendar()\n\n return\n }\n\n // move focus from Input to Calendar\n e.preventDefault()\n firstCalendarButton.focus()\n\n return\n }\n\n const calendarButtonAry = Array.from(calendarButtons)\n const currentFocused = calendarButtonAry.find((button) => button === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstCalendarButton) {\n // move focus from Calendar to Input\n inputRef.current.focus()\n e.preventDefault()\n }\n } else if (currentFocused === calendarButtonAry.at(-1)) {\n // move focus from Calendar to next elements of DatePicker\n inputRef.current.focus()\n functions.closeCalendar()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n latest.closeFrame.cancel()\n }\n }, [functions, latest])\n\n const caretIconColor =\n isInputFocused || isCalendarShown\n ? theme.textColor.black\n : disabled\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n return (\n // eslint-disable-next-line smarthr/best-practice-for-interactive-element\n <div\n onClick={!isCalendarShown && !disabled ? functions.openCalendar : undefined}\n onKeyDown={isCalendarShown ? functions.handleDelegateKeyDown : undefined}\n role=\"presentation\"\n className={classNames.container}\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n }}\n >\n <div ref={inputWrapperRef}>\n <Input\n {...rest}\n data-smarthr-ui-input=\"true\"\n width=\"100%\"\n name={name}\n onChange={isCalendarShown ? functions.closeCalendar : undefined}\n onKeyPress={functions.handleKeyPressInput}\n onFocus={functions.handleFocusInput}\n onBlur={functions.handleBlur}\n suffix={\n <InputSuffixIcon\n alternativeFormat={showAlternative ? alternativeFormat : null}\n caretIconColor={caretIconColor}\n classNames={classNames}\n />\n }\n disabled={disabled}\n error={error}\n ref={inputRef}\n className=\"smarthr-ui-DatePicker-inputContainer\"\n aria-expanded={isCalendarShown}\n aria-controls={calenderId}\n aria-haspopup={true}\n />\n </div>\n {isCalendarShown && inputRect && (\n <Portal inputRect={inputRect} ref={calendarPortalRef}>\n <Calendar\n id={calenderId}\n value={selectedDate || undefined}\n from={from}\n to={to}\n onSelectDate={functions.handleSelectDateCalendar}\n />\n </Portal>\n )}\n </div>\n )\n },\n)\n\nconst InputSuffixIcon = memo<{\n classNames: { inputSuffixLayout: string; inputSuffixWrapper: string; inputSuffixText: string }\n alternativeFormat: null | ReactNode\n caretIconColor: ComponentProps<typeof FaCalendarDaysIcon>['color']\n}>(({ classNames, alternativeFormat, caretIconColor }) => (\n <span className={classNames.inputSuffixLayout}>\n <span className={classNames.inputSuffixWrapper}>\n {alternativeFormat && <span className={classNames.inputSuffixText}>{alternativeFormat}</span>}\n <FaCalendarDaysIcon color={caretIconColor} />\n </span>\n </span>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AA8EO;AAEP;AACE;AACE;AACA;AACA;AAEA;AACD;AACF;AAED;AACA;AAEA;AAEA;AAIE;AAAU;AACV;AACF;AAEA;;AAsBI;AACA;AACE;;AAIE;;;;;AAKJ;;AAGA;AACA;AACA;;;;AAIA;AAEA;AAIA;;;;;;;;;;;AAYC;AAED;;AAIE;;AAC+B;AAC7B;AACF;AAEA;AAGA;;;AAII;;;;AAMF;;;AAIE;;;AAIF;AAEA;AACA;;AAGA;;;AAIE;AACA;AAEA;AACA;;AAEE;;;;;;;AAOE;AACA;;;AAIC;;;AAGT;;;AAKE;;;;AAIF;;;;;;;AAQE;;;AAGE;;AAEF;;;;AAII;;AAEsB;;;AAG1B;AACE;AACE;;AAEA;;;;;AAKF;;AAEF;AACE;;AAEA;;AAEsB;;;AAG5B;AAEA;;;;;AAWE;;;;AAIG;;;;;;;;;;;;;;;AAqBH;AACE;;;;AAMA;;;AAIA;AAEA;AACE;;;;;;;;;;;AAeF;AAEA;AACE;;AAEE;;;;;;AAKF;;;AAGJ;AAEA;AAEA;AACE;AACA;AACF;AACF;AAEA;AAEI;AACA;AACE;AACA;;;AAIJ;AAMI;AACD;AAyCP;AAGF;;;"}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import dayjs from '../../_virtual/dayjs.min.js';
|
|
4
4
|
import { forwardRef, useMemo, useState, useRef, useId, useImperativeHandle, useEffect, memo } from 'react';
|
|
5
|
-
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.46_@
|
|
5
|
+
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.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js';
|
|
6
|
+
import { useAnimationFrame } from '../../hooks/useAnimationFrame.js';
|
|
6
7
|
import { useLatest } from '../../hooks/useLatest.js';
|
|
7
8
|
import { useOuterClick } from '../../hooks/useOuterClick.js';
|
|
8
9
|
import { useTheme } from '../../hooks/useTheme.js';
|
|
@@ -54,6 +55,7 @@ const DatePicker = forwardRef(({ value, name, from = DEFAULT_FROM, to, disabled,
|
|
|
54
55
|
const [alternativeFormat, setAlternativeFormat] = useState(null);
|
|
55
56
|
const calenderId = useId();
|
|
56
57
|
const [selectedDate, setSelectedDate] = useState(() => parseStringDate(value, parseInput));
|
|
58
|
+
const closeFrame = useAnimationFrame();
|
|
57
59
|
const latest = useLatest({
|
|
58
60
|
onChange,
|
|
59
61
|
onChangeDate,
|
|
@@ -63,6 +65,7 @@ const DatePicker = forwardRef(({ value, name, from = DEFAULT_FROM, to, disabled,
|
|
|
63
65
|
onBlur,
|
|
64
66
|
isInputFocused,
|
|
65
67
|
selectedDate,
|
|
68
|
+
closeFrame,
|
|
66
69
|
});
|
|
67
70
|
const functions = useMemo(() => {
|
|
68
71
|
const dateToString = (date) => latest.formatDate ? latest.formatDate(date) : DEFAULT_DATE_TO_STRING(date);
|
|
@@ -134,7 +137,7 @@ const DatePicker = forwardRef(({ value, name, from = DEFAULT_FROM, to, disabled,
|
|
|
134
137
|
if (ESCAPE_KEY_REGEX.test(e.key)) {
|
|
135
138
|
e.stopPropagation();
|
|
136
139
|
// delay hiding calendar because calendar will be displayed when input is focused
|
|
137
|
-
|
|
140
|
+
latest.closeFrame.request(closeCalendar);
|
|
138
141
|
if (inputRef.current)
|
|
139
142
|
inputRef.current.focus();
|
|
140
143
|
}
|
|
@@ -153,7 +156,7 @@ const DatePicker = forwardRef(({ value, name, from = DEFAULT_FROM, to, disabled,
|
|
|
153
156
|
handleSelectDateCalendar: (e, selected) => {
|
|
154
157
|
updateDate(e, selected);
|
|
155
158
|
// delay hiding calendar because calendar will be displayed when input is focused
|
|
156
|
-
|
|
159
|
+
latest.closeFrame.request(closeCalendar);
|
|
157
160
|
if (inputRef.current)
|
|
158
161
|
inputRef.current.focus();
|
|
159
162
|
},
|
|
@@ -221,6 +224,7 @@ const DatePicker = forwardRef(({ value, name, from = DEFAULT_FROM, to, disabled,
|
|
|
221
224
|
window.addEventListener('keydown', handleKeyDown);
|
|
222
225
|
return () => {
|
|
223
226
|
window.removeEventListener('keydown', handleKeyDown);
|
|
227
|
+
latest.closeFrame.cancel();
|
|
224
228
|
};
|
|
225
229
|
}, [functions, latest]);
|
|
226
230
|
const caretIconColor = isInputFocused || isCalendarShown
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.js","sources":["../../../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["'use client'\n\nimport dayjs from 'dayjs'\nimport {\n type ChangeEvent,\n type ComponentProps,\n type ComponentPropsWithRef,\n type MouseEvent,\n type ReactNode,\n forwardRef,\n memo,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useOuterClick } from '../../hooks/useOuterClick'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Calendar } from '../Calendar'\nimport { FaCalendarDaysIcon } from '../Icon'\nimport { Input } from '../Input'\n\nimport { Portal } from './Portal'\nimport { parseJpnDateString } from './datePickerHelper'\n\ntype ChangeLikeEvent = ChangeEvent | React.KeyboardEvent | MouseEvent\ntype BaseProps = {\n /** input 要素の `value` 属性の値 */\n value?: string | null\n /** input 要素の `name` 属性の値 */\n name?: string\n /** 選択可能な期間の開始日 */\n from?: Date\n /** 選択可能な期間の終了日 */\n to?: Date\n /** フォームを無効にするかどうか */\n disabled?: boolean\n /**\n * placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** 入力を独自にパースする場合に、パース処理を記述する関数 */\n parseInput?: (input: string) => Date | null\n /** 表示する日付を独自にフォーマットする場合に、フォーマット処理を記述する関数 */\n formatDate?: (date: Date | null) => string\n /** 入出力用文字列と併記する別フォーマット処理を記述する関数 */\n showAlternative?: (date: Date | null) => ReactNode\n /** @deprecated onChangeDate は非推奨です。onChange を使ってください。 */\n onChangeDate?: (date: Date | null, value: string, other: { errors: string[] }) => void\n /** 選択された日付が変わった時に発火するコールバック関数 */\n onChange?: (\n e: ChangeEvent<HTMLInputElement>,\n other: { date: Date | null; formatValue: string; errors: string[] },\n ) => void\n}\ntype Props = BaseProps &\n Omit<\n ComponentPropsWithRef<'input'>,\n | keyof BaseProps\n | 'type'\n | 'onChange'\n | 'onKeyPress'\n | 'onFocus'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-haspopup'\n >\n\nexport const DEFAULT_FROM = new Date(1900, 0, 1)\n\nconst classNameGenerator = tv({\n slots: {\n container: 'smarthr-ui-DatePicker shr-inline-block',\n inputSuffixLayout: 'shr-box-border shr-h-full shr-py-0.5',\n inputSuffixWrapper:\n 'shr-border-l-shorthand shr-box-border shr-flex shr-h-full shr-items-center shr-justify-center shr-ps-0.5 shr-text-base',\n inputSuffixText: 'shr-text-gray shr-me-0.5 shr-text-sm',\n },\n})\n\nconst DEFAULT_DATE_TO_STRING_FORMAT = 'YYYY/MM/DD'\nconst DEFAULT_DATE_TO_STRING = (d: Date | null) =>\n d ? dayjs(d).format(DEFAULT_DATE_TO_STRING_FORMAT) : ''\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\n\nconst parseStringDate = (\n str: string | null | undefined,\n parseInputFn: ((input: string) => Date | null) | undefined,\n) => {\n if (!str) return null\n return parseInputFn ? parseInputFn(str) : parseJpnDateString(str)\n}\n\n/** @deprecated DatePicker は非推奨です。Input[type=date] を使ってください。 */\nexport const DatePicker = forwardRef<HTMLInputElement, Props>(\n (\n {\n value,\n name,\n from = DEFAULT_FROM,\n to,\n disabled,\n width,\n error,\n className,\n parseInput,\n formatDate,\n showAlternative,\n onChangeDate,\n onChange,\n onBlur,\n ...rest\n },\n ref,\n ) => {\n const theme = useTheme()\n const classNames = useMemo(() => {\n const { container, inputSuffixLayout, inputSuffixWrapper, inputSuffixText } =\n classNameGenerator()\n\n return {\n container: container({ className }),\n inputSuffixLayout: inputSuffixLayout(),\n inputSuffixWrapper: inputSuffixWrapper(),\n inputSuffixText: inputSuffixText(),\n }\n }, [className])\n\n const [isInputFocused, setIsInputFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const inputWrapperRef = useRef<HTMLDivElement>(null)\n const calendarPortalRef = useRef<HTMLDivElement>(null)\n const [inputRect, setInputRect] = useState<DOMRect | null>(null)\n const [isCalendarShown, setIsCalendarShown] = useState(false)\n const [alternativeFormat, setAlternativeFormat] = useState<null | ReactNode>(null)\n const calenderId = useId()\n\n const [selectedDate, setSelectedDate] = useState<Date | null>(() =>\n parseStringDate(value, parseInput),\n )\n\n const latest = useLatest({\n onChange,\n onChangeDate,\n parseInput,\n formatDate,\n showAlternative,\n onBlur,\n isInputFocused,\n selectedDate,\n })\n\n const functions = useMemo(() => {\n const dateToString = (date: Date | null) =>\n latest.formatDate ? latest.formatDate(date) : DEFAULT_DATE_TO_STRING(date)\n\n const dateToAlternativeFormat = (d: Date | null) => {\n if (!latest.showAlternative) return null\n return d ? latest.showAlternative(d) : null\n }\n\n const stringToDate = (str: string | null | undefined) =>\n parseStringDate(str, latest.parseInput)\n\n const updateDate = (e: ChangeLikeEvent, newDate: Date | null) => {\n if (\n !inputRef.current ||\n newDate === latest.selectedDate ||\n (newDate && latest.selectedDate && newDate.getTime() === latest.selectedDate.getTime())\n ) {\n // Do not update date if the new date is same with the old one.\n return\n }\n\n const isValid = !newDate || dayjs(newDate).isValid()\n const errors: string[] = []\n\n if (!isValid) {\n errors.push('INVALID_DATE')\n }\n\n const nextDate = isValid ? newDate : null\n const formatValue = dateToString(nextDate)\n\n inputRef.current.value = formatValue\n setAlternativeFormat(dateToAlternativeFormat(nextDate))\n setSelectedDate(nextDate)\n\n if (latest.onChange) {\n e.preventDefault()\n e.stopPropagation()\n\n const event = new Event('change', { bubbles: true })\n const input = inputRef.current\n\n input.dispatchEvent(event)\n latest.onChange(\n // HINT: 型問題のため別途オブジェクトをイベントに見立てる\n {\n stopPropagation: () => {\n event.stopPropagation()\n },\n preventDefault: () => {\n event.preventDefault()\n },\n target: input,\n currentTarget: input,\n } as ChangeEvent<HTMLInputElement>,\n { date: nextDate, formatValue, errors },\n )\n } else if (latest.onChangeDate) {\n latest.onChangeDate(nextDate, formatValue, { errors })\n }\n }\n\n const closeCalendar = () => setIsCalendarShown(false)\n\n const openCalendar = () => {\n if (inputWrapperRef.current) {\n setIsCalendarShown(true)\n setInputRect(inputWrapperRef.current.getBoundingClientRect())\n }\n }\n\n return {\n stringToDate,\n dateToString,\n dateToAlternativeFormat,\n closeCalendar,\n openCalendar,\n handleBlur: (e: React.FocusEvent<HTMLInputElement>) => {\n setIsInputFocused(false)\n updateDate(e, e.target.value ? stringToDate(e.target.value) : null)\n latest.onBlur?.(e)\n },\n handleDelegateKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n // delay hiding calendar because calendar will be displayed when input is focused\n requestAnimationFrame(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n }\n },\n handleKeyPressInput: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n const isExpanded = e.currentTarget.getAttribute('aria-expanded') === 'true'\n ;(isExpanded ? closeCalendar : openCalendar)()\n updateDate(e, stringToDate(e.currentTarget.value))\n }\n },\n handleFocusInput: () => {\n setIsInputFocused(true)\n openCalendar()\n },\n handleSelectDateCalendar: (e: ChangeLikeEvent, selected: Date | null) => {\n updateDate(e, selected)\n // delay hiding calendar because calendar will be displayed when input is focused\n requestAnimationFrame(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n },\n }\n }, [latest])\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => inputRef.current,\n [],\n )\n\n useEffect(() => {\n if (value === undefined || !inputRef.current) {\n return\n }\n\n /**\n * Do not format the given value in the following cases\n * - while input element is focused.\n * - if the given value is not date formattable.\n */\n if (!isInputFocused) {\n const newDate = functions.stringToDate(value)\n\n if (newDate && dayjs(newDate).isValid()) {\n inputRef.current.value = functions.dateToString(newDate)\n setAlternativeFormat(functions.dateToAlternativeFormat(newDate))\n setSelectedDate(newDate)\n\n return\n }\n\n setSelectedDate(null)\n }\n\n inputRef.current.value = value || ''\n }, [value, isInputFocused, functions])\n\n useOuterClick([inputWrapperRef, calendarPortalRef], functions.closeCalendar)\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!inputRef.current || !calendarPortalRef.current || e.key !== 'Tab') {\n return\n }\n\n const calendarButtons = calendarPortalRef.current.querySelectorAll('button')\n\n if (calendarButtons.length === 0) {\n return\n }\n\n const firstCalendarButton = calendarButtons[0]\n\n if (latest.isInputFocused) {\n if (e.shiftKey) {\n // move focus from Input to previous elements of DatePicker\n functions.closeCalendar()\n\n return\n }\n\n // move focus from Input to Calendar\n e.preventDefault()\n firstCalendarButton.focus()\n\n return\n }\n\n const calendarButtonAry = Array.from(calendarButtons)\n const currentFocused = calendarButtonAry.find((button) => button === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstCalendarButton) {\n // move focus from Calendar to Input\n inputRef.current.focus()\n e.preventDefault()\n }\n } else if (currentFocused === calendarButtonAry.at(-1)) {\n // move focus from Calendar to next elements of DatePicker\n inputRef.current.focus()\n functions.closeCalendar()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [functions, latest])\n\n const caretIconColor =\n isInputFocused || isCalendarShown\n ? theme.textColor.black\n : disabled\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n return (\n // eslint-disable-next-line smarthr/best-practice-for-interactive-element\n <div\n onClick={!isCalendarShown && !disabled ? functions.openCalendar : undefined}\n onKeyDown={isCalendarShown ? functions.handleDelegateKeyDown : undefined}\n role=\"presentation\"\n className={classNames.container}\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n }}\n >\n <div ref={inputWrapperRef}>\n <Input\n {...rest}\n data-smarthr-ui-input=\"true\"\n width=\"100%\"\n name={name}\n onChange={isCalendarShown ? functions.closeCalendar : undefined}\n onKeyPress={functions.handleKeyPressInput}\n onFocus={functions.handleFocusInput}\n onBlur={functions.handleBlur}\n suffix={\n <InputSuffixIcon\n alternativeFormat={showAlternative ? alternativeFormat : null}\n caretIconColor={caretIconColor}\n classNames={classNames}\n />\n }\n disabled={disabled}\n error={error}\n ref={inputRef}\n className=\"smarthr-ui-DatePicker-inputContainer\"\n aria-expanded={isCalendarShown}\n aria-controls={calenderId}\n aria-haspopup={true}\n />\n </div>\n {isCalendarShown && inputRect && (\n <Portal inputRect={inputRect} ref={calendarPortalRef}>\n <Calendar\n id={calenderId}\n value={selectedDate || undefined}\n from={from}\n to={to}\n onSelectDate={functions.handleSelectDateCalendar}\n />\n </Portal>\n )}\n </div>\n )\n },\n)\n\nconst InputSuffixIcon = memo<{\n classNames: { inputSuffixLayout: string; inputSuffixWrapper: string; inputSuffixText: string }\n alternativeFormat: null | ReactNode\n caretIconColor: ComponentProps<typeof FaCalendarDaysIcon>['color']\n}>(({ classNames, alternativeFormat, caretIconColor }) => (\n <span className={classNames.inputSuffixLayout}>\n <span className={classNames.inputSuffixWrapper}>\n {alternativeFormat && <span className={classNames.inputSuffixText}>{alternativeFormat}</span>}\n <FaCalendarDaysIcon color={caretIconColor} />\n </span>\n </span>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AA6EO;AAEP;AACE;AACE;AACA;AACA;AAEA;AACD;AACF;AAED;AACA;AAEA;AAEA;AAIE;AAAU;AACV;AACF;AAEA;;AAsBI;AACA;AACE;;AAIE;;;;;AAKJ;;AAGA;AACA;AACA;;;;AAIA;AAEA;;;;;;;;;;AAaC;AAED;;AAIE;;AAC+B;AAC7B;AACF;AAEA;AAGA;;;AAII;;;;AAMF;;;AAIE;;;AAIF;AAEA;AACA;;AAGA;;;AAIE;AACA;AAEA;AACA;;AAEE;;;;;;;AAOE;AACA;;;AAIC;;;AAGT;;;AAKE;;;;AAIF;;;;;;;AAQE;;;AAGE;;AAEF;;;;;;AAM0B;;;AAG1B;AACE;AACE;;AAEA;;;;;AAKF;;AAEF;AACE;;;;AAIsB;;;AAG5B;AAEA;;;;;AAWE;;;;AAIG;;;;;;;;;;;;;;;AAqBH;AACE;;;;AAMA;;;AAIA;AAEA;AACE;;;;;;;;;;;AAeF;AAEA;AACE;;AAEE;;;;;;AAKF;;;AAGJ;AAEA;AAEA;AACE;AACF;AACF;AAEA;AAEI;AACA;AACE;AACA;;;AAIJ;AAMI;AACD;AAyCP;AAGF;;"}
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sources":["../../../src/components/DatePicker/DatePicker.tsx"],"sourcesContent":["'use client'\n\nimport dayjs from 'dayjs'\nimport {\n type ChangeEvent,\n type ComponentProps,\n type ComponentPropsWithRef,\n type MouseEvent,\n type ReactNode,\n forwardRef,\n memo,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useAnimationFrame } from '../../hooks/useAnimationFrame'\nimport { useLatest } from '../../hooks/useLatest'\nimport { useOuterClick } from '../../hooks/useOuterClick'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Calendar } from '../Calendar'\nimport { FaCalendarDaysIcon } from '../Icon'\nimport { Input } from '../Input'\n\nimport { Portal } from './Portal'\nimport { parseJpnDateString } from './datePickerHelper'\n\ntype ChangeLikeEvent = ChangeEvent | React.KeyboardEvent | MouseEvent\ntype BaseProps = {\n /** input 要素の `value` 属性の値 */\n value?: string | null\n /** input 要素の `name` 属性の値 */\n name?: string\n /** 選択可能な期間の開始日 */\n from?: Date\n /** 選択可能な期間の終了日 */\n to?: Date\n /** フォームを無効にするかどうか */\n disabled?: boolean\n /**\n * placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** 入力を独自にパースする場合に、パース処理を記述する関数 */\n parseInput?: (input: string) => Date | null\n /** 表示する日付を独自にフォーマットする場合に、フォーマット処理を記述する関数 */\n formatDate?: (date: Date | null) => string\n /** 入出力用文字列と併記する別フォーマット処理を記述する関数 */\n showAlternative?: (date: Date | null) => ReactNode\n /** @deprecated onChangeDate は非推奨です。onChange を使ってください。 */\n onChangeDate?: (date: Date | null, value: string, other: { errors: string[] }) => void\n /** 選択された日付が変わった時に発火するコールバック関数 */\n onChange?: (\n e: ChangeEvent<HTMLInputElement>,\n other: { date: Date | null; formatValue: string; errors: string[] },\n ) => void\n}\ntype Props = BaseProps &\n Omit<\n ComponentPropsWithRef<'input'>,\n | keyof BaseProps\n | 'type'\n | 'onChange'\n | 'onKeyPress'\n | 'onFocus'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-haspopup'\n >\n\nexport const DEFAULT_FROM = new Date(1900, 0, 1)\n\nconst classNameGenerator = tv({\n slots: {\n container: 'smarthr-ui-DatePicker shr-inline-block',\n inputSuffixLayout: 'shr-box-border shr-h-full shr-py-0.5',\n inputSuffixWrapper:\n 'shr-border-l-shorthand shr-box-border shr-flex shr-h-full shr-items-center shr-justify-center shr-ps-0.5 shr-text-base',\n inputSuffixText: 'shr-text-gray shr-me-0.5 shr-text-sm',\n },\n})\n\nconst DEFAULT_DATE_TO_STRING_FORMAT = 'YYYY/MM/DD'\nconst DEFAULT_DATE_TO_STRING = (d: Date | null) =>\n d ? dayjs(d).format(DEFAULT_DATE_TO_STRING_FORMAT) : ''\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\n\nconst parseStringDate = (\n str: string | null | undefined,\n parseInputFn: ((input: string) => Date | null) | undefined,\n) => {\n if (!str) return null\n return parseInputFn ? parseInputFn(str) : parseJpnDateString(str)\n}\n\n/** @deprecated DatePicker は非推奨です。Input[type=date] を使ってください。 */\nexport const DatePicker = forwardRef<HTMLInputElement, Props>(\n (\n {\n value,\n name,\n from = DEFAULT_FROM,\n to,\n disabled,\n width,\n error,\n className,\n parseInput,\n formatDate,\n showAlternative,\n onChangeDate,\n onChange,\n onBlur,\n ...rest\n },\n ref,\n ) => {\n const theme = useTheme()\n const classNames = useMemo(() => {\n const { container, inputSuffixLayout, inputSuffixWrapper, inputSuffixText } =\n classNameGenerator()\n\n return {\n container: container({ className }),\n inputSuffixLayout: inputSuffixLayout(),\n inputSuffixWrapper: inputSuffixWrapper(),\n inputSuffixText: inputSuffixText(),\n }\n }, [className])\n\n const [isInputFocused, setIsInputFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n const inputWrapperRef = useRef<HTMLDivElement>(null)\n const calendarPortalRef = useRef<HTMLDivElement>(null)\n const [inputRect, setInputRect] = useState<DOMRect | null>(null)\n const [isCalendarShown, setIsCalendarShown] = useState(false)\n const [alternativeFormat, setAlternativeFormat] = useState<null | ReactNode>(null)\n const calenderId = useId()\n\n const [selectedDate, setSelectedDate] = useState<Date | null>(() =>\n parseStringDate(value, parseInput),\n )\n\n const closeFrame = useAnimationFrame()\n\n const latest = useLatest({\n onChange,\n onChangeDate,\n parseInput,\n formatDate,\n showAlternative,\n onBlur,\n isInputFocused,\n selectedDate,\n closeFrame,\n })\n\n const functions = useMemo(() => {\n const dateToString = (date: Date | null) =>\n latest.formatDate ? latest.formatDate(date) : DEFAULT_DATE_TO_STRING(date)\n\n const dateToAlternativeFormat = (d: Date | null) => {\n if (!latest.showAlternative) return null\n return d ? latest.showAlternative(d) : null\n }\n\n const stringToDate = (str: string | null | undefined) =>\n parseStringDate(str, latest.parseInput)\n\n const updateDate = (e: ChangeLikeEvent, newDate: Date | null) => {\n if (\n !inputRef.current ||\n newDate === latest.selectedDate ||\n (newDate && latest.selectedDate && newDate.getTime() === latest.selectedDate.getTime())\n ) {\n // Do not update date if the new date is same with the old one.\n return\n }\n\n const isValid = !newDate || dayjs(newDate).isValid()\n const errors: string[] = []\n\n if (!isValid) {\n errors.push('INVALID_DATE')\n }\n\n const nextDate = isValid ? newDate : null\n const formatValue = dateToString(nextDate)\n\n inputRef.current.value = formatValue\n setAlternativeFormat(dateToAlternativeFormat(nextDate))\n setSelectedDate(nextDate)\n\n if (latest.onChange) {\n e.preventDefault()\n e.stopPropagation()\n\n const event = new Event('change', { bubbles: true })\n const input = inputRef.current\n\n input.dispatchEvent(event)\n latest.onChange(\n // HINT: 型問題のため別途オブジェクトをイベントに見立てる\n {\n stopPropagation: () => {\n event.stopPropagation()\n },\n preventDefault: () => {\n event.preventDefault()\n },\n target: input,\n currentTarget: input,\n } as ChangeEvent<HTMLInputElement>,\n { date: nextDate, formatValue, errors },\n )\n } else if (latest.onChangeDate) {\n latest.onChangeDate(nextDate, formatValue, { errors })\n }\n }\n\n const closeCalendar = () => setIsCalendarShown(false)\n\n const openCalendar = () => {\n if (inputWrapperRef.current) {\n setIsCalendarShown(true)\n setInputRect(inputWrapperRef.current.getBoundingClientRect())\n }\n }\n\n return {\n stringToDate,\n dateToString,\n dateToAlternativeFormat,\n closeCalendar,\n openCalendar,\n handleBlur: (e: React.FocusEvent<HTMLInputElement>) => {\n setIsInputFocused(false)\n updateDate(e, e.target.value ? stringToDate(e.target.value) : null)\n latest.onBlur?.(e)\n },\n handleDelegateKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n // delay hiding calendar because calendar will be displayed when input is focused\n latest.closeFrame.request(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n }\n },\n handleKeyPressInput: (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n const isExpanded = e.currentTarget.getAttribute('aria-expanded') === 'true'\n ;(isExpanded ? closeCalendar : openCalendar)()\n updateDate(e, stringToDate(e.currentTarget.value))\n }\n },\n handleFocusInput: () => {\n setIsInputFocused(true)\n openCalendar()\n },\n handleSelectDateCalendar: (e: ChangeLikeEvent, selected: Date | null) => {\n updateDate(e, selected)\n // delay hiding calendar because calendar will be displayed when input is focused\n latest.closeFrame.request(closeCalendar)\n\n if (inputRef.current) inputRef.current.focus()\n },\n }\n }, [latest])\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => inputRef.current,\n [],\n )\n\n useEffect(() => {\n if (value === undefined || !inputRef.current) {\n return\n }\n\n /**\n * Do not format the given value in the following cases\n * - while input element is focused.\n * - if the given value is not date formattable.\n */\n if (!isInputFocused) {\n const newDate = functions.stringToDate(value)\n\n if (newDate && dayjs(newDate).isValid()) {\n inputRef.current.value = functions.dateToString(newDate)\n setAlternativeFormat(functions.dateToAlternativeFormat(newDate))\n setSelectedDate(newDate)\n\n return\n }\n\n setSelectedDate(null)\n }\n\n inputRef.current.value = value || ''\n }, [value, isInputFocused, functions])\n\n useOuterClick([inputWrapperRef, calendarPortalRef], functions.closeCalendar)\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!inputRef.current || !calendarPortalRef.current || e.key !== 'Tab') {\n return\n }\n\n const calendarButtons = calendarPortalRef.current.querySelectorAll('button')\n\n if (calendarButtons.length === 0) {\n return\n }\n\n const firstCalendarButton = calendarButtons[0]\n\n if (latest.isInputFocused) {\n if (e.shiftKey) {\n // move focus from Input to previous elements of DatePicker\n functions.closeCalendar()\n\n return\n }\n\n // move focus from Input to Calendar\n e.preventDefault()\n firstCalendarButton.focus()\n\n return\n }\n\n const calendarButtonAry = Array.from(calendarButtons)\n const currentFocused = calendarButtonAry.find((button) => button === e.target)\n\n if (e.shiftKey) {\n if (currentFocused === firstCalendarButton) {\n // move focus from Calendar to Input\n inputRef.current.focus()\n e.preventDefault()\n }\n } else if (currentFocused === calendarButtonAry.at(-1)) {\n // move focus from Calendar to next elements of DatePicker\n inputRef.current.focus()\n functions.closeCalendar()\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n latest.closeFrame.cancel()\n }\n }, [functions, latest])\n\n const caretIconColor =\n isInputFocused || isCalendarShown\n ? theme.textColor.black\n : disabled\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n return (\n // eslint-disable-next-line smarthr/best-practice-for-interactive-element\n <div\n onClick={!isCalendarShown && !disabled ? functions.openCalendar : undefined}\n onKeyDown={isCalendarShown ? functions.handleDelegateKeyDown : undefined}\n role=\"presentation\"\n className={classNames.container}\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n }}\n >\n <div ref={inputWrapperRef}>\n <Input\n {...rest}\n data-smarthr-ui-input=\"true\"\n width=\"100%\"\n name={name}\n onChange={isCalendarShown ? functions.closeCalendar : undefined}\n onKeyPress={functions.handleKeyPressInput}\n onFocus={functions.handleFocusInput}\n onBlur={functions.handleBlur}\n suffix={\n <InputSuffixIcon\n alternativeFormat={showAlternative ? alternativeFormat : null}\n caretIconColor={caretIconColor}\n classNames={classNames}\n />\n }\n disabled={disabled}\n error={error}\n ref={inputRef}\n className=\"smarthr-ui-DatePicker-inputContainer\"\n aria-expanded={isCalendarShown}\n aria-controls={calenderId}\n aria-haspopup={true}\n />\n </div>\n {isCalendarShown && inputRect && (\n <Portal inputRect={inputRect} ref={calendarPortalRef}>\n <Calendar\n id={calenderId}\n value={selectedDate || undefined}\n from={from}\n to={to}\n onSelectDate={functions.handleSelectDateCalendar}\n />\n </Portal>\n )}\n </div>\n )\n },\n)\n\nconst InputSuffixIcon = memo<{\n classNames: { inputSuffixLayout: string; inputSuffixWrapper: string; inputSuffixText: string }\n alternativeFormat: null | ReactNode\n caretIconColor: ComponentProps<typeof FaCalendarDaysIcon>['color']\n}>(({ classNames, alternativeFormat, caretIconColor }) => (\n <span className={classNames.inputSuffixLayout}>\n <span className={classNames.inputSuffixWrapper}>\n {alternativeFormat && <span className={classNames.inputSuffixText}>{alternativeFormat}</span>}\n <FaCalendarDaysIcon color={caretIconColor} />\n </span>\n </span>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AA8EO;AAEP;AACE;AACE;AACA;AACA;AAEA;AACD;AACF;AAED;AACA;AAEA;AAEA;AAIE;AAAU;AACV;AACF;AAEA;;AAsBI;AACA;AACE;;AAIE;;;;;AAKJ;;AAGA;AACA;AACA;;;;AAIA;AAEA;AAIA;;;;;;;;;;;AAYC;AAED;;AAIE;;AAC+B;AAC7B;AACF;AAEA;AAGA;;;AAII;;;;AAMF;;;AAIE;;;AAIF;AAEA;AACA;;AAGA;;;AAIE;AACA;AAEA;AACA;;AAEE;;;;;;;AAOE;AACA;;;AAIC;;;AAGT;;;AAKE;;;;AAIF;;;;;;;AAQE;;;AAGE;;AAEF;;;;AAII;;AAEsB;;;AAG1B;AACE;AACE;;AAEA;;;;;AAKF;;AAEF;AACE;;AAEA;;AAEsB;;;AAG5B;AAEA;;;;;AAWE;;;;AAIG;;;;;;;;;;;;;;;AAqBH;AACE;;;;AAMA;;;AAIA;AAEA;AACE;;;;;;;;;;;AAeF;AAEA;AACE;;AAEE;;;;;;AAKF;;;AAGJ;AAEA;AAEA;AACE;AACA;AACF;AACF;AAEA;AAEI;AACA;AACE;AACA;;;AAIJ;AAMI;AACD;AAyCP;AAGF;;"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
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.46_@
|
|
5
|
+
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
|
|
6
6
|
require('../Layout/Stack/Stack.cjs');
|
|
7
7
|
var components_Layout_Cluster_Cluster = require('../Layout/Cluster/Cluster.cjs');
|
|
8
8
|
require('../Layout/Reel/Reel.cjs');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
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.46_@
|
|
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.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js';
|
|
4
4
|
import '../Layout/Stack/Stack.js';
|
|
5
5
|
import { Cluster } from '../Layout/Cluster/Cluster.js';
|
|
6
6
|
import '../Layout/Reel/Reel.js';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var React = require('react');
|
|
6
|
-
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@
|
|
6
|
+
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
|
|
7
7
|
var hooks_useObjectAttributes = require('../../hooks/useObjectAttributes.cjs');
|
|
8
8
|
var hooks_useTheme = require('../../hooks/useTheme.cjs');
|
|
9
9
|
var components_Layout_Stack_Stack = require('../Layout/Stack/Stack.cjs');
|
|
@@ -43,14 +43,13 @@ const DefinitionListItem = ({ term: orgTerm, children, maxColumns, fullWidth, cl
|
|
|
43
43
|
description: cs.description(),
|
|
44
44
|
};
|
|
45
45
|
}, [className, fullWidth]);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return (jsxRuntime.jsxs(components_Layout_Stack_Stack.Stack, { gap: 0.25, className: classNames.wrapper, style: style, children: [jsxRuntime.jsx(DefinitionTerm, { styleType: term.styleType, className: classNames.term, children: term.text }), jsxRuntime.jsx(components_Text_Text.Text, { as: "dd", size: "M", color: "TEXT_BLACK", leading: "NORMAL", className: classNames.description, children: children })] }));
|
|
46
|
+
return (jsxRuntime.jsxs(components_Layout_Stack_Stack.Stack, { gap: 0.25, className: classNames.wrapper, style: {
|
|
47
|
+
flexBasis:
|
|
48
|
+
// fullWidth の方が強い
|
|
49
|
+
!fullWidth && maxColumns
|
|
50
|
+
? `calc((100% - ${theme.spacingByChar(1.5)} * ${maxColumns - 1}) / ${maxColumns})`
|
|
51
|
+
: undefined,
|
|
52
|
+
}, children: [jsxRuntime.jsx(DefinitionTerm, { styleType: term.styleType, className: classNames.term, children: term.text }), jsxRuntime.jsx(components_Text_Text.Text, { as: "dd", size: "M", color: "TEXT_BLACK", leading: "NORMAL", className: classNames.description, children: children })] }));
|
|
54
53
|
};
|
|
55
54
|
const DefinitionTerm = React.memo(({ styleType = 'subBlockTitle', className, children }) => (jsxRuntime.jsx(components_Text_Text.Text, { as: "dt", leading: "TIGHT", styleType: styleType, className: className, children: children })));
|
|
56
55
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefinitionListItem.cjs","sources":["../../../src/components/DefinitionList/DefinitionListItem.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithoutRef,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../hooks/useObjectAttributes'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Stack } from '../Layout'\nimport { Text } from '../Text'\n\ntype ObjectTermType = {\n text: ReactNode\n styleType?: 'blockTitle' | 'subBlockTitle' | 'subSubBlockTitle'\n}\ntype BaseProps = PropsWithChildren<{\n term: ReactNode | ObjectTermType\n fullWidth?: boolean\n maxColumns?: number\n}>\ntype Props = BaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof BaseProps>\n\nconst termObjectConverter = (term: ReactNode): ObjectTermType => ({ text: term })\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-DefinitionListItem shr-border-b-shorthand shr-min-w-[12em] shr-grow shr-border-dotted',\n 'contrast-more:shr-border-b-high-contrast',\n ],\n term: 'smarthr-ui-DefinitionListItem-term',\n description:\n 'smarthr-ui-DefinitionListItem-description shr-ms-[initial] shr-min-h-[calc(1em*theme(lineHeight.normal))] shr-pb-0.25',\n },\n variants: {\n fullWidth: {\n true: {\n wrapper: 'shr-basis-full',\n },\n },\n },\n})\n\nexport const DefinitionListItem: FC<Props> = ({\n term: orgTerm,\n children,\n maxColumns,\n fullWidth,\n className,\n}) => {\n const theme = useTheme()\n const term = useObjectAttributes<ReactNode | ObjectTermType, ObjectTermType>(\n orgTerm,\n termObjectConverter,\n )\n\n const classNames = useMemo(() => {\n const cs = classNameGenerator()\n\n return {\n wrapper: cs.wrapper({ fullWidth, className }),\n term: cs.term(),\n description: cs.description(),\n }\n }, [className, fullWidth])\n
|
|
1
|
+
{"version":3,"file":"DefinitionListItem.cjs","sources":["../../../src/components/DefinitionList/DefinitionListItem.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithoutRef,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../hooks/useObjectAttributes'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Stack } from '../Layout'\nimport { Text } from '../Text'\n\ntype ObjectTermType = {\n text: ReactNode\n styleType?: 'blockTitle' | 'subBlockTitle' | 'subSubBlockTitle'\n}\ntype BaseProps = PropsWithChildren<{\n term: ReactNode | ObjectTermType\n fullWidth?: boolean\n maxColumns?: number\n}>\ntype Props = BaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof BaseProps>\n\nconst termObjectConverter = (term: ReactNode): ObjectTermType => ({ text: term })\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-DefinitionListItem shr-border-b-shorthand shr-min-w-[12em] shr-grow shr-border-dotted',\n 'contrast-more:shr-border-b-high-contrast',\n ],\n term: 'smarthr-ui-DefinitionListItem-term',\n description:\n 'smarthr-ui-DefinitionListItem-description shr-ms-[initial] shr-min-h-[calc(1em*theme(lineHeight.normal))] shr-pb-0.25',\n },\n variants: {\n fullWidth: {\n true: {\n wrapper: 'shr-basis-full',\n },\n },\n },\n})\n\nexport const DefinitionListItem: FC<Props> = ({\n term: orgTerm,\n children,\n maxColumns,\n fullWidth,\n className,\n}) => {\n const theme = useTheme()\n const term = useObjectAttributes<ReactNode | ObjectTermType, ObjectTermType>(\n orgTerm,\n termObjectConverter,\n )\n\n const classNames = useMemo(() => {\n const cs = classNameGenerator()\n\n return {\n wrapper: cs.wrapper({ fullWidth, className }),\n term: cs.term(),\n description: cs.description(),\n }\n }, [className, fullWidth])\n\n return (\n <Stack\n gap={0.25}\n className={classNames.wrapper}\n style={{\n flexBasis:\n // fullWidth の方が強い\n !fullWidth && maxColumns\n ? `calc((100% - ${theme.spacingByChar(1.5)} * ${maxColumns - 1}) / ${maxColumns})`\n : undefined,\n }}\n >\n <DefinitionTerm styleType={term.styleType} className={classNames.term}>\n {term.text}\n </DefinitionTerm>\n <Text as=\"dd\" size=\"M\" color=\"TEXT_BLACK\" leading=\"NORMAL\" className={classNames.description}>\n {children}\n </Text>\n </Stack>\n )\n}\n\nconst DefinitionTerm = memo<\n PropsWithChildren<{ styleType: ObjectTermType['styleType']; className: string }>\n>(({ styleType = 'subBlockTitle', className, children }) => (\n <Text as=\"dt\" leading=\"TIGHT\" styleType={styleType} className={className}>\n {children}\n </Text>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AA4BA;AAEA;AACE;AACE;;;AAGC;AACD;AACA;AAED;AACD;AACE;AACE;AACE;AACD;AACF;AACF;AACF;AAEM;AAOL;;AAMA;AACE;;;AAIE;AACA;;AAEJ;AAEA;;;;AAQU;AACA;;AAWZ;AAEA;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { memo, useMemo } from 'react';
|
|
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.46_@
|
|
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.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js';
|
|
5
5
|
import { useObjectAttributes } from '../../hooks/useObjectAttributes.js';
|
|
6
6
|
import { useTheme } from '../../hooks/useTheme.js';
|
|
7
7
|
import { Stack } from '../Layout/Stack/Stack.js';
|
|
@@ -41,14 +41,13 @@ const DefinitionListItem = ({ term: orgTerm, children, maxColumns, fullWidth, cl
|
|
|
41
41
|
description: cs.description(),
|
|
42
42
|
};
|
|
43
43
|
}, [className, fullWidth]);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return (jsxs(Stack, { gap: 0.25, className: classNames.wrapper, style: style, children: [jsx(DefinitionTerm, { styleType: term.styleType, className: classNames.term, children: term.text }), jsx(Text, { as: "dd", size: "M", color: "TEXT_BLACK", leading: "NORMAL", className: classNames.description, children: children })] }));
|
|
44
|
+
return (jsxs(Stack, { gap: 0.25, className: classNames.wrapper, style: {
|
|
45
|
+
flexBasis:
|
|
46
|
+
// fullWidth の方が強い
|
|
47
|
+
!fullWidth && maxColumns
|
|
48
|
+
? `calc((100% - ${theme.spacingByChar(1.5)} * ${maxColumns - 1}) / ${maxColumns})`
|
|
49
|
+
: undefined,
|
|
50
|
+
}, children: [jsx(DefinitionTerm, { styleType: term.styleType, className: classNames.term, children: term.text }), jsx(Text, { as: "dd", size: "M", color: "TEXT_BLACK", leading: "NORMAL", className: classNames.description, children: children })] }));
|
|
52
51
|
};
|
|
53
52
|
const DefinitionTerm = memo(({ styleType = 'subBlockTitle', className, children }) => (jsx(Text, { as: "dt", leading: "TIGHT", styleType: styleType, className: className, children: children })));
|
|
54
53
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefinitionListItem.js","sources":["../../../src/components/DefinitionList/DefinitionListItem.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithoutRef,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../hooks/useObjectAttributes'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Stack } from '../Layout'\nimport { Text } from '../Text'\n\ntype ObjectTermType = {\n text: ReactNode\n styleType?: 'blockTitle' | 'subBlockTitle' | 'subSubBlockTitle'\n}\ntype BaseProps = PropsWithChildren<{\n term: ReactNode | ObjectTermType\n fullWidth?: boolean\n maxColumns?: number\n}>\ntype Props = BaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof BaseProps>\n\nconst termObjectConverter = (term: ReactNode): ObjectTermType => ({ text: term })\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-DefinitionListItem shr-border-b-shorthand shr-min-w-[12em] shr-grow shr-border-dotted',\n 'contrast-more:shr-border-b-high-contrast',\n ],\n term: 'smarthr-ui-DefinitionListItem-term',\n description:\n 'smarthr-ui-DefinitionListItem-description shr-ms-[initial] shr-min-h-[calc(1em*theme(lineHeight.normal))] shr-pb-0.25',\n },\n variants: {\n fullWidth: {\n true: {\n wrapper: 'shr-basis-full',\n },\n },\n },\n})\n\nexport const DefinitionListItem: FC<Props> = ({\n term: orgTerm,\n children,\n maxColumns,\n fullWidth,\n className,\n}) => {\n const theme = useTheme()\n const term = useObjectAttributes<ReactNode | ObjectTermType, ObjectTermType>(\n orgTerm,\n termObjectConverter,\n )\n\n const classNames = useMemo(() => {\n const cs = classNameGenerator()\n\n return {\n wrapper: cs.wrapper({ fullWidth, className }),\n term: cs.term(),\n description: cs.description(),\n }\n }, [className, fullWidth])\n
|
|
1
|
+
{"version":3,"file":"DefinitionListItem.js","sources":["../../../src/components/DefinitionList/DefinitionListItem.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithoutRef,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../hooks/useObjectAttributes'\nimport { useTheme } from '../../hooks/useTheme'\nimport { Stack } from '../Layout'\nimport { Text } from '../Text'\n\ntype ObjectTermType = {\n text: ReactNode\n styleType?: 'blockTitle' | 'subBlockTitle' | 'subSubBlockTitle'\n}\ntype BaseProps = PropsWithChildren<{\n term: ReactNode | ObjectTermType\n fullWidth?: boolean\n maxColumns?: number\n}>\ntype Props = BaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof BaseProps>\n\nconst termObjectConverter = (term: ReactNode): ObjectTermType => ({ text: term })\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-DefinitionListItem shr-border-b-shorthand shr-min-w-[12em] shr-grow shr-border-dotted',\n 'contrast-more:shr-border-b-high-contrast',\n ],\n term: 'smarthr-ui-DefinitionListItem-term',\n description:\n 'smarthr-ui-DefinitionListItem-description shr-ms-[initial] shr-min-h-[calc(1em*theme(lineHeight.normal))] shr-pb-0.25',\n },\n variants: {\n fullWidth: {\n true: {\n wrapper: 'shr-basis-full',\n },\n },\n },\n})\n\nexport const DefinitionListItem: FC<Props> = ({\n term: orgTerm,\n children,\n maxColumns,\n fullWidth,\n className,\n}) => {\n const theme = useTheme()\n const term = useObjectAttributes<ReactNode | ObjectTermType, ObjectTermType>(\n orgTerm,\n termObjectConverter,\n )\n\n const classNames = useMemo(() => {\n const cs = classNameGenerator()\n\n return {\n wrapper: cs.wrapper({ fullWidth, className }),\n term: cs.term(),\n description: cs.description(),\n }\n }, [className, fullWidth])\n\n return (\n <Stack\n gap={0.25}\n className={classNames.wrapper}\n style={{\n flexBasis:\n // fullWidth の方が強い\n !fullWidth && maxColumns\n ? `calc((100% - ${theme.spacingByChar(1.5)} * ${maxColumns - 1}) / ${maxColumns})`\n : undefined,\n }}\n >\n <DefinitionTerm styleType={term.styleType} className={classNames.term}>\n {term.text}\n </DefinitionTerm>\n <Text as=\"dd\" size=\"M\" color=\"TEXT_BLACK\" leading=\"NORMAL\" className={classNames.description}>\n {children}\n </Text>\n </Stack>\n )\n}\n\nconst DefinitionTerm = memo<\n PropsWithChildren<{ styleType: ObjectTermType['styleType']; className: string }>\n>(({ styleType = 'subBlockTitle', className, children }) => (\n <Text as=\"dt\" leading=\"TIGHT\" styleType={styleType} className={className}>\n {children}\n </Text>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA4BA;AAEA;AACE;AACE;;;AAGC;AACD;AACA;AAED;AACD;AACE;AACE;AACE;AACD;AACF;AACF;AACF;AAEM;AAOL;;AAMA;AACE;;;AAIE;AACA;;AAEJ;AAEA;;;;AAQU;AACA;;AAWZ;AAEA;;"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
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.46_@
|
|
5
|
+
var index = require('./../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
|
|
6
6
|
var hooks_useResponseStatus = require('../../../hooks/useResponseStatus.cjs');
|
|
7
7
|
require('../../../intl/IntlProvider.cjs');
|
|
8
8
|
require('react-intl');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { memo } 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.46_@
|
|
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.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js';
|
|
4
4
|
import { useResponseStatus } from '../../../hooks/useResponseStatus.js';
|
|
5
5
|
import '../../../intl/IntlProvider.js';
|
|
6
6
|
import 'react-intl';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var hooks_useLatest = require('../../../hooks/useLatest.cjs');
|
|
7
|
+
var hooks_useObjectAttributes = require('../../../hooks/useObjectAttributes.cjs');
|
|
7
8
|
require('../../../intl/IntlProvider.cjs');
|
|
8
9
|
var intl_useIntl = require('../../../intl/useIntl.cjs');
|
|
9
10
|
require('react-intl');
|
|
@@ -15,9 +16,36 @@ var components_Dialog_useDialogPortal = require('../useDialogPortal.cjs');
|
|
|
15
16
|
var components_Dialog_useObjectHeading = require('../useObjectHeading.cjs');
|
|
16
17
|
var components_Dialog_ControlledStepFormDialog_StepFormDialogContentInner = require('./StepFormDialogContentInner.cjs');
|
|
17
18
|
var components_Dialog_ControlledStepFormDialog_StepFormDialogProvider = require('./StepFormDialogProvider.cjs');
|
|
18
|
-
var components_Dialog_ControlledStepFormDialog_useStepFormDialogButton = require('./useStepFormDialogButton.cjs');
|
|
19
19
|
|
|
20
20
|
const headingObjectConverter = (text) => ({ text });
|
|
21
|
+
const buttonObjectConverter = (text) => ({
|
|
22
|
+
text,
|
|
23
|
+
});
|
|
24
|
+
const useStepFormDialogButton = ({ button, currentStep, defaultValues: { text: defaultText, theme: defaultTheme }, }) => {
|
|
25
|
+
const { text: tempText, theme: tempTheme, disabled: tempDisabled, hidden: tempHidden, } = hooks_useObjectAttributes.useObjectAttributes(button, buttonObjectConverter);
|
|
26
|
+
const actualButton = React.useMemo(() => {
|
|
27
|
+
let text = tempText ?? defaultText;
|
|
28
|
+
let textFunc = false;
|
|
29
|
+
if (typeof text === 'function') {
|
|
30
|
+
textFunc = true;
|
|
31
|
+
text = text(currentStep, defaultText);
|
|
32
|
+
}
|
|
33
|
+
const actualTempTheme = tempTheme || defaultTheme;
|
|
34
|
+
const theme = typeof actualTempTheme === 'function' ? actualTempTheme(currentStep) : actualTempTheme;
|
|
35
|
+
const disabled = typeof tempDisabled === 'function' ? tempDisabled(currentStep) : tempDisabled;
|
|
36
|
+
const hidden = typeof tempHidden === 'function' ? tempHidden(currentStep) : tempHidden;
|
|
37
|
+
return {
|
|
38
|
+
text,
|
|
39
|
+
theme,
|
|
40
|
+
disabled,
|
|
41
|
+
hidden,
|
|
42
|
+
functionCall: {
|
|
43
|
+
text: textFunc,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}, [currentStep, tempText, tempTheme, tempDisabled, tempHidden, defaultText, defaultTheme]);
|
|
47
|
+
return actualButton;
|
|
48
|
+
};
|
|
21
49
|
const ControlledStepFormDialog = ({ portalParent, id, firstStep, ...rest }) => {
|
|
22
50
|
const { createPortal } = components_Dialog_useDialogPortal.useDialogPortal(portalParent, id);
|
|
23
51
|
return createPortal(jsxRuntime.jsx(components_Dialog_ControlledStepFormDialog_StepFormDialogProvider.StepFormDialogProvider, { firstStep: firstStep, children: jsxRuntime.jsx(ActualControlledStepFormDialog, { ...rest, firstStep: firstStep }) }));
|
|
@@ -40,7 +68,7 @@ const ActualControlledStepFormDialog = ({ children, heading: orgHeading, stepLen
|
|
|
40
68
|
const { currentStep } = React.useContext(components_Dialog_ControlledStepFormDialog_StepFormDialogProvider.StepFormDialogContext);
|
|
41
69
|
const activeStep = currentStep?.stepNumber ?? 1;
|
|
42
70
|
const heading = components_Dialog_useObjectHeading.useObjectHeading(orgHeading, headingObjectConverter);
|
|
43
|
-
const tempSubmitButton =
|
|
71
|
+
const tempSubmitButton = useStepFormDialogButton({
|
|
44
72
|
button: originalSubmitButton,
|
|
45
73
|
currentStep,
|
|
46
74
|
defaultValues: {
|
|
@@ -54,14 +82,14 @@ const ActualControlledStepFormDialog = ({ children, heading: orgHeading, stepLen
|
|
|
54
82
|
? tempSubmitButton.text
|
|
55
83
|
: defaultTexts.nextButtonLabel,
|
|
56
84
|
}), [tempSubmitButton, activeStep, stepLength, defaultTexts.nextButtonLabel]);
|
|
57
|
-
const closeButton =
|
|
85
|
+
const closeButton = useStepFormDialogButton({
|
|
58
86
|
button: originalCloseButton,
|
|
59
87
|
currentStep,
|
|
60
88
|
defaultValues: {
|
|
61
89
|
text: defaultTexts.closeButtonLabel,
|
|
62
90
|
},
|
|
63
91
|
});
|
|
64
|
-
const backButton =
|
|
92
|
+
const backButton = useStepFormDialogButton({
|
|
65
93
|
button: originalBackButton,
|
|
66
94
|
currentStep,
|
|
67
95
|
defaultValues: {
|