@vkontakte/vkui 7.3.8 → 7.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/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/IconButton/IconButton.js.map +1 -1
- 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/IconButton/IconButton.tsx +2 -2
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/CalendarRange/CalendarRange.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n addMonths,\n endOfDay,\n isAfter,\n isBefore,\n isSameDay,\n isSameMonth,\n isWithinInterval,\n startOfDay,\n subMonths,\n} from 'date-fns';\nimport { useCalendar } from '../../hooks/useCalendar';\nimport { useCustomEnsuredControl } from '../../hooks/useEnsuredControl';\nimport { Keys, pressedKey } from '../../lib/accessibility';\nimport { isFirstDay, isLastDay, navigateDate, NAVIGATION_KEYS } from '../../lib/calendar';\nimport { isHTMLElement } from '../../lib/dom';\nimport type { HTMLAttributesWithRootRef } from '../../types';\nimport {\n CalendarDays,\n type CalendarDaysProps,\n type CalendarDaysTestsProps,\n} from '../CalendarDays/CalendarDays';\nimport {\n CalendarHeader,\n type CalendarHeaderProps,\n type CalendarHeaderTestsProps,\n} from '../CalendarHeader/CalendarHeader';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport styles from './CalendarRange.module.css';\n\nexport type DateRangeType = [Date | null, Date | null];\n\nexport type CalendarRangeTestsProps = CalendarDaysTestsProps & {\n /**\n * Передает атрибуты `data-testid` для интерактивных элементов в заголовке календаря в левой части.\n */\n leftPartHeaderTestsData?: CalendarHeaderTestsProps;\n /**\n * Передает атрибуты `data-testid` для интерактивных элементов в заголовке календаря в правой части.\n */\n rightPartHeaderTestsData?: CalendarHeaderTestsProps;\n};\n\nexport interface CalendarRangeProps\n extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange' | 'defaultValue'>,\n Pick<\n CalendarHeaderProps,\n | 'prevMonthLabel'\n | 'nextMonthLabel'\n | 'changeMonthLabel'\n | 'changeYearLabel'\n | 'prevMonthIcon'\n | 'nextMonthIcon'\n >,\n Pick<CalendarDaysProps, 'listenDayChangesForUpdate' | 'renderDayContent'>,\n CalendarRangeTestsProps {\n /**\n * Текущий выбранный промежуток.\n */\n value?: DateRangeType | null;\n /**\n * Начальный промежуток при монтировании.\n */\n defaultValue?: DateRangeType | null;\n /**\n * Запрещает выбор даты в прошлом.\n * Применяется, если не заданы `shouldDisableDate` и `disableFuture`.\n */\n disablePast?: boolean;\n /**\n * Запрещает выбор даты в будущем.\n * Применяется, если не задано `shouldDisableDate`.\n */\n disableFuture?: boolean;\n /**\n * Отключает селекторы выбора месяца/года.\n */\n disablePickers?: boolean;\n /**\n * `aria-label` для изменения дня.\n */\n changeDayLabel?: string;\n /**\n * День недели, с которого начинается неделя.\n */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /**\n * Обработчик изменения выбранного промежутка.\n */\n onChange?: (value: DateRangeType | undefined) => void; // TODO [>=8]: поменять тип на `(value?: DateRangeType | null) => void`\n /**\n * Функция для проверки запрета выбора даты.\n */\n shouldDisableDate?: (value: Date) => boolean;\n /**\n * @deprecated Свойство не используется.\n */\n onClose?: () => void;\n}\n\nconst getIsDaySelected = (day: Date, value?: DateRangeType | null) => {\n if (!value?.[0] || !value[1]) {\n return false;\n }\n\n return isWithinInterval(day, { start: startOfDay(value[0]), end: endOfDay(value[1]) });\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/CalendarRange\n */\nexport const CalendarRange = ({\n value: valueProp,\n defaultValue,\n onChange,\n disablePast,\n disableFuture,\n shouldDisableDate,\n weekStartsOn = 1,\n disablePickers,\n prevMonthLabel = 'Предыдущий месяц',\n nextMonthLabel = 'Следующий месяц',\n changeMonthLabel = 'Изменить месяц',\n changeYearLabel = 'Изменить год',\n changeDayLabel = 'Изменить день',\n prevMonthIcon,\n nextMonthIcon,\n listenDayChangesForUpdate,\n renderDayContent,\n dayTestId,\n leftPartHeaderTestsData,\n rightPartHeaderTestsData,\n getRootRef,\n ...props\n}: CalendarRangeProps): React.ReactNode => {\n const _onChange = React.useCallback(\n (newValue: DateRangeType | null | undefined) => onChange?.(newValue || undefined),\n [onChange],\n );\n\n const [value, updateValue] = useCustomEnsuredControl<DateRangeType | null | undefined>({\n value: valueProp,\n defaultValue,\n onChange: _onChange,\n });\n\n const {\n viewDate,\n setViewDate,\n setPrevMonth,\n setNextMonth,\n focusedDay,\n setFocusedDay,\n isDayFocused,\n isDayDisabled,\n resetSelectedDay,\n isMonthDisabled,\n isYearDisabled,\n } = useCalendar({ value, disableFuture, disablePast, shouldDisableDate });\n\n const [hintedDate, setHintedDate] = React.useState<DateRangeType>();\n const secondViewDate = addMonths(viewDate, 1);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n const key = pressedKey(event);\n\n if (key && NAVIGATION_KEYS.includes(key)) {\n event.preventDefault();\n\n const newFocusedDay = navigateDate(focusedDay ?? value?.[1], key);\n\n if (\n newFocusedDay &&\n !isSameMonth(newFocusedDay, viewDate) &&\n !isSameMonth(newFocusedDay, addMonths(viewDate, 1))\n ) {\n setViewDate(newFocusedDay);\n }\n setFocusedDay(newFocusedDay);\n return;\n }\n\n if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {\n event.preventDefault();\n event.target.click?.();\n }\n },\n [focusedDay, setFocusedDay, setViewDate, value, viewDate],\n );\n\n const getNewValue = React.useCallback(\n (date: Date): DateRangeType => {\n const isValueEmpty = !value || (value[0] === null && value[1] === null);\n const isRangeSelected = value && !!value[0] && !!value[1];\n if (isValueEmpty || isRangeSelected) {\n return [date, null];\n }\n\n const [start] = value;\n if (start && isSameDay(date, start)) {\n return [startOfDay(start), endOfDay(start)];\n } else if (start && isBefore(date, start)) {\n return [startOfDay(date), endOfDay(start)];\n } else if (start && isAfter(date, start)) {\n return [start, endOfDay(date)];\n }\n return value;\n },\n [value],\n );\n\n const onDayChange = React.useCallback(\n (date: Date) => {\n updateValue(getNewValue(date));\n setHintedDate(undefined);\n },\n [updateValue, getNewValue],\n );\n\n const isDaySelected = React.useCallback((day: Date) => getIsDaySelected(day, value), [value]);\n\n const isDayActive = React.useCallback(\n (day: Date) =>\n Boolean((value?.[0] && isSameDay(day, value[0])) || (value?.[1] && isSameDay(day, value[1]))),\n [value],\n );\n\n const isDaySelectionEnd = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isLastDay(day, dayOfWeek) || (value?.[1] && isSameDay(day, value[1]))),\n [value],\n );\n\n const isHintedDaySelectionEnd = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isLastDay(day, dayOfWeek) || (hintedDate?.[1] && isSameDay(day, hintedDate[1]))),\n [hintedDate],\n );\n\n const isDaySelectionStart = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isFirstDay(day, dayOfWeek) || (value?.[0] && isSameDay(day, value[0]))),\n [value],\n );\n\n const isHintedDaySelectionStart = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isFirstDay(day, dayOfWeek) || (hintedDate?.[0] && isSameDay(day, hintedDate[0]))),\n [hintedDate],\n );\n\n const onDayEnter = React.useCallback(\n (date: Date) => setHintedDate(getNewValue(date)),\n [setHintedDate, getNewValue],\n );\n\n const onDayLeave = React.useCallback(() => setHintedDate(undefined), [setHintedDate]);\n\n const isDayHinted = React.useCallback(\n (day: Date) => getIsDaySelected(day, hintedDate),\n [hintedDate],\n );\n\n const onRightPartViewDateChange = React.useCallback(\n (newDate: Date) => setViewDate(subMonths(newDate, 1)),\n [setViewDate],\n );\n\n return (\n <RootComponent {...props} baseClassName={styles.host} getRootRef={getRootRef}>\n <div className={styles.inner}>\n <CalendarHeader\n viewDate={viewDate}\n onChange={setViewDate}\n nextMonthHidden\n onPrevMonth={setPrevMonth}\n disablePickers={disablePickers}\n className={styles.header}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n prevMonthIcon={prevMonthIcon}\n isMonthDisabled={isMonthDisabled}\n isYearDisabled={isYearDisabled}\n {...leftPartHeaderTestsData}\n />\n <CalendarDays\n viewDate={viewDate}\n value={value}\n weekStartsOn={weekStartsOn}\n onKeyDown={handleKeyDown}\n isDayFocused={isDayFocused}\n onDayChange={onDayChange}\n isDaySelected={isDaySelected}\n isDayActive={isDayActive}\n isDaySelectionEnd={isDaySelectionEnd}\n isDaySelectionStart={isDaySelectionStart}\n isDayHinted={isDayHinted}\n onDayEnter={onDayEnter}\n onDayLeave={onDayLeave}\n isHintedDaySelectionEnd={isHintedDaySelectionEnd}\n isHintedDaySelectionStart={isHintedDaySelectionStart}\n isDayDisabled={isDayDisabled}\n listenDayChangesForUpdate={listenDayChangesForUpdate}\n renderDayContent={renderDayContent}\n aria-label={changeDayLabel}\n dayTestId={dayTestId}\n />\n </div>\n <div className={styles.inner}>\n <CalendarHeader\n viewDate={secondViewDate}\n onChange={onRightPartViewDateChange}\n prevMonthHidden\n onNextMonth={setNextMonth}\n disablePickers={disablePickers}\n className={styles.header}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n nextMonthIcon={nextMonthIcon}\n isMonthDisabled={isMonthDisabled}\n isYearDisabled={isYearDisabled}\n {...rightPartHeaderTestsData}\n />\n <CalendarDays\n viewDate={secondViewDate}\n value={value}\n weekStartsOn={weekStartsOn}\n aria-label={changeDayLabel}\n onKeyDown={handleKeyDown}\n isDayFocused={isDayFocused}\n onDayChange={onDayChange}\n isDaySelected={isDaySelected}\n isDayActive={isDayActive}\n isDaySelectionEnd={isDaySelectionEnd}\n isDaySelectionStart={isDaySelectionStart}\n isDayHinted={isDayHinted}\n onDayEnter={onDayEnter}\n onDayLeave={onDayLeave}\n isHintedDaySelectionEnd={isHintedDaySelectionEnd}\n isHintedDaySelectionStart={isHintedDaySelectionStart}\n isDayDisabled={isDayDisabled}\n listenDayChangesForUpdate={listenDayChangesForUpdate}\n renderDayContent={renderDayContent}\n tabIndex={0}\n onBlur={resetSelectedDay}\n dayTestId={dayTestId}\n />\n </div>\n </RootComponent>\n );\n};\n"],"names":["React","addMonths","endOfDay","isAfter","isBefore","isSameDay","isSameMonth","isWithinInterval","startOfDay","subMonths","useCalendar","useCustomEnsuredControl","Keys","pressedKey","isFirstDay","isLastDay","navigateDate","NAVIGATION_KEYS","isHTMLElement","CalendarDays","CalendarHeader","RootComponent","styles","getIsDaySelected","day","value","start","end","CalendarRange","valueProp","defaultValue","onChange","disablePast","disableFuture","shouldDisableDate","weekStartsOn","disablePickers","prevMonthLabel","nextMonthLabel","changeMonthLabel","changeYearLabel","changeDayLabel","prevMonthIcon","nextMonthIcon","listenDayChangesForUpdate","renderDayContent","dayTestId","leftPartHeaderTestsData","rightPartHeaderTestsData","getRootRef","props","_onChange","useCallback","newValue","undefined","updateValue","viewDate","setViewDate","setPrevMonth","setNextMonth","focusedDay","setFocusedDay","isDayFocused","isDayDisabled","resetSelectedDay","isMonthDisabled","isYearDisabled","hintedDate","setHintedDate","useState","secondViewDate","handleKeyDown","event","key","includes","preventDefault","newFocusedDay","ENTER","SPACE","target","click","getNewValue","date","isValueEmpty","isRangeSelected","onDayChange","isDaySelected","isDayActive","Boolean","isDaySelectionEnd","dayOfWeek","isHintedDaySelectionEnd","isDaySelectionStart","isHintedDaySelectionStart","onDayEnter","onDayLeave","isDayHinted","onRightPartViewDateChange","newDate","baseClassName","host","div","className","inner","nextMonthHidden","onPrevMonth","header","onKeyDown","aria-label","prevMonthHidden","onNextMonth","tabIndex","onBlur"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/CalendarRange/CalendarRange.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n addMonths,\n endOfDay,\n isAfter,\n isBefore,\n isSameDay,\n isWithinInterval,\n startOfDay,\n subMonths,\n} from 'date-fns';\nimport { useCalendar } from '../../hooks/useCalendar';\nimport { useCustomEnsuredControl } from '../../hooks/useEnsuredControl';\nimport { isFirstDay, isLastDay } from '../../lib/calendar';\nimport type { HTMLAttributesWithRootRef } from '../../types';\nimport {\n CalendarDays,\n type CalendarDaysProps,\n type CalendarDaysTestsProps,\n} from '../CalendarDays/CalendarDays';\nimport {\n CalendarHeader,\n type CalendarHeaderProps,\n type CalendarHeaderTestsProps,\n} from '../CalendarHeader/CalendarHeader';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport type { DateRangeType } from './types';\nimport { useCalendarKeyboardNavigation, useIsDayFocusable } from './utils';\nimport styles from './CalendarRange.module.css';\n\nexport type { DateRangeType };\n\nexport type CalendarRangeTestsProps = CalendarDaysTestsProps & {\n /**\n * Передает атрибуты `data-testid` для интерактивных элементов в заголовке календаря в левой части.\n */\n leftPartHeaderTestsData?: CalendarHeaderTestsProps;\n /**\n * Передает атрибуты `data-testid` для интерактивных элементов в заголовке календаря в правой части.\n */\n rightPartHeaderTestsData?: CalendarHeaderTestsProps;\n};\n\nexport interface CalendarRangeProps\n extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange' | 'defaultValue'>,\n Pick<\n CalendarHeaderProps,\n | 'prevMonthLabel'\n | 'nextMonthLabel'\n | 'changeMonthLabel'\n | 'changeYearLabel'\n | 'prevMonthIcon'\n | 'nextMonthIcon'\n >,\n Pick<CalendarDaysProps, 'listenDayChangesForUpdate' | 'renderDayContent'>,\n CalendarRangeTestsProps {\n /**\n * Текущий выбранный промежуток.\n */\n value?: DateRangeType | null;\n /**\n * Начальный промежуток при монтировании.\n */\n defaultValue?: DateRangeType | null;\n /**\n * Запрещает выбор даты в прошлом.\n * Применяется, если не заданы `shouldDisableDate` и `disableFuture`.\n */\n disablePast?: boolean;\n /**\n * Запрещает выбор даты в будущем.\n * Применяется, если не задано `shouldDisableDate`.\n */\n disableFuture?: boolean;\n /**\n * Отключает селекторы выбора месяца/года.\n */\n disablePickers?: boolean;\n /**\n * `aria-label` для изменения дня.\n *\n * @deprecated Since 7.4.0.\n *\n * Будет удалeно в **VKUI v8**. Использовалось для задания aria-label для контейнера дней в календаре.\n * Теперь этот контейнер является таблицей (с помощью role=\"grid\") и\n * в aria-label рендерится текущий открытый в календаре месяц и год.\n */\n changeDayLabel?: string;\n /**\n * День недели, с которого начинается неделя.\n */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /**\n * Обработчик изменения выбранного промежутка.\n */\n onChange?: (value: DateRangeType | undefined) => void; // TODO [>=8]: поменять тип на `(value?: DateRangeType | null) => void`\n /**\n * Функция для проверки запрета выбора даты.\n */\n shouldDisableDate?: (value: Date) => boolean;\n /**\n * @deprecated Свойство не используется.\n */\n onClose?: () => void;\n}\n\nconst getIsDaySelected = (day: Date, value?: DateRangeType | null) => {\n if (!value?.[0] || !value[1]) {\n return false;\n }\n\n return isWithinInterval(day, { start: startOfDay(value[0]), end: endOfDay(value[1]) });\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/CalendarRange\n */\nexport const CalendarRange = ({\n 'value': valueProp,\n defaultValue,\n onChange,\n disablePast,\n disableFuture,\n shouldDisableDate,\n weekStartsOn = 1,\n disablePickers,\n prevMonthLabel = 'Предыдущий месяц',\n nextMonthLabel = 'Следующий месяц',\n changeMonthLabel = 'Изменить месяц',\n changeYearLabel = 'Изменить год',\n 'aria-label': ariaLabel = 'Календарь',\n prevMonthIcon,\n nextMonthIcon,\n listenDayChangesForUpdate,\n renderDayContent,\n dayTestId,\n leftPartHeaderTestsData,\n rightPartHeaderTestsData,\n getRootRef,\n ...props\n}: CalendarRangeProps): React.ReactNode => {\n const _onChange = React.useCallback(\n (newValue: DateRangeType | null | undefined) => onChange?.(newValue || undefined),\n [onChange],\n );\n\n const [value, updateValue] = useCustomEnsuredControl<DateRangeType | null | undefined>({\n value: valueProp,\n defaultValue,\n onChange: _onChange,\n });\n\n const {\n viewDate,\n setViewDate,\n setPrevMonth,\n setNextMonth,\n focusedDay,\n setFocusedDay,\n isDayFocused,\n isDayDisabled,\n isMonthDisabled,\n isYearDisabled,\n } = useCalendar({ value, disableFuture, disablePast, shouldDisableDate });\n\n const [hintedDate, setHintedDate] = React.useState<DateRangeType>();\n const secondViewDate = addMonths(viewDate, 1);\n\n const {\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n handleFirstCalendarKeyDown,\n handleSecondCalendarKeyDown,\n handleDayFocus,\n } = useCalendarKeyboardNavigation({\n focusedDay,\n setFocusedDay,\n value,\n viewDates: [viewDate, secondViewDate],\n setViewDate,\n });\n\n const getNewValue = React.useCallback(\n (date: Date): DateRangeType => {\n const isValueEmpty = !value || (value[0] === null && value[1] === null);\n const isRangeSelected = value && !!value[0] && !!value[1];\n if (isValueEmpty || isRangeSelected) {\n return [date, null];\n }\n\n const [start] = value;\n if (start && isSameDay(date, start)) {\n return [startOfDay(start), endOfDay(start)];\n } else if (start && isBefore(date, start)) {\n return [startOfDay(date), endOfDay(start)];\n } else if (start && isAfter(date, start)) {\n return [start, endOfDay(date)];\n }\n return value;\n },\n [value],\n );\n\n const onDayChange = React.useCallback(\n (date: Date) => {\n updateValue(getNewValue(date));\n setHintedDate(undefined);\n },\n [updateValue, getNewValue],\n );\n\n const isDaySelected = React.useCallback((day: Date) => getIsDaySelected(day, value), [value]);\n\n const isDayActive = React.useCallback(\n (day: Date) =>\n Boolean((value?.[0] && isSameDay(day, value[0])) || (value?.[1] && isSameDay(day, value[1]))),\n [value],\n );\n\n const isDaySelectionEnd = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isLastDay(day, dayOfWeek) || (value?.[1] && isSameDay(day, value[1]))),\n [value],\n );\n\n const isHintedDaySelectionEnd = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isLastDay(day, dayOfWeek) || (hintedDate?.[1] && isSameDay(day, hintedDate[1]))),\n [hintedDate],\n );\n\n const isDaySelectionStart = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isFirstDay(day, dayOfWeek) || (value?.[0] && isSameDay(day, value[0]))),\n [value],\n );\n\n const isHintedDaySelectionStart = React.useCallback(\n (day: Date, dayOfWeek: number) =>\n Boolean(isFirstDay(day, dayOfWeek) || (hintedDate?.[0] && isSameDay(day, hintedDate[0]))),\n [hintedDate],\n );\n\n const onDayEnter = React.useCallback(\n (date: Date) => setHintedDate(getNewValue(date)),\n [setHintedDate, getNewValue],\n );\n\n const onDayLeave = React.useCallback(() => setHintedDate(undefined), [setHintedDate]);\n\n const isDayHinted = React.useCallback(\n (day: Date) => getIsDaySelected(day, hintedDate),\n [hintedDate],\n );\n\n const onRightPartViewDateChange = React.useCallback(\n (newDate: Date) => setViewDate(subMonths(newDate, 1)),\n [setViewDate],\n );\n\n const isDayFocusableInFirstCalendar = useIsDayFocusable({\n value,\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n viewDate,\n isDayActive,\n });\n\n const isDayFocusableInSecondCalendar = useIsDayFocusable({\n value,\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n viewDate: secondViewDate,\n isDayActive,\n });\n\n const onDayFocus = React.useCallback(\n (date: Date) => {\n if (focusedDay && isSameDay(focusedDay, date)) {\n return;\n }\n\n setFocusedDay(date);\n handleDayFocus(date);\n },\n [focusedDay, handleDayFocus, setFocusedDay],\n );\n\n return (\n <RootComponent\n aria-label={ariaLabel}\n {...props}\n baseClassName={styles.host}\n getRootRef={getRootRef}\n >\n <div className={styles.inner}>\n <CalendarHeader\n viewDate={viewDate}\n onChange={setViewDate}\n nextMonthHidden\n onPrevMonth={setPrevMonth}\n disablePickers={disablePickers}\n className={styles.header}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n prevMonthIcon={prevMonthIcon}\n isMonthDisabled={isMonthDisabled}\n isYearDisabled={isYearDisabled}\n {...leftPartHeaderTestsData}\n />\n <CalendarDays\n viewDate={viewDate}\n value={value}\n weekStartsOn={weekStartsOn}\n onKeyDown={handleFirstCalendarKeyDown}\n onDayFocus={onDayFocus}\n isDayFocused={isDayFocused}\n isDayFocusable={isDayFocusableInFirstCalendar}\n onDayChange={onDayChange}\n isDaySelected={isDaySelected}\n isDayActive={isDayActive}\n isDaySelectionEnd={isDaySelectionEnd}\n isDaySelectionStart={isDaySelectionStart}\n isDayHinted={isDayHinted}\n onDayEnter={onDayEnter}\n onDayLeave={onDayLeave}\n isHintedDaySelectionEnd={isHintedDaySelectionEnd}\n isHintedDaySelectionStart={isHintedDaySelectionStart}\n isDayDisabled={isDayDisabled}\n listenDayChangesForUpdate={listenDayChangesForUpdate}\n renderDayContent={renderDayContent}\n dayTestId={dayTestId}\n />\n </div>\n <div className={styles.inner}>\n <CalendarHeader\n viewDate={secondViewDate}\n onChange={onRightPartViewDateChange}\n prevMonthHidden\n onNextMonth={setNextMonth}\n disablePickers={disablePickers}\n className={styles.header}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n nextMonthIcon={nextMonthIcon}\n isMonthDisabled={isMonthDisabled}\n isYearDisabled={isYearDisabled}\n {...rightPartHeaderTestsData}\n />\n <CalendarDays\n viewDate={secondViewDate}\n value={value}\n weekStartsOn={weekStartsOn}\n onKeyDown={handleSecondCalendarKeyDown}\n onDayFocus={onDayFocus}\n isDayFocused={isDayFocused}\n isDayFocusable={isDayFocusableInSecondCalendar}\n onDayChange={onDayChange}\n isDaySelected={isDaySelected}\n isDayActive={isDayActive}\n isDaySelectionEnd={isDaySelectionEnd}\n isDaySelectionStart={isDaySelectionStart}\n isDayHinted={isDayHinted}\n onDayEnter={onDayEnter}\n onDayLeave={onDayLeave}\n isHintedDaySelectionEnd={isHintedDaySelectionEnd}\n isHintedDaySelectionStart={isHintedDaySelectionStart}\n isDayDisabled={isDayDisabled}\n listenDayChangesForUpdate={listenDayChangesForUpdate}\n renderDayContent={renderDayContent}\n dayTestId={dayTestId}\n />\n </div>\n </RootComponent>\n );\n};\n"],"names":["React","addMonths","endOfDay","isAfter","isBefore","isSameDay","isWithinInterval","startOfDay","subMonths","useCalendar","useCustomEnsuredControl","isFirstDay","isLastDay","CalendarDays","CalendarHeader","RootComponent","useCalendarKeyboardNavigation","useIsDayFocusable","styles","getIsDaySelected","day","value","start","end","CalendarRange","valueProp","defaultValue","onChange","disablePast","disableFuture","shouldDisableDate","weekStartsOn","disablePickers","prevMonthLabel","nextMonthLabel","changeMonthLabel","changeYearLabel","ariaLabel","prevMonthIcon","nextMonthIcon","listenDayChangesForUpdate","renderDayContent","dayTestId","leftPartHeaderTestsData","rightPartHeaderTestsData","getRootRef","props","_onChange","useCallback","newValue","undefined","updateValue","viewDate","setViewDate","setPrevMonth","setNextMonth","focusedDay","setFocusedDay","isDayFocused","isDayDisabled","isMonthDisabled","isYearDisabled","hintedDate","setHintedDate","useState","secondViewDate","focusableDayOnFirstCalendar","focusableDayOnSecondCalendar","handleFirstCalendarKeyDown","handleSecondCalendarKeyDown","handleDayFocus","viewDates","getNewValue","date","isValueEmpty","isRangeSelected","onDayChange","isDaySelected","isDayActive","Boolean","isDaySelectionEnd","dayOfWeek","isHintedDaySelectionEnd","isDaySelectionStart","isHintedDaySelectionStart","onDayEnter","onDayLeave","isDayHinted","onRightPartViewDateChange","newDate","isDayFocusableInFirstCalendar","isDayFocusableInSecondCalendar","onDayFocus","aria-label","baseClassName","host","div","className","inner","nextMonthHidden","onPrevMonth","header","onKeyDown","isDayFocusable","prevMonthHidden","onNextMonth"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/CalendarRange/types.ts"],"sourcesContent":["export type DateRangeType = [Date | null, Date | null];\n"],"names":[],"mappings":"AAAA,WAAuD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
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.js";
|
|
5
|
+
import { navigateDate, NAVIGATION_KEYS } from "../../lib/calendar.js";
|
|
6
|
+
import { isHTMLElement } from "../../lib/dom.js";
|
|
7
|
+
export function useCalendarKeyboardNavigation({ focusedDay, value, setFocusedDay, viewDates: [firstCalendarViewDate, secondCalendarViewDate], setViewDate }) {
|
|
8
|
+
// соотвествует дню, на котором можно сфокусироваться с помощью Tab
|
|
9
|
+
const [focusableDayOnFirstCalendar, setFocusableDayOnFirstCalendar] = React.useState();
|
|
10
|
+
const [focusableDayOnSecondCalendar, setFocusableDayOnSecondCalendar] = React.useState();
|
|
11
|
+
const handleCalendarKeyDown = React.useCallback((event, isFirst)=>{
|
|
12
|
+
const key = pressedKey(event);
|
|
13
|
+
if (!key) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (NAVIGATION_KEYS.includes(key)) {
|
|
17
|
+
event.preventDefault();
|
|
18
|
+
const newFocusedDay = navigateDate(focusedDay ?? value?.[0], key);
|
|
19
|
+
if (newFocusedDay && !isSameMonth(newFocusedDay, firstCalendarViewDate) && !isSameMonth(newFocusedDay, secondCalendarViewDate)) {
|
|
20
|
+
setViewDate(newFocusedDay);
|
|
21
|
+
}
|
|
22
|
+
if (isFirst) {
|
|
23
|
+
if (isSameMonth(newFocusedDay, firstCalendarViewDate)) {
|
|
24
|
+
setFocusableDayOnFirstCalendar(newFocusedDay);
|
|
25
|
+
} else if (isAfter(newFocusedDay, firstCalendarViewDate)) {
|
|
26
|
+
setFocusableDayOnSecondCalendar(newFocusedDay);
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
if (isSameMonth(newFocusedDay, secondCalendarViewDate)) {
|
|
30
|
+
setFocusableDayOnSecondCalendar(newFocusedDay);
|
|
31
|
+
} else if (isBefore(newFocusedDay, secondCalendarViewDate)) {
|
|
32
|
+
setFocusableDayOnFirstCalendar(newFocusedDay);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
setFocusedDay(newFocusedDay);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (key === Keys.TAB) {
|
|
39
|
+
setFocusedDay(undefined);
|
|
40
|
+
if (isFirst) {
|
|
41
|
+
setFocusableDayOnFirstCalendar(focusedDay);
|
|
42
|
+
} else {
|
|
43
|
+
setFocusableDayOnSecondCalendar(focusedDay);
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {
|
|
48
|
+
event.preventDefault();
|
|
49
|
+
event.target.click?.();
|
|
50
|
+
}
|
|
51
|
+
}, [
|
|
52
|
+
focusedDay,
|
|
53
|
+
value,
|
|
54
|
+
firstCalendarViewDate,
|
|
55
|
+
secondCalendarViewDate,
|
|
56
|
+
setFocusedDay,
|
|
57
|
+
setViewDate
|
|
58
|
+
]);
|
|
59
|
+
const handleFirstCalendarKeyDown = React.useCallback((event)=>{
|
|
60
|
+
handleCalendarKeyDown(event, true);
|
|
61
|
+
}, [
|
|
62
|
+
handleCalendarKeyDown
|
|
63
|
+
]);
|
|
64
|
+
const handleSecondCalendarKeyDown = React.useCallback((event)=>{
|
|
65
|
+
handleCalendarKeyDown(event, false);
|
|
66
|
+
}, [
|
|
67
|
+
handleCalendarKeyDown
|
|
68
|
+
]);
|
|
69
|
+
const handleDayFocus = React.useCallback((value)=>{
|
|
70
|
+
if (isSameMonth(firstCalendarViewDate, value) && (!focusableDayOnFirstCalendar || !isSameDate(focusableDayOnFirstCalendar, value))) {
|
|
71
|
+
setFocusableDayOnFirstCalendar(value);
|
|
72
|
+
}
|
|
73
|
+
if (isSameMonth(secondCalendarViewDate, value) && (!focusableDayOnSecondCalendar || !isSameDate(focusableDayOnSecondCalendar, value))) {
|
|
74
|
+
setFocusableDayOnSecondCalendar(value);
|
|
75
|
+
}
|
|
76
|
+
}, [
|
|
77
|
+
firstCalendarViewDate,
|
|
78
|
+
focusableDayOnFirstCalendar,
|
|
79
|
+
focusableDayOnSecondCalendar,
|
|
80
|
+
secondCalendarViewDate
|
|
81
|
+
]);
|
|
82
|
+
return {
|
|
83
|
+
focusableDayOnFirstCalendar,
|
|
84
|
+
focusableDayOnSecondCalendar,
|
|
85
|
+
handleFirstCalendarKeyDown,
|
|
86
|
+
handleSecondCalendarKeyDown,
|
|
87
|
+
handleDayFocus
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Возвращает функцию, которая позволяет проверить является ли день в календаре днём на который
|
|
92
|
+
* можно попасть с помощью Tab.
|
|
93
|
+
* Единственный день в таблице календаря у которого есть tabIndex="0"
|
|
94
|
+
* Чтобы на него можно было попасть из заголовка календаря.
|
|
95
|
+
*/ export function useIsDayFocusable({ value, focusableDayOnFirstCalendar, focusableDayOnSecondCalendar, viewDate, isDayActive }) {
|
|
96
|
+
const isValueVisibleOnCalendar = Boolean(value && (value[0] && isSameMonth(value[0], viewDate) || value[1] && isSameMonth(value[1], viewDate)));
|
|
97
|
+
const isCalendarHasFocusableDay = Boolean(focusableDayOnFirstCalendar && isSameMonth(focusableDayOnFirstCalendar, viewDate) || focusableDayOnSecondCalendar && isSameMonth(focusableDayOnSecondCalendar, viewDate));
|
|
98
|
+
const isDayFocusable = React.useCallback((day)=>{
|
|
99
|
+
// если focusableDay день находится среди дней открытого сейчас месяца, то такой день получит tabIndex="0",
|
|
100
|
+
if (isCalendarHasFocusableDay) {
|
|
101
|
+
return Boolean(focusableDayOnFirstCalendar && isSameDay(focusableDayOnFirstCalendar, day) || focusableDayOnSecondCalendar && isSameDay(focusableDayOnSecondCalendar, day));
|
|
102
|
+
}
|
|
103
|
+
// при открытии календаря focusableDay не определён,
|
|
104
|
+
// поэтому tabIndex="0" будет у дня, соответствующего дню в инпуте
|
|
105
|
+
if (isValueVisibleOnCalendar) {
|
|
106
|
+
return isDayActive(day);
|
|
107
|
+
}
|
|
108
|
+
// при переключении месяца любая навигация с помощью Tab начинается
|
|
109
|
+
// с первого дня месяца.
|
|
110
|
+
return isSameDay(startOfMonth(viewDate), day);
|
|
111
|
+
}, [
|
|
112
|
+
isCalendarHasFocusableDay,
|
|
113
|
+
isValueVisibleOnCalendar,
|
|
114
|
+
viewDate,
|
|
115
|
+
isDayActive,
|
|
116
|
+
focusableDayOnFirstCalendar,
|
|
117
|
+
focusableDayOnSecondCalendar
|
|
118
|
+
]);
|
|
119
|
+
return isDayFocusable;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/CalendarRange/utils.ts"],"sourcesContent":["import * as React from 'react';\nimport { isSameDate } from '@vkontakte/vkjs';\nimport { isAfter, isBefore, isSameDay, isSameMonth, startOfMonth } from 'date-fns';\nimport { Keys, pressedKey } from '../../lib/accessibility';\nimport { navigateDate, NAVIGATION_KEYS } from '../../lib/calendar';\nimport { isHTMLElement } from '../../lib/dom';\nimport type { DateRangeType } from './types';\n\nexport function useCalendarKeyboardNavigation({\n focusedDay,\n value,\n setFocusedDay,\n viewDates: [firstCalendarViewDate, secondCalendarViewDate],\n setViewDate,\n}: {\n focusedDay: Date | undefined;\n setViewDate: (date: Date) => void;\n setFocusedDay: React.Dispatch<React.SetStateAction<Date | undefined>>;\n viewDates: [Date, Date];\n value: DateRangeType | null | undefined;\n}) {\n // соотвествует дню, на котором можно сфокусироваться с помощью Tab\n const [focusableDayOnFirstCalendar, setFocusableDayOnFirstCalendar] = React.useState<Date>();\n const [focusableDayOnSecondCalendar, setFocusableDayOnSecondCalendar] = React.useState<Date>();\n\n const handleCalendarKeyDown = React.useCallback(\n (event: React.KeyboardEvent, isFirst: boolean) => {\n const key = pressedKey(event);\n if (!key) {\n return;\n }\n\n if (NAVIGATION_KEYS.includes(key)) {\n event.preventDefault();\n\n const newFocusedDay = navigateDate(focusedDay ?? value?.[0], key);\n\n if (\n newFocusedDay &&\n !isSameMonth(newFocusedDay, firstCalendarViewDate) &&\n !isSameMonth(newFocusedDay, secondCalendarViewDate)\n ) {\n setViewDate(newFocusedDay);\n }\n\n if (isFirst) {\n if (isSameMonth(newFocusedDay, firstCalendarViewDate)) {\n setFocusableDayOnFirstCalendar(newFocusedDay);\n } else if (isAfter(newFocusedDay, firstCalendarViewDate)) {\n setFocusableDayOnSecondCalendar(newFocusedDay);\n }\n } else {\n if (isSameMonth(newFocusedDay, secondCalendarViewDate)) {\n setFocusableDayOnSecondCalendar(newFocusedDay);\n } else if (isBefore(newFocusedDay, secondCalendarViewDate)) {\n setFocusableDayOnFirstCalendar(newFocusedDay);\n }\n }\n\n setFocusedDay(newFocusedDay);\n\n return;\n }\n\n if (key === Keys.TAB) {\n setFocusedDay(undefined);\n if (isFirst) {\n setFocusableDayOnFirstCalendar(focusedDay);\n } else {\n setFocusableDayOnSecondCalendar(focusedDay);\n }\n\n return;\n }\n\n if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {\n event.preventDefault();\n event.target.click?.();\n }\n },\n [focusedDay, value, firstCalendarViewDate, secondCalendarViewDate, setFocusedDay, setViewDate],\n );\n\n const handleFirstCalendarKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n handleCalendarKeyDown(event, true);\n },\n [handleCalendarKeyDown],\n );\n\n const handleSecondCalendarKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n handleCalendarKeyDown(event, false);\n },\n [handleCalendarKeyDown],\n );\n\n const handleDayFocus = React.useCallback(\n (value: Date) => {\n if (\n isSameMonth(firstCalendarViewDate, value) &&\n (!focusableDayOnFirstCalendar || !isSameDate(focusableDayOnFirstCalendar, value))\n ) {\n setFocusableDayOnFirstCalendar(value);\n }\n if (\n isSameMonth(secondCalendarViewDate, value) &&\n (!focusableDayOnSecondCalendar || !isSameDate(focusableDayOnSecondCalendar, value))\n ) {\n setFocusableDayOnSecondCalendar(value);\n }\n },\n [\n firstCalendarViewDate,\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n secondCalendarViewDate,\n ],\n );\n\n return {\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n handleFirstCalendarKeyDown,\n handleSecondCalendarKeyDown,\n handleDayFocus,\n };\n}\n\n/**\n * Возвращает функцию, которая позволяет проверить является ли день в календаре днём на который\n * можно попасть с помощью Tab.\n * Единственный день в таблице календаря у которого есть tabIndex=\"0\"\n * Чтобы на него можно было попасть из заголовка календаря.\n */\nexport function useIsDayFocusable({\n value,\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n viewDate,\n isDayActive,\n}: {\n value: DateRangeType | null | undefined;\n focusableDayOnFirstCalendar: Date | undefined;\n focusableDayOnSecondCalendar: Date | undefined;\n viewDate: Date;\n isDayActive: (date: Date) => boolean;\n}) {\n const isValueVisibleOnCalendar = Boolean(\n value &&\n ((value[0] && isSameMonth(value[0], viewDate)) ||\n (value[1] && isSameMonth(value[1], viewDate))),\n );\n\n const isCalendarHasFocusableDay = Boolean(\n (focusableDayOnFirstCalendar && isSameMonth(focusableDayOnFirstCalendar, viewDate)) ||\n (focusableDayOnSecondCalendar && isSameMonth(focusableDayOnSecondCalendar, viewDate)),\n );\n\n const isDayFocusable = React.useCallback(\n (day: Date) => {\n // если focusableDay день находится среди дней открытого сейчас месяца, то такой день получит tabIndex=\"0\",\n if (isCalendarHasFocusableDay) {\n return Boolean(\n (focusableDayOnFirstCalendar && isSameDay(focusableDayOnFirstCalendar, day)) ||\n (focusableDayOnSecondCalendar && isSameDay(focusableDayOnSecondCalendar, day)),\n );\n }\n\n // при открытии календаря focusableDay не определён,\n // поэтому tabIndex=\"0\" будет у дня, соответствующего дню в инпуте\n if (isValueVisibleOnCalendar) {\n return isDayActive(day);\n }\n\n // при переключении месяца любая навигация с помощью Tab начинается\n // с первого дня месяца.\n return isSameDay(startOfMonth(viewDate), day);\n },\n [\n isCalendarHasFocusableDay,\n isValueVisibleOnCalendar,\n viewDate,\n isDayActive,\n focusableDayOnFirstCalendar,\n focusableDayOnSecondCalendar,\n ],\n );\n return isDayFocusable;\n}\n"],"names":["React","isSameDate","isAfter","isBefore","isSameDay","isSameMonth","startOfMonth","Keys","pressedKey","navigateDate","NAVIGATION_KEYS","isHTMLElement","useCalendarKeyboardNavigation","focusedDay","value","setFocusedDay","viewDates","firstCalendarViewDate","secondCalendarViewDate","setViewDate","focusableDayOnFirstCalendar","setFocusableDayOnFirstCalendar","useState","focusableDayOnSecondCalendar","setFocusableDayOnSecondCalendar","handleCalendarKeyDown","useCallback","event","isFirst","key","includes","preventDefault","newFocusedDay","TAB","undefined","ENTER","SPACE","target","click","handleFirstCalendarKeyDown","handleSecondCalendarKeyDown","handleDayFocus","useIsDayFocusable","viewDate","isDayActive","isValueVisibleOnCalendar","Boolean","isCalendarHasFocusableDay","isDayFocusable","day"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { hasReactNode } from '@vkontakte/vkjs';\nimport type { HasRootRef } from '../../types';\nimport { SelectionControl } from '../SelectionControl/SelectionControl';\nimport { SelectionControlLabel } from '../SelectionControl/SelectionControlLabel/SelectionControlLabel';\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { hasReactNode } from '@vkontakte/vkjs';\nimport type { HasRootRef } from '../../types';\nimport { SelectionControl } from '../SelectionControl/SelectionControl';\nimport { SelectionControlLabel } from '../SelectionControl/SelectionControlLabel/SelectionControlLabel';\nimport type { TappableOmitProps } from '../Tappable/Tappable';\nimport { CheckboxInput, type CheckboxInputProps } from './CheckboxInput/CheckboxInput';\nimport { CheckboxSimple } from './CheckboxSimple/CheckboxSimple';\n\nexport interface CheckboxProps\n extends Omit<CheckboxInputProps, 'getRootRef'>,\n HasRootRef<HTMLLabelElement>,\n Pick<\n TappableOmitProps,\n 'hoverMode' | 'activeMode' | 'hasHover' | 'hasActive' | 'focusVisibleMode'\n > {\n /**\n * Подпись под основным текстом.\n */\n description?: React.ReactNode;\n /**\n * Контент, идущий за основным текстом.\n */\n titleAfter?: React.ReactNode;\n}\n\nconst CheckboxComponent = ({\n children,\n className,\n style,\n getRootRef,\n description,\n hoverMode,\n activeMode,\n hasHover,\n hasActive,\n focusVisibleMode,\n titleAfter,\n ...restProps\n}: CheckboxProps): React.ReactNode => {\n return (\n <SelectionControl\n className={className}\n style={style}\n disabled={restProps.disabled}\n getRootRef={getRootRef}\n hoverMode={hoverMode}\n activeMode={activeMode}\n hasHover={hasHover}\n hasActive={hasActive}\n focusVisibleMode={focusVisibleMode}\n >\n <CheckboxInput {...restProps} />\n <SelectionControlLabel titleAfter={titleAfter} description={description}>\n {children}\n </SelectionControlLabel>\n </SelectionControl>\n );\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Checkbox\n */\nexport const Checkbox = (props: CheckboxProps): React.ReactNode => {\n const simple = !(hasReactNode(props.children) || hasReactNode(props.description));\n if (simple) {\n return <CheckboxSimple {...props} />;\n }\n\n return <CheckboxComponent {...props} />;\n};\n\nCheckbox.Input = CheckboxInput;\n"],"names":["React","hasReactNode","SelectionControl","SelectionControlLabel","CheckboxInput","CheckboxSimple","CheckboxComponent","children","className","style","getRootRef","description","hoverMode","activeMode","hasHover","hasActive","focusVisibleMode","titleAfter","restProps","disabled","Checkbox","props","simple","Input"],"mappings":";AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,kBAAkB;AAE/C,SAASC,gBAAgB,QAAQ,0CAAuC;AACxE,SAASC,qBAAqB,QAAQ,qEAAkE;AAExG,SAASC,aAAa,QAAiC,mCAAgC;AACvF,SAASC,cAAc,QAAQ,qCAAkC;AAmBjE,MAAMC,oBAAoB,CAAC,EACzBC,QAAQ,EACRC,SAAS,EACTC,KAAK,EACLC,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,UAAU,EACVC,QAAQ,EACRC,SAAS,EACTC,gBAAgB,EAChBC,UAAU,EACV,GAAGC,WACW;IACd,qBACE,MAAChB;QACCM,WAAWA;QACXC,OAAOA;QACPU,UAAUD,UAAUC,QAAQ;QAC5BT,YAAYA;QACZE,WAAWA;QACXC,YAAYA;QACZC,UAAUA;QACVC,WAAWA;QACXC,kBAAkBA;;0BAElB,KAACZ;gBAAe,GAAGc,SAAS;;0BAC5B,KAACf;gBAAsBc,YAAYA;gBAAYN,aAAaA;0BACzDJ;;;;AAIT;AAEA;;CAEC,GACD,OAAO,MAAMa,WAAW,CAACC;IACvB,MAAMC,SAAS,CAAErB,CAAAA,aAAaoB,MAAMd,QAAQ,KAAKN,aAAaoB,MAAMV,WAAW,CAAA;IAC/E,IAAIW,QAAQ;QACV,qBAAO,KAACjB;YAAgB,GAAGgB,KAAK;;IAClC;IAEA,qBAAO,KAACf;QAAmB,GAAGe,KAAK;;AACrC,EAAE;AAEFD,SAASG,KAAK,GAAGnB"}
|
|
@@ -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.js";
|
|
3
4
|
import { useNativeFormResetListener } from "../../hooks/useNativeFormResetListener.js";
|
|
4
5
|
import { simulateReactInput } from "../../lib/react/index.js";
|
|
@@ -9,6 +10,23 @@ export const transformValue = (value, getOptionValue, getOptionLabel)=>value.map
|
|
|
9
10
|
label: getOptionLabel(option),
|
|
10
11
|
value: getOptionValue(option)
|
|
11
12
|
}));
|
|
13
|
+
function getRegExpFromArray(separators) {
|
|
14
|
+
const validSeparators = separators.filter((s)=>s.length > 0);
|
|
15
|
+
if (validSeparators.length === 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const escaped = validSeparators.map((s)=>escapeRegExp(s));
|
|
19
|
+
return new RegExp(`(?:${escaped.join('|')})`);
|
|
20
|
+
}
|
|
21
|
+
function getRegexFromDelimiter(delimiter) {
|
|
22
|
+
if (delimiter instanceof RegExp) {
|
|
23
|
+
return delimiter;
|
|
24
|
+
}
|
|
25
|
+
if (typeof delimiter === 'string') {
|
|
26
|
+
return new RegExp(escapeRegExp(delimiter));
|
|
27
|
+
}
|
|
28
|
+
return getRegExpFromArray(delimiter);
|
|
29
|
+
}
|
|
12
30
|
export const useChipsInput = ({ // option
|
|
13
31
|
value: valueProp, defaultValue = DEFAULT_VALUE, onChange, getOptionLabel = getOptionLabelDefault, getOptionValue = getOptionValueDefault, getNewOptionData = getNewOptionDataDefault, // input
|
|
14
32
|
inputValue: inputValueProp, defaultInputValue = DEFAULT_INPUT_VALUE, onInputChange: onInputChangeProp, // other
|
|
@@ -94,11 +112,12 @@ disabled, delimiter })=>{
|
|
|
94
112
|
]);
|
|
95
113
|
const onInputChange = React.useCallback((e, canCreate = true)=>{
|
|
96
114
|
const newInputValue = e.target.value;
|
|
97
|
-
|
|
115
|
+
const delimiterRegex = delimiter ? getRegexFromDelimiter(delimiter) : null;
|
|
116
|
+
if (!delimiterRegex || !delimiterRegex.test(newInputValue) || !canCreate) {
|
|
98
117
|
setInputChange(e);
|
|
99
118
|
return;
|
|
100
119
|
}
|
|
101
|
-
const values = newInputValue.trim().split(
|
|
120
|
+
const values = newInputValue.trim().split(delimiterRegex).map((v)=>v.trim()).filter(Boolean);
|
|
102
121
|
e.target.value = '';
|
|
103
122
|
e.currentTarget.value = '';
|
|
104
123
|
setInputChange(e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ChipsInput/useChipsInput.ts"],"sourcesContent":["import * as React from 'react';\nimport { useCustomEnsuredControl, useEnsuredControl } from '../../hooks/useEnsuredControl';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { simulateReactInput, type SimulateReactInputTargetState } from '../../lib/react';\nimport {\n DEFAULT_INPUT_VALUE,\n DEFAULT_VALUE,\n getNewOptionDataDefault,\n getOptionLabelDefault,\n getOptionValueDefault,\n} from '../ChipsInputBase/constants';\nimport { isValueLikeChipOptionObject } from '../ChipsInputBase/helpers';\nimport type {\n ChipOption,\n ChipOptionLabel,\n ChipOptionValue,\n GetNewOptionData,\n GetOptionLabel,\n GetOptionValue,\n UseChipsInputBaseProps,\n} from '../ChipsInputBase/types';\n\nexport const transformValue = <O extends ChipOption>(\n value: O[],\n getOptionValue: GetOptionValue<O>,\n getOptionLabel: GetOptionLabel<O>,\n): Array<\n O & {\n label: ChipOptionLabel;\n value: ChipOptionValue;\n }\n> =>\n value.map((option) => ({\n ...option,\n label: getOptionLabel(option),\n value: getOptionValue(option),\n }));\n\ninterface ToggleOption<O extends ChipOption> {\n (optionsForAdd: Array<O | string>, isNewValue: true): void;\n (optionsForRemove: Array<O | ChipOptionValue>, isNewValue: false): void;\n}\n\nexport interface UseChipsInputProps<O extends ChipOption = ChipOption>\n extends UseChipsInputBaseProps<O> {\n /**\n * Селектор значения.\n */\n getOptionValue?: GetOptionValue<O>;\n /**\n * Селектор пользовательского представления.\n */\n getOptionLabel?: GetOptionLabel<O>;\n /**\n * Функция для создания новой опции.\n */\n getNewOptionData?: GetNewOptionData<O>;\n}\n\nexport const useChipsInput = <O extends ChipOption>({\n // option\n value: valueProp,\n defaultValue = DEFAULT_VALUE,\n onChange,\n getOptionLabel = getOptionLabelDefault,\n getOptionValue = getOptionValueDefault,\n getNewOptionData = getNewOptionDataDefault,\n\n // input\n inputValue: inputValueProp,\n defaultInputValue = DEFAULT_INPUT_VALUE,\n onInputChange: onInputChangeProp,\n\n // other\n disabled,\n delimiter,\n}: UseChipsInputProps<O>): {\n value: Array<\n O & {\n label: ChipOptionLabel;\n value: ChipOptionValue;\n }\n >;\n addOption: (newValue: O | string) => void;\n addOptionFromInput: (inputValue: string) => void;\n removeOption: (newValue: O | ChipOptionValue) => void;\n clearOptions: () => void;\n inputRef: React.RefObject<(HTMLInputElement & SimulateReactInputTargetState) | null>;\n inputValue: string;\n onInputChange: (e: React.ChangeEvent<HTMLInputElement>, canCreate?: boolean) => any;\n clearInput: () => void;\n} => {\n const [value, setValue] = useCustomEnsuredControl({\n disabled,\n value: valueProp ? transformValue(valueProp, getOptionValue, getOptionLabel) : undefined,\n defaultValue: transformValue(defaultValue, getOptionValue, getOptionLabel),\n onChange,\n });\n\n const inputRef = React.useRef<(HTMLInputElement & SimulateReactInputTargetState) | null>(null);\n const [inputValue, setInputChange] = useEnsuredControl({\n disabled,\n value: inputValueProp,\n defaultValue: defaultInputValue,\n onChange: onInputChangeProp,\n });\n\n const toggleOption: ToggleOption<O> = React.useCallback(\n (nextValuesProp: Array<O | ChipOptionValue>, isNewValue: boolean) => {\n setValue((prevValue) => {\n const resolvedNextOptionsSet = new Set<ChipOptionValue>();\n const resolvedNextOptions = nextValuesProp.map((option) => {\n const isLikeObjectOption = isValueLikeChipOptionObject(option);\n const resolvedOption = isLikeObjectOption\n ? getNewOptionData(option.value, option.label)\n : getNewOptionData(option, typeof option === 'string' ? option : '');\n resolvedNextOptionsSet.add(resolvedOption.value);\n return isLikeObjectOption ? { ...option, ...resolvedOption } : resolvedOption;\n });\n\n const nextValue = prevValue.filter(\n (option: O) => !resolvedNextOptionsSet.has(option.value),\n );\n\n if (isNewValue) {\n nextValue.push(...resolvedNextOptions);\n }\n\n return nextValue;\n });\n },\n [setValue, getNewOptionData],\n );\n\n const clearInput = React.useCallback(() => {\n /* istanbul ignore if */\n if (!inputRef.current) {\n return;\n }\n simulateReactInput(inputRef.current, '');\n }, [inputRef]);\n\n const addOption = React.useCallback(\n (newValue: O | string) => toggleOption([newValue], true),\n [toggleOption],\n );\n\n const addOptions = React.useCallback(\n (newValues: Array<O | string>) => toggleOption(newValues, true),\n [toggleOption],\n );\n\n const removeOption = React.useCallback(\n (newValue: O | ChipOptionValue) => toggleOption([newValue], false),\n [toggleOption],\n );\n\n const addOptionFromInput = React.useCallback(\n (inputValue: string) => {\n const label = inputValue.trim();\n if (label) {\n addOption(label);\n clearInput();\n }\n },\n [addOption, clearInput],\n );\n\n const reset = React.useCallback(() => {\n setValue(defaultValue);\n }, [defaultValue, setValue]);\n\n const clearOptions = React.useCallback(() => {\n setValue(DEFAULT_VALUE);\n clearInput();\n }, [clearInput, setValue]);\n\n const onInputChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>, canCreate = true) => {\n const newInputValue = e.target.value;\n if (!delimiter || !newInputValue.includes(delimiter) || !canCreate) {\n setInputChange(e);\n return;\n }\n const values = newInputValue\n .trim()\n .split(delimiter)\n .map((v) => v.trim())\n .filter(Boolean);\n\n e.target.value = '';\n e.currentTarget.value = '';\n setInputChange(e);\n\n addOptions(values);\n },\n [addOptions, delimiter, setInputChange],\n );\n\n useNativeFormResetListener(inputRef, reset);\n\n return {\n value,\n addOption,\n addOptionFromInput,\n removeOption,\n\n inputRef,\n inputValue,\n onInputChange,\n clearInput,\n clearOptions,\n };\n};\n"],"names":["React","useCustomEnsuredControl","useEnsuredControl","useNativeFormResetListener","simulateReactInput","DEFAULT_INPUT_VALUE","DEFAULT_VALUE","getNewOptionDataDefault","getOptionLabelDefault","getOptionValueDefault","isValueLikeChipOptionObject","transformValue","value","getOptionValue","getOptionLabel","map","option","label","useChipsInput","valueProp","defaultValue","onChange","getNewOptionData","inputValue","inputValueProp","defaultInputValue","onInputChange","onInputChangeProp","disabled","delimiter","setValue","undefined","inputRef","useRef","setInputChange","toggleOption","useCallback","nextValuesProp","isNewValue","prevValue","resolvedNextOptionsSet","Set","resolvedNextOptions","isLikeObjectOption","resolvedOption","add","nextValue","filter","has","push","clearInput","current","addOption","newValue","addOptions","newValues","removeOption","addOptionFromInput","trim","reset","clearOptions","e","canCreate","newInputValue","target","includes","values","split","v","Boolean","currentTarget"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ChipsInput/useChipsInput.ts"],"sourcesContent":["import * as React from 'react';\nimport { escapeRegExp } from '@vkontakte/vkjs';\nimport { useCustomEnsuredControl, useEnsuredControl } from '../../hooks/useEnsuredControl';\nimport { useNativeFormResetListener } from '../../hooks/useNativeFormResetListener';\nimport { simulateReactInput, type SimulateReactInputTargetState } from '../../lib/react';\nimport {\n DEFAULT_INPUT_VALUE,\n DEFAULT_VALUE,\n getNewOptionDataDefault,\n getOptionLabelDefault,\n getOptionValueDefault,\n} from '../ChipsInputBase/constants';\nimport { isValueLikeChipOptionObject } from '../ChipsInputBase/helpers';\nimport type {\n ChipOption,\n ChipOptionLabel,\n ChipOptionValue,\n GetNewOptionData,\n GetOptionLabel,\n GetOptionValue,\n UseChipsInputBaseProps,\n} from '../ChipsInputBase/types';\n\nexport const transformValue = <O extends ChipOption>(\n value: O[],\n getOptionValue: GetOptionValue<O>,\n getOptionLabel: GetOptionLabel<O>,\n): Array<\n O & {\n label: ChipOptionLabel;\n value: ChipOptionValue;\n }\n> =>\n value.map((option) => ({\n ...option,\n label: getOptionLabel(option),\n value: getOptionValue(option),\n }));\n\nfunction getRegExpFromArray(separators: string[]) {\n const validSeparators = separators.filter((s) => s.length > 0);\n if (validSeparators.length === 0) {\n return null;\n }\n const escaped = validSeparators.map((s) => escapeRegExp(s));\n return new RegExp(`(?:${escaped.join('|')})`);\n}\n\nfunction getRegexFromDelimiter(delimiter: string | RegExp | string[]): RegExp | null {\n if (delimiter instanceof RegExp) {\n return delimiter;\n }\n if (typeof delimiter === 'string') {\n return new RegExp(escapeRegExp(delimiter));\n }\n return getRegExpFromArray(delimiter);\n}\n\ninterface ToggleOption<O extends ChipOption> {\n (optionsForAdd: Array<O | string>, isNewValue: true): void;\n (optionsForRemove: Array<O | ChipOptionValue>, isNewValue: false): void;\n}\n\nexport interface UseChipsInputProps<O extends ChipOption = ChipOption>\n extends UseChipsInputBaseProps<O> {\n /**\n * Селектор значения.\n */\n getOptionValue?: GetOptionValue<O>;\n /**\n * Селектор пользовательского представления.\n */\n getOptionLabel?: GetOptionLabel<O>;\n /**\n * Функция для создания новой опции.\n */\n getNewOptionData?: GetNewOptionData<O>;\n}\n\nexport const useChipsInput = <O extends ChipOption>({\n // option\n value: valueProp,\n defaultValue = DEFAULT_VALUE,\n onChange,\n getOptionLabel = getOptionLabelDefault,\n getOptionValue = getOptionValueDefault,\n getNewOptionData = getNewOptionDataDefault,\n\n // input\n inputValue: inputValueProp,\n defaultInputValue = DEFAULT_INPUT_VALUE,\n onInputChange: onInputChangeProp,\n\n // other\n disabled,\n delimiter,\n}: UseChipsInputProps<O>): {\n value: Array<\n O & {\n label: ChipOptionLabel;\n value: ChipOptionValue;\n }\n >;\n addOption: (newValue: O | string) => void;\n addOptionFromInput: (inputValue: string) => void;\n removeOption: (newValue: O | ChipOptionValue) => void;\n clearOptions: () => void;\n inputRef: React.RefObject<(HTMLInputElement & SimulateReactInputTargetState) | null>;\n inputValue: string;\n onInputChange: (e: React.ChangeEvent<HTMLInputElement>, canCreate?: boolean) => any;\n clearInput: () => void;\n} => {\n const [value, setValue] = useCustomEnsuredControl({\n disabled,\n value: valueProp ? transformValue(valueProp, getOptionValue, getOptionLabel) : undefined,\n defaultValue: transformValue(defaultValue, getOptionValue, getOptionLabel),\n onChange,\n });\n\n const inputRef = React.useRef<(HTMLInputElement & SimulateReactInputTargetState) | null>(null);\n const [inputValue, setInputChange] = useEnsuredControl({\n disabled,\n value: inputValueProp,\n defaultValue: defaultInputValue,\n onChange: onInputChangeProp,\n });\n\n const toggleOption: ToggleOption<O> = React.useCallback(\n (nextValuesProp: Array<O | ChipOptionValue>, isNewValue: boolean) => {\n setValue((prevValue) => {\n const resolvedNextOptionsSet = new Set<ChipOptionValue>();\n const resolvedNextOptions = nextValuesProp.map((option) => {\n const isLikeObjectOption = isValueLikeChipOptionObject(option);\n const resolvedOption = isLikeObjectOption\n ? getNewOptionData(option.value, option.label)\n : getNewOptionData(option, typeof option === 'string' ? option : '');\n resolvedNextOptionsSet.add(resolvedOption.value);\n return isLikeObjectOption ? { ...option, ...resolvedOption } : resolvedOption;\n });\n\n const nextValue = prevValue.filter(\n (option: O) => !resolvedNextOptionsSet.has(option.value),\n );\n\n if (isNewValue) {\n nextValue.push(...resolvedNextOptions);\n }\n\n return nextValue;\n });\n },\n [setValue, getNewOptionData],\n );\n\n const clearInput = React.useCallback(() => {\n /* istanbul ignore if */\n if (!inputRef.current) {\n return;\n }\n simulateReactInput(inputRef.current, '');\n }, [inputRef]);\n\n const addOption = React.useCallback(\n (newValue: O | string) => toggleOption([newValue], true),\n [toggleOption],\n );\n\n const addOptions = React.useCallback(\n (newValues: Array<O | string>) => toggleOption(newValues, true),\n [toggleOption],\n );\n\n const removeOption = React.useCallback(\n (newValue: O | ChipOptionValue) => toggleOption([newValue], false),\n [toggleOption],\n );\n\n const addOptionFromInput = React.useCallback(\n (inputValue: string) => {\n const label = inputValue.trim();\n if (label) {\n addOption(label);\n clearInput();\n }\n },\n [addOption, clearInput],\n );\n\n const reset = React.useCallback(() => {\n setValue(defaultValue);\n }, [defaultValue, setValue]);\n\n const clearOptions = React.useCallback(() => {\n setValue(DEFAULT_VALUE);\n clearInput();\n }, [clearInput, setValue]);\n\n const onInputChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>, canCreate = true) => {\n const newInputValue = e.target.value;\n const delimiterRegex = delimiter ? getRegexFromDelimiter(delimiter) : null;\n if (!delimiterRegex || !delimiterRegex.test(newInputValue) || !canCreate) {\n setInputChange(e);\n return;\n }\n const values = newInputValue\n .trim()\n .split(delimiterRegex)\n .map((v) => v.trim())\n .filter(Boolean);\n\n e.target.value = '';\n e.currentTarget.value = '';\n setInputChange(e);\n\n addOptions(values);\n },\n [addOptions, delimiter, setInputChange],\n );\n\n useNativeFormResetListener(inputRef, reset);\n\n return {\n value,\n addOption,\n addOptionFromInput,\n removeOption,\n\n inputRef,\n inputValue,\n onInputChange,\n clearInput,\n clearOptions,\n };\n};\n"],"names":["React","escapeRegExp","useCustomEnsuredControl","useEnsuredControl","useNativeFormResetListener","simulateReactInput","DEFAULT_INPUT_VALUE","DEFAULT_VALUE","getNewOptionDataDefault","getOptionLabelDefault","getOptionValueDefault","isValueLikeChipOptionObject","transformValue","value","getOptionValue","getOptionLabel","map","option","label","getRegExpFromArray","separators","validSeparators","filter","s","length","escaped","RegExp","join","getRegexFromDelimiter","delimiter","useChipsInput","valueProp","defaultValue","onChange","getNewOptionData","inputValue","inputValueProp","defaultInputValue","onInputChange","onInputChangeProp","disabled","setValue","undefined","inputRef","useRef","setInputChange","toggleOption","useCallback","nextValuesProp","isNewValue","prevValue","resolvedNextOptionsSet","Set","resolvedNextOptions","isLikeObjectOption","resolvedOption","add","nextValue","has","push","clearInput","current","addOption","newValue","addOptions","newValues","removeOption","addOptionFromInput","trim","reset","clearOptions","e","canCreate","newInputValue","target","delimiterRegex","test","values","split","v","Boolean","currentTarget"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ChipsInputBase/types.ts"],"sourcesContent":["import type * as React from 'react';\nimport type {\n HasAlign,\n HasComponent,\n HasDataAttribute,\n HasRef,\n HTMLAttributesWithRootRef,\n} from '../../types';\nimport { type FormFieldProps } from '../FormField/FormField';\nimport { type FormFieldClearButtonProps } from '../FormFieldClearButton/FormFieldClearButton';\n\nexport type NavigateTo = 'prev' | 'next' | 'last';\n\nexport type ChipOptionValue = string | number;\n\nexport type ChipOptionLabel = React.ReactElement | string | number;\n\nexport type ChipOption = {\n /**\n * Значение опции.\n */\n value: ChipOptionValue;\n /**\n * Отображаемый текст опции.\n */\n label: ChipOptionLabel;\n /**\n * Блокировка взаимодействия с оцией.\n */\n disabled?: boolean;\n [index: string]: any;\n};\n\nexport interface ChipProps\n extends HasComponent,\n HasDataAttribute,\n HTMLAttributesWithRootRef<HTMLElement> {\n /**\n * Значение чипа.\n */\n value?: ChipOptionValue;\n /**\n * Можно ли удалить чип.\n */\n removable?: boolean;\n /**\n * Блокировка взаимодействия с чипом.\n */\n disabled?: boolean;\n /**\n * Режим только для чтения.\n */\n readOnly?: boolean;\n /**\n * Текст для кнопки удаления.\n */\n removeLabel?: string;\n /**\n * Контент перед основным содержимым.\n */\n before?: React.ReactNode;\n /**\n * Контент после основного содержимого.\n */\n after?: React.ReactNode;\n /**\n * Обработчик удаления чипа.\n */\n onRemove?: (event: React.MouseEvent, value: ChipOptionValue) => void;\n}\n\nexport interface RenderChipProps extends ChipProps {\n /**\n * Отображаемый текст чипа.\n */\n label: ChipOptionLabel;\n}\n\nexport type RenderChip<O extends ChipOption = ChipOption> = (\n props: RenderChipProps,\n option: O,\n) => React.ReactNode;\n\nexport type GetOptionValue<O extends ChipOption = ChipOption> = (option: O) => ChipOptionValue;\n\nexport type GetOptionLabel<O extends ChipOption = ChipOption> = (option: O) => ChipOptionLabel;\n\nexport type GetNewOptionData<O extends ChipOption = ChipOption> = (\n value: ChipOptionValue,\n label: ChipOptionLabel,\n) => O;\n\nexport type OnChange<O extends ChipOption = ChipOption> = (value: O[]) => void;\n\nexport type OnInputChange = (event: React.ChangeEvent<HTMLInputElement>) => void;\n\n/**\n * @public\n */\nexport interface UseChipsInputBaseProps<O extends ChipOption = ChipOption> {\n /**\n * Блокировка взаимодействия с компонентом.\n */\n disabled?: boolean;\n /**\n * Выбранные опции.\n */\n value?: O[];\n /**\n * Выбранные опции по умолчанию.\n */\n defaultValue?: O[];\n /**\n * Обработчик изменения выбранных опций.\n */\n onChange?: OnChange<O>;\n /**\n * Значение поля ввода.\n */\n inputValue?: string;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultInputValue?: string;\n /**\n * Обработчик изменения значения в поле ввода.\n */\n onInputChange?: OnInputChange;\n /**\n * Символ или строка, которая будет использоваться как разделитель для автоматического создания опций из текста, введенного в поле ввода.\n *\n * Работает в двух сценариях:\n * 1. При вводе разделителя - текст до разделителя автоматически преобразуется в новую опцию.\n * Например, при `delimiter=\",\"` ввод \"опция1,\" создаст опцию \"опция1\".\n *\n * 2. При вставке из буфера обмена - если вставляемый текст содержит разделители,\n * он будет автоматически разбит на несколько опций.\n * Например, при `delimiter=\",\"` вставка \"опция1,опция2,опция3\" создаст\n * три отдельные опции: \"опция1\", \"опция2\" и \"опция3\".\n */\n delimiter?: string;\n}\n\n/**\n * @private\n */\ntype UseChipsInputBaseOnlyNeededProps<O extends ChipOption = ChipOption> = Omit<\n UseChipsInputBaseProps<O>,\n 'onChange' | 'defaultValue' | 'defaultInputValue'\n>;\n\n/**\n * @public\n */\nexport interface ChipsInputBaseProps<O extends ChipOption = ChipOption>\n extends UseChipsInputBaseOnlyNeededProps<O>,\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n keyof UseChipsInputBaseProps<O> | 'defaultChecked'\n >,\n HasRef<HTMLInputElement>,\n HasAlign {\n /**\n * Ссылка на корневой элемент.\n */\n getRootRef?: React.Ref<HTMLDivElement>;\n /**\n * Добавляет значение в список на событие `onBlur`.\n */\n addOnBlur?: boolean;\n /**\n * Render prop функция для возврата своего компонента.\n *\n * @default Используется [Chip](#/Chip)\n */\n renderChip?: RenderChip<O>;\n /**\n * Показывать ли кнопку для очистки значения.\n */\n clearButtonShown?: boolean;\n /**\n * (e2e) testId кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Кастомная кнопка для очистки значения.\n * Должна принимать обязательное свойство `onClick`.\n */\n ClearButton?: React.ComponentType<FormFieldClearButtonProps>;\n}\n\n/**\n * @private\n */\nexport interface ChipsInputBasePrivateProps<O extends ChipOption = ChipOption>\n extends ChipsInputBaseProps<O>,\n Pick<FormFieldProps, 'mode' | 'status' | 'before' | 'after' | 'maxHeight'> {\n /**\n * Обработчик очистки всех выбранных опций.\n */\n onClear: () => void;\n /**\n * Обработчик добавления новой опции чипа.\n */\n onAddChipOption: (value: string) => void;\n /**\n * Обработчик удаления опции чипа.\n */\n onRemoveChipOption: (value: O | ChipOptionValue) => void;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ChipsInputBase/types.ts"],"sourcesContent":["import type * as React from 'react';\nimport type {\n HasAlign,\n HasComponent,\n HasDataAttribute,\n HasRef,\n HTMLAttributesWithRootRef,\n} from '../../types';\nimport { type FormFieldProps } from '../FormField/FormField';\nimport { type FormFieldClearButtonProps } from '../FormFieldClearButton/FormFieldClearButton';\n\nexport type NavigateTo = 'prev' | 'next' | 'last';\n\nexport type ChipOptionValue = string | number;\n\nexport type ChipOptionLabel = React.ReactElement | string | number;\n\nexport type ChipOption = {\n /**\n * Значение опции.\n */\n value: ChipOptionValue;\n /**\n * Отображаемый текст опции.\n */\n label: ChipOptionLabel;\n /**\n * Блокировка взаимодействия с оцией.\n */\n disabled?: boolean;\n [index: string]: any;\n};\n\nexport interface ChipProps\n extends HasComponent,\n HasDataAttribute,\n HTMLAttributesWithRootRef<HTMLElement> {\n /**\n * Значение чипа.\n */\n value?: ChipOptionValue;\n /**\n * Можно ли удалить чип.\n */\n removable?: boolean;\n /**\n * Блокировка взаимодействия с чипом.\n */\n disabled?: boolean;\n /**\n * Режим только для чтения.\n */\n readOnly?: boolean;\n /**\n * Текст для кнопки удаления.\n */\n removeLabel?: string;\n /**\n * Контент перед основным содержимым.\n */\n before?: React.ReactNode;\n /**\n * Контент после основного содержимого.\n */\n after?: React.ReactNode;\n /**\n * Обработчик удаления чипа.\n */\n onRemove?: (event: React.MouseEvent, value: ChipOptionValue) => void;\n}\n\nexport interface RenderChipProps extends ChipProps {\n /**\n * Отображаемый текст чипа.\n */\n label: ChipOptionLabel;\n}\n\nexport type RenderChip<O extends ChipOption = ChipOption> = (\n props: RenderChipProps,\n option: O,\n) => React.ReactNode;\n\nexport type GetOptionValue<O extends ChipOption = ChipOption> = (option: O) => ChipOptionValue;\n\nexport type GetOptionLabel<O extends ChipOption = ChipOption> = (option: O) => ChipOptionLabel;\n\nexport type GetNewOptionData<O extends ChipOption = ChipOption> = (\n value: ChipOptionValue,\n label: ChipOptionLabel,\n) => O;\n\nexport type OnChange<O extends ChipOption = ChipOption> = (value: O[]) => void;\n\nexport type OnInputChange = (event: React.ChangeEvent<HTMLInputElement>) => void;\n\n/**\n * @public\n */\nexport interface UseChipsInputBaseProps<O extends ChipOption = ChipOption> {\n /**\n * Блокировка взаимодействия с компонентом.\n */\n disabled?: boolean;\n /**\n * Выбранные опции.\n */\n value?: O[];\n /**\n * Выбранные опции по умолчанию.\n */\n defaultValue?: O[];\n /**\n * Обработчик изменения выбранных опций.\n */\n onChange?: OnChange<O>;\n /**\n * Значение поля ввода.\n */\n inputValue?: string;\n /**\n * Значение поля ввода по умолчанию.\n */\n defaultInputValue?: string;\n /**\n * Обработчик изменения значения в поле ввода.\n */\n onInputChange?: OnInputChange;\n /**\n * Символ или строка, которая будет использоваться как разделитель для автоматического создания опций из текста, введенного в поле ввода.\n * Принимает:\n * - `string` - простая строка\n * - `RegExp` - регулярное выражение\n * - `string[]` - массив строк, по которым нужно разелять ввод.\n *\n * Работает в двух сценариях:\n * 1. При вводе разделителя - текст до разделителя автоматически преобразуется в новую опцию.\n * Например, при `delimiter=\",\"` ввод \"опция1,\" создаст опцию \"опция1\".\n *\n * 2. При вставке из буфера обмена - если вставляемый текст содержит разделители,\n * он будет автоматически разбит на несколько опций.\n * Например, при `delimiter=\",\"` вставка \"опция1,опция2,опция3\" создаст\n * три отдельные опции: \"опция1\", \"опция2\" и \"опция3\".\n */\n delimiter?: string | RegExp | string[];\n}\n\n/**\n * @private\n */\ntype UseChipsInputBaseOnlyNeededProps<O extends ChipOption = ChipOption> = Omit<\n UseChipsInputBaseProps<O>,\n 'onChange' | 'defaultValue' | 'defaultInputValue'\n>;\n\n/**\n * @public\n */\nexport interface ChipsInputBaseProps<O extends ChipOption = ChipOption>\n extends UseChipsInputBaseOnlyNeededProps<O>,\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n keyof UseChipsInputBaseProps<O> | 'defaultChecked'\n >,\n HasRef<HTMLInputElement>,\n HasAlign {\n /**\n * Ссылка на корневой элемент.\n */\n getRootRef?: React.Ref<HTMLDivElement>;\n /**\n * Добавляет значение в список на событие `onBlur`.\n */\n addOnBlur?: boolean;\n /**\n * Render prop функция для возврата своего компонента.\n *\n * @default Используется [Chip](#/Chip)\n */\n renderChip?: RenderChip<O>;\n /**\n * Показывать ли кнопку для очистки значения.\n */\n clearButtonShown?: boolean;\n /**\n * (e2e) testId кнопки очистки.\n */\n clearButtonTestId?: string;\n /**\n * Кастомная кнопка для очистки значения.\n * Должна принимать обязательное свойство `onClick`.\n */\n ClearButton?: React.ComponentType<FormFieldClearButtonProps>;\n}\n\n/**\n * @private\n */\nexport interface ChipsInputBasePrivateProps<O extends ChipOption = ChipOption>\n extends ChipsInputBaseProps<O>,\n Pick<FormFieldProps, 'mode' | 'status' | 'before' | 'after' | 'maxHeight'> {\n /**\n * Обработчик очистки всех выбранных опций.\n */\n onClear: () => void;\n /**\n * Обработчик добавления новой опции чипа.\n */\n onAddChipOption: (value: string) => void;\n /**\n * Обработчик удаления опции чипа.\n */\n onRemoveChipOption: (value: O | ChipOptionValue) => void;\n}\n"],"names":[],"mappings":"AAmMA;;CAEC,GACD,WAeC"}
|
|
@@ -6,7 +6,8 @@ import { RealClickable } from "./RealClickable.js";
|
|
|
6
6
|
import styles from "./Clickable.module.css";
|
|
7
7
|
/**
|
|
8
8
|
* Некликабельный компонент. Отключаем возможность нажимать на компонент.
|
|
9
|
-
*/ const NonClickable = ({ href, onClick, onClickCapture, activeClassName, hoverClassName, hasActive, hasHover, hovered, unlockParentHover, activated, activeEffectDelay, focusVisibleMode, ...restProps })=>/*#__PURE__*/ _jsx(RootComponent, {
|
|
9
|
+
*/ const NonClickable = ({ href, onClick, onClickCapture, activeClassName, hoverClassName, hasActive, hasHover, hovered, unlockParentHover, activated, activeEffectDelay, focusVisibleMode, DefaultComponent, Component, ...restProps })=>/*#__PURE__*/ _jsx(RootComponent, {
|
|
10
|
+
Component: Component || DefaultComponent,
|
|
10
11
|
...restProps
|
|
11
12
|
});
|
|
12
13
|
/**
|
|
@@ -21,7 +22,7 @@ import styles from "./Clickable.module.css";
|
|
|
21
22
|
* - при передаче `href` превратится в `a`,
|
|
22
23
|
* - при передаче `onClick` превратится в `div` c `role="button"` и `tabIndex="0"`.
|
|
23
24
|
* - иначе используется `div`.
|
|
24
|
-
*/ function component({ Component, onClick, onClickCapture, href, disabled }) {
|
|
25
|
+
*/ function component({ Component, DefaultComponent = 'div', onClick, onClickCapture, href, disabled }) {
|
|
25
26
|
if (Component !== undefined) {
|
|
26
27
|
return {
|
|
27
28
|
Component,
|
|
@@ -45,7 +46,7 @@ import styles from "./Clickable.module.css";
|
|
|
45
46
|
};
|
|
46
47
|
} else if (onClick !== undefined || onClickCapture !== undefined) {
|
|
47
48
|
return {
|
|
48
|
-
Component:
|
|
49
|
+
Component: DefaultComponent,
|
|
49
50
|
role: 'button',
|
|
50
51
|
...disabled ? {
|
|
51
52
|
'aria-disabled': true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Clickable/Clickable.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { type FocusVisibleModeProps } from '../../hooks/useFocusVisibleClassName';\nimport { RootComponent, type RootComponentProps } from '../RootComponent/RootComponent';\nimport { RealClickable } from './RealClickable';\nimport { type StateProps } from './useState';\nimport styles from './Clickable.module.css';\n\nexport interface ClickableProps<T = HTMLElement>\n extends RootComponentProps<T>,\n FocusVisibleModeProps,\n StateProps {}\n\n/**\n * Некликабельный компонент. Отключаем возможность нажимать на компонент.\n */\nconst NonClickable = <T,>({\n href,\n onClick,\n onClickCapture,\n activeClassName,\n hoverClassName,\n hasActive,\n hasHover,\n hovered,\n unlockParentHover,\n activated,\n activeEffectDelay,\n focusVisibleMode,\n ...restProps\n}: ClickableProps<T>) => <RootComponent {...restProps} />;\n\n/**\n * Проверяем, является ли компонент кликабельным.\n */\nexport function checkClickable<T>(props: ClickableProps<T>): boolean {\n return (\n (props.href !== undefined ||\n props.onClick !== undefined ||\n props.onClickCapture !== undefined ||\n props.Component === 'a' ||\n props.Component === 'button' ||\n props.Component === 'label' ||\n props.Component === 'input') &&\n !props.disabled\n );\n}\n\n/**\n * Определяет правильный компонент и его свойства.\n *\n * - если передан Component, используем его\n * - при передаче `href` превратится в `a`,\n * - при передаче `onClick` превратится в `div` c `role=\"button\"` и `tabIndex=\"0\"`.\n * - иначе используется `div`.\n */\nfunction component<T>({\n Component,\n onClick,\n onClickCapture,\n href,\n disabled,\n}:
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Clickable/Clickable.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { type FocusVisibleModeProps } from '../../hooks/useFocusVisibleClassName';\nimport { RootComponent, type RootComponentProps } from '../RootComponent/RootComponent';\nimport { RealClickable } from './RealClickable';\nimport { type StateProps } from './useState';\nimport styles from './Clickable.module.css';\n\nexport interface ClickableProps<T = HTMLElement>\n extends RootComponentProps<T>,\n FocusVisibleModeProps,\n StateProps {\n /**\n * Компонент который будет при передаче `onClick`. По умолчанию `\"div\"`.\n */\n DefaultComponent?: React.ElementType;\n}\n\n/**\n * Некликабельный компонент. Отключаем возможность нажимать на компонент.\n */\nconst NonClickable = <T,>({\n href,\n onClick,\n onClickCapture,\n activeClassName,\n hoverClassName,\n hasActive,\n hasHover,\n hovered,\n unlockParentHover,\n activated,\n activeEffectDelay,\n focusVisibleMode,\n DefaultComponent,\n Component,\n ...restProps\n}: ClickableProps<T>) => <RootComponent Component={Component || DefaultComponent} {...restProps} />;\n\n/**\n * Проверяем, является ли компонент кликабельным.\n */\nexport function checkClickable<T>(props: ClickableProps<T>): boolean {\n return (\n (props.href !== undefined ||\n props.onClick !== undefined ||\n props.onClickCapture !== undefined ||\n props.Component === 'a' ||\n props.Component === 'button' ||\n props.Component === 'label' ||\n props.Component === 'input') &&\n !props.disabled\n );\n}\n\n/**\n * Определяет правильный компонент и его свойства.\n *\n * - если передан Component, используем его\n * - при передаче `href` превратится в `a`,\n * - при передаче `onClick` превратится в `div` c `role=\"button\"` и `tabIndex=\"0\"`.\n * - иначе используется `div`.\n */\nfunction component<T>({\n Component,\n DefaultComponent = 'div',\n onClick,\n onClickCapture,\n href,\n disabled,\n}: ClickableProps<T>): RootComponentProps<T> {\n if (Component !== undefined) {\n return { Component, disabled };\n } else if (href !== undefined) {\n return {\n Component: 'a',\n\n /**\n * Если ссылка отключена, добавляем атрибуты для доступности.\n *\n * - Тег `a` не поддерживает атрибут disabled, поэтому используем `aria-disabled`\n * - Тег `a` без `href` не является ссылкой, поэтому добавляем `role=\"link\"`.\n *\n * @see см. https://w3c.github.io/html-aria/#example-communicate-a-disabled-link-with-aria.\n *\n */\n ...(disabled && {\n 'aria-disabled': true,\n 'role': 'link',\n }),\n };\n } else if (onClick !== undefined || onClickCapture !== undefined) {\n return {\n Component: DefaultComponent,\n role: 'button',\n ...(disabled ? { 'aria-disabled': true } : { tabIndex: 0 }),\n };\n }\n\n return {};\n}\n\n/**\n * Базовый кликабельный корневой компонент.\n *\n * - при передаче `href` превратится в `a`,\n * - при передаче `onClick` превратится в `div` c `role=\"button\"` и `tabIndex=\"0\"`.\n * - иначе используется `div`.\n *\n * Отвечает за:\n *\n * - стейты наведения и нажатия\n * - a11y компонентов.\n */\nexport const Clickable = <T,>(props: ClickableProps<T>): React.ReactNode => {\n const commonProps = component(props);\n const isClickable = checkClickable(props);\n const Component = isClickable ? RealClickable : NonClickable;\n\n const {\n baseClassName,\n disabled, // Игнорируем disabled из пропсов, т.к. он обрабатывается в commonProps\n Component: ignore,\n ...restProps\n } = props;\n\n return (\n <Component\n baseClassName={classNames(baseClassName, styles.host)}\n {...commonProps}\n {...restProps}\n />\n );\n};\n"],"names":["React","classNames","RootComponent","RealClickable","styles","NonClickable","href","onClick","onClickCapture","activeClassName","hoverClassName","hasActive","hasHover","hovered","unlockParentHover","activated","activeEffectDelay","focusVisibleMode","DefaultComponent","Component","restProps","checkClickable","props","undefined","disabled","component","role","tabIndex","Clickable","commonProps","isClickable","baseClassName","ignore","host"],"mappings":";AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,QAAQ,kBAAkB;AAE7C,SAASC,aAAa,QAAiC,oCAAiC;AACxF,SAASC,aAAa,QAAQ,qBAAkB;AAEhD,OAAOC,YAAY,yBAAyB;AAY5C;;CAEC,GACD,MAAMC,eAAe,CAAK,EACxBC,IAAI,EACJC,OAAO,EACPC,cAAc,EACdC,eAAe,EACfC,cAAc,EACdC,SAAS,EACTC,QAAQ,EACRC,OAAO,EACPC,iBAAiB,EACjBC,SAAS,EACTC,iBAAiB,EACjBC,gBAAgB,EAChBC,gBAAgB,EAChBC,SAAS,EACT,GAAGC,WACe,iBAAK,KAAClB;QAAciB,WAAWA,aAAaD;QAAmB,GAAGE,SAAS;;AAE/F;;CAEC,GACD,OAAO,SAASC,eAAkBC,KAAwB;IACxD,OACE,AAACA,CAAAA,MAAMhB,IAAI,KAAKiB,aACdD,MAAMf,OAAO,KAAKgB,aAClBD,MAAMd,cAAc,KAAKe,aACzBD,MAAMH,SAAS,KAAK,OACpBG,MAAMH,SAAS,KAAK,YACpBG,MAAMH,SAAS,KAAK,WACpBG,MAAMH,SAAS,KAAK,OAAM,KAC5B,CAACG,MAAME,QAAQ;AAEnB;AAEA;;;;;;;CAOC,GACD,SAASC,UAAa,EACpBN,SAAS,EACTD,mBAAmB,KAAK,EACxBX,OAAO,EACPC,cAAc,EACdF,IAAI,EACJkB,QAAQ,EACU;IAClB,IAAIL,cAAcI,WAAW;QAC3B,OAAO;YAAEJ;YAAWK;QAAS;IAC/B,OAAO,IAAIlB,SAASiB,WAAW;QAC7B,OAAO;YACLJ,WAAW;YAEX;;;;;;;;OAQC,GACD,GAAIK,YAAY;gBACd,iBAAiB;gBACjB,QAAQ;YACV,CAAC;QACH;IACF,OAAO,IAAIjB,YAAYgB,aAAaf,mBAAmBe,WAAW;QAChE,OAAO;YACLJ,WAAWD;YACXQ,MAAM;YACN,GAAIF,WAAW;gBAAE,iBAAiB;YAAK,IAAI;gBAAEG,UAAU;YAAE,CAAC;QAC5D;IACF;IAEA,OAAO,CAAC;AACV;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,YAAY,CAAKN;IAC5B,MAAMO,cAAcJ,UAAUH;IAC9B,MAAMQ,cAAcT,eAAeC;IACnC,MAAMH,YAAYW,cAAc3B,gBAAgBE;IAEhD,MAAM,EACJ0B,aAAa,EACbP,QAAQ,EACRL,WAAWa,MAAM,EACjB,GAAGZ,WACJ,GAAGE;IAEJ,qBACE,KAACH;QACCY,eAAe9B,WAAW8B,eAAe3B,OAAO6B,IAAI;QACnD,GAAGJ,WAAW;QACd,GAAGT,SAAS;;AAGnB,EAAE"}
|
|
@@ -11,7 +11,7 @@ import { ClickableLockStateContext, DEFAULT_ACTIVE_EFFECT_DELAY, useState } from
|
|
|
11
11
|
import styles from "./Clickable.module.css";
|
|
12
12
|
/**
|
|
13
13
|
* Кликабельный компонент. Добавляем кучу обвесов.
|
|
14
|
-
*/ export const RealClickable = ({ baseClassName, children, focusVisibleMode = 'inside', activeClassName, hoverClassName, activeEffectDelay = DEFAULT_ACTIVE_EFFECT_DELAY, hasHover = true, hasActive = true, hovered, activated, hasHoverWithChildren, unlockParentHover, onPointerEnter, onPointerLeave, onPointerDown, onPointerCancel, onPointerUp, onBlur, onFocus, onKeyDown, ...restProps })=>{
|
|
14
|
+
*/ export const RealClickable = ({ baseClassName, children, focusVisibleMode = 'inside', activeClassName, hoverClassName, activeEffectDelay = DEFAULT_ACTIVE_EFFECT_DELAY, hasHover = true, hasActive = true, hovered, activated, hasHoverWithChildren, unlockParentHover, onPointerEnter, onPointerLeave, onPointerDown, onPointerCancel, onPointerUp, onBlur, onFocus, onKeyDown, DefaultComponent, ...restProps })=>{
|
|
15
15
|
const { focusVisible, ...focusEvents } = useFocusVisible();
|
|
16
16
|
const focusVisibleClassNames = useFocusVisibleClassName({
|
|
17
17
|
focusVisible,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/Clickable/RealClickable.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useFocusVisible } from '../../hooks/useFocusVisible';\nimport { useFocusVisibleClassName } from '../../hooks/useFocusVisibleClassName';\nimport { mergeCalls } from '../../lib/mergeCalls';\nimport { clickByKeyboardHandler } from '../../lib/utils';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { type ClickableProps } from './Clickable';\nimport { ClickableLockStateContext, DEFAULT_ACTIVE_EFFECT_DELAY, useState } from './useState';\nimport styles from './Clickable.module.css';\n\n/**\n * Кликабельный компонент. Добавляем кучу обвесов.\n */\nexport const RealClickable = <T,>({\n baseClassName,\n children,\n focusVisibleMode = 'inside',\n activeClassName,\n hoverClassName,\n activeEffectDelay = DEFAULT_ACTIVE_EFFECT_DELAY,\n hasHover = true,\n hasActive = true,\n hovered,\n activated,\n hasHoverWithChildren,\n unlockParentHover,\n onPointerEnter,\n onPointerLeave,\n onPointerDown,\n onPointerCancel,\n onPointerUp,\n onBlur,\n onFocus,\n onKeyDown,\n ...restProps\n}: ClickableProps<T>) => {\n const { focusVisible, ...focusEvents } = useFocusVisible();\n const focusVisibleClassNames = useFocusVisibleClassName({ focusVisible, mode: focusVisibleMode });\n\n const {\n stateClassName,\n setLockHoverBubblingImmediate,\n setLockActiveBubblingImmediate,\n ...stateEvents\n } = useState({\n activeClassName,\n hoverClassName,\n activeEffectDelay,\n hasHover,\n hasActive,\n hovered,\n activated,\n unlockParentHover,\n });\n\n const handlers = mergeCalls(\n focusEvents,\n stateEvents,\n { onKeyDown: clickByKeyboardHandler },\n {\n onPointerEnter,\n onPointerLeave,\n onPointerDown,\n onPointerCancel,\n onPointerUp,\n onBlur,\n onFocus,\n onKeyDown,\n },\n );\n\n const lockStateContextValue = React.useMemo(\n () => ({\n lockHoverStateBubbling: hasHoverWithChildren ? noop : setLockHoverBubblingImmediate,\n lockActiveStateBubbling: setLockActiveBubblingImmediate,\n }),\n [setLockHoverBubblingImmediate, setLockActiveBubblingImmediate, hasHoverWithChildren],\n );\n\n return (\n <RootComponent\n baseClassName={classNames(\n baseClassName,\n styles.realClickable,\n focusVisibleClassNames,\n stateClassName,\n )}\n {...handlers}\n {...restProps}\n >\n <ClickableLockStateContext.Provider value={lockStateContextValue}>\n {children}\n </ClickableLockStateContext.Provider>\n </RootComponent>\n );\n};\n"],"names":["React","classNames","noop","useFocusVisible","useFocusVisibleClassName","mergeCalls","clickByKeyboardHandler","RootComponent","ClickableLockStateContext","DEFAULT_ACTIVE_EFFECT_DELAY","useState","styles","RealClickable","baseClassName","children","focusVisibleMode","activeClassName","hoverClassName","activeEffectDelay","hasHover","hasActive","hovered","activated","hasHoverWithChildren","unlockParentHover","onPointerEnter","onPointerLeave","onPointerDown","onPointerCancel","onPointerUp","onBlur","onFocus","onKeyDown","restProps","focusVisible","focusEvents","focusVisibleClassNames","mode","stateClassName","setLockHoverBubblingImmediate","setLockActiveBubblingImmediate","stateEvents","handlers","lockStateContextValue","useMemo","lockHoverStateBubbling","lockActiveStateBubbling","realClickable","Provider","value"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,eAAe,QAAQ,iCAA8B;AAC9D,SAASC,wBAAwB,QAAQ,0CAAuC;AAChF,SAASC,UAAU,QAAQ,0BAAuB;AAClD,SAASC,sBAAsB,QAAQ,qBAAkB;AACzD,SAASC,aAAa,QAAQ,oCAAiC;AAE/D,SAASC,yBAAyB,EAAEC,2BAA2B,EAAEC,QAAQ,QAAQ,gBAAa;AAC9F,OAAOC,YAAY,yBAAyB;AAE5C;;CAEC,GACD,OAAO,MAAMC,gBAAgB,CAAK,EAChCC,aAAa,EACbC,QAAQ,EACRC,mBAAmB,QAAQ,EAC3BC,eAAe,EACfC,cAAc,EACdC,oBAAoBT,2BAA2B,EAC/CU,WAAW,IAAI,EACfC,YAAY,IAAI,EAChBC,OAAO,EACPC,SAAS,EACTC,oBAAoB,EACpBC,iBAAiB,EACjBC,cAAc,EACdC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,WAAW,EACXC,MAAM,EACNC,OAAO,EACPC,SAAS,
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/Clickable/RealClickable.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useFocusVisible } from '../../hooks/useFocusVisible';\nimport { useFocusVisibleClassName } from '../../hooks/useFocusVisibleClassName';\nimport { mergeCalls } from '../../lib/mergeCalls';\nimport { clickByKeyboardHandler } from '../../lib/utils';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { type ClickableProps } from './Clickable';\nimport { ClickableLockStateContext, DEFAULT_ACTIVE_EFFECT_DELAY, useState } from './useState';\nimport styles from './Clickable.module.css';\n\n/**\n * Кликабельный компонент. Добавляем кучу обвесов.\n */\nexport const RealClickable = <T,>({\n baseClassName,\n children,\n focusVisibleMode = 'inside',\n activeClassName,\n hoverClassName,\n activeEffectDelay = DEFAULT_ACTIVE_EFFECT_DELAY,\n hasHover = true,\n hasActive = true,\n hovered,\n activated,\n hasHoverWithChildren,\n unlockParentHover,\n onPointerEnter,\n onPointerLeave,\n onPointerDown,\n onPointerCancel,\n onPointerUp,\n onBlur,\n onFocus,\n onKeyDown,\n DefaultComponent,\n ...restProps\n}: ClickableProps<T>) => {\n const { focusVisible, ...focusEvents } = useFocusVisible();\n const focusVisibleClassNames = useFocusVisibleClassName({ focusVisible, mode: focusVisibleMode });\n\n const {\n stateClassName,\n setLockHoverBubblingImmediate,\n setLockActiveBubblingImmediate,\n ...stateEvents\n } = useState({\n activeClassName,\n hoverClassName,\n activeEffectDelay,\n hasHover,\n hasActive,\n hovered,\n activated,\n unlockParentHover,\n });\n\n const handlers = mergeCalls(\n focusEvents,\n stateEvents,\n { onKeyDown: clickByKeyboardHandler },\n {\n onPointerEnter,\n onPointerLeave,\n onPointerDown,\n onPointerCancel,\n onPointerUp,\n onBlur,\n onFocus,\n onKeyDown,\n },\n );\n\n const lockStateContextValue = React.useMemo(\n () => ({\n lockHoverStateBubbling: hasHoverWithChildren ? noop : setLockHoverBubblingImmediate,\n lockActiveStateBubbling: setLockActiveBubblingImmediate,\n }),\n [setLockHoverBubblingImmediate, setLockActiveBubblingImmediate, hasHoverWithChildren],\n );\n\n return (\n <RootComponent\n baseClassName={classNames(\n baseClassName,\n styles.realClickable,\n focusVisibleClassNames,\n stateClassName,\n )}\n {...handlers}\n {...restProps}\n >\n <ClickableLockStateContext.Provider value={lockStateContextValue}>\n {children}\n </ClickableLockStateContext.Provider>\n </RootComponent>\n );\n};\n"],"names":["React","classNames","noop","useFocusVisible","useFocusVisibleClassName","mergeCalls","clickByKeyboardHandler","RootComponent","ClickableLockStateContext","DEFAULT_ACTIVE_EFFECT_DELAY","useState","styles","RealClickable","baseClassName","children","focusVisibleMode","activeClassName","hoverClassName","activeEffectDelay","hasHover","hasActive","hovered","activated","hasHoverWithChildren","unlockParentHover","onPointerEnter","onPointerLeave","onPointerDown","onPointerCancel","onPointerUp","onBlur","onFocus","onKeyDown","DefaultComponent","restProps","focusVisible","focusEvents","focusVisibleClassNames","mode","stateClassName","setLockHoverBubblingImmediate","setLockActiveBubblingImmediate","stateEvents","handlers","lockStateContextValue","useMemo","lockHoverStateBubbling","lockActiveStateBubbling","realClickable","Provider","value"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,eAAe,QAAQ,iCAA8B;AAC9D,SAASC,wBAAwB,QAAQ,0CAAuC;AAChF,SAASC,UAAU,QAAQ,0BAAuB;AAClD,SAASC,sBAAsB,QAAQ,qBAAkB;AACzD,SAASC,aAAa,QAAQ,oCAAiC;AAE/D,SAASC,yBAAyB,EAAEC,2BAA2B,EAAEC,QAAQ,QAAQ,gBAAa;AAC9F,OAAOC,YAAY,yBAAyB;AAE5C;;CAEC,GACD,OAAO,MAAMC,gBAAgB,CAAK,EAChCC,aAAa,EACbC,QAAQ,EACRC,mBAAmB,QAAQ,EAC3BC,eAAe,EACfC,cAAc,EACdC,oBAAoBT,2BAA2B,EAC/CU,WAAW,IAAI,EACfC,YAAY,IAAI,EAChBC,OAAO,EACPC,SAAS,EACTC,oBAAoB,EACpBC,iBAAiB,EACjBC,cAAc,EACdC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,WAAW,EACXC,MAAM,EACNC,OAAO,EACPC,SAAS,EACTC,gBAAgB,EAChB,GAAGC,WACe;IAClB,MAAM,EAAEC,YAAY,EAAE,GAAGC,aAAa,GAAGjC;IACzC,MAAMkC,yBAAyBjC,yBAAyB;QAAE+B;QAAcG,MAAMvB;IAAiB;IAE/F,MAAM,EACJwB,cAAc,EACdC,6BAA6B,EAC7BC,8BAA8B,EAC9B,GAAGC,aACJ,GAAGhC,SAAS;QACXM;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAE;IACF;IAEA,MAAMmB,WAAWtC,WACf+B,aACAM,aACA;QAAEV,WAAW1B;IAAuB,GACpC;QACEmB;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;IAGF,MAAMY,wBAAwB5C,MAAM6C,OAAO,CACzC,IAAO,CAAA;YACLC,wBAAwBvB,uBAAuBrB,OAAOsC;YACtDO,yBAAyBN;QAC3B,CAAA,GACA;QAACD;QAA+BC;QAAgClB;KAAqB;IAGvF,qBACE,KAAChB;QACCM,eAAeZ,WACbY,eACAF,OAAOqC,aAAa,EACpBX,wBACAE;QAED,GAAGI,QAAQ;QACX,GAAGT,SAAS;kBAEb,cAAA,KAAC1B,0BAA0ByC,QAAQ;YAACC,OAAON;sBACxC9B;;;AAIT,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ContentCard/ContentCard.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { getFetchPriorityProp } from '../../lib/utils';\nimport type { HasComponent, HasRef, HasRootRef } from '../../types';\nimport { Card, type CardProps } from '../Card/Card';\nimport { Tappable, type
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ContentCard/ContentCard.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { getFetchPriorityProp } from '../../lib/utils';\nimport type { HasComponent, HasRef, HasRootRef } from '../../types';\nimport { Card, type CardProps } from '../Card/Card';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport { Caption } from '../Typography/Caption/Caption';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Text } from '../Typography/Text/Text';\nimport styles from './ContentCard.module.css';\n\nexport interface ContentCardProps\n extends HasRootRef<HTMLDivElement>,\n HasComponent,\n Omit<TappableOmitProps, 'getRootRef' | 'crossOrigin' | 'title'>,\n Omit<React.ImgHTMLAttributes<HTMLImageElement>, keyof React.HTMLAttributes<HTMLImageElement>>,\n HasRef<HTMLImageElement> {\n /**\n Текст над заголовком.\n */\n overTitle?: React.ReactNode;\n /**\n Заголовок.\n */\n title?: React.ReactNode;\n /**\n Позволяет поменять тег используемый для заголовка.\n */\n titleComponent?: React.ElementType;\n /**\n Текст.\n */\n description?: React.ReactNode;\n /**\n Нижний текст.\n */\n caption?: React.ReactNode;\n /**\n Максимальная высота изображения.\n */\n maxHeight?: number;\n /**\n * Внешний вид карточки.\n */\n mode?: CardProps['mode'];\n /**\n * Пользовательское значения стиля `object-fit` для картинки\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-fit).\n */\n imageObjectFit?: React.CSSProperties['objectFit'];\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ContentCard\n */\nexport const ContentCard = ({\n overTitle,\n title,\n titleComponent = 'span',\n description,\n caption,\n // card props\n className,\n mode = 'shadow',\n style,\n getRootRef,\n // img props\n getRef,\n maxHeight,\n src,\n srcSet,\n alt = '',\n width = '100%',\n height,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n useMap,\n fetchPriority,\n imageObjectFit,\n hasHover = false,\n hasActive = false,\n Component = 'li',\n ...restProps\n}: ContentCardProps): React.ReactNode => {\n return (\n <Card\n mode={mode}\n getRootRef={getRootRef}\n Component={Component}\n style={style}\n className={classNames(restProps.disabled && styles.disabled, className)}\n >\n <Tappable\n hasHover={hasHover}\n hasActive={hasActive}\n {...restProps}\n baseClassName={styles.tappable}\n >\n {(src || srcSet) && (\n <img\n ref={getRef}\n className={styles.img}\n src={src}\n srcSet={srcSet}\n alt={alt}\n crossOrigin={crossOrigin}\n decoding={decoding}\n loading={loading}\n referrerPolicy={referrerPolicy}\n sizes={sizes}\n useMap={useMap}\n {...getFetchPriorityProp(fetchPriority)}\n height={height}\n width={width}\n style={{ maxHeight, objectFit: imageObjectFit }}\n />\n )}\n <div className={styles.body}>\n {hasReactNode(overTitle) && (\n <Caption\n className={classNames(styles.text, styles.overTitle)}\n weight=\"1\"\n level=\"3\"\n caps\n >\n {overTitle}\n </Caption>\n )}\n {hasReactNode(title) && (\n <Headline className={styles.text} weight=\"2\" level=\"1\" Component={titleComponent}>\n {title}\n </Headline>\n )}\n {hasReactNode(description) && <Text className={styles.text}>{description}</Text>}\n {hasReactNode(caption) && (\n <Footnote className={classNames(styles.text, styles.caption)}>{caption}</Footnote>\n )}\n </div>\n </Tappable>\n </Card>\n );\n};\n"],"names":["React","classNames","hasReactNode","getFetchPriorityProp","Card","Tappable","Caption","Footnote","Headline","Text","styles","ContentCard","overTitle","title","titleComponent","description","caption","className","mode","style","getRootRef","getRef","maxHeight","src","srcSet","alt","width","height","crossOrigin","decoding","loading","referrerPolicy","sizes","useMap","fetchPriority","imageObjectFit","hasHover","hasActive","Component","restProps","disabled","baseClassName","tappable","img","ref","objectFit","div","body","text","weight","level","caps"],"mappings":";AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,YAAY,QAAQ,kBAAkB;AAC3D,SAASC,oBAAoB,QAAQ,qBAAkB;AAEvD,SAASC,IAAI,QAAwB,kBAAe;AACpD,SAASC,QAAQ,QAAgC,0BAAuB;AACxE,SAASC,OAAO,QAAQ,mCAAgC;AACxD,SAASC,QAAQ,QAAQ,qCAAkC;AAC3D,SAASC,QAAQ,QAAQ,qCAAkC;AAC3D,SAASC,IAAI,QAAQ,6BAA0B;AAC/C,OAAOC,YAAY,2BAA2B;AA2C9C;;CAEC,GACD,OAAO,MAAMC,cAAc,CAAC,EAC1BC,SAAS,EACTC,KAAK,EACLC,iBAAiB,MAAM,EACvBC,WAAW,EACXC,OAAO,EACP,aAAa;AACbC,SAAS,EACTC,OAAO,QAAQ,EACfC,KAAK,EACLC,UAAU,EACV,YAAY;AACZC,MAAM,EACNC,SAAS,EACTC,GAAG,EACHC,MAAM,EACNC,MAAM,EAAE,EACRC,QAAQ,MAAM,EACdC,MAAM,EACNC,WAAW,EACXC,QAAQ,EACRC,OAAO,EACPC,cAAc,EACdC,KAAK,EACLC,MAAM,EACNC,aAAa,EACbC,cAAc,EACdC,WAAW,KAAK,EAChBC,YAAY,KAAK,EACjBC,YAAY,IAAI,EAChB,GAAGC,WACc;IACjB,qBACE,KAACnC;QACCc,MAAMA;QACNE,YAAYA;QACZkB,WAAWA;QACXnB,OAAOA;QACPF,WAAWhB,WAAWsC,UAAUC,QAAQ,IAAI9B,OAAO8B,QAAQ,EAAEvB;kBAE7D,cAAA,MAACZ;YACC+B,UAAUA;YACVC,WAAWA;YACV,GAAGE,SAAS;YACbE,eAAe/B,OAAOgC,QAAQ;;gBAE5BnB,CAAAA,OAAOC,MAAK,mBACZ,KAACmB;oBACCC,KAAKvB;oBACLJ,WAAWP,OAAOiC,GAAG;oBACrBpB,KAAKA;oBACLC,QAAQA;oBACRC,KAAKA;oBACLG,aAAaA;oBACbC,UAAUA;oBACVC,SAASA;oBACTC,gBAAgBA;oBAChBC,OAAOA;oBACPC,QAAQA;oBACP,GAAG9B,qBAAqB+B,cAAc;oBACvCP,QAAQA;oBACRD,OAAOA;oBACPP,OAAO;wBAAEG;wBAAWuB,WAAWV;oBAAe;;8BAGlD,MAACW;oBAAI7B,WAAWP,OAAOqC,IAAI;;wBACxB7C,aAAaU,4BACZ,KAACN;4BACCW,WAAWhB,WAAWS,OAAOsC,IAAI,EAAEtC,OAAOE,SAAS;4BACnDqC,QAAO;4BACPC,OAAM;4BACNC,IAAI;sCAEHvC;;wBAGJV,aAAaW,wBACZ,KAACL;4BAASS,WAAWP,OAAOsC,IAAI;4BAAEC,QAAO;4BAAIC,OAAM;4BAAIZ,WAAWxB;sCAC/DD;;wBAGJX,aAAaa,8BAAgB,KAACN;4BAAKQ,WAAWP,OAAOsC,IAAI;sCAAGjC;;wBAC5Db,aAAac,0BACZ,KAACT;4BAASU,WAAWhB,WAAWS,OAAOsC,IAAI,EAAEtC,OAAOM,OAAO;sCAAIA;;;;;;;AAM3E,EAAE"}
|