@lobehub/ui 5.24.0 → 5.26.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/A/index.mjs +2 -1
- package/es/A/index.mjs.map +1 -1
- package/es/Accordion/AccordionItem.mjs +0 -1
- package/es/Accordion/AccordionItem.mjs.map +1 -1
- package/es/ActionIcon/components/utils.mjs +7 -9
- package/es/ActionIcon/components/utils.mjs.map +1 -1
- package/es/Checkbox/CheckboxGroup.mjs +4 -2
- package/es/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/CodeDiff/CodeDiff.mjs +20 -18
- package/es/CodeDiff/CodeDiff.mjs.map +1 -1
- package/es/CodeDiff/PatchDiff.mjs +18 -16
- package/es/CodeDiff/PatchDiff.mjs.map +1 -1
- package/es/CopyButton/CopyButton.mjs +2 -1
- package/es/CopyButton/CopyButton.mjs.map +1 -1
- package/es/Highlighter/LangSelect.mjs +41 -40
- package/es/Highlighter/LangSelect.mjs.map +1 -1
- package/es/Highlighter/SyntaxHighlighter/StaticRenderer.mjs +2 -1
- package/es/Highlighter/SyntaxHighlighter/StaticRenderer.mjs.map +1 -1
- package/es/HotkeyInput/HotkeyInput.mjs +3 -1
- package/es/HotkeyInput/HotkeyInput.mjs.map +1 -1
- package/es/HtmlPreview/const.mjs +1 -1
- package/es/HtmlPreview/const.mjs.map +1 -1
- package/es/Icon/components/utils.mjs +7 -9
- package/es/Icon/components/utils.mjs.map +1 -1
- package/es/Image/Image.mjs +138 -37
- package/es/Image/Image.mjs.map +1 -1
- package/es/Image/PreviewGroup.d.mts +1 -0
- package/es/Image/PreviewGroup.mjs +33 -10
- package/es/Image/PreviewGroup.mjs.map +1 -1
- package/es/Image/index.d.mts +2 -2
- package/es/Image/index.mjs +1 -1
- package/es/Image/style.mjs +126 -71
- package/es/Image/style.mjs.map +1 -1
- package/es/Image/type.d.mts +14 -17
- package/es/Image/viewer/GalleryNav.mjs +44 -0
- package/es/Image/viewer/GalleryNav.mjs.map +1 -0
- package/es/Image/viewer/ImageViewer.mjs +275 -0
- package/es/Image/viewer/ImageViewer.mjs.map +1 -0
- package/es/Image/viewer/PreviewOutlet.mjs +19 -0
- package/es/Image/viewer/PreviewOutlet.mjs.map +1 -0
- package/es/Image/viewer/Toolbar.mjs +184 -0
- package/es/Image/viewer/Toolbar.mjs.map +1 -0
- package/es/Image/viewer/ViewerChrome.mjs +54 -0
- package/es/Image/viewer/ViewerChrome.mjs.map +1 -0
- package/es/Image/viewer/geometry.mjs +85 -0
- package/es/Image/viewer/geometry.mjs.map +1 -0
- package/es/Image/viewer/registry.d.mts +2 -0
- package/es/Image/viewer/registry.mjs +52 -0
- package/es/Image/viewer/registry.mjs.map +1 -0
- package/es/Image/viewer/useChromeIdle.mjs +72 -0
- package/es/Image/viewer/useChromeIdle.mjs.map +1 -0
- package/es/Image/viewer/useFinalFocus.mjs +10 -0
- package/es/Image/viewer/useFinalFocus.mjs.map +1 -0
- package/es/Image/viewer/useFlipTransition.mjs +321 -0
- package/es/Image/viewer/useFlipTransition.mjs.map +1 -0
- package/es/Image/viewer/useGalleryNav.mjs +89 -0
- package/es/Image/viewer/useGalleryNav.mjs.map +1 -0
- package/es/Image/viewer/useRefitTransition.mjs +47 -0
- package/es/Image/viewer/useRefitTransition.mjs.map +1 -0
- package/es/Image/viewer/useViewerGestures.mjs +148 -0
- package/es/Image/viewer/useViewerGestures.mjs.map +1 -0
- package/es/Image/viewer/useZoomPan.mjs +346 -0
- package/es/Image/viewer/useZoomPan.mjs.map +1 -0
- package/es/Img/index.mjs +2 -1
- package/es/Img/index.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/StreamdownRender.mjs +2 -1
- package/es/Markdown/SyntaxMarkdown/StreamdownRender.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/useSmoothStreamContent.mjs +2 -2
- package/es/Markdown/SyntaxMarkdown/useSmoothStreamContent.mjs.map +1 -1
- package/es/Modal/RawModalStackItem.mjs +6 -5
- package/es/Modal/RawModalStackItem.mjs.map +1 -1
- package/es/Modal/imperative.mjs +4 -2
- package/es/Modal/imperative.mjs.map +1 -1
- package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs +1 -1
- package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs.map +1 -1
- package/es/ScrollShadow/ScrollShadow.mjs +13 -12
- package/es/ScrollShadow/ScrollShadow.mjs.map +1 -1
- package/es/Skeleton/SkeletonButton.mjs +2 -1
- package/es/Skeleton/SkeletonButton.mjs.map +1 -1
- package/es/SortableList/SortableList.mjs +5 -1
- package/es/SortableList/SortableList.mjs.map +1 -1
- package/es/Text/Text.mjs +22 -21
- package/es/Text/Text.mjs.map +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs +3 -2
- package/es/ThemeProvider/ThemeProvider.mjs.map +1 -1
- package/es/awesome/GradientButton/GradientButton.mjs +1 -3
- package/es/awesome/GradientButton/GradientButton.mjs.map +1 -1
- package/es/awesome/Spotlight/Spotlight.mjs +2 -1
- package/es/awesome/Spotlight/Spotlight.mjs.map +1 -1
- package/es/base-ui/Button/Button.mjs +13 -11
- package/es/base-ui/Button/Button.mjs.map +1 -1
- package/es/base-ui/Button/SplitButton.mjs +2 -1
- package/es/base-ui/Button/SplitButton.mjs.map +1 -1
- package/es/base-ui/ContextMenu/ContextMenuTrigger.mjs +2 -1
- package/es/base-ui/ContextMenu/ContextMenuTrigger.mjs.map +1 -1
- package/es/base-ui/ContextMenu/renderItems.mjs +2 -1
- package/es/base-ui/ContextMenu/renderItems.mjs.map +1 -1
- package/es/base-ui/Drawer/Drawer.d.mts +6 -0
- package/es/base-ui/Drawer/Drawer.mjs +152 -0
- package/es/base-ui/Drawer/Drawer.mjs.map +1 -0
- package/es/base-ui/Drawer/DrawerLayerContext.mjs +10 -0
- package/es/base-ui/Drawer/DrawerLayerContext.mjs.map +1 -0
- package/es/base-ui/Drawer/DrawerPushContext.mjs +27 -0
- package/es/base-ui/Drawer/DrawerPushContext.mjs.map +1 -0
- package/es/base-ui/Drawer/atoms.d.mts +58 -0
- package/es/base-ui/Drawer/atoms.mjs +262 -0
- package/es/base-ui/Drawer/atoms.mjs.map +1 -0
- package/es/base-ui/Drawer/constants.d.mts +17 -0
- package/es/base-ui/Drawer/constants.mjs +72 -0
- package/es/base-ui/Drawer/constants.mjs.map +1 -0
- package/es/base-ui/Drawer/index.d.mts +5 -0
- package/es/base-ui/Drawer/style.mjs +295 -0
- package/es/base-ui/Drawer/style.mjs.map +1 -0
- package/es/base-ui/Drawer/type.d.mts +65 -0
- package/es/base-ui/DropdownMenu/DropdownMenu.mjs +2 -1
- package/es/base-ui/DropdownMenu/DropdownMenu.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/atoms.mjs +2 -1
- package/es/base-ui/DropdownMenu/atoms.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/renderItems.mjs +2 -1
- package/es/base-ui/DropdownMenu/renderItems.mjs.map +1 -1
- package/es/base-ui/FloatingSheet/FloatingSheet.mjs +4 -1
- package/es/base-ui/FloatingSheet/FloatingSheet.mjs.map +1 -1
- package/es/base-ui/Input/style.d.mts +1 -1
- package/es/base-ui/Modal/atoms.mjs +7 -5
- package/es/base-ui/Modal/atoms.mjs.map +1 -1
- package/es/base-ui/Modal/imperative.mjs +2 -1
- package/es/base-ui/Modal/imperative.mjs.map +1 -1
- package/es/base-ui/Popover/atoms.mjs +2 -1
- package/es/base-ui/Popover/atoms.mjs.map +1 -1
- package/es/base-ui/Popover/context.mjs +4 -2
- package/es/base-ui/Popover/context.mjs.map +1 -1
- package/es/base-ui/Select/atoms.mjs +2 -1
- package/es/base-ui/Select/atoms.mjs.map +1 -1
- package/es/base-ui/Toast/hostGuard.mjs +26 -0
- package/es/base-ui/Toast/hostGuard.mjs.map +1 -0
- package/es/base-ui/Toast/imperative.mjs +43 -20
- package/es/base-ui/Toast/imperative.mjs.map +1 -1
- package/es/base-ui/Toast/pendingQueue.mjs +30 -0
- package/es/base-ui/Toast/pendingQueue.mjs.map +1 -0
- package/es/base-ui/index.d.mts +6 -1
- package/es/base-ui/index.mjs +5 -2
- package/es/brand/LobeChat/index.mjs +0 -1
- package/es/brand/LobeChat/index.mjs.map +1 -1
- package/es/brand/LobeHub/index.mjs +0 -1
- package/es/brand/LobeHub/index.mjs.map +1 -1
- package/es/brand/Logo3d/index.mjs +2 -1
- package/es/brand/Logo3d/index.mjs.map +1 -1
- package/es/chat/ChatItem/components/Actions.mjs +5 -4
- package/es/chat/ChatItem/components/Actions.mjs.map +1 -1
- package/es/chat/ChatList/ChatList.mjs +2 -1
- package/es/chat/ChatList/ChatList.mjs.map +1 -1
- package/es/color/ColorScales/ScaleRow.mjs +0 -2
- package/es/color/ColorScales/ScaleRow.mjs.map +1 -1
- package/es/hooks/useMermaid.mjs +2 -1
- package/es/hooks/useMermaid.mjs.map +1 -1
- package/es/i18n/resources/en/image.d.mts +5 -0
- package/es/i18n/resources/en/image.mjs +6 -1
- package/es/i18n/resources/en/image.mjs.map +1 -1
- package/es/i18n/resources/zhCn/image.d.mts +5 -0
- package/es/i18n/resources/zhCn/image.mjs +6 -1
- package/es/i18n/resources/zhCn/image.mjs.map +1 -1
- package/es/index.mjs +8 -8
- package/package.json +1 -1
- package/es/Image/components/Preview.mjs +0 -23
- package/es/Image/components/Preview.mjs.map +0 -1
- package/es/Image/components/Toolbar.mjs +0 -128
- package/es/Image/components/Toolbar.mjs.map +0 -1
- package/es/Image/components/usePreview.mjs +0 -58
- package/es/Image/components/usePreview.mjs.map +0 -1
- package/es/Image/components/usePreviewGroup.mjs +0 -57
- package/es/Image/components/usePreviewGroup.mjs.map +0 -1
|
@@ -59,18 +59,20 @@ const Button = ({ block, children, className, classNames, danger = false, disabl
|
|
|
59
59
|
const shapeCls = shape === "circle" ? styles.shapeCircle : shape === "round" ? styles.shapeRound : void 0;
|
|
60
60
|
const iconOnlySizeCls = !(children !== void 0 && children !== null && children !== false && children !== "") && !!(loading || icon) ? resolveIconOnlySizeCls(size) : void 0;
|
|
61
61
|
const composedClassName = cx(styles.base, sizeCls, variantCls, shapeCls, block && styles.block, iconPosition === "end" && styles.iconEnd, iconOnlySizeCls, className);
|
|
62
|
+
const spinnerNode = /* @__PURE__ */ jsx("span", {
|
|
63
|
+
"aria-hidden": !loading,
|
|
64
|
+
style: userStyles?.icon,
|
|
65
|
+
className: cx(styles.iconBox, styles.spinnerSlot, loading && styles.spinnerSlotShow, iconPosition === "end" && styles.spinnerSlotEnd, classNames?.icon),
|
|
66
|
+
children: /* @__PURE__ */ jsx("span", { className: styles.spinner })
|
|
67
|
+
});
|
|
68
|
+
const iconNode = icon && !loading ? /* @__PURE__ */ jsx("span", {
|
|
69
|
+
className: cx(styles.iconBox, classNames?.icon),
|
|
70
|
+
style: userStyles?.icon,
|
|
71
|
+
children: resolveIconNode(icon)
|
|
72
|
+
}) : null;
|
|
62
73
|
const inner = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
style: userStyles?.icon,
|
|
66
|
-
className: cx(styles.iconBox, styles.spinnerSlot, loading && styles.spinnerSlotShow, iconPosition === "end" && styles.spinnerSlotEnd, classNames?.icon),
|
|
67
|
-
children: /* @__PURE__ */ jsx("span", { className: styles.spinner })
|
|
68
|
-
}),
|
|
69
|
-
icon && !loading ? /* @__PURE__ */ jsx("span", {
|
|
70
|
-
className: cx(styles.iconBox, classNames?.icon),
|
|
71
|
-
style: userStyles?.icon,
|
|
72
|
-
children: resolveIconNode(icon)
|
|
73
|
-
}) : null,
|
|
74
|
+
spinnerNode,
|
|
75
|
+
iconNode,
|
|
74
76
|
children
|
|
75
77
|
] });
|
|
76
78
|
const motionGestures = isInteractionDisabled ? {} : {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.mjs","names":[],"sources":["../../../src/base-ui/Button/Button.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { isValidElement, type MouseEvent, type ReactNode, type Ref } from 'react';\n\nimport Icon, { type IconProps } from '@/Icon';\nimport { useMotionComponent } from '@/MotionProvider';\n\nimport { styles } from './style';\nimport type { ButtonProps } from './type';\n\nconst resolveIconNode = (node: ReactNode | IconProps['icon'] | undefined | null) => {\n if (node === undefined || node === null) return null;\n if (isValidElement(node) || typeof node === 'string' || typeof node === 'number') {\n return node;\n }\n return <Icon icon={node as any} size={'small'} />;\n};\n\nconst resolveSizeCls = (size: ButtonProps['size']) => {\n if (size === 'small') return styles.sizeSmall;\n if (size === 'large') return styles.sizeLarge;\n return styles.sizeMiddle;\n};\n\nconst resolveIconOnlySizeCls = (size: ButtonProps['size']) => {\n if (size === 'small') return styles.iconOnlySmall;\n if (size === 'large') return styles.iconOnlyLarge;\n return styles.iconOnlyMiddle;\n};\n\nconst resolveVariantCls = ({\n danger,\n ghost,\n type,\n}: {\n danger: boolean;\n ghost: boolean;\n type: NonNullable<ButtonProps['type']>;\n}): string => {\n if (ghost) {\n if (danger) return styles.ghostDanger;\n if (type === 'primary') return styles.ghostPrimary;\n if (type === 'dashed') return cx(styles.ghostDefault, styles.ghostDashed);\n return styles.ghostDefault;\n }\n\n switch (type) {\n case 'primary': {\n return danger ? styles.dangerSolid : styles.variantPrimary;\n }\n case 'dashed': {\n return danger ? cx(styles.variantDashed, styles.dangerOutlined) : styles.variantDashed;\n }\n case 'fill': {\n return danger ? styles.dangerFill : styles.variantFill;\n }\n case 'text': {\n return danger ? cx(styles.variantText, styles.dangerInline) : styles.variantText;\n }\n case 'link': {\n return danger ? cx(styles.variantLink, styles.dangerInline) : styles.variantLink;\n }\n default: {\n return danger ? cx(styles.variantDefault, styles.dangerOutlined) : styles.variantDefault;\n }\n }\n};\n\nconst tapAnim = { scale: 0.98 };\nconst motionTransition = {\n damping: 26,\n mass: 0.6,\n stiffness: 600,\n type: 'spring' as const,\n};\n\nconst Button = ({\n block,\n children,\n className,\n classNames,\n danger = false,\n disabled,\n ghost = false,\n href,\n htmlType = 'button',\n icon,\n iconPosition = 'start',\n loading,\n onClick,\n ref,\n shape = 'default',\n size = 'middle',\n styles: userStyles,\n target,\n type = 'default',\n ...rest\n}: ButtonProps) => {\n const Motion = useMotionComponent();\n const isInteractionDisabled = disabled || loading;\n const sizeCls = resolveSizeCls(size);\n const variantCls = resolveVariantCls({ danger, ghost, type });\n const shapeCls =\n shape === 'circle' ? styles.shapeCircle : shape === 'round' ? styles.shapeRound : undefined;\n\n const hasChildren =\n children !== undefined && children !== null && children !== false && children !== '';\n const renderIcon = loading || icon;\n const iconOnly = !hasChildren && !!renderIcon;\n const iconOnlySizeCls = iconOnly ? resolveIconOnlySizeCls(size) : undefined;\n\n const composedClassName = cx(\n styles.base,\n sizeCls,\n variantCls,\n shapeCls,\n block && styles.block,\n iconPosition === 'end' && styles.iconEnd,\n iconOnlySizeCls,\n className,\n );\n\n const spinnerNode = (\n <span\n aria-hidden={!loading}\n style={userStyles?.icon}\n className={cx(\n styles.iconBox,\n styles.spinnerSlot,\n loading && styles.spinnerSlotShow,\n iconPosition === 'end' && styles.spinnerSlotEnd,\n classNames?.icon,\n )}\n >\n <span className={styles.spinner} />\n </span>\n );\n\n const iconNode =\n icon && !loading ? (\n <span className={cx(styles.iconBox, classNames?.icon)} style={userStyles?.icon}>\n {resolveIconNode(icon)}\n </span>\n ) : null;\n\n const inner = (\n <>\n {spinnerNode}\n {iconNode}\n {children}\n </>\n );\n\n const motionGestures = isInteractionDisabled\n ? {}\n : { transition: motionTransition, whileTap: tapAnim };\n\n if (href !== undefined) {\n const handleAnchorClick = (e: MouseEvent<HTMLAnchorElement>) => {\n if (isInteractionDisabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e as unknown as MouseEvent<HTMLButtonElement>);\n };\n\n return (\n <Motion.a\n aria-busy={loading || undefined}\n aria-disabled={isInteractionDisabled || undefined}\n href={disabled ? undefined : href}\n target={target}\n {...(rest as any)}\n className={composedClassName}\n ref={ref as Ref<HTMLAnchorElement>}\n onClick={handleAnchorClick}\n {...motionGestures}\n >\n {inner}\n </Motion.a>\n );\n }\n\n const handleButtonClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (isInteractionDisabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e);\n };\n\n return (\n <Motion.button\n type={htmlType}\n {...(rest as any)}\n aria-busy={loading || undefined}\n aria-disabled={isInteractionDisabled || undefined}\n className={composedClassName}\n disabled={disabled}\n ref={ref as Ref<HTMLButtonElement>}\n onClick={handleButtonClick}\n {...motionGestures}\n >\n {inner}\n </Motion.button>\n );\n};\n\nButton.displayName = 'BaseButton';\n\nexport default Button;\n"],"mappings":";;;;;;;;AAWA,MAAM,mBAAmB,SAA2D;CAClF,IAAI,SAAS,KAAA,KAAa,SAAS,MAAM,OAAO;CAChD,IAAI,eAAe,IAAI,KAAK,OAAO,SAAS,YAAY,OAAO,SAAS,UACtE,OAAO;CAET,OAAO,oBAAC,MAAD;EAAM,MAAM;EAAa,MAAM;CAAU,CAAA;AAClD;AAEA,MAAM,kBAAkB,SAA8B;CACpD,IAAI,SAAS,SAAS,OAAO,OAAO;CACpC,IAAI,SAAS,SAAS,OAAO,OAAO;CACpC,OAAO,OAAO;AAChB;AAEA,MAAM,0BAA0B,SAA8B;CAC5D,IAAI,SAAS,SAAS,OAAO,OAAO;CACpC,IAAI,SAAS,SAAS,OAAO,OAAO;CACpC,OAAO,OAAO;AAChB;AAEA,MAAM,qBAAqB,EACzB,QACA,OACA,WAKY;CACZ,IAAI,OAAO;EACT,IAAI,QAAQ,OAAO,OAAO;EAC1B,IAAI,SAAS,WAAW,OAAO,OAAO;EACtC,IAAI,SAAS,UAAU,OAAO,GAAG,OAAO,cAAc,OAAO,WAAW;EACxE,OAAO,OAAO;CAChB;CAEA,QAAQ,MAAR;EACE,KAAK,WACH,OAAO,SAAS,OAAO,cAAc,OAAO;EAE9C,KAAK,UACH,OAAO,SAAS,GAAG,OAAO,eAAe,OAAO,cAAc,IAAI,OAAO;EAE3E,KAAK,QACH,OAAO,SAAS,OAAO,aAAa,OAAO;EAE7C,KAAK,QACH,OAAO,SAAS,GAAG,OAAO,aAAa,OAAO,YAAY,IAAI,OAAO;EAEvE,KAAK,QACH,OAAO,SAAS,GAAG,OAAO,aAAa,OAAO,YAAY,IAAI,OAAO;EAEvE,SACE,OAAO,SAAS,GAAG,OAAO,gBAAgB,OAAO,cAAc,IAAI,OAAO;CAE9E;AACF;AAEA,MAAM,UAAU,EAAE,OAAO,IAAK;AAC9B,MAAM,mBAAmB;CACvB,SAAS;CACT,MAAM;CACN,WAAW;CACX,MAAM;AACR;AAEA,MAAM,UAAU,EACd,OACA,UACA,WACA,YACA,SAAS,OACT,UACA,QAAQ,OACR,MACA,WAAW,UACX,MACA,eAAe,SACf,SACA,SACA,KACA,QAAQ,WACR,OAAO,UACP,QAAQ,YACR,QACA,OAAO,WACP,GAAG,WACc;CACjB,MAAM,SAAS,mBAAmB;CAClC,MAAM,wBAAwB,YAAY;CAC1C,MAAM,UAAU,eAAe,IAAI;CACnC,MAAM,aAAa,kBAAkB;EAAE;EAAQ;EAAO;CAAK,CAAC;CAC5D,MAAM,WACJ,UAAU,WAAW,OAAO,cAAc,UAAU,UAAU,OAAO,aAAa,KAAA;CAMpF,MAAM,kBADW,EAFf,aAAa,KAAA,KAAa,aAAa,QAAQ,aAAa,SAAS,aAAa,OAEnD,CAAC,EADf,WAAW,QAEK,uBAAuB,IAAI,IAAI,KAAA;CAElE,MAAM,oBAAoB,GACxB,OAAO,MACP,SACA,YACA,UACA,SAAS,OAAO,OAChB,iBAAiB,SAAS,OAAO,SACjC,iBACA,SACF;
|
|
1
|
+
{"version":3,"file":"Button.mjs","names":[],"sources":["../../../src/base-ui/Button/Button.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { isValidElement, type MouseEvent, type ReactNode, type Ref } from 'react';\n\nimport Icon, { type IconProps } from '@/Icon';\nimport { useMotionComponent } from '@/MotionProvider';\n\nimport { styles } from './style';\nimport type { ButtonProps } from './type';\n\nconst resolveIconNode = (node: ReactNode | IconProps['icon'] | undefined | null) => {\n if (node === undefined || node === null) return null;\n if (isValidElement(node) || typeof node === 'string' || typeof node === 'number') {\n return node;\n }\n return <Icon icon={node as any} size={'small'} />;\n};\n\nconst resolveSizeCls = (size: ButtonProps['size']) => {\n if (size === 'small') return styles.sizeSmall;\n if (size === 'large') return styles.sizeLarge;\n return styles.sizeMiddle;\n};\n\nconst resolveIconOnlySizeCls = (size: ButtonProps['size']) => {\n if (size === 'small') return styles.iconOnlySmall;\n if (size === 'large') return styles.iconOnlyLarge;\n return styles.iconOnlyMiddle;\n};\n\nconst resolveVariantCls = ({\n danger,\n ghost,\n type,\n}: {\n danger: boolean;\n ghost: boolean;\n type: NonNullable<ButtonProps['type']>;\n}): string => {\n if (ghost) {\n if (danger) return styles.ghostDanger;\n if (type === 'primary') return styles.ghostPrimary;\n if (type === 'dashed') return cx(styles.ghostDefault, styles.ghostDashed);\n return styles.ghostDefault;\n }\n\n switch (type) {\n case 'primary': {\n return danger ? styles.dangerSolid : styles.variantPrimary;\n }\n case 'dashed': {\n return danger ? cx(styles.variantDashed, styles.dangerOutlined) : styles.variantDashed;\n }\n case 'fill': {\n return danger ? styles.dangerFill : styles.variantFill;\n }\n case 'text': {\n return danger ? cx(styles.variantText, styles.dangerInline) : styles.variantText;\n }\n case 'link': {\n return danger ? cx(styles.variantLink, styles.dangerInline) : styles.variantLink;\n }\n default: {\n return danger ? cx(styles.variantDefault, styles.dangerOutlined) : styles.variantDefault;\n }\n }\n};\n\nconst tapAnim = { scale: 0.98 };\nconst motionTransition = {\n damping: 26,\n mass: 0.6,\n stiffness: 600,\n type: 'spring' as const,\n};\n\nconst Button = ({\n block,\n children,\n className,\n classNames,\n danger = false,\n disabled,\n ghost = false,\n href,\n htmlType = 'button',\n icon,\n iconPosition = 'start',\n loading,\n onClick,\n ref,\n shape = 'default',\n size = 'middle',\n styles: userStyles,\n target,\n type = 'default',\n ...rest\n}: ButtonProps) => {\n const Motion = useMotionComponent();\n const isInteractionDisabled = disabled || loading;\n const sizeCls = resolveSizeCls(size);\n const variantCls = resolveVariantCls({ danger, ghost, type });\n const shapeCls =\n shape === 'circle' ? styles.shapeCircle : shape === 'round' ? styles.shapeRound : undefined;\n\n const hasChildren =\n children !== undefined && children !== null && children !== false && children !== '';\n const renderIcon = loading || icon;\n const iconOnly = !hasChildren && !!renderIcon;\n const iconOnlySizeCls = iconOnly ? resolveIconOnlySizeCls(size) : undefined;\n\n const composedClassName = cx(\n styles.base,\n sizeCls,\n variantCls,\n shapeCls,\n block && styles.block,\n iconPosition === 'end' && styles.iconEnd,\n iconOnlySizeCls,\n className,\n );\n\n const spinnerNode = (\n <span\n aria-hidden={!loading}\n style={userStyles?.icon}\n className={cx(\n styles.iconBox,\n styles.spinnerSlot,\n loading && styles.spinnerSlotShow,\n iconPosition === 'end' && styles.spinnerSlotEnd,\n classNames?.icon,\n )}\n >\n <span className={styles.spinner} />\n </span>\n );\n\n const iconNode =\n icon && !loading ? (\n <span className={cx(styles.iconBox, classNames?.icon)} style={userStyles?.icon}>\n {resolveIconNode(icon)}\n </span>\n ) : null;\n\n const inner = (\n <>\n {spinnerNode}\n {iconNode}\n {children}\n </>\n );\n\n const motionGestures = isInteractionDisabled\n ? {}\n : { transition: motionTransition, whileTap: tapAnim };\n\n if (href !== undefined) {\n const handleAnchorClick = (e: MouseEvent<HTMLAnchorElement>) => {\n if (isInteractionDisabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e as unknown as MouseEvent<HTMLButtonElement>);\n };\n\n return (\n <Motion.a\n aria-busy={loading || undefined}\n aria-disabled={isInteractionDisabled || undefined}\n href={disabled ? undefined : href}\n target={target}\n {...(rest as any)}\n className={composedClassName}\n ref={ref as Ref<HTMLAnchorElement>}\n onClick={handleAnchorClick}\n {...motionGestures}\n >\n {inner}\n </Motion.a>\n );\n }\n\n const handleButtonClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (isInteractionDisabled) {\n e.preventDefault();\n return;\n }\n onClick?.(e);\n };\n\n return (\n <Motion.button\n type={htmlType}\n {...(rest as any)}\n aria-busy={loading || undefined}\n aria-disabled={isInteractionDisabled || undefined}\n className={composedClassName}\n disabled={disabled}\n ref={ref as Ref<HTMLButtonElement>}\n onClick={handleButtonClick}\n {...motionGestures}\n >\n {inner}\n </Motion.button>\n );\n};\n\nButton.displayName = 'BaseButton';\n\nexport default Button;\n"],"mappings":"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"}
|
|
@@ -46,8 +46,9 @@ const SplitButton = ({ children, className, style, danger, disabled, loading, si
|
|
|
46
46
|
});
|
|
47
47
|
};
|
|
48
48
|
const SplitButtonMain = (props) => {
|
|
49
|
+
const shared = use(SplitButtonContext);
|
|
49
50
|
return /* @__PURE__ */ jsx(Button, {
|
|
50
|
-
...
|
|
51
|
+
...shared,
|
|
51
52
|
...props
|
|
52
53
|
});
|
|
53
54
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SplitButton.mjs","names":[],"sources":["../../../src/base-ui/Button/SplitButton.tsx"],"sourcesContent":["'use client';\n\nimport { createStaticStyles, cx } from 'antd-style';\nimport { ChevronDownIcon } from 'lucide-react';\nimport { createContext, type CSSProperties, type ReactNode, use, useMemo } from 'react';\n\nimport { DropdownMenu, type DropdownMenuProps } from '@/base-ui/DropdownMenu';\n\nimport Button from './Button';\nimport type { ButtonProps } from './type';\n\ninterface SharedVisualProps {\n danger?: boolean;\n disabled?: boolean;\n loading?: boolean;\n size?: ButtonProps['size'];\n type?: ButtonProps['type'];\n}\n\ninterface SplitButtonProps extends SharedVisualProps {\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SplitButtonContext = createContext<SharedVisualProps>({});\n\nconst styles = createStaticStyles(({ css }) => ({\n splitButton: css`\n display: inline-flex;\n flex-direction: row;\n\n & > :where(button, a):first-of-type {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n }\n\n & > :where(button, a):last-of-type {\n margin-inline-start: -1px;\n border-start-start-radius: 0;\n border-end-start-radius: 0;\n }\n `,\n}));\n\nconst SplitButton = ({\n children,\n className,\n style,\n danger,\n disabled,\n loading,\n size,\n type,\n}: SplitButtonProps) => {\n const shared = useMemo<SharedVisualProps>(\n () => ({ danger, disabled, loading, size, type }),\n [danger, disabled, loading, size, type],\n );\n return (\n <SplitButtonContext value={shared}>\n <div className={cx(styles.splitButton, className)} style={style}>\n {children}\n </div>\n </SplitButtonContext>\n );\n};\n\nconst SplitButtonMain = (props: ButtonProps) => {\n const shared = use(SplitButtonContext);\n return <Button {...shared} {...props} />;\n};\n\ninterface SplitButtonMenuProps extends Omit<DropdownMenuProps, 'children'> {\n icon?: ReactNode;\n}\n\nconst SplitButtonMenu = ({\n icon = <ChevronDownIcon size={14} />,\n ...menuProps\n}: SplitButtonMenuProps) => {\n const shared = use(SplitButtonContext);\n return (\n <DropdownMenu {...menuProps}>\n <Button {...shared} icon={icon} />\n </DropdownMenu>\n );\n};\n\ntype SplitButtonComponent = typeof SplitButton & {\n Main: typeof SplitButtonMain;\n Menu: typeof SplitButtonMenu;\n};\n\n(SplitButton as SplitButtonComponent).Main = SplitButtonMain;\n(SplitButton as SplitButtonComponent).Menu = SplitButtonMenu;\n\nexport type { SplitButtonMenuProps, SplitButtonProps };\nexport default SplitButton as SplitButtonComponent;\n"],"mappings":";;;;;;;;AAyBA,MAAM,qBAAqB,cAAiC,CAAC,CAAC;AAE9D,MAAM,SAAS,oBAAoB,EAAE,WAAW,EAC9C,aAAa,GAAG;;;;;;;;;;;;;;IAelB,EAAE;AAEF,MAAM,eAAe,EACnB,UACA,WACA,OACA,QACA,UACA,SACA,MACA,WACsB;CACtB,MAAM,SAAS,eACN;EAAE;EAAQ;EAAU;EAAS;EAAM;CAAK,IAC/C;EAAC;EAAQ;EAAU;EAAS;EAAM;CAAI,CACxC;CACA,OACE,oBAAC,oBAAD;EAAoB,OAAO;EACzB,UAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,OAAO,aAAa,SAAS;GAAU;GACvD;EACE,CAAA;CACa,CAAA;AAExB;AAEA,MAAM,mBAAmB,UAAuB;
|
|
1
|
+
{"version":3,"file":"SplitButton.mjs","names":[],"sources":["../../../src/base-ui/Button/SplitButton.tsx"],"sourcesContent":["'use client';\n\nimport { createStaticStyles, cx } from 'antd-style';\nimport { ChevronDownIcon } from 'lucide-react';\nimport { createContext, type CSSProperties, type ReactNode, use, useMemo } from 'react';\n\nimport { DropdownMenu, type DropdownMenuProps } from '@/base-ui/DropdownMenu';\n\nimport Button from './Button';\nimport type { ButtonProps } from './type';\n\ninterface SharedVisualProps {\n danger?: boolean;\n disabled?: boolean;\n loading?: boolean;\n size?: ButtonProps['size'];\n type?: ButtonProps['type'];\n}\n\ninterface SplitButtonProps extends SharedVisualProps {\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SplitButtonContext = createContext<SharedVisualProps>({});\n\nconst styles = createStaticStyles(({ css }) => ({\n splitButton: css`\n display: inline-flex;\n flex-direction: row;\n\n & > :where(button, a):first-of-type {\n border-start-end-radius: 0;\n border-end-end-radius: 0;\n }\n\n & > :where(button, a):last-of-type {\n margin-inline-start: -1px;\n border-start-start-radius: 0;\n border-end-start-radius: 0;\n }\n `,\n}));\n\nconst SplitButton = ({\n children,\n className,\n style,\n danger,\n disabled,\n loading,\n size,\n type,\n}: SplitButtonProps) => {\n const shared = useMemo<SharedVisualProps>(\n () => ({ danger, disabled, loading, size, type }),\n [danger, disabled, loading, size, type],\n );\n return (\n <SplitButtonContext value={shared}>\n <div className={cx(styles.splitButton, className)} style={style}>\n {children}\n </div>\n </SplitButtonContext>\n );\n};\n\nconst SplitButtonMain = (props: ButtonProps) => {\n const shared = use(SplitButtonContext);\n return <Button {...shared} {...props} />;\n};\n\ninterface SplitButtonMenuProps extends Omit<DropdownMenuProps, 'children'> {\n icon?: ReactNode;\n}\n\nconst SplitButtonMenu = ({\n icon = <ChevronDownIcon size={14} />,\n ...menuProps\n}: SplitButtonMenuProps) => {\n const shared = use(SplitButtonContext);\n return (\n <DropdownMenu {...menuProps}>\n <Button {...shared} icon={icon} />\n </DropdownMenu>\n );\n};\n\ntype SplitButtonComponent = typeof SplitButton & {\n Main: typeof SplitButtonMain;\n Menu: typeof SplitButtonMenu;\n};\n\n(SplitButton as SplitButtonComponent).Main = SplitButtonMain;\n(SplitButton as SplitButtonComponent).Menu = SplitButtonMenu;\n\nexport type { SplitButtonMenuProps, SplitButtonProps };\nexport default SplitButton as SplitButtonComponent;\n"],"mappings":";;;;;;;;AAyBA,MAAM,qBAAqB,cAAiC,CAAC,CAAC;AAE9D,MAAM,SAAS,oBAAoB,EAAE,WAAW,EAC9C,aAAa,GAAG;;;;;;;;;;;;;;IAelB,EAAE;AAEF,MAAM,eAAe,EACnB,UACA,WACA,OACA,QACA,UACA,SACA,MACA,WACsB;CACtB,MAAM,SAAS,eACN;EAAE;EAAQ;EAAU;EAAS;EAAM;CAAK,IAC/C;EAAC;EAAQ;EAAU;EAAS;EAAM;CAAI,CACxC;CACA,OACE,oBAAC,oBAAD;EAAoB,OAAO;EACzB,UAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,OAAO,aAAa,SAAS;GAAU;GACvD;EACE,CAAA;CACa,CAAA;AAExB;AAEA,MAAM,mBAAmB,UAAuB;CAC9C,MAAM,SAAS,IAAI,kBAAkB;CACrC,OAAO,oBAAC,QAAD;EAAQ,GAAI;EAAQ,GAAI;CAAQ,CAAA;AACzC;AAMA,MAAM,mBAAmB,EACvB,OAAO,oBAAC,iBAAD,EAAiB,MAAM,GAAK,CAAA,GACnC,GAAG,gBACuB;CAC1B,MAAM,SAAS,IAAI,kBAAkB;CACrC,OACE,oBAAC,cAAD;EAAc,GAAI;EAChB,UAAA,oBAAC,QAAD;GAAQ,GAAI;GAAc;EAAO,CAAA;CACrB,CAAA;AAElB;AAOA,YAAsC,OAAO;AAC7C,YAAsC,OAAO"}
|
|
@@ -14,7 +14,8 @@ const ContextMenuTrigger = memo(({ children, footer, header, items, onContextMen
|
|
|
14
14
|
const handleContextMenu = useCallback((event) => {
|
|
15
15
|
if (items) {
|
|
16
16
|
event.preventDefault();
|
|
17
|
-
|
|
17
|
+
const resolvedItems = typeof items === "function" ? items() : items;
|
|
18
|
+
showContextMenu(resolvedItems, {
|
|
18
19
|
footer,
|
|
19
20
|
header
|
|
20
21
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenuTrigger.mjs","names":[],"sources":["../../../src/base-ui/ContextMenu/ContextMenuTrigger.tsx"],"sourcesContent":["'use client';\n\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport clsx from 'clsx';\nimport React, {\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useId,\n useSyncExternalStore,\n} from 'react';\n\nimport { CLASSNAMES } from '@/styles/classNames';\n\nimport { getServerSnapshot, getSnapshot, showContextMenu, subscribe } from './store';\nimport { type ContextMenuItem } from './type';\n\nexport type ContextMenuTriggerProps = {\n children: ReactNode;\n /**\n * Footer slot pinned below the scrollable items area, with a divider border.\n */\n footer?: ReactNode;\n /**\n * Header slot pinned above the scrollable items area, with a divider border.\n */\n header?: ReactNode;\n /**\n * Menu items to display. Supports lazy rendering via function.\n * When provided, context menu will be automatically shown on right-click.\n */\n items?: ContextMenuItem[] | (() => ContextMenuItem[]);\n /**\n * Custom context menu handler. If `items` is provided, this is optional.\n */\n onContextMenu?: (event: MouseEvent<HTMLElement>) => void;\n} & Omit<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'children'>;\n\nconst styles = {\n trigger: {\n display: 'contents',\n },\n};\n\nexport const ContextMenuTrigger = memo<ContextMenuTriggerProps>(\n ({ children, footer, header, items, onContextMenu, ...rest }) => {\n const triggerId = useId();\n const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const open = state.open && state.triggerId === triggerId;\n\n const handleContextMenu = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (items) {\n event.preventDefault();\n const resolvedItems = typeof items === 'function' ? items() : items;\n showContextMenu(resolvedItems, { footer, header });\n }\n onContextMenu?.(event);\n },\n [items, onContextMenu, footer, header],\n );\n\n const triggerProps = {\n ...rest,\n 'aria-expanded': open || undefined,\n 'className': clsx(CLASSNAMES.ContextTrigger, rest.className),\n 'data-contextmenu-trigger': triggerId,\n 'data-popup-open': open ? '' : undefined,\n 'data-state': open ? 'open' : undefined,\n 'onContextMenu': handleContextMenu,\n };\n\n if (isValidElement(children) && React.Children.only(children)) {\n return cloneElement(children, mergeProps(children.props as any, triggerProps));\n }\n\n return (\n <span style={styles.trigger} {...triggerProps}>\n {children}\n </span>\n );\n },\n);\n\nContextMenuTrigger.displayName = 'ContextMenuTrigger';\n"],"mappings":";;;;;;;;AA0CA,MAAM,SAAS,EACb,SAAS,EACP,SAAS,WACX,EACF;AAEA,MAAa,qBAAqB,MAC/B,EAAE,UAAU,QAAQ,QAAQ,OAAO,eAAe,GAAG,WAAW;CAC/D,MAAM,YAAY,MAAM;CACxB,MAAM,QAAQ,qBAAqB,WAAW,aAAa,iBAAiB;CAC5E,MAAM,OAAO,MAAM,QAAQ,MAAM,cAAc;CAE/C,MAAM,oBAAoB,aACvB,UAAmC;EAClC,IAAI,OAAO;GACT,MAAM,eAAe;
|
|
1
|
+
{"version":3,"file":"ContextMenuTrigger.mjs","names":[],"sources":["../../../src/base-ui/ContextMenu/ContextMenuTrigger.tsx"],"sourcesContent":["'use client';\n\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport clsx from 'clsx';\nimport React, {\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n memo,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useId,\n useSyncExternalStore,\n} from 'react';\n\nimport { CLASSNAMES } from '@/styles/classNames';\n\nimport { getServerSnapshot, getSnapshot, showContextMenu, subscribe } from './store';\nimport { type ContextMenuItem } from './type';\n\nexport type ContextMenuTriggerProps = {\n children: ReactNode;\n /**\n * Footer slot pinned below the scrollable items area, with a divider border.\n */\n footer?: ReactNode;\n /**\n * Header slot pinned above the scrollable items area, with a divider border.\n */\n header?: ReactNode;\n /**\n * Menu items to display. Supports lazy rendering via function.\n * When provided, context menu will be automatically shown on right-click.\n */\n items?: ContextMenuItem[] | (() => ContextMenuItem[]);\n /**\n * Custom context menu handler. If `items` is provided, this is optional.\n */\n onContextMenu?: (event: MouseEvent<HTMLElement>) => void;\n} & Omit<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'children'>;\n\nconst styles = {\n trigger: {\n display: 'contents',\n },\n};\n\nexport const ContextMenuTrigger = memo<ContextMenuTriggerProps>(\n ({ children, footer, header, items, onContextMenu, ...rest }) => {\n const triggerId = useId();\n const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const open = state.open && state.triggerId === triggerId;\n\n const handleContextMenu = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (items) {\n event.preventDefault();\n const resolvedItems = typeof items === 'function' ? items() : items;\n showContextMenu(resolvedItems, { footer, header });\n }\n onContextMenu?.(event);\n },\n [items, onContextMenu, footer, header],\n );\n\n const triggerProps = {\n ...rest,\n 'aria-expanded': open || undefined,\n 'className': clsx(CLASSNAMES.ContextTrigger, rest.className),\n 'data-contextmenu-trigger': triggerId,\n 'data-popup-open': open ? '' : undefined,\n 'data-state': open ? 'open' : undefined,\n 'onContextMenu': handleContextMenu,\n };\n\n if (isValidElement(children) && React.Children.only(children)) {\n return cloneElement(children, mergeProps(children.props as any, triggerProps));\n }\n\n return (\n <span style={styles.trigger} {...triggerProps}>\n {children}\n </span>\n );\n },\n);\n\nContextMenuTrigger.displayName = 'ContextMenuTrigger';\n"],"mappings":";;;;;;;;AA0CA,MAAM,SAAS,EACb,SAAS,EACP,SAAS,WACX,EACF;AAEA,MAAa,qBAAqB,MAC/B,EAAE,UAAU,QAAQ,QAAQ,OAAO,eAAe,GAAG,WAAW;CAC/D,MAAM,YAAY,MAAM;CACxB,MAAM,QAAQ,qBAAqB,WAAW,aAAa,iBAAiB;CAC5E,MAAM,OAAO,MAAM,QAAQ,MAAM,cAAc;CAE/C,MAAM,oBAAoB,aACvB,UAAmC;EAClC,IAAI,OAAO;GACT,MAAM,eAAe;GACrB,MAAM,gBAAgB,OAAO,UAAU,aAAa,MAAM,IAAI;GAC9D,gBAAgB,eAAe;IAAE;IAAQ;GAAO,CAAC;EACnD;EACA,gBAAgB,KAAK;CACvB,GACA;EAAC;EAAO;EAAe;EAAQ;CAAM,CACvC;CAEA,MAAM,eAAe;EACnB,GAAG;EACH,iBAAiB,QAAQ,KAAA;EACzB,aAAa,KAAK,WAAW,gBAAgB,KAAK,SAAS;EAC3D,4BAA4B;EAC5B,mBAAmB,OAAO,KAAK,KAAA;EAC/B,cAAc,OAAO,SAAS,KAAA;EAC9B,iBAAiB;CACnB;CAEA,IAAI,eAAe,QAAQ,KAAK,MAAM,SAAS,KAAK,QAAQ,GAC1D,OAAO,aAAa,UAAU,WAAW,SAAS,OAAc,YAAY,CAAC;CAG/E,OACE,oBAAC,QAAD;EAAM,OAAO,OAAO;EAAS,GAAI;EAC9B;CACG,CAAA;AAEV,CACF;AAEA,mBAAmB,cAAc"}
|
|
@@ -122,7 +122,8 @@ const renderContextMenuItems = (items, keyPath = [], options) => {
|
|
|
122
122
|
const indicatorOnRight = options?.indicatorOnRight ?? hasCheckboxAndIcon(items);
|
|
123
123
|
return items.map((item, index) => {
|
|
124
124
|
if (!item) return null;
|
|
125
|
-
const
|
|
125
|
+
const fallbackKey = `${keyPath.join("-") || "root"}-${index}`;
|
|
126
|
+
const itemKey = getItemKey(item, fallbackKey);
|
|
126
127
|
const nextKeyPath = [...keyPath, String(itemKey)];
|
|
127
128
|
if (item.type === "checkbox") {
|
|
128
129
|
const checkboxItem = item;
|
|
@@ -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 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 { 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 {\n type ContextMenuCheckboxItem,\n type ContextMenuItem,\n type ContextMenuSwitchItem,\n} from './type';\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 <ContextMenu.Positioner\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 </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, { 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 { type MenuInfo } from 'rc-menu/es/interface';\nimport {\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 { 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 {\n type ContextMenuCheckboxItem,\n type ContextMenuItem,\n type ContextMenuSwitchItem,\n} from './type';\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 <ContextMenu.Positioner\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 </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, { iconAlign, reserveIconSpace })}\n </ContextMenu.Item>\n );\n });\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { DEFAULT_CONTAINER_MAX_WIDTH } from "./constants.mjs";
|
|
3
|
+
import { styles } from "./style.mjs";
|
|
4
|
+
import { DrawerBackdrop, DrawerContent, DrawerFooter, DrawerHeader, DrawerPopup, DrawerPortal, DrawerRoot, DrawerTitle } from "./atoms.mjs";
|
|
5
|
+
import { DrawerPushProvider, useDrawerPush } from "./DrawerPushContext.mjs";
|
|
6
|
+
import { memo, useCallback, useMemo } from "react";
|
|
7
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { cx } from "antd-style";
|
|
9
|
+
import { X } from "lucide-react";
|
|
10
|
+
//#region src/base-ui/Drawer/Drawer.tsx
|
|
11
|
+
const resolvePushDistance = (push) => {
|
|
12
|
+
if (push === false) return 0;
|
|
13
|
+
if (push === true) return 180;
|
|
14
|
+
return push.distance ?? 180;
|
|
15
|
+
};
|
|
16
|
+
const FULL_SIZES = /* @__PURE__ */ new Set([
|
|
17
|
+
"100%",
|
|
18
|
+
"100dvh",
|
|
19
|
+
"100dvw",
|
|
20
|
+
"100vh",
|
|
21
|
+
"100vw"
|
|
22
|
+
]);
|
|
23
|
+
const Drawer = memo(({ open, placement = "right", width, height, mask = true, maskClosable = true, keyboard = true, closable = true, closeIcon, extra, title, footer, noHeader, sidebar, sidebarWidth = 280, containerMaxWidth = DEFAULT_CONTAINER_MAX_WIDTH, push = true, zIndex, getContainer, className, classNames, style, styles: semanticStyles, afterOpenChange, onClose, children }) => {
|
|
24
|
+
const isOpen = open ?? false;
|
|
25
|
+
const { childValue, pushed } = useDrawerPush(isOpen);
|
|
26
|
+
const pushOffset = pushed ? resolvePushDistance(push) : 0;
|
|
27
|
+
const handleOpenChange = useCallback((nextOpen, eventDetails) => {
|
|
28
|
+
if (nextOpen || !isOpen) return;
|
|
29
|
+
if (!keyboard && eventDetails.reason === "escape-key") return;
|
|
30
|
+
if (!maskClosable && eventDetails.reason === "outside-press") return;
|
|
31
|
+
onClose?.();
|
|
32
|
+
}, [
|
|
33
|
+
isOpen,
|
|
34
|
+
keyboard,
|
|
35
|
+
maskClosable,
|
|
36
|
+
onClose
|
|
37
|
+
]);
|
|
38
|
+
const handleExitComplete = useCallback(() => afterOpenChange?.(false), [afterOpenChange]);
|
|
39
|
+
const handleAnimationComplete = useCallback(() => {
|
|
40
|
+
if (isOpen) afterOpenChange?.(true);
|
|
41
|
+
}, [isOpen, afterOpenChange]);
|
|
42
|
+
const isHorizontal = placement === "left" || placement === "right";
|
|
43
|
+
const resolvedWidth = isHorizontal ? width ?? 378 : width;
|
|
44
|
+
const resolvedHeight = isHorizontal ? height : height ?? 378;
|
|
45
|
+
const isFlush = FULL_SIZES.has(String(isHorizontal ? resolvedWidth : resolvedHeight));
|
|
46
|
+
const surfaceWeightClass = (() => {
|
|
47
|
+
if (isFlush) return void 0;
|
|
48
|
+
if (pushed) return styles.panelRecessed;
|
|
49
|
+
return mask ? void 0 : styles.panelBoosted;
|
|
50
|
+
})();
|
|
51
|
+
const showTitle = title !== void 0 && title !== null;
|
|
52
|
+
const showHeader = !noHeader && (showTitle || closable || !!extra);
|
|
53
|
+
const hasSidebar = !!sidebar;
|
|
54
|
+
const containerStyle = useMemo(() => ({ maxWidth: containerMaxWidth }), [containerMaxWidth]);
|
|
55
|
+
const closeNode = closable && /* @__PURE__ */ jsx("button", {
|
|
56
|
+
"aria-label": "Close",
|
|
57
|
+
className: cx(styles.close, classNames?.close),
|
|
58
|
+
style: semanticStyles?.close,
|
|
59
|
+
type: "button",
|
|
60
|
+
onClick: onClose,
|
|
61
|
+
children: closeIcon ?? /* @__PURE__ */ jsx(X, { size: 16 })
|
|
62
|
+
});
|
|
63
|
+
const extraNode = (extra || closeNode) && /* @__PURE__ */ jsxs("div", {
|
|
64
|
+
className: cx(styles.extra, !showHeader && styles.extraFloating, classNames?.extra),
|
|
65
|
+
style: semanticStyles?.extra,
|
|
66
|
+
children: [extra, closeNode]
|
|
67
|
+
});
|
|
68
|
+
const bodyNode = hasSidebar ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
69
|
+
className: cx(styles.sidebar, classNames?.sidebar),
|
|
70
|
+
style: {
|
|
71
|
+
width: sidebarWidth,
|
|
72
|
+
...semanticStyles?.sidebar
|
|
73
|
+
},
|
|
74
|
+
children: sidebar
|
|
75
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
76
|
+
className: cx(styles.sidebarContent, classNames?.sidebarContent),
|
|
77
|
+
style: semanticStyles?.sidebarContent,
|
|
78
|
+
children
|
|
79
|
+
})] }) : children;
|
|
80
|
+
return /* @__PURE__ */ jsx(DrawerRoot, {
|
|
81
|
+
modal: mask,
|
|
82
|
+
open: isOpen,
|
|
83
|
+
zIndex,
|
|
84
|
+
onExitComplete: handleExitComplete,
|
|
85
|
+
onOpenChange: handleOpenChange,
|
|
86
|
+
children: /* @__PURE__ */ jsxs(DrawerPortal, {
|
|
87
|
+
container: getContainer === false ? void 0 : getContainer ?? void 0,
|
|
88
|
+
children: [mask && /* @__PURE__ */ jsx(DrawerBackdrop, {
|
|
89
|
+
className: classNames?.backdrop,
|
|
90
|
+
style: semanticStyles?.backdrop
|
|
91
|
+
}), /* @__PURE__ */ jsx(DrawerPopup, {
|
|
92
|
+
className: classNames?.popup,
|
|
93
|
+
flush: isFlush,
|
|
94
|
+
height: resolvedHeight,
|
|
95
|
+
motionProps: { onAnimationComplete: handleAnimationComplete },
|
|
96
|
+
panelClassName: cx(surfaceWeightClass, className, classNames?.panel),
|
|
97
|
+
panelStyle: {
|
|
98
|
+
...style,
|
|
99
|
+
...semanticStyles?.panel
|
|
100
|
+
},
|
|
101
|
+
placement,
|
|
102
|
+
popupStyle: semanticStyles?.popup,
|
|
103
|
+
pushOffset,
|
|
104
|
+
width: resolvedWidth,
|
|
105
|
+
children: /* @__PURE__ */ jsxs(DrawerPushProvider, {
|
|
106
|
+
value: childValue,
|
|
107
|
+
children: [
|
|
108
|
+
showHeader ? /* @__PURE__ */ jsx(DrawerHeader, {
|
|
109
|
+
className: classNames?.header,
|
|
110
|
+
style: semanticStyles?.header,
|
|
111
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
112
|
+
className: styles.containerInner,
|
|
113
|
+
style: containerStyle,
|
|
114
|
+
children: [showTitle ? /* @__PURE__ */ jsx(DrawerTitle, {
|
|
115
|
+
className: classNames?.title,
|
|
116
|
+
style: semanticStyles?.title,
|
|
117
|
+
children: title
|
|
118
|
+
}) : /* @__PURE__ */ jsx("span", {}), extraNode]
|
|
119
|
+
})
|
|
120
|
+
}) : extraNode,
|
|
121
|
+
/* @__PURE__ */ jsx(DrawerContent, {
|
|
122
|
+
className: cx(hasSidebar && styles.contentSidebar, classNames?.content),
|
|
123
|
+
style: semanticStyles?.content,
|
|
124
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
125
|
+
style: {
|
|
126
|
+
...containerStyle,
|
|
127
|
+
...semanticStyles?.bodyContent
|
|
128
|
+
},
|
|
129
|
+
className: cx(styles.bodyContent, hasSidebar && styles.bodyContentSidebar, classNames?.bodyContent),
|
|
130
|
+
children: bodyNode
|
|
131
|
+
})
|
|
132
|
+
}),
|
|
133
|
+
footer && /* @__PURE__ */ jsx(DrawerFooter, {
|
|
134
|
+
className: classNames?.footer,
|
|
135
|
+
style: semanticStyles?.footer,
|
|
136
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
137
|
+
className: cx(styles.containerInner, styles.containerInnerFooter),
|
|
138
|
+
style: containerStyle,
|
|
139
|
+
children: footer
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
]
|
|
143
|
+
})
|
|
144
|
+
})]
|
|
145
|
+
})
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
Drawer.displayName = "Drawer";
|
|
149
|
+
//#endregion
|
|
150
|
+
export { Drawer as default };
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=Drawer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Drawer.mjs","names":[],"sources":["../../../src/base-ui/Drawer/Drawer.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { X } from 'lucide-react';\nimport type { CSSProperties } from 'react';\nimport { memo, useCallback, useMemo } from 'react';\n\nimport {\n DrawerBackdrop,\n DrawerContent,\n DrawerFooter,\n DrawerHeader,\n DrawerPopup,\n DrawerPortal,\n DrawerRoot,\n type DrawerRootProps,\n DrawerTitle,\n} from './atoms';\nimport {\n DEFAULT_CONTAINER_MAX_WIDTH,\n DEFAULT_DRAWER_HEIGHT,\n DEFAULT_DRAWER_WIDTH,\n DEFAULT_PUSH_DISTANCE,\n DEFAULT_SIDEBAR_WIDTH,\n} from './constants';\nimport { DrawerPushProvider, useDrawerPush } from './DrawerPushContext';\nimport { styles } from './style';\nimport type { DrawerProps, DrawerPush } from './type';\n\nconst resolvePushDistance = (push: DrawerPush) => {\n if (push === false) return 0;\n if (push === true) return DEFAULT_PUSH_DISTANCE;\n return push.distance ?? DEFAULT_PUSH_DISTANCE;\n};\n\nconst FULL_SIZES = new Set(['100%', '100dvh', '100dvw', '100vh', '100vw']);\n\nconst Drawer = memo<DrawerProps>(\n ({\n open,\n placement = 'right',\n width,\n height,\n mask = true,\n maskClosable = true,\n keyboard = true,\n closable = true,\n closeIcon,\n extra,\n title,\n footer,\n noHeader,\n sidebar,\n sidebarWidth = DEFAULT_SIDEBAR_WIDTH,\n containerMaxWidth = DEFAULT_CONTAINER_MAX_WIDTH,\n push = true,\n zIndex,\n getContainer,\n className,\n classNames,\n style,\n styles: semanticStyles,\n afterOpenChange,\n onClose,\n children,\n }) => {\n const isOpen = open ?? false;\n const { childValue, pushed } = useDrawerPush(isOpen);\n const pushOffset = pushed ? resolvePushDistance(push) : 0;\n\n const handleOpenChange = useCallback<NonNullable<DrawerRootProps['onOpenChange']>>(\n (nextOpen, eventDetails) => {\n if (nextOpen || !isOpen) return;\n if (!keyboard && eventDetails.reason === 'escape-key') return;\n if (!maskClosable && eventDetails.reason === 'outside-press') return;\n onClose?.();\n },\n [isOpen, keyboard, maskClosable, onClose],\n );\n\n const handleExitComplete = useCallback(() => afterOpenChange?.(false), [afterOpenChange]);\n const handleAnimationComplete = useCallback(() => {\n if (isOpen) afterOpenChange?.(true);\n }, [isOpen, afterOpenChange]);\n\n const isHorizontal = placement === 'left' || placement === 'right';\n const resolvedWidth = isHorizontal ? (width ?? DEFAULT_DRAWER_WIDTH) : width;\n const resolvedHeight = isHorizontal ? height : (height ?? DEFAULT_DRAWER_HEIGHT);\n\n const isFlush = FULL_SIZES.has(String(isHorizontal ? resolvedWidth : resolvedHeight));\n const surfaceWeightClass = (() => {\n if (isFlush) return undefined;\n if (pushed) return styles.panelRecessed;\n return mask ? undefined : styles.panelBoosted;\n })();\n\n const showTitle = title !== undefined && title !== null;\n const showHeader = !noHeader && (showTitle || closable || !!extra);\n const hasSidebar = !!sidebar;\n\n const containerStyle = useMemo<CSSProperties>(\n () => ({ maxWidth: containerMaxWidth }),\n [containerMaxWidth],\n );\n\n const closeNode = closable && (\n <button\n aria-label=\"Close\"\n className={cx(styles.close, classNames?.close)}\n style={semanticStyles?.close}\n type=\"button\"\n onClick={onClose}\n >\n {closeIcon ?? <X size={16} />}\n </button>\n );\n\n const extraNode = (extra || closeNode) && (\n <div\n className={cx(styles.extra, !showHeader && styles.extraFloating, classNames?.extra)}\n style={semanticStyles?.extra}\n >\n {extra}\n {closeNode}\n </div>\n );\n\n const bodyNode = hasSidebar ? (\n <>\n <div\n className={cx(styles.sidebar, classNames?.sidebar)}\n style={{ width: sidebarWidth, ...semanticStyles?.sidebar }}\n >\n {sidebar}\n </div>\n <div\n className={cx(styles.sidebarContent, classNames?.sidebarContent)}\n style={semanticStyles?.sidebarContent}\n >\n {children}\n </div>\n </>\n ) : (\n children\n );\n\n const container = getContainer === false ? undefined : (getContainer ?? undefined);\n\n return (\n <DrawerRoot\n modal={mask}\n open={isOpen}\n zIndex={zIndex}\n onExitComplete={handleExitComplete}\n onOpenChange={handleOpenChange}\n >\n <DrawerPortal container={container}>\n {mask && (\n <DrawerBackdrop className={classNames?.backdrop} style={semanticStyles?.backdrop} />\n )}\n <DrawerPopup\n className={classNames?.popup}\n flush={isFlush}\n height={resolvedHeight}\n motionProps={{ onAnimationComplete: handleAnimationComplete }}\n panelClassName={cx(surfaceWeightClass, className, classNames?.panel)}\n panelStyle={{ ...style, ...semanticStyles?.panel }}\n placement={placement}\n popupStyle={semanticStyles?.popup}\n pushOffset={pushOffset}\n width={resolvedWidth}\n >\n <DrawerPushProvider value={childValue}>\n {showHeader ? (\n <DrawerHeader className={classNames?.header} style={semanticStyles?.header}>\n <div className={styles.containerInner} style={containerStyle}>\n {showTitle ? (\n <DrawerTitle className={classNames?.title} style={semanticStyles?.title}>\n {title}\n </DrawerTitle>\n ) : (\n <span />\n )}\n {extraNode}\n </div>\n </DrawerHeader>\n ) : (\n extraNode\n )}\n <DrawerContent\n className={cx(hasSidebar && styles.contentSidebar, classNames?.content)}\n style={semanticStyles?.content}\n >\n <div\n style={{ ...containerStyle, ...semanticStyles?.bodyContent }}\n className={cx(\n styles.bodyContent,\n hasSidebar && styles.bodyContentSidebar,\n classNames?.bodyContent,\n )}\n >\n {bodyNode}\n </div>\n </DrawerContent>\n {footer && (\n <DrawerFooter className={classNames?.footer} style={semanticStyles?.footer}>\n <div\n className={cx(styles.containerInner, styles.containerInnerFooter)}\n style={containerStyle}\n >\n {footer}\n </div>\n </DrawerFooter>\n )}\n </DrawerPushProvider>\n </DrawerPopup>\n </DrawerPortal>\n </DrawerRoot>\n );\n },\n);\n\nDrawer.displayName = 'Drawer';\n\nexport default Drawer;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, use } from "react";
|
|
3
|
+
//#region src/base-ui/Drawer/DrawerLayerContext.tsx
|
|
4
|
+
const DrawerLayerContext = createContext(null);
|
|
5
|
+
const useDrawerLayer = () => use(DrawerLayerContext);
|
|
6
|
+
const DrawerLayerProvider = DrawerLayerContext.Provider;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { DrawerLayerProvider, useDrawerLayer };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=DrawerLayerContext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DrawerLayerContext.mjs","names":[],"sources":["../../../src/base-ui/Drawer/DrawerLayerContext.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, use } from 'react';\n\nexport interface DrawerLayer {\n popupRef: (node: HTMLElement | null) => void;\n zIndex: number | undefined;\n}\n\nconst DrawerLayerContext = createContext<DrawerLayer | null>(null);\n\nexport const useDrawerLayer = () => use(DrawerLayerContext);\nexport const DrawerLayerProvider = DrawerLayerContext.Provider;\n"],"mappings":";;;AASA,MAAM,qBAAqB,cAAkC,IAAI;AAEjE,MAAa,uBAAuB,IAAI,kBAAkB;AAC1D,MAAa,sBAAsB,mBAAmB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, use, useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
+
//#region src/base-ui/Drawer/DrawerPushContext.tsx
|
|
4
|
+
const DrawerPushContext = createContext(null);
|
|
5
|
+
const DrawerPushProvider = DrawerPushContext.Provider;
|
|
6
|
+
const useDrawerPush = (open) => {
|
|
7
|
+
const parent = use(DrawerPushContext);
|
|
8
|
+
const [pushedCount, setPushedCount] = useState(0);
|
|
9
|
+
const push = useCallback(() => setPushedCount((count) => count + 1), []);
|
|
10
|
+
const pull = useCallback(() => setPushedCount((count) => Math.max(0, count - 1)), []);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!open || !parent) return;
|
|
13
|
+
parent.push();
|
|
14
|
+
return () => parent.pull();
|
|
15
|
+
}, [open, parent]);
|
|
16
|
+
return {
|
|
17
|
+
childValue: useMemo(() => ({
|
|
18
|
+
pull,
|
|
19
|
+
push
|
|
20
|
+
}), [pull, push]),
|
|
21
|
+
pushed: pushedCount > 0
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { DrawerPushProvider, useDrawerPush };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=DrawerPushContext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DrawerPushContext.mjs","names":[],"sources":["../../../src/base-ui/Drawer/DrawerPushContext.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, use, useCallback, useEffect, useMemo, useState } from 'react';\n\nexport interface DrawerPushParent {\n pull: () => void;\n push: () => void;\n}\n\nconst DrawerPushContext = createContext<DrawerPushParent | null>(null);\n\nexport const DrawerPushProvider = DrawerPushContext.Provider;\n\nexport const useDrawerPush = (open: boolean) => {\n const parent = use(DrawerPushContext);\n const [pushedCount, setPushedCount] = useState(0);\n\n const push = useCallback(() => setPushedCount((count) => count + 1), []);\n const pull = useCallback(() => setPushedCount((count) => Math.max(0, count - 1)), []);\n\n useEffect(() => {\n if (!open || !parent) return;\n parent.push();\n return () => parent.pull();\n }, [open, parent]);\n\n const childValue = useMemo<DrawerPushParent>(() => ({ pull, push }), [pull, push]);\n\n return { childValue, pushed: pushedCount > 0 };\n};\n"],"mappings":";;;AASA,MAAM,oBAAoB,cAAuC,IAAI;AAErE,MAAa,qBAAqB,kBAAkB;AAEpD,MAAa,iBAAiB,SAAkB;CAC9C,MAAM,SAAS,IAAI,iBAAiB;CACpC,MAAM,CAAC,aAAa,kBAAkB,SAAS,CAAC;CAEhD,MAAM,OAAO,kBAAkB,gBAAgB,UAAU,QAAQ,CAAC,GAAG,CAAC,CAAC;CACvE,MAAM,OAAO,kBAAkB,gBAAgB,UAAU,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;CAEpF,gBAAgB;EACd,IAAI,CAAC,QAAQ,CAAC,QAAQ;EACtB,OAAO,KAAK;EACZ,aAAa,OAAO,KAAK;CAC3B,GAAG,CAAC,MAAM,MAAM,CAAC;CAIjB,OAAO;EAAE,YAFU,eAAiC;GAAE;GAAM;EAAK,IAAI,CAAC,MAAM,IAAI,CAE9D;EAAG,QAAQ,cAAc;CAAE;AAC/C"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { DrawerPlacement } from "./type.mjs";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Dialog } from "@base-ui/react/dialog";
|
|
4
|
+
//#region src/base-ui/Drawer/atoms.d.ts
|
|
5
|
+
interface DrawerAnimationActions {
|
|
6
|
+
onExitComplete: () => void;
|
|
7
|
+
}
|
|
8
|
+
declare const useDrawerOpen: () => boolean | null;
|
|
9
|
+
declare const useDrawerActions: () => DrawerAnimationActions | null;
|
|
10
|
+
type DrawerRootProps = Dialog.Root.Props & {
|
|
11
|
+
onExitComplete?: () => void;
|
|
12
|
+
zIndex?: number;
|
|
13
|
+
};
|
|
14
|
+
declare const DrawerRoot: ({ open, onExitComplete, ...rest }: DrawerRootProps) => React.JSX.Element;
|
|
15
|
+
type DrawerPortalProps = React.ComponentProps<typeof Dialog.Portal> & {
|
|
16
|
+
container?: HTMLElement | null;
|
|
17
|
+
};
|
|
18
|
+
declare const DrawerPortal: ({ container, ...rest }: DrawerPortalProps) => React.JSX.Element;
|
|
19
|
+
type DrawerBackdropProps = React.ComponentProps<typeof Dialog.Backdrop>;
|
|
20
|
+
declare const DrawerBackdrop: ({ className, style, ...rest }: DrawerBackdropProps) => React.JSX.Element;
|
|
21
|
+
type DrawerPopupProps = React.ComponentProps<typeof Dialog.Popup> & {
|
|
22
|
+
flush?: boolean;
|
|
23
|
+
height?: number | string;
|
|
24
|
+
motionProps?: Record<string, any>;
|
|
25
|
+
panelClassName?: string;
|
|
26
|
+
panelStyle?: React.CSSProperties;
|
|
27
|
+
placement?: DrawerPlacement;
|
|
28
|
+
popupStyle?: React.CSSProperties;
|
|
29
|
+
pushOffset?: number;
|
|
30
|
+
width?: number | string;
|
|
31
|
+
};
|
|
32
|
+
declare const DrawerPopup: ({ className, children, placement: placementProp, width: widthProp, height: heightProp, flush, pushOffset, motionProps, panelClassName, panelStyle, popupStyle, ref: forwardedRef, ...rest }: DrawerPopupProps) => React.JSX.Element;
|
|
33
|
+
type DrawerHeaderProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
34
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
35
|
+
};
|
|
36
|
+
declare const DrawerHeader: ({ className, ...rest }: DrawerHeaderProps) => React.JSX.Element;
|
|
37
|
+
type DrawerTitleProps = React.ComponentProps<typeof Dialog.Title>;
|
|
38
|
+
declare const DrawerTitle: ({ className, ...rest }: DrawerTitleProps) => React.JSX.Element;
|
|
39
|
+
type DrawerDescriptionProps = React.ComponentProps<typeof Dialog.Description>;
|
|
40
|
+
declare const DrawerDescription: React.FC<DrawerDescriptionProps>;
|
|
41
|
+
type DrawerContentProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
42
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
43
|
+
};
|
|
44
|
+
declare const DrawerContent: ({ className, ...rest }: DrawerContentProps) => React.JSX.Element;
|
|
45
|
+
type DrawerFooterProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
46
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
47
|
+
};
|
|
48
|
+
declare const DrawerFooter: ({ className, ...rest }: DrawerFooterProps) => React.JSX.Element;
|
|
49
|
+
type DrawerCloseProps = React.ComponentProps<typeof Dialog.Close>;
|
|
50
|
+
declare const DrawerClose: ({ className, children, ...rest }: DrawerCloseProps) => React.JSX.Element;
|
|
51
|
+
type DrawerTriggerProps = Omit<React.ComponentPropsWithRef<typeof Dialog.Trigger>, 'children' | 'render'> & {
|
|
52
|
+
children?: React.ReactNode;
|
|
53
|
+
nativeButton?: boolean;
|
|
54
|
+
};
|
|
55
|
+
declare const DrawerTrigger: ({ children, className, nativeButton, ref: refProp, ...rest }: DrawerTriggerProps) => React.JSX.Element;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { DrawerBackdrop, DrawerBackdropProps, DrawerClose, DrawerCloseProps, DrawerContent, DrawerContentProps, DrawerDescription, DrawerDescriptionProps, DrawerFooter, DrawerFooterProps, DrawerHeader, DrawerHeaderProps, DrawerPopup, DrawerPopupProps, DrawerPortal, DrawerPortalProps, DrawerRoot, DrawerRootProps, DrawerTitle, DrawerTitleProps, DrawerTrigger, DrawerTriggerProps, useDrawerActions, useDrawerOpen };
|
|
58
|
+
//# sourceMappingURL=atoms.d.mts.map
|