@lobehub/ui 5.51.2 → 5.52.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/es/Accordion/Accordion.mjs +1 -1
- package/es/Accordion/Accordion.mjs.map +1 -1
- package/es/ActionIconGroup/type.d.mts +2 -1
- package/es/Alert/Alert.mjs +1 -1
- package/es/AutoComplete/Select.mjs +1 -1
- package/es/Avatar/Avatar.mjs +2 -2
- package/es/Burger/Burger.mjs +2 -2
- package/es/Burger/Burger.mjs.map +1 -1
- package/es/Button/Button.mjs +1 -1
- package/es/CodeDiff/DiffPanel.mjs +1 -1
- package/es/CodeDiff/DiffPanel.mjs.map +1 -1
- package/es/Collapse/Collapse.mjs +1 -1
- package/es/ColorSwatches/ColorSwatches.mjs +21 -21
- package/es/ColorSwatches/ColorSwatches.mjs.map +1 -1
- package/es/ColorSwatches/style.mjs +3 -12
- package/es/ColorSwatches/style.mjs.map +1 -1
- package/es/DatePicker/DatePicker.mjs +1 -1
- package/es/DraggablePanel/DraggablePanel.mjs +1 -1
- package/es/Drawer/Drawer.mjs +1 -1
- package/es/EditableText/ControlInput.d.mts +2 -2
- package/es/EditableText/ControlInput.mjs +1 -1
- package/es/EditableText/ControlInput.mjs.map +1 -1
- package/es/EditableText/EditableText.mjs +1 -0
- package/es/EditableText/EditableText.mjs.map +1 -1
- package/es/EditableText/type.d.mts +5 -1
- package/es/EmojiPicker/AvatarUploader.mjs +76 -71
- package/es/EmojiPicker/AvatarUploader.mjs.map +1 -1
- package/es/EmojiPicker/EmojiPicker.mjs +12 -6
- package/es/EmojiPicker/EmojiPicker.mjs.map +1 -1
- package/es/EmojiPicker/style.mjs +32 -9
- package/es/EmojiPicker/style.mjs.map +1 -1
- package/es/EmojiPicker/type.d.mts +2 -1
- package/es/Form/Form.mjs +1 -1
- package/es/Form/components/FormDivider.mjs +1 -1
- package/es/Form/components/FormItem.mjs +1 -1
- package/es/Form/components/FormSubmitFooter.mjs +1 -1
- package/es/Form/components/FormTitle.mjs +1 -1
- package/es/GroupAvatar/GroupAvatar.mjs +1 -1
- package/es/GroupAvatar/GroupAvatar.mjs.map +1 -1
- package/es/GroupAvatar/type.d.mts +2 -1
- package/es/Highlighter/Highlighter.mjs +1 -1
- package/es/Highlighter/Highlighter.mjs.map +1 -1
- package/es/Highlighter/LangSelect.mjs +23 -13
- package/es/Highlighter/LangSelect.mjs.map +1 -1
- package/es/Highlighter/style.mjs +1 -1
- package/es/Highlighter/style.mjs.map +1 -1
- package/es/HtmlPreview/HtmlPreview.mjs +28 -1
- package/es/HtmlPreview/HtmlPreview.mjs.map +1 -1
- package/es/Image/viewer/ImageViewer.mjs +1 -1
- package/es/Image/viewer/ImageViewer.mjs.map +1 -1
- package/es/Image/viewer/Toolbar.mjs +1 -1
- package/es/Input/Input.mjs +1 -1
- package/es/Input/InputNumber.mjs +1 -1
- package/es/Input/InputOPT.mjs +1 -1
- package/es/Input/InputPassword.mjs +1 -1
- package/es/Input/TextArea.mjs +1 -1
- package/es/Menu/Menu.mjs +1 -1
- package/es/Menu/index.d.mts +2 -1
- package/es/Menu/index.mjs +1 -1
- package/es/Menu/itemInterface.d.mts +71 -0
- package/es/Menu/type.d.mts +8 -8
- package/es/Mermaid/Mermaid.mjs +1 -1
- package/es/Mermaid/Mermaid.mjs.map +1 -1
- package/es/Modal/Modal.mjs +1 -1
- package/es/SearchBar/SearchBar.mjs +1 -1
- package/es/SearchBar/SearchBar.mjs.map +1 -1
- package/es/SearchBar/type.d.mts +2 -2
- package/es/Segmented/Segmented.mjs +1 -1
- package/es/Select/Select.mjs +1 -1
- package/es/SliderWithInput/SliderWithInput.mjs +1 -1
- package/es/Tabs/Tabs.mjs +1 -1
- package/es/Tag/Tag.mjs +1 -1
- package/es/ThemeProvider/ConfigProvider.mjs +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs +1 -1
- package/es/ThemeSwitch/ThemeSwitch.mjs +1 -1
- package/es/Toc/Toc.mjs +1 -1
- package/es/Toc/TocMobile.mjs +1 -1
- package/es/awesome/AgentSkillCard/AgentSkillCard.mjs +1 -1
- package/es/awesome/Hero/Hero.mjs +1 -1
- package/es/awesome/LandingSection/LandingSection.mjs +1 -1
- package/es/base-ui/Anchor/Anchor.d.mts +6 -0
- package/es/base-ui/Anchor/Anchor.mjs +141 -0
- package/es/base-ui/Anchor/Anchor.mjs.map +1 -0
- package/es/base-ui/Anchor/index.d.mts +3 -0
- package/es/base-ui/Anchor/style.mjs +80 -0
- package/es/base-ui/Anchor/style.mjs.map +1 -0
- package/es/base-ui/Anchor/type.d.mts +20 -0
- package/es/base-ui/AutoComplete/AutoComplete.mjs.map +1 -1
- package/es/base-ui/Avatar/Avatar.mjs +1 -1
- package/es/base-ui/Breadcrumb/Breadcrumb.d.mts +6 -0
- package/es/base-ui/Breadcrumb/Breadcrumb.mjs +58 -0
- package/es/base-ui/Breadcrumb/Breadcrumb.mjs.map +1 -0
- package/es/base-ui/Breadcrumb/index.d.mts +3 -0
- package/es/base-ui/Breadcrumb/style.mjs +65 -0
- package/es/base-ui/Breadcrumb/style.mjs.map +1 -0
- package/es/base-ui/Breadcrumb/type.d.mts +24 -0
- package/es/base-ui/Burger/Burger.d.mts +6 -0
- package/es/base-ui/Burger/Burger.mjs +69 -0
- package/es/base-ui/Burger/Burger.mjs.map +1 -0
- package/es/base-ui/Burger/index.d.mts +3 -0
- package/es/base-ui/Burger/style.mjs +63 -0
- package/es/base-ui/Burger/style.mjs.map +1 -0
- package/es/base-ui/Burger/type.d.mts +23 -0
- package/es/base-ui/Carousel/Carousel.d.mts +6 -0
- package/es/base-ui/Carousel/Carousel.mjs +157 -0
- package/es/base-ui/Carousel/Carousel.mjs.map +1 -0
- package/es/base-ui/Carousel/index.d.mts +3 -0
- package/es/base-ui/Carousel/style.mjs +88 -0
- package/es/base-ui/Carousel/style.mjs.map +1 -0
- package/es/base-ui/Carousel/type.d.mts +23 -0
- package/es/base-ui/ColorPicker/ColorPicker.d.mts +6 -0
- package/es/base-ui/ColorPicker/ColorPicker.mjs +227 -0
- package/es/base-ui/ColorPicker/ColorPicker.mjs.map +1 -0
- package/es/base-ui/ColorPicker/SaturationArea.mjs +64 -0
- package/es/base-ui/ColorPicker/SaturationArea.mjs.map +1 -0
- package/es/base-ui/ColorPicker/color.mjs +28 -0
- package/es/base-ui/ColorPicker/color.mjs.map +1 -0
- package/es/base-ui/ColorPicker/index.d.mts +3 -0
- package/es/base-ui/ColorPicker/style.mjs +180 -0
- package/es/base-ui/ColorPicker/style.mjs.map +1 -0
- package/es/base-ui/ColorPicker/type.d.mts +20 -0
- package/es/base-ui/ContextMenu/ContextMenuHost.mjs.map +1 -1
- package/es/base-ui/ContextMenu/renderItems.d.mts +0 -1
- package/es/base-ui/ContextMenu/renderItems.mjs.map +1 -1
- package/es/base-ui/DatePicker/CalendarPanel.mjs +188 -0
- package/es/base-ui/DatePicker/CalendarPanel.mjs.map +1 -0
- package/es/base-ui/DatePicker/DatePicker.d.mts +6 -0
- package/es/base-ui/DatePicker/DatePicker.mjs +88 -0
- package/es/base-ui/DatePicker/DatePicker.mjs.map +1 -0
- package/es/base-ui/DatePicker/DateRangePicker.d.mts +6 -0
- package/es/base-ui/DatePicker/DateRangePicker.mjs +128 -0
- package/es/base-ui/DatePicker/DateRangePicker.mjs.map +1 -0
- package/es/base-ui/DatePicker/PickerShell.mjs +43 -0
- package/es/base-ui/DatePicker/PickerShell.mjs.map +1 -0
- package/es/base-ui/DatePicker/calendar.d.mts +5 -0
- package/es/base-ui/DatePicker/calendar.mjs +46 -0
- package/es/base-ui/DatePicker/calendar.mjs.map +1 -0
- package/es/base-ui/DatePicker/index.d.mts +5 -0
- package/es/base-ui/DatePicker/style.mjs +193 -0
- package/es/base-ui/DatePicker/style.mjs.map +1 -0
- package/es/base-ui/DatePicker/type.d.mts +35 -0
- package/es/base-ui/Descriptions/Descriptions.d.mts +6 -0
- package/es/base-ui/Descriptions/Descriptions.mjs +62 -0
- package/es/base-ui/Descriptions/Descriptions.mjs.map +1 -0
- package/es/base-ui/Descriptions/index.d.mts +3 -0
- package/es/base-ui/Descriptions/style.mjs +64 -0
- package/es/base-ui/Descriptions/style.mjs.map +1 -0
- package/es/base-ui/Descriptions/type.d.mts +28 -0
- package/es/base-ui/Divider/Divider.d.mts +6 -0
- package/es/base-ui/Divider/Divider.mjs +30 -0
- package/es/base-ui/Divider/Divider.mjs.map +1 -0
- package/es/base-ui/Divider/index.d.mts +3 -0
- package/es/base-ui/Divider/style.mjs +59 -0
- package/es/base-ui/Divider/style.mjs.map +1 -0
- package/es/base-ui/Divider/type.d.mts +12 -0
- package/es/base-ui/Drawer/atoms.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/atoms.mjs +1 -1
- package/es/base-ui/DropdownMenu/atoms.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/renderItems.d.mts +0 -1
- package/es/base-ui/DropdownMenu/renderItems.mjs.map +1 -1
- package/es/base-ui/Form/components/FormTitle.mjs +1 -1
- package/es/base-ui/Form/components/FormTitle.mjs.map +1 -1
- package/es/base-ui/Form/type.d.mts +2 -2
- package/es/base-ui/Input/ClearButton.mjs +32 -0
- package/es/base-ui/Input/ClearButton.mjs.map +1 -0
- package/es/base-ui/Input/Input.mjs +30 -4
- package/es/base-ui/Input/Input.mjs.map +1 -1
- package/es/base-ui/Input/InputNumber.mjs +43 -22
- package/es/base-ui/Input/InputNumber.mjs.map +1 -1
- package/es/base-ui/Input/TextArea.mjs +50 -13
- package/es/base-ui/Input/TextArea.mjs.map +1 -1
- package/es/base-ui/Input/clearNativeValue.mjs +12 -0
- package/es/base-ui/Input/clearNativeValue.mjs.map +1 -0
- package/es/base-ui/Input/pressEnter.mjs +6 -0
- package/es/base-ui/Input/pressEnter.mjs.map +1 -0
- package/es/base-ui/Input/style.d.mts +5 -1
- package/es/base-ui/Input/style.mjs +67 -4
- package/es/base-ui/Input/style.mjs.map +1 -1
- package/es/base-ui/Input/type.d.mts +13 -2
- package/es/base-ui/List/List.d.mts +6 -0
- package/es/base-ui/List/List.mjs +50 -0
- package/es/base-ui/List/List.mjs.map +1 -0
- package/es/base-ui/List/ListRow.mjs +74 -0
- package/es/base-ui/List/ListRow.mjs.map +1 -0
- package/es/base-ui/List/index.d.mts +3 -0
- package/es/base-ui/List/style.mjs +146 -0
- package/es/base-ui/List/style.mjs.map +1 -0
- package/es/base-ui/List/type.d.mts +48 -0
- package/es/base-ui/Modal/atoms.mjs.map +1 -1
- package/es/base-ui/Modal/imperative.mjs +1 -1
- package/es/base-ui/Modal/imperative.mjs.map +1 -1
- package/es/base-ui/Modal/type.d.mts +1 -0
- package/es/base-ui/Popover/PopoverPortal.mjs.map +1 -1
- package/es/base-ui/Progress/Progress.mjs +16 -14
- package/es/base-ui/Progress/Progress.mjs.map +1 -1
- package/es/base-ui/Progress/style.mjs +16 -25
- package/es/base-ui/Progress/style.mjs.map +1 -1
- package/es/base-ui/QRCode/QRCode.d.mts +6 -0
- package/es/base-ui/QRCode/QRCode.mjs +105 -0
- package/es/base-ui/QRCode/QRCode.mjs.map +1 -0
- package/es/base-ui/QRCode/index.d.mts +3 -0
- package/es/base-ui/QRCode/qrPath.mjs +16 -0
- package/es/base-ui/QRCode/qrPath.mjs.map +1 -0
- package/es/base-ui/QRCode/style.mjs +52 -0
- package/es/base-ui/QRCode/style.mjs.map +1 -0
- package/es/base-ui/QRCode/type.d.mts +19 -0
- package/es/base-ui/Rate/Rate.d.mts +6 -0
- package/es/base-ui/Rate/Rate.mjs +111 -0
- package/es/base-ui/Rate/Rate.mjs.map +1 -0
- package/es/base-ui/Rate/index.d.mts +3 -0
- package/es/base-ui/Rate/style.mjs +81 -0
- package/es/base-ui/Rate/style.mjs.map +1 -0
- package/es/base-ui/Rate/type.d.mts +19 -0
- package/es/base-ui/Select/atoms.mjs.map +1 -1
- package/es/base-ui/Select/hooks.mjs.map +1 -1
- package/es/base-ui/Statistic/Statistic.d.mts +6 -0
- package/es/base-ui/Statistic/Statistic.mjs +42 -0
- package/es/base-ui/Statistic/Statistic.mjs.map +1 -0
- package/es/base-ui/Statistic/formatValue.d.mts +5 -0
- package/es/base-ui/Statistic/formatValue.mjs +23 -0
- package/es/base-ui/Statistic/formatValue.mjs.map +1 -0
- package/es/base-ui/Statistic/index.d.mts +4 -0
- package/es/base-ui/Statistic/style.mjs +34 -0
- package/es/base-ui/Statistic/style.mjs.map +1 -0
- package/es/base-ui/Statistic/type.d.mts +23 -0
- package/es/base-ui/Steps/Steps.d.mts +6 -0
- package/es/base-ui/Steps/Steps.mjs +74 -0
- package/es/base-ui/Steps/Steps.mjs.map +1 -0
- package/es/base-ui/Steps/index.d.mts +3 -0
- package/es/base-ui/Steps/style.mjs +155 -0
- package/es/base-ui/Steps/style.mjs.map +1 -0
- package/es/base-ui/Steps/type.d.mts +32 -0
- package/es/base-ui/Table/FilterMenu.mjs +45 -0
- package/es/base-ui/Table/FilterMenu.mjs.map +1 -0
- package/es/base-ui/Table/Table.d.mts +10 -0
- package/es/base-ui/Table/Table.mjs +134 -0
- package/es/base-ui/Table/Table.mjs.map +1 -0
- package/es/base-ui/Table/TableBody.mjs +59 -0
- package/es/base-ui/Table/TableBody.mjs.map +1 -0
- package/es/base-ui/Table/TableHead.mjs +50 -0
- package/es/base-ui/Table/TableHead.mjs.map +1 -0
- package/es/base-ui/Table/features.mjs +12 -0
- package/es/base-ui/Table/features.mjs.map +1 -0
- package/es/base-ui/Table/fixedOffsets.mjs +29 -0
- package/es/base-ui/Table/fixedOffsets.mjs.map +1 -0
- package/es/base-ui/Table/index.d.mts +3 -0
- package/es/base-ui/Table/style.mjs +168 -0
- package/es/base-ui/Table/style.mjs.map +1 -0
- package/es/base-ui/Table/toColumnDefs.mjs +26 -0
- package/es/base-ui/Table/toColumnDefs.mjs.map +1 -0
- package/es/base-ui/Table/type.d.mts +68 -0
- package/es/base-ui/Table/useTableState.mjs +99 -0
- package/es/base-ui/Table/useTableState.mjs.map +1 -0
- package/es/base-ui/Toast/imperative.mjs.map +1 -1
- package/es/base-ui/Tooltip/TooltipGroup.mjs.map +1 -1
- package/es/base-ui/Tooltip/TooltipStandalone.mjs.map +1 -1
- package/es/base-ui/index.d.mts +66 -21
- package/es/base-ui/index.mjs +42 -26
- package/es/base-ui/panelStyles.mjs +95 -0
- package/es/base-ui/panelStyles.mjs.map +1 -0
- package/es/chat/ChatList/components/HistoryDivider.mjs +9 -6
- package/es/chat/ChatList/components/HistoryDivider.mjs.map +1 -1
- package/es/chat/MessageModal/MessageModal.mjs +1 -1
- package/es/chat/TokenTag/TokenTag.mjs +1 -1
- package/es/color/CssVar/VarRow.mjs +1 -1
- package/es/color/CssVar/index.mjs +1 -1
- package/es/dashboard/FilterSidebar/FilterSidebar.mjs +1 -1
- package/es/i18n/resources/en/burger.d.mts +8 -0
- package/es/i18n/resources/en/burger.mjs +9 -0
- package/es/i18n/resources/en/burger.mjs.map +1 -0
- package/es/i18n/resources/en/colorPicker.d.mts +12 -0
- package/es/i18n/resources/en/colorPicker.mjs +13 -0
- package/es/i18n/resources/en/colorPicker.mjs.map +1 -0
- package/es/i18n/resources/en/common.d.mts +1 -0
- package/es/i18n/resources/en/common.mjs +1 -0
- package/es/i18n/resources/en/common.mjs.map +1 -1
- package/es/i18n/resources/en/datePicker.d.mts +13 -0
- package/es/i18n/resources/en/datePicker.mjs +14 -0
- package/es/i18n/resources/en/datePicker.mjs.map +1 -0
- package/es/i18n/resources/en/index.d.mts +15 -11
- package/es/i18n/resources/en/index.mjs +9 -1
- package/es/i18n/resources/en/index.mjs.map +1 -1
- package/es/i18n/resources/en/qrCode.d.mts +9 -0
- package/es/i18n/resources/en/qrCode.mjs +10 -0
- package/es/i18n/resources/en/qrCode.mjs.map +1 -0
- package/es/i18n/resources/zhCn/burger.d.mts +8 -0
- package/es/i18n/resources/zhCn/burger.mjs +9 -0
- package/es/i18n/resources/zhCn/burger.mjs.map +1 -0
- package/es/i18n/resources/zhCn/colorPicker.d.mts +12 -0
- package/es/i18n/resources/zhCn/colorPicker.mjs +13 -0
- package/es/i18n/resources/zhCn/colorPicker.mjs.map +1 -0
- package/es/i18n/resources/zhCn/common.d.mts +1 -0
- package/es/i18n/resources/zhCn/common.mjs +1 -0
- package/es/i18n/resources/zhCn/common.mjs.map +1 -1
- package/es/i18n/resources/zhCn/datePicker.d.mts +13 -0
- package/es/i18n/resources/zhCn/datePicker.mjs +14 -0
- package/es/i18n/resources/zhCn/datePicker.mjs.map +1 -0
- package/es/i18n/resources/zhCn/index.d.mts +15 -11
- package/es/i18n/resources/zhCn/index.mjs +9 -1
- package/es/i18n/resources/zhCn/index.mjs.map +1 -1
- package/es/i18n/resources/zhCn/qrCode.d.mts +9 -0
- package/es/i18n/resources/zhCn/qrCode.mjs +10 -0
- package/es/i18n/resources/zhCn/qrCode.mjs.map +1 -0
- package/es/i18n/types.d.mts +14 -10
- package/es/index.d.mts +12 -11
- package/es/index.mjs +23 -23
- package/es/mdx/Cards/Card.d.mts +2 -2
- package/es/mdx/Cards/Card.mjs +1 -1
- package/es/mdx/Cards/Card.mjs.map +1 -1
- package/es/mdx/Mdx/index.mjs +1 -1
- package/es/mdx/Mdx/index.mjs.map +1 -1
- package/es/mdx/Tabs/index.d.mts +2 -2
- package/es/mdx/Tabs/index.mjs +7 -2
- package/es/mdx/Tabs/index.mjs.map +1 -1
- package/es/mdx/Tabs/style.mjs +33 -1
- package/es/mdx/Tabs/style.mjs.map +1 -1
- package/es/mdx/mdxComponents/Citation/PopoverPanel.mjs +1 -1
- package/es/mdx/mdxComponents/Citation/PopoverPanel.mjs.map +1 -1
- package/es/static-css/baseline.mjs +1 -4
- package/es/static-css/baseline.mjs.map +1 -1
- package/es/static-css/buildAntdStaticCss.mjs +1 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderItems.mjs","names":["common"],"sources":["../../../src/base-ui/ContextMenu/renderItems.tsx"],"sourcesContent":["import { ContextMenu } from '@base-ui/react/context-menu';\nimport { cx } from 'antd-style';\nimport { Check } from 'lucide-react';\nimport { type MenuInfo } from 'rc-menu/es/interface';\nimport {\n type ComponentProps,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport { memo, useCallback, useState } from 'react';\n\nimport { styles } from '@/base-ui/DropdownMenu/sharedStyle';\nimport { getFloatingCollisionPadding } from '@/base-ui/floating';\nimport { SubmenuArrowIcon } from '@/base-ui/SubmenuArrowIcon';\nimport Switch from '@/base-ui/Switch';\nimport common from '@/i18n/resources/en/common';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\nimport {\n type BaseMenuItemGroupType,\n type BaseSubMenuType,\n getItemKey,\n getItemLabel,\n hasAnyIcon,\n hasCheckboxAndIcon,\n type MenuDividerType,\n type MenuItemType,\n renderIcon,\n type RenderItemContentOptions,\n type RenderOptions,\n} from '@/Menu';\nimport { preventDefaultAndStopPropagation } from '@/utils/dom';\n\nimport { useLayerZIndex } from '../zIndex';\nimport {\n type ContextMenuCheckboxItem,\n type ContextMenuItem,\n type ContextMenuSwitchItem,\n} from './type';\n\ntype ContextMenuPositionerProps = ComponentProps<typeof ContextMenu.Positioner>;\n\n/**\n * Submenu positioners are portaled outside the root menu, so they must allocate\n * their own layer z-index (same pattern as DropdownMenu) rather than relying on\n * the fixed CSS fallback that can fall behind after repeated root openings (#608).\n */\nconst ContextMenuSubmenuPositioner = memo(\n ({ collisionPadding, style, ...rest }: ContextMenuPositionerProps) => {\n const explicitZIndex =\n typeof style !== 'function' && style?.zIndex != null && typeof style.zIndex === 'number'\n ? style.zIndex\n : undefined;\n const { zIndex, ref: zRef } = useLayerZIndex<HTMLDivElement>('floating', explicitZIndex);\n\n const resolvedStyle =\n typeof style === 'function'\n ? (state: any) => ({ zIndex, ...style(state) })\n : { zIndex, ...style };\n\n return (\n <ContextMenu.Positioner\n {...rest}\n collisionPadding={collisionPadding ?? getFloatingCollisionPadding()}\n ref={zRef as any}\n style={resolvedStyle}\n />\n );\n },\n);\n\nContextMenuSubmenuPositioner.displayName = 'ContextMenuSubmenuPositioner';\n\nexport type { IconAlign, IconSpaceMode } from '@/Menu';\n\nconst EmptyMenuItem = memo(() => {\n const { t } = useTranslation(common);\n return (\n <ContextMenu.Item disabled className={cx(styles.item, styles.empty)}>\n <div className={styles.itemContent}>\n <span className={styles.label}>{t('common.empty')}</span>\n </div>\n </ContextMenu.Item>\n );\n});\n\nEmptyMenuItem.displayName = 'EmptyMenuItem';\n\ninterface ContextMenuSwitchItemInternalProps {\n checked?: boolean;\n children: ReactNode;\n closeOnClick?: boolean;\n danger?: boolean;\n defaultChecked?: boolean;\n disabled?: boolean;\n label?: string;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nconst ContextMenuSwitchItemInternal = ({\n checked: checkedProp,\n children,\n closeOnClick = false,\n danger,\n defaultChecked,\n disabled,\n label,\n onCheckedChange,\n}: ContextMenuSwitchItemInternalProps) => {\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleCheckedChange = useCallback(\n (newChecked: boolean) => {\n if (!isControlled) {\n setInternalChecked(newChecked);\n }\n onCheckedChange?.(newChecked);\n },\n [isControlled, onCheckedChange],\n );\n\n return (\n <ContextMenu.Item\n className={cx(styles.item, danger && styles.danger)}\n closeOnClick={closeOnClick}\n disabled={disabled}\n label={label}\n onClick={(e) => {\n e.preventDefault();\n if (!disabled) {\n handleCheckedChange(!checked);\n }\n }}\n >\n {children}\n <span\n style={{ display: 'inline-flex', marginInlineStart: 16 }}\n onFocus={(e) => e.stopPropagation()}\n >\n <Switch\n checked={checked}\n disabled={disabled}\n size=\"small\"\n tabIndex={-1}\n onChange={handleCheckedChange}\n onClick={(_, e) => e.stopPropagation()}\n />\n </span>\n </ContextMenu.Item>\n );\n};\n\nconst renderItemContent = (\n item: MenuItemType | BaseSubMenuType | ContextMenuCheckboxItem | ContextMenuSwitchItem,\n options?: RenderItemContentOptions,\n iconNode?: ReactNode,\n) => {\n const label = getItemLabel(item);\n const desc = 'desc' in item ? item.desc : undefined;\n const extra = 'extra' in item ? item.extra : undefined;\n const indicatorOnRight = options?.indicatorOnRight;\n const alignStart = Boolean(desc) && options?.iconAlign === 'start';\n const hasCustomIcon = iconNode !== undefined && !indicatorOnRight;\n const hasIcon = hasCustomIcon ? Boolean(iconNode) : Boolean(item.icon);\n const shouldRenderIcon = hasCustomIcon\n ? Boolean(options?.reserveIconSpace || iconNode)\n : Boolean(hasIcon || options?.reserveIconSpace);\n\n const labelNode = desc ? (\n <div className={styles.labelGroup}>\n <span className={styles.label}>{label}</span>\n <span className={styles.desc}>{desc}</span>\n </div>\n ) : (\n <span className={styles.label}>{label}</span>\n );\n\n return (\n <div className={cx(styles.itemContent, alignStart && styles.itemContentAlignStart)}>\n {shouldRenderIcon ? (\n <span\n aria-hidden={!hasIcon}\n className={cx(styles.icon, alignStart && styles.iconAlignStart)}\n >\n {hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon, 'small') : null}\n </span>\n ) : null}\n {labelNode}\n {extra ? <span className={styles.extra}>{extra}</span> : null}\n {indicatorOnRight && iconNode ? iconNode : null}\n {options?.submenu ? (\n <span className={styles.submenuArrow}>\n <SubmenuArrowIcon />\n </span>\n ) : null}\n </div>\n );\n};\n\nconst invokeItemClick = (\n item: MenuItemType,\n keyPath: string[],\n event: ReactMouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>,\n) => {\n if (!item.onClick) return;\n const key = item.key ?? keyPath.at(-1) ?? '';\n const info: MenuInfo = {\n domEvent: event,\n item: event.currentTarget as MenuInfo['item'],\n key: String(key),\n keyPath,\n };\n item.onClick(info);\n};\n\nexport const renderContextMenuItems = (\n items: ContextMenuItem[],\n keyPath: string[] = [],\n options?: RenderOptions,\n): ReactNode[] => {\n const iconAlign = options?.iconAlign;\n const iconSpaceMode = options?.iconSpaceMode ?? 'global';\n const reserveIconSpace =\n options?.reserveIconSpace ?? hasAnyIcon(items, iconSpaceMode === 'global');\n const indicatorOnRight = options?.indicatorOnRight ?? hasCheckboxAndIcon(items);\n\n return items.map((item, index) => {\n if (!item) return null;\n\n const fallbackKey = `${keyPath.join('-') || 'root'}-${index}`;\n const itemKey = getItemKey(item, fallbackKey);\n const nextKeyPath = [...keyPath, String(itemKey)];\n\n if ((item as ContextMenuCheckboxItem).type === 'checkbox') {\n const checkboxItem = item as ContextMenuCheckboxItem;\n const label = getItemLabel(checkboxItem);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = Boolean(checkboxItem.danger);\n const indicator = (\n <ContextMenu.CheckboxItemIndicator>\n <Icon icon={Check} size={'small'} />\n </ContextMenu.CheckboxItemIndicator>\n );\n\n return (\n <ContextMenu.CheckboxItem\n checked={checkboxItem.checked}\n className={cx(styles.item, isDanger && styles.danger)}\n closeOnClick={checkboxItem.closeOnClick}\n defaultChecked={checkboxItem.defaultChecked}\n disabled={checkboxItem.disabled}\n key={itemKey}\n label={labelText}\n onCheckedChange={(checked) => checkboxItem.onCheckedChange?.(checked)}\n >\n {renderItemContent(\n checkboxItem,\n { iconAlign, indicatorOnRight, reserveIconSpace },\n indicator,\n )}\n </ContextMenu.CheckboxItem>\n );\n }\n\n if ((item as ContextMenuSwitchItem).type === 'switch') {\n const switchItem = item as ContextMenuSwitchItem;\n const label = getItemLabel(switchItem);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = Boolean(switchItem.danger);\n\n return (\n <ContextMenuSwitchItemInternal\n checked={switchItem.checked}\n closeOnClick={switchItem.closeOnClick}\n danger={isDanger}\n defaultChecked={switchItem.defaultChecked}\n disabled={switchItem.disabled}\n key={itemKey}\n label={labelText}\n onCheckedChange={switchItem.onCheckedChange}\n >\n {renderItemContent(switchItem, { iconAlign, reserveIconSpace })}\n </ContextMenuSwitchItemInternal>\n );\n }\n\n if ((item as MenuDividerType).type === 'divider') {\n return <ContextMenu.Separator className={styles.separator} key={itemKey} />;\n }\n\n if ((item as BaseMenuItemGroupType).type === 'group') {\n const group = item as BaseMenuItemGroupType;\n const groupReserveIconSpace =\n iconSpaceMode === 'group'\n ? group.children\n ? hasAnyIcon(group.children)\n : false\n : reserveIconSpace;\n const groupIndicatorOnRight = group.children ? hasCheckboxAndIcon(group.children) : false;\n return (\n <ContextMenu.Group key={itemKey}>\n {group.label ? (\n <ContextMenu.GroupLabel className={styles.groupLabel}>\n {group.label}\n </ContextMenu.GroupLabel>\n ) : null}\n {group.children\n ? renderContextMenuItems(group.children, nextKeyPath, {\n iconAlign,\n iconSpaceMode,\n indicatorOnRight: groupIndicatorOnRight,\n reserveIconSpace: groupReserveIconSpace,\n })\n : null}\n </ContextMenu.Group>\n );\n }\n\n if (\n (item as BaseSubMenuType).type === 'submenu' ||\n ('children' in item && (item as BaseSubMenuType).children)\n ) {\n const submenu = item as BaseSubMenuType;\n const label = getItemLabel(submenu);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = 'danger' in submenu && Boolean(submenu.danger);\n const submenuHasSlots = submenu.header != null || submenu.footer != null;\n const submenuBody =\n submenu.children && submenu.children.length > 0 ? (\n renderContextMenuItems(submenu.children, nextKeyPath, {\n iconAlign,\n iconSpaceMode,\n })\n ) : (\n <EmptyMenuItem />\n );\n\n return (\n <ContextMenu.SubmenuRoot\n defaultOpen={submenu.defaultOpen}\n key={itemKey}\n open={submenu.open}\n onOpenChange={submenu.onOpenChange}\n >\n <ContextMenu.SubmenuTrigger\n {...submenu.triggerProps}\n className={cx(styles.item, isDanger && styles.danger)}\n closeDelay={submenu.closeDelay}\n delay={submenu.delay}\n disabled={submenu.disabled}\n label={labelText}\n openOnHover={submenu.openOnHover}\n onClick={submenu.onClick}\n >\n {renderItemContent(submenu, {\n iconAlign,\n reserveIconSpace,\n submenu: true,\n })}\n </ContextMenu.SubmenuTrigger>\n <ContextMenu.Portal>\n <ContextMenuSubmenuPositioner\n alignOffset={-4}\n className={styles.positioner}\n data-submenu=\"\"\n sideOffset={-1}\n onContextMenu={preventDefaultAndStopPropagation}\n >\n <ContextMenu.Popup\n className={submenuHasSlots ? cx(styles.popup, styles.popupWithSlots) : styles.popup}\n >\n {submenu.header == null ? null : (\n <div className={styles.header}>{submenu.header}</div>\n )}\n {submenuHasSlots ? (\n <div className={styles.slotViewport}>{submenuBody}</div>\n ) : (\n submenuBody\n )}\n {submenu.footer == null ? null : (\n <div className={styles.footer}>{submenu.footer}</div>\n )}\n </ContextMenu.Popup>\n </ContextMenuSubmenuPositioner>\n </ContextMenu.Portal>\n </ContextMenu.SubmenuRoot>\n );\n }\n\n const menuItem = item as MenuItemType;\n const label = getItemLabel(menuItem);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = 'danger' in menuItem && Boolean(menuItem.danger);\n\n return (\n <ContextMenu.Item\n className={cx(styles.item, isDanger && styles.danger)}\n closeOnClick={menuItem.closeOnClick}\n disabled={menuItem.disabled}\n key={itemKey}\n label={labelText}\n onClick={(event) => invokeItemClick(menuItem, nextKeyPath, event)}\n >\n {renderItemContent(menuItem, { iconAlign, reserveIconSpace })}\n </ContextMenu.Item>\n );\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderItems.mjs","names":["common"],"sources":["../../../src/base-ui/ContextMenu/renderItems.tsx"],"sourcesContent":["import { ContextMenu } from '@base-ui/react/context-menu';\nimport { cx } from 'antd-style';\nimport { Check } from 'lucide-react';\nimport {\n type ComponentProps,\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport { memo, useCallback, useState } from 'react';\n\nimport { styles } from '@/base-ui/DropdownMenu/sharedStyle';\nimport { getFloatingCollisionPadding } from '@/base-ui/floating';\nimport { SubmenuArrowIcon } from '@/base-ui/SubmenuArrowIcon';\nimport Switch from '@/base-ui/Switch';\nimport common from '@/i18n/resources/en/common';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\nimport type { BaseMenuItemGroupType, BaseSubMenuType } from '@/Menu/baseItem';\nimport {\n getItemKey,\n getItemLabel,\n hasAnyIcon,\n hasCheckboxAndIcon,\n renderIcon,\n type RenderItemContentOptions,\n type RenderOptions,\n} from '@/Menu/renderUtils';\nimport type { MenuDividerType, MenuInfo, MenuItemType } from '@/Menu/type';\nimport { preventDefaultAndStopPropagation } from '@/utils/dom';\n\nimport { useLayerZIndex } from '../zIndex';\nimport {\n type ContextMenuCheckboxItem,\n type ContextMenuItem,\n type ContextMenuSwitchItem,\n} from './type';\n\ntype ContextMenuPositionerProps = ComponentProps<typeof ContextMenu.Positioner>;\n\n/**\n * Submenu positioners are portaled outside the root menu, so they must allocate\n * their own layer z-index (same pattern as DropdownMenu) rather than relying on\n * the fixed CSS fallback that can fall behind after repeated root openings (#608).\n */\nconst ContextMenuSubmenuPositioner = memo(\n ({ collisionPadding, style, ...rest }: ContextMenuPositionerProps) => {\n const explicitZIndex =\n typeof style !== 'function' && style?.zIndex != null && typeof style.zIndex === 'number'\n ? style.zIndex\n : undefined;\n const { zIndex, ref: zRef } = useLayerZIndex<HTMLDivElement>('floating', explicitZIndex);\n\n const resolvedStyle =\n typeof style === 'function'\n ? (state: any) => ({ zIndex, ...style(state) })\n : { zIndex, ...style };\n\n return (\n <ContextMenu.Positioner\n {...rest}\n collisionPadding={collisionPadding ?? getFloatingCollisionPadding()}\n ref={zRef as any}\n style={resolvedStyle}\n />\n );\n },\n);\n\nContextMenuSubmenuPositioner.displayName = 'ContextMenuSubmenuPositioner';\n\nexport type { IconAlign, IconSpaceMode } from '@/Menu/renderUtils';\n\nconst EmptyMenuItem = memo(() => {\n const { t } = useTranslation(common);\n return (\n <ContextMenu.Item disabled className={cx(styles.item, styles.empty)}>\n <div className={styles.itemContent}>\n <span className={styles.label}>{t('common.empty')}</span>\n </div>\n </ContextMenu.Item>\n );\n});\n\nEmptyMenuItem.displayName = 'EmptyMenuItem';\n\ninterface ContextMenuSwitchItemInternalProps {\n checked?: boolean;\n children: ReactNode;\n closeOnClick?: boolean;\n danger?: boolean;\n defaultChecked?: boolean;\n disabled?: boolean;\n label?: string;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nconst ContextMenuSwitchItemInternal = ({\n checked: checkedProp,\n children,\n closeOnClick = false,\n danger,\n defaultChecked,\n disabled,\n label,\n onCheckedChange,\n}: ContextMenuSwitchItemInternalProps) => {\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleCheckedChange = useCallback(\n (newChecked: boolean) => {\n if (!isControlled) {\n setInternalChecked(newChecked);\n }\n onCheckedChange?.(newChecked);\n },\n [isControlled, onCheckedChange],\n );\n\n return (\n <ContextMenu.Item\n className={cx(styles.item, danger && styles.danger)}\n closeOnClick={closeOnClick}\n disabled={disabled}\n label={label}\n onClick={(e) => {\n e.preventDefault();\n if (!disabled) {\n handleCheckedChange(!checked);\n }\n }}\n >\n {children}\n <span\n style={{ display: 'inline-flex', marginInlineStart: 16 }}\n onFocus={(e) => e.stopPropagation()}\n >\n <Switch\n checked={checked}\n disabled={disabled}\n size=\"small\"\n tabIndex={-1}\n onChange={handleCheckedChange}\n onClick={(_, e) => e.stopPropagation()}\n />\n </span>\n </ContextMenu.Item>\n );\n};\n\nconst renderItemContent = (\n item: MenuItemType | BaseSubMenuType | ContextMenuCheckboxItem | ContextMenuSwitchItem,\n options?: RenderItemContentOptions,\n iconNode?: ReactNode,\n) => {\n const label = getItemLabel(item);\n const desc = 'desc' in item ? item.desc : undefined;\n const extra = 'extra' in item ? item.extra : undefined;\n const indicatorOnRight = options?.indicatorOnRight;\n const alignStart = Boolean(desc) && options?.iconAlign === 'start';\n const hasCustomIcon = iconNode !== undefined && !indicatorOnRight;\n const hasIcon = hasCustomIcon ? Boolean(iconNode) : Boolean(item.icon);\n const shouldRenderIcon = hasCustomIcon\n ? Boolean(options?.reserveIconSpace || iconNode)\n : Boolean(hasIcon || options?.reserveIconSpace);\n\n const labelNode = desc ? (\n <div className={styles.labelGroup}>\n <span className={styles.label}>{label}</span>\n <span className={styles.desc}>{desc}</span>\n </div>\n ) : (\n <span className={styles.label}>{label}</span>\n );\n\n return (\n <div className={cx(styles.itemContent, alignStart && styles.itemContentAlignStart)}>\n {shouldRenderIcon ? (\n <span\n aria-hidden={!hasIcon}\n className={cx(styles.icon, alignStart && styles.iconAlignStart)}\n >\n {hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon, 'small') : null}\n </span>\n ) : null}\n {labelNode}\n {extra ? <span className={styles.extra}>{extra}</span> : null}\n {indicatorOnRight && iconNode ? iconNode : null}\n {options?.submenu ? (\n <span className={styles.submenuArrow}>\n <SubmenuArrowIcon />\n </span>\n ) : null}\n </div>\n );\n};\n\nconst invokeItemClick = (\n item: MenuItemType,\n keyPath: string[],\n event: ReactMouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>,\n) => {\n if (!item.onClick) return;\n const key = item.key ?? keyPath.at(-1) ?? '';\n const info: MenuInfo = {\n domEvent: event,\n item: event.currentTarget as MenuInfo['item'],\n key: String(key),\n keyPath,\n };\n item.onClick(info);\n};\n\nexport const renderContextMenuItems = (\n items: ContextMenuItem[],\n keyPath: string[] = [],\n options?: RenderOptions,\n): ReactNode[] => {\n const iconAlign = options?.iconAlign;\n const iconSpaceMode = options?.iconSpaceMode ?? 'global';\n const reserveIconSpace =\n options?.reserveIconSpace ?? hasAnyIcon(items, iconSpaceMode === 'global');\n const indicatorOnRight = options?.indicatorOnRight ?? hasCheckboxAndIcon(items);\n\n return items.map((item, index) => {\n if (!item) return null;\n\n const fallbackKey = `${keyPath.join('-') || 'root'}-${index}`;\n const itemKey = getItemKey(item, fallbackKey);\n const nextKeyPath = [...keyPath, String(itemKey)];\n\n if ((item as ContextMenuCheckboxItem).type === 'checkbox') {\n const checkboxItem = item as ContextMenuCheckboxItem;\n const label = getItemLabel(checkboxItem);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = Boolean(checkboxItem.danger);\n const indicator = (\n <ContextMenu.CheckboxItemIndicator>\n <Icon icon={Check} size={'small'} />\n </ContextMenu.CheckboxItemIndicator>\n );\n\n return (\n <ContextMenu.CheckboxItem\n checked={checkboxItem.checked}\n className={cx(styles.item, isDanger && styles.danger)}\n closeOnClick={checkboxItem.closeOnClick}\n defaultChecked={checkboxItem.defaultChecked}\n disabled={checkboxItem.disabled}\n key={itemKey}\n label={labelText}\n onCheckedChange={(checked) => checkboxItem.onCheckedChange?.(checked)}\n >\n {renderItemContent(\n checkboxItem,\n { iconAlign, indicatorOnRight, reserveIconSpace },\n indicator,\n )}\n </ContextMenu.CheckboxItem>\n );\n }\n\n if ((item as ContextMenuSwitchItem).type === 'switch') {\n const switchItem = item as ContextMenuSwitchItem;\n const label = getItemLabel(switchItem);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = Boolean(switchItem.danger);\n\n return (\n <ContextMenuSwitchItemInternal\n checked={switchItem.checked}\n closeOnClick={switchItem.closeOnClick}\n danger={isDanger}\n defaultChecked={switchItem.defaultChecked}\n disabled={switchItem.disabled}\n key={itemKey}\n label={labelText}\n onCheckedChange={switchItem.onCheckedChange}\n >\n {renderItemContent(switchItem, { iconAlign, reserveIconSpace })}\n </ContextMenuSwitchItemInternal>\n );\n }\n\n if ((item as MenuDividerType).type === 'divider') {\n return <ContextMenu.Separator className={styles.separator} key={itemKey} />;\n }\n\n if ((item as BaseMenuItemGroupType).type === 'group') {\n const group = item as BaseMenuItemGroupType;\n const groupReserveIconSpace =\n iconSpaceMode === 'group'\n ? group.children\n ? hasAnyIcon(group.children)\n : false\n : reserveIconSpace;\n const groupIndicatorOnRight = group.children ? hasCheckboxAndIcon(group.children) : false;\n return (\n <ContextMenu.Group key={itemKey}>\n {group.label ? (\n <ContextMenu.GroupLabel className={styles.groupLabel}>\n {group.label}\n </ContextMenu.GroupLabel>\n ) : null}\n {group.children\n ? renderContextMenuItems(group.children, nextKeyPath, {\n iconAlign,\n iconSpaceMode,\n indicatorOnRight: groupIndicatorOnRight,\n reserveIconSpace: groupReserveIconSpace,\n })\n : null}\n </ContextMenu.Group>\n );\n }\n\n if (\n (item as BaseSubMenuType).type === 'submenu' ||\n ('children' in item && (item as BaseSubMenuType).children)\n ) {\n const submenu = item as BaseSubMenuType;\n const label = getItemLabel(submenu);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = 'danger' in submenu && Boolean(submenu.danger);\n const submenuHasSlots = submenu.header != null || submenu.footer != null;\n const submenuBody =\n submenu.children && submenu.children.length > 0 ? (\n renderContextMenuItems(submenu.children, nextKeyPath, {\n iconAlign,\n iconSpaceMode,\n })\n ) : (\n <EmptyMenuItem />\n );\n\n return (\n <ContextMenu.SubmenuRoot\n defaultOpen={submenu.defaultOpen}\n key={itemKey}\n open={submenu.open}\n onOpenChange={submenu.onOpenChange}\n >\n <ContextMenu.SubmenuTrigger\n {...submenu.triggerProps}\n className={cx(styles.item, isDanger && styles.danger)}\n closeDelay={submenu.closeDelay}\n delay={submenu.delay}\n disabled={submenu.disabled}\n label={labelText}\n openOnHover={submenu.openOnHover}\n onClick={submenu.onClick}\n >\n {renderItemContent(submenu, {\n iconAlign,\n reserveIconSpace,\n submenu: true,\n })}\n </ContextMenu.SubmenuTrigger>\n <ContextMenu.Portal>\n <ContextMenuSubmenuPositioner\n alignOffset={-4}\n className={styles.positioner}\n data-submenu=\"\"\n sideOffset={-1}\n onContextMenu={preventDefaultAndStopPropagation}\n >\n <ContextMenu.Popup\n className={submenuHasSlots ? cx(styles.popup, styles.popupWithSlots) : styles.popup}\n >\n {submenu.header == null ? null : (\n <div className={styles.header}>{submenu.header}</div>\n )}\n {submenuHasSlots ? (\n <div className={styles.slotViewport}>{submenuBody}</div>\n ) : (\n submenuBody\n )}\n {submenu.footer == null ? null : (\n <div className={styles.footer}>{submenu.footer}</div>\n )}\n </ContextMenu.Popup>\n </ContextMenuSubmenuPositioner>\n </ContextMenu.Portal>\n </ContextMenu.SubmenuRoot>\n );\n }\n\n const menuItem = item as MenuItemType;\n const label = getItemLabel(menuItem);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = 'danger' in menuItem && Boolean(menuItem.danger);\n\n return (\n <ContextMenu.Item\n className={cx(styles.item, isDanger && styles.danger)}\n closeOnClick={menuItem.closeOnClick}\n disabled={menuItem.disabled}\n key={itemKey}\n label={labelText}\n onClick={(event) => invokeItemClick(menuItem, nextKeyPath, event)}\n >\n {renderItemContent(menuItem, { iconAlign, reserveIconSpace })}\n </ContextMenu.Item>\n );\n });\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import Icon from "../../Icon/Icon.mjs";
|
|
3
|
+
import { useTranslation } from "../../i18n/useTranslation.mjs";
|
|
4
|
+
import { panelStyles } from "../panelStyles.mjs";
|
|
5
|
+
import datePicker_default from "../../i18n/resources/en/datePicker.mjs";
|
|
6
|
+
import { buildMonthGrid, getWeekStart, getWeekdayLabels, isDayDisabled, isMonthDisabled, isSameDay, isYearDisabled, moveDayFocus, orderRange } from "./calendar.mjs";
|
|
7
|
+
import { styles } from "./style.mjs";
|
|
8
|
+
import { memo, useEffect, useRef, useState } from "react";
|
|
9
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { cx } from "antd-style";
|
|
11
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
12
|
+
import dayjs from "dayjs";
|
|
13
|
+
//#region src/base-ui/DatePicker/CalendarPanel.tsx
|
|
14
|
+
const MONTHS = Array.from({ length: 12 }, (_, index) => index);
|
|
15
|
+
const CalendarPanel = memo(({ bounds, hovered, mode, month, onHover, onMonthChange, onSelect, range, selected, showNav = true }) => {
|
|
16
|
+
const { t } = useTranslation(datePicker_default);
|
|
17
|
+
const [view, setView] = useState(mode);
|
|
18
|
+
const [focused, setFocused] = useState(selected ?? month);
|
|
19
|
+
const gridRef = useRef(null);
|
|
20
|
+
const weekStart = getWeekStart();
|
|
21
|
+
const today = /* @__PURE__ */ new Date();
|
|
22
|
+
const current = dayjs(month);
|
|
23
|
+
const decadeStart = Math.floor(current.year() / 12) * 12;
|
|
24
|
+
const days = buildMonthGrid(month, weekStart);
|
|
25
|
+
const focusDay = dayjs(focused).isSame(month, "month") && !isDayDisabled(focused, bounds) ? focused : days.find((day) => dayjs(day).isSame(month, "month") && !isDayDisabled(day, bounds)) ?? current.startOf("month").toDate();
|
|
26
|
+
const keyboardMoveRef = useRef(false);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!keyboardMoveRef.current) return;
|
|
29
|
+
keyboardMoveRef.current = false;
|
|
30
|
+
gridRef.current?.querySelector("[data-focus-target]")?.focus();
|
|
31
|
+
}, [focused, month]);
|
|
32
|
+
const step = (direction) => {
|
|
33
|
+
const unit = view === "date" ? "month" : "year";
|
|
34
|
+
const amount = view === "year" ? 12 * direction : direction;
|
|
35
|
+
onMonthChange(current.add(amount, unit).toDate());
|
|
36
|
+
};
|
|
37
|
+
const drillUp = () => setView(view === "date" ? "month" : "year");
|
|
38
|
+
const handleDayKey = (event) => {
|
|
39
|
+
let next = moveDayFocus(focusDay, event.key, weekStart);
|
|
40
|
+
if (!next) return;
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
for (let step = 0; next && isDayDisabled(next, bounds) && step < 366; step++) next = moveDayFocus(next, event.key, weekStart);
|
|
43
|
+
if (!next || isDayDisabled(next, bounds)) return;
|
|
44
|
+
keyboardMoveRef.current = true;
|
|
45
|
+
setFocused(next);
|
|
46
|
+
if (!dayjs(next).isSame(month, "month")) onMonthChange(next);
|
|
47
|
+
};
|
|
48
|
+
const band = (() => {
|
|
49
|
+
if (!range?.[0]) return null;
|
|
50
|
+
const end = range[1] ?? hovered;
|
|
51
|
+
return end ? orderRange(range[0], end) : null;
|
|
52
|
+
})();
|
|
53
|
+
const renderDays = () => {
|
|
54
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
55
|
+
"aria-label": current.format("MMMM YYYY"),
|
|
56
|
+
className: styles.grid,
|
|
57
|
+
ref: gridRef,
|
|
58
|
+
role: "grid",
|
|
59
|
+
onMouseLeave: () => onHover?.(null),
|
|
60
|
+
children: [getWeekdayLabels(weekStart).map((label) => /* @__PURE__ */ jsx("span", {
|
|
61
|
+
className: cx(styles.weekday, panelStyles.label),
|
|
62
|
+
role: "columnheader",
|
|
63
|
+
children: label
|
|
64
|
+
}, label)), days.map((date) => {
|
|
65
|
+
const outside = !dayjs(date).isSame(month, "month");
|
|
66
|
+
const isStart = !outside && !!band && isSameDay(date, band[0]);
|
|
67
|
+
const isEnd = !outside && !!band && isSameDay(date, band[1]);
|
|
68
|
+
const inBand = !outside && !!band && dayjs(date).isAfter(band[0], "day") && dayjs(date).isBefore(band[1], "day");
|
|
69
|
+
const pressed = !outside && (isSameDay(date, selected) || isStart || isEnd);
|
|
70
|
+
const focusTarget = isSameDay(date, focusDay) && !outside;
|
|
71
|
+
return /* @__PURE__ */ jsx("span", {
|
|
72
|
+
"aria-selected": pressed,
|
|
73
|
+
role: "gridcell",
|
|
74
|
+
className: cx(styles.cell, inBand && styles.band, isStart && !isEnd && styles.bandStart, isEnd && !isStart && styles.bandEnd),
|
|
75
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
76
|
+
"aria-label": dayjs(date).format("MMMM D, YYYY"),
|
|
77
|
+
"aria-pressed": pressed,
|
|
78
|
+
className: styles.day,
|
|
79
|
+
"data-focus-target": focusTarget ? "" : void 0,
|
|
80
|
+
"data-outside": outside ? "" : void 0,
|
|
81
|
+
"data-today": isSameDay(date, today) ? "" : void 0,
|
|
82
|
+
disabled: isDayDisabled(date, bounds),
|
|
83
|
+
tabIndex: focusTarget ? 0 : -1,
|
|
84
|
+
type: "button",
|
|
85
|
+
onClick: () => onSelect(dayjs(date).startOf("day").toDate()),
|
|
86
|
+
onKeyDown: handleDayKey,
|
|
87
|
+
onMouseEnter: () => onHover?.(date),
|
|
88
|
+
children: date.getDate()
|
|
89
|
+
})
|
|
90
|
+
}, date.toISOString());
|
|
91
|
+
})]
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
const renderMonths = () => /* @__PURE__ */ jsx("div", {
|
|
95
|
+
className: styles.tiles,
|
|
96
|
+
children: MONTHS.map((index) => {
|
|
97
|
+
const date = current.month(index).startOf("month").toDate();
|
|
98
|
+
return /* @__PURE__ */ jsx("button", {
|
|
99
|
+
"aria-pressed": !!selected && dayjs(selected).isSame(date, "month"),
|
|
100
|
+
className: styles.tile,
|
|
101
|
+
"data-today": dayjs(today).isSame(date, "month") ? "" : void 0,
|
|
102
|
+
disabled: isMonthDisabled(date, bounds),
|
|
103
|
+
type: "button",
|
|
104
|
+
onClick: () => {
|
|
105
|
+
if (mode === "month") return onSelect(date);
|
|
106
|
+
onMonthChange(date);
|
|
107
|
+
setView("date");
|
|
108
|
+
},
|
|
109
|
+
children: dayjs(date).format("MMM")
|
|
110
|
+
}, index);
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
const renderYears = () => /* @__PURE__ */ jsx("div", {
|
|
114
|
+
className: styles.tiles,
|
|
115
|
+
children: MONTHS.map((index) => {
|
|
116
|
+
const date = dayjs(new Date(decadeStart + index, 0, 1)).toDate();
|
|
117
|
+
return /* @__PURE__ */ jsx("button", {
|
|
118
|
+
"aria-pressed": !!selected && dayjs(selected).isSame(date, "year"),
|
|
119
|
+
className: styles.tile,
|
|
120
|
+
"data-today": dayjs(today).isSame(date, "year") ? "" : void 0,
|
|
121
|
+
disabled: isYearDisabled(date, bounds),
|
|
122
|
+
type: "button",
|
|
123
|
+
onClick: () => {
|
|
124
|
+
if (mode === "year") return onSelect(date);
|
|
125
|
+
onMonthChange(current.year(decadeStart + index).toDate());
|
|
126
|
+
setView("month");
|
|
127
|
+
},
|
|
128
|
+
children: decadeStart + index
|
|
129
|
+
}, index);
|
|
130
|
+
})
|
|
131
|
+
});
|
|
132
|
+
const title = (() => {
|
|
133
|
+
if (view === "date") return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
134
|
+
current.format("MMMM"),
|
|
135
|
+
" ",
|
|
136
|
+
/* @__PURE__ */ jsx("span", {
|
|
137
|
+
className: panelStyles.titleMuted,
|
|
138
|
+
children: current.format("YYYY")
|
|
139
|
+
})
|
|
140
|
+
] });
|
|
141
|
+
if (view === "month") return current.format("YYYY");
|
|
142
|
+
return `${decadeStart} – ${decadeStart + 11}`;
|
|
143
|
+
})();
|
|
144
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
145
|
+
className: styles.calendar,
|
|
146
|
+
children: [
|
|
147
|
+
/* @__PURE__ */ jsxs("div", {
|
|
148
|
+
className: styles.header,
|
|
149
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
150
|
+
className: panelStyles.title,
|
|
151
|
+
disabled: view === "year",
|
|
152
|
+
type: "button",
|
|
153
|
+
onClick: drillUp,
|
|
154
|
+
children: title
|
|
155
|
+
}), showNav && /* @__PURE__ */ jsxs("div", {
|
|
156
|
+
className: styles.navGroup,
|
|
157
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
158
|
+
"aria-label": t("datePicker.previous"),
|
|
159
|
+
className: panelStyles.nav,
|
|
160
|
+
type: "button",
|
|
161
|
+
onClick: () => step(-1),
|
|
162
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
163
|
+
icon: ChevronLeft,
|
|
164
|
+
size: 14
|
|
165
|
+
})
|
|
166
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
167
|
+
"aria-label": t("datePicker.next"),
|
|
168
|
+
className: panelStyles.nav,
|
|
169
|
+
type: "button",
|
|
170
|
+
onClick: () => step(1),
|
|
171
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
172
|
+
icon: ChevronRight,
|
|
173
|
+
size: 14
|
|
174
|
+
})
|
|
175
|
+
})]
|
|
176
|
+
})]
|
|
177
|
+
}),
|
|
178
|
+
view === "date" && renderDays(),
|
|
179
|
+
view === "month" && renderMonths(),
|
|
180
|
+
view === "year" && renderYears()
|
|
181
|
+
]
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
CalendarPanel.displayName = "CalendarPanel";
|
|
185
|
+
//#endregion
|
|
186
|
+
export { CalendarPanel as default };
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=CalendarPanel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarPanel.mjs","names":["datePickerMessages"],"sources":["../../../src/base-ui/DatePicker/CalendarPanel.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport dayjs from 'dayjs';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { type KeyboardEvent, memo, useEffect, useRef, useState } from 'react';\n\nimport { panelStyles } from '@/base-ui/panelStyles';\nimport datePickerMessages from '@/i18n/resources/en/datePicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\n\nimport {\n buildMonthGrid,\n type CalendarMode,\n type DateBounds,\n getWeekdayLabels,\n getWeekStart,\n isDayDisabled,\n isMonthDisabled,\n isSameDay,\n isYearDisabled,\n moveDayFocus,\n orderRange,\n} from './calendar';\nimport { styles } from './style';\n\nexport interface CalendarPanelProps {\n bounds: DateBounds;\n hovered?: Date | null;\n mode: CalendarMode;\n month: Date;\n onHover?: (date: Date | null) => void;\n onMonthChange: (month: Date) => void;\n onSelect: (date: Date) => void;\n range?: [Date | null, Date | null];\n selected?: Date | null;\n showNav?: boolean;\n}\n\nconst MONTHS = Array.from({ length: 12 }, (_, index) => index);\n\nconst CalendarPanel = memo<CalendarPanelProps>(\n ({\n bounds,\n hovered,\n mode,\n month,\n onHover,\n onMonthChange,\n onSelect,\n range,\n selected,\n showNav = true,\n }) => {\n const { t } = useTranslation(datePickerMessages);\n const [view, setView] = useState<CalendarMode>(mode);\n const [focused, setFocused] = useState<Date>(selected ?? month);\n const gridRef = useRef<HTMLDivElement>(null);\n const weekStart = getWeekStart();\n const today = new Date();\n const current = dayjs(month);\n const decadeStart = Math.floor(current.year() / 12) * 12;\n const days = buildMonthGrid(month, weekStart);\n const focusDay =\n dayjs(focused).isSame(month, 'month') && !isDayDisabled(focused, bounds)\n ? focused\n : (days.find((day) => dayjs(day).isSame(month, 'month') && !isDayDisabled(day, bounds)) ??\n current.startOf('month').toDate());\n const keyboardMoveRef = useRef(false);\n\n useEffect(() => {\n if (!keyboardMoveRef.current) return;\n keyboardMoveRef.current = false;\n gridRef.current?.querySelector<HTMLButtonElement>('[data-focus-target]')?.focus();\n }, [focused, month]);\n\n const step = (direction: 1 | -1) => {\n const unit = view === 'date' ? 'month' : 'year';\n const amount = view === 'year' ? 12 * direction : direction;\n onMonthChange(current.add(amount, unit).toDate());\n };\n\n const drillUp = () => setView(view === 'date' ? 'month' : 'year');\n\n const handleDayKey = (event: KeyboardEvent<HTMLButtonElement>) => {\n let next = moveDayFocus(focusDay, event.key, weekStart);\n if (!next) return;\n event.preventDefault();\n for (let step = 0; next && isDayDisabled(next, bounds) && step < 366; step++) {\n next = moveDayFocus(next, event.key, weekStart);\n }\n if (!next || isDayDisabled(next, bounds)) return;\n keyboardMoveRef.current = true;\n setFocused(next);\n if (!dayjs(next).isSame(month, 'month')) onMonthChange(next);\n };\n\n const band = (() => {\n if (!range?.[0]) return null;\n const end = range[1] ?? hovered;\n return end ? orderRange(range[0], end) : null;\n })();\n\n const renderDays = () => {\n return (\n <div\n aria-label={current.format('MMMM YYYY')}\n className={styles.grid}\n ref={gridRef}\n role=\"grid\"\n onMouseLeave={() => onHover?.(null)}\n >\n {getWeekdayLabels(weekStart).map((label) => (\n <span className={cx(styles.weekday, panelStyles.label)} key={label} role=\"columnheader\">\n {label}\n </span>\n ))}\n {days.map((date) => {\n const outside = !dayjs(date).isSame(month, 'month');\n const isStart = !outside && !!band && isSameDay(date, band[0]);\n const isEnd = !outside && !!band && isSameDay(date, band[1]);\n const inBand =\n !outside &&\n !!band &&\n dayjs(date).isAfter(band[0], 'day') &&\n dayjs(date).isBefore(band[1], 'day');\n const pressed = !outside && (isSameDay(date, selected) || isStart || isEnd);\n const focusTarget = isSameDay(date, focusDay) && !outside;\n\n return (\n <span\n aria-selected={pressed}\n key={date.toISOString()}\n role=\"gridcell\"\n className={cx(\n styles.cell,\n inBand && styles.band,\n isStart && !isEnd && styles.bandStart,\n isEnd && !isStart && styles.bandEnd,\n )}\n >\n <button\n aria-label={dayjs(date).format('MMMM D, YYYY')}\n aria-pressed={pressed}\n className={styles.day}\n data-focus-target={focusTarget ? '' : undefined}\n data-outside={outside ? '' : undefined}\n data-today={isSameDay(date, today) ? '' : undefined}\n disabled={isDayDisabled(date, bounds)}\n tabIndex={focusTarget ? 0 : -1}\n type=\"button\"\n onClick={() => onSelect(dayjs(date).startOf('day').toDate())}\n onKeyDown={handleDayKey}\n onMouseEnter={() => onHover?.(date)}\n >\n {date.getDate()}\n </button>\n </span>\n );\n })}\n </div>\n );\n };\n\n const renderMonths = () => (\n <div className={styles.tiles}>\n {MONTHS.map((index) => {\n const date = current.month(index).startOf('month').toDate();\n return (\n <button\n aria-pressed={!!selected && dayjs(selected).isSame(date, 'month')}\n className={styles.tile}\n data-today={dayjs(today).isSame(date, 'month') ? '' : undefined}\n disabled={isMonthDisabled(date, bounds)}\n key={index}\n type=\"button\"\n onClick={() => {\n if (mode === 'month') return onSelect(date);\n onMonthChange(date);\n setView('date');\n }}\n >\n {dayjs(date).format('MMM')}\n </button>\n );\n })}\n </div>\n );\n\n const renderYears = () => (\n <div className={styles.tiles}>\n {MONTHS.map((index) => {\n const date = dayjs(new Date(decadeStart + index, 0, 1)).toDate();\n return (\n <button\n aria-pressed={!!selected && dayjs(selected).isSame(date, 'year')}\n className={styles.tile}\n data-today={dayjs(today).isSame(date, 'year') ? '' : undefined}\n disabled={isYearDisabled(date, bounds)}\n key={index}\n type=\"button\"\n onClick={() => {\n if (mode === 'year') return onSelect(date);\n onMonthChange(current.year(decadeStart + index).toDate());\n setView('month');\n }}\n >\n {decadeStart + index}\n </button>\n );\n })}\n </div>\n );\n\n const title = (() => {\n if (view === 'date')\n return (\n <>\n {current.format('MMMM')}{' '}\n <span className={panelStyles.titleMuted}>{current.format('YYYY')}</span>\n </>\n );\n if (view === 'month') return current.format('YYYY');\n return `${decadeStart} – ${decadeStart + 11}`;\n })();\n\n return (\n <div className={styles.calendar}>\n <div className={styles.header}>\n <button\n className={panelStyles.title}\n disabled={view === 'year'}\n type=\"button\"\n onClick={drillUp}\n >\n {title}\n </button>\n {showNav && (\n <div className={styles.navGroup}>\n <button\n aria-label={t('datePicker.previous')}\n className={panelStyles.nav}\n type=\"button\"\n onClick={() => step(-1)}\n >\n <Icon icon={ChevronLeft} size={14} />\n </button>\n <button\n aria-label={t('datePicker.next')}\n className={panelStyles.nav}\n type=\"button\"\n onClick={() => step(1)}\n >\n <Icon icon={ChevronRight} size={14} />\n </button>\n </div>\n )}\n </div>\n {view === 'date' && renderDays()}\n {view === 'month' && renderMonths()}\n {view === 'year' && renderYears()}\n </div>\n );\n },\n);\n\nCalendarPanel.displayName = 'CalendarPanel';\n\nexport default CalendarPanel;\n"],"mappings":";;;;;;;;;;;;;AAwCA,MAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,UAAU,KAAK;AAE7D,MAAM,gBAAgB,MACnB,EACC,QACA,SACA,MACA,OACA,SACA,eACA,UACA,OACA,UACA,UAAU,WACN;CACJ,MAAM,EAAE,MAAM,eAAeA,kBAAkB;CAC/C,MAAM,CAAC,MAAM,WAAW,SAAuB,IAAI;CACnD,MAAM,CAAC,SAAS,cAAc,SAAe,YAAY,KAAK;CAC9D,MAAM,UAAU,OAAuB,IAAI;CAC3C,MAAM,YAAY,aAAa;CAC/B,MAAM,wBAAQ,IAAI,KAAK;CACvB,MAAM,UAAU,MAAM,KAAK;CAC3B,MAAM,cAAc,KAAK,MAAM,QAAQ,KAAK,IAAI,EAAE,IAAI;CACtD,MAAM,OAAO,eAAe,OAAO,SAAS;CAC5C,MAAM,WACJ,MAAM,OAAO,CAAC,CAAC,OAAO,OAAO,OAAO,KAAK,CAAC,cAAc,SAAS,MAAM,IACnE,UACC,KAAK,MAAM,QAAQ,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,OAAO,KAAK,CAAC,cAAc,KAAK,MAAM,CAAC,KACpF,QAAQ,QAAQ,OAAO,CAAC,CAAC,OAAO;CACtC,MAAM,kBAAkB,OAAO,KAAK;CAEpC,gBAAgB;EACd,IAAI,CAAC,gBAAgB,SAAS;EAC9B,gBAAgB,UAAU;EAC1B,QAAQ,SAAS,cAAiC,qBAAqB,CAAC,EAAE,MAAM;CAClF,GAAG,CAAC,SAAS,KAAK,CAAC;CAEnB,MAAM,QAAQ,cAAsB;EAClC,MAAM,OAAO,SAAS,SAAS,UAAU;EACzC,MAAM,SAAS,SAAS,SAAS,KAAK,YAAY;EAClD,cAAc,QAAQ,IAAI,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC;CAClD;CAEA,MAAM,gBAAgB,QAAQ,SAAS,SAAS,UAAU,MAAM;CAEhE,MAAM,gBAAgB,UAA4C;EAChE,IAAI,OAAO,aAAa,UAAU,MAAM,KAAK,SAAS;EACtD,IAAI,CAAC,MAAM;EACX,MAAM,eAAe;EACrB,KAAK,IAAI,OAAO,GAAG,QAAQ,cAAc,MAAM,MAAM,KAAK,OAAO,KAAK,QACpE,OAAO,aAAa,MAAM,MAAM,KAAK,SAAS;EAEhD,IAAI,CAAC,QAAQ,cAAc,MAAM,MAAM,GAAG;EAC1C,gBAAgB,UAAU;EAC1B,WAAW,IAAI;EACf,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,OAAO,OAAO,GAAG,cAAc,IAAI;CAC7D;CAEA,MAAM,cAAc;EAClB,IAAI,CAAC,QAAQ,IAAI,OAAO;EACxB,MAAM,MAAM,MAAM,MAAM;EACxB,OAAO,MAAM,WAAW,MAAM,IAAI,GAAG,IAAI;CAC3C,EAAA,CAAG;CAEH,MAAM,mBAAmB;EACvB,OACE,qBAAC,OAAD;GACE,cAAY,QAAQ,OAAO,WAAW;GACtC,WAAW,OAAO;GAClB,KAAK;GACL,MAAK;GACL,oBAAoB,UAAU,IAAI;GALpC,UAAA,CAOG,iBAAiB,SAAS,CAAC,CAAC,KAAK,UAChC,oBAAC,QAAD;IAAM,WAAW,GAAG,OAAO,SAAS,YAAY,KAAK;IAAe,MAAK;IACtE,UAAA;GACG,GAFuD,KAEvD,CACP,GACA,KAAK,KAAK,SAAS;IAClB,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,OAAO,OAAO;IAClD,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,UAAU,MAAM,KAAK,EAAE;IAC7D,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC,QAAQ,UAAU,MAAM,KAAK,EAAE;IAC3D,MAAM,SACJ,CAAC,WACD,CAAC,CAAC,QACF,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,KAAK,KAClC,MAAM,IAAI,CAAC,CAAC,SAAS,KAAK,IAAI,KAAK;IACrC,MAAM,UAAU,CAAC,YAAY,UAAU,MAAM,QAAQ,KAAK,WAAW;IACrE,MAAM,cAAc,UAAU,MAAM,QAAQ,KAAK,CAAC;IAElD,OACE,oBAAC,QAAD;KACE,iBAAe;KAEf,MAAK;KACL,WAAW,GACT,OAAO,MACP,UAAU,OAAO,MACjB,WAAW,CAAC,SAAS,OAAO,WAC5B,SAAS,CAAC,WAAW,OAAO,OAC9B;KAEA,UAAA,oBAAC,UAAD;MACE,cAAY,MAAM,IAAI,CAAC,CAAC,OAAO,cAAc;MAC7C,gBAAc;MACd,WAAW,OAAO;MAClB,qBAAmB,cAAc,KAAK,KAAA;MACtC,gBAAc,UAAU,KAAK,KAAA;MAC7B,cAAY,UAAU,MAAM,KAAK,IAAI,KAAK,KAAA;MAC1C,UAAU,cAAc,MAAM,MAAM;MACpC,UAAU,cAAc,IAAI;MAC5B,MAAK;MACL,eAAe,SAAS,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,CAAC;MAC3D,WAAW;MACX,oBAAoB,UAAU,IAAI;MAEjC,UAAA,KAAK,QAAQ;KACR,CAAA;IACJ,GAzBC,KAAK,YAAY,CAyBlB;GAEV,CAAC,CACE;;CAET;CAEA,MAAM,qBACJ,oBAAC,OAAD;EAAK,WAAW,OAAO;EACpB,UAAA,OAAO,KAAK,UAAU;GACrB,MAAM,OAAO,QAAQ,MAAM,KAAK,CAAC,CAAC,QAAQ,OAAO,CAAC,CAAC,OAAO;GAC1D,OACE,oBAAC,UAAD;IACE,gBAAc,CAAC,CAAC,YAAY,MAAM,QAAQ,CAAC,CAAC,OAAO,MAAM,OAAO;IAChE,WAAW,OAAO;IAClB,cAAY,MAAM,KAAK,CAAC,CAAC,OAAO,MAAM,OAAO,IAAI,KAAK,KAAA;IACtD,UAAU,gBAAgB,MAAM,MAAM;IAEtC,MAAK;IACL,eAAe;KACb,IAAI,SAAS,SAAS,OAAO,SAAS,IAAI;KAC1C,cAAc,IAAI;KAClB,QAAQ,MAAM;IAChB;IAEC,UAAA,MAAM,IAAI,CAAC,CAAC,OAAO,KAAK;GACnB,GATD,KASC;EAEZ,CAAC;CACE,CAAA;CAGP,MAAM,oBACJ,oBAAC,OAAD;EAAK,WAAW,OAAO;EACpB,UAAA,OAAO,KAAK,UAAU;GACrB,MAAM,OAAO,MAAM,IAAI,KAAK,cAAc,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO;GAC/D,OACE,oBAAC,UAAD;IACE,gBAAc,CAAC,CAAC,YAAY,MAAM,QAAQ,CAAC,CAAC,OAAO,MAAM,MAAM;IAC/D,WAAW,OAAO;IAClB,cAAY,MAAM,KAAK,CAAC,CAAC,OAAO,MAAM,MAAM,IAAI,KAAK,KAAA;IACrD,UAAU,eAAe,MAAM,MAAM;IAErC,MAAK;IACL,eAAe;KACb,IAAI,SAAS,QAAQ,OAAO,SAAS,IAAI;KACzC,cAAc,QAAQ,KAAK,cAAc,KAAK,CAAC,CAAC,OAAO,CAAC;KACxD,QAAQ,OAAO;IACjB;IAEC,UAAA,cAAc;GACT,GATD,KASC;EAEZ,CAAC;CACE,CAAA;CAGP,MAAM,eAAe;EACnB,IAAI,SAAS,QACX,OACE,qBAAA,YAAA,EAAA,UAAA;GACG,QAAQ,OAAO,MAAM;GAAG;GACzB,oBAAC,QAAD;IAAM,WAAW,YAAY;IAAa,UAAA,QAAQ,OAAO,MAAM;GAAQ,CAAA;EACvE,EAAA,CAAA;EAEN,IAAI,SAAS,SAAS,OAAO,QAAQ,OAAO,MAAM;EAClD,OAAO,GAAG,YAAY,KAAK,cAAc;CAC3C,EAAA,CAAG;CAEH,OACE,qBAAC,OAAD;EAAK,WAAW,OAAO;EAAvB,UAAA;GACE,qBAAC,OAAD;IAAK,WAAW,OAAO;IAAvB,UAAA,CACE,oBAAC,UAAD;KACE,WAAW,YAAY;KACvB,UAAU,SAAS;KACnB,MAAK;KACL,SAAS;KAER,UAAA;IACK,CAAA,GACP,WACC,qBAAC,OAAD;KAAK,WAAW,OAAO;KAAvB,UAAA,CACE,oBAAC,UAAD;MACE,cAAY,EAAE,qBAAqB;MACnC,WAAW,YAAY;MACvB,MAAK;MACL,eAAe,KAAK,EAAE;MAEtB,UAAA,oBAAC,MAAD;OAAM,MAAM;OAAa,MAAM;MAAK,CAAA;KAC9B,CAAA,GACR,oBAAC,UAAD;MACE,cAAY,EAAE,iBAAiB;MAC/B,WAAW,YAAY;MACvB,MAAK;MACL,eAAe,KAAK,CAAC;MAErB,UAAA,oBAAC,MAAD;OAAM,MAAM;OAAc,MAAM;MAAK,CAAA;KAC/B,CAAA,CACL;IAEJ,CAAA,CAAA;;GACJ,SAAS,UAAU,WAAW;GAC9B,SAAS,WAAW,aAAa;GACjC,SAAS,UAAU,YAAY;EAC7B;;AAET,CACF;AAEA,cAAc,cAAc"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DatePickerProps } from "./type.mjs";
|
|
2
|
+
//#region src/base-ui/DatePicker/DatePicker.d.ts
|
|
3
|
+
declare const DatePicker: import("react").NamedExoticComponent<DatePickerProps>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { DatePicker as default };
|
|
6
|
+
//# sourceMappingURL=DatePicker.d.mts.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import Icon from "../../Icon/Icon.mjs";
|
|
3
|
+
import { useTranslation } from "../../i18n/useTranslation.mjs";
|
|
4
|
+
import datePicker_default from "../../i18n/resources/en/datePicker.mjs";
|
|
5
|
+
import { DEFAULT_FORMAT, clampToBounds } from "./calendar.mjs";
|
|
6
|
+
import { styles } from "./style.mjs";
|
|
7
|
+
import CalendarPanel from "./CalendarPanel.mjs";
|
|
8
|
+
import PickerShell from "./PickerShell.mjs";
|
|
9
|
+
import { memo, useState } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import useMergeState from "use-merge-value";
|
|
12
|
+
import { CalendarIcon } from "lucide-react";
|
|
13
|
+
import dayjs from "dayjs";
|
|
14
|
+
//#region src/base-ui/DatePicker/DatePicker.tsx
|
|
15
|
+
const PLACEHOLDER_KEY = {
|
|
16
|
+
date: "datePicker.placeholder",
|
|
17
|
+
month: "datePicker.monthPlaceholder",
|
|
18
|
+
year: "datePicker.yearPlaceholder"
|
|
19
|
+
};
|
|
20
|
+
const formatDate = (date, format, fallback) => typeof format === "function" ? format(date) : dayjs(date).format(format ?? fallback);
|
|
21
|
+
const DatePicker = memo(({ allowClear = true, className, defaultValue = null, disabled, disabledDate, footer, format, max, min, mode = "date", onChange, placeholder, shadow, size, style, value, variant }) => {
|
|
22
|
+
const { t } = useTranslation(datePicker_default);
|
|
23
|
+
const [current, setCurrent] = useMergeState(defaultValue, {
|
|
24
|
+
defaultValue,
|
|
25
|
+
onChange,
|
|
26
|
+
value
|
|
27
|
+
});
|
|
28
|
+
const [open, setOpen] = useState(false);
|
|
29
|
+
const [month, setMonth] = useState(() => current ?? /* @__PURE__ */ new Date());
|
|
30
|
+
const text = current ? formatDate(current, format, DEFAULT_FORMAT[mode]) : null;
|
|
31
|
+
return /* @__PURE__ */ jsxs(PickerShell, {
|
|
32
|
+
className,
|
|
33
|
+
disabled,
|
|
34
|
+
open,
|
|
35
|
+
shadow,
|
|
36
|
+
showClear: allowClear && !!current,
|
|
37
|
+
size,
|
|
38
|
+
style,
|
|
39
|
+
variant,
|
|
40
|
+
icon: /* @__PURE__ */ jsx("span", {
|
|
41
|
+
className: styles.icon,
|
|
42
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
43
|
+
icon: CalendarIcon,
|
|
44
|
+
size: 14
|
|
45
|
+
})
|
|
46
|
+
}),
|
|
47
|
+
trigger: /* @__PURE__ */ jsx("button", {
|
|
48
|
+
className: styles.trigger,
|
|
49
|
+
disabled,
|
|
50
|
+
type: "button",
|
|
51
|
+
children: text ?? /* @__PURE__ */ jsx("span", {
|
|
52
|
+
className: styles.placeholder,
|
|
53
|
+
children: placeholder ?? t(PLACEHOLDER_KEY[mode])
|
|
54
|
+
})
|
|
55
|
+
}),
|
|
56
|
+
onClear: () => setCurrent(null),
|
|
57
|
+
onOpenChange: (next) => {
|
|
58
|
+
if (next) setMonth(current ?? clampToBounds(/* @__PURE__ */ new Date(), {
|
|
59
|
+
max,
|
|
60
|
+
min
|
|
61
|
+
}));
|
|
62
|
+
setOpen(next);
|
|
63
|
+
},
|
|
64
|
+
children: [/* @__PURE__ */ jsx(CalendarPanel, {
|
|
65
|
+
bounds: {
|
|
66
|
+
disabledDate,
|
|
67
|
+
max,
|
|
68
|
+
min
|
|
69
|
+
},
|
|
70
|
+
mode,
|
|
71
|
+
month,
|
|
72
|
+
selected: current,
|
|
73
|
+
onMonthChange: setMonth,
|
|
74
|
+
onSelect: (date) => {
|
|
75
|
+
setCurrent(date);
|
|
76
|
+
setOpen(false);
|
|
77
|
+
}
|
|
78
|
+
}), footer && /* @__PURE__ */ jsx("div", {
|
|
79
|
+
className: styles.footer,
|
|
80
|
+
children: footer
|
|
81
|
+
})]
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
DatePicker.displayName = "DatePicker";
|
|
85
|
+
//#endregion
|
|
86
|
+
export { DatePicker as default, formatDate };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=DatePicker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.mjs","names":["datePickerMessages","useControlledState"],"sources":["../../../src/base-ui/DatePicker/DatePicker.tsx"],"sourcesContent":["'use client';\n\nimport dayjs from 'dayjs';\nimport { CalendarIcon } from 'lucide-react';\nimport { memo, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport datePickerMessages from '@/i18n/resources/en/datePicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\n\nimport { clampToBounds, DEFAULT_FORMAT } from './calendar';\nimport CalendarPanel from './CalendarPanel';\nimport PickerShell from './PickerShell';\nimport { styles } from './style';\nimport type { DatePickerProps } from './type';\n\nconst PLACEHOLDER_KEY = {\n date: 'datePicker.placeholder',\n month: 'datePicker.monthPlaceholder',\n year: 'datePicker.yearPlaceholder',\n} as const;\n\nexport const formatDate = (date: Date, format: DatePickerProps['format'], fallback: string) =>\n typeof format === 'function' ? format(date) : dayjs(date).format(format ?? fallback);\n\nconst DatePicker = memo<DatePickerProps>(\n ({\n allowClear = true,\n className,\n defaultValue = null,\n disabled,\n disabledDate,\n footer,\n format,\n max,\n min,\n mode = 'date',\n onChange,\n placeholder,\n shadow,\n size,\n style,\n value,\n variant,\n }) => {\n const { t } = useTranslation(datePickerMessages);\n const [current, setCurrent] = useControlledState<Date | null>(defaultValue, {\n defaultValue,\n onChange,\n value,\n });\n const [open, setOpen] = useState(false);\n const [month, setMonth] = useState<Date>(() => current ?? new Date());\n\n const text = current ? formatDate(current, format, DEFAULT_FORMAT[mode]) : null;\n\n return (\n <PickerShell\n className={className}\n disabled={disabled}\n open={open}\n shadow={shadow}\n showClear={allowClear && !!current}\n size={size}\n style={style}\n variant={variant}\n icon={\n <span className={styles.icon}>\n <Icon icon={CalendarIcon} size={14} />\n </span>\n }\n trigger={\n <button className={styles.trigger} disabled={disabled} type=\"button\">\n {text ?? (\n <span className={styles.placeholder}>{placeholder ?? t(PLACEHOLDER_KEY[mode])}</span>\n )}\n </button>\n }\n onClear={() => setCurrent(null)}\n onOpenChange={(next) => {\n if (next) setMonth(current ?? clampToBounds(new Date(), { max, min }));\n setOpen(next);\n }}\n >\n <CalendarPanel\n bounds={{ disabledDate, max, min }}\n mode={mode}\n month={month}\n selected={current}\n onMonthChange={setMonth}\n onSelect={(date) => {\n setCurrent(date);\n setOpen(false);\n }}\n />\n {footer && <div className={styles.footer}>{footer}</div>}\n </PickerShell>\n );\n },\n);\n\nDatePicker.displayName = 'DatePicker';\n\nexport default DatePicker;\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAM,kBAAkB;CACtB,MAAM;CACN,OAAO;CACP,MAAM;AACR;AAEA,MAAa,cAAc,MAAY,QAAmC,aACxE,OAAO,WAAW,aAAa,OAAO,IAAI,IAAI,MAAM,IAAI,CAAC,CAAC,OAAO,UAAU,QAAQ;AAErF,MAAM,aAAa,MAChB,EACC,aAAa,MACb,WACA,eAAe,MACf,UACA,cACA,QACA,QACA,KACA,KACA,OAAO,QACP,UACA,aACA,QACA,MACA,OACA,OACA,cACI;CACJ,MAAM,EAAE,MAAM,eAAeA,kBAAkB;CAC/C,MAAM,CAAC,SAAS,cAAcC,cAAgC,cAAc;EAC1E;EACA;EACA;CACF,CAAC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,eAAqB,2BAAW,IAAI,KAAK,CAAC;CAEpE,MAAM,OAAO,UAAU,WAAW,SAAS,QAAQ,eAAe,KAAK,IAAI;CAE3E,OACE,qBAAC,aAAD;EACa;EACD;EACJ;EACE;EACR,WAAW,cAAc,CAAC,CAAC;EACrB;EACC;EACE;EACT,MACE,oBAAC,QAAD;GAAM,WAAW,OAAO;GACtB,UAAA,oBAAC,MAAD;IAAM,MAAM;IAAc,MAAM;GAAK,CAAA;EACjC,CAAA;EAER,SACE,oBAAC,UAAD;GAAQ,WAAW,OAAO;GAAmB;GAAU,MAAK;GACzD,UAAA,QACC,oBAAC,QAAD;IAAM,WAAW,OAAO;IAAc,UAAA,eAAe,EAAE,gBAAgB,KAAK;GAAQ,CAAA;EAEhF,CAAA;EAEV,eAAe,WAAW,IAAI;EAC9B,eAAe,SAAS;GACtB,IAAI,MAAM,SAAS,WAAW,8BAAc,IAAI,KAAK,GAAG;IAAE;IAAK;GAAI,CAAC,CAAC;GACrE,QAAQ,IAAI;EACd;EAzBF,UAAA,CA2BE,oBAAC,eAAD;GACE,QAAQ;IAAE;IAAc;IAAK;GAAI;GAC3B;GACC;GACP,UAAU;GACV,eAAe;GACf,WAAW,SAAS;IAClB,WAAW,IAAI;IACf,QAAQ,KAAK;GACf;EACD,CAAA,GACA,UAAU,oBAAC,OAAD;GAAK,WAAW,OAAO;GAAS,UAAA;EAAY,CAAA,CAC5C;;AAEjB,CACF;AAEA,WAAW,cAAc"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DateRangePickerProps } from "./type.mjs";
|
|
2
|
+
//#region src/base-ui/DatePicker/DateRangePicker.d.ts
|
|
3
|
+
declare const DateRangePicker: import("react").NamedExoticComponent<DateRangePickerProps>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { DateRangePicker as default };
|
|
6
|
+
//# sourceMappingURL=DateRangePicker.d.mts.map
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import Icon from "../../Icon/Icon.mjs";
|
|
3
|
+
import { useTranslation } from "../../i18n/useTranslation.mjs";
|
|
4
|
+
import datePicker_default from "../../i18n/resources/en/datePicker.mjs";
|
|
5
|
+
import { DEFAULT_FORMAT, clampToBounds, orderRange } from "./calendar.mjs";
|
|
6
|
+
import { styles } from "./style.mjs";
|
|
7
|
+
import CalendarPanel from "./CalendarPanel.mjs";
|
|
8
|
+
import PickerShell from "./PickerShell.mjs";
|
|
9
|
+
import { formatDate } from "./DatePicker.mjs";
|
|
10
|
+
import { memo, useState } from "react";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import useMergeState from "use-merge-value";
|
|
13
|
+
import { ArrowRight, CalendarIcon } from "lucide-react";
|
|
14
|
+
import dayjs from "dayjs";
|
|
15
|
+
//#region src/base-ui/DatePicker/DateRangePicker.tsx
|
|
16
|
+
const EMPTY = [null, null];
|
|
17
|
+
const DateRangePicker = memo(({ allowClear = true, className, defaultValue = EMPTY, disabled, disabledDate, format, max, min, onChange, placeholder, shadow, size, style, value, variant }) => {
|
|
18
|
+
const { t } = useTranslation(datePicker_default);
|
|
19
|
+
const [current, setCurrent] = useMergeState(defaultValue, {
|
|
20
|
+
defaultValue,
|
|
21
|
+
onChange,
|
|
22
|
+
value
|
|
23
|
+
});
|
|
24
|
+
const [open, setOpen] = useState(false);
|
|
25
|
+
const [draft, setDraft] = useState(EMPTY);
|
|
26
|
+
const [hovered, setHovered] = useState(null);
|
|
27
|
+
const [month, setMonth] = useState(() => current[0] ?? /* @__PURE__ */ new Date());
|
|
28
|
+
const shown = open && draft[0] ? draft : current;
|
|
29
|
+
const nextMonth = dayjs(month).add(1, "month").toDate();
|
|
30
|
+
const bounds = {
|
|
31
|
+
disabledDate,
|
|
32
|
+
max,
|
|
33
|
+
min
|
|
34
|
+
};
|
|
35
|
+
const half = (date, fallback, active) => /* @__PURE__ */ jsx("span", {
|
|
36
|
+
className: styles.rangeHalf,
|
|
37
|
+
"data-active": active ? "" : void 0,
|
|
38
|
+
children: date ? formatDate(date, format, DEFAULT_FORMAT.date) : /* @__PURE__ */ jsx("span", {
|
|
39
|
+
className: styles.placeholder,
|
|
40
|
+
children: fallback
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
const select = (date) => {
|
|
44
|
+
if (!draft[0] || draft[1]) {
|
|
45
|
+
setDraft([date, null]);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const ordered = orderRange(draft[0], date);
|
|
49
|
+
setDraft(EMPTY);
|
|
50
|
+
setCurrent(ordered);
|
|
51
|
+
setOpen(false);
|
|
52
|
+
};
|
|
53
|
+
return /* @__PURE__ */ jsx(PickerShell, {
|
|
54
|
+
className,
|
|
55
|
+
disabled,
|
|
56
|
+
open,
|
|
57
|
+
shadow,
|
|
58
|
+
showClear: allowClear && !!(current[0] || current[1]),
|
|
59
|
+
size,
|
|
60
|
+
style,
|
|
61
|
+
variant,
|
|
62
|
+
icon: /* @__PURE__ */ jsx("span", {
|
|
63
|
+
className: styles.icon,
|
|
64
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
65
|
+
icon: CalendarIcon,
|
|
66
|
+
size: 14
|
|
67
|
+
})
|
|
68
|
+
}),
|
|
69
|
+
trigger: /* @__PURE__ */ jsx("button", {
|
|
70
|
+
className: styles.trigger,
|
|
71
|
+
disabled,
|
|
72
|
+
type: "button",
|
|
73
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
74
|
+
className: styles.rangeTrigger,
|
|
75
|
+
children: [
|
|
76
|
+
half(shown[0], placeholder?.[0] ?? t("datePicker.startPlaceholder"), open && !draft[0]),
|
|
77
|
+
/* @__PURE__ */ jsx("span", {
|
|
78
|
+
className: styles.icon,
|
|
79
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
80
|
+
icon: ArrowRight,
|
|
81
|
+
size: 14
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
half(shown[1], placeholder?.[1] ?? t("datePicker.endPlaceholder"), open && !!draft[0])
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
}),
|
|
88
|
+
onClear: () => setCurrent(EMPTY),
|
|
89
|
+
onOpenChange: (next) => {
|
|
90
|
+
if (next) {
|
|
91
|
+
setMonth(current[0] ?? clampToBounds(/* @__PURE__ */ new Date(), {
|
|
92
|
+
max,
|
|
93
|
+
min
|
|
94
|
+
}));
|
|
95
|
+
setDraft(EMPTY);
|
|
96
|
+
}
|
|
97
|
+
setOpen(next);
|
|
98
|
+
},
|
|
99
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
100
|
+
className: styles.range,
|
|
101
|
+
children: [/* @__PURE__ */ jsx(CalendarPanel, {
|
|
102
|
+
bounds,
|
|
103
|
+
hovered,
|
|
104
|
+
mode: "date",
|
|
105
|
+
month,
|
|
106
|
+
range: draft[0] ? draft : current,
|
|
107
|
+
showNav: false,
|
|
108
|
+
onHover: setHovered,
|
|
109
|
+
onMonthChange: setMonth,
|
|
110
|
+
onSelect: select
|
|
111
|
+
}), /* @__PURE__ */ jsx(CalendarPanel, {
|
|
112
|
+
bounds,
|
|
113
|
+
hovered,
|
|
114
|
+
mode: "date",
|
|
115
|
+
month: nextMonth,
|
|
116
|
+
range: draft[0] ? draft : current,
|
|
117
|
+
onHover: setHovered,
|
|
118
|
+
onMonthChange: (next) => setMonth(dayjs(next).subtract(1, "month").toDate()),
|
|
119
|
+
onSelect: select
|
|
120
|
+
})]
|
|
121
|
+
})
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
DateRangePicker.displayName = "DateRangePicker";
|
|
125
|
+
//#endregion
|
|
126
|
+
export { DateRangePicker as default };
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=DateRangePicker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateRangePicker.mjs","names":["datePickerMessages","useControlledState"],"sources":["../../../src/base-ui/DatePicker/DateRangePicker.tsx"],"sourcesContent":["'use client';\n\nimport dayjs from 'dayjs';\nimport { ArrowRight, CalendarIcon } from 'lucide-react';\nimport { memo, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport datePickerMessages from '@/i18n/resources/en/datePicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\n\nimport { clampToBounds, DEFAULT_FORMAT, orderRange } from './calendar';\nimport CalendarPanel from './CalendarPanel';\nimport { formatDate } from './DatePicker';\nimport PickerShell from './PickerShell';\nimport { styles } from './style';\nimport type { DateRangePickerProps, DateRangeValue } from './type';\n\nconst EMPTY: DateRangeValue = [null, null];\n\nconst DateRangePicker = memo<DateRangePickerProps>(\n ({\n allowClear = true,\n className,\n defaultValue = EMPTY,\n disabled,\n disabledDate,\n format,\n max,\n min,\n onChange,\n placeholder,\n shadow,\n size,\n style,\n value,\n variant,\n }) => {\n const { t } = useTranslation(datePickerMessages);\n const [current, setCurrent] = useControlledState<DateRangeValue>(defaultValue, {\n defaultValue,\n onChange,\n value,\n });\n const [open, setOpen] = useState(false);\n const [draft, setDraft] = useState<DateRangeValue>(EMPTY);\n const [hovered, setHovered] = useState<Date | null>(null);\n const [month, setMonth] = useState<Date>(() => current[0] ?? new Date());\n\n const shown = open && draft[0] ? draft : current;\n const nextMonth = dayjs(month).add(1, 'month').toDate();\n const bounds = { disabledDate, max, min };\n\n const half = (date: Date | null, fallback: string, active: boolean) => (\n <span className={styles.rangeHalf} data-active={active ? '' : undefined}>\n {date ? (\n formatDate(date, format, DEFAULT_FORMAT.date)\n ) : (\n <span className={styles.placeholder}>{fallback}</span>\n )}\n </span>\n );\n\n const select = (date: Date) => {\n if (!draft[0] || draft[1]) {\n setDraft([date, null]);\n return;\n }\n const ordered = orderRange(draft[0], date);\n setDraft(EMPTY);\n setCurrent(ordered);\n setOpen(false);\n };\n\n return (\n <PickerShell\n className={className}\n disabled={disabled}\n open={open}\n shadow={shadow}\n showClear={allowClear && !!(current[0] || current[1])}\n size={size}\n style={style}\n variant={variant}\n icon={\n <span className={styles.icon}>\n <Icon icon={CalendarIcon} size={14} />\n </span>\n }\n trigger={\n <button className={styles.trigger} disabled={disabled} type=\"button\">\n <span className={styles.rangeTrigger}>\n {half(\n shown[0],\n placeholder?.[0] ?? t('datePicker.startPlaceholder'),\n open && !draft[0],\n )}\n <span className={styles.icon}>\n <Icon icon={ArrowRight} size={14} />\n </span>\n {half(\n shown[1],\n placeholder?.[1] ?? t('datePicker.endPlaceholder'),\n open && !!draft[0],\n )}\n </span>\n </button>\n }\n onClear={() => setCurrent(EMPTY)}\n onOpenChange={(next) => {\n if (next) {\n setMonth(current[0] ?? clampToBounds(new Date(), { max, min }));\n setDraft(EMPTY);\n }\n setOpen(next);\n }}\n >\n <div className={styles.range}>\n <CalendarPanel\n bounds={bounds}\n hovered={hovered}\n mode=\"date\"\n month={month}\n range={draft[0] ? draft : current}\n showNav={false}\n onHover={setHovered}\n onMonthChange={setMonth}\n onSelect={select}\n />\n <CalendarPanel\n bounds={bounds}\n hovered={hovered}\n mode=\"date\"\n month={nextMonth}\n range={draft[0] ? draft : current}\n onHover={setHovered}\n onMonthChange={(next) => setMonth(dayjs(next).subtract(1, 'month').toDate())}\n onSelect={select}\n />\n </div>\n </PickerShell>\n );\n },\n);\n\nDateRangePicker.displayName = 'DateRangePicker';\n\nexport default DateRangePicker;\n"],"mappings":";;;;;;;;;;;;;;;AAkBA,MAAM,QAAwB,CAAC,MAAM,IAAI;AAEzC,MAAM,kBAAkB,MACrB,EACC,aAAa,MACb,WACA,eAAe,OACf,UACA,cACA,QACA,KACA,KACA,UACA,aACA,QACA,MACA,OACA,OACA,cACI;CACJ,MAAM,EAAE,MAAM,eAAeA,kBAAkB;CAC/C,MAAM,CAAC,SAAS,cAAcC,cAAmC,cAAc;EAC7E;EACA;EACA;CACF,CAAC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAyB,KAAK;CACxD,MAAM,CAAC,SAAS,cAAc,SAAsB,IAAI;CACxD,MAAM,CAAC,OAAO,YAAY,eAAqB,QAAQ,sBAAM,IAAI,KAAK,CAAC;CAEvE,MAAM,QAAQ,QAAQ,MAAM,KAAK,QAAQ;CACzC,MAAM,YAAY,MAAM,KAAK,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,OAAO;CACtD,MAAM,SAAS;EAAE;EAAc;EAAK;CAAI;CAExC,MAAM,QAAQ,MAAmB,UAAkB,WACjD,oBAAC,QAAD;EAAM,WAAW,OAAO;EAAW,eAAa,SAAS,KAAK,KAAA;EAC3D,UAAA,OACC,WAAW,MAAM,QAAQ,eAAe,IAAI,IAE5C,oBAAC,QAAD;GAAM,WAAW,OAAO;GAAc,UAAA;EAAe,CAAA;CAEnD,CAAA;CAGR,MAAM,UAAU,SAAe;EAC7B,IAAI,CAAC,MAAM,MAAM,MAAM,IAAI;GACzB,SAAS,CAAC,MAAM,IAAI,CAAC;GACrB;EACF;EACA,MAAM,UAAU,WAAW,MAAM,IAAI,IAAI;EACzC,SAAS,KAAK;EACd,WAAW,OAAO;EAClB,QAAQ,KAAK;CACf;CAEA,OACE,oBAAC,aAAD;EACa;EACD;EACJ;EACE;EACR,WAAW,cAAc,CAAC,EAAE,QAAQ,MAAM,QAAQ;EAC5C;EACC;EACE;EACT,MACE,oBAAC,QAAD;GAAM,WAAW,OAAO;GACtB,UAAA,oBAAC,MAAD;IAAM,MAAM;IAAc,MAAM;GAAK,CAAA;EACjC,CAAA;EAER,SACE,oBAAC,UAAD;GAAQ,WAAW,OAAO;GAAmB;GAAU,MAAK;GAC1D,UAAA,qBAAC,QAAD;IAAM,WAAW,OAAO;IAAxB,UAAA;KACG,KACC,MAAM,IACN,cAAc,MAAM,EAAE,6BAA6B,GACnD,QAAQ,CAAC,MAAM,EACjB;KACA,oBAAC,QAAD;MAAM,WAAW,OAAO;MACtB,UAAA,oBAAC,MAAD;OAAM,MAAM;OAAY,MAAM;MAAK,CAAA;KAC/B,CAAA;KACL,KACC,MAAM,IACN,cAAc,MAAM,EAAE,2BAA2B,GACjD,QAAQ,CAAC,CAAC,MAAM,EAClB;IACI;;EACA,CAAA;EAEV,eAAe,WAAW,KAAK;EAC/B,eAAe,SAAS;GACtB,IAAI,MAAM;IACR,SAAS,QAAQ,MAAM,8BAAc,IAAI,KAAK,GAAG;KAAE;KAAK;IAAI,CAAC,CAAC;IAC9D,SAAS,KAAK;GAChB;GACA,QAAQ,IAAI;EACd;EAEA,UAAA,qBAAC,OAAD;GAAK,WAAW,OAAO;GAAvB,UAAA,CACE,oBAAC,eAAD;IACU;IACC;IACT,MAAK;IACE;IACP,OAAO,MAAM,KAAK,QAAQ;IAC1B,SAAS;IACT,SAAS;IACT,eAAe;IACf,UAAU;GACX,CAAA,GACD,oBAAC,eAAD;IACU;IACC;IACT,MAAK;IACL,OAAO;IACP,OAAO,MAAM,KAAK,QAAQ;IAC1B,SAAS;IACT,gBAAgB,SAAS,SAAS,MAAM,IAAI,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC;IAC3E,UAAU;GACX,CAAA,CACE;;CACM,CAAA;AAEjB,CACF;AAEA,gBAAgB,cAAc"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { rootVariants } from "../Input/style.mjs";
|
|
3
|
+
import ClearButton from "../Input/ClearButton.mjs";
|
|
4
|
+
import { panelStyles } from "../panelStyles.mjs";
|
|
5
|
+
import { PopoverPopup, PopoverPortal, PopoverPositioner, PopoverRoot, PopoverTriggerElement } from "../Popover/atoms.mjs";
|
|
6
|
+
import { memo, useRef } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { cx, useThemeMode } from "antd-style";
|
|
9
|
+
//#region src/base-ui/DatePicker/PickerShell.tsx
|
|
10
|
+
const PickerShell = memo(({ children, className, disabled, icon, onClear, onOpenChange, open, shadow, showClear, size = "middle", style, trigger, variant }) => {
|
|
11
|
+
const { isDarkMode } = useThemeMode();
|
|
12
|
+
const anchorRef = useRef(null);
|
|
13
|
+
const popupRef = useRef(null);
|
|
14
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
15
|
+
"data-disabled": disabled ? "" : void 0,
|
|
16
|
+
ref: anchorRef,
|
|
17
|
+
style,
|
|
18
|
+
className: cx(rootVariants({
|
|
19
|
+
shadow,
|
|
20
|
+
size,
|
|
21
|
+
variant: variant || (isDarkMode ? "filled" : "outlined")
|
|
22
|
+
}), className),
|
|
23
|
+
children: [/* @__PURE__ */ jsxs(PopoverRoot, {
|
|
24
|
+
open,
|
|
25
|
+
onOpenChange: (next) => !disabled && onOpenChange(next),
|
|
26
|
+
children: [/* @__PURE__ */ jsx(PopoverTriggerElement, { children: trigger }), /* @__PURE__ */ jsx(PopoverPortal, { children: /* @__PURE__ */ jsx(PopoverPositioner, {
|
|
27
|
+
anchor: anchorRef,
|
|
28
|
+
placement: "bottomLeft",
|
|
29
|
+
children: /* @__PURE__ */ jsx(PopoverPopup, {
|
|
30
|
+
className: panelStyles.popup,
|
|
31
|
+
ref: popupRef,
|
|
32
|
+
initialFocus: () => popupRef.current?.querySelector("[data-focus-target]") ?? true,
|
|
33
|
+
children
|
|
34
|
+
})
|
|
35
|
+
}) })]
|
|
36
|
+
}), showClear && !disabled ? /* @__PURE__ */ jsx(ClearButton, { onClear }) : icon]
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
PickerShell.displayName = "PickerShell";
|
|
40
|
+
//#endregion
|
|
41
|
+
export { PickerShell as default };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=PickerShell.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PickerShell.mjs","names":[],"sources":["../../../src/base-ui/DatePicker/PickerShell.tsx"],"sourcesContent":["'use client';\n\nimport { cx, useThemeMode } from 'antd-style';\nimport { type CSSProperties, memo, type ReactElement, type ReactNode, useRef } from 'react';\n\nimport ClearButton from '@/base-ui/Input/ClearButton';\nimport { rootVariants } from '@/base-ui/Input/style';\nimport type { InputSize, InputVariant } from '@/base-ui/Input/type';\nimport { panelStyles } from '@/base-ui/panelStyles';\nimport {\n PopoverPopup,\n PopoverPortal,\n PopoverPositioner,\n PopoverRoot,\n PopoverTriggerElement,\n} from '@/base-ui/Popover';\n\nexport interface PickerShellProps {\n children: ReactNode;\n className?: string;\n disabled?: boolean;\n icon: ReactNode;\n onClear: () => void;\n onOpenChange: (open: boolean) => void;\n open: boolean;\n shadow?: boolean;\n showClear: boolean;\n size?: InputSize;\n style?: CSSProperties;\n trigger: ReactElement;\n variant?: InputVariant;\n}\n\nconst PickerShell = memo<PickerShellProps>(\n ({\n children,\n className,\n disabled,\n icon,\n onClear,\n onOpenChange,\n open,\n shadow,\n showClear,\n size = 'middle',\n style,\n trigger,\n variant,\n }) => {\n const { isDarkMode } = useThemeMode();\n const anchorRef = useRef<HTMLDivElement>(null);\n const popupRef = useRef<HTMLDivElement>(null);\n\n return (\n <div\n data-disabled={disabled ? '' : undefined}\n ref={anchorRef}\n style={style}\n className={cx(\n rootVariants({ shadow, size, variant: variant || (isDarkMode ? 'filled' : 'outlined') }),\n className,\n )}\n >\n <PopoverRoot open={open} onOpenChange={(next) => !disabled && onOpenChange(next)}>\n <PopoverTriggerElement>{trigger}</PopoverTriggerElement>\n <PopoverPortal>\n <PopoverPositioner anchor={anchorRef} placement=\"bottomLeft\">\n <PopoverPopup\n className={panelStyles.popup}\n ref={popupRef}\n initialFocus={() =>\n popupRef.current?.querySelector<HTMLElement>('[data-focus-target]') ?? true\n }\n >\n {children}\n </PopoverPopup>\n </PopoverPositioner>\n </PopoverPortal>\n </PopoverRoot>\n {showClear && !disabled ? <ClearButton onClear={onClear} /> : icon}\n </div>\n );\n },\n);\n\nPickerShell.displayName = 'PickerShell';\n\nexport default PickerShell;\n"],"mappings":";;;;;;;;;AAiCA,MAAM,cAAc,MACjB,EACC,UACA,WACA,UACA,MACA,SACA,cACA,MACA,QACA,WACA,OAAO,UACP,OACA,SACA,cACI;CACJ,MAAM,EAAE,eAAe,aAAa;CACpC,MAAM,YAAY,OAAuB,IAAI;CAC7C,MAAM,WAAW,OAAuB,IAAI;CAE5C,OACE,qBAAC,OAAD;EACE,iBAAe,WAAW,KAAK,KAAA;EAC/B,KAAK;EACE;EACP,WAAW,GACT,aAAa;GAAE;GAAQ;GAAM,SAAS,YAAY,aAAa,WAAW;EAAY,CAAC,GACvF,SACF;EAPF,UAAA,CASE,qBAAC,aAAD;GAAmB;GAAM,eAAe,SAAS,CAAC,YAAY,aAAa,IAAI;GAA/E,UAAA,CACE,oBAAC,uBAAD,EAAA,UAAwB,QAA+B,CAAA,GACvD,oBAAC,eAAD,EAAA,UACE,oBAAC,mBAAD;IAAmB,QAAQ;IAAW,WAAU;IAC9C,UAAA,oBAAC,cAAD;KACE,WAAW,YAAY;KACvB,KAAK;KACL,oBACE,SAAS,SAAS,cAA2B,qBAAqB,KAAK;KAGxE;IACW,CAAA;GACG,CAAA,EACN,CAAA,CACJ;EACZ,CAAA,GAAA,aAAa,CAAC,WAAW,oBAAC,aAAD,EAAsB,QAAU,CAAA,IAAI,IAC3D;;AAET,CACF;AAEA,YAAY,cAAc"}
|