@vkontakte/vkui 7.3.8 → 7.4.1
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/dist/components/ActionSheet/ActionSheet.d.ts +1 -1
- package/dist/components/ActionSheet/ActionSheet.d.ts.map +1 -1
- package/dist/components/ActionSheet/ActionSheet.js.map +1 -1
- package/dist/components/AppRoot/ScrollContext.js +2 -2
- package/dist/components/AppRoot/ScrollContext.js.map +1 -1
- package/dist/components/Banner/Banner.d.ts +2 -2
- package/dist/components/Banner/Banner.d.ts.map +1 -1
- package/dist/components/Banner/Banner.js.map +1 -1
- package/dist/components/Button/Button.d.ts +2 -2
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/components/Calendar/Calendar.js +9 -7
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/CalendarRange/CalendarRange.d.ts +9 -2
- package/dist/components/CalendarRange/CalendarRange.d.ts.map +1 -1
- package/dist/components/CalendarRange/CalendarRange.js +48 -35
- package/dist/components/CalendarRange/CalendarRange.js.map +1 -1
- package/dist/components/CalendarRange/types.d.ts +2 -0
- package/dist/components/CalendarRange/types.d.ts.map +1 -0
- package/dist/components/CalendarRange/types.js +3 -0
- package/dist/components/CalendarRange/types.js.map +1 -0
- package/dist/components/CalendarRange/utils.d.ts +29 -0
- package/dist/components/CalendarRange/utils.d.ts.map +1 -0
- package/dist/components/CalendarRange/utils.js +123 -0
- package/dist/components/CalendarRange/utils.js.map +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +2 -2
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/ChipsInput/useChipsInput.d.ts.map +1 -1
- package/dist/components/ChipsInput/useChipsInput.js +21 -2
- package/dist/components/ChipsInput/useChipsInput.js.map +1 -1
- package/dist/components/ChipsInputBase/types.d.ts +5 -1
- package/dist/components/ChipsInputBase/types.d.ts.map +1 -1
- package/dist/components/ChipsInputBase/types.js.map +1 -1
- package/dist/components/Clickable/Clickable.d.ts +4 -0
- package/dist/components/Clickable/Clickable.d.ts.map +1 -1
- package/dist/components/Clickable/Clickable.js +9 -5
- package/dist/components/Clickable/Clickable.js.map +1 -1
- package/dist/components/Clickable/RealClickable.d.ts +1 -1
- package/dist/components/Clickable/RealClickable.d.ts.map +1 -1
- package/dist/components/Clickable/RealClickable.js +3 -2
- package/dist/components/Clickable/RealClickable.js.map +1 -1
- package/dist/components/ContentCard/ContentCard.d.ts +2 -2
- package/dist/components/ContentCard/ContentCard.d.ts.map +1 -1
- package/dist/components/ContentCard/ContentCard.js.map +1 -1
- package/dist/components/CustomSelect/CustomSelect.d.ts +4 -1
- package/dist/components/CustomSelect/CustomSelect.d.ts.map +1 -1
- package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
- package/dist/components/DateInput/DateInput.d.ts +1 -1
- package/dist/components/DateInput/DateInput.d.ts.map +1 -1
- package/dist/components/DateInput/DateInput.js +48 -50
- package/dist/components/DateInput/DateInput.js.map +1 -1
- package/dist/components/DateRangeInput/DateRangeInput.d.ts +22 -2
- package/dist/components/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/components/DateRangeInput/DateRangeInput.js +159 -66
- package/dist/components/DateRangeInput/DateRangeInput.js.map +1 -1
- package/dist/components/FocusTrap/FocusTrap.d.ts +1 -1
- package/dist/components/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/dist/components/FocusTrap/FocusTrap.js +6 -3
- package/dist/components/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/components/HorizontalCell/HorizontalCell.d.ts +2 -2
- package/dist/components/HorizontalCell/HorizontalCell.d.ts.map +1 -1
- package/dist/components/HorizontalCell/HorizontalCell.js.map +1 -1
- package/dist/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.d.ts +2 -2
- package/dist/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.d.ts.map +1 -1
- package/dist/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.js.map +1 -1
- package/dist/components/IconButton/IconButton.d.ts +2 -2
- package/dist/components/IconButton/IconButton.d.ts.map +1 -1
- package/dist/components/IconButton/IconButton.js.map +1 -1
- package/dist/components/InputLike/InputLike.d.ts +1 -1
- package/dist/components/InputLike/InputLike.d.ts.map +1 -1
- package/dist/components/InputLike/InputLike.js +7 -6
- package/dist/components/InputLike/InputLike.js.map +1 -1
- package/dist/components/Link/Link.d.ts +2 -2
- package/dist/components/Link/Link.d.ts.map +1 -1
- package/dist/components/Link/Link.js +2 -1
- package/dist/components/Link/Link.js.map +1 -1
- package/dist/components/MiniInfoCell/MiniInfoCell.d.ts.map +1 -1
- package/dist/components/MiniInfoCell/MiniInfoCell.js +1 -8
- package/dist/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
- package/dist/components/ModalOutsideButton/ModalOutsideButton.d.ts +2 -2
- package/dist/components/ModalOutsideButton/ModalOutsideButton.d.ts.map +1 -1
- package/dist/components/ModalOutsideButton/ModalOutsideButton.js.map +1 -1
- package/dist/components/NumberInputLike/NumberInputLike.d.ts +8 -0
- package/dist/components/NumberInputLike/NumberInputLike.d.ts.map +1 -0
- package/dist/components/NumberInputLike/NumberInputLike.js +45 -0
- package/dist/components/NumberInputLike/NumberInputLike.js.map +1 -0
- package/dist/components/Pagination/PaginationPage/PaginationPageButton.d.ts +2 -2
- package/dist/components/Pagination/PaginationPage/PaginationPageButton.d.ts.map +1 -1
- package/dist/components/Pagination/PaginationPage/PaginationPageButton.js.map +1 -1
- package/dist/components/PanelHeader/PanelHeader.d.ts +3 -1
- package/dist/components/PanelHeader/PanelHeader.d.ts.map +1 -1
- package/dist/components/PanelHeader/PanelHeader.js.map +1 -1
- package/dist/components/PanelHeaderButton/PanelHeaderButton.d.ts +2 -2
- package/dist/components/PanelHeaderButton/PanelHeaderButton.d.ts.map +1 -1
- package/dist/components/PanelHeaderButton/PanelHeaderButton.js.map +1 -1
- package/dist/components/Radio/Radio.d.ts +2 -2
- package/dist/components/Radio/Radio.d.ts.map +1 -1
- package/dist/components/Radio/Radio.js.map +1 -1
- package/dist/components/Removable/Removable.d.ts +1 -4
- package/dist/components/Removable/Removable.d.ts.map +1 -1
- package/dist/components/Removable/Removable.js +39 -116
- package/dist/components/Removable/Removable.js.map +1 -1
- package/dist/components/Removable/RemovableIos.d.ts +10 -0
- package/dist/components/Removable/RemovableIos.d.ts.map +1 -0
- package/dist/components/Removable/RemovableIos.js +124 -0
- package/dist/components/Removable/RemovableIos.js.map +1 -0
- package/dist/components/RichCell/RichCell.d.ts +2 -2
- package/dist/components/RichCell/RichCell.d.ts.map +1 -1
- package/dist/components/RichCell/RichCell.js.map +1 -1
- package/dist/components/ScreenSpinner/ScreenSpinner.d.ts.map +1 -1
- package/dist/components/ScreenSpinner/ScreenSpinner.js +4 -2
- package/dist/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
- package/dist/components/ScreenSpinner/ScreenSpinnerContainer.d.ts +2 -2
- package/dist/components/ScreenSpinner/ScreenSpinnerContainer.d.ts.map +1 -1
- package/dist/components/ScreenSpinner/ScreenSpinnerContainer.js +4 -3
- package/dist/components/ScreenSpinner/ScreenSpinnerContainer.js.map +1 -1
- package/dist/components/SelectionControl/SelectionControl.d.ts +2 -2
- package/dist/components/SelectionControl/SelectionControl.d.ts.map +1 -1
- package/dist/components/SelectionControl/SelectionControl.js.map +1 -1
- package/dist/components/SimpleCell/SimpleCell.d.ts +2 -2
- package/dist/components/SimpleCell/SimpleCell.d.ts.map +1 -1
- package/dist/components/SimpleCell/SimpleCell.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.d.ts +5 -1
- package/dist/components/Skeleton/Skeleton.d.ts.map +1 -1
- package/dist/components/Skeleton/Skeleton.js +7 -4
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Spinner/Spinner.d.ts +5 -1
- package/dist/components/Spinner/Spinner.d.ts.map +1 -1
- package/dist/components/Spinner/Spinner.js +6 -3
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/SubnavigationButton/SubnavigationButton.d.ts +2 -2
- package/dist/components/SubnavigationButton/SubnavigationButton.d.ts.map +1 -1
- package/dist/components/SubnavigationButton/SubnavigationButton.js.map +1 -1
- package/dist/components/Tabs/Tabs.d.ts +13 -9
- package/dist/components/Tabs/Tabs.d.ts.map +1 -1
- package/dist/components/Tabs/Tabs.js +14 -10
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tabs/TabsController.d.ts +7 -0
- package/dist/components/Tabs/TabsController.d.ts.map +1 -0
- package/dist/components/Tabs/TabsController.js +19 -0
- package/dist/components/Tabs/TabsController.js.map +1 -0
- package/dist/components/Tabs/TabsModeContext.d.ts +13 -0
- package/dist/components/Tabs/TabsModeContext.d.ts.map +1 -0
- package/dist/components/Tabs/TabsModeContext.js +11 -0
- package/dist/components/Tabs/TabsModeContext.js.map +1 -0
- package/dist/components/TabsItem/TabsItem.d.ts +3 -3
- package/dist/components/TabsItem/TabsItem.d.ts.map +1 -1
- package/dist/components/TabsItem/TabsItem.js +21 -6
- package/dist/components/TabsItem/TabsItem.js.map +1 -1
- package/dist/components/Tappable/Tappable.d.ts +1 -0
- package/dist/components/Tappable/Tappable.d.ts.map +1 -1
- package/dist/components/Tappable/Tappable.js.map +1 -1
- package/dist/components/ToolButton/ToolButton.d.ts +2 -2
- package/dist/components/ToolButton/ToolButton.d.ts.map +1 -1
- package/dist/components/ToolButton/ToolButton.js.map +1 -1
- package/dist/components/View/ViewInfinite.js.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.css.map +1 -1
- package/dist/cssm/components/ActionSheet/ActionSheet.js.map +1 -1
- package/dist/cssm/components/AppRoot/ScrollContext.js +2 -2
- package/dist/cssm/components/AppRoot/ScrollContext.js.map +1 -1
- package/dist/cssm/components/Banner/Banner.js.map +1 -1
- package/dist/cssm/components/Button/Button.js.map +1 -1
- package/dist/cssm/components/Calendar/Calendar.js +9 -7
- package/dist/cssm/components/Calendar/Calendar.js.map +1 -1
- package/dist/cssm/components/CalendarRange/CalendarRange.js +44 -31
- package/dist/cssm/components/CalendarRange/CalendarRange.js.map +1 -1
- package/dist/cssm/components/CalendarRange/types.js +3 -0
- package/dist/cssm/components/CalendarRange/types.js.map +1 -0
- package/dist/cssm/components/CalendarRange/utils.js +122 -0
- package/dist/cssm/components/CalendarRange/utils.js.map +1 -0
- package/dist/cssm/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/cssm/components/ChipsInput/useChipsInput.js +21 -2
- package/dist/cssm/components/ChipsInput/useChipsInput.js.map +1 -1
- package/dist/cssm/components/ChipsInputBase/types.js.map +1 -1
- package/dist/cssm/components/Clickable/Clickable.js +4 -3
- package/dist/cssm/components/Clickable/Clickable.js.map +1 -1
- package/dist/cssm/components/Clickable/RealClickable.js +1 -1
- package/dist/cssm/components/Clickable/RealClickable.js.map +1 -1
- package/dist/cssm/components/ContentCard/ContentCard.js.map +1 -1
- package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
- package/dist/cssm/components/DateInput/DateInput.js +45 -46
- package/dist/cssm/components/DateInput/DateInput.js.map +1 -1
- package/dist/cssm/components/DateRangeInput/DateRangeInput.js +148 -58
- package/dist/cssm/components/DateRangeInput/DateRangeInput.js.map +1 -1
- package/dist/cssm/components/FocusTrap/FocusTrap.js +4 -2
- package/dist/cssm/components/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/cssm/components/HorizontalCell/HorizontalCell.js.map +1 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.js.map +1 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.module.css +2 -3
- package/dist/cssm/components/IconButton/IconButton.js.map +1 -1
- package/dist/cssm/components/ImageBase/ImageBase.module.css +2 -3
- package/dist/cssm/components/InputLike/InputLike.js +3 -3
- package/dist/cssm/components/InputLike/InputLike.js.map +1 -1
- package/dist/cssm/components/Link/Link.js +1 -0
- package/dist/cssm/components/Link/Link.js.map +1 -1
- package/dist/cssm/components/MiniInfoCell/MiniInfoCell.js +1 -8
- package/dist/cssm/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
- package/dist/cssm/components/ModalOutsideButton/ModalOutsideButton.js.map +1 -1
- package/dist/cssm/components/NumberInputLike/NumberInputLike.js +33 -0
- package/dist/cssm/components/NumberInputLike/NumberInputLike.js.map +1 -0
- package/dist/cssm/components/Pagination/PaginationPage/PaginationPageButton.js.map +1 -1
- package/dist/cssm/components/PanelHeader/PanelHeader.js.map +1 -1
- package/dist/cssm/components/PanelHeaderButton/PanelHeaderButton.js.map +1 -1
- package/dist/cssm/components/Radio/Radio.js.map +1 -1
- package/dist/cssm/components/Removable/Removable.js +39 -115
- package/dist/cssm/components/Removable/Removable.js.map +1 -1
- package/dist/cssm/components/Removable/Removable.module.css +9 -0
- package/dist/cssm/components/Removable/RemovableIos.js +118 -0
- package/dist/cssm/components/Removable/RemovableIos.js.map +1 -0
- package/dist/cssm/components/RichCell/RichCell.js.map +1 -1
- package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js +2 -1
- package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
- package/dist/cssm/components/ScreenSpinner/ScreenSpinnerContainer.js +3 -2
- package/dist/cssm/components/ScreenSpinner/ScreenSpinnerContainer.js.map +1 -1
- package/dist/cssm/components/SelectionControl/SelectionControl.js.map +1 -1
- package/dist/cssm/components/SimpleCell/SimpleCell.js.map +1 -1
- package/dist/cssm/components/Skeleton/Skeleton.js +6 -3
- package/dist/cssm/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/cssm/components/Spinner/Spinner.js +5 -2
- package/dist/cssm/components/Spinner/Spinner.js.map +1 -1
- package/dist/cssm/components/SubnavigationButton/SubnavigationButton.js.map +1 -1
- package/dist/cssm/components/Tabs/Tabs.js +10 -9
- package/dist/cssm/components/Tabs/Tabs.js.map +1 -1
- package/dist/cssm/components/Tabs/TabsController.js +19 -0
- package/dist/cssm/components/Tabs/TabsController.js.map +1 -0
- package/dist/cssm/components/Tabs/TabsModeContext.js +11 -0
- package/dist/cssm/components/Tabs/TabsModeContext.js.map +1 -0
- package/dist/cssm/components/TabsItem/TabsItem.js +17 -4
- package/dist/cssm/components/TabsItem/TabsItem.js.map +1 -1
- package/dist/cssm/components/Tappable/Tappable.js.map +1 -1
- package/dist/cssm/components/ToolButton/ToolButton.js.map +1 -1
- package/dist/cssm/components/View/ViewInfinite.js.map +1 -1
- package/dist/cssm/hooks/useCalendar.js +0 -10
- package/dist/cssm/hooks/useCalendar.js.map +1 -1
- package/dist/cssm/hooks/useDateInput.js +28 -17
- package/dist/cssm/hooks/useDateInput.js.map +1 -1
- package/dist/cssm/hooks/useEventListener.js.map +1 -1
- package/dist/cssm/hooks/useExternRef.js.map +1 -1
- package/dist/cssm/hooks/useFocusTrap.js +2 -2
- package/dist/cssm/hooks/useFocusTrap.js.map +1 -1
- package/dist/cssm/hooks/useMutationObserver.js +6 -5
- package/dist/cssm/hooks/useMutationObserver.js.map +1 -1
- package/dist/cssm/lib/dom.js +7 -1
- package/dist/cssm/lib/dom.js.map +1 -1
- package/dist/cssm/lib/floating/customResizeObserver.js.map +1 -1
- package/dist/cssm/lib/floating/index.js.map +1 -1
- package/dist/cssm/lib/floating/types/common.js.map +1 -1
- package/dist/cssm/lib/sheet/controllers/BottomSheetController.js.map +1 -1
- package/dist/cssm/lib/sheet/controllers/CSSTransitionController.js.map +1 -1
- package/dist/cssm/styles/animationVisibilityDelay.js +10 -0
- package/dist/cssm/styles/animationVisibilityDelay.js.map +1 -0
- package/dist/cssm/styles/animationVisibilityDelay.module.css +13 -0
- package/dist/cssm/styles/themes.css +4 -2
- package/dist/hooks/useCalendar.d.ts +0 -3
- package/dist/hooks/useCalendar.d.ts.map +1 -1
- package/dist/hooks/useCalendar.js +0 -10
- package/dist/hooks/useCalendar.js.map +1 -1
- package/dist/hooks/useDateInput.d.ts.map +1 -1
- package/dist/hooks/useDateInput.js +29 -18
- package/dist/hooks/useDateInput.js.map +1 -1
- package/dist/hooks/useEventListener.js.map +1 -1
- package/dist/hooks/useExternRef.js.map +1 -1
- package/dist/hooks/useFocusTrap.d.ts +5 -1
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +2 -2
- package/dist/hooks/useFocusTrap.js.map +1 -1
- package/dist/hooks/useMutationObserver.d.ts +2 -1
- package/dist/hooks/useMutationObserver.d.ts.map +1 -1
- package/dist/hooks/useMutationObserver.js +6 -5
- package/dist/hooks/useMutationObserver.js.map +1 -1
- package/dist/lib/dom.d.ts.map +1 -1
- package/dist/lib/dom.js +7 -1
- package/dist/lib/dom.js.map +1 -1
- package/dist/lib/floating/customResizeObserver.js.map +1 -1
- package/dist/lib/floating/index.d.ts +1 -1
- package/dist/lib/floating/index.d.ts.map +1 -1
- package/dist/lib/floating/index.js.map +1 -1
- package/dist/lib/floating/types/common.d.ts +1 -1
- package/dist/lib/floating/types/common.d.ts.map +1 -1
- package/dist/lib/floating/types/common.js.map +1 -1
- package/dist/lib/sheet/controllers/BottomSheetController.js.map +1 -1
- package/dist/lib/sheet/controllers/CSSTransitionController.js.map +1 -1
- package/dist/styles/animationVisibilityDelay.d.ts +3 -0
- package/dist/styles/animationVisibilityDelay.d.ts.map +1 -0
- package/dist/styles/animationVisibilityDelay.js +10 -0
- package/dist/styles/animationVisibilityDelay.js.map +1 -0
- package/dist/vkui.css +1 -1
- package/dist/vkui.css.map +1 -1
- package/package.json +3 -6
- package/src/components/ActionSheet/ActionSheet.tsx +4 -1
- package/src/components/AppRoot/AppRoot.mdx +1 -1
- package/src/components/AppRoot/ScrollContext.tsx +2 -2
- package/src/components/Banner/Banner.tsx +2 -2
- package/src/components/Button/Button.tsx +2 -2
- package/src/components/Calendar/Calendar.tsx +8 -7
- package/src/components/CalendarRange/CalendarRange.tsx +65 -42
- package/src/components/CalendarRange/types.ts +1 -0
- package/src/components/CalendarRange/utils.ts +190 -0
- package/src/components/Checkbox/Checkbox.tsx +2 -2
- package/src/components/ChipsInput/useChipsInput.ts +23 -2
- package/src/components/ChipsInputBase/types.ts +5 -1
- package/src/components/Clickable/Clickable.tsx +12 -4
- package/src/components/Clickable/RealClickable.tsx +1 -0
- package/src/components/ContentCard/ContentCard.tsx +2 -2
- package/src/components/CustomSelect/CustomSelect.tsx +11 -7
- package/src/components/DateInput/DateInput.tsx +41 -43
- package/src/components/DateRangeInput/DateRangeInput.tsx +183 -65
- package/src/components/FocusTrap/FocusTrap.tsx +3 -0
- package/src/components/FormItem/FormItemTop/FormItemTop.mdx +1 -1
- package/src/components/HorizontalCell/HorizontalCell.tsx +2 -2
- package/src/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.tsx +2 -2
- package/src/components/HorizontalScroll/HorizontalScroll.module.css +2 -3
- package/src/components/HorizontalScroll/HorizontalScroll.module.css.d.ts.map +1 -1
- package/src/components/IconButton/IconButton.tsx +2 -2
- package/src/components/ImageBase/ImageBase.module.css +2 -3
- package/src/components/ImageBase/ImageBase.module.css.d.ts.map +1 -1
- package/src/components/InputLike/InputLike.tsx +4 -3
- package/src/components/Link/Link.tsx +3 -2
- package/src/components/MiniInfoCell/MiniInfoCell.tsx +2 -7
- package/src/components/ModalOutsideButton/ModalOutsideButton.tsx +2 -2
- package/src/components/NumberInputLike/NumberInputLike.tsx +56 -0
- package/src/components/Pagination/PaginationPage/PaginationPageButton.tsx +2 -2
- package/src/components/PanelHeader/PanelHeader.tsx +3 -1
- package/src/components/PanelHeaderButton/PanelHeaderButton.tsx +2 -2
- package/src/components/Radio/Radio.tsx +2 -2
- package/src/components/Removable/Removable.module.css +9 -0
- package/src/components/Removable/Removable.module.css.d.ts.map +1 -1
- package/src/components/Removable/Removable.tsx +50 -120
- package/src/components/Removable/RemovableIos.tsx +135 -0
- package/src/components/RichCell/RichCell.tsx +2 -2
- package/src/components/ScreenSpinner/ScreenSpinner.tsx +8 -1
- package/src/components/ScreenSpinner/ScreenSpinnerContainer.tsx +4 -1
- package/src/components/SelectionControl/SelectionControl.tsx +2 -2
- package/src/components/SimpleCell/SimpleCell.tsx +2 -2
- package/src/components/Skeleton/Skeleton.tsx +15 -2
- package/src/components/Spinner/Spinner.tsx +13 -1
- package/src/components/SubnavigationButton/SubnavigationButton.tsx +2 -2
- package/src/components/Tabs/Tabs.tsx +23 -19
- package/src/components/Tabs/TabsController.ts +37 -0
- package/src/components/Tabs/TabsModeContext.ts +24 -0
- package/src/components/TabsItem/TabsItem.tsx +22 -5
- package/src/components/Tappable/Tappable.tsx +5 -0
- package/src/components/ToolButton/ToolButton.tsx +2 -2
- package/src/components/UnstyledTextField/UnstyledTextField.mdx +1 -1
- package/src/hooks/useCalendar.ts +0 -12
- package/src/hooks/useDateInput.ts +21 -12
- package/src/hooks/useFocusTrap.ts +10 -1
- package/src/hooks/useMutationObserver.ts +7 -4
- package/src/lib/dom.tsx +7 -1
- package/src/lib/floating/index.ts +2 -0
- package/src/lib/floating/types/common.ts +2 -0
- package/src/styles/animationVisibilityDelay.module.css +13 -0
- package/src/styles/animationVisibilityDelay.module.css.d.ts.map +1 -0
- package/src/styles/animationVisibilityDelay.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.1",
|
|
4
4
|
"name": "@vkontakte/vkui",
|
|
5
5
|
"description": "VKUI library",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"lint:generated-files": "yarn run -T concurrently 'yarn:lint:generated-files:*'",
|
|
75
75
|
"lint:generated-files:css-custom-medias": "yarn run -T tsc scripts/generateCSSCustomMedias.mjs --checkJs --module ESNext --moduleResolution node --resolveJsonModule --allowSyntheticDefaultImports --jsx react-jsx --noEmit && yarn run generate:css-custom-medias && git diff --exit-code src/styles/customMedias.generated.css",
|
|
76
76
|
"lint:generated-files:css-modules": "yarn run generate:css-modules",
|
|
77
|
-
"storybook": "bash -c 'source .env && yarn run -T
|
|
78
|
-
"storybook:build": "yarn run -T
|
|
77
|
+
"storybook": "bash -c 'source .env && yarn run -T storybook dev -p ${STORYBOOK_DEV_PORT:=6006}'",
|
|
78
|
+
"storybook:build": "yarn run -T storybook build",
|
|
79
79
|
"generate": "yarn run -T concurrently 'yarn:generate:*'",
|
|
80
80
|
"generate:css-custom-medias": "node scripts/generateCSSCustomMedias.mjs",
|
|
81
81
|
"generate:css-modules": "yarn run -T hcm 'src/**/*.css'"
|
|
@@ -93,12 +93,9 @@
|
|
|
93
93
|
"date-fns": "^4.1.0"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
-
"@storybook/react": "8.6.12",
|
|
97
|
-
"@storybook/react-webpack5": "8.6.12",
|
|
98
96
|
"@types/node": "*",
|
|
99
97
|
"react": "^18.3.1",
|
|
100
98
|
"react-dom": "^18.3.1",
|
|
101
|
-
"storybook": "8.6.12",
|
|
102
99
|
"ts-node": "*"
|
|
103
100
|
},
|
|
104
101
|
"size-limit": [
|
|
@@ -30,7 +30,10 @@ export interface ActionSheetProps
|
|
|
30
30
|
SharedDropdownProps,
|
|
31
31
|
'toggleRef' | 'popupOffsetDistance' | 'placement' | 'allowClickPropagation'
|
|
32
32
|
>,
|
|
33
|
-
Omit<
|
|
33
|
+
Omit<
|
|
34
|
+
UseFocusTrapProps,
|
|
35
|
+
'onClose' | 'mount' | 'disabled' | 'captureEscapeKeyboardEvent' | 'mutationObserverOptions'
|
|
36
|
+
>,
|
|
34
37
|
Omit<React.HTMLAttributes<HTMLDivElement>, 'autoFocus' | 'title'> {
|
|
35
38
|
/**
|
|
36
39
|
* Заголовок всплыващего окна.
|
|
@@ -155,8 +155,8 @@ const _getScroll = ({
|
|
|
155
155
|
? [-parseFloat(elementStyles.left || '0'), -parseFloat(elementStyles.top || '0')]
|
|
156
156
|
: [xOffset, yOffset];
|
|
157
157
|
return {
|
|
158
|
-
x: scrollLeft,
|
|
159
|
-
y: customCalcY(scrollTop),
|
|
158
|
+
x: scrollLeft || 0,
|
|
159
|
+
y: customCalcY(scrollTop) || 0,
|
|
160
160
|
};
|
|
161
161
|
};
|
|
162
162
|
|
|
@@ -5,14 +5,14 @@ import { Icon24Cancel, Icon24Chevron, Icon24Dismiss, Icon24DismissDark } from '@
|
|
|
5
5
|
import { classNames, hasReactNode } from '@vkontakte/vkjs';
|
|
6
6
|
import { usePlatform } from '../../hooks/usePlatform';
|
|
7
7
|
import { IconButton } from '../IconButton/IconButton';
|
|
8
|
-
import { Tappable, type
|
|
8
|
+
import { Tappable, type TappableOmitProps } from '../Tappable/Tappable';
|
|
9
9
|
import { Headline } from '../Typography/Headline/Headline';
|
|
10
10
|
import { Subhead } from '../Typography/Subhead/Subhead';
|
|
11
11
|
import { Text } from '../Typography/Text/Text';
|
|
12
12
|
import { Title } from '../Typography/Title/Title';
|
|
13
13
|
import styles from './Banner.module.css';
|
|
14
14
|
|
|
15
|
-
export interface BannerProps extends Omit<
|
|
15
|
+
export interface BannerProps extends Omit<TappableOmitProps, 'title' | 'size'> {
|
|
16
16
|
/**
|
|
17
17
|
* Тип баннера.
|
|
18
18
|
*/
|
|
@@ -6,7 +6,7 @@ import { useAdaptivity } from '../../hooks/useAdaptivity';
|
|
|
6
6
|
import { usePlatform } from '../../hooks/usePlatform';
|
|
7
7
|
import type { HasAlign } from '../../types';
|
|
8
8
|
import { Spinner } from '../Spinner/Spinner';
|
|
9
|
-
import { Tappable, type
|
|
9
|
+
import { Tappable, type TappableOmitProps } from '../Tappable/Tappable';
|
|
10
10
|
import '../Tappable/Tappable.module.css';
|
|
11
11
|
import '../Spinner/Spinner.module.css';
|
|
12
12
|
import styles from './Button.module.css';
|
|
@@ -83,7 +83,7 @@ export interface VKUIButtonProps extends HasAlign {
|
|
|
83
83
|
rounded?: boolean;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export interface ButtonProps extends Omit<
|
|
86
|
+
export interface ButtonProps extends Omit<TappableOmitProps, 'size'>, VKUIButtonProps {}
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
89
|
* @see https://vkcom.github.io/VKUI/#/Button
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { classNames } from '@vkontakte/vkjs';
|
|
4
|
+
import { classNames, isSameDate } from '@vkontakte/vkjs';
|
|
5
5
|
import { isSameDay, isSameMonth, startOfMonth } from 'date-fns';
|
|
6
6
|
import { useCalendar } from '../../hooks/useCalendar';
|
|
7
7
|
import { useCustomEnsuredControl } from '../../hooks/useEnsuredControl';
|
|
@@ -220,8 +220,6 @@ export const Calendar = ({
|
|
|
220
220
|
setNextMonth,
|
|
221
221
|
focusedDay,
|
|
222
222
|
setFocusedDay,
|
|
223
|
-
focusableDay,
|
|
224
|
-
setFocusableDay,
|
|
225
223
|
isDayFocused,
|
|
226
224
|
isDayDisabled,
|
|
227
225
|
isMonthDisabled,
|
|
@@ -237,6 +235,8 @@ export const Calendar = ({
|
|
|
237
235
|
minDateTime,
|
|
238
236
|
maxDateTime,
|
|
239
237
|
});
|
|
238
|
+
// соотвествует дню, на котором можно сфокусироваться с помощью Tab
|
|
239
|
+
const [focusableDay, setFocusableDay] = React.useState<Date>();
|
|
240
240
|
|
|
241
241
|
useIsomorphicLayoutEffect(() => {
|
|
242
242
|
if (timeZonedValue) {
|
|
@@ -291,10 +291,8 @@ export const Calendar = ({
|
|
|
291
291
|
actualDate = clamp(actualDate, { min: minDateTime, max: maxDateTime });
|
|
292
292
|
}
|
|
293
293
|
updateValue(actualDate);
|
|
294
|
-
setFocusedDay(actualDate);
|
|
295
|
-
setFocusableDay(actualDate);
|
|
296
294
|
},
|
|
297
|
-
[timeZonedValue, updateValue, maxDateTime, minDateTime
|
|
295
|
+
[timeZonedValue, updateValue, maxDateTime, minDateTime],
|
|
298
296
|
);
|
|
299
297
|
|
|
300
298
|
const onDayFocus = React.useCallback(
|
|
@@ -304,8 +302,11 @@ export const Calendar = ({
|
|
|
304
302
|
}
|
|
305
303
|
|
|
306
304
|
setFocusedDay(date);
|
|
305
|
+
if (!focusableDay || !isSameDate(date, focusableDay)) {
|
|
306
|
+
setFocusableDay(date);
|
|
307
|
+
}
|
|
307
308
|
},
|
|
308
|
-
[focusedDay, setFocusedDay],
|
|
309
|
+
[focusableDay, focusedDay, setFocusedDay],
|
|
309
310
|
);
|
|
310
311
|
|
|
311
312
|
// activeDay это день в календаре соответствующий значению в инпуте
|
|
@@ -7,16 +7,13 @@ import {
|
|
|
7
7
|
isAfter,
|
|
8
8
|
isBefore,
|
|
9
9
|
isSameDay,
|
|
10
|
-
isSameMonth,
|
|
11
10
|
isWithinInterval,
|
|
12
11
|
startOfDay,
|
|
13
12
|
subMonths,
|
|
14
13
|
} from 'date-fns';
|
|
15
14
|
import { useCalendar } from '../../hooks/useCalendar';
|
|
16
15
|
import { useCustomEnsuredControl } from '../../hooks/useEnsuredControl';
|
|
17
|
-
import {
|
|
18
|
-
import { isFirstDay, isLastDay, navigateDate, NAVIGATION_KEYS } from '../../lib/calendar';
|
|
19
|
-
import { isHTMLElement } from '../../lib/dom';
|
|
16
|
+
import { isFirstDay, isLastDay } from '../../lib/calendar';
|
|
20
17
|
import type { HTMLAttributesWithRootRef } from '../../types';
|
|
21
18
|
import {
|
|
22
19
|
CalendarDays,
|
|
@@ -29,9 +26,11 @@ import {
|
|
|
29
26
|
type CalendarHeaderTestsProps,
|
|
30
27
|
} from '../CalendarHeader/CalendarHeader';
|
|
31
28
|
import { RootComponent } from '../RootComponent/RootComponent';
|
|
29
|
+
import type { DateRangeType } from './types';
|
|
30
|
+
import { useCalendarKeyboardNavigation, useIsDayFocusable } from './utils';
|
|
32
31
|
import styles from './CalendarRange.module.css';
|
|
33
32
|
|
|
34
|
-
export type DateRangeType
|
|
33
|
+
export type { DateRangeType };
|
|
35
34
|
|
|
36
35
|
export type CalendarRangeTestsProps = CalendarDaysTestsProps & {
|
|
37
36
|
/**
|
|
@@ -81,6 +80,12 @@ export interface CalendarRangeProps
|
|
|
81
80
|
disablePickers?: boolean;
|
|
82
81
|
/**
|
|
83
82
|
* `aria-label` для изменения дня.
|
|
83
|
+
*
|
|
84
|
+
* @deprecated Since 7.4.0.
|
|
85
|
+
*
|
|
86
|
+
* Будет удалeно в **VKUI v8**. Использовалось для задания aria-label для контейнера дней в календаре.
|
|
87
|
+
* Теперь этот контейнер является таблицей (с помощью role="grid") и
|
|
88
|
+
* в aria-label рендерится текущий открытый в календаре месяц и год.
|
|
84
89
|
*/
|
|
85
90
|
changeDayLabel?: string;
|
|
86
91
|
/**
|
|
@@ -113,7 +118,7 @@ const getIsDaySelected = (day: Date, value?: DateRangeType | null) => {
|
|
|
113
118
|
* @see https://vkcom.github.io/VKUI/#/CalendarRange
|
|
114
119
|
*/
|
|
115
120
|
export const CalendarRange = ({
|
|
116
|
-
value: valueProp,
|
|
121
|
+
'value': valueProp,
|
|
117
122
|
defaultValue,
|
|
118
123
|
onChange,
|
|
119
124
|
disablePast,
|
|
@@ -125,7 +130,7 @@ export const CalendarRange = ({
|
|
|
125
130
|
nextMonthLabel = 'Следующий месяц',
|
|
126
131
|
changeMonthLabel = 'Изменить месяц',
|
|
127
132
|
changeYearLabel = 'Изменить год',
|
|
128
|
-
|
|
133
|
+
'aria-label': ariaLabel = 'Календарь',
|
|
129
134
|
prevMonthIcon,
|
|
130
135
|
nextMonthIcon,
|
|
131
136
|
listenDayChangesForUpdate,
|
|
@@ -156,7 +161,6 @@ export const CalendarRange = ({
|
|
|
156
161
|
setFocusedDay,
|
|
157
162
|
isDayFocused,
|
|
158
163
|
isDayDisabled,
|
|
159
|
-
resetSelectedDay,
|
|
160
164
|
isMonthDisabled,
|
|
161
165
|
isYearDisabled,
|
|
162
166
|
} = useCalendar({ value, disableFuture, disablePast, shouldDisableDate });
|
|
@@ -164,33 +168,19 @@ export const CalendarRange = ({
|
|
|
164
168
|
const [hintedDate, setHintedDate] = React.useState<DateRangeType>();
|
|
165
169
|
const secondViewDate = addMonths(viewDate, 1);
|
|
166
170
|
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
) {
|
|
181
|
-
setViewDate(newFocusedDay);
|
|
182
|
-
}
|
|
183
|
-
setFocusedDay(newFocusedDay);
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {
|
|
188
|
-
event.preventDefault();
|
|
189
|
-
event.target.click?.();
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
[focusedDay, setFocusedDay, setViewDate, value, viewDate],
|
|
193
|
-
);
|
|
171
|
+
const {
|
|
172
|
+
focusableDayOnFirstCalendar,
|
|
173
|
+
focusableDayOnSecondCalendar,
|
|
174
|
+
handleFirstCalendarKeyDown,
|
|
175
|
+
handleSecondCalendarKeyDown,
|
|
176
|
+
handleDayFocus,
|
|
177
|
+
} = useCalendarKeyboardNavigation({
|
|
178
|
+
focusedDay,
|
|
179
|
+
setFocusedDay,
|
|
180
|
+
value,
|
|
181
|
+
viewDates: [viewDate, secondViewDate],
|
|
182
|
+
setViewDate,
|
|
183
|
+
});
|
|
194
184
|
|
|
195
185
|
const getNewValue = React.useCallback(
|
|
196
186
|
(date: Date): DateRangeType => {
|
|
@@ -270,8 +260,41 @@ export const CalendarRange = ({
|
|
|
270
260
|
[setViewDate],
|
|
271
261
|
);
|
|
272
262
|
|
|
263
|
+
const isDayFocusableInFirstCalendar = useIsDayFocusable({
|
|
264
|
+
value,
|
|
265
|
+
focusableDayOnFirstCalendar,
|
|
266
|
+
focusableDayOnSecondCalendar,
|
|
267
|
+
viewDate,
|
|
268
|
+
isDayActive,
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
const isDayFocusableInSecondCalendar = useIsDayFocusable({
|
|
272
|
+
value,
|
|
273
|
+
focusableDayOnFirstCalendar,
|
|
274
|
+
focusableDayOnSecondCalendar,
|
|
275
|
+
viewDate: secondViewDate,
|
|
276
|
+
isDayActive,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const onDayFocus = React.useCallback(
|
|
280
|
+
(date: Date) => {
|
|
281
|
+
if (focusedDay && isSameDay(focusedDay, date)) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
setFocusedDay(date);
|
|
286
|
+
handleDayFocus(date);
|
|
287
|
+
},
|
|
288
|
+
[focusedDay, handleDayFocus, setFocusedDay],
|
|
289
|
+
);
|
|
290
|
+
|
|
273
291
|
return (
|
|
274
|
-
<RootComponent
|
|
292
|
+
<RootComponent
|
|
293
|
+
aria-label={ariaLabel}
|
|
294
|
+
{...props}
|
|
295
|
+
baseClassName={styles.host}
|
|
296
|
+
getRootRef={getRootRef}
|
|
297
|
+
>
|
|
275
298
|
<div className={styles.inner}>
|
|
276
299
|
<CalendarHeader
|
|
277
300
|
viewDate={viewDate}
|
|
@@ -293,8 +316,10 @@ export const CalendarRange = ({
|
|
|
293
316
|
viewDate={viewDate}
|
|
294
317
|
value={value}
|
|
295
318
|
weekStartsOn={weekStartsOn}
|
|
296
|
-
onKeyDown={
|
|
319
|
+
onKeyDown={handleFirstCalendarKeyDown}
|
|
320
|
+
onDayFocus={onDayFocus}
|
|
297
321
|
isDayFocused={isDayFocused}
|
|
322
|
+
isDayFocusable={isDayFocusableInFirstCalendar}
|
|
298
323
|
onDayChange={onDayChange}
|
|
299
324
|
isDaySelected={isDaySelected}
|
|
300
325
|
isDayActive={isDayActive}
|
|
@@ -308,7 +333,6 @@ export const CalendarRange = ({
|
|
|
308
333
|
isDayDisabled={isDayDisabled}
|
|
309
334
|
listenDayChangesForUpdate={listenDayChangesForUpdate}
|
|
310
335
|
renderDayContent={renderDayContent}
|
|
311
|
-
aria-label={changeDayLabel}
|
|
312
336
|
dayTestId={dayTestId}
|
|
313
337
|
/>
|
|
314
338
|
</div>
|
|
@@ -333,9 +357,10 @@ export const CalendarRange = ({
|
|
|
333
357
|
viewDate={secondViewDate}
|
|
334
358
|
value={value}
|
|
335
359
|
weekStartsOn={weekStartsOn}
|
|
336
|
-
|
|
337
|
-
|
|
360
|
+
onKeyDown={handleSecondCalendarKeyDown}
|
|
361
|
+
onDayFocus={onDayFocus}
|
|
338
362
|
isDayFocused={isDayFocused}
|
|
363
|
+
isDayFocusable={isDayFocusableInSecondCalendar}
|
|
339
364
|
onDayChange={onDayChange}
|
|
340
365
|
isDaySelected={isDaySelected}
|
|
341
366
|
isDayActive={isDayActive}
|
|
@@ -349,8 +374,6 @@ export const CalendarRange = ({
|
|
|
349
374
|
isDayDisabled={isDayDisabled}
|
|
350
375
|
listenDayChangesForUpdate={listenDayChangesForUpdate}
|
|
351
376
|
renderDayContent={renderDayContent}
|
|
352
|
-
tabIndex={0}
|
|
353
|
-
onBlur={resetSelectedDay}
|
|
354
377
|
dayTestId={dayTestId}
|
|
355
378
|
/>
|
|
356
379
|
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type DateRangeType = [Date | null, Date | null];
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { isSameDate } from '@vkontakte/vkjs';
|
|
3
|
+
import { isAfter, isBefore, isSameDay, isSameMonth, startOfMonth } from 'date-fns';
|
|
4
|
+
import { Keys, pressedKey } from '../../lib/accessibility';
|
|
5
|
+
import { navigateDate, NAVIGATION_KEYS } from '../../lib/calendar';
|
|
6
|
+
import { isHTMLElement } from '../../lib/dom';
|
|
7
|
+
import type { DateRangeType } from './types';
|
|
8
|
+
|
|
9
|
+
export function useCalendarKeyboardNavigation({
|
|
10
|
+
focusedDay,
|
|
11
|
+
value,
|
|
12
|
+
setFocusedDay,
|
|
13
|
+
viewDates: [firstCalendarViewDate, secondCalendarViewDate],
|
|
14
|
+
setViewDate,
|
|
15
|
+
}: {
|
|
16
|
+
focusedDay: Date | undefined;
|
|
17
|
+
setViewDate: (date: Date) => void;
|
|
18
|
+
setFocusedDay: React.Dispatch<React.SetStateAction<Date | undefined>>;
|
|
19
|
+
viewDates: [Date, Date];
|
|
20
|
+
value: DateRangeType | null | undefined;
|
|
21
|
+
}) {
|
|
22
|
+
// соотвествует дню, на котором можно сфокусироваться с помощью Tab
|
|
23
|
+
const [focusableDayOnFirstCalendar, setFocusableDayOnFirstCalendar] = React.useState<Date>();
|
|
24
|
+
const [focusableDayOnSecondCalendar, setFocusableDayOnSecondCalendar] = React.useState<Date>();
|
|
25
|
+
|
|
26
|
+
const handleCalendarKeyDown = React.useCallback(
|
|
27
|
+
(event: React.KeyboardEvent, isFirst: boolean) => {
|
|
28
|
+
const key = pressedKey(event);
|
|
29
|
+
if (!key) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (NAVIGATION_KEYS.includes(key)) {
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
|
|
36
|
+
const newFocusedDay = navigateDate(focusedDay ?? value?.[0], key);
|
|
37
|
+
|
|
38
|
+
if (
|
|
39
|
+
newFocusedDay &&
|
|
40
|
+
!isSameMonth(newFocusedDay, firstCalendarViewDate) &&
|
|
41
|
+
!isSameMonth(newFocusedDay, secondCalendarViewDate)
|
|
42
|
+
) {
|
|
43
|
+
setViewDate(newFocusedDay);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (isFirst) {
|
|
47
|
+
if (isSameMonth(newFocusedDay, firstCalendarViewDate)) {
|
|
48
|
+
setFocusableDayOnFirstCalendar(newFocusedDay);
|
|
49
|
+
} else if (isAfter(newFocusedDay, firstCalendarViewDate)) {
|
|
50
|
+
setFocusableDayOnSecondCalendar(newFocusedDay);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
if (isSameMonth(newFocusedDay, secondCalendarViewDate)) {
|
|
54
|
+
setFocusableDayOnSecondCalendar(newFocusedDay);
|
|
55
|
+
} else if (isBefore(newFocusedDay, secondCalendarViewDate)) {
|
|
56
|
+
setFocusableDayOnFirstCalendar(newFocusedDay);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setFocusedDay(newFocusedDay);
|
|
61
|
+
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (key === Keys.TAB) {
|
|
66
|
+
setFocusedDay(undefined);
|
|
67
|
+
if (isFirst) {
|
|
68
|
+
setFocusableDayOnFirstCalendar(focusedDay);
|
|
69
|
+
} else {
|
|
70
|
+
setFocusableDayOnSecondCalendar(focusedDay);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
event.target.click?.();
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[focusedDay, value, firstCalendarViewDate, secondCalendarViewDate, setFocusedDay, setViewDate],
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const handleFirstCalendarKeyDown = React.useCallback(
|
|
85
|
+
(event: React.KeyboardEvent) => {
|
|
86
|
+
handleCalendarKeyDown(event, true);
|
|
87
|
+
},
|
|
88
|
+
[handleCalendarKeyDown],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const handleSecondCalendarKeyDown = React.useCallback(
|
|
92
|
+
(event: React.KeyboardEvent) => {
|
|
93
|
+
handleCalendarKeyDown(event, false);
|
|
94
|
+
},
|
|
95
|
+
[handleCalendarKeyDown],
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const handleDayFocus = React.useCallback(
|
|
99
|
+
(value: Date) => {
|
|
100
|
+
if (
|
|
101
|
+
isSameMonth(firstCalendarViewDate, value) &&
|
|
102
|
+
(!focusableDayOnFirstCalendar || !isSameDate(focusableDayOnFirstCalendar, value))
|
|
103
|
+
) {
|
|
104
|
+
setFocusableDayOnFirstCalendar(value);
|
|
105
|
+
}
|
|
106
|
+
if (
|
|
107
|
+
isSameMonth(secondCalendarViewDate, value) &&
|
|
108
|
+
(!focusableDayOnSecondCalendar || !isSameDate(focusableDayOnSecondCalendar, value))
|
|
109
|
+
) {
|
|
110
|
+
setFocusableDayOnSecondCalendar(value);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
[
|
|
114
|
+
firstCalendarViewDate,
|
|
115
|
+
focusableDayOnFirstCalendar,
|
|
116
|
+
focusableDayOnSecondCalendar,
|
|
117
|
+
secondCalendarViewDate,
|
|
118
|
+
],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
focusableDayOnFirstCalendar,
|
|
123
|
+
focusableDayOnSecondCalendar,
|
|
124
|
+
handleFirstCalendarKeyDown,
|
|
125
|
+
handleSecondCalendarKeyDown,
|
|
126
|
+
handleDayFocus,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Возвращает функцию, которая позволяет проверить является ли день в календаре днём на который
|
|
132
|
+
* можно попасть с помощью Tab.
|
|
133
|
+
* Единственный день в таблице календаря у которого есть tabIndex="0"
|
|
134
|
+
* Чтобы на него можно было попасть из заголовка календаря.
|
|
135
|
+
*/
|
|
136
|
+
export function useIsDayFocusable({
|
|
137
|
+
value,
|
|
138
|
+
focusableDayOnFirstCalendar,
|
|
139
|
+
focusableDayOnSecondCalendar,
|
|
140
|
+
viewDate,
|
|
141
|
+
isDayActive,
|
|
142
|
+
}: {
|
|
143
|
+
value: DateRangeType | null | undefined;
|
|
144
|
+
focusableDayOnFirstCalendar: Date | undefined;
|
|
145
|
+
focusableDayOnSecondCalendar: Date | undefined;
|
|
146
|
+
viewDate: Date;
|
|
147
|
+
isDayActive: (date: Date) => boolean;
|
|
148
|
+
}) {
|
|
149
|
+
const isValueVisibleOnCalendar = Boolean(
|
|
150
|
+
value &&
|
|
151
|
+
((value[0] && isSameMonth(value[0], viewDate)) ||
|
|
152
|
+
(value[1] && isSameMonth(value[1], viewDate))),
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
const isCalendarHasFocusableDay = Boolean(
|
|
156
|
+
(focusableDayOnFirstCalendar && isSameMonth(focusableDayOnFirstCalendar, viewDate)) ||
|
|
157
|
+
(focusableDayOnSecondCalendar && isSameMonth(focusableDayOnSecondCalendar, viewDate)),
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const isDayFocusable = React.useCallback(
|
|
161
|
+
(day: Date) => {
|
|
162
|
+
// если focusableDay день находится среди дней открытого сейчас месяца, то такой день получит tabIndex="0",
|
|
163
|
+
if (isCalendarHasFocusableDay) {
|
|
164
|
+
return Boolean(
|
|
165
|
+
(focusableDayOnFirstCalendar && isSameDay(focusableDayOnFirstCalendar, day)) ||
|
|
166
|
+
(focusableDayOnSecondCalendar && isSameDay(focusableDayOnSecondCalendar, day)),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// при открытии календаря focusableDay не определён,
|
|
171
|
+
// поэтому tabIndex="0" будет у дня, соответствующего дню в инпуте
|
|
172
|
+
if (isValueVisibleOnCalendar) {
|
|
173
|
+
return isDayActive(day);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// при переключении месяца любая навигация с помощью Tab начинается
|
|
177
|
+
// с первого дня месяца.
|
|
178
|
+
return isSameDay(startOfMonth(viewDate), day);
|
|
179
|
+
},
|
|
180
|
+
[
|
|
181
|
+
isCalendarHasFocusableDay,
|
|
182
|
+
isValueVisibleOnCalendar,
|
|
183
|
+
viewDate,
|
|
184
|
+
isDayActive,
|
|
185
|
+
focusableDayOnFirstCalendar,
|
|
186
|
+
focusableDayOnSecondCalendar,
|
|
187
|
+
],
|
|
188
|
+
);
|
|
189
|
+
return isDayFocusable;
|
|
190
|
+
}
|
|
@@ -3,7 +3,7 @@ import { hasReactNode } from '@vkontakte/vkjs';
|
|
|
3
3
|
import type { HasRootRef } from '../../types';
|
|
4
4
|
import { SelectionControl } from '../SelectionControl/SelectionControl';
|
|
5
5
|
import { SelectionControlLabel } from '../SelectionControl/SelectionControlLabel/SelectionControlLabel';
|
|
6
|
-
import type {
|
|
6
|
+
import type { TappableOmitProps } from '../Tappable/Tappable';
|
|
7
7
|
import { CheckboxInput, type CheckboxInputProps } from './CheckboxInput/CheckboxInput';
|
|
8
8
|
import { CheckboxSimple } from './CheckboxSimple/CheckboxSimple';
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ export interface CheckboxProps
|
|
|
11
11
|
extends Omit<CheckboxInputProps, 'getRootRef'>,
|
|
12
12
|
HasRootRef<HTMLLabelElement>,
|
|
13
13
|
Pick<
|
|
14
|
-
|
|
14
|
+
TappableOmitProps,
|
|
15
15
|
'hoverMode' | 'activeMode' | 'hasHover' | 'hasActive' | 'focusVisibleMode'
|
|
16
16
|
> {
|
|
17
17
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { escapeRegExp } from '@vkontakte/vkjs';
|
|
2
3
|
import { useCustomEnsuredControl, useEnsuredControl } from '../../hooks/useEnsuredControl';
|
|
3
4
|
import { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';
|
|
4
5
|
import { simulateReactInput, type SimulateReactInputTargetState } from '../../lib/react';
|
|
@@ -36,6 +37,25 @@ export const transformValue = <O extends ChipOption>(
|
|
|
36
37
|
value: getOptionValue(option),
|
|
37
38
|
}));
|
|
38
39
|
|
|
40
|
+
function getRegExpFromArray(separators: string[]) {
|
|
41
|
+
const validSeparators = separators.filter((s) => s.length > 0);
|
|
42
|
+
if (validSeparators.length === 0) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const escaped = validSeparators.map((s) => escapeRegExp(s));
|
|
46
|
+
return new RegExp(`(?:${escaped.join('|')})`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getRegexFromDelimiter(delimiter: string | RegExp | string[]): RegExp | null {
|
|
50
|
+
if (delimiter instanceof RegExp) {
|
|
51
|
+
return delimiter;
|
|
52
|
+
}
|
|
53
|
+
if (typeof delimiter === 'string') {
|
|
54
|
+
return new RegExp(escapeRegExp(delimiter));
|
|
55
|
+
}
|
|
56
|
+
return getRegExpFromArray(delimiter);
|
|
57
|
+
}
|
|
58
|
+
|
|
39
59
|
interface ToggleOption<O extends ChipOption> {
|
|
40
60
|
(optionsForAdd: Array<O | string>, isNewValue: true): void;
|
|
41
61
|
(optionsForRemove: Array<O | ChipOptionValue>, isNewValue: false): void;
|
|
@@ -178,13 +198,14 @@ export const useChipsInput = <O extends ChipOption>({
|
|
|
178
198
|
const onInputChange = React.useCallback(
|
|
179
199
|
(e: React.ChangeEvent<HTMLInputElement>, canCreate = true) => {
|
|
180
200
|
const newInputValue = e.target.value;
|
|
181
|
-
|
|
201
|
+
const delimiterRegex = delimiter ? getRegexFromDelimiter(delimiter) : null;
|
|
202
|
+
if (!delimiterRegex || !delimiterRegex.test(newInputValue) || !canCreate) {
|
|
182
203
|
setInputChange(e);
|
|
183
204
|
return;
|
|
184
205
|
}
|
|
185
206
|
const values = newInputValue
|
|
186
207
|
.trim()
|
|
187
|
-
.split(
|
|
208
|
+
.split(delimiterRegex)
|
|
188
209
|
.map((v) => v.trim())
|
|
189
210
|
.filter(Boolean);
|
|
190
211
|
|
|
@@ -128,6 +128,10 @@ export interface UseChipsInputBaseProps<O extends ChipOption = ChipOption> {
|
|
|
128
128
|
onInputChange?: OnInputChange;
|
|
129
129
|
/**
|
|
130
130
|
* Символ или строка, которая будет использоваться как разделитель для автоматического создания опций из текста, введенного в поле ввода.
|
|
131
|
+
* Принимает:
|
|
132
|
+
* - `string` - простая строка
|
|
133
|
+
* - `RegExp` - регулярное выражение
|
|
134
|
+
* - `string[]` - массив строк, по которым нужно разелять ввод.
|
|
131
135
|
*
|
|
132
136
|
* Работает в двух сценариях:
|
|
133
137
|
* 1. При вводе разделителя - текст до разделителя автоматически преобразуется в новую опцию.
|
|
@@ -138,7 +142,7 @@ export interface UseChipsInputBaseProps<O extends ChipOption = ChipOption> {
|
|
|
138
142
|
* Например, при `delimiter=","` вставка "опция1,опция2,опция3" создаст
|
|
139
143
|
* три отдельные опции: "опция1", "опция2" и "опция3".
|
|
140
144
|
*/
|
|
141
|
-
delimiter?: string;
|
|
145
|
+
delimiter?: string | RegExp | string[];
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
/**
|
|
@@ -9,7 +9,12 @@ import styles from './Clickable.module.css';
|
|
|
9
9
|
export interface ClickableProps<T = HTMLElement>
|
|
10
10
|
extends RootComponentProps<T>,
|
|
11
11
|
FocusVisibleModeProps,
|
|
12
|
-
StateProps {
|
|
12
|
+
StateProps {
|
|
13
|
+
/**
|
|
14
|
+
* Компонент который будет при передаче `onClick`. По умолчанию `"div"`.
|
|
15
|
+
*/
|
|
16
|
+
DefaultComponent?: React.ElementType;
|
|
17
|
+
}
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* Некликабельный компонент. Отключаем возможность нажимать на компонент.
|
|
@@ -27,8 +32,10 @@ const NonClickable = <T,>({
|
|
|
27
32
|
activated,
|
|
28
33
|
activeEffectDelay,
|
|
29
34
|
focusVisibleMode,
|
|
35
|
+
DefaultComponent,
|
|
36
|
+
Component,
|
|
30
37
|
...restProps
|
|
31
|
-
}: ClickableProps<T>) => <RootComponent {...restProps} />;
|
|
38
|
+
}: ClickableProps<T>) => <RootComponent Component={Component || DefaultComponent} {...restProps} />;
|
|
32
39
|
|
|
33
40
|
/**
|
|
34
41
|
* Проверяем, является ли компонент кликабельным.
|
|
@@ -56,11 +63,12 @@ export function checkClickable<T>(props: ClickableProps<T>): boolean {
|
|
|
56
63
|
*/
|
|
57
64
|
function component<T>({
|
|
58
65
|
Component,
|
|
66
|
+
DefaultComponent = 'div',
|
|
59
67
|
onClick,
|
|
60
68
|
onClickCapture,
|
|
61
69
|
href,
|
|
62
70
|
disabled,
|
|
63
|
-
}:
|
|
71
|
+
}: ClickableProps<T>): RootComponentProps<T> {
|
|
64
72
|
if (Component !== undefined) {
|
|
65
73
|
return { Component, disabled };
|
|
66
74
|
} else if (href !== undefined) {
|
|
@@ -83,7 +91,7 @@ function component<T>({
|
|
|
83
91
|
};
|
|
84
92
|
} else if (onClick !== undefined || onClickCapture !== undefined) {
|
|
85
93
|
return {
|
|
86
|
-
Component:
|
|
94
|
+
Component: DefaultComponent,
|
|
87
95
|
role: 'button',
|
|
88
96
|
...(disabled ? { 'aria-disabled': true } : { tabIndex: 0 }),
|
|
89
97
|
};
|