@pixpilot/shadcn-ui 1.26.0 → 1.28.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/dist/dialog/Dialog.d.ts +4 -4
- package/dist/file-upload/FileUpload.d.cts +2 -2
- package/dist/file-upload-inline/FileUploadInline.d.cts +2 -2
- package/dist/file-upload-inline/FileUploadInline.d.ts +2 -2
- package/dist/file-upload-root/FileUploadRoot.d.cts +2 -2
- package/dist/file-upload-root/FileUploadRoot.d.ts +2 -2
- package/dist/input/Input.d.cts +2 -2
- package/dist/rich-text-editor/LinkPopoverToolbarButton.cjs +185 -0
- package/dist/rich-text-editor/LinkPopoverToolbarButton.js +180 -0
- package/dist/rich-text-editor/RichTextEditor.cjs +31 -7
- package/dist/rich-text-editor/RichTextEditor.d.cts +12 -0
- package/dist/rich-text-editor/RichTextEditor.d.ts +12 -0
- package/dist/rich-text-editor/RichTextEditor.js +31 -7
- package/dist/rich-text-editor/RichTextEditorToolbar.cjs +9 -1
- package/dist/rich-text-editor/RichTextEditorToolbar.js +9 -1
- package/dist/rich-text-editor/predefined-toolbar-items.cjs +2 -2
- package/dist/rich-text-editor/predefined-toolbar-items.js +2 -2
- package/dist/tags-input/TagsInput.d.cts +2 -2
- package/dist/tags-input/TagsInput.d.ts +2 -2
- package/dist/theme-toggle/ThemeModeDropdown.d.cts +2 -2
- package/dist/theme-toggle/ThemeModeSwitchInside.d.cts +2 -2
- package/dist/theme-toggle/ThemeModeSwitchOutside.d.cts +2 -2
- package/dist/theme-toggle/ThemeModeToggleButton.d.ts +2 -2
- package/dist/toast/AlertToast.cjs +48 -16
- package/dist/toast/AlertToast.js +48 -16
- package/package.json +2 -2
package/dist/dialog/Dialog.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DialogContent } from "@pixpilot/shadcn";
|
|
2
2
|
import * as React$1 from "react";
|
|
3
|
-
import * as
|
|
3
|
+
import * as react_jsx_runtime9 from "react/jsx-runtime";
|
|
4
4
|
import * as _radix_ui_react_dialog0 from "@radix-ui/react-dialog";
|
|
5
5
|
|
|
6
6
|
//#region src/dialog/Dialog.d.ts
|
|
@@ -13,14 +13,14 @@ declare const DialogContent$1: React$1.ForwardRefExoticComponent<Omit<_radix_ui_
|
|
|
13
13
|
declare function DialogHeader$1({
|
|
14
14
|
className,
|
|
15
15
|
...props
|
|
16
|
-
}: React$1.HTMLAttributes<HTMLDivElement>):
|
|
16
|
+
}: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime9.JSX.Element;
|
|
17
17
|
declare function DialogBody({
|
|
18
18
|
className,
|
|
19
19
|
...props
|
|
20
|
-
}: React$1.HTMLAttributes<HTMLDivElement>):
|
|
20
|
+
}: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime9.JSX.Element;
|
|
21
21
|
declare function DialogFooter$1({
|
|
22
22
|
className,
|
|
23
23
|
...props
|
|
24
|
-
}: React$1.HTMLAttributes<HTMLDivElement>):
|
|
24
|
+
}: React$1.HTMLAttributes<HTMLDivElement>): react_jsx_runtime9.JSX.Element;
|
|
25
25
|
//#endregion
|
|
26
26
|
export { DialogBody, DialogContent$1 as DialogContent, DialogContentProps, DialogFooter$1 as DialogFooter, DialogHeader$1 as DialogHeader };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FileUploadProps } from "./types/index.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime8 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/file-upload/FileUpload.d.ts
|
|
5
|
-
declare function FileUpload(props: FileUploadProps):
|
|
5
|
+
declare function FileUpload(props: FileUploadProps): react_jsx_runtime8.JSX.Element;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { FileUpload };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FileUploadInlineProps } from "./types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime12 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/file-upload-inline/FileUploadInline.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* FileUploadInline - An inline file upload component using FileUpload primitives
|
|
7
7
|
*/
|
|
8
|
-
declare function FileUploadInline(props: FileUploadInlineProps):
|
|
8
|
+
declare function FileUploadInline(props: FileUploadInlineProps): react_jsx_runtime12.JSX.Element;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { FileUploadInline };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FileUploadInlineProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime13 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/file-upload-inline/FileUploadInline.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* FileUploadInline - An inline file upload component using FileUpload primitives
|
|
7
7
|
*/
|
|
8
|
-
declare function FileUploadInline(props: FileUploadInlineProps):
|
|
8
|
+
declare function FileUploadInline(props: FileUploadInlineProps): react_jsx_runtime13.JSX.Element;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { FileUploadInline };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { FileUploadRootProps } from "./types.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime13 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/file-upload-root/FileUploadRoot.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* FileUploadInline - An inline file upload component using FileUpload primitives
|
|
7
7
|
*/
|
|
8
|
-
declare function FileUploadRoot(props: FileUploadRootProps):
|
|
8
|
+
declare function FileUploadRoot(props: FileUploadRootProps): react_jsx_runtime13.JSX.Element;
|
|
9
9
|
declare namespace FileUploadRoot {
|
|
10
10
|
var displayName: string;
|
|
11
11
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { FileUploadRootProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime12 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/file-upload-root/FileUploadRoot.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* FileUploadInline - An inline file upload component using FileUpload primitives
|
|
7
7
|
*/
|
|
8
|
-
declare function FileUploadRoot(props: FileUploadRootProps):
|
|
8
|
+
declare function FileUploadRoot(props: FileUploadRootProps): react_jsx_runtime12.JSX.Element;
|
|
9
9
|
declare namespace FileUploadRoot {
|
|
10
10
|
var displayName: string;
|
|
11
11
|
}
|
package/dist/input/Input.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime14 from "react/jsx-runtime";
|
|
2
2
|
import { InputProps } from "@pixpilot/shadcn";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
4
|
|
|
@@ -10,6 +10,6 @@ type InputProps$1 = InputProps & {
|
|
|
10
10
|
prefixClassName?: string;
|
|
11
11
|
suffixClassName?: string;
|
|
12
12
|
};
|
|
13
|
-
declare function Input(props: InputProps$1):
|
|
13
|
+
declare function Input(props: InputProps$1): react_jsx_runtime14.JSX.Element;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { Input, InputProps$1 as InputProps };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_Button = require('../Button.cjs');
|
|
3
|
+
const require_Input = require('../input/Input.cjs');
|
|
4
|
+
require('../input/index.cjs');
|
|
5
|
+
const require_Popover = require('../popover/Popover.cjs');
|
|
6
|
+
require('../popover/index.cjs');
|
|
7
|
+
let __pixpilot_shadcn = require("@pixpilot/shadcn");
|
|
8
|
+
__pixpilot_shadcn = require_rolldown_runtime.__toESM(__pixpilot_shadcn);
|
|
9
|
+
let lucide_react = require("lucide-react");
|
|
10
|
+
lucide_react = require_rolldown_runtime.__toESM(lucide_react);
|
|
11
|
+
let react = require("react");
|
|
12
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
13
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
14
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
15
|
+
|
|
16
|
+
//#region src/rich-text-editor/LinkPopoverToolbarButton.tsx
|
|
17
|
+
function getLinkTargetOption(target) {
|
|
18
|
+
return target === "_blank" ? "blank" : "current";
|
|
19
|
+
}
|
|
20
|
+
function getLinkAttributes(openTarget) {
|
|
21
|
+
if (openTarget === "blank") return {
|
|
22
|
+
target: "_blank",
|
|
23
|
+
rel: "noopener noreferrer"
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
target: null,
|
|
27
|
+
rel: null
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const LinkPopoverToolbarButton = ({ editor, isActive, className, tooltipMode, allowLinkTarget = false }) => {
|
|
31
|
+
const [open, setOpen] = react.default.useState(false);
|
|
32
|
+
const [href, setHref] = react.default.useState("");
|
|
33
|
+
const [openTarget, setOpenTarget] = react.default.useState("current");
|
|
34
|
+
const inputRef = react.default.useRef(null);
|
|
35
|
+
const syncFormFromSelection = react.default.useCallback(() => {
|
|
36
|
+
const attributes = editor.getAttributes("link");
|
|
37
|
+
setHref(typeof attributes.href === "string" ? attributes.href : "");
|
|
38
|
+
setOpenTarget(getLinkTargetOption(attributes.target));
|
|
39
|
+
}, [editor]);
|
|
40
|
+
const handleOpenChange = (nextOpen) => {
|
|
41
|
+
if (nextOpen) syncFormFromSelection();
|
|
42
|
+
setOpen(nextOpen);
|
|
43
|
+
};
|
|
44
|
+
react.default.useEffect(() => {
|
|
45
|
+
if (!open) return;
|
|
46
|
+
window.requestAnimationFrame(() => {
|
|
47
|
+
inputRef.current?.focus();
|
|
48
|
+
inputRef.current?.select();
|
|
49
|
+
});
|
|
50
|
+
}, [open]);
|
|
51
|
+
const applyLink = () => {
|
|
52
|
+
const trimmedHref = href.trim();
|
|
53
|
+
if (!trimmedHref) {
|
|
54
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
55
|
+
setOpen(false);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
editor.chain().focus().extendMarkRange("link").setLink({
|
|
59
|
+
href: trimmedHref,
|
|
60
|
+
...getLinkAttributes(allowLinkTarget ? openTarget : "current")
|
|
61
|
+
}).run();
|
|
62
|
+
setOpen(false);
|
|
63
|
+
};
|
|
64
|
+
const removeLink = () => {
|
|
65
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
66
|
+
setOpen(false);
|
|
67
|
+
};
|
|
68
|
+
const tooltip = "Edit Link";
|
|
69
|
+
const inputId = `link-input-${react.default.useId()}`;
|
|
70
|
+
const radioCurrentId = `link-target-current-${react.default.useId()}`;
|
|
71
|
+
const radioBlankId = `link-target-blank-${react.default.useId()}`;
|
|
72
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Popover, {
|
|
73
|
+
open,
|
|
74
|
+
onOpenChange: handleOpenChange,
|
|
75
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.PopoverTrigger, {
|
|
76
|
+
asChild: true,
|
|
77
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Button.Button, {
|
|
78
|
+
...tooltipMode === "native" ? { title: tooltip } : { tooltip },
|
|
79
|
+
"data-slot": "link-button",
|
|
80
|
+
type: "button",
|
|
81
|
+
variant: isActive ? "default" : "ghost",
|
|
82
|
+
size: "sm",
|
|
83
|
+
onMouseDown: (event) => {
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
},
|
|
86
|
+
className: (0, __pixpilot_shadcn.cn)("h-8 w-8 p-0", className),
|
|
87
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Link, { className: "h-4 w-4" })
|
|
88
|
+
})
|
|
89
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Popover.PopoverContent, {
|
|
90
|
+
align: "start",
|
|
91
|
+
className: "w-80 space-y-3 p-3",
|
|
92
|
+
onEscapeKeyDown: () => {
|
|
93
|
+
setOpen(false);
|
|
94
|
+
},
|
|
95
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
96
|
+
className: "space-y-3",
|
|
97
|
+
"data-slot": "link-form",
|
|
98
|
+
onSubmit: (event) => {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
event.stopPropagation();
|
|
101
|
+
applyLink();
|
|
102
|
+
},
|
|
103
|
+
children: [
|
|
104
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
105
|
+
className: "space-y-1.5",
|
|
106
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Label, {
|
|
107
|
+
htmlFor: inputId,
|
|
108
|
+
children: "URL"
|
|
109
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Input.Input, {
|
|
110
|
+
ref: inputRef,
|
|
111
|
+
id: inputId,
|
|
112
|
+
type: "url",
|
|
113
|
+
value: href,
|
|
114
|
+
placeholder: "https://example.com",
|
|
115
|
+
"data-slot": "link-input",
|
|
116
|
+
onKeyDown: (event) => {
|
|
117
|
+
if (event.key === "Escape") setOpen(false);
|
|
118
|
+
},
|
|
119
|
+
onChange: (event) => {
|
|
120
|
+
setHref(event.target.value);
|
|
121
|
+
}
|
|
122
|
+
})]
|
|
123
|
+
}),
|
|
124
|
+
allowLinkTarget && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.RadioGroup, {
|
|
125
|
+
value: openTarget,
|
|
126
|
+
onKeyDown: (event) => {
|
|
127
|
+
if (event.key === "Escape") setOpen(false);
|
|
128
|
+
if (event.key === "Enter") {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
applyLink();
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
onValueChange: (value) => {
|
|
134
|
+
setOpenTarget(value);
|
|
135
|
+
},
|
|
136
|
+
className: "gap-2",
|
|
137
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
138
|
+
className: "flex items-center gap-2",
|
|
139
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.RadioGroupItem, {
|
|
140
|
+
id: radioCurrentId,
|
|
141
|
+
"data-slot": "link-target-current",
|
|
142
|
+
value: "current"
|
|
143
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Label, {
|
|
144
|
+
htmlFor: radioCurrentId,
|
|
145
|
+
children: "Open in this window"
|
|
146
|
+
})]
|
|
147
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
148
|
+
className: "flex items-center gap-2",
|
|
149
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.RadioGroupItem, {
|
|
150
|
+
id: radioBlankId,
|
|
151
|
+
"data-slot": "link-target-blank",
|
|
152
|
+
value: "blank"
|
|
153
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Label, {
|
|
154
|
+
htmlFor: radioBlankId,
|
|
155
|
+
children: "Open in new window"
|
|
156
|
+
})]
|
|
157
|
+
})]
|
|
158
|
+
}),
|
|
159
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
160
|
+
className: "flex items-center justify-between gap-2",
|
|
161
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Button.Button, {
|
|
162
|
+
type: "button",
|
|
163
|
+
variant: "ghost",
|
|
164
|
+
size: "sm",
|
|
165
|
+
onClick: removeLink,
|
|
166
|
+
"data-slot": "link-remove-button",
|
|
167
|
+
disabled: !editor.isActive("link"),
|
|
168
|
+
children: "Remove"
|
|
169
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Button.Button, {
|
|
170
|
+
type: "submit",
|
|
171
|
+
size: "sm",
|
|
172
|
+
disabled: !href.trim(),
|
|
173
|
+
"data-slot": "link-apply-button",
|
|
174
|
+
children: "Apply"
|
|
175
|
+
})]
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
})
|
|
179
|
+
})]
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
LinkPopoverToolbarButton.displayName = "LinkPopoverToolbarButton";
|
|
183
|
+
|
|
184
|
+
//#endregion
|
|
185
|
+
exports.LinkPopoverToolbarButton = LinkPopoverToolbarButton;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Button as Button$1 } from "../Button.js";
|
|
2
|
+
import { Input as Input$1 } from "../input/Input.js";
|
|
3
|
+
import "../input/index.js";
|
|
4
|
+
import { Popover as Popover$1, PopoverContent as PopoverContent$1, PopoverTrigger as PopoverTrigger$1 } from "../popover/Popover.js";
|
|
5
|
+
import "../popover/index.js";
|
|
6
|
+
import { Label, RadioGroup, RadioGroupItem, cn } from "@pixpilot/shadcn";
|
|
7
|
+
import { Link } from "lucide-react";
|
|
8
|
+
import React from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
|
|
11
|
+
//#region src/rich-text-editor/LinkPopoverToolbarButton.tsx
|
|
12
|
+
function getLinkTargetOption(target) {
|
|
13
|
+
return target === "_blank" ? "blank" : "current";
|
|
14
|
+
}
|
|
15
|
+
function getLinkAttributes(openTarget) {
|
|
16
|
+
if (openTarget === "blank") return {
|
|
17
|
+
target: "_blank",
|
|
18
|
+
rel: "noopener noreferrer"
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
target: null,
|
|
22
|
+
rel: null
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const LinkPopoverToolbarButton = ({ editor, isActive, className, tooltipMode, allowLinkTarget = false }) => {
|
|
26
|
+
const [open, setOpen] = React.useState(false);
|
|
27
|
+
const [href, setHref] = React.useState("");
|
|
28
|
+
const [openTarget, setOpenTarget] = React.useState("current");
|
|
29
|
+
const inputRef = React.useRef(null);
|
|
30
|
+
const syncFormFromSelection = React.useCallback(() => {
|
|
31
|
+
const attributes = editor.getAttributes("link");
|
|
32
|
+
setHref(typeof attributes.href === "string" ? attributes.href : "");
|
|
33
|
+
setOpenTarget(getLinkTargetOption(attributes.target));
|
|
34
|
+
}, [editor]);
|
|
35
|
+
const handleOpenChange = (nextOpen) => {
|
|
36
|
+
if (nextOpen) syncFormFromSelection();
|
|
37
|
+
setOpen(nextOpen);
|
|
38
|
+
};
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
if (!open) return;
|
|
41
|
+
window.requestAnimationFrame(() => {
|
|
42
|
+
inputRef.current?.focus();
|
|
43
|
+
inputRef.current?.select();
|
|
44
|
+
});
|
|
45
|
+
}, [open]);
|
|
46
|
+
const applyLink = () => {
|
|
47
|
+
const trimmedHref = href.trim();
|
|
48
|
+
if (!trimmedHref) {
|
|
49
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
50
|
+
setOpen(false);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
editor.chain().focus().extendMarkRange("link").setLink({
|
|
54
|
+
href: trimmedHref,
|
|
55
|
+
...getLinkAttributes(allowLinkTarget ? openTarget : "current")
|
|
56
|
+
}).run();
|
|
57
|
+
setOpen(false);
|
|
58
|
+
};
|
|
59
|
+
const removeLink = () => {
|
|
60
|
+
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
61
|
+
setOpen(false);
|
|
62
|
+
};
|
|
63
|
+
const tooltip = "Edit Link";
|
|
64
|
+
const inputId = `link-input-${React.useId()}`;
|
|
65
|
+
const radioCurrentId = `link-target-current-${React.useId()}`;
|
|
66
|
+
const radioBlankId = `link-target-blank-${React.useId()}`;
|
|
67
|
+
return /* @__PURE__ */ jsxs(Popover$1, {
|
|
68
|
+
open,
|
|
69
|
+
onOpenChange: handleOpenChange,
|
|
70
|
+
children: [/* @__PURE__ */ jsx(PopoverTrigger$1, {
|
|
71
|
+
asChild: true,
|
|
72
|
+
children: /* @__PURE__ */ jsx(Button$1, {
|
|
73
|
+
...tooltipMode === "native" ? { title: tooltip } : { tooltip },
|
|
74
|
+
"data-slot": "link-button",
|
|
75
|
+
type: "button",
|
|
76
|
+
variant: isActive ? "default" : "ghost",
|
|
77
|
+
size: "sm",
|
|
78
|
+
onMouseDown: (event) => {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
},
|
|
81
|
+
className: cn("h-8 w-8 p-0", className),
|
|
82
|
+
children: /* @__PURE__ */ jsx(Link, { className: "h-4 w-4" })
|
|
83
|
+
})
|
|
84
|
+
}), /* @__PURE__ */ jsx(PopoverContent$1, {
|
|
85
|
+
align: "start",
|
|
86
|
+
className: "w-80 space-y-3 p-3",
|
|
87
|
+
onEscapeKeyDown: () => {
|
|
88
|
+
setOpen(false);
|
|
89
|
+
},
|
|
90
|
+
children: /* @__PURE__ */ jsxs("form", {
|
|
91
|
+
className: "space-y-3",
|
|
92
|
+
"data-slot": "link-form",
|
|
93
|
+
onSubmit: (event) => {
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
event.stopPropagation();
|
|
96
|
+
applyLink();
|
|
97
|
+
},
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsxs("div", {
|
|
100
|
+
className: "space-y-1.5",
|
|
101
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
102
|
+
htmlFor: inputId,
|
|
103
|
+
children: "URL"
|
|
104
|
+
}), /* @__PURE__ */ jsx(Input$1, {
|
|
105
|
+
ref: inputRef,
|
|
106
|
+
id: inputId,
|
|
107
|
+
type: "url",
|
|
108
|
+
value: href,
|
|
109
|
+
placeholder: "https://example.com",
|
|
110
|
+
"data-slot": "link-input",
|
|
111
|
+
onKeyDown: (event) => {
|
|
112
|
+
if (event.key === "Escape") setOpen(false);
|
|
113
|
+
},
|
|
114
|
+
onChange: (event) => {
|
|
115
|
+
setHref(event.target.value);
|
|
116
|
+
}
|
|
117
|
+
})]
|
|
118
|
+
}),
|
|
119
|
+
allowLinkTarget && /* @__PURE__ */ jsxs(RadioGroup, {
|
|
120
|
+
value: openTarget,
|
|
121
|
+
onKeyDown: (event) => {
|
|
122
|
+
if (event.key === "Escape") setOpen(false);
|
|
123
|
+
if (event.key === "Enter") {
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
applyLink();
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
onValueChange: (value) => {
|
|
129
|
+
setOpenTarget(value);
|
|
130
|
+
},
|
|
131
|
+
className: "gap-2",
|
|
132
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
133
|
+
className: "flex items-center gap-2",
|
|
134
|
+
children: [/* @__PURE__ */ jsx(RadioGroupItem, {
|
|
135
|
+
id: radioCurrentId,
|
|
136
|
+
"data-slot": "link-target-current",
|
|
137
|
+
value: "current"
|
|
138
|
+
}), /* @__PURE__ */ jsx(Label, {
|
|
139
|
+
htmlFor: radioCurrentId,
|
|
140
|
+
children: "Open in this window"
|
|
141
|
+
})]
|
|
142
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
143
|
+
className: "flex items-center gap-2",
|
|
144
|
+
children: [/* @__PURE__ */ jsx(RadioGroupItem, {
|
|
145
|
+
id: radioBlankId,
|
|
146
|
+
"data-slot": "link-target-blank",
|
|
147
|
+
value: "blank"
|
|
148
|
+
}), /* @__PURE__ */ jsx(Label, {
|
|
149
|
+
htmlFor: radioBlankId,
|
|
150
|
+
children: "Open in new window"
|
|
151
|
+
})]
|
|
152
|
+
})]
|
|
153
|
+
}),
|
|
154
|
+
/* @__PURE__ */ jsxs("div", {
|
|
155
|
+
className: "flex items-center justify-between gap-2",
|
|
156
|
+
children: [/* @__PURE__ */ jsx(Button$1, {
|
|
157
|
+
type: "button",
|
|
158
|
+
variant: "ghost",
|
|
159
|
+
size: "sm",
|
|
160
|
+
onClick: removeLink,
|
|
161
|
+
"data-slot": "link-remove-button",
|
|
162
|
+
disabled: !editor.isActive("link"),
|
|
163
|
+
children: "Remove"
|
|
164
|
+
}), /* @__PURE__ */ jsx(Button$1, {
|
|
165
|
+
type: "submit",
|
|
166
|
+
size: "sm",
|
|
167
|
+
disabled: !href.trim(),
|
|
168
|
+
"data-slot": "link-apply-button",
|
|
169
|
+
children: "Apply"
|
|
170
|
+
})]
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
})
|
|
174
|
+
})]
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
LinkPopoverToolbarButton.displayName = "LinkPopoverToolbarButton";
|
|
178
|
+
|
|
179
|
+
//#endregion
|
|
180
|
+
export { LinkPopoverToolbarButton };
|
|
@@ -41,21 +41,34 @@ const defaultToolbarItems = [
|
|
|
41
41
|
"blockquote",
|
|
42
42
|
"codeBlock"
|
|
43
43
|
];
|
|
44
|
-
function useEditorProps(slots, customEditorProps) {
|
|
44
|
+
function useEditorProps(slots, customEditorProps, openOnClick = false) {
|
|
45
45
|
const defaultEditorProps = react.default.useMemo(() => ({ attributes: { class: (0, __pixpilot_shadcn.cn)("min-h-[200px] p-4 text-sm leading-relaxed focus:outline-none", "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:leading-tight [&_h1]:mt-8 [&_h1]:mb-4 [&_h1:first-child]:mt-0", "[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:leading-tight [&_h2]:mt-6 [&_h2]:mb-3 [&_h2:first-child]:mt-0", "[&_h3]:text-xl [&_h3]:font-bold [&_h3]:leading-tight [&_h3]:mt-4 [&_h3]:mb-2 [&_h3:first-child]:mt-0", "[&_p]:mb-3", "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-3", "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:mb-3", "[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:mb-4 [&_blockquote]:italic [&_blockquote:first-child]:mt-0", "[&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_code]:font-mono", "[&_pre]:bg-muted [&_pre]:p-4 [&_pre]:rounded [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:mb-4", "[&_a]:text-blue-500 [&_a]:hover:text-blue-600 [&_a]:cursor-pointer [&_a]:underline [&_a]:underline-offset-2 ", "[&_*:last-child]:mb-0", "[&_.is-editor-empty:first-child::before]:content-[attr(data-placeholder)] [&_.is-editor-empty:first-child::before]:float-left [&_.is-editor-empty:first-child::before]:text-muted-foreground [&_.is-editor-empty:first-child::before]:pointer-events-none [&_.is-editor-empty:first-child::before]:h-0", slots?.content?.className) } }), [slots]);
|
|
46
46
|
return react.default.useMemo(() => ({
|
|
47
47
|
...defaultEditorProps,
|
|
48
48
|
...customEditorProps,
|
|
49
|
+
handleClickOn: (view, pos, node, nodePos, event, direct) => {
|
|
50
|
+
const { target } = event;
|
|
51
|
+
const linkElement = target instanceof Element ? target.closest("a[href]") : null;
|
|
52
|
+
if (!openOnClick && linkElement != null) {
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return customEditorProps?.handleClickOn?.(view, pos, node, nodePos, event, direct);
|
|
57
|
+
},
|
|
49
58
|
attributes: {
|
|
50
59
|
...defaultEditorProps.attributes,
|
|
51
60
|
...customEditorProps?.attributes,
|
|
52
61
|
class: (0, __pixpilot_shadcn.cn)(defaultEditorProps.attributes.class, (customEditorProps?.attributes)?.class)
|
|
53
62
|
}
|
|
54
|
-
}), [
|
|
63
|
+
}), [
|
|
64
|
+
defaultEditorProps,
|
|
65
|
+
customEditorProps,
|
|
66
|
+
openOnClick
|
|
67
|
+
]);
|
|
55
68
|
}
|
|
56
|
-
const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, editable = true, slots, showToolbar = true, toolbarItems = defaultToolbarItems, editorProps: customEditorProps, immediatelyRender = false, tooltipMode = "native", placeholder }) => {
|
|
69
|
+
const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, editable = true, slots, showToolbar = true, toolbarItems = defaultToolbarItems, editorProps: customEditorProps, immediatelyRender = false, tooltipMode = "native", placeholder, allowLinkTarget = false, openOnClick = false }) => {
|
|
57
70
|
const [renderTick, forceRender] = react.default.useReducer((x) => x + 1, 0);
|
|
58
|
-
const mergedEditorProps = useEditorProps(slots, customEditorProps);
|
|
71
|
+
const mergedEditorProps = useEditorProps(slots, customEditorProps, openOnClick);
|
|
59
72
|
const onChangeRef = react.default.useRef(onChange);
|
|
60
73
|
onChangeRef.current = onChange;
|
|
61
74
|
const handleChange = react.default.useCallback((props) => {
|
|
@@ -65,12 +78,22 @@ const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, edita
|
|
|
65
78
|
extensions: react.default.useMemo(() => {
|
|
66
79
|
const baseExtensions = [
|
|
67
80
|
__tiptap_starter_kit.default,
|
|
68
|
-
__tiptap_extension_link.default
|
|
81
|
+
__tiptap_extension_link.default.configure({
|
|
82
|
+
openOnClick,
|
|
83
|
+
HTMLAttributes: {
|
|
84
|
+
target: null,
|
|
85
|
+
rel: null
|
|
86
|
+
}
|
|
87
|
+
}),
|
|
69
88
|
__tiptap_extension_text_align.default.configure({ types: ["heading", "paragraph"] })
|
|
70
89
|
];
|
|
71
90
|
if (placeholder != null) baseExtensions.push(__tiptap_extension_placeholder.default.configure({ placeholder }));
|
|
72
91
|
return baseExtensions.concat(extensions);
|
|
73
|
-
}, [
|
|
92
|
+
}, [
|
|
93
|
+
extensions,
|
|
94
|
+
placeholder,
|
|
95
|
+
openOnClick
|
|
96
|
+
]),
|
|
74
97
|
content: value,
|
|
75
98
|
editable,
|
|
76
99
|
onUpdate: handleChange,
|
|
@@ -108,7 +131,8 @@ const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, edita
|
|
|
108
131
|
slots,
|
|
109
132
|
showToolbar,
|
|
110
133
|
renderTick,
|
|
111
|
-
tooltipMode
|
|
134
|
+
tooltipMode,
|
|
135
|
+
allowLinkTarget
|
|
112
136
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tiptap_react.EditorContent, { editor: editorInstance })]
|
|
113
137
|
});
|
|
114
138
|
};
|
|
@@ -86,6 +86,18 @@ interface RichTextEditorProps {
|
|
|
86
86
|
* Placeholder text to show when the editor is empty
|
|
87
87
|
*/
|
|
88
88
|
placeholder?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the link popover should expose target controls.
|
|
91
|
+
* When false, links are always written without `target` and `rel`.
|
|
92
|
+
* @default false
|
|
93
|
+
*/
|
|
94
|
+
allowLinkTarget?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Whether link clicks should open links inside the editor.
|
|
97
|
+
* When false, link clicks are prevented so linked text can be selected.
|
|
98
|
+
* @default false
|
|
99
|
+
*/
|
|
100
|
+
openOnClick?: boolean;
|
|
89
101
|
}
|
|
90
102
|
declare const RichTextEditor: React.FC<RichTextEditorProps>;
|
|
91
103
|
//#endregion
|
|
@@ -86,6 +86,18 @@ interface RichTextEditorProps {
|
|
|
86
86
|
* Placeholder text to show when the editor is empty
|
|
87
87
|
*/
|
|
88
88
|
placeholder?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the link popover should expose target controls.
|
|
91
|
+
* When false, links are always written without `target` and `rel`.
|
|
92
|
+
* @default false
|
|
93
|
+
*/
|
|
94
|
+
allowLinkTarget?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Whether link clicks should open links inside the editor.
|
|
97
|
+
* When false, link clicks are prevented so linked text can be selected.
|
|
98
|
+
* @default false
|
|
99
|
+
*/
|
|
100
|
+
openOnClick?: boolean;
|
|
89
101
|
}
|
|
90
102
|
declare const RichTextEditor: React.FC<RichTextEditorProps>;
|
|
91
103
|
//#endregion
|
|
@@ -32,21 +32,34 @@ const defaultToolbarItems = [
|
|
|
32
32
|
"blockquote",
|
|
33
33
|
"codeBlock"
|
|
34
34
|
];
|
|
35
|
-
function useEditorProps(slots, customEditorProps) {
|
|
35
|
+
function useEditorProps(slots, customEditorProps, openOnClick = false) {
|
|
36
36
|
const defaultEditorProps = React.useMemo(() => ({ attributes: { class: cn("min-h-[200px] p-4 text-sm leading-relaxed focus:outline-none", "[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:leading-tight [&_h1]:mt-8 [&_h1]:mb-4 [&_h1:first-child]:mt-0", "[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:leading-tight [&_h2]:mt-6 [&_h2]:mb-3 [&_h2:first-child]:mt-0", "[&_h3]:text-xl [&_h3]:font-bold [&_h3]:leading-tight [&_h3]:mt-4 [&_h3]:mb-2 [&_h3:first-child]:mt-0", "[&_p]:mb-3", "[&_ul]:list-disc [&_ul]:pl-6 [&_ul]:mb-3", "[&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:mb-3", "[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:mb-4 [&_blockquote]:italic [&_blockquote:first-child]:mt-0", "[&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_code]:font-mono", "[&_pre]:bg-muted [&_pre]:p-4 [&_pre]:rounded [&_pre]:overflow-x-auto [&_pre]:font-mono [&_pre]:mb-4", "[&_a]:text-blue-500 [&_a]:hover:text-blue-600 [&_a]:cursor-pointer [&_a]:underline [&_a]:underline-offset-2 ", "[&_*:last-child]:mb-0", "[&_.is-editor-empty:first-child::before]:content-[attr(data-placeholder)] [&_.is-editor-empty:first-child::before]:float-left [&_.is-editor-empty:first-child::before]:text-muted-foreground [&_.is-editor-empty:first-child::before]:pointer-events-none [&_.is-editor-empty:first-child::before]:h-0", slots?.content?.className) } }), [slots]);
|
|
37
37
|
return React.useMemo(() => ({
|
|
38
38
|
...defaultEditorProps,
|
|
39
39
|
...customEditorProps,
|
|
40
|
+
handleClickOn: (view, pos, node, nodePos, event, direct) => {
|
|
41
|
+
const { target } = event;
|
|
42
|
+
const linkElement = target instanceof Element ? target.closest("a[href]") : null;
|
|
43
|
+
if (!openOnClick && linkElement != null) {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return customEditorProps?.handleClickOn?.(view, pos, node, nodePos, event, direct);
|
|
48
|
+
},
|
|
40
49
|
attributes: {
|
|
41
50
|
...defaultEditorProps.attributes,
|
|
42
51
|
...customEditorProps?.attributes,
|
|
43
52
|
class: cn(defaultEditorProps.attributes.class, (customEditorProps?.attributes)?.class)
|
|
44
53
|
}
|
|
45
|
-
}), [
|
|
54
|
+
}), [
|
|
55
|
+
defaultEditorProps,
|
|
56
|
+
customEditorProps,
|
|
57
|
+
openOnClick
|
|
58
|
+
]);
|
|
46
59
|
}
|
|
47
|
-
const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, editable = true, slots, showToolbar = true, toolbarItems = defaultToolbarItems, editorProps: customEditorProps, immediatelyRender = false, tooltipMode = "native", placeholder }) => {
|
|
60
|
+
const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, editable = true, slots, showToolbar = true, toolbarItems = defaultToolbarItems, editorProps: customEditorProps, immediatelyRender = false, tooltipMode = "native", placeholder, allowLinkTarget = false, openOnClick = false }) => {
|
|
48
61
|
const [renderTick, forceRender] = React.useReducer((x) => x + 1, 0);
|
|
49
|
-
const mergedEditorProps = useEditorProps(slots, customEditorProps);
|
|
62
|
+
const mergedEditorProps = useEditorProps(slots, customEditorProps, openOnClick);
|
|
50
63
|
const onChangeRef = React.useRef(onChange);
|
|
51
64
|
onChangeRef.current = onChange;
|
|
52
65
|
const handleChange = React.useCallback((props) => {
|
|
@@ -56,12 +69,22 @@ const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, edita
|
|
|
56
69
|
extensions: React.useMemo(() => {
|
|
57
70
|
const baseExtensions = [
|
|
58
71
|
StarterKit,
|
|
59
|
-
Link
|
|
72
|
+
Link.configure({
|
|
73
|
+
openOnClick,
|
|
74
|
+
HTMLAttributes: {
|
|
75
|
+
target: null,
|
|
76
|
+
rel: null
|
|
77
|
+
}
|
|
78
|
+
}),
|
|
60
79
|
TextAlign.configure({ types: ["heading", "paragraph"] })
|
|
61
80
|
];
|
|
62
81
|
if (placeholder != null) baseExtensions.push(Placeholder.configure({ placeholder }));
|
|
63
82
|
return baseExtensions.concat(extensions);
|
|
64
|
-
}, [
|
|
83
|
+
}, [
|
|
84
|
+
extensions,
|
|
85
|
+
placeholder,
|
|
86
|
+
openOnClick
|
|
87
|
+
]),
|
|
65
88
|
content: value,
|
|
66
89
|
editable,
|
|
67
90
|
onUpdate: handleChange,
|
|
@@ -99,7 +122,8 @@ const RichTextEditor = ({ value, onChange, extensions = defaultExtensions, edita
|
|
|
99
122
|
slots,
|
|
100
123
|
showToolbar,
|
|
101
124
|
renderTick,
|
|
102
|
-
tooltipMode
|
|
125
|
+
tooltipMode,
|
|
126
|
+
allowLinkTarget
|
|
103
127
|
}), /* @__PURE__ */ jsx(EditorContent, { editor: editorInstance })]
|
|
104
128
|
});
|
|
105
129
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_LinkPopoverToolbarButton = require('./LinkPopoverToolbarButton.cjs');
|
|
2
3
|
const require_predefined_toolbar_items = require('./predefined-toolbar-items.cjs');
|
|
3
4
|
const require_ToolbarButton = require('./ToolbarButton.cjs');
|
|
4
5
|
let __pixpilot_shadcn = require("@pixpilot/shadcn");
|
|
@@ -9,7 +10,7 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
9
10
|
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
10
11
|
|
|
11
12
|
//#region src/rich-text-editor/RichTextEditorToolbar.tsx
|
|
12
|
-
const RichTextEditorToolbarComponent = ({ editor, toolbarItems, slots, showToolbar, renderTick, tooltipMode }) => {
|
|
13
|
+
const RichTextEditorToolbarComponent = ({ editor, toolbarItems, slots, showToolbar, renderTick, tooltipMode, allowLinkTarget }) => {
|
|
13
14
|
if (!showToolbar) return null;
|
|
14
15
|
const handleCommand = (commandFn) => {
|
|
15
16
|
try {
|
|
@@ -28,6 +29,13 @@ const RichTextEditorToolbarComponent = ({ editor, toolbarItems, slots, showToolb
|
|
|
28
29
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: (0, __pixpilot_shadcn.cn)("mx-1 h-6 w-px bg-border", slots?.toolbar?.separator?.className) }, `separator-${separatorCount}`);
|
|
29
30
|
}
|
|
30
31
|
if (typeof option === "string") {
|
|
32
|
+
if (option === "link" || option === "linkPopover") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_LinkPopoverToolbarButton.LinkPopoverToolbarButton, {
|
|
33
|
+
editor,
|
|
34
|
+
isActive: isEditorFocused && editor.isActive("link"),
|
|
35
|
+
className: slots?.toolbar?.button?.className,
|
|
36
|
+
tooltipMode,
|
|
37
|
+
allowLinkTarget
|
|
38
|
+
}, option);
|
|
31
39
|
const predefinedOption = require_predefined_toolbar_items.predefinedToolbarItems[option];
|
|
32
40
|
if (!predefinedOption) return null;
|
|
33
41
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ToolbarButton.ToolbarButton, {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LinkPopoverToolbarButton } from "./LinkPopoverToolbarButton.js";
|
|
1
2
|
import { predefinedToolbarItems } from "./predefined-toolbar-items.js";
|
|
2
3
|
import { ToolbarButton } from "./ToolbarButton.js";
|
|
3
4
|
import { cn } from "@pixpilot/shadcn";
|
|
@@ -5,7 +6,7 @@ import React from "react";
|
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
|
|
7
8
|
//#region src/rich-text-editor/RichTextEditorToolbar.tsx
|
|
8
|
-
const RichTextEditorToolbarComponent = ({ editor, toolbarItems, slots, showToolbar, renderTick, tooltipMode }) => {
|
|
9
|
+
const RichTextEditorToolbarComponent = ({ editor, toolbarItems, slots, showToolbar, renderTick, tooltipMode, allowLinkTarget }) => {
|
|
9
10
|
if (!showToolbar) return null;
|
|
10
11
|
const handleCommand = (commandFn) => {
|
|
11
12
|
try {
|
|
@@ -24,6 +25,13 @@ const RichTextEditorToolbarComponent = ({ editor, toolbarItems, slots, showToolb
|
|
|
24
25
|
return /* @__PURE__ */ jsx("div", { className: cn("mx-1 h-6 w-px bg-border", slots?.toolbar?.separator?.className) }, `separator-${separatorCount}`);
|
|
25
26
|
}
|
|
26
27
|
if (typeof option === "string") {
|
|
28
|
+
if (option === "link" || option === "linkPopover") return /* @__PURE__ */ jsx(LinkPopoverToolbarButton, {
|
|
29
|
+
editor,
|
|
30
|
+
isActive: isEditorFocused && editor.isActive("link"),
|
|
31
|
+
className: slots?.toolbar?.button?.className,
|
|
32
|
+
tooltipMode,
|
|
33
|
+
allowLinkTarget
|
|
34
|
+
}, option);
|
|
27
35
|
const predefinedOption = predefinedToolbarItems[option];
|
|
28
36
|
if (!predefinedOption) return null;
|
|
29
37
|
return /* @__PURE__ */ jsx(ToolbarButton, {
|
|
@@ -24,9 +24,9 @@ const predefinedToolbarItems = {
|
|
|
24
24
|
onClick: (editor) => editor.chain().focus().toggleUnderline().run(),
|
|
25
25
|
isActive: (editor) => editor.isActive("underline")
|
|
26
26
|
},
|
|
27
|
-
|
|
27
|
+
toggleLink: {
|
|
28
28
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Link, { className: "h-4 w-4" }),
|
|
29
|
-
tooltip: "Link",
|
|
29
|
+
tooltip: "Toggle Link",
|
|
30
30
|
onClick: (editor) => editor.chain().focus().toggleLink().run(),
|
|
31
31
|
isActive: (editor) => editor.isActive("link")
|
|
32
32
|
},
|
|
@@ -21,9 +21,9 @@ const predefinedToolbarItems = {
|
|
|
21
21
|
onClick: (editor) => editor.chain().focus().toggleUnderline().run(),
|
|
22
22
|
isActive: (editor) => editor.isActive("underline")
|
|
23
23
|
},
|
|
24
|
-
|
|
24
|
+
toggleLink: {
|
|
25
25
|
icon: /* @__PURE__ */ jsx(Link, { className: "h-4 w-4" }),
|
|
26
|
-
tooltip: "Link",
|
|
26
|
+
tooltip: "Toggle Link",
|
|
27
27
|
onClick: (editor) => editor.chain().focus().toggleLink().run(),
|
|
28
28
|
isActive: (editor) => editor.isActive("link")
|
|
29
29
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommandOptionListItem } from "../CommandOptionList.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime17 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/tags-input/TagsInput.d.ts
|
|
5
5
|
interface TagsInputProps {
|
|
@@ -59,6 +59,6 @@ declare function TagsInput({
|
|
|
59
59
|
addOnTab,
|
|
60
60
|
onValidate,
|
|
61
61
|
addButtonVisibility
|
|
62
|
-
}: TagsInputProps):
|
|
62
|
+
}: TagsInputProps): react_jsx_runtime17.JSX.Element;
|
|
63
63
|
//#endregion
|
|
64
64
|
export { TagsInput, TagsInputProps };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommandOptionListItem } from "../CommandOptionList.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime17 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/tags-input/TagsInput.d.ts
|
|
5
5
|
interface TagsInputProps {
|
|
@@ -59,6 +59,6 @@ declare function TagsInput({
|
|
|
59
59
|
addOnTab,
|
|
60
60
|
onValidate,
|
|
61
61
|
addButtonVisibility
|
|
62
|
-
}: TagsInputProps):
|
|
62
|
+
}: TagsInputProps): react_jsx_runtime17.JSX.Element;
|
|
63
63
|
//#endregion
|
|
64
64
|
export { TagsInput, TagsInputProps };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime18 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeDropdown.d.ts
|
|
4
4
|
interface ThemeModeDropdownProps {
|
|
@@ -18,7 +18,7 @@ interface ThemeModeDropdownProps {
|
|
|
18
18
|
* Provides Light / Dark / System options.
|
|
19
19
|
* Pure component - requires themeValue and onChange props.
|
|
20
20
|
*/
|
|
21
|
-
declare function ThemeModeDropdown(props: ThemeModeDropdownProps):
|
|
21
|
+
declare function ThemeModeDropdown(props: ThemeModeDropdownProps): react_jsx_runtime18.JSX.Element;
|
|
22
22
|
declare namespace ThemeModeDropdown {
|
|
23
23
|
var displayName: string;
|
|
24
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime19 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeSwitchInside.d.ts
|
|
4
4
|
type ThemeModeSwitchInsideSize = 'sm' | 'md' | 'lg';
|
|
@@ -26,7 +26,7 @@ interface ThemeModeSwitchInsideProps {
|
|
|
26
26
|
* Icons are embedded within the switch control.
|
|
27
27
|
* Pure component - requires value and onChange props.
|
|
28
28
|
*/
|
|
29
|
-
declare function ThemeModeSwitchInside(props: ThemeModeSwitchInsideProps):
|
|
29
|
+
declare function ThemeModeSwitchInside(props: ThemeModeSwitchInsideProps): react_jsx_runtime19.JSX.Element;
|
|
30
30
|
declare namespace ThemeModeSwitchInside {
|
|
31
31
|
var displayName: string;
|
|
32
32
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime20 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeSwitchOutside.d.ts
|
|
4
4
|
interface ThemeModeSwitchOutsideProps {
|
|
@@ -23,7 +23,7 @@ interface ThemeModeSwitchOutsideProps {
|
|
|
23
23
|
* Icons flank the switch control on either side.
|
|
24
24
|
* Pure component - requires value and onChange props.
|
|
25
25
|
*/
|
|
26
|
-
declare function ThemeModeSwitchOutside(props: ThemeModeSwitchOutsideProps):
|
|
26
|
+
declare function ThemeModeSwitchOutside(props: ThemeModeSwitchOutsideProps): react_jsx_runtime20.JSX.Element;
|
|
27
27
|
declare namespace ThemeModeSwitchOutside {
|
|
28
28
|
var displayName: string;
|
|
29
29
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime16 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/theme-toggle/ThemeModeToggleButton.d.ts
|
|
4
4
|
interface ThemeModeToggleButtonProps {
|
|
@@ -14,7 +14,7 @@ interface ThemeModeToggleButtonProps {
|
|
|
14
14
|
* Light/Dark toggle button.
|
|
15
15
|
* Pure component - toggles between light and dark.
|
|
16
16
|
*/
|
|
17
|
-
declare function ThemeModeToggleButton(props: ThemeModeToggleButtonProps):
|
|
17
|
+
declare function ThemeModeToggleButton(props: ThemeModeToggleButtonProps): react_jsx_runtime16.JSX.Element;
|
|
18
18
|
declare namespace ThemeModeToggleButton {
|
|
19
19
|
var displayName: string;
|
|
20
20
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_variant_config = require('../variant-config.cjs');
|
|
2
3
|
const require_Alert = require('../Alert.cjs');
|
|
3
4
|
let __pixpilot_shadcn = require("@pixpilot/shadcn");
|
|
4
5
|
__pixpilot_shadcn = require_rolldown_runtime.__toESM(__pixpilot_shadcn);
|
|
@@ -11,25 +12,56 @@ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
|
11
12
|
|
|
12
13
|
//#region src/toast/AlertToast.tsx
|
|
13
14
|
const AlertToast = (props) => {
|
|
14
|
-
const { duration, onClose,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const { children, className, description, duration, icon = true, id, onClose, title, variant = "default",...rest } = props;
|
|
16
|
+
const config = require_variant_config.variantConfig[variant] ?? require_variant_config.variantConfig.default;
|
|
17
|
+
const hasTitle = title != null && title.trim() !== "";
|
|
18
|
+
const closeButton = onClose && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
19
|
+
className: "flex shrink-0 items-start pt-0.5 ",
|
|
20
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
21
|
+
id,
|
|
22
|
+
type: "button",
|
|
23
|
+
className: "cursor-pointer opacity-80 transition-opacity hover:opacity-100",
|
|
24
|
+
onClick: onClose,
|
|
25
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XIcon, { className: "size-4.5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
26
|
+
className: "sr-only",
|
|
27
|
+
children: "Close"
|
|
28
|
+
})]
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
if (onClose) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Alert.Alert, {
|
|
32
|
+
icon,
|
|
17
33
|
...rest,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
variant,
|
|
35
|
+
className: (0, __pixpilot_shadcn.cn)("shadow-md pr-3", className),
|
|
36
|
+
description: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
37
|
+
className: "flex w-full min-w-0 items-start gap-3",
|
|
38
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39
|
+
className: "flex min-w-0 flex-1 flex-col gap-1",
|
|
40
|
+
children: [
|
|
41
|
+
hasTitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
42
|
+
"data-slot": "toast-title",
|
|
43
|
+
className: (0, __pixpilot_shadcn.cn)("line-clamp-1 min-h-4 font-medium tracking-tight", config.textClass),
|
|
44
|
+
children: title
|
|
45
|
+
}),
|
|
46
|
+
description != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
47
|
+
"data-slot": "toast-description",
|
|
48
|
+
className: (0, __pixpilot_shadcn.cn)(config.descClass, !hasTitle && config.textClass, "whitespace-pre-wrap"),
|
|
49
|
+
children: description
|
|
50
|
+
}),
|
|
51
|
+
children
|
|
52
|
+
]
|
|
53
|
+
}), closeButton]
|
|
31
54
|
})
|
|
32
55
|
});
|
|
56
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Alert.Alert, {
|
|
57
|
+
icon,
|
|
58
|
+
...rest,
|
|
59
|
+
variant,
|
|
60
|
+
title,
|
|
61
|
+
description,
|
|
62
|
+
className: (0, __pixpilot_shadcn.cn)("shadow-md", className),
|
|
63
|
+
children
|
|
64
|
+
});
|
|
33
65
|
};
|
|
34
66
|
AlertToast.displayName = "AlertToast";
|
|
35
67
|
|
package/dist/toast/AlertToast.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { variantConfig } from "../variant-config.js";
|
|
1
2
|
import { Alert as Alert$1 } from "../Alert.js";
|
|
2
3
|
import { cn } from "@pixpilot/shadcn";
|
|
3
4
|
import { XIcon } from "lucide-react";
|
|
@@ -6,25 +7,56 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
6
7
|
|
|
7
8
|
//#region src/toast/AlertToast.tsx
|
|
8
9
|
const AlertToast = (props) => {
|
|
9
|
-
const { duration, onClose,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const { children, className, description, duration, icon = true, id, onClose, title, variant = "default",...rest } = props;
|
|
11
|
+
const config = variantConfig[variant] ?? variantConfig.default;
|
|
12
|
+
const hasTitle = title != null && title.trim() !== "";
|
|
13
|
+
const closeButton = onClose && /* @__PURE__ */ jsx("div", {
|
|
14
|
+
className: "flex shrink-0 items-start pt-0.5 ",
|
|
15
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
16
|
+
id,
|
|
17
|
+
type: "button",
|
|
18
|
+
className: "cursor-pointer opacity-80 transition-opacity hover:opacity-100",
|
|
19
|
+
onClick: onClose,
|
|
20
|
+
children: [/* @__PURE__ */ jsx(XIcon, { className: "size-4.5" }), /* @__PURE__ */ jsx("span", {
|
|
21
|
+
className: "sr-only",
|
|
22
|
+
children: "Close"
|
|
23
|
+
})]
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
if (onClose) return /* @__PURE__ */ jsx(Alert$1, {
|
|
27
|
+
icon,
|
|
12
28
|
...rest,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
variant,
|
|
30
|
+
className: cn("shadow-md pr-3", className),
|
|
31
|
+
description: /* @__PURE__ */ jsxs("div", {
|
|
32
|
+
className: "flex w-full min-w-0 items-start gap-3",
|
|
33
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
34
|
+
className: "flex min-w-0 flex-1 flex-col gap-1",
|
|
35
|
+
children: [
|
|
36
|
+
hasTitle && /* @__PURE__ */ jsx("div", {
|
|
37
|
+
"data-slot": "toast-title",
|
|
38
|
+
className: cn("line-clamp-1 min-h-4 font-medium tracking-tight", config.textClass),
|
|
39
|
+
children: title
|
|
40
|
+
}),
|
|
41
|
+
description != null && /* @__PURE__ */ jsx("div", {
|
|
42
|
+
"data-slot": "toast-description",
|
|
43
|
+
className: cn(config.descClass, !hasTitle && config.textClass, "whitespace-pre-wrap"),
|
|
44
|
+
children: description
|
|
45
|
+
}),
|
|
46
|
+
children
|
|
47
|
+
]
|
|
48
|
+
}), closeButton]
|
|
26
49
|
})
|
|
27
50
|
});
|
|
51
|
+
return /* @__PURE__ */ jsx(Alert$1, {
|
|
52
|
+
icon,
|
|
53
|
+
...rest,
|
|
54
|
+
variant,
|
|
55
|
+
title,
|
|
56
|
+
description,
|
|
57
|
+
className: cn("shadow-md", className),
|
|
58
|
+
children
|
|
59
|
+
});
|
|
28
60
|
};
|
|
29
61
|
AlertToast.displayName = "AlertToast";
|
|
30
62
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixpilot/shadcn-ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.28.0",
|
|
5
5
|
"description": "Custom UI components and utilities built with shadcn/ui.",
|
|
6
6
|
"author": "m.doaie <m.doaie@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"typescript": "^5.9.3",
|
|
66
66
|
"@internal/eslint-config": "0.3.0",
|
|
67
67
|
"@internal/hooks": "0.0.0",
|
|
68
|
-
"@internal/prettier-config": "0.0.1",
|
|
69
68
|
"@internal/tsconfig": "0.1.0",
|
|
69
|
+
"@internal/prettier-config": "0.0.1",
|
|
70
70
|
"@internal/tsdown-config": "0.1.0",
|
|
71
71
|
"@internal/vitest-config": "0.1.0"
|
|
72
72
|
},
|