@lobehub/editor 4.18.0 → 4.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/plugins/slash/react/components/DefaultSlashMenu.js +111 -53
- package/es/plugins/slash/react/type.d.ts +5 -2
- package/es/react/ChatInput/ChatInput.js +1 -1
- package/es/react/ChatInput/type.d.ts +5 -0
- package/es/react.d.ts +1 -5
- package/es/react.js +1 -3
- package/package.json +1 -1
- package/es/react/FloatMenu/FloatMenu.d.ts +0 -7
- package/es/react/FloatMenu/FloatMenu.js +0 -32
- package/es/react/FloatMenu/index.d.ts +0 -2
- package/es/react/FloatMenu/style.js +0 -28
- package/es/react/FloatMenu/type.d.ts +0 -25
- package/es/react/SlashMenu/SlashMenu.d.ts +0 -7
- package/es/react/SlashMenu/SlashMenu.js +0 -40
- package/es/react/SlashMenu/index.d.ts +0 -2
- package/es/react/SlashMenu/type.d.ts +0 -17
|
@@ -4,7 +4,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { createStaticStyles } from "antd-style";
|
|
6
6
|
import { createPortal } from "react-dom";
|
|
7
|
-
import { flip, offset, shift, useFloating } from "@floating-ui/react";
|
|
7
|
+
import { autoUpdate, flip, offset, shift, size, useFloating } from "@floating-ui/react";
|
|
8
8
|
//#region src/plugins/slash/react/components/DefaultSlashMenu.tsx
|
|
9
9
|
const LOBE_THEME_APP_ID$1 = "lobe-ui-theme-app";
|
|
10
10
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
@@ -13,7 +13,6 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
13
13
|
|
|
14
14
|
overflow-y: auto;
|
|
15
15
|
|
|
16
|
-
min-width: 200px;
|
|
17
16
|
max-height: min(50vh, 400px);
|
|
18
17
|
padding: 4px;
|
|
19
18
|
border-radius: ${cssVar.borderRadius};
|
|
@@ -24,14 +23,92 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
24
23
|
0 0 15px 0 #00000008,
|
|
25
24
|
0 2px 30px 0 #00000014,
|
|
26
25
|
0 0 0 1px ${cssVar.colorBorder} inset;
|
|
26
|
+
`,
|
|
27
|
+
popupCaret: css`
|
|
28
|
+
width: max-content;
|
|
29
|
+
min-width: 200px;
|
|
27
30
|
`,
|
|
28
31
|
root: css`
|
|
29
32
|
z-index: 1100;
|
|
30
|
-
width: max-content;
|
|
31
33
|
`
|
|
32
34
|
}));
|
|
33
35
|
const isDividerOption = (option) => "type" in option && option.type === "divider";
|
|
34
|
-
const
|
|
36
|
+
const renderItems = (options, activeKey, loading, onSelect) => {
|
|
37
|
+
if (loading) return /* @__PURE__ */ jsx("div", {
|
|
38
|
+
className: menuSharedStyles.empty,
|
|
39
|
+
children: "Loading..."
|
|
40
|
+
});
|
|
41
|
+
return options.map((opt, index) => {
|
|
42
|
+
if (isDividerOption(opt)) return /* @__PURE__ */ jsx("div", { className: menuSharedStyles.separator }, `__divider_${index}`);
|
|
43
|
+
const item = opt;
|
|
44
|
+
const isHighlighted = item.key === activeKey;
|
|
45
|
+
const isDisabled = Boolean(item.disabled);
|
|
46
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
47
|
+
"aria-disabled": isDisabled || void 0,
|
|
48
|
+
className: menuSharedStyles.item,
|
|
49
|
+
"data-disabled": isDisabled ? "" : void 0,
|
|
50
|
+
"data-highlighted": isHighlighted ? "" : void 0,
|
|
51
|
+
onClick: () => {
|
|
52
|
+
if (isDisabled) return;
|
|
53
|
+
onSelect(item);
|
|
54
|
+
},
|
|
55
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
56
|
+
role: "menuitem",
|
|
57
|
+
children: [
|
|
58
|
+
item.icon ? /* @__PURE__ */ jsx("span", {
|
|
59
|
+
className: menuSharedStyles.icon,
|
|
60
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: item.icon })
|
|
61
|
+
}) : null,
|
|
62
|
+
/* @__PURE__ */ jsx("span", {
|
|
63
|
+
className: menuSharedStyles.label,
|
|
64
|
+
children: item.label
|
|
65
|
+
}),
|
|
66
|
+
item.extra ? /* @__PURE__ */ jsx("span", {
|
|
67
|
+
className: menuSharedStyles.extra,
|
|
68
|
+
children: item.extra
|
|
69
|
+
}) : null
|
|
70
|
+
]
|
|
71
|
+
}, String(item.key));
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const resolvePortalContainer = () => {
|
|
75
|
+
if (typeof document === "undefined") return null;
|
|
76
|
+
return document.getElementById(LOBE_THEME_APP_ID$1) ?? document.body;
|
|
77
|
+
};
|
|
78
|
+
const FullWidthSlashMenu = ({ activeKey, anchor, loading, onSelect, open, options, placement }) => {
|
|
79
|
+
const resolvedPlacement = placement === "bottom" ? "bottom-start" : "top-start";
|
|
80
|
+
const { refs, floatingStyles, isPositioned } = useFloating({
|
|
81
|
+
elements: { reference: anchor },
|
|
82
|
+
middleware: [
|
|
83
|
+
offset(8),
|
|
84
|
+
size({ apply({ rects, elements }) {
|
|
85
|
+
elements.floating.style.width = `${rects.reference.width}px`;
|
|
86
|
+
} }),
|
|
87
|
+
flip({ fallbackPlacements: placement === "bottom" ? ["top-start"] : ["bottom-start"] }),
|
|
88
|
+
shift({ padding: 8 })
|
|
89
|
+
],
|
|
90
|
+
open,
|
|
91
|
+
placement: resolvedPlacement,
|
|
92
|
+
strategy: "fixed",
|
|
93
|
+
whileElementsMounted: autoUpdate
|
|
94
|
+
});
|
|
95
|
+
const portalContainer = resolvePortalContainer();
|
|
96
|
+
if (!portalContainer) return null;
|
|
97
|
+
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
98
|
+
className: styles.root,
|
|
99
|
+
"data-resolved-placement": resolvedPlacement,
|
|
100
|
+
ref: refs.setFloating,
|
|
101
|
+
style: {
|
|
102
|
+
...floatingStyles,
|
|
103
|
+
visibility: isPositioned ? "visible" : "hidden"
|
|
104
|
+
},
|
|
105
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
106
|
+
className: styles.popup,
|
|
107
|
+
children: renderItems(options, activeKey, loading, onSelect)
|
|
108
|
+
})
|
|
109
|
+
}), portalContainer);
|
|
110
|
+
};
|
|
111
|
+
const CaretSlashMenu = ({ activeKey, loading, onSelect, open, options, placement: forcePlacement, position }) => {
|
|
35
112
|
const resolvedPlacement = forcePlacement ? `${forcePlacement}-start` : "top-start";
|
|
36
113
|
const middleware = useMemo(() => [
|
|
37
114
|
offset(8),
|
|
@@ -62,62 +139,19 @@ const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, ope
|
|
|
62
139
|
useEffect(() => {
|
|
63
140
|
if (!open) return;
|
|
64
141
|
const onScroll = () => update();
|
|
65
|
-
const container = getPopupContainer?.();
|
|
66
142
|
window.addEventListener("scroll", onScroll, {
|
|
67
143
|
capture: true,
|
|
68
144
|
passive: true
|
|
69
145
|
});
|
|
70
|
-
if (container) container.addEventListener("scroll", onScroll, { passive: true });
|
|
71
146
|
return () => {
|
|
72
147
|
window.removeEventListener("scroll", onScroll, { capture: true });
|
|
73
|
-
if (container) container.removeEventListener("scroll", onScroll);
|
|
74
148
|
};
|
|
75
|
-
}, [
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
update
|
|
79
|
-
]);
|
|
80
|
-
const hasVisibleItems = options?.some((item) => !isDividerOption(item));
|
|
81
|
-
if (!open || !hasVisibleItems) return null;
|
|
82
|
-
const portalContainer = getPopupContainer?.() || document.getElementById(LOBE_THEME_APP_ID$1) || document.body;
|
|
83
|
-
const renderedItems = loading ? /* @__PURE__ */ jsx("div", {
|
|
84
|
-
className: menuSharedStyles.empty,
|
|
85
|
-
children: "Loading..."
|
|
86
|
-
}) : options.map((opt, index) => {
|
|
87
|
-
if (isDividerOption(opt)) return /* @__PURE__ */ jsx("div", { className: menuSharedStyles.separator }, `__divider_${index}`);
|
|
88
|
-
const item = opt;
|
|
89
|
-
const isHighlighted = item.key === activeKey;
|
|
90
|
-
const isDisabled = Boolean(item.disabled);
|
|
91
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
92
|
-
"aria-disabled": isDisabled || void 0,
|
|
93
|
-
className: menuSharedStyles.item,
|
|
94
|
-
"data-disabled": isDisabled ? "" : void 0,
|
|
95
|
-
"data-highlighted": isHighlighted ? "" : void 0,
|
|
96
|
-
onClick: () => {
|
|
97
|
-
if (isDisabled) return;
|
|
98
|
-
onSelect(item);
|
|
99
|
-
},
|
|
100
|
-
onMouseDown: (event) => event.preventDefault(),
|
|
101
|
-
role: "menuitem",
|
|
102
|
-
children: [
|
|
103
|
-
item.icon ? /* @__PURE__ */ jsx("span", {
|
|
104
|
-
className: menuSharedStyles.icon,
|
|
105
|
-
children: /* @__PURE__ */ jsx(Icon, { icon: item.icon })
|
|
106
|
-
}) : null,
|
|
107
|
-
/* @__PURE__ */ jsx("span", {
|
|
108
|
-
className: menuSharedStyles.label,
|
|
109
|
-
children: item.label
|
|
110
|
-
}),
|
|
111
|
-
item.extra ? /* @__PURE__ */ jsx("span", {
|
|
112
|
-
className: menuSharedStyles.extra,
|
|
113
|
-
children: item.extra
|
|
114
|
-
}) : null
|
|
115
|
-
]
|
|
116
|
-
}, String(item.key));
|
|
117
|
-
});
|
|
149
|
+
}, [open, update]);
|
|
150
|
+
const portalContainer = resolvePortalContainer();
|
|
151
|
+
if (!portalContainer) return null;
|
|
118
152
|
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
119
|
-
className: styles.root
|
|
120
|
-
"data-
|
|
153
|
+
className: `${styles.root} ${styles.popupCaret}`,
|
|
154
|
+
"data-resolved-placement": resolvedPlacement,
|
|
121
155
|
ref: refs.setFloating,
|
|
122
156
|
style: {
|
|
123
157
|
...floatingStyles,
|
|
@@ -125,10 +159,34 @@ const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, ope
|
|
|
125
159
|
},
|
|
126
160
|
children: /* @__PURE__ */ jsx("div", {
|
|
127
161
|
className: styles.popup,
|
|
128
|
-
children:
|
|
162
|
+
children: renderItems(options, activeKey, loading, onSelect)
|
|
129
163
|
})
|
|
130
164
|
}), portalContainer);
|
|
131
165
|
};
|
|
166
|
+
const DefaultSlashMenu = ({ activeKey, getPopupContainer, loading, onSelect, open, options, placement, position }) => {
|
|
167
|
+
const hasVisibleItems = options?.some((item) => !isDividerOption(item));
|
|
168
|
+
if (!open || !hasVisibleItems) return null;
|
|
169
|
+
const anchor = getPopupContainer?.() ?? null;
|
|
170
|
+
if (anchor) return /* @__PURE__ */ jsx(FullWidthSlashMenu, {
|
|
171
|
+
activeKey,
|
|
172
|
+
anchor,
|
|
173
|
+
loading,
|
|
174
|
+
onSelect,
|
|
175
|
+
open,
|
|
176
|
+
options,
|
|
177
|
+
placement: placement ?? "top"
|
|
178
|
+
});
|
|
179
|
+
if (!position) return null;
|
|
180
|
+
return /* @__PURE__ */ jsx(CaretSlashMenu, {
|
|
181
|
+
activeKey,
|
|
182
|
+
loading,
|
|
183
|
+
onSelect,
|
|
184
|
+
open,
|
|
185
|
+
options,
|
|
186
|
+
placement,
|
|
187
|
+
position
|
|
188
|
+
});
|
|
189
|
+
};
|
|
132
190
|
DefaultSlashMenu.displayName = "DefaultSlashMenu";
|
|
133
191
|
//#endregion
|
|
134
192
|
export { DefaultSlashMenu as default };
|
|
@@ -94,8 +94,11 @@ interface SlashMenuProps {
|
|
|
94
94
|
options: Array<ISlashOption>;
|
|
95
95
|
/** Force menu placement direction, skipping auto-flip detection */
|
|
96
96
|
placement?: 'bottom' | 'top';
|
|
97
|
-
/**
|
|
98
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Caret position used by the floating fallback when no getPopupContainer
|
|
99
|
+
* is provided. Ignored in full-width mode.
|
|
100
|
+
*/
|
|
101
|
+
position?: {
|
|
99
102
|
getRect?: () => DOMRect;
|
|
100
103
|
rect?: DOMRect;
|
|
101
104
|
x: number;
|
|
@@ -38,11 +38,11 @@ const ChatInput = (props) => {
|
|
|
38
38
|
return /* @__PURE__ */ jsxs(Flexbox, {
|
|
39
39
|
className: cx(isDarkMode ? styles.containerDark : styles.containerLight, styles.root, className),
|
|
40
40
|
height: fullscreen ? "100%" : void 0,
|
|
41
|
+
ref: slashMenuRef,
|
|
41
42
|
style,
|
|
42
43
|
width: "100%",
|
|
43
44
|
...rest,
|
|
44
45
|
children: [
|
|
45
|
-
slashMenuRef && /* @__PURE__ */ jsx("div", { ref: slashMenuRef }),
|
|
46
46
|
/* @__PURE__ */ jsx("div", {
|
|
47
47
|
className: cx(styles.header, classNames?.header),
|
|
48
48
|
ref: headerRef,
|
|
@@ -21,6 +21,11 @@ interface ChatInputProps extends Omit<FlexboxProps, 'height'> {
|
|
|
21
21
|
resize?: boolean;
|
|
22
22
|
resizeMaxHeightOffset?: number;
|
|
23
23
|
showResizeHandle?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Ref attached to the ChatInput root element. Pass the same ref to
|
|
26
|
+
* `<Editor getPopupContainer={() => ref.current}>` to anchor the slash /
|
|
27
|
+
* mention menu to the ChatInput's outer edges (full-width).
|
|
28
|
+
*/
|
|
24
29
|
slashMenuRef?: Ref<HTMLDivElement>;
|
|
25
30
|
styles?: {
|
|
26
31
|
body?: CSSProperties;
|
package/es/react.d.ts
CHANGED
|
@@ -15,10 +15,6 @@ import { Editor } from "./react/Editor/index.js";
|
|
|
15
15
|
import { EditorProvider, EditorProviderConfig, EditorProviderProps, useEditorContent } from "./react/EditorProvider/index.js";
|
|
16
16
|
import { FloatActionsProps } from "./react/FloatActions/type.js";
|
|
17
17
|
import { FloatActions } from "./react/FloatActions/FloatActions.js";
|
|
18
|
-
import { FloatMenuProps } from "./react/FloatMenu/type.js";
|
|
19
|
-
import { FloatMenu } from "./react/FloatMenu/FloatMenu.js";
|
|
20
18
|
import { SendButtonProps } from "./react/SendButton/type.js";
|
|
21
19
|
import { SendButton } from "./react/SendButton/SendButton.js";
|
|
22
|
-
|
|
23
|
-
import { SlashMenu } from "./react/SlashMenu/SlashMenu.js";
|
|
24
|
-
export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, type ChatInputActionBarProps, type ChatInputActionEvent, ChatInputActions, type ChatInputActionsProps, type ChatInputProps, CodeLanguageSelect, type CodeLanguageSelectProps, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, type EditorProps, EditorProvider, type EditorProviderConfig, type EditorProviderProps, type EditorState, FloatActions, type FloatActionsProps, FloatMenu, type FloatMenuProps, SendButton, type SendButtonProps, SlashMenu, type SlashMenuProps, useEditor, useEditorContent, useEditorState, withProps };
|
|
20
|
+
export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, type ChatInputActionBarProps, type ChatInputActionEvent, ChatInputActions, type ChatInputActionsProps, type ChatInputProps, CodeLanguageSelect, type CodeLanguageSelectProps, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, type EditorProps, EditorProvider, type EditorProviderConfig, type EditorProviderProps, type EditorState, FloatActions, type FloatActionsProps, SendButton, type SendButtonProps, useEditor, useEditorContent, useEditorState, withProps };
|
package/es/react.js
CHANGED
|
@@ -9,7 +9,5 @@ import { EditorProvider, useEditorContent } from "./react/EditorProvider/index.j
|
|
|
9
9
|
import { withProps } from "./react/Editor/utils.js";
|
|
10
10
|
import Editor from "./react/Editor/index.js";
|
|
11
11
|
import FloatActions from "./react/FloatActions/FloatActions.js";
|
|
12
|
-
import FloatMenu from "./react/FloatMenu/FloatMenu.js";
|
|
13
12
|
import SendButton from "./react/SendButton/SendButton.js";
|
|
14
|
-
|
|
15
|
-
export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, ChatInputActions, CodeLanguageSelect, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, EditorProvider, FloatActions, FloatMenu, SendButton, SlashMenu, useEditor, useEditorContent, useEditorState, withProps };
|
|
13
|
+
export { ANCHOR_PADDING_CSS_VAR, ChatInput, ChatInputActionBar, ChatInputActions, CodeLanguageSelect, DEFAULT_BLOCK_ANCHOR_PADDING, Editor, EditorProvider, FloatActions, SendButton, useEditor, useEditorContent, useEditorState, withProps };
|
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { styles } from "./style.js";
|
|
3
|
-
import { Block, Flexbox } from "@lobehub/ui";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
import { cx } from "antd-style";
|
|
6
|
-
import { createPortal } from "react-dom";
|
|
7
|
-
//#region src/react/FloatMenu/FloatMenu.tsx
|
|
8
|
-
const FloatMenu = ({ className, style, getPopupContainer, children, maxHeight = "min(50vh, 640px)", open, placement = "top", styles: customStyles, classNames }) => {
|
|
9
|
-
const parent = getPopupContainer();
|
|
10
|
-
if (!parent) return;
|
|
11
|
-
if (!open) return;
|
|
12
|
-
return createPortal(/* @__PURE__ */ jsx(Flexbox, {
|
|
13
|
-
className: cx(placement === "bottom" ? styles.rootBottom : styles.rootTop, classNames?.root),
|
|
14
|
-
paddingInline: 8,
|
|
15
|
-
style: customStyles?.root,
|
|
16
|
-
width: "100%",
|
|
17
|
-
children: /* @__PURE__ */ jsx(Block, {
|
|
18
|
-
className: cx(styles.container, className, classNames?.container),
|
|
19
|
-
shadow: true,
|
|
20
|
-
style: {
|
|
21
|
-
maxHeight,
|
|
22
|
-
...style,
|
|
23
|
-
...customStyles?.container
|
|
24
|
-
},
|
|
25
|
-
variant: "outlined",
|
|
26
|
-
children
|
|
27
|
-
})
|
|
28
|
-
}), parent);
|
|
29
|
-
};
|
|
30
|
-
FloatMenu.displayName = "FloatMenu";
|
|
31
|
-
//#endregion
|
|
32
|
-
export { FloatMenu as default };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { createStaticStyles } from "antd-style";
|
|
2
|
-
//#region src/react/FloatMenu/style.ts
|
|
3
|
-
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
4
|
-
container: css`
|
|
5
|
-
position: relative;
|
|
6
|
-
overflow: hidden auto;
|
|
7
|
-
background: ${cssVar.colorBgElevated};
|
|
8
|
-
`,
|
|
9
|
-
containerWithMaxHeight: css`
|
|
10
|
-
/* maxHeight is set via inline style as it's dynamic */
|
|
11
|
-
`,
|
|
12
|
-
rootBottom: css`
|
|
13
|
-
position: absolute;
|
|
14
|
-
z-index: 9999;
|
|
15
|
-
inset-block-start: 100%;
|
|
16
|
-
inset-inline-start: 0;
|
|
17
|
-
|
|
18
|
-
padding-block-start: 8px;
|
|
19
|
-
`,
|
|
20
|
-
rootTop: css`
|
|
21
|
-
position: absolute;
|
|
22
|
-
inset-block-start: -8px;
|
|
23
|
-
inset-inline-start: 0;
|
|
24
|
-
transform: translateY(-100%);
|
|
25
|
-
`
|
|
26
|
-
}));
|
|
27
|
-
//#endregion
|
|
28
|
-
export { styles };
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { BlockProps } from "@lobehub/ui";
|
|
2
|
-
import { CSSProperties, ReactNode } from "react";
|
|
3
|
-
|
|
4
|
-
//#region src/react/FloatMenu/type.d.ts
|
|
5
|
-
interface FloatMenuProps {
|
|
6
|
-
children?: ReactNode;
|
|
7
|
-
className?: string;
|
|
8
|
-
classNames?: {
|
|
9
|
-
container?: string;
|
|
10
|
-
root?: string;
|
|
11
|
-
};
|
|
12
|
-
containerProps?: Omit<BlockProps, 'children'>;
|
|
13
|
-
getPopupContainer: () => HTMLDivElement | null;
|
|
14
|
-
maxHeight?: string | number;
|
|
15
|
-
open?: boolean;
|
|
16
|
-
/** Menu placement direction: 'top' (default) or 'bottom' */
|
|
17
|
-
placement?: 'bottom' | 'top';
|
|
18
|
-
style?: CSSProperties;
|
|
19
|
-
styles?: {
|
|
20
|
-
container?: CSSProperties;
|
|
21
|
-
root?: CSSProperties;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
//#endregion
|
|
25
|
-
export { FloatMenuProps };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import FloatMenu from "../FloatMenu/FloatMenu.js";
|
|
3
|
-
import { Menu } from "@lobehub/ui";
|
|
4
|
-
import { useCallback } from "react";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
|
-
//#region src/react/SlashMenu/SlashMenu.tsx
|
|
7
|
-
const SlashMenu = ({ options, activeKey, loading, onSelect, classNames, styles: customStyles, menuProps, ...floatMenuProps }) => {
|
|
8
|
-
const handleMenuClick = useCallback(({ key }) => {
|
|
9
|
-
if (!onSelect) return;
|
|
10
|
-
const option = options.find((item) => "key" in item && item.key === key);
|
|
11
|
-
if (option) onSelect?.(option);
|
|
12
|
-
}, [options, onSelect]);
|
|
13
|
-
return /* @__PURE__ */ jsx(FloatMenu, {
|
|
14
|
-
classNames: {
|
|
15
|
-
container: classNames?.container,
|
|
16
|
-
root: classNames?.root
|
|
17
|
-
},
|
|
18
|
-
styles: {
|
|
19
|
-
container: customStyles?.container,
|
|
20
|
-
root: customStyles?.root
|
|
21
|
-
},
|
|
22
|
-
...floatMenuProps,
|
|
23
|
-
children: /* @__PURE__ */ jsx(Menu, {
|
|
24
|
-
className: classNames?.menu,
|
|
25
|
-
items: loading ? [{
|
|
26
|
-
disabled: true,
|
|
27
|
-
key: "loading",
|
|
28
|
-
label: "Loading..."
|
|
29
|
-
}] : options,
|
|
30
|
-
mode: "inline",
|
|
31
|
-
onClick: handleMenuClick,
|
|
32
|
-
selectedKeys: activeKey ? [activeKey] : void 0,
|
|
33
|
-
style: customStyles?.menu,
|
|
34
|
-
...menuProps
|
|
35
|
-
})
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
SlashMenu.displayName = "SlashMenu";
|
|
39
|
-
//#endregion
|
|
40
|
-
export { SlashMenu as default };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { MenuRenderProps } from "../../plugins/slash/react/type.js";
|
|
2
|
-
import { FloatMenuProps } from "../FloatMenu/type.js";
|
|
3
|
-
import { MenuProps } from "@lobehub/ui";
|
|
4
|
-
import { CSSProperties } from "react";
|
|
5
|
-
|
|
6
|
-
//#region src/react/SlashMenu/type.d.ts
|
|
7
|
-
interface SlashMenuProps extends MenuRenderProps, Omit<FloatMenuProps, 'children'> {
|
|
8
|
-
classNames?: FloatMenuProps['classNames'] & {
|
|
9
|
-
menu?: string;
|
|
10
|
-
};
|
|
11
|
-
menuProps?: MenuProps;
|
|
12
|
-
styles?: FloatMenuProps['styles'] & {
|
|
13
|
-
menu?: CSSProperties;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
export { SlashMenuProps };
|