@bizapps/design-system-testing 1.7.2 → 1.8.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/editor.cjs +79 -75
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.d.cts +49 -31
- package/dist/editor.d.ts +49 -31
- package/dist/editor.js +79 -75
- package/dist/editor.js.map +1 -1
- package/package.json +1 -1
package/dist/editor.d.cts
CHANGED
|
@@ -164,6 +164,36 @@ interface InsertImageDialogProps {
|
|
|
164
164
|
*/
|
|
165
165
|
declare function InsertImageDialog({ open, onOpenChange, labels, url, onUrlChange, alt, onAltChange, file, onFileChange, uploading, onApply, onCancel, removable, onRemove, maxSizeBytes, accept, }: InsertImageDialogProps): react.JSX.Element;
|
|
166
166
|
|
|
167
|
+
interface LinkBubbleMenuLabels {
|
|
168
|
+
open: string;
|
|
169
|
+
edit: string;
|
|
170
|
+
remove: string;
|
|
171
|
+
}
|
|
172
|
+
interface LinkBubbleMenuProps {
|
|
173
|
+
editor: Editor | null;
|
|
174
|
+
labels: LinkBubbleMenuLabels;
|
|
175
|
+
/** Opens the consumer's link dialog, pre-filled with the current href. */
|
|
176
|
+
onEdit: () => void;
|
|
177
|
+
/**
|
|
178
|
+
* Follows the link. Left to the consumer for the cases this package cannot
|
|
179
|
+
* judge — routing instead of navigating, or confirming first.
|
|
180
|
+
*
|
|
181
|
+
* Defaults to opening a new tab, which is also what Ctrl/Cmd-click does, so
|
|
182
|
+
* the author never loses unsaved work just by checking a URL.
|
|
183
|
+
*/
|
|
184
|
+
onOpen?: (href: string) => void;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* A floating bar that appears when the caret sits inside a link, offering to
|
|
188
|
+
* open, edit or unlink it.
|
|
189
|
+
*
|
|
190
|
+
* It exists because an editor cannot let a plain click navigate: clicking is how
|
|
191
|
+
* you place the caret to fix a typo, so `openOnClick` stays false and this gives
|
|
192
|
+
* the author a deliberate way out to the URL. Ctrl/Cmd-click is wired separately,
|
|
193
|
+
* on the editor itself, for people who expect the shortcut.
|
|
194
|
+
*/
|
|
195
|
+
declare function LinkBubbleMenu({ editor, labels, onEdit, onOpen }: LinkBubbleMenuProps): react.JSX.Element | null;
|
|
196
|
+
|
|
167
197
|
/**
|
|
168
198
|
* Whatever `useEditor` accepts in its `extensions` array.
|
|
169
199
|
*
|
|
@@ -190,6 +220,8 @@ interface RichTextEditorLabels {
|
|
|
190
220
|
bullet: string;
|
|
191
221
|
ordered: string;
|
|
192
222
|
};
|
|
223
|
+
/** The floating bar shown while the caret sits inside a link. */
|
|
224
|
+
link: LinkBubbleMenuLabels;
|
|
193
225
|
table: TableMenuLabels;
|
|
194
226
|
highlight: string;
|
|
195
227
|
}
|
|
@@ -217,6 +249,14 @@ interface UseRichTextEditorOptions {
|
|
|
217
249
|
after?: string;
|
|
218
250
|
items: ToolbarItem[];
|
|
219
251
|
}[];
|
|
252
|
+
/**
|
|
253
|
+
* Replaces a built-in entry, keyed by its id.
|
|
254
|
+
*
|
|
255
|
+
* For when a product needs a richer version of something the preset already
|
|
256
|
+
* provides — swapping the single highlight button for a palette of shades,
|
|
257
|
+
* say. Replacing rather than adding keeps the toolbar from carrying both.
|
|
258
|
+
*/
|
|
259
|
+
replaceToolbar?: Record<string, ToolbarItem>;
|
|
220
260
|
/** Merged on top of the built-in content styles. */
|
|
221
261
|
contentClassName?: string;
|
|
222
262
|
/** Allows data: URIs in images. Off by default: uploads belong in storage. */
|
|
@@ -233,6 +273,14 @@ interface UseRichTextEditorOptions {
|
|
|
233
273
|
}
|
|
234
274
|
interface UseRichTextEditorResult {
|
|
235
275
|
editor: Editor | null;
|
|
276
|
+
/**
|
|
277
|
+
* The floating link bar, ready to render beside `<RichTextEditor />`.
|
|
278
|
+
*
|
|
279
|
+
* Returned as an element rather than left to the consumer because it is easy
|
|
280
|
+
* to forget, and an editor without it gives the author no way to reach or
|
|
281
|
+
* remove a link they have already inserted.
|
|
282
|
+
*/
|
|
283
|
+
linkMenu: ReactNode;
|
|
236
284
|
/** Ready for `<RichTextEditor items={...} />`. */
|
|
237
285
|
toolbar: ToolbarItem[];
|
|
238
286
|
/** True when the caret has no selection, so a new link needs its own text. */
|
|
@@ -254,7 +302,7 @@ interface UseRichTextEditorResult {
|
|
|
254
302
|
* What stays with the consumer is what only it can know: the marks its document
|
|
255
303
|
* contract allows, and the copy. Both arrive as options.
|
|
256
304
|
*/
|
|
257
|
-
declare function useRichTextEditor({ labels, onUpdate, content, onInsertLink, onInsertImage, extraExtensions, extraToolbar, contentClassName, allowBase64Images, editorProps, }: UseRichTextEditorOptions): UseRichTextEditorResult;
|
|
305
|
+
declare function useRichTextEditor({ labels, onUpdate, content, onInsertLink, onInsertImage, extraExtensions, extraToolbar, replaceToolbar, contentClassName, allowBase64Images, editorProps, }: UseRichTextEditorOptions): UseRichTextEditorResult;
|
|
258
306
|
|
|
259
307
|
/**
|
|
260
308
|
* One entry in the palette.
|
|
@@ -363,36 +411,6 @@ interface InsertLinkDialogProps {
|
|
|
363
411
|
*/
|
|
364
412
|
declare function InsertLinkDialog({ open, onOpenChange, labels, url, onUrlChange, text, onTextChange, needsText, onApply, onCancel, }: InsertLinkDialogProps): react.JSX.Element;
|
|
365
413
|
|
|
366
|
-
interface LinkBubbleMenuLabels {
|
|
367
|
-
open: string;
|
|
368
|
-
edit: string;
|
|
369
|
-
remove: string;
|
|
370
|
-
}
|
|
371
|
-
interface LinkBubbleMenuProps {
|
|
372
|
-
editor: Editor | null;
|
|
373
|
-
labels: LinkBubbleMenuLabels;
|
|
374
|
-
/** Opens the consumer's link dialog, pre-filled with the current href. */
|
|
375
|
-
onEdit: () => void;
|
|
376
|
-
/**
|
|
377
|
-
* Follows the link. Left to the consumer for the cases this package cannot
|
|
378
|
-
* judge — routing instead of navigating, or confirming first.
|
|
379
|
-
*
|
|
380
|
-
* Defaults to opening a new tab, which is also what Ctrl/Cmd-click does, so
|
|
381
|
-
* the author never loses unsaved work just by checking a URL.
|
|
382
|
-
*/
|
|
383
|
-
onOpen?: (href: string) => void;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* A floating bar that appears when the caret sits inside a link, offering to
|
|
387
|
-
* open, edit or unlink it.
|
|
388
|
-
*
|
|
389
|
-
* It exists because an editor cannot let a plain click navigate: clicking is how
|
|
390
|
-
* you place the caret to fix a typo, so `openOnClick` stays false and this gives
|
|
391
|
-
* the author a deliberate way out to the URL. Ctrl/Cmd-click is wired separately,
|
|
392
|
-
* on the editor itself, for people who expect the shortcut.
|
|
393
|
-
*/
|
|
394
|
-
declare function LinkBubbleMenu({ editor, labels, onEdit, onOpen }: LinkBubbleMenuProps): react.JSX.Element | null;
|
|
395
|
-
|
|
396
414
|
interface ResizableImageOptions {
|
|
397
415
|
/** Already translated: names the resize handle for assistive tech. */
|
|
398
416
|
resizeLabel: string;
|
package/dist/editor.d.ts
CHANGED
|
@@ -164,6 +164,36 @@ interface InsertImageDialogProps {
|
|
|
164
164
|
*/
|
|
165
165
|
declare function InsertImageDialog({ open, onOpenChange, labels, url, onUrlChange, alt, onAltChange, file, onFileChange, uploading, onApply, onCancel, removable, onRemove, maxSizeBytes, accept, }: InsertImageDialogProps): react.JSX.Element;
|
|
166
166
|
|
|
167
|
+
interface LinkBubbleMenuLabels {
|
|
168
|
+
open: string;
|
|
169
|
+
edit: string;
|
|
170
|
+
remove: string;
|
|
171
|
+
}
|
|
172
|
+
interface LinkBubbleMenuProps {
|
|
173
|
+
editor: Editor | null;
|
|
174
|
+
labels: LinkBubbleMenuLabels;
|
|
175
|
+
/** Opens the consumer's link dialog, pre-filled with the current href. */
|
|
176
|
+
onEdit: () => void;
|
|
177
|
+
/**
|
|
178
|
+
* Follows the link. Left to the consumer for the cases this package cannot
|
|
179
|
+
* judge — routing instead of navigating, or confirming first.
|
|
180
|
+
*
|
|
181
|
+
* Defaults to opening a new tab, which is also what Ctrl/Cmd-click does, so
|
|
182
|
+
* the author never loses unsaved work just by checking a URL.
|
|
183
|
+
*/
|
|
184
|
+
onOpen?: (href: string) => void;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* A floating bar that appears when the caret sits inside a link, offering to
|
|
188
|
+
* open, edit or unlink it.
|
|
189
|
+
*
|
|
190
|
+
* It exists because an editor cannot let a plain click navigate: clicking is how
|
|
191
|
+
* you place the caret to fix a typo, so `openOnClick` stays false and this gives
|
|
192
|
+
* the author a deliberate way out to the URL. Ctrl/Cmd-click is wired separately,
|
|
193
|
+
* on the editor itself, for people who expect the shortcut.
|
|
194
|
+
*/
|
|
195
|
+
declare function LinkBubbleMenu({ editor, labels, onEdit, onOpen }: LinkBubbleMenuProps): react.JSX.Element | null;
|
|
196
|
+
|
|
167
197
|
/**
|
|
168
198
|
* Whatever `useEditor` accepts in its `extensions` array.
|
|
169
199
|
*
|
|
@@ -190,6 +220,8 @@ interface RichTextEditorLabels {
|
|
|
190
220
|
bullet: string;
|
|
191
221
|
ordered: string;
|
|
192
222
|
};
|
|
223
|
+
/** The floating bar shown while the caret sits inside a link. */
|
|
224
|
+
link: LinkBubbleMenuLabels;
|
|
193
225
|
table: TableMenuLabels;
|
|
194
226
|
highlight: string;
|
|
195
227
|
}
|
|
@@ -217,6 +249,14 @@ interface UseRichTextEditorOptions {
|
|
|
217
249
|
after?: string;
|
|
218
250
|
items: ToolbarItem[];
|
|
219
251
|
}[];
|
|
252
|
+
/**
|
|
253
|
+
* Replaces a built-in entry, keyed by its id.
|
|
254
|
+
*
|
|
255
|
+
* For when a product needs a richer version of something the preset already
|
|
256
|
+
* provides — swapping the single highlight button for a palette of shades,
|
|
257
|
+
* say. Replacing rather than adding keeps the toolbar from carrying both.
|
|
258
|
+
*/
|
|
259
|
+
replaceToolbar?: Record<string, ToolbarItem>;
|
|
220
260
|
/** Merged on top of the built-in content styles. */
|
|
221
261
|
contentClassName?: string;
|
|
222
262
|
/** Allows data: URIs in images. Off by default: uploads belong in storage. */
|
|
@@ -233,6 +273,14 @@ interface UseRichTextEditorOptions {
|
|
|
233
273
|
}
|
|
234
274
|
interface UseRichTextEditorResult {
|
|
235
275
|
editor: Editor | null;
|
|
276
|
+
/**
|
|
277
|
+
* The floating link bar, ready to render beside `<RichTextEditor />`.
|
|
278
|
+
*
|
|
279
|
+
* Returned as an element rather than left to the consumer because it is easy
|
|
280
|
+
* to forget, and an editor without it gives the author no way to reach or
|
|
281
|
+
* remove a link they have already inserted.
|
|
282
|
+
*/
|
|
283
|
+
linkMenu: ReactNode;
|
|
236
284
|
/** Ready for `<RichTextEditor items={...} />`. */
|
|
237
285
|
toolbar: ToolbarItem[];
|
|
238
286
|
/** True when the caret has no selection, so a new link needs its own text. */
|
|
@@ -254,7 +302,7 @@ interface UseRichTextEditorResult {
|
|
|
254
302
|
* What stays with the consumer is what only it can know: the marks its document
|
|
255
303
|
* contract allows, and the copy. Both arrive as options.
|
|
256
304
|
*/
|
|
257
|
-
declare function useRichTextEditor({ labels, onUpdate, content, onInsertLink, onInsertImage, extraExtensions, extraToolbar, contentClassName, allowBase64Images, editorProps, }: UseRichTextEditorOptions): UseRichTextEditorResult;
|
|
305
|
+
declare function useRichTextEditor({ labels, onUpdate, content, onInsertLink, onInsertImage, extraExtensions, extraToolbar, replaceToolbar, contentClassName, allowBase64Images, editorProps, }: UseRichTextEditorOptions): UseRichTextEditorResult;
|
|
258
306
|
|
|
259
307
|
/**
|
|
260
308
|
* One entry in the palette.
|
|
@@ -363,36 +411,6 @@ interface InsertLinkDialogProps {
|
|
|
363
411
|
*/
|
|
364
412
|
declare function InsertLinkDialog({ open, onOpenChange, labels, url, onUrlChange, text, onTextChange, needsText, onApply, onCancel, }: InsertLinkDialogProps): react.JSX.Element;
|
|
365
413
|
|
|
366
|
-
interface LinkBubbleMenuLabels {
|
|
367
|
-
open: string;
|
|
368
|
-
edit: string;
|
|
369
|
-
remove: string;
|
|
370
|
-
}
|
|
371
|
-
interface LinkBubbleMenuProps {
|
|
372
|
-
editor: Editor | null;
|
|
373
|
-
labels: LinkBubbleMenuLabels;
|
|
374
|
-
/** Opens the consumer's link dialog, pre-filled with the current href. */
|
|
375
|
-
onEdit: () => void;
|
|
376
|
-
/**
|
|
377
|
-
* Follows the link. Left to the consumer for the cases this package cannot
|
|
378
|
-
* judge — routing instead of navigating, or confirming first.
|
|
379
|
-
*
|
|
380
|
-
* Defaults to opening a new tab, which is also what Ctrl/Cmd-click does, so
|
|
381
|
-
* the author never loses unsaved work just by checking a URL.
|
|
382
|
-
*/
|
|
383
|
-
onOpen?: (href: string) => void;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* A floating bar that appears when the caret sits inside a link, offering to
|
|
387
|
-
* open, edit or unlink it.
|
|
388
|
-
*
|
|
389
|
-
* It exists because an editor cannot let a plain click navigate: clicking is how
|
|
390
|
-
* you place the caret to fix a typo, so `openOnClick` stays false and this gives
|
|
391
|
-
* the author a deliberate way out to the URL. Ctrl/Cmd-click is wired separately,
|
|
392
|
-
* on the editor itself, for people who expect the shortcut.
|
|
393
|
-
*/
|
|
394
|
-
declare function LinkBubbleMenu({ editor, labels, onEdit, onOpen }: LinkBubbleMenuProps): react.JSX.Element | null;
|
|
395
|
-
|
|
396
414
|
interface ResizableImageOptions {
|
|
397
415
|
/** Already translated: names the resize handle for assistive tech. */
|
|
398
416
|
resizeLabel: string;
|
package/dist/editor.js
CHANGED
|
@@ -974,6 +974,78 @@ function createResizableImage(options) {
|
|
|
974
974
|
}
|
|
975
975
|
});
|
|
976
976
|
}
|
|
977
|
+
function LinkActions({ editor, labels, onEdit, onOpen }) {
|
|
978
|
+
const href = useEditorState({
|
|
979
|
+
editor,
|
|
980
|
+
selector: ({ editor: current }) => current.getAttributes("link").href ?? ""
|
|
981
|
+
});
|
|
982
|
+
return /* @__PURE__ */ jsxs(
|
|
983
|
+
"div",
|
|
984
|
+
{
|
|
985
|
+
"data-slot": "link-bubble-menu",
|
|
986
|
+
className: "bg-popover text-popover-foreground flex items-center gap-1 rounded-md border p-1 shadow-md",
|
|
987
|
+
children: [
|
|
988
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground max-w-[16rem] truncate px-2 text-xs", children: href }),
|
|
989
|
+
/* @__PURE__ */ jsx(
|
|
990
|
+
Button,
|
|
991
|
+
{
|
|
992
|
+
type: "button",
|
|
993
|
+
size: "sm",
|
|
994
|
+
variant: "ghost",
|
|
995
|
+
title: labels.open,
|
|
996
|
+
"aria-label": labels.open,
|
|
997
|
+
disabled: !href,
|
|
998
|
+
onClick: () => {
|
|
999
|
+
if (!href) return;
|
|
1000
|
+
if (onOpen) {
|
|
1001
|
+
onOpen(href);
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
window.open(href, "_blank", "noopener,noreferrer");
|
|
1005
|
+
},
|
|
1006
|
+
children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4" })
|
|
1007
|
+
}
|
|
1008
|
+
),
|
|
1009
|
+
/* @__PURE__ */ jsx(
|
|
1010
|
+
Button,
|
|
1011
|
+
{
|
|
1012
|
+
type: "button",
|
|
1013
|
+
size: "sm",
|
|
1014
|
+
variant: "ghost",
|
|
1015
|
+
title: labels.edit,
|
|
1016
|
+
"aria-label": labels.edit,
|
|
1017
|
+
onClick: onEdit,
|
|
1018
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
1019
|
+
}
|
|
1020
|
+
),
|
|
1021
|
+
/* @__PURE__ */ jsx(
|
|
1022
|
+
Button,
|
|
1023
|
+
{
|
|
1024
|
+
type: "button",
|
|
1025
|
+
size: "sm",
|
|
1026
|
+
variant: "ghost",
|
|
1027
|
+
className: "text-destructive",
|
|
1028
|
+
title: labels.remove,
|
|
1029
|
+
"aria-label": labels.remove,
|
|
1030
|
+
onClick: () => editor.chain().focus().extendMarkRange("link").unsetLink().run(),
|
|
1031
|
+
children: /* @__PURE__ */ jsx(Unlink, { className: "h-4 w-4" })
|
|
1032
|
+
}
|
|
1033
|
+
)
|
|
1034
|
+
]
|
|
1035
|
+
}
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
function LinkBubbleMenu({ editor, labels, onEdit, onOpen }) {
|
|
1039
|
+
const shouldShow = useCallback(
|
|
1040
|
+
// Only while the caret is actually in a link — otherwise this bar would
|
|
1041
|
+
// compete with any other bubble menu the consumer adds.
|
|
1042
|
+
({ editor: current }) => current.isActive("link"),
|
|
1043
|
+
[]
|
|
1044
|
+
);
|
|
1045
|
+
const options = useMemo(() => ({ placement: "bottom", offset: 8 }), []);
|
|
1046
|
+
if (!editor) return null;
|
|
1047
|
+
return /* @__PURE__ */ jsx(BubbleMenu, { editor, shouldShow, options, children: /* @__PURE__ */ jsx(LinkActions, { editor, labels, onEdit, onOpen }) });
|
|
1048
|
+
}
|
|
977
1049
|
function ListMenu({ editor, triggerLabel, icon, options }) {
|
|
978
1050
|
const active = options.find((option) => editor?.isActive(option.node));
|
|
979
1051
|
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
@@ -1026,6 +1098,7 @@ function useRichTextEditor({
|
|
|
1026
1098
|
onInsertImage,
|
|
1027
1099
|
extraExtensions = [],
|
|
1028
1100
|
extraToolbar = [],
|
|
1101
|
+
replaceToolbar,
|
|
1029
1102
|
contentClassName,
|
|
1030
1103
|
allowBase64Images = false,
|
|
1031
1104
|
editorProps
|
|
@@ -1221,7 +1294,9 @@ function useRichTextEditor({
|
|
|
1221
1294
|
)
|
|
1222
1295
|
}
|
|
1223
1296
|
];
|
|
1224
|
-
let items = builtIn
|
|
1297
|
+
let items = replaceToolbar ? builtIn.map(
|
|
1298
|
+
(item) => item.kind !== "separator" && replaceToolbar[item.id] ? replaceToolbar[item.id] : item
|
|
1299
|
+
) : builtIn;
|
|
1225
1300
|
const appended = [];
|
|
1226
1301
|
for (const group of extraToolbar) {
|
|
1227
1302
|
if (!group.after) {
|
|
@@ -1238,8 +1313,9 @@ function useRichTextEditor({
|
|
|
1238
1313
|
items = [...items.slice(0, at + 1), ...group.items, ...items.slice(at + 1)];
|
|
1239
1314
|
}
|
|
1240
1315
|
return [...items, ...appended];
|
|
1241
|
-
}, [labels, extraToolbar, onInsertImage, openLink]);
|
|
1242
|
-
|
|
1316
|
+
}, [labels, extraToolbar, replaceToolbar, onInsertImage, openLink]);
|
|
1317
|
+
const linkMenu = /* @__PURE__ */ jsx(LinkBubbleMenu, { editor, labels: labels.link, onEdit: openLink });
|
|
1318
|
+
return { editor, toolbar, linkMenu, linkNeedsText, currentLinkHref, applyLink };
|
|
1243
1319
|
}
|
|
1244
1320
|
function ColorMenu({ editor, labels, icon, swatches }) {
|
|
1245
1321
|
const active = swatches.find((swatch) => editor?.isActive(swatch.mark));
|
|
@@ -1379,78 +1455,6 @@ function InsertLinkDialog({
|
|
|
1379
1455
|
] })
|
|
1380
1456
|
] }) });
|
|
1381
1457
|
}
|
|
1382
|
-
function LinkActions({ editor, labels, onEdit, onOpen }) {
|
|
1383
|
-
const href = useEditorState({
|
|
1384
|
-
editor,
|
|
1385
|
-
selector: ({ editor: current }) => current.getAttributes("link").href ?? ""
|
|
1386
|
-
});
|
|
1387
|
-
return /* @__PURE__ */ jsxs(
|
|
1388
|
-
"div",
|
|
1389
|
-
{
|
|
1390
|
-
"data-slot": "link-bubble-menu",
|
|
1391
|
-
className: "bg-popover text-popover-foreground flex items-center gap-1 rounded-md border p-1 shadow-md",
|
|
1392
|
-
children: [
|
|
1393
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground max-w-[16rem] truncate px-2 text-xs", children: href }),
|
|
1394
|
-
/* @__PURE__ */ jsx(
|
|
1395
|
-
Button,
|
|
1396
|
-
{
|
|
1397
|
-
type: "button",
|
|
1398
|
-
size: "sm",
|
|
1399
|
-
variant: "ghost",
|
|
1400
|
-
title: labels.open,
|
|
1401
|
-
"aria-label": labels.open,
|
|
1402
|
-
disabled: !href,
|
|
1403
|
-
onClick: () => {
|
|
1404
|
-
if (!href) return;
|
|
1405
|
-
if (onOpen) {
|
|
1406
|
-
onOpen(href);
|
|
1407
|
-
return;
|
|
1408
|
-
}
|
|
1409
|
-
window.open(href, "_blank", "noopener,noreferrer");
|
|
1410
|
-
},
|
|
1411
|
-
children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4" })
|
|
1412
|
-
}
|
|
1413
|
-
),
|
|
1414
|
-
/* @__PURE__ */ jsx(
|
|
1415
|
-
Button,
|
|
1416
|
-
{
|
|
1417
|
-
type: "button",
|
|
1418
|
-
size: "sm",
|
|
1419
|
-
variant: "ghost",
|
|
1420
|
-
title: labels.edit,
|
|
1421
|
-
"aria-label": labels.edit,
|
|
1422
|
-
onClick: onEdit,
|
|
1423
|
-
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
1424
|
-
}
|
|
1425
|
-
),
|
|
1426
|
-
/* @__PURE__ */ jsx(
|
|
1427
|
-
Button,
|
|
1428
|
-
{
|
|
1429
|
-
type: "button",
|
|
1430
|
-
size: "sm",
|
|
1431
|
-
variant: "ghost",
|
|
1432
|
-
className: "text-destructive",
|
|
1433
|
-
title: labels.remove,
|
|
1434
|
-
"aria-label": labels.remove,
|
|
1435
|
-
onClick: () => editor.chain().focus().extendMarkRange("link").unsetLink().run(),
|
|
1436
|
-
children: /* @__PURE__ */ jsx(Unlink, { className: "h-4 w-4" })
|
|
1437
|
-
}
|
|
1438
|
-
)
|
|
1439
|
-
]
|
|
1440
|
-
}
|
|
1441
|
-
);
|
|
1442
|
-
}
|
|
1443
|
-
function LinkBubbleMenu({ editor, labels, onEdit, onOpen }) {
|
|
1444
|
-
const shouldShow = useCallback(
|
|
1445
|
-
// Only while the caret is actually in a link — otherwise this bar would
|
|
1446
|
-
// compete with any other bubble menu the consumer adds.
|
|
1447
|
-
({ editor: current }) => current.isActive("link"),
|
|
1448
|
-
[]
|
|
1449
|
-
);
|
|
1450
|
-
const options = useMemo(() => ({ placement: "bottom", offset: 8 }), []);
|
|
1451
|
-
if (!editor) return null;
|
|
1452
|
-
return /* @__PURE__ */ jsx(BubbleMenu, { editor, shouldShow, options, children: /* @__PURE__ */ jsx(LinkActions, { editor, labels, onEdit, onOpen }) });
|
|
1453
|
-
}
|
|
1454
1458
|
|
|
1455
1459
|
export { ColorMenu, EDITOR_CONTENT_STYLE, InsertImageDialog, InsertLinkDialog, LinkBubbleMenu, ListMenu, RichTextEditor, RichTextToolbar, TableMenu, createResizableImage, useRichTextEditor };
|
|
1456
1460
|
//# sourceMappingURL=editor.js.map
|