@lobehub/ui 4.30.2 → 4.32.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.d.mts +2 -2
- package/es/Accordion/Accordion.mjs +2 -2
- package/es/Accordion/Accordion.mjs.map +1 -1
- package/es/Accordion/AccordionItem.d.mts +2 -2
- package/es/Accordion/AccordionItem.mjs +2 -2
- package/es/Accordion/AccordionItem.mjs.map +1 -1
- package/es/ActionIcon/ActionIcon.d.mts +2 -2
- package/es/Alert/Alert.d.mts +2 -2
- package/es/AutoComplete/Select.d.mts +2 -2
- package/es/Avatar/AvatarGroup/index.d.mts +2 -2
- package/es/Burger/Burger.d.mts +2 -2
- package/es/Checkbox/Checkbox.mjs +2 -2
- package/es/Checkbox/Checkbox.mjs.map +1 -1
- package/es/Checkbox/CheckboxGroup.mjs +2 -2
- package/es/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/CodeDiff/CodeDiff.d.mts +2 -2
- package/es/CodeDiff/PatchDiff.d.mts +2 -2
- package/es/CodeEditor/CodeEditor.d.mts +2 -2
- package/es/CodeEditor/CodeEditor.mjs +2 -2
- package/es/CodeEditor/CodeEditor.mjs.map +1 -1
- package/es/Collapse/Collapse.d.mts +2 -2
- package/es/ColorSwatches/ColorSwatches.mjs +2 -2
- package/es/ColorSwatches/ColorSwatches.mjs.map +1 -1
- package/es/ConfigProvider/index.d.mts +2 -2
- package/es/ContextMenu/ContextMenuHost.d.mts +2 -2
- package/es/ContextMenu/ContextMenuHost.mjs +1 -1
- package/es/ContextMenu/ContextMenuHost.mjs.map +1 -1
- package/es/ContextMenu/index.d.mts +4 -2
- package/es/ContextMenu/renderItems.d.mts +4 -0
- package/es/ContextMenu/renderItems.mjs +21 -32
- package/es/ContextMenu/renderItems.mjs.map +1 -1
- package/es/ContextMenu/store.d.mts +7 -2
- package/es/ContextMenu/store.mjs +4 -1
- package/es/ContextMenu/store.mjs.map +1 -1
- package/es/CopyButton/CopyButton.d.mts +2 -2
- package/es/DatePicker/DatePicker.d.mts +2 -2
- package/es/DraggablePanel/DraggablePanel.mjs +2 -2
- package/es/DraggablePanel/DraggablePanel.mjs.map +1 -1
- package/es/DraggablePanel/components/DraggablePanelBody.d.mts +2 -2
- package/es/DraggablePanel/components/DraggablePanelContainer.d.mts +2 -2
- package/es/DraggablePanel/components/DraggablePanelFooter.d.mts +2 -2
- package/es/DraggablePanel/components/DraggablePanelHeader.d.mts +2 -2
- package/es/DraggablePanel/components/DraggablePanelHeader.mjs +2 -2
- package/es/DraggablePanel/components/DraggablePanelHeader.mjs.map +1 -1
- package/es/DraggableSideNav/DraggableSideNav.d.mts +2 -2
- package/es/DraggableSideNav/DraggableSideNav.mjs +2 -2
- package/es/DraggableSideNav/DraggableSideNav.mjs.map +1 -1
- package/es/Drawer/Drawer.d.mts +2 -2
- package/es/Dropdown/Dropdown.d.mts +2 -2
- package/es/DropdownMenu/DropdownMenu.d.mts +2 -2
- package/es/DropdownMenu/DropdownMenu.mjs +7 -3
- package/es/DropdownMenu/DropdownMenu.mjs.map +1 -1
- package/es/DropdownMenu/index.d.mts +3 -2
- package/es/DropdownMenu/renderItems.d.mts +3 -3
- package/es/DropdownMenu/renderItems.mjs +20 -30
- package/es/DropdownMenu/renderItems.mjs.map +1 -1
- package/es/DropdownMenu/type.d.mts +9 -0
- package/es/EditableText/EditableText.d.mts +2 -2
- package/es/EditableText/EditableText.mjs +2 -2
- package/es/EditableText/EditableText.mjs.map +1 -1
- package/es/EditorSlashMenu/atoms.d.mts +12 -12
- package/es/EmojiPicker/EmojiPicker.d.mts +2 -2
- package/es/EmojiPicker/EmojiPicker.mjs +3 -3
- package/es/EmojiPicker/EmojiPicker.mjs.map +1 -1
- package/es/Flex/FlexBasic.d.mts +2 -2
- package/es/FontLoader/index.d.mts +2 -2
- package/es/Footer/Footer.d.mts +2 -2
- package/es/Form/components/FormGroup.d.mts +2 -2
- package/es/Form/components/FormItem.d.mts +2 -2
- package/es/Form/components/FormSubmitFooter.d.mts +2 -2
- package/es/FormModal/FormModal.d.mts +2 -2
- package/es/GuideCard/GuideCard.d.mts +2 -2
- package/es/Header/Header.d.mts +2 -2
- package/es/Highlighter/Highlighter.d.mts +2 -2
- package/es/Highlighter/SyntaxHighlighter/index.d.mts +2 -2
- package/es/Hotkey/Hotkey.d.mts +2 -2
- package/es/HotkeyInput/HotkeyInput.d.mts +2 -2
- package/es/HotkeyInput/HotkeyInput.mjs +2 -2
- package/es/HotkeyInput/HotkeyInput.mjs.map +1 -1
- package/es/Icon/Icon.d.mts +2 -2
- package/es/Icon/components/IconProvider.d.mts +3 -3
- package/es/Image/PreviewGroup.d.mts +2 -2
- package/es/ImageSelect/ImageSelect.d.mts +2 -2
- package/es/ImageSelect/ImageSelect.mjs +2 -2
- package/es/ImageSelect/ImageSelect.mjs.map +1 -1
- package/es/Input/Input.d.mts +2 -2
- package/es/Input/InputNumber.d.mts +2 -2
- package/es/Input/InputOPT.d.mts +2 -2
- package/es/Input/InputPassword.d.mts +2 -2
- package/es/Input/TextArea.d.mts +2 -2
- package/es/Layout/components/LayoutFooter.d.mts +2 -2
- package/es/Layout/components/LayoutHeader.d.mts +2 -2
- package/es/Layout/components/LayoutMain.d.mts +2 -2
- package/es/Layout/components/LayoutSidebar.d.mts +2 -2
- package/es/Layout/components/LayoutSidebarInner.d.mts +2 -2
- package/es/Layout/components/LayoutToc.d.mts +2 -2
- package/es/List/ListItem/index.d.mts +2 -2
- package/es/LobeSelect/LobeSelect.d.mts +2 -2
- package/es/LobeSelect/atoms.d.mts +19 -19
- package/es/LobeSwitch/LobeSwitch.d.mts +2 -2
- package/es/LobeSwitch/atoms.d.mts +4 -4
- package/es/LobeSwitch/atoms.mjs +2 -2
- package/es/LobeSwitch/atoms.mjs.map +1 -1
- package/es/Markdown/Markdown.d.mts +2 -2
- package/es/Markdown/Typography.d.mts +2 -2
- package/es/Markdown/components/SearchResultCards/index.d.mts +2 -2
- package/es/MaskShadow/MaskShadow.d.mts +2 -2
- package/es/Menu/Menu.d.mts +2 -2
- package/es/Menu/baseItem.d.mts +21 -3
- package/es/Menu/index.d.mts +3 -2
- package/es/Menu/index.mjs +2 -1
- package/es/Menu/renderUtils.d.mts +35 -0
- package/es/Menu/renderUtils.mjs +46 -0
- package/es/Menu/renderUtils.mjs.map +1 -0
- package/es/Mermaid/Mermaid.d.mts +2 -2
- package/es/Mermaid/SyntaxMermaid/index.d.mts +2 -2
- package/es/Modal/Modal.d.mts +2 -2
- package/es/Modal/ModalProvider.d.mts +2 -2
- package/es/Modal/imperative.d.mts +2 -2
- package/es/MotionProvider/index.d.mts +2 -2
- package/es/Popover/ArrowIcon.d.mts +2 -2
- package/es/Popover/atoms.d.mts +9 -9
- package/es/Popover/context.d.mts +2 -2
- package/es/SearchBar/SearchBar.d.mts +2 -2
- package/es/SearchBar/SearchBar.mjs +2 -2
- package/es/SearchBar/SearchBar.mjs.map +1 -1
- package/es/Segmented/Segmented.d.mts +2 -2
- package/es/Select/Select.d.mts +6 -3
- package/es/Select/Select.mjs +6 -3
- package/es/Select/Select.mjs.map +1 -1
- package/es/Select/index.d.mts +2 -2
- package/es/SideNav/SideNav.d.mts +2 -2
- package/es/SliderWithInput/SliderWithInput.d.mts +2 -2
- package/es/SortableList/components/DragHandle.d.mts +2 -2
- package/es/SortableList/components/SortableItem.d.mts +2 -2
- package/es/ThemeProvider/ThemeProvider.d.mts +2 -2
- package/es/Toast/Toast.mjs +40 -22
- package/es/Toast/Toast.mjs.map +1 -1
- package/es/Toast/imperative.d.mts +3 -3
- package/es/Toast/index.d.mts +2 -2
- package/es/Toast/style.mjs +99 -12
- package/es/Toast/style.mjs.map +1 -1
- package/es/Toast/type.d.mts +33 -1
- package/es/Toc/Toc.d.mts +2 -2
- package/es/Toc/TocMobile.mjs +2 -2
- package/es/Toc/TocMobile.mjs.map +1 -1
- package/es/Video/index.d.mts +2 -2
- package/es/awesome/AuroraBackground/AuroraBackground.d.mts +2 -2
- package/es/awesome/BottomGradientButton/BottomGradientButton.d.mts +2 -2
- package/es/awesome/Features/Features.d.mts +2 -2
- package/es/awesome/Giscus/Giscus.d.mts +2 -2
- package/es/awesome/GradientButton/GradientButton.d.mts +2 -2
- package/es/awesome/GridBackground/GridBackground.d.mts +2 -2
- package/es/awesome/GridBackground/GridShowcase.d.mts +2 -2
- package/es/awesome/Hero/Hero.d.mts +2 -2
- package/es/awesome/Spline/Spine.d.mts +2 -2
- package/es/awesome/Spotlight/Spotlight.d.mts +2 -2
- package/es/awesome/SpotlightCard/SpotlightCard.d.mts +2 -2
- package/es/awesome/TypewriterEffect/TypewriterEffect.d.mts +2 -2
- package/es/brand/LobeChat/index.d.mts +2 -2
- package/es/brand/LobeHub/index.d.mts +2 -2
- package/es/brand/LogoThree/LogoSpline.d.mts +2 -2
- package/es/brand/LogoThree/index.d.mts +2 -2
- package/es/chat/BackBottom/BackBottom.d.mts +2 -2
- package/es/chat/ChatInputArea/components/ChatInputAreaInner.d.mts +2 -2
- package/es/chat/ChatItem/ChatItem.d.mts +2 -2
- package/es/chat/ChatList/ChatList.d.mts +2 -2
- package/es/chat/EditableMessage/EditableMessage.d.mts +2 -2
- package/es/chat/EditableMessage/EditableMessage.mjs +3 -3
- package/es/chat/EditableMessage/EditableMessage.mjs.map +1 -1
- package/es/chat/EditableMessageList/EditableMessageList.d.mts +2 -2
- package/es/chat/MessageInput/MessageInput.d.mts +2 -2
- package/es/chat/MessageModal/MessageModal.d.mts +2 -2
- package/es/chat/MessageModal/MessageModal.mjs +3 -3
- package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
- package/es/color/ColorScales/index.d.mts +2 -2
- package/es/color/CssVar/index.d.mts +2 -2
- package/es/i18n/context.d.mts +2 -2
- package/es/icons/lucideExtra/BotPromptIcon.d.mts +2 -2
- package/es/icons/lucideExtra/CreateBotIcon.d.mts +3 -3
- package/es/icons/lucideExtra/DiscordIcon.d.mts +3 -3
- package/es/icons/lucideExtra/GlobeOffIcon.d.mts +2 -2
- package/es/icons/lucideExtra/GroupBotIcon.d.mts +2 -2
- package/es/icons/lucideExtra/GroupBotSquareIcon.d.mts +3 -3
- package/es/icons/lucideExtra/LeftClickIcon.d.mts +3 -3
- package/es/icons/lucideExtra/LeftDoubleClickIcon.d.mts +2 -2
- package/es/icons/lucideExtra/McpIcon.d.mts +3 -3
- package/es/icons/lucideExtra/ProviderIcon.d.mts +2 -2
- package/es/icons/lucideExtra/RightClickIcon.d.mts +3 -3
- package/es/icons/lucideExtra/RightDoubleClickIcon.d.mts +3 -3
- package/es/icons/lucideExtra/ShapesUploadIcon.d.mts +2 -2
- package/es/icons/lucideExtra/TreeDownRightIcon.d.mts +2 -2
- package/es/icons/lucideExtra/TreeUpDownRightIcon.d.mts +2 -2
- package/es/index.d.mts +3 -3
- package/es/index.mjs +1 -1
- package/es/mdx/Mdx/index.d.mts +2 -2
- package/es/mobile/ChatHeader/ChatHeaderTitle.d.mts +2 -2
- package/es/mobile/ChatInputArea/components/ChatSendButton.d.mts +2 -2
- package/es/mobile/TabBar/TabBar.mjs +2 -2
- package/es/mobile/TabBar/TabBar.mjs.map +1 -1
- package/es/storybook/StoryBook/index.d.mts +2 -2
- package/package.json +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import Icon_default from "../Icon/Icon.mjs";
|
|
2
2
|
import { preventDefaultAndStopPropagation } from "../utils/dom.mjs";
|
|
3
3
|
import { styles } from "../Menu/sharedStyle.mjs";
|
|
4
|
+
import { getItemKey, getItemLabel, hasAnyIcon, hasCheckboxAndIcon, renderIcon } from "../Menu/renderUtils.mjs";
|
|
4
5
|
import common_default from "../i18n/resources/en/common.mjs";
|
|
5
6
|
import { useTranslation } from "../i18n/useTranslation.mjs";
|
|
6
|
-
import {
|
|
7
|
+
import { memo, useCallback, useState } from "react";
|
|
7
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { Switch } from "antd";
|
|
9
10
|
import { cx } from "antd-style";
|
|
@@ -53,35 +54,11 @@ const ContextMenuSwitchItemInternal = ({ checked: checkedProp, children, closeOn
|
|
|
53
54
|
})]
|
|
54
55
|
});
|
|
55
56
|
};
|
|
56
|
-
const getItemKey = (item, fallback) => {
|
|
57
|
-
if (item && "key" in item && item.key !== void 0) return item.key;
|
|
58
|
-
return fallback;
|
|
59
|
-
};
|
|
60
|
-
const getItemLabel = (item) => {
|
|
61
|
-
if (item.label !== void 0) return item.label;
|
|
62
|
-
if ("title" in item && item.title !== void 0) return item.title;
|
|
63
|
-
return item.key;
|
|
64
|
-
};
|
|
65
|
-
const renderIcon = (icon) => {
|
|
66
|
-
if (!icon) return null;
|
|
67
|
-
if (isValidElement(icon)) return icon;
|
|
68
|
-
return /* @__PURE__ */ jsx(Icon_default, {
|
|
69
|
-
icon,
|
|
70
|
-
size: "small"
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
const hasAnyIcon = (items) => {
|
|
74
|
-
return items.some((item) => {
|
|
75
|
-
if (!item) return false;
|
|
76
|
-
if (item.type === "checkbox") return true;
|
|
77
|
-
if ("icon" in item && item.icon) return true;
|
|
78
|
-
return false;
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
57
|
const renderItemContent = (item, options, iconNode) => {
|
|
82
58
|
const label = getItemLabel(item);
|
|
83
59
|
const extra = "extra" in item ? item.extra : void 0;
|
|
84
|
-
const
|
|
60
|
+
const indicatorOnRight = options?.indicatorOnRight;
|
|
61
|
+
const hasCustomIcon = iconNode !== void 0 && !indicatorOnRight;
|
|
85
62
|
const hasIcon = hasCustomIcon ? Boolean(iconNode) : Boolean(item.icon);
|
|
86
63
|
const shouldRenderIcon = hasCustomIcon ? Boolean(options?.reserveIconSpace || iconNode) : Boolean(hasIcon || options?.reserveIconSpace);
|
|
87
64
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -90,7 +67,7 @@ const renderItemContent = (item, options, iconNode) => {
|
|
|
90
67
|
shouldRenderIcon ? /* @__PURE__ */ jsx("span", {
|
|
91
68
|
"aria-hidden": !hasIcon,
|
|
92
69
|
className: styles.icon,
|
|
93
|
-
children: hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon) : null
|
|
70
|
+
children: hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon, "small") : null
|
|
94
71
|
}) : null,
|
|
95
72
|
/* @__PURE__ */ jsx("span", {
|
|
96
73
|
className: styles.label,
|
|
@@ -100,6 +77,7 @@ const renderItemContent = (item, options, iconNode) => {
|
|
|
100
77
|
className: styles.extra,
|
|
101
78
|
children: extra
|
|
102
79
|
}) : null,
|
|
80
|
+
indicatorOnRight && iconNode ? iconNode : null,
|
|
103
81
|
options?.submenu ? /* @__PURE__ */ jsx("span", {
|
|
104
82
|
className: styles.submenuArrow,
|
|
105
83
|
children: /* @__PURE__ */ jsx(ChevronRight, { size: 16 })
|
|
@@ -119,7 +97,9 @@ const invokeItemClick = (item, keyPath, event) => {
|
|
|
119
97
|
item.onClick(info);
|
|
120
98
|
};
|
|
121
99
|
const renderContextMenuItems = (items, keyPath = [], options) => {
|
|
122
|
-
const
|
|
100
|
+
const iconSpaceMode = options?.iconSpaceMode ?? "global";
|
|
101
|
+
const reserveIconSpace = options?.reserveIconSpace ?? hasAnyIcon(items, iconSpaceMode === "global");
|
|
102
|
+
const indicatorOnRight = options?.indicatorOnRight ?? hasCheckboxAndIcon(items);
|
|
123
103
|
return items.map((item, index) => {
|
|
124
104
|
if (!item) return null;
|
|
125
105
|
const itemKey = getItemKey(item, `${keyPath.join("-") || "root"}-${index}`);
|
|
@@ -141,7 +121,10 @@ const renderContextMenuItems = (items, keyPath = [], options) => {
|
|
|
141
121
|
disabled: checkboxItem.disabled,
|
|
142
122
|
label: labelText$1,
|
|
143
123
|
onCheckedChange: (checked) => checkboxItem.onCheckedChange?.(checked),
|
|
144
|
-
children: renderItemContent(checkboxItem, {
|
|
124
|
+
children: renderItemContent(checkboxItem, {
|
|
125
|
+
indicatorOnRight,
|
|
126
|
+
reserveIconSpace
|
|
127
|
+
}, indicator)
|
|
145
128
|
}, itemKey);
|
|
146
129
|
}
|
|
147
130
|
if (item.type === "switch") {
|
|
@@ -163,10 +146,16 @@ const renderContextMenuItems = (items, keyPath = [], options) => {
|
|
|
163
146
|
if (item.type === "divider") return /* @__PURE__ */ jsx(ContextMenu.Separator, { className: styles.separator }, itemKey);
|
|
164
147
|
if (item.type === "group") {
|
|
165
148
|
const group = item;
|
|
149
|
+
const groupReserveIconSpace = iconSpaceMode === "group" ? group.children ? hasAnyIcon(group.children) : false : reserveIconSpace;
|
|
150
|
+
const groupIndicatorOnRight = group.children ? hasCheckboxAndIcon(group.children) : false;
|
|
166
151
|
return /* @__PURE__ */ jsxs(ContextMenu.Group, { children: [group.label ? /* @__PURE__ */ jsx(ContextMenu.GroupLabel, {
|
|
167
152
|
className: styles.groupLabel,
|
|
168
153
|
children: group.label
|
|
169
|
-
}) : null, group.children ? renderContextMenuItems(group.children, nextKeyPath, {
|
|
154
|
+
}) : null, group.children ? renderContextMenuItems(group.children, nextKeyPath, {
|
|
155
|
+
iconSpaceMode,
|
|
156
|
+
indicatorOnRight: groupIndicatorOnRight,
|
|
157
|
+
reserveIconSpace: groupReserveIconSpace
|
|
158
|
+
}) : null] }, itemKey);
|
|
170
159
|
}
|
|
171
160
|
if (item.type === "submenu" || "children" in item && item.children) {
|
|
172
161
|
const submenu = item;
|
|
@@ -188,7 +177,7 @@ const renderContextMenuItems = (items, keyPath = [], options) => {
|
|
|
188
177
|
sideOffset: -1,
|
|
189
178
|
children: /* @__PURE__ */ jsx(ContextMenu.Popup, {
|
|
190
179
|
className: styles.popup,
|
|
191
|
-
children: submenu.children && submenu.children.length > 0 ? renderContextMenuItems(submenu.children, nextKeyPath) : /* @__PURE__ */ jsx(EmptyMenuItem, {})
|
|
180
|
+
children: submenu.children && submenu.children.length > 0 ? renderContextMenuItems(submenu.children, nextKeyPath, { iconSpaceMode }) : /* @__PURE__ */ jsx(EmptyMenuItem, {})
|
|
192
181
|
})
|
|
193
182
|
}) })] }, itemKey);
|
|
194
183
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderItems.mjs","names":["common","Icon","info: MenuInfo","label","labelText","isDanger"],"sources":["../../src/ContextMenu/renderItems.tsx"],"sourcesContent":["import { ContextMenu } from '@base-ui/react/context-menu';\nimport { Switch } from 'antd';\nimport { cx } from 'antd-style';\nimport { Check, ChevronRight } from 'lucide-react';\nimport type { MenuInfo } from 'rc-menu/es/interface';\nimport type {\n Key,\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n} from 'react';\nimport { isValidElement, memo, useCallback, useState } from 'react';\n\nimport Icon from '@/Icon';\nimport type { MenuDividerType, MenuItemGroupType, MenuItemType, SubMenuType } from '@/Menu';\nimport common from '@/i18n/resources/en/common';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport { preventDefaultAndStopPropagation } from '@/utils/dom';\n\nimport { styles } from './style';\nimport type { ContextMenuCheckboxItem, ContextMenuItem, ContextMenuSwitchItem } from './type';\n\nconst EmptyMenuItem = memo(() => {\n const { t } = useTranslation(common);\n return (\n <ContextMenu.Item className={cx(styles.item, styles.empty)} disabled>\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 <Switch\n checked={checked}\n disabled={disabled}\n onChange={handleCheckedChange}\n onClick={(_, e) => e.stopPropagation()}\n size=\"small\"\n style={{ marginInlineStart: 16 }}\n />\n </ContextMenu.Item>\n );\n};\n\ntype KeyableItem = { key?: Key };\n\nconst getItemKey = (item: KeyableItem, fallback: string): Key => {\n if (item && 'key' in item && item.key !== undefined) return item.key;\n return fallback;\n};\n\ntype LabelableItem = {\n key?: Key;\n label?: ReactNode;\n title?: ReactNode;\n};\n\nconst getItemLabel = (\n item: MenuItemType | SubMenuType | ContextMenuCheckboxItem | LabelableItem,\n): ReactNode => {\n if (item.label !== undefined) return item.label;\n if ('title' in item && item.title !== undefined) return item.title;\n return item.key;\n};\n\nconst renderIcon = (icon: MenuItemType['icon']) => {\n if (!icon) return null;\n if (isValidElement(icon)) return icon;\n return <Icon icon={icon} size={'small'} />;\n};\n\nconst hasAnyIcon = (items: ContextMenuItem[]): boolean => {\n return items.some((item) => {\n if (!item) return false;\n if ((item as ContextMenuCheckboxItem).type === 'checkbox') return true;\n if ('icon' in item && item.icon) return true;\n return false;\n });\n};\n\nconst renderItemContent = (\n item: MenuItemType | SubMenuType | ContextMenuCheckboxItem | ContextMenuSwitchItem,\n options?: { reserveIconSpace?: boolean; submenu?: boolean },\n iconNode?: ReactNode,\n) => {\n const label = getItemLabel(item);\n const extra = 'extra' in item ? item.extra : undefined;\n const hasCustomIcon = iconNode !== undefined;\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 return (\n <div className={styles.itemContent}>\n {shouldRenderIcon ? (\n <span aria-hidden={!hasIcon} className={styles.icon}>\n {hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon) : null}\n </span>\n ) : null}\n <span className={styles.label}>{label}</span>\n {extra ? <span className={styles.extra}>{extra}</span> : null}\n {options?.submenu ? (\n <span className={styles.submenuArrow}>\n <ChevronRight size={16} />\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?: { reserveIconSpace?: boolean },\n): ReactNode[] => {\n const reserveIconSpace = options?.reserveIconSpace ?? hasAnyIcon(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(checkboxItem, { reserveIconSpace }, indicator)}\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, { 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 MenuItemGroupType).type === 'group') {\n const group = item as MenuItemGroupType;\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, { reserveIconSpace })\n : null}\n </ContextMenu.Group>\n );\n }\n\n if (\n (item as SubMenuType).type === 'submenu' ||\n ('children' in item && (item as SubMenuType).children)\n ) {\n const submenu = item as SubMenuType;\n const label = getItemLabel(submenu);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = 'danger' in submenu && Boolean(submenu.danger);\n\n return (\n <ContextMenu.SubmenuRoot key={itemKey}>\n <ContextMenu.SubmenuTrigger\n className={cx(styles.item, isDanger && styles.danger)}\n disabled={submenu.disabled}\n label={labelText}\n >\n {renderItemContent(submenu, {\n reserveIconSpace,\n submenu: true,\n })}\n </ContextMenu.SubmenuTrigger>\n <ContextMenu.Portal>\n <ContextMenu.Positioner\n alignOffset={-4}\n className={styles.positioner}\n onContextMenu={preventDefaultAndStopPropagation}\n sideOffset={-1}\n >\n <ContextMenu.Popup className={styles.popup}>\n {submenu.children && submenu.children.length > 0 ? (\n renderContextMenuItems(submenu.children, nextKeyPath)\n ) : (\n <EmptyMenuItem />\n )}\n </ContextMenu.Popup>\n </ContextMenu.Positioner>\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, { reserveIconSpace })}\n </ContextMenu.Item>\n );\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderItems.mjs","names":["common","info: MenuInfo","label","labelText","isDanger","Icon"],"sources":["../../src/ContextMenu/renderItems.tsx"],"sourcesContent":["import { ContextMenu } from '@base-ui/react/context-menu';\nimport { Switch } from 'antd';\nimport { cx } from 'antd-style';\nimport { Check, ChevronRight } from 'lucide-react';\nimport type { MenuInfo } from 'rc-menu/es/interface';\nimport type {\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n} from 'react';\nimport { memo, useCallback, useState } from 'react';\n\nimport Icon from '@/Icon';\nimport {\n type MenuDividerType,\n type MenuItemGroupType,\n type MenuItemType,\n type RenderItemContentOptions,\n type RenderOptions,\n type SubMenuType,\n getItemKey,\n getItemLabel,\n hasAnyIcon,\n hasCheckboxAndIcon,\n renderIcon,\n} from '@/Menu';\nimport common from '@/i18n/resources/en/common';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport { preventDefaultAndStopPropagation } from '@/utils/dom';\n\nimport { styles } from './style';\nimport type { ContextMenuCheckboxItem, ContextMenuItem, ContextMenuSwitchItem } from './type';\n\nexport type { IconSpaceMode } from '@/Menu';\n\nconst EmptyMenuItem = memo(() => {\n const { t } = useTranslation(common);\n return (\n <ContextMenu.Item className={cx(styles.item, styles.empty)} disabled>\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 <Switch\n checked={checked}\n disabled={disabled}\n onChange={handleCheckedChange}\n onClick={(_, e) => e.stopPropagation()}\n size=\"small\"\n style={{ marginInlineStart: 16 }}\n />\n </ContextMenu.Item>\n );\n};\n\nconst renderItemContent = (\n item: MenuItemType | SubMenuType | ContextMenuCheckboxItem | ContextMenuSwitchItem,\n options?: RenderItemContentOptions,\n iconNode?: ReactNode,\n) => {\n const label = getItemLabel(item);\n const extra = 'extra' in item ? item.extra : undefined;\n const indicatorOnRight = options?.indicatorOnRight;\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 return (\n <div className={styles.itemContent}>\n {shouldRenderIcon ? (\n <span aria-hidden={!hasIcon} className={styles.icon}>\n {hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon, 'small') : null}\n </span>\n ) : null}\n <span className={styles.label}>{label}</span>\n {extra ? <span className={styles.extra}>{extra}</span> : null}\n {indicatorOnRight && iconNode ? iconNode : null}\n {options?.submenu ? (\n <span className={styles.submenuArrow}>\n <ChevronRight size={16} />\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 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(checkboxItem, { indicatorOnRight, reserveIconSpace }, indicator)}\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, { 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 MenuItemGroupType).type === 'group') {\n const group = item as MenuItemGroupType;\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 iconSpaceMode,\n indicatorOnRight: groupIndicatorOnRight,\n reserveIconSpace: groupReserveIconSpace,\n })\n : null}\n </ContextMenu.Group>\n );\n }\n\n if (\n (item as SubMenuType).type === 'submenu' ||\n ('children' in item && (item as SubMenuType).children)\n ) {\n const submenu = item as SubMenuType;\n const label = getItemLabel(submenu);\n const labelText = typeof label === 'string' ? label : undefined;\n const isDanger = 'danger' in submenu && Boolean(submenu.danger);\n\n return (\n <ContextMenu.SubmenuRoot key={itemKey}>\n <ContextMenu.SubmenuTrigger\n className={cx(styles.item, isDanger && styles.danger)}\n disabled={submenu.disabled}\n label={labelText}\n >\n {renderItemContent(submenu, {\n reserveIconSpace,\n submenu: true,\n })}\n </ContextMenu.SubmenuTrigger>\n <ContextMenu.Portal>\n <ContextMenu.Positioner\n alignOffset={-4}\n className={styles.positioner}\n onContextMenu={preventDefaultAndStopPropagation}\n sideOffset={-1}\n >\n <ContextMenu.Popup className={styles.popup}>\n {submenu.children && submenu.children.length > 0 ? (\n renderContextMenuItems(submenu.children, nextKeyPath, { iconSpaceMode })\n ) : (\n <EmptyMenuItem />\n )}\n </ContextMenu.Popup>\n </ContextMenu.Positioner>\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, { reserveIconSpace })}\n </ContextMenu.Item>\n );\n });\n};\n"],"mappings":"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"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { IconSpaceMode } from "../Menu/renderUtils.mjs";
|
|
1
2
|
import { ContextMenuItem } from "./type.mjs";
|
|
3
|
+
import "./renderItems.mjs";
|
|
2
4
|
import "@floating-ui/react";
|
|
3
5
|
|
|
4
6
|
//#region src/ContextMenu/store.d.ts
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
interface ShowContextMenuOptions {
|
|
9
|
+
iconSpaceMode?: IconSpaceMode;
|
|
10
|
+
}
|
|
11
|
+
declare const showContextMenu: (items: ContextMenuItem[], options?: ShowContextMenuOptions) => void;
|
|
7
12
|
/**
|
|
8
13
|
* Update menu items while keeping current anchor/position.
|
|
9
14
|
* Useful for interactive menu items (e.g. checkbox) to avoid re-positioning.
|
|
@@ -11,5 +16,5 @@ declare const showContextMenu: (items: ContextMenuItem[]) => void;
|
|
|
11
16
|
declare const updateContextMenuItems: (items: ContextMenuItem[]) => void;
|
|
12
17
|
declare const closeContextMenu: () => void;
|
|
13
18
|
//#endregion
|
|
14
|
-
export { closeContextMenu, showContextMenu, updateContextMenuItems };
|
|
19
|
+
export { ShowContextMenuOptions, closeContextMenu, showContextMenu, updateContextMenuItems };
|
|
15
20
|
//# sourceMappingURL=store.d.mts.map
|
package/es/ContextMenu/store.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//#region src/ContextMenu/store.ts
|
|
2
2
|
const emptyState = {
|
|
3
3
|
anchor: null,
|
|
4
|
+
iconSpaceMode: "global",
|
|
4
5
|
items: [],
|
|
5
6
|
open: false,
|
|
6
7
|
triggerId: null
|
|
@@ -50,7 +51,7 @@ const setContextMenuState = (next) => {
|
|
|
50
51
|
};
|
|
51
52
|
notify();
|
|
52
53
|
};
|
|
53
|
-
const showContextMenu = (items) => {
|
|
54
|
+
const showContextMenu = (items, options) => {
|
|
54
55
|
if (typeof window === "undefined") return;
|
|
55
56
|
const fallbackPoint = {
|
|
56
57
|
x: window.innerWidth / 2,
|
|
@@ -61,6 +62,7 @@ const showContextMenu = (items) => {
|
|
|
61
62
|
x: lastPointer.x,
|
|
62
63
|
y: lastPointer.y
|
|
63
64
|
} : fallbackPoint),
|
|
65
|
+
iconSpaceMode: options?.iconSpaceMode ?? "global",
|
|
64
66
|
items,
|
|
65
67
|
open: true,
|
|
66
68
|
triggerId: lastPointer.triggerId ?? null
|
|
@@ -77,6 +79,7 @@ const updateContextMenuItems = (items) => {
|
|
|
77
79
|
const closeContextMenu = () => {
|
|
78
80
|
setContextMenuState({
|
|
79
81
|
anchor: null,
|
|
82
|
+
iconSpaceMode: "global",
|
|
80
83
|
items: [],
|
|
81
84
|
open: false,
|
|
82
85
|
triggerId: null
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.mjs","names":["emptyState: ContextMenuState","contextMenuState: ContextMenuState"],"sources":["../../src/ContextMenu/store.ts"],"sourcesContent":["import type { VirtualElement } from '@floating-ui/react';\n\nimport type { ContextMenuItem } from './type';\n\nexport type ContextMenuState = {\n anchor: VirtualElement | null;\n items: ContextMenuItem[];\n open: boolean;\n triggerId: string | null;\n};\n\nconst emptyState: ContextMenuState = {\n anchor: null,\n items: [],\n open: false,\n triggerId: null,\n};\n\nlet contextMenuState: ContextMenuState = emptyState;\nconst listeners = new Set<() => void>();\nconst lastPointer = { ready: false, triggerId: null as string | null, x: 0, y: 0 };\n\nconst notify = () => {\n listeners.forEach((listener) => listener());\n};\n\nexport const subscribe = (listener: () => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n};\n\nexport const getSnapshot = () => contextMenuState;\nexport const getServerSnapshot = () => emptyState;\n\nexport const updateLastPointer = (event: MouseEvent | PointerEvent) => {\n lastPointer.x = event.clientX;\n lastPointer.y = event.clientY;\n lastPointer.ready = true;\n if (event.target instanceof Element) {\n const trigger = event.target.closest<HTMLElement>('[data-contextmenu-trigger]');\n lastPointer.triggerId = trigger?.dataset.contextmenuTrigger ?? null;\n } else {\n lastPointer.triggerId = null;\n }\n};\n\nconst createVirtualElement = (point: { x: number; y: number }): VirtualElement => ({\n contextElement: typeof document === 'undefined' ? undefined : document.body,\n getBoundingClientRect: () =>\n ({\n bottom: point.y,\n height: 0,\n left: point.x,\n right: point.x,\n toJSON: () => undefined,\n top: point.y,\n width: 0,\n x: point.x,\n y: point.y,\n }) as DOMRect,\n});\n\nexport const setContextMenuState = (next: Partial<ContextMenuState>) => {\n contextMenuState = { ...contextMenuState, ...next };\n notify();\n};\n\nexport const showContextMenu = (items: ContextMenuItem[]) => {\n if (typeof window === 'undefined') return;\n\n const fallbackPoint = { x: window.innerWidth / 2, y: window.innerHeight / 2 };\n const point = lastPointer.ready ? { x: lastPointer.x, y: lastPointer.y } : fallbackPoint;\n\n setContextMenuState({\n anchor: createVirtualElement(point),\n items,\n open: true,\n triggerId: lastPointer.triggerId ?? null,\n });\n};\n\n/**\n * Update menu items while keeping current anchor/position.\n * Useful for interactive menu items (e.g. checkbox) to avoid re-positioning.\n */\nexport const updateContextMenuItems = (items: ContextMenuItem[]) => {\n if (typeof window === 'undefined') return;\n setContextMenuState({ items });\n};\n\nexport const closeContextMenu = () => {\n setContextMenuState({
|
|
1
|
+
{"version":3,"file":"store.mjs","names":["emptyState: ContextMenuState","contextMenuState: ContextMenuState"],"sources":["../../src/ContextMenu/store.ts"],"sourcesContent":["import type { VirtualElement } from '@floating-ui/react';\n\nimport type { IconSpaceMode } from './renderItems';\nimport type { ContextMenuItem } from './type';\n\nexport type ContextMenuState = {\n anchor: VirtualElement | null;\n iconSpaceMode: IconSpaceMode;\n items: ContextMenuItem[];\n open: boolean;\n triggerId: string | null;\n};\n\nconst emptyState: ContextMenuState = {\n anchor: null,\n iconSpaceMode: 'global',\n items: [],\n open: false,\n triggerId: null,\n};\n\nlet contextMenuState: ContextMenuState = emptyState;\nconst listeners = new Set<() => void>();\nconst lastPointer = { ready: false, triggerId: null as string | null, x: 0, y: 0 };\n\nconst notify = () => {\n listeners.forEach((listener) => listener());\n};\n\nexport const subscribe = (listener: () => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n};\n\nexport const getSnapshot = () => contextMenuState;\nexport const getServerSnapshot = () => emptyState;\n\nexport const updateLastPointer = (event: MouseEvent | PointerEvent) => {\n lastPointer.x = event.clientX;\n lastPointer.y = event.clientY;\n lastPointer.ready = true;\n if (event.target instanceof Element) {\n const trigger = event.target.closest<HTMLElement>('[data-contextmenu-trigger]');\n lastPointer.triggerId = trigger?.dataset.contextmenuTrigger ?? null;\n } else {\n lastPointer.triggerId = null;\n }\n};\n\nconst createVirtualElement = (point: { x: number; y: number }): VirtualElement => ({\n contextElement: typeof document === 'undefined' ? undefined : document.body,\n getBoundingClientRect: () =>\n ({\n bottom: point.y,\n height: 0,\n left: point.x,\n right: point.x,\n toJSON: () => undefined,\n top: point.y,\n width: 0,\n x: point.x,\n y: point.y,\n }) as DOMRect,\n});\n\nexport const setContextMenuState = (next: Partial<ContextMenuState>) => {\n contextMenuState = { ...contextMenuState, ...next };\n notify();\n};\n\nexport interface ShowContextMenuOptions {\n iconSpaceMode?: IconSpaceMode;\n}\n\nexport const showContextMenu = (items: ContextMenuItem[], options?: ShowContextMenuOptions) => {\n if (typeof window === 'undefined') return;\n\n const fallbackPoint = { x: window.innerWidth / 2, y: window.innerHeight / 2 };\n const point = lastPointer.ready ? { x: lastPointer.x, y: lastPointer.y } : fallbackPoint;\n\n setContextMenuState({\n anchor: createVirtualElement(point),\n iconSpaceMode: options?.iconSpaceMode ?? 'global',\n items,\n open: true,\n triggerId: lastPointer.triggerId ?? null,\n });\n};\n\n/**\n * Update menu items while keeping current anchor/position.\n * Useful for interactive menu items (e.g. checkbox) to avoid re-positioning.\n */\nexport const updateContextMenuItems = (items: ContextMenuItem[]) => {\n if (typeof window === 'undefined') return;\n setContextMenuState({ items });\n};\n\nexport const closeContextMenu = () => {\n setContextMenuState({\n anchor: null,\n iconSpaceMode: 'global',\n items: [],\n open: false,\n triggerId: null,\n });\n};\n"],"mappings":";AAaA,MAAMA,aAA+B;CACnC,QAAQ;CACR,eAAe;CACf,OAAO,EAAE;CACT,MAAM;CACN,WAAW;CACZ;AAED,IAAIC,mBAAqC;AACzC,MAAM,4BAAY,IAAI,KAAiB;AACvC,MAAM,cAAc;CAAE,OAAO;CAAO,WAAW;CAAuB,GAAG;CAAG,GAAG;CAAG;AAElF,MAAM,eAAe;AACnB,WAAU,SAAS,aAAa,UAAU,CAAC;;AAG7C,MAAa,aAAa,aAAyB;AACjD,WAAU,IAAI,SAAS;AACvB,cAAa,UAAU,OAAO,SAAS;;AAGzC,MAAa,oBAAoB;AACjC,MAAa,0BAA0B;AAEvC,MAAa,qBAAqB,UAAqC;AACrE,aAAY,IAAI,MAAM;AACtB,aAAY,IAAI,MAAM;AACtB,aAAY,QAAQ;AACpB,KAAI,MAAM,kBAAkB,QAE1B,aAAY,YADI,MAAM,OAAO,QAAqB,6BAA6B,EAC9C,QAAQ,sBAAsB;KAE/D,aAAY,YAAY;;AAI5B,MAAM,wBAAwB,WAAqD;CACjF,gBAAgB,OAAO,aAAa,cAAc,SAAY,SAAS;CACvE,8BACG;EACC,QAAQ,MAAM;EACd,QAAQ;EACR,MAAM,MAAM;EACZ,OAAO,MAAM;EACb,cAAc;EACd,KAAK,MAAM;EACX,OAAO;EACP,GAAG,MAAM;EACT,GAAG,MAAM;EACV;CACJ;AAED,MAAa,uBAAuB,SAAoC;AACtE,oBAAmB;EAAE,GAAG;EAAkB,GAAG;EAAM;AACnD,SAAQ;;AAOV,MAAa,mBAAmB,OAA0B,YAAqC;AAC7F,KAAI,OAAO,WAAW,YAAa;CAEnC,MAAM,gBAAgB;EAAE,GAAG,OAAO,aAAa;EAAG,GAAG,OAAO,cAAc;EAAG;AAG7E,qBAAoB;EAClB,QAAQ,qBAHI,YAAY,QAAQ;GAAE,GAAG,YAAY;GAAG,GAAG,YAAY;GAAG,GAAG,cAGtC;EACnC,eAAe,SAAS,iBAAiB;EACzC;EACA,MAAM;EACN,WAAW,YAAY,aAAa;EACrC,CAAC;;;;;;AAOJ,MAAa,0BAA0B,UAA6B;AAClE,KAAI,OAAO,WAAW,YAAa;AACnC,qBAAoB,EAAE,OAAO,CAAC;;AAGhC,MAAa,yBAAyB;AACpC,qBAAoB;EAClB,QAAQ;EACR,eAAe;EACf,OAAO,EAAE;EACT,MAAM;EACN,WAAW;EACZ,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CopyButtonProps } from "./type.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react19 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/CopyButton/CopyButton.d.ts
|
|
5
|
-
declare const CopyButton:
|
|
5
|
+
declare const CopyButton: react19.NamedExoticComponent<CopyButtonProps>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { CopyButton };
|
|
8
8
|
//# sourceMappingURL=CopyButton.d.mts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DatePickerProps } from "./type.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react76 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/DatePicker/DatePicker.d.ts
|
|
5
|
-
declare const DatePicker:
|
|
5
|
+
declare const DatePicker: react76.NamedExoticComponent<DatePickerProps>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { DatePicker };
|
|
8
8
|
//# sourceMappingURL=DatePicker.d.mts.map
|
|
@@ -8,7 +8,7 @@ import { memo, use, useCallback, useEffect, useMemo, useReducer, useRef, useTran
|
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { ConfigProvider } from "antd";
|
|
10
10
|
import { cx } from "antd-style";
|
|
11
|
-
import
|
|
11
|
+
import useMergeState from "use-merge-value";
|
|
12
12
|
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from "lucide-react";
|
|
13
13
|
import { useHover } from "ahooks";
|
|
14
14
|
import isEqual from "fast-deep-equal";
|
|
@@ -57,7 +57,7 @@ const DraggablePanel = memo(({ headerHeight = DEFAULT_HEADER_HEIGHT, fullscreen,
|
|
|
57
57
|
"--draggable-panel-bg": backgroundColor || "",
|
|
58
58
|
"--draggable-panel-header-height": `${headerHeight}px`
|
|
59
59
|
}), [backgroundColor, headerHeight]);
|
|
60
|
-
const [isExpand, setIsExpand] =
|
|
60
|
+
const [isExpand, setIsExpand] = useMergeState(defaultExpand, {
|
|
61
61
|
onChange: onExpandChange,
|
|
62
62
|
value: expand
|
|
63
63
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DraggablePanel.mjs","names":["defaultSize: Size","Center","Icon"],"sources":["../../src/DraggablePanel/DraggablePanel.tsx"],"sourcesContent":["'use client';\n\nimport { useHover } from 'ahooks';\nimport { ConfigProvider } from 'antd';\nimport { cx } from 'antd-style';\nimport isEqual from 'fast-deep-equal';\nimport { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from 'lucide-react';\nimport type { Enable, NumberSize, Size } from 're-resizable';\nimport { Resizable } from 're-resizable';\nimport {\n memo,\n use,\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n useTransition,\n} from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { Center } from '@/Flex';\nimport Icon from '@/Icon';\n\nimport { handleVariants, panelVariants, styles, toggleVariants } from './style';\nimport type { DraggablePanelProps } from './type';\nimport { reversePlacement } from './utils';\n\n// Constants\nconst DEFAULT_HEIGHT = 180;\nconst DEFAULT_WIDTH = 280;\nconst DEFAULT_HEADER_HEIGHT = 0;\nconst DEFAULT_PIN = true;\nconst DEFAULT_MODE = 'fixed';\nconst DEFAULT_EXPANDABLE = true;\nconst DEFAULT_EXPAND = true;\nconst DEFAULT_SHOW_HANDLE_WIDE_AREA = true;\n\n// State reducer for better state management\ninterface DraggablePanelState {\n isResizing: boolean;\n showExpand: boolean;\n}\n\ntype DraggablePanelAction =\n | { type: 'START_RESIZE' }\n | { type: 'STOP_RESIZE' }\n | { payload: boolean; type: 'SET_SHOW_EXPAND' };\n\nfunction draggablePanelReducer(\n state: DraggablePanelState,\n action: DraggablePanelAction,\n): DraggablePanelState {\n switch (action.type) {\n case 'START_RESIZE': {\n return { ...state, isResizing: true, showExpand: false };\n }\n case 'STOP_RESIZE': {\n return { ...state, isResizing: false, showExpand: true };\n }\n case 'SET_SHOW_EXPAND': {\n return { ...state, showExpand: action.payload };\n }\n default: {\n return state;\n }\n }\n}\n\nconst DraggablePanel = memo<DraggablePanelProps>(\n ({\n headerHeight = DEFAULT_HEADER_HEIGHT,\n fullscreen,\n maxHeight,\n pin = DEFAULT_PIN,\n mode = DEFAULT_MODE,\n children,\n placement = 'right',\n resize,\n style,\n showBorder = true,\n showHandleHighlight = false,\n showHandleWideArea = DEFAULT_SHOW_HANDLE_WIDE_AREA,\n backgroundColor,\n size,\n defaultSize: customizeDefaultSize,\n minWidth,\n minHeight,\n maxWidth,\n onSizeChange,\n onSizeDragging,\n expandable = DEFAULT_EXPANDABLE,\n expand,\n defaultExpand = DEFAULT_EXPAND,\n onExpandChange,\n className,\n showHandleWhenCollapsed,\n destroyOnClose,\n styles: customStyles,\n classNames,\n dir,\n }) => {\n const ref = useRef<HTMLDivElement>(null);\n const isHovering = useHover(ref);\n const isVertical = placement === 'top' || placement === 'bottom';\n const [isPending, startTransition] = useTransition();\n\n // Use ref for hover timeout to avoid memory leaks\n const hoverTimeoutRef = useRef<any>(undefined);\n\n // inherit direction from Ant Design ConfigProvider\n const { direction: antdDirection } = use(ConfigProvider.ConfigContext);\n const direction = dir ?? antdDirection;\n\n // Handle RTL direction\n const internalPlacement = useMemo(() => {\n return direction === 'rtl' && ['left', 'right'].includes(placement)\n ? placement === 'left'\n ? 'right'\n : 'left'\n : placement;\n }, [direction, placement]);\n\n const cssVariables = useMemo<Record<string, string>>(\n () => ({\n '--draggable-panel-bg': backgroundColor || '',\n '--draggable-panel-header-height': `${headerHeight}px`,\n }),\n [backgroundColor, headerHeight],\n );\n\n const [isExpand, setIsExpand] = useControlledState(defaultExpand, {\n onChange: onExpandChange,\n value: expand,\n });\n\n // Initialize state with useReducer for better performance\n const initialState: DraggablePanelState = {\n isResizing: false,\n showExpand: true,\n };\n\n const [state, dispatch] = useReducer(draggablePanelReducer, initialState);\n\n // Auto-expand on hover if not pinned with optimized transition\n useEffect(() => {\n if (pin) return;\n\n // Clear previous timeout\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current);\n }\n\n if (isHovering && !isExpand) {\n startTransition(() => {\n setIsExpand(true);\n });\n } else if (!isHovering && isExpand) {\n // Add a small delay before collapsing to prevent flickering\n hoverTimeoutRef.current = setTimeout(() => {\n startTransition(() => {\n setIsExpand(false);\n });\n }, 150);\n }\n }, [pin, isHovering, isExpand, setIsExpand]);\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current);\n }\n };\n }, []);\n\n const canResizing = resize !== false && isExpand;\n\n // Configure resizing handles\n const resizing = useMemo(\n () => ({\n bottom: false,\n bottomLeft: false,\n bottomRight: false,\n left: false,\n right: false,\n top: false,\n topLeft: false,\n topRight: false,\n [reversePlacement(internalPlacement)]: true,\n ...(resize as Enable),\n }),\n [internalPlacement, resize],\n );\n\n // Calculate default size based on orientation\n const defaultSize: Size = useMemo(() => {\n if (isVertical)\n return {\n height: DEFAULT_HEIGHT,\n width: '100%',\n ...customizeDefaultSize,\n };\n\n return {\n height: '100%',\n width: DEFAULT_WIDTH,\n ...customizeDefaultSize,\n };\n }, [isVertical, customizeDefaultSize]);\n\n // Determine appropriate size props based on expand state\n const sizeProps = useMemo(() => {\n if (!isExpand) {\n return isVertical\n ? { minHeight: 0, size: { height: 0 } }\n : { minWidth: 0, size: { width: 0 } };\n }\n\n return {\n defaultSize,\n maxHeight: typeof maxHeight === 'number' ? Math.max(maxHeight, 0) : maxHeight,\n maxWidth: typeof maxWidth === 'number' ? Math.max(maxWidth, 0) : maxWidth,\n minHeight: typeof minHeight === 'number' ? Math.max(minHeight, 0) : minHeight,\n minWidth: typeof minWidth === 'number' ? Math.max(minWidth, 0) : minWidth,\n size: size as Size,\n };\n }, [isExpand, isVertical, defaultSize, maxHeight, maxWidth, minHeight, minWidth, size]);\n\n // Determine the appropriate arrow icon based on placement\n const Arrow = useMemo(() => {\n switch (internalPlacement) {\n case 'top': {\n return ChevronDown;\n }\n case 'bottom': {\n return ChevronUp;\n }\n case 'right': {\n return ChevronLeft;\n }\n case 'left': {\n return ChevronRight;\n }\n default: {\n return ChevronLeft;\n }\n }\n }, [internalPlacement]);\n\n // Toggle expand state with transition for better performance\n const toggleExpand = useCallback(() => {\n if (!expandable) return;\n\n startTransition(() => {\n setIsExpand(!isExpand);\n });\n }, [expandable, isExpand, setIsExpand]);\n\n // Toggle handle component\n const handle = useMemo(\n () => (\n <Center\n className={toggleVariants({ placement: internalPlacement, showHandleWideArea })}\n style={{ opacity: isExpand ? (pin ? undefined : 0) : showHandleWhenCollapsed ? 1 : 0 }}\n >\n <Center\n className={classNames?.handle}\n onClick={toggleExpand}\n style={customStyles?.handle}\n >\n <Icon\n className={styles.handlerIcon}\n icon={Arrow}\n size={16}\n style={{\n marginBottom: internalPlacement === 'top' ? 4 : 0,\n marginLeft: internalPlacement === 'right' ? 4 : 0,\n marginRight: internalPlacement === 'left' ? 4 : 0,\n marginTop: internalPlacement === 'bottom' ? 4 : 0,\n transform: `rotate(${isExpand ? 180 : 0}deg)`,\n transition: 'transform 0.3s ease',\n }}\n />\n </Center>\n </Center>\n ),\n [\n toggleVariants,\n internalPlacement,\n isExpand,\n pin,\n showHandleWhenCollapsed,\n classNames?.handle,\n toggleExpand,\n customStyles?.handle,\n styles.handlerIcon,\n Arrow,\n ],\n );\n\n // Handle resize events with memoization\n const handleResize = useCallback(\n (_: unknown, _direction: unknown, reference_: HTMLElement, delta: NumberSize) => {\n onSizeDragging?.(delta, {\n height: reference_.style.height,\n width: reference_.style.width,\n });\n },\n [onSizeDragging],\n );\n\n const handleResizeStart = useCallback(() => {\n dispatch({ type: 'START_RESIZE' });\n }, []);\n\n const handleResizeStop = useCallback(\n (e: unknown, direction: unknown, reference_: HTMLElement, delta: NumberSize) => {\n dispatch({ type: 'STOP_RESIZE' });\n onSizeChange?.(delta, {\n height: reference_.style.height,\n width: reference_.style.width,\n });\n },\n [onSizeChange],\n );\n\n // Main panel content\n const inner = useMemo(\n () => (\n <Resizable\n {...sizeProps}\n className={cx(styles.panel, classNames?.content)}\n enable={canResizing ? (resizing as Enable) : undefined}\n handleClasses={\n canResizing\n ? {\n [reversePlacement(internalPlacement)]: cx(\n handleVariants({\n placement: reversePlacement(internalPlacement),\n }),\n showHandleHighlight && styles.handleHighlight,\n ),\n }\n : {}\n }\n onResize={handleResize}\n onResizeStart={handleResizeStart}\n onResizeStop={handleResizeStop}\n style={{\n ...cssVariables,\n opacity: isPending ? 0.95 : 1,\n transition: state.isResizing ? 'unset' : undefined,\n ...style,\n }}\n >\n {children}\n </Resizable>\n ),\n [\n sizeProps,\n styles.panel,\n classNames?.content,\n canResizing,\n resizing,\n internalPlacement,\n handleVariants,\n showHandleHighlight,\n styles.handleHighlight,\n handleResize,\n handleResizeStart,\n handleResizeStop,\n state.isResizing,\n isPending,\n style,\n children,\n cx,\n ],\n );\n\n // For fullscreen mode, return a simpler layout\n if (fullscreen) {\n return (\n <div className={cx(styles.fullscreen, className)} style={cssVariables}>\n {children}\n </div>\n );\n }\n\n return (\n <aside\n className={cx(\n panelVariants({\n isExpand,\n mode,\n placement: internalPlacement,\n showBorder,\n }),\n className,\n )}\n dir={dir}\n ref={ref}\n style={cssVariables}\n >\n {expandable && state.showExpand && handle}\n {destroyOnClose ? isExpand && inner : inner}\n </aside>\n );\n },\n isEqual,\n);\n\nDraggablePanel.displayName = 'DraggablePanel';\n\nexport default DraggablePanel;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DraggablePanel.mjs","names":["useControlledState","defaultSize: Size","Center","Icon"],"sources":["../../src/DraggablePanel/DraggablePanel.tsx"],"sourcesContent":["'use client';\n\nimport { useHover } from 'ahooks';\nimport { ConfigProvider } from 'antd';\nimport { cx } from 'antd-style';\nimport isEqual from 'fast-deep-equal';\nimport { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from 'lucide-react';\nimport type { Enable, NumberSize, Size } from 're-resizable';\nimport { Resizable } from 're-resizable';\nimport {\n memo,\n use,\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n useTransition,\n} from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { Center } from '@/Flex';\nimport Icon from '@/Icon';\n\nimport { handleVariants, panelVariants, styles, toggleVariants } from './style';\nimport type { DraggablePanelProps } from './type';\nimport { reversePlacement } from './utils';\n\n// Constants\nconst DEFAULT_HEIGHT = 180;\nconst DEFAULT_WIDTH = 280;\nconst DEFAULT_HEADER_HEIGHT = 0;\nconst DEFAULT_PIN = true;\nconst DEFAULT_MODE = 'fixed';\nconst DEFAULT_EXPANDABLE = true;\nconst DEFAULT_EXPAND = true;\nconst DEFAULT_SHOW_HANDLE_WIDE_AREA = true;\n\n// State reducer for better state management\ninterface DraggablePanelState {\n isResizing: boolean;\n showExpand: boolean;\n}\n\ntype DraggablePanelAction =\n | { type: 'START_RESIZE' }\n | { type: 'STOP_RESIZE' }\n | { payload: boolean; type: 'SET_SHOW_EXPAND' };\n\nfunction draggablePanelReducer(\n state: DraggablePanelState,\n action: DraggablePanelAction,\n): DraggablePanelState {\n switch (action.type) {\n case 'START_RESIZE': {\n return { ...state, isResizing: true, showExpand: false };\n }\n case 'STOP_RESIZE': {\n return { ...state, isResizing: false, showExpand: true };\n }\n case 'SET_SHOW_EXPAND': {\n return { ...state, showExpand: action.payload };\n }\n default: {\n return state;\n }\n }\n}\n\nconst DraggablePanel = memo<DraggablePanelProps>(\n ({\n headerHeight = DEFAULT_HEADER_HEIGHT,\n fullscreen,\n maxHeight,\n pin = DEFAULT_PIN,\n mode = DEFAULT_MODE,\n children,\n placement = 'right',\n resize,\n style,\n showBorder = true,\n showHandleHighlight = false,\n showHandleWideArea = DEFAULT_SHOW_HANDLE_WIDE_AREA,\n backgroundColor,\n size,\n defaultSize: customizeDefaultSize,\n minWidth,\n minHeight,\n maxWidth,\n onSizeChange,\n onSizeDragging,\n expandable = DEFAULT_EXPANDABLE,\n expand,\n defaultExpand = DEFAULT_EXPAND,\n onExpandChange,\n className,\n showHandleWhenCollapsed,\n destroyOnClose,\n styles: customStyles,\n classNames,\n dir,\n }) => {\n const ref = useRef<HTMLDivElement>(null);\n const isHovering = useHover(ref);\n const isVertical = placement === 'top' || placement === 'bottom';\n const [isPending, startTransition] = useTransition();\n\n // Use ref for hover timeout to avoid memory leaks\n const hoverTimeoutRef = useRef<any>(undefined);\n\n // inherit direction from Ant Design ConfigProvider\n const { direction: antdDirection } = use(ConfigProvider.ConfigContext);\n const direction = dir ?? antdDirection;\n\n // Handle RTL direction\n const internalPlacement = useMemo(() => {\n return direction === 'rtl' && ['left', 'right'].includes(placement)\n ? placement === 'left'\n ? 'right'\n : 'left'\n : placement;\n }, [direction, placement]);\n\n const cssVariables = useMemo<Record<string, string>>(\n () => ({\n '--draggable-panel-bg': backgroundColor || '',\n '--draggable-panel-header-height': `${headerHeight}px`,\n }),\n [backgroundColor, headerHeight],\n );\n\n const [isExpand, setIsExpand] = useControlledState(defaultExpand, {\n onChange: onExpandChange,\n value: expand,\n });\n\n // Initialize state with useReducer for better performance\n const initialState: DraggablePanelState = {\n isResizing: false,\n showExpand: true,\n };\n\n const [state, dispatch] = useReducer(draggablePanelReducer, initialState);\n\n // Auto-expand on hover if not pinned with optimized transition\n useEffect(() => {\n if (pin) return;\n\n // Clear previous timeout\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current);\n }\n\n if (isHovering && !isExpand) {\n startTransition(() => {\n setIsExpand(true);\n });\n } else if (!isHovering && isExpand) {\n // Add a small delay before collapsing to prevent flickering\n hoverTimeoutRef.current = setTimeout(() => {\n startTransition(() => {\n setIsExpand(false);\n });\n }, 150);\n }\n }, [pin, isHovering, isExpand, setIsExpand]);\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (hoverTimeoutRef.current) {\n clearTimeout(hoverTimeoutRef.current);\n }\n };\n }, []);\n\n const canResizing = resize !== false && isExpand;\n\n // Configure resizing handles\n const resizing = useMemo(\n () => ({\n bottom: false,\n bottomLeft: false,\n bottomRight: false,\n left: false,\n right: false,\n top: false,\n topLeft: false,\n topRight: false,\n [reversePlacement(internalPlacement)]: true,\n ...(resize as Enable),\n }),\n [internalPlacement, resize],\n );\n\n // Calculate default size based on orientation\n const defaultSize: Size = useMemo(() => {\n if (isVertical)\n return {\n height: DEFAULT_HEIGHT,\n width: '100%',\n ...customizeDefaultSize,\n };\n\n return {\n height: '100%',\n width: DEFAULT_WIDTH,\n ...customizeDefaultSize,\n };\n }, [isVertical, customizeDefaultSize]);\n\n // Determine appropriate size props based on expand state\n const sizeProps = useMemo(() => {\n if (!isExpand) {\n return isVertical\n ? { minHeight: 0, size: { height: 0 } }\n : { minWidth: 0, size: { width: 0 } };\n }\n\n return {\n defaultSize,\n maxHeight: typeof maxHeight === 'number' ? Math.max(maxHeight, 0) : maxHeight,\n maxWidth: typeof maxWidth === 'number' ? Math.max(maxWidth, 0) : maxWidth,\n minHeight: typeof minHeight === 'number' ? Math.max(minHeight, 0) : minHeight,\n minWidth: typeof minWidth === 'number' ? Math.max(minWidth, 0) : minWidth,\n size: size as Size,\n };\n }, [isExpand, isVertical, defaultSize, maxHeight, maxWidth, minHeight, minWidth, size]);\n\n // Determine the appropriate arrow icon based on placement\n const Arrow = useMemo(() => {\n switch (internalPlacement) {\n case 'top': {\n return ChevronDown;\n }\n case 'bottom': {\n return ChevronUp;\n }\n case 'right': {\n return ChevronLeft;\n }\n case 'left': {\n return ChevronRight;\n }\n default: {\n return ChevronLeft;\n }\n }\n }, [internalPlacement]);\n\n // Toggle expand state with transition for better performance\n const toggleExpand = useCallback(() => {\n if (!expandable) return;\n\n startTransition(() => {\n setIsExpand(!isExpand);\n });\n }, [expandable, isExpand, setIsExpand]);\n\n // Toggle handle component\n const handle = useMemo(\n () => (\n <Center\n className={toggleVariants({ placement: internalPlacement, showHandleWideArea })}\n style={{ opacity: isExpand ? (pin ? undefined : 0) : showHandleWhenCollapsed ? 1 : 0 }}\n >\n <Center\n className={classNames?.handle}\n onClick={toggleExpand}\n style={customStyles?.handle}\n >\n <Icon\n className={styles.handlerIcon}\n icon={Arrow}\n size={16}\n style={{\n marginBottom: internalPlacement === 'top' ? 4 : 0,\n marginLeft: internalPlacement === 'right' ? 4 : 0,\n marginRight: internalPlacement === 'left' ? 4 : 0,\n marginTop: internalPlacement === 'bottom' ? 4 : 0,\n transform: `rotate(${isExpand ? 180 : 0}deg)`,\n transition: 'transform 0.3s ease',\n }}\n />\n </Center>\n </Center>\n ),\n [\n toggleVariants,\n internalPlacement,\n isExpand,\n pin,\n showHandleWhenCollapsed,\n classNames?.handle,\n toggleExpand,\n customStyles?.handle,\n styles.handlerIcon,\n Arrow,\n ],\n );\n\n // Handle resize events with memoization\n const handleResize = useCallback(\n (_: unknown, _direction: unknown, reference_: HTMLElement, delta: NumberSize) => {\n onSizeDragging?.(delta, {\n height: reference_.style.height,\n width: reference_.style.width,\n });\n },\n [onSizeDragging],\n );\n\n const handleResizeStart = useCallback(() => {\n dispatch({ type: 'START_RESIZE' });\n }, []);\n\n const handleResizeStop = useCallback(\n (e: unknown, direction: unknown, reference_: HTMLElement, delta: NumberSize) => {\n dispatch({ type: 'STOP_RESIZE' });\n onSizeChange?.(delta, {\n height: reference_.style.height,\n width: reference_.style.width,\n });\n },\n [onSizeChange],\n );\n\n // Main panel content\n const inner = useMemo(\n () => (\n <Resizable\n {...sizeProps}\n className={cx(styles.panel, classNames?.content)}\n enable={canResizing ? (resizing as Enable) : undefined}\n handleClasses={\n canResizing\n ? {\n [reversePlacement(internalPlacement)]: cx(\n handleVariants({\n placement: reversePlacement(internalPlacement),\n }),\n showHandleHighlight && styles.handleHighlight,\n ),\n }\n : {}\n }\n onResize={handleResize}\n onResizeStart={handleResizeStart}\n onResizeStop={handleResizeStop}\n style={{\n ...cssVariables,\n opacity: isPending ? 0.95 : 1,\n transition: state.isResizing ? 'unset' : undefined,\n ...style,\n }}\n >\n {children}\n </Resizable>\n ),\n [\n sizeProps,\n styles.panel,\n classNames?.content,\n canResizing,\n resizing,\n internalPlacement,\n handleVariants,\n showHandleHighlight,\n styles.handleHighlight,\n handleResize,\n handleResizeStart,\n handleResizeStop,\n state.isResizing,\n isPending,\n style,\n children,\n cx,\n ],\n );\n\n // For fullscreen mode, return a simpler layout\n if (fullscreen) {\n return (\n <div className={cx(styles.fullscreen, className)} style={cssVariables}>\n {children}\n </div>\n );\n }\n\n return (\n <aside\n className={cx(\n panelVariants({\n isExpand,\n mode,\n placement: internalPlacement,\n showBorder,\n }),\n className,\n )}\n dir={dir}\n ref={ref}\n style={cssVariables}\n >\n {expandable && state.showExpand && handle}\n {destroyOnClose ? isExpand && inner : inner}\n </aside>\n );\n },\n isEqual,\n);\n\nDraggablePanel.displayName = 'DraggablePanel';\n\nexport default DraggablePanel;\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DivProps } from "../../types/index.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react81 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/DraggablePanel/components/DraggablePanelBody.d.ts
|
|
5
5
|
type DraggablePanelBodyProps = DivProps;
|
|
6
|
-
declare const DraggablePanelBody:
|
|
6
|
+
declare const DraggablePanelBody: react81.NamedExoticComponent<DivProps>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { DraggablePanelBody, DraggablePanelBodyProps };
|
|
9
9
|
//# sourceMappingURL=DraggablePanelBody.d.mts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DivProps } from "../../types/index.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react82 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/DraggablePanel/components/DraggablePanelContainer.d.ts
|
|
5
5
|
type DraggablePanelContainerProps = DivProps;
|
|
6
|
-
declare const DraggablePanelContainer:
|
|
6
|
+
declare const DraggablePanelContainer: react82.NamedExoticComponent<DivProps>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { DraggablePanelContainer, DraggablePanelContainerProps };
|
|
9
9
|
//# sourceMappingURL=DraggablePanelContainer.d.mts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DivProps } from "../../types/index.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react83 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/DraggablePanel/components/DraggablePanelFooter.d.ts
|
|
5
5
|
type DraggablePanelFooterProps = DivProps;
|
|
6
|
-
declare const DraggablePanelFooter:
|
|
6
|
+
declare const DraggablePanelFooter: react83.NamedExoticComponent<DivProps>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { DraggablePanelFooter, DraggablePanelFooterProps };
|
|
9
9
|
//# sourceMappingURL=DraggablePanelFooter.d.mts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DivProps } from "../../types/index.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react84 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/DraggablePanel/components/DraggablePanelHeader.d.ts
|
|
5
5
|
interface DraggablePanelHeaderProps extends Omit<DivProps, 'children'> {
|
|
@@ -9,7 +9,7 @@ interface DraggablePanelHeaderProps extends Omit<DivProps, 'children'> {
|
|
|
9
9
|
setPin?: (pin: boolean) => void;
|
|
10
10
|
title?: string;
|
|
11
11
|
}
|
|
12
|
-
declare const DraggablePanelHeader:
|
|
12
|
+
declare const DraggablePanelHeader: react84.NamedExoticComponent<DraggablePanelHeaderProps>;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { DraggablePanelHeader, DraggablePanelHeaderProps };
|
|
15
15
|
//# sourceMappingURL=DraggablePanelHeader.d.mts.map
|
|
@@ -6,13 +6,13 @@ import { styles } from "./style.mjs";
|
|
|
6
6
|
import { memo } from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { cx } from "antd-style";
|
|
9
|
-
import
|
|
9
|
+
import useMergeState from "use-merge-value";
|
|
10
10
|
import { PanelLeft, Pin, PinOff } from "lucide-react";
|
|
11
11
|
|
|
12
12
|
//#region src/DraggablePanel/components/DraggablePanelHeader.tsx
|
|
13
13
|
const DraggablePanelHeader = memo((props) => {
|
|
14
14
|
const { pin, setPin, className, setExpand, title, position = "left", ...rest } = props;
|
|
15
|
-
const [isPinned, setIsPinned] =
|
|
15
|
+
const [isPinned, setIsPinned] = useMergeState(false, {
|
|
16
16
|
onChange: setPin,
|
|
17
17
|
value: pin
|
|
18
18
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DraggablePanelHeader.mjs","names":["ActionIcon","Flexbox"],"sources":["../../../src/DraggablePanel/components/DraggablePanelHeader.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { PanelLeft, Pin, PinOff } from 'lucide-react';\nimport { memo } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport ActionIcon from '@/ActionIcon';\nimport { Flexbox } from '@/Flex';\nimport { type DivProps } from '@/types';\n\nimport { styles } from './style';\n\nexport interface DraggablePanelHeaderProps extends Omit<DivProps, 'children'> {\n pin?: boolean;\n position?: 'left' | 'right';\n setExpand?: (expand: boolean) => void;\n setPin?: (pin: boolean) => void;\n title?: string;\n}\n\nconst DraggablePanelHeader = memo<DraggablePanelHeaderProps>((props) => {\n const { pin, setPin, className, setExpand, title, position = 'left', ...rest } = props;\n\n const [isPinned, setIsPinned] = useControlledState(false, {\n onChange: setPin,\n value: pin,\n });\n\n const panelIcon = (\n <ActionIcon icon={PanelLeft} onClick={() => setExpand?.(false)} size={'small'} />\n );\n const pinIcon = (\n <ActionIcon\n active={pin}\n icon={pin ? Pin : PinOff}\n onClick={() => setIsPinned(!isPinned)}\n size={'small'}\n />\n );\n return (\n <Flexbox\n align={'center'}\n className={cx(styles.header, className)}\n flex={'none'}\n gap={8}\n horizontal\n justify={'space-between'}\n {...rest}\n >\n {position === 'left' ? panelIcon : pinIcon}\n {title}\n {position === 'left' ? pinIcon : panelIcon}\n </Flexbox>\n );\n});\n\nDraggablePanelHeader.displayName = 'DraggablePanelHeader';\n\nexport default DraggablePanelHeader;\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,uBAAuB,MAAiC,UAAU;CACtE,MAAM,EAAE,KAAK,QAAQ,WAAW,WAAW,OAAO,WAAW,QAAQ,GAAG,SAAS;CAEjF,MAAM,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"DraggablePanelHeader.mjs","names":["useControlledState","ActionIcon","Flexbox"],"sources":["../../../src/DraggablePanel/components/DraggablePanelHeader.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { PanelLeft, Pin, PinOff } from 'lucide-react';\nimport { memo } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport ActionIcon from '@/ActionIcon';\nimport { Flexbox } from '@/Flex';\nimport { type DivProps } from '@/types';\n\nimport { styles } from './style';\n\nexport interface DraggablePanelHeaderProps extends Omit<DivProps, 'children'> {\n pin?: boolean;\n position?: 'left' | 'right';\n setExpand?: (expand: boolean) => void;\n setPin?: (pin: boolean) => void;\n title?: string;\n}\n\nconst DraggablePanelHeader = memo<DraggablePanelHeaderProps>((props) => {\n const { pin, setPin, className, setExpand, title, position = 'left', ...rest } = props;\n\n const [isPinned, setIsPinned] = useControlledState(false, {\n onChange: setPin,\n value: pin,\n });\n\n const panelIcon = (\n <ActionIcon icon={PanelLeft} onClick={() => setExpand?.(false)} size={'small'} />\n );\n const pinIcon = (\n <ActionIcon\n active={pin}\n icon={pin ? Pin : PinOff}\n onClick={() => setIsPinned(!isPinned)}\n size={'small'}\n />\n );\n return (\n <Flexbox\n align={'center'}\n className={cx(styles.header, className)}\n flex={'none'}\n gap={8}\n horizontal\n justify={'space-between'}\n {...rest}\n >\n {position === 'left' ? panelIcon : pinIcon}\n {title}\n {position === 'left' ? pinIcon : panelIcon}\n </Flexbox>\n );\n});\n\nDraggablePanelHeader.displayName = 'DraggablePanelHeader';\n\nexport default DraggablePanelHeader;\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAM,uBAAuB,MAAiC,UAAU;CACtE,MAAM,EAAE,KAAK,QAAQ,WAAW,WAAW,OAAO,WAAW,QAAQ,GAAG,SAAS;CAEjF,MAAM,CAAC,UAAU,eAAeA,cAAmB,OAAO;EACxD,UAAU;EACV,OAAO;EACR,CAAC;CAEF,MAAM,YACJ,oBAACC;EAAW,MAAM;EAAW,eAAe,YAAY,MAAM;EAAE,MAAM;GAAW;CAEnF,MAAM,UACJ,oBAACA;EACC,QAAQ;EACR,MAAM,MAAM,MAAM;EAClB,eAAe,YAAY,CAAC,SAAS;EACrC,MAAM;GACN;AAEJ,QACE,qBAACC;EACC,OAAO;EACP,WAAW,GAAG,OAAO,QAAQ,UAAU;EACvC,MAAM;EACN,KAAK;EACL;EACA,SAAS;EACT,GAAI;;GAEH,aAAa,SAAS,YAAY;GAClC;GACA,aAAa,SAAS,UAAU;;GACzB;EAEZ;AAEF,qBAAqB,cAAc;AAEnC,mCAAe"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DraggableSideNavProps } from "./type.mjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react77 from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/DraggableSideNav/DraggableSideNav.d.ts
|
|
5
|
-
declare const DraggableSideNav:
|
|
5
|
+
declare const DraggableSideNav: react77.NamedExoticComponent<DraggableSideNavProps>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { DraggableSideNav };
|
|
8
8
|
//# sourceMappingURL=DraggableSideNav.d.mts.map
|
|
@@ -7,7 +7,7 @@ import { styles } from "./style.mjs";
|
|
|
7
7
|
import { memo, useCallback, useEffect, useMemo, useReducer, useRef } from "react";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { cx } from "antd-style";
|
|
10
|
-
import
|
|
10
|
+
import useMergeState from "use-merge-value";
|
|
11
11
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
12
12
|
import { useHover } from "ahooks";
|
|
13
13
|
import { Resizable } from "re-resizable";
|
|
@@ -74,7 +74,7 @@ const DraggableSideNav = memo(({ body, className, classNames, defaultExpand = DE
|
|
|
74
74
|
const cssVariables = useMemo(() => ({ "--draggable-side-nav-bg": backgroundColor || "" }), [backgroundColor]);
|
|
75
75
|
const ref = useRef(null);
|
|
76
76
|
const isHovering = useHover(ref);
|
|
77
|
-
const [isExpand, setIsExpand] =
|
|
77
|
+
const [isExpand, setIsExpand] = useMergeState(defaultExpand, {
|
|
78
78
|
onChange: onExpandChange,
|
|
79
79
|
value: expand
|
|
80
80
|
});
|