@bizapps/design-system-testing 1.7.2 → 1.8.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/editor.cjs CHANGED
@@ -868,20 +868,21 @@ function ResizableImageView({ node, updateAttributes, selected, extension }) {
868
868
  if (sizeRef.current.width > 0 || fittedSrcRef.current === src) return;
869
869
  const fit = () => {
870
870
  const available = img.closest(".ProseMirror")?.clientWidth ?? 0;
871
- if (!img.naturalWidth || !img.naturalHeight || available <= 0) return;
871
+ if (!img.naturalWidth || !img.naturalHeight || available <= 0) return false;
872
872
  fittedSrcRef.current = src;
873
873
  const nextWidth = Math.min(img.naturalWidth, available);
874
874
  updateAttributes({
875
875
  width: nextWidth,
876
876
  height: Math.round(nextWidth / (img.naturalWidth / img.naturalHeight))
877
877
  });
878
+ return true;
878
879
  };
879
- if (img.complete) {
880
- fit();
881
- return;
882
- }
883
- img.addEventListener("load", fit, { once: true });
884
- return () => img.removeEventListener("load", fit);
880
+ if (img.complete && fit()) return;
881
+ const onLoad = () => {
882
+ if (fit()) img.removeEventListener("load", onLoad);
883
+ };
884
+ img.addEventListener("load", onLoad);
885
+ return () => img.removeEventListener("load", onLoad);
885
886
  }, [src, updateAttributes]);
886
887
  const onPointerDown = react.useCallback(
887
888
  (event) => {
@@ -981,6 +982,78 @@ function createResizableImage(options) {
981
982
  }
982
983
  });
983
984
  }
985
+ function LinkActions({ editor, labels, onEdit, onOpen }) {
986
+ const href = react$1.useEditorState({
987
+ editor,
988
+ selector: ({ editor: current }) => current.getAttributes("link").href ?? ""
989
+ });
990
+ return /* @__PURE__ */ jsxRuntime.jsxs(
991
+ "div",
992
+ {
993
+ "data-slot": "link-bubble-menu",
994
+ className: "bg-popover text-popover-foreground flex items-center gap-1 rounded-md border p-1 shadow-md",
995
+ children: [
996
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground max-w-[16rem] truncate px-2 text-xs", children: href }),
997
+ /* @__PURE__ */ jsxRuntime.jsx(
998
+ Button,
999
+ {
1000
+ type: "button",
1001
+ size: "sm",
1002
+ variant: "ghost",
1003
+ title: labels.open,
1004
+ "aria-label": labels.open,
1005
+ disabled: !href,
1006
+ onClick: () => {
1007
+ if (!href) return;
1008
+ if (onOpen) {
1009
+ onOpen(href);
1010
+ return;
1011
+ }
1012
+ window.open(href, "_blank", "noopener,noreferrer");
1013
+ },
1014
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4" })
1015
+ }
1016
+ ),
1017
+ /* @__PURE__ */ jsxRuntime.jsx(
1018
+ Button,
1019
+ {
1020
+ type: "button",
1021
+ size: "sm",
1022
+ variant: "ghost",
1023
+ title: labels.edit,
1024
+ "aria-label": labels.edit,
1025
+ onClick: onEdit,
1026
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-4 w-4" })
1027
+ }
1028
+ ),
1029
+ /* @__PURE__ */ jsxRuntime.jsx(
1030
+ Button,
1031
+ {
1032
+ type: "button",
1033
+ size: "sm",
1034
+ variant: "ghost",
1035
+ className: "text-destructive",
1036
+ title: labels.remove,
1037
+ "aria-label": labels.remove,
1038
+ onClick: () => editor.chain().focus().extendMarkRange("link").unsetLink().run(),
1039
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Unlink, { className: "h-4 w-4" })
1040
+ }
1041
+ )
1042
+ ]
1043
+ }
1044
+ );
1045
+ }
1046
+ function LinkBubbleMenu({ editor, labels, onEdit, onOpen }) {
1047
+ const shouldShow = react.useCallback(
1048
+ // Only while the caret is actually in a link — otherwise this bar would
1049
+ // compete with any other bubble menu the consumer adds.
1050
+ ({ editor: current }) => current.isActive("link"),
1051
+ []
1052
+ );
1053
+ const options = react.useMemo(() => ({ placement: "bottom", offset: 8 }), []);
1054
+ if (!editor) return null;
1055
+ return /* @__PURE__ */ jsxRuntime.jsx(menus.BubbleMenu, { editor, shouldShow, options, children: /* @__PURE__ */ jsxRuntime.jsx(LinkActions, { editor, labels, onEdit, onOpen }) });
1056
+ }
984
1057
  function ListMenu({ editor, triggerLabel, icon, options }) {
985
1058
  const active = options.find((option) => editor?.isActive(option.node));
986
1059
  return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
@@ -1033,6 +1106,7 @@ function useRichTextEditor({
1033
1106
  onInsertImage,
1034
1107
  extraExtensions = [],
1035
1108
  extraToolbar = [],
1109
+ replaceToolbar,
1036
1110
  contentClassName,
1037
1111
  allowBase64Images = false,
1038
1112
  editorProps
@@ -1228,7 +1302,9 @@ function useRichTextEditor({
1228
1302
  )
1229
1303
  }
1230
1304
  ];
1231
- let items = builtIn;
1305
+ let items = replaceToolbar ? builtIn.map(
1306
+ (item) => item.kind !== "separator" && replaceToolbar[item.id] ? replaceToolbar[item.id] : item
1307
+ ) : builtIn;
1232
1308
  const appended = [];
1233
1309
  for (const group of extraToolbar) {
1234
1310
  if (!group.after) {
@@ -1245,8 +1321,9 @@ function useRichTextEditor({
1245
1321
  items = [...items.slice(0, at + 1), ...group.items, ...items.slice(at + 1)];
1246
1322
  }
1247
1323
  return [...items, ...appended];
1248
- }, [labels, extraToolbar, onInsertImage, openLink]);
1249
- return { editor, toolbar, linkNeedsText, currentLinkHref, applyLink };
1324
+ }, [labels, extraToolbar, replaceToolbar, onInsertImage, openLink]);
1325
+ const linkMenu = /* @__PURE__ */ jsxRuntime.jsx(LinkBubbleMenu, { editor, labels: labels.link, onEdit: openLink });
1326
+ return { editor, toolbar, linkMenu, linkNeedsText, currentLinkHref, applyLink };
1250
1327
  }
1251
1328
  function ColorMenu({ editor, labels, icon, swatches }) {
1252
1329
  const active = swatches.find((swatch) => editor?.isActive(swatch.mark));
@@ -1386,78 +1463,6 @@ function InsertLinkDialog({
1386
1463
  ] })
1387
1464
  ] }) });
1388
1465
  }
1389
- function LinkActions({ editor, labels, onEdit, onOpen }) {
1390
- const href = react$1.useEditorState({
1391
- editor,
1392
- selector: ({ editor: current }) => current.getAttributes("link").href ?? ""
1393
- });
1394
- return /* @__PURE__ */ jsxRuntime.jsxs(
1395
- "div",
1396
- {
1397
- "data-slot": "link-bubble-menu",
1398
- className: "bg-popover text-popover-foreground flex items-center gap-1 rounded-md border p-1 shadow-md",
1399
- children: [
1400
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground max-w-[16rem] truncate px-2 text-xs", children: href }),
1401
- /* @__PURE__ */ jsxRuntime.jsx(
1402
- Button,
1403
- {
1404
- type: "button",
1405
- size: "sm",
1406
- variant: "ghost",
1407
- title: labels.open,
1408
- "aria-label": labels.open,
1409
- disabled: !href,
1410
- onClick: () => {
1411
- if (!href) return;
1412
- if (onOpen) {
1413
- onOpen(href);
1414
- return;
1415
- }
1416
- window.open(href, "_blank", "noopener,noreferrer");
1417
- },
1418
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-4 w-4" })
1419
- }
1420
- ),
1421
- /* @__PURE__ */ jsxRuntime.jsx(
1422
- Button,
1423
- {
1424
- type: "button",
1425
- size: "sm",
1426
- variant: "ghost",
1427
- title: labels.edit,
1428
- "aria-label": labels.edit,
1429
- onClick: onEdit,
1430
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-4 w-4" })
1431
- }
1432
- ),
1433
- /* @__PURE__ */ jsxRuntime.jsx(
1434
- Button,
1435
- {
1436
- type: "button",
1437
- size: "sm",
1438
- variant: "ghost",
1439
- className: "text-destructive",
1440
- title: labels.remove,
1441
- "aria-label": labels.remove,
1442
- onClick: () => editor.chain().focus().extendMarkRange("link").unsetLink().run(),
1443
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Unlink, { className: "h-4 w-4" })
1444
- }
1445
- )
1446
- ]
1447
- }
1448
- );
1449
- }
1450
- function LinkBubbleMenu({ editor, labels, onEdit, onOpen }) {
1451
- const shouldShow = react.useCallback(
1452
- // Only while the caret is actually in a link — otherwise this bar would
1453
- // compete with any other bubble menu the consumer adds.
1454
- ({ editor: current }) => current.isActive("link"),
1455
- []
1456
- );
1457
- const options = react.useMemo(() => ({ placement: "bottom", offset: 8 }), []);
1458
- if (!editor) return null;
1459
- return /* @__PURE__ */ jsxRuntime.jsx(menus.BubbleMenu, { editor, shouldShow, options, children: /* @__PURE__ */ jsxRuntime.jsx(LinkActions, { editor, labels, onEdit, onOpen }) });
1460
- }
1461
1466
 
1462
1467
  exports.ColorMenu = ColorMenu;
1463
1468
  exports.EDITOR_CONTENT_STYLE = EDITOR_CONTENT_STYLE;