@choice-ui/react 1.9.9 → 2.0.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/dist/components/button/dist/index.d.ts +2 -9
- package/dist/components/button/dist/index.js +38 -19
- package/dist/components/code-block/dist/index.d.ts +11 -14
- package/dist/components/code-block/dist/index.js +120 -93
- package/dist/components/command/dist/index.d.ts +0 -13
- package/dist/components/emoji-picker/dist/index.d.ts +1 -0
- package/dist/components/emoji-picker/dist/index.js +4 -2
- package/dist/components/md-render/dist/index.d.ts +2 -1
- package/dist/components/md-render/dist/index.js +5 -9
- package/dist/components/md-render/src/components/markdown-block.d.ts +3 -0
- package/dist/components/modal/dist/index.js +2 -2
- package/dist/components/notifications/dist/index.d.ts +1 -5
- package/dist/components/numeric-input/dist/index.d.ts +25 -10
- package/dist/components/numeric-input/dist/index.js +68 -10
- package/dist/components/panel/dist/index.d.ts +16 -16
- package/dist/components/picture-preview/dist/index.d.ts +5 -0
- package/dist/components/picture-preview/dist/index.js +287 -140
- package/dist/components/popover/dist/index.d.ts +5 -0
- package/dist/components/popover/dist/index.js +21 -2
- package/dist/components/separator/dist/index.d.ts +1 -8
- package/dist/components/splitter/dist/index.d.ts +1 -1
- package/dist/components/text-field/dist/index.d.ts +2 -3
- package/dist/components/text-field/dist/index.js +4 -19
- package/dist/components/toast/dist/index.d.ts +274 -0
- package/package.json +33 -21
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
import { HTMLProps } from 'react';
|
|
2
|
-
import { TooltipProps } from '../../tooltip/src';
|
|
3
2
|
import * as react from 'react';
|
|
4
3
|
|
|
5
|
-
interface ButtonProps extends Omit<HTMLProps<HTMLButtonElement>, "size"> {
|
|
4
|
+
interface ButtonProps extends Omit<HTMLProps<HTMLButtonElement | HTMLAnchorElement>, "size" | "as"> {
|
|
6
5
|
active?: boolean;
|
|
6
|
+
as?: React.ElementType;
|
|
7
7
|
asChild?: boolean;
|
|
8
8
|
className?: string;
|
|
9
9
|
focused?: boolean;
|
|
10
10
|
loading?: boolean;
|
|
11
11
|
readOnly?: boolean;
|
|
12
|
-
/**
|
|
13
|
-
* @default "default"
|
|
14
|
-
*/
|
|
15
12
|
size?: "default" | "large";
|
|
16
|
-
tooltip?: TooltipProps;
|
|
17
|
-
/**
|
|
18
|
-
* @default "primary"
|
|
19
|
-
*/
|
|
20
13
|
variant?: "primary" | "secondary" | "solid" | "destructive" | "secondary-destruct" | "inverse" | "success" | "link" | "link-danger" | "ghost" | "dark" | "reset";
|
|
21
14
|
}
|
|
22
15
|
declare const Button: react.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { LoaderCircle } from "@choiceform/icons-react";
|
|
2
1
|
import { Slot } from "../../slot/dist/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import { forwardRef, isValidElement, cloneElement
|
|
2
|
+
import { LoaderCircle } from "@choiceform/icons-react";
|
|
3
|
+
import { forwardRef, useMemo, isValidElement, cloneElement } from "react";
|
|
5
4
|
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
6
|
-
import { isMultiElement } from "../../../shared/utils/assertion.js";
|
|
7
5
|
import { tcv, tcx } from "../../../shared/utils/tcx/tcx.js";
|
|
6
|
+
import { isMultiElement } from "../../../shared/utils/assertion.js";
|
|
8
7
|
var buttonTv = tcv({
|
|
9
8
|
slots: {
|
|
10
9
|
button: [
|
|
@@ -75,6 +74,10 @@ var buttonTv = tcv({
|
|
|
75
74
|
focused: {
|
|
76
75
|
true: "",
|
|
77
76
|
false: ""
|
|
77
|
+
},
|
|
78
|
+
multiElement: {
|
|
79
|
+
true: "",
|
|
80
|
+
false: ""
|
|
78
81
|
}
|
|
79
82
|
},
|
|
80
83
|
compoundVariants: [
|
|
@@ -123,10 +126,15 @@ var buttonTv = tcv({
|
|
|
123
126
|
variant: ["link", "link-danger", "ghost"],
|
|
124
127
|
disabled: true,
|
|
125
128
|
class: {
|
|
126
|
-
button: [
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
button: ["text-disabled-foreground pointer-events-none"]
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
variant: ["link", "link-danger", "ghost"],
|
|
134
|
+
disabled: true,
|
|
135
|
+
multiElement: true,
|
|
136
|
+
class: {
|
|
137
|
+
button: ["border-default-boundary"]
|
|
130
138
|
}
|
|
131
139
|
},
|
|
132
140
|
{
|
|
@@ -244,7 +252,8 @@ var buttonTv = tcv({
|
|
|
244
252
|
active: false,
|
|
245
253
|
disabled: false,
|
|
246
254
|
loading: false,
|
|
247
|
-
focused: false
|
|
255
|
+
focused: false,
|
|
256
|
+
multiElement: false
|
|
248
257
|
}
|
|
249
258
|
});
|
|
250
259
|
var Button = forwardRef(function Button2(props, ref) {
|
|
@@ -259,13 +268,25 @@ var Button = forwardRef(function Button2(props, ref) {
|
|
|
259
268
|
loading,
|
|
260
269
|
asChild,
|
|
261
270
|
children,
|
|
262
|
-
|
|
271
|
+
as,
|
|
263
272
|
"aria-label": ariaLabel,
|
|
264
273
|
onClick,
|
|
265
274
|
...rest
|
|
266
275
|
} = props;
|
|
267
|
-
const
|
|
268
|
-
const
|
|
276
|
+
const As = as ?? "button";
|
|
277
|
+
const AsComponent = asChild ? Slot : As;
|
|
278
|
+
const elementProps = !asChild && As === "button" ? { type: rest.type ?? "button" } : {};
|
|
279
|
+
const tv = useMemo(
|
|
280
|
+
() => buttonTv({
|
|
281
|
+
variant,
|
|
282
|
+
size,
|
|
283
|
+
active,
|
|
284
|
+
disabled,
|
|
285
|
+
loading,
|
|
286
|
+
focused
|
|
287
|
+
}),
|
|
288
|
+
[variant, size, active, disabled, loading, focused]
|
|
289
|
+
);
|
|
269
290
|
const content = isValidElement(children) ? cloneElement(children, {
|
|
270
291
|
children: children.props.children
|
|
271
292
|
}) : loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -279,23 +300,21 @@ var Button = forwardRef(function Button2(props, ref) {
|
|
|
279
300
|
return props["aria-label"];
|
|
280
301
|
}, [children, props]);
|
|
281
302
|
const handleClick = readOnly ? void 0 : onClick;
|
|
282
|
-
|
|
283
|
-
|
|
303
|
+
return /* @__PURE__ */ jsx(
|
|
304
|
+
AsComponent,
|
|
284
305
|
{
|
|
285
|
-
...rest,
|
|
286
306
|
ref,
|
|
287
|
-
|
|
307
|
+
className: tcx(tv.button({ multiElement: isMultiElement(content) }), className),
|
|
308
|
+
...elementProps,
|
|
309
|
+
...rest,
|
|
288
310
|
disabled: disabled || loading,
|
|
289
311
|
onClick: handleClick,
|
|
290
|
-
className: tcx(tv.button(), className),
|
|
291
|
-
"data-multi-element": isMultiElement(content),
|
|
292
312
|
"aria-disabled": disabled || loading,
|
|
293
313
|
"aria-busy": loading,
|
|
294
314
|
"aria-label": ariaLabelProps,
|
|
295
315
|
children: content
|
|
296
316
|
}
|
|
297
317
|
);
|
|
298
|
-
return tooltip ? /* @__PURE__ */ jsx(Tooltip, { ...tooltip, children: button }) : button;
|
|
299
318
|
});
|
|
300
319
|
Button.displayName = "Button";
|
|
301
320
|
export {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { default as React__default, ReactNode, HTMLProps, RefObject } from 'react';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
3
|
|
|
5
4
|
interface CodeBlockContextValue {
|
|
6
5
|
codeExpanded: boolean;
|
|
@@ -14,7 +13,7 @@ interface CodeBlockContextValue {
|
|
|
14
13
|
isExpanded: boolean;
|
|
15
14
|
language: string;
|
|
16
15
|
lineCount: number;
|
|
17
|
-
lineThreshold
|
|
16
|
+
lineThreshold?: number;
|
|
18
17
|
needsScroll: boolean;
|
|
19
18
|
scrollRef?: RefObject<HTMLDivElement>;
|
|
20
19
|
variant?: "default" | "light" | "dark";
|
|
@@ -51,35 +50,33 @@ interface CodeBlockFooterProps extends CodeBlockInjectedProps {
|
|
|
51
50
|
}
|
|
52
51
|
interface CodeBlockContentProps extends CodeBlockInjectedProps {
|
|
53
52
|
className?: string;
|
|
54
|
-
code: string;
|
|
55
53
|
language?: string;
|
|
56
54
|
withScrollArea?: boolean;
|
|
55
|
+
children?: string;
|
|
57
56
|
}
|
|
58
57
|
interface CodeBlockCodeProps extends HTMLProps<HTMLDivElement> {
|
|
59
58
|
className?: string;
|
|
60
|
-
|
|
61
|
-
/** 从 CodeBlock 传递的 context */
|
|
59
|
+
children?: string;
|
|
62
60
|
codeBlock?: CodeBlockContextValue;
|
|
63
61
|
codeBlockId?: string;
|
|
64
62
|
language?: string;
|
|
65
|
-
/** 手动指定主题,覆盖自动检测 */
|
|
66
63
|
variant?: "light" | "dark";
|
|
67
64
|
}
|
|
68
65
|
|
|
66
|
+
declare const CodeBlock: React__default.NamedExoticComponent<CodeBlockProps> & {
|
|
67
|
+
Code: React__default.NamedExoticComponent<CodeBlockCodeProps>;
|
|
68
|
+
Content: React__default.NamedExoticComponent<CodeBlockContentProps>;
|
|
69
|
+
Footer: React__default.NamedExoticComponent<CodeBlockFooterProps>;
|
|
70
|
+
Header: React__default.NamedExoticComponent<CodeBlockHeaderProps>;
|
|
71
|
+
};
|
|
72
|
+
|
|
69
73
|
declare const CodeBlockCode: React.NamedExoticComponent<CodeBlockCodeProps>;
|
|
70
74
|
|
|
71
75
|
declare const CodeBlockHeader: React__default.NamedExoticComponent<CodeBlockHeaderProps>;
|
|
72
76
|
|
|
73
77
|
declare const CodeBlockFooter: React.NamedExoticComponent<CodeBlockFooterProps>;
|
|
74
78
|
|
|
75
|
-
declare
|
|
76
|
-
|
|
77
|
-
declare const CodeBlock: React__default.NamedExoticComponent<CodeBlockProps> & {
|
|
78
|
-
Code: React__default.NamedExoticComponent<CodeBlockCodeProps>;
|
|
79
|
-
Content: typeof CodeBlockContent;
|
|
80
|
-
Footer: React__default.NamedExoticComponent<CodeBlockFooterProps>;
|
|
81
|
-
Header: React__default.NamedExoticComponent<CodeBlockHeaderProps>;
|
|
82
|
-
};
|
|
79
|
+
declare const CodeBlockContent: React.NamedExoticComponent<CodeBlockContentProps>;
|
|
83
80
|
|
|
84
81
|
declare function getDefaultFilenameForLanguage(language: string): string;
|
|
85
82
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React__default, { memo, useState, useEffect } from "react";
|
|
1
|
+
import React__default, { memo, useState, useEffect, useRef, useCallback } from "react";
|
|
2
2
|
import { useStickToBottom } from "use-stick-to-bottom";
|
|
3
3
|
import { codeToHtml } from "shiki";
|
|
4
4
|
import { useEventCallback } from "usehooks-ts";
|
|
@@ -34,13 +34,34 @@ function useCodeBlock({
|
|
|
34
34
|
if (!code || typeof code !== "string") {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
const onSuccess = () => {
|
|
38
|
+
setCopied(true);
|
|
39
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
40
|
+
};
|
|
41
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
42
|
+
try {
|
|
39
43
|
await navigator.clipboard.writeText(code);
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
onSuccess();
|
|
45
|
+
return;
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const textArea = document.createElement("textarea");
|
|
50
|
+
try {
|
|
51
|
+
textArea.value = code;
|
|
52
|
+
textArea.style.cssText = "position:fixed;top:0;left:0;width:2em;height:2em;padding:0;border:none;outline:none;box-shadow:none;background:transparent;";
|
|
53
|
+
document.body.appendChild(textArea);
|
|
54
|
+
textArea.focus();
|
|
55
|
+
textArea.select();
|
|
56
|
+
const successful = document.execCommand("copy");
|
|
57
|
+
if (successful) {
|
|
58
|
+
onSuccess();
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
} finally {
|
|
62
|
+
if (textArea.parentNode) {
|
|
63
|
+
textArea.parentNode.removeChild(textArea);
|
|
42
64
|
}
|
|
43
|
-
} catch (error) {
|
|
44
65
|
}
|
|
45
66
|
});
|
|
46
67
|
return {
|
|
@@ -56,12 +77,15 @@ function useScrollDetection({
|
|
|
56
77
|
scrollRef,
|
|
57
78
|
contentRef,
|
|
58
79
|
isExpanded,
|
|
59
|
-
codeExpanded
|
|
60
|
-
children
|
|
80
|
+
codeExpanded
|
|
61
81
|
}) {
|
|
62
82
|
const [needsScroll, setNeedsScroll] = useState(false);
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
const debounceRef = useRef(null);
|
|
84
|
+
const checkScrollNeeded = useCallback(() => {
|
|
85
|
+
if (debounceRef.current) {
|
|
86
|
+
clearTimeout(debounceRef.current);
|
|
87
|
+
}
|
|
88
|
+
debounceRef.current = setTimeout(() => {
|
|
65
89
|
if (!scrollRef.current || !contentRef.current) {
|
|
66
90
|
setNeedsScroll(false);
|
|
67
91
|
return;
|
|
@@ -71,50 +95,30 @@ function useScrollDetection({
|
|
|
71
95
|
const content = contentRef.current;
|
|
72
96
|
const hasScroll = content.scrollHeight > viewport.clientHeight;
|
|
73
97
|
setNeedsScroll(hasScroll);
|
|
74
|
-
} catch
|
|
98
|
+
} catch {
|
|
75
99
|
setNeedsScroll(false);
|
|
76
100
|
}
|
|
77
|
-
};
|
|
101
|
+
}, 50);
|
|
102
|
+
}, [scrollRef, contentRef]);
|
|
103
|
+
useEffect(() => {
|
|
78
104
|
const timeoutId = setTimeout(checkScrollNeeded, 100);
|
|
79
105
|
window.addEventListener("resize", checkScrollNeeded);
|
|
80
106
|
let resizeObserver = null;
|
|
81
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
107
|
+
if (typeof ResizeObserver !== "undefined" && contentRef.current) {
|
|
82
108
|
resizeObserver = new ResizeObserver(checkScrollNeeded);
|
|
83
|
-
|
|
84
|
-
resizeObserver.observe(contentRef.current);
|
|
85
|
-
}
|
|
109
|
+
resizeObserver.observe(contentRef.current);
|
|
86
110
|
}
|
|
87
111
|
return () => {
|
|
88
112
|
clearTimeout(timeoutId);
|
|
113
|
+
if (debounceRef.current) {
|
|
114
|
+
clearTimeout(debounceRef.current);
|
|
115
|
+
}
|
|
89
116
|
window.removeEventListener("resize", checkScrollNeeded);
|
|
90
117
|
resizeObserver == null ? void 0 : resizeObserver.disconnect();
|
|
91
118
|
};
|
|
92
|
-
}, [
|
|
119
|
+
}, [checkScrollNeeded, isExpanded, codeExpanded]);
|
|
93
120
|
return needsScroll;
|
|
94
121
|
}
|
|
95
|
-
function useLineCount(children) {
|
|
96
|
-
const [lineCount, setLineCount] = useState(0);
|
|
97
|
-
useEffect(() => {
|
|
98
|
-
try {
|
|
99
|
-
const codeContent = React__default.Children.toArray(children).map((child) => {
|
|
100
|
-
var _a;
|
|
101
|
-
if (React__default.isValidElement(child) && ((_a = child.props) == null ? void 0 : _a.code) && typeof child.props.code === "string") {
|
|
102
|
-
return child.props.code;
|
|
103
|
-
}
|
|
104
|
-
return "";
|
|
105
|
-
}).join("");
|
|
106
|
-
if (codeContent) {
|
|
107
|
-
const lines = codeContent.split("\n").length;
|
|
108
|
-
setLineCount(lines);
|
|
109
|
-
} else {
|
|
110
|
-
setLineCount(0);
|
|
111
|
-
}
|
|
112
|
-
} catch (error) {
|
|
113
|
-
setLineCount(0);
|
|
114
|
-
}
|
|
115
|
-
}, [children]);
|
|
116
|
-
return lineCount;
|
|
117
|
-
}
|
|
118
122
|
function useTheme() {
|
|
119
123
|
const [theme, setTheme] = useState(() => {
|
|
120
124
|
if (typeof window === "undefined") return "light";
|
|
@@ -176,34 +180,46 @@ var codeBlockCodeTv = tcv({
|
|
|
176
180
|
base: "text-message-code w-fit min-w-full bg-transparent font-mono [&>pre]:!bg-transparent [&>pre]:px-4 [&>pre]:py-4"
|
|
177
181
|
});
|
|
178
182
|
var CodeBlockCode = memo(function CodeBlockCode2(props) {
|
|
179
|
-
const {
|
|
183
|
+
const { children, language = "tsx", className, variant: variantProp, codeBlock, ...rest } = props;
|
|
180
184
|
const systemTheme = useTheme();
|
|
181
185
|
const resolvedVariant = variantProp ?? ((codeBlock == null ? void 0 : codeBlock.variant) === "default" ? void 0 : codeBlock == null ? void 0 : codeBlock.variant);
|
|
182
186
|
const theme = resolvedVariant ?? systemTheme;
|
|
183
187
|
const [highlightedHtml, setHighlightedHtml] = useState(null);
|
|
184
188
|
useEffect(() => {
|
|
189
|
+
let isMounted = true;
|
|
185
190
|
async function highlight() {
|
|
186
|
-
if (!
|
|
187
|
-
setHighlightedHtml("<pre><code></code></pre>");
|
|
191
|
+
if (!children) {
|
|
192
|
+
if (isMounted) setHighlightedHtml("<pre><code></code></pre>");
|
|
188
193
|
return;
|
|
189
194
|
}
|
|
190
195
|
const resolvedLang = resolveLanguage(language);
|
|
196
|
+
const themeConfig = theme === "light" ? "github-light" : "github-dark";
|
|
191
197
|
try {
|
|
192
|
-
const html = await codeToHtml(
|
|
198
|
+
const html = await codeToHtml(children, {
|
|
193
199
|
lang: resolvedLang,
|
|
194
|
-
theme:
|
|
200
|
+
theme: themeConfig
|
|
195
201
|
});
|
|
196
|
-
setHighlightedHtml(html);
|
|
202
|
+
if (isMounted) setHighlightedHtml(html);
|
|
197
203
|
} catch {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
try {
|
|
205
|
+
const html = await codeToHtml(children, {
|
|
206
|
+
lang: "text",
|
|
207
|
+
theme: themeConfig
|
|
208
|
+
});
|
|
209
|
+
if (isMounted) setHighlightedHtml(html);
|
|
210
|
+
} catch {
|
|
211
|
+
if (isMounted) {
|
|
212
|
+
const escaped = children.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
213
|
+
setHighlightedHtml(`<pre><code>${escaped}</code></pre>`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
203
216
|
}
|
|
204
217
|
}
|
|
205
218
|
highlight();
|
|
206
|
-
|
|
219
|
+
return () => {
|
|
220
|
+
isMounted = false;
|
|
221
|
+
};
|
|
222
|
+
}, [children, language, theme]);
|
|
207
223
|
const classNames = codeBlockCodeTv({ className });
|
|
208
224
|
return highlightedHtml ? /* @__PURE__ */ jsx(
|
|
209
225
|
"div",
|
|
@@ -217,10 +233,29 @@ var CodeBlockCode = memo(function CodeBlockCode2(props) {
|
|
|
217
233
|
{
|
|
218
234
|
className: tcx("min-w-0", classNames),
|
|
219
235
|
...rest,
|
|
220
|
-
children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children
|
|
236
|
+
children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children }) })
|
|
221
237
|
}
|
|
222
238
|
);
|
|
223
239
|
});
|
|
240
|
+
function extractCodeFromChildren(children) {
|
|
241
|
+
if (!children) return "";
|
|
242
|
+
try {
|
|
243
|
+
return React__default.Children.toArray(children).map((child) => {
|
|
244
|
+
var _a, _b;
|
|
245
|
+
if (React__default.isValidElement(child)) {
|
|
246
|
+
if (((_a = child.props) == null ? void 0 : _a.code) && typeof child.props.code === "string") {
|
|
247
|
+
return child.props.code;
|
|
248
|
+
}
|
|
249
|
+
if (((_b = child.props) == null ? void 0 : _b.children) && typeof child.props.children === "string") {
|
|
250
|
+
return child.props.children;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return "";
|
|
254
|
+
}).filter(Boolean).join("");
|
|
255
|
+
} catch {
|
|
256
|
+
return "";
|
|
257
|
+
}
|
|
258
|
+
}
|
|
224
259
|
var icons = {
|
|
225
260
|
js: /* @__PURE__ */ jsxs(
|
|
226
261
|
"svg",
|
|
@@ -908,9 +943,8 @@ var CodeBlockHeader = memo(function CodeBlockHeader2(props) {
|
|
|
908
943
|
handleCopy,
|
|
909
944
|
variant
|
|
910
945
|
} = codeBlock;
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
946
|
+
const canExpand = Boolean(handleExpand);
|
|
947
|
+
const canCopy = Boolean(handleCopy);
|
|
914
948
|
const tv = codeBlockHeaderTv({ isExpanded, variant });
|
|
915
949
|
let icon = null;
|
|
916
950
|
try {
|
|
@@ -934,17 +968,17 @@ var CodeBlockHeader = memo(function CodeBlockHeader2(props) {
|
|
|
934
968
|
children
|
|
935
969
|
] }),
|
|
936
970
|
/* @__PURE__ */ jsxs("div", { className: tv.actions(), children: [
|
|
937
|
-
isExpanded && /* @__PURE__ */ jsx(
|
|
971
|
+
isExpanded && canCopy && /* @__PURE__ */ jsx(
|
|
938
972
|
IconButton,
|
|
939
973
|
{
|
|
940
974
|
className: tv.button(),
|
|
941
975
|
variant: variant === "dark" ? "dark" : "ghost",
|
|
942
|
-
onClick: () => handleCopy(),
|
|
976
|
+
onClick: () => handleCopy == null ? void 0 : handleCopy(),
|
|
943
977
|
tooltip: { content: copyTooltipContent },
|
|
944
978
|
children: copied ? /* @__PURE__ */ jsx(Check, { className: "text-success-foreground" }) : /* @__PURE__ */ jsx(ClipboardSmall, {})
|
|
945
979
|
}
|
|
946
980
|
),
|
|
947
|
-
expandable && /* @__PURE__ */ jsx(
|
|
981
|
+
expandable && canExpand && /* @__PURE__ */ jsx(
|
|
948
982
|
IconButton,
|
|
949
983
|
{
|
|
950
984
|
className: tv.button(),
|
|
@@ -972,9 +1006,10 @@ var codeBlockFooterTv = tcv({
|
|
|
972
1006
|
},
|
|
973
1007
|
false: {
|
|
974
1008
|
footer: [
|
|
975
|
-
"bg-secondary-background/
|
|
1009
|
+
"bg-secondary-background/80 absolute inset-x-0 bottom-0 z-3",
|
|
976
1010
|
"opacity-0 group-hover:opacity-100",
|
|
977
|
-
"hover:bg-tertiary-background"
|
|
1011
|
+
"hover:bg-tertiary-background",
|
|
1012
|
+
"backdrop-blur-xs"
|
|
978
1013
|
]
|
|
979
1014
|
}
|
|
980
1015
|
}
|
|
@@ -988,7 +1023,7 @@ var CodeBlockFooter = memo(function CodeBlockFooter2(props) {
|
|
|
988
1023
|
if (!codeBlock) return null;
|
|
989
1024
|
const { isExpanded, codeExpanded, handleCodeExpand, lineCount, lineThreshold, needsScroll } = codeBlock;
|
|
990
1025
|
const tv = codeBlockFooterTv({ codeExpanded });
|
|
991
|
-
if (!(lineCount > lineThreshold || needsScroll || codeExpanded) || !isExpanded) {
|
|
1026
|
+
if (lineThreshold && !(lineCount > lineThreshold || needsScroll || codeExpanded) || !isExpanded) {
|
|
992
1027
|
return null;
|
|
993
1028
|
}
|
|
994
1029
|
return /* @__PURE__ */ jsx(
|
|
@@ -1000,24 +1035,26 @@ var CodeBlockFooter = memo(function CodeBlockFooter2(props) {
|
|
|
1000
1035
|
}
|
|
1001
1036
|
);
|
|
1002
1037
|
});
|
|
1038
|
+
var LINE_HEIGHT_PX = 16;
|
|
1039
|
+
var HEIGHT_PADDING_PX = 32 + 40;
|
|
1003
1040
|
var codeBlockTv = tcv({
|
|
1004
1041
|
slots: {
|
|
1005
|
-
code: "overflow-hidden",
|
|
1042
|
+
code: "overflow-hidden min-h-0 flex-1",
|
|
1006
1043
|
content: "flex w-fit flex-col overflow-clip p-[inherit]"
|
|
1007
1044
|
}
|
|
1008
1045
|
});
|
|
1009
|
-
|
|
1010
|
-
const {
|
|
1046
|
+
var CodeBlockContent = memo(function CodeBlockContent2(props) {
|
|
1047
|
+
const { className, codeBlock, withScrollArea = true, children } = props;
|
|
1011
1048
|
if (!codeBlock) return null;
|
|
1012
1049
|
const { language, isExpanded, codeExpanded, scrollRef, contentRef, lineCount, lineThreshold } = codeBlock;
|
|
1013
1050
|
if (!isExpanded) {
|
|
1014
1051
|
return null;
|
|
1015
1052
|
}
|
|
1016
|
-
if (typeof
|
|
1053
|
+
if (typeof children !== "string") {
|
|
1017
1054
|
return null;
|
|
1018
1055
|
}
|
|
1019
1056
|
const tv = codeBlockTv();
|
|
1020
|
-
const shouldLimitHeight = lineCount > lineThreshold && !codeExpanded;
|
|
1057
|
+
const shouldLimitHeight = lineThreshold && lineCount > lineThreshold && !codeExpanded;
|
|
1021
1058
|
return /* @__PURE__ */ jsx(Fragment, { children: withScrollArea ? /* @__PURE__ */ jsx(
|
|
1022
1059
|
ScrollArea,
|
|
1023
1060
|
{
|
|
@@ -1030,7 +1067,7 @@ function CodeBlockContent(props) {
|
|
|
1030
1067
|
{
|
|
1031
1068
|
ref: scrollRef,
|
|
1032
1069
|
style: {
|
|
1033
|
-
maxHeight: shouldLimitHeight ? `${lineThreshold *
|
|
1070
|
+
maxHeight: shouldLimitHeight ? `${lineThreshold * LINE_HEIGHT_PX + HEIGHT_PADDING_PX}px` : "none"
|
|
1034
1071
|
},
|
|
1035
1072
|
children: /* @__PURE__ */ jsx(
|
|
1036
1073
|
ScrollArea.Content,
|
|
@@ -1040,9 +1077,9 @@ function CodeBlockContent(props) {
|
|
|
1040
1077
|
children: /* @__PURE__ */ jsx(
|
|
1041
1078
|
CodeBlockCode,
|
|
1042
1079
|
{
|
|
1043
|
-
code,
|
|
1044
1080
|
language,
|
|
1045
|
-
codeBlock
|
|
1081
|
+
codeBlock,
|
|
1082
|
+
children
|
|
1046
1083
|
}
|
|
1047
1084
|
)
|
|
1048
1085
|
}
|
|
@@ -1053,19 +1090,19 @@ function CodeBlockContent(props) {
|
|
|
1053
1090
|
) : /* @__PURE__ */ jsx("div", { className: tcx(tv.content(), className), children: /* @__PURE__ */ jsx(
|
|
1054
1091
|
CodeBlockCode,
|
|
1055
1092
|
{
|
|
1056
|
-
code,
|
|
1057
1093
|
language,
|
|
1058
|
-
codeBlock
|
|
1094
|
+
codeBlock,
|
|
1095
|
+
children
|
|
1059
1096
|
}
|
|
1060
1097
|
) }) });
|
|
1061
|
-
}
|
|
1098
|
+
});
|
|
1062
1099
|
var CodeBlockRoot = memo(function CodeBlock(props) {
|
|
1063
1100
|
const {
|
|
1064
1101
|
children,
|
|
1065
1102
|
className,
|
|
1066
1103
|
filename,
|
|
1067
1104
|
language = "code",
|
|
1068
|
-
lineThreshold
|
|
1105
|
+
lineThreshold,
|
|
1069
1106
|
expandable = true,
|
|
1070
1107
|
defaultExpanded = true,
|
|
1071
1108
|
defaultCodeExpanded = false,
|
|
@@ -1077,7 +1114,6 @@ var CodeBlockRoot = memo(function CodeBlock(props) {
|
|
|
1077
1114
|
resize: "smooth",
|
|
1078
1115
|
initial: "smooth"
|
|
1079
1116
|
});
|
|
1080
|
-
const codeContentRef = React__default.useRef("");
|
|
1081
1117
|
const {
|
|
1082
1118
|
isExpanded,
|
|
1083
1119
|
codeExpanded,
|
|
@@ -1092,34 +1128,25 @@ var CodeBlockRoot = memo(function CodeBlock(props) {
|
|
|
1092
1128
|
onCodeExpandChange,
|
|
1093
1129
|
scrollToBottom
|
|
1094
1130
|
});
|
|
1131
|
+
const codeContent = React__default.useMemo(() => extractCodeFromChildren(children), [children]);
|
|
1132
|
+
const lineCount = React__default.useMemo(
|
|
1133
|
+
() => codeContent ? codeContent.split("\n").length : 0,
|
|
1134
|
+
[codeContent]
|
|
1135
|
+
);
|
|
1095
1136
|
const handleCopy = React__default.useCallback(
|
|
1096
1137
|
(code) => {
|
|
1097
|
-
const codeToUse = code ||
|
|
1138
|
+
const codeToUse = code || codeContent;
|
|
1098
1139
|
if (codeToUse) {
|
|
1099
1140
|
originalHandleCopy(codeToUse);
|
|
1100
1141
|
}
|
|
1101
1142
|
},
|
|
1102
|
-
[originalHandleCopy]
|
|
1143
|
+
[originalHandleCopy, codeContent]
|
|
1103
1144
|
);
|
|
1104
|
-
React__default.useEffect(() => {
|
|
1105
|
-
try {
|
|
1106
|
-
React__default.Children.forEach(children, (child) => {
|
|
1107
|
-
if (React__default.isValidElement(child) && child.props) {
|
|
1108
|
-
if (child.props.code && typeof child.props.code === "string") {
|
|
1109
|
-
codeContentRef.current = child.props.code;
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
});
|
|
1113
|
-
} catch {
|
|
1114
|
-
}
|
|
1115
|
-
}, [children]);
|
|
1116
|
-
const lineCount = useLineCount(children);
|
|
1117
1145
|
const needsScroll = useScrollDetection({
|
|
1118
1146
|
scrollRef,
|
|
1119
1147
|
contentRef,
|
|
1120
1148
|
isExpanded,
|
|
1121
|
-
codeExpanded
|
|
1122
|
-
children
|
|
1149
|
+
codeExpanded
|
|
1123
1150
|
});
|
|
1124
1151
|
const contextValue = React__default.useMemo(
|
|
1125
1152
|
() => ({
|
|
@@ -1178,7 +1205,7 @@ var CodeBlockRoot = memo(function CodeBlock(props) {
|
|
|
1178
1205
|
"div",
|
|
1179
1206
|
{
|
|
1180
1207
|
className: tcx(
|
|
1181
|
-
"group/code-block relative overflow-hidden rounded-lg",
|
|
1208
|
+
"group/code-block relative flex flex-col overflow-hidden rounded-lg",
|
|
1182
1209
|
variant === "default" && "bg-secondary-background",
|
|
1183
1210
|
variant === "light" && "bg-gray-100",
|
|
1184
1211
|
variant === "dark" && "bg-gray-700",
|
|
@@ -43,10 +43,6 @@ interface CommandItemProps extends Omit<HTMLProps<HTMLDivElement>, "onSelect"> {
|
|
|
43
43
|
keywords?: string[];
|
|
44
44
|
onSelect?: (value: string) => void;
|
|
45
45
|
prefixElement?: ReactNode;
|
|
46
|
-
/**
|
|
47
|
-
* When true, this item will be set as the selected item and scrolled into view.
|
|
48
|
-
*/
|
|
49
|
-
selected?: boolean;
|
|
50
46
|
shortcut?: {
|
|
51
47
|
keys?: ReactNode;
|
|
52
48
|
modifier?: KbdKey | KbdKey[] | undefined;
|
|
@@ -58,9 +54,6 @@ interface CommandItemProps extends Omit<HTMLProps<HTMLDivElement>, "onSelect"> {
|
|
|
58
54
|
interface CommandListProps extends ScrollAreaProps {
|
|
59
55
|
children: React.ReactNode;
|
|
60
56
|
className?: string;
|
|
61
|
-
classNames?: {
|
|
62
|
-
content?: string;
|
|
63
|
-
};
|
|
64
57
|
label?: string;
|
|
65
58
|
}
|
|
66
59
|
|
|
@@ -113,11 +106,6 @@ interface CommandProps extends Omit<react__default.HTMLAttributes<HTMLDivElement
|
|
|
113
106
|
* Event handler called when the selected item of the menu changes.
|
|
114
107
|
*/
|
|
115
108
|
onChange?: (value: string) => void;
|
|
116
|
-
/**
|
|
117
|
-
* Optionally set to `true` to enable selection mode.
|
|
118
|
-
* When enabled, items with `selected` prop will be scrolled into view on mount.
|
|
119
|
-
*/
|
|
120
|
-
selection?: boolean;
|
|
121
109
|
/**
|
|
122
110
|
* Optionally set to `false` to turn off the automatic filtering and sorting.
|
|
123
111
|
* If `false`, you must conditionally render valid items based on the search query yourself.
|
|
@@ -152,7 +140,6 @@ type Context = {
|
|
|
152
140
|
labelId: string;
|
|
153
141
|
listId: string;
|
|
154
142
|
listInnerRef: react__default.MutableRefObject<HTMLDivElement | null>;
|
|
155
|
-
selection?: boolean;
|
|
156
143
|
size?: "default" | "large";
|
|
157
144
|
store: Store;
|
|
158
145
|
value: (id: string, value?: string, keywords?: string[]) => void;
|
|
@@ -12017,6 +12017,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12017
12017
|
showCategories = true,
|
|
12018
12018
|
showFrequentlyUsed = true,
|
|
12019
12019
|
showSearch = true,
|
|
12020
|
+
showFooter = true,
|
|
12020
12021
|
children,
|
|
12021
12022
|
variant = "dark"
|
|
12022
12023
|
}) {
|
|
@@ -12063,6 +12064,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12063
12064
|
onChange == null ? void 0 : onChange(emoji);
|
|
12064
12065
|
});
|
|
12065
12066
|
const handleEmojiHover = useEventCallback((emoji) => {
|
|
12067
|
+
if (!showFooter) return;
|
|
12066
12068
|
setHoveredEmoji(emoji);
|
|
12067
12069
|
});
|
|
12068
12070
|
const handleCategoryClick = useEventCallback((category) => {
|
|
@@ -12079,7 +12081,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12079
12081
|
className: tv.container({ className }),
|
|
12080
12082
|
style: rootStyle,
|
|
12081
12083
|
children: [
|
|
12082
|
-
/* @__PURE__ */ jsxs("div", { className: tv.header(), children: [
|
|
12084
|
+
(showSearch || showCategories) && /* @__PURE__ */ jsxs("div", { className: tv.header(), children: [
|
|
12083
12085
|
showSearch && /* @__PURE__ */ jsx(
|
|
12084
12086
|
SearchInput,
|
|
12085
12087
|
{
|
|
@@ -12181,7 +12183,7 @@ var EmojiPicker = memo(function EmojiPicker2({
|
|
|
12181
12183
|
)
|
|
12182
12184
|
}
|
|
12183
12185
|
),
|
|
12184
|
-
/* @__PURE__ */ jsx(
|
|
12186
|
+
showFooter && /* @__PURE__ */ jsx(
|
|
12185
12187
|
EmojiFooter,
|
|
12186
12188
|
{
|
|
12187
12189
|
hoveredEmoji,
|