tiptap-editor-custom-stg 1.0.4 → 1.0.5

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/index.d.mts CHANGED
@@ -4,7 +4,7 @@ import * as _tiptap_extension_underline from '@tiptap/extension-underline';
4
4
  import * as _tiptap_core from '@tiptap/core';
5
5
  import { Extension } from '@tiptap/core';
6
6
 
7
- type ToolbarGroup = 'history' | 'font' | 'fontSize' | 'textColor' | 'highlight' | 'list' | 'alignment' | 'table' | 'inline' | 'link' | 'insert';
7
+ type ToolbarGroup = 'history' | 'heading' | 'font' | 'fontSize' | 'textColor' | 'highlight' | 'list' | 'alignment' | 'table' | 'inline' | 'link' | 'insert';
8
8
  interface ToolbarConfig {
9
9
  groups?: ToolbarGroup[];
10
10
  showDividers?: boolean;
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as _tiptap_extension_underline from '@tiptap/extension-underline';
4
4
  import * as _tiptap_core from '@tiptap/core';
5
5
  import { Extension } from '@tiptap/core';
6
6
 
7
- type ToolbarGroup = 'history' | 'font' | 'fontSize' | 'textColor' | 'highlight' | 'list' | 'alignment' | 'table' | 'inline' | 'link' | 'insert';
7
+ type ToolbarGroup = 'history' | 'heading' | 'font' | 'fontSize' | 'textColor' | 'highlight' | 'list' | 'alignment' | 'table' | 'inline' | 'link' | 'insert';
8
8
  interface ToolbarConfig {
9
9
  groups?: ToolbarGroup[];
10
10
  showDividers?: boolean;
package/dist/index.js CHANGED
@@ -398,6 +398,11 @@ var ClearIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(LucideSvg, {
398
398
  ] });
399
399
  var SubmitIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LucideSvg, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "20 6 9 17 4 12" }) });
400
400
  var AttachIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LucideSvg, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.82-2.82l8.49-8.48" }) });
401
+ var HeadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(LucideSvg, { children: [
402
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 12h12" }),
403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 20V4" }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 20V4" })
405
+ ] });
401
406
  var FontSizeIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
402
407
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m3 7 5-5 5 5" }),
403
408
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 2v10" }),
@@ -447,6 +452,51 @@ var HistoryGroup = ({ editor, isReadOnly }) => /* @__PURE__ */ (0, import_jsx_ru
447
452
  }
448
453
  )
449
454
  ] });
455
+ var HeadingGroup = ({ editor, isReadOnly, showMenu, onToggle, onClose }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
456
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
457
+ "button",
458
+ {
459
+ title: "Heading",
460
+ onClick: onToggle,
461
+ onMouseDown: (e) => e.preventDefault(),
462
+ disabled: isReadOnly,
463
+ className: `toolbar-button-dropdown ${showMenu ? "is-active" : ""}`,
464
+ "aria-label": "Heading selection",
465
+ children: [
466
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(HeadingIcon, {}),
467
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "dropdown-arrow", viewBox: "0 0 24 24", width: "10", height: "10", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7 10l5 5 5-5z", fill: "currentColor" }) })
468
+ ]
469
+ }
470
+ ),
471
+ showMenu && !isReadOnly && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "tiptap-heading-menu", children: [
472
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
473
+ "button",
474
+ {
475
+ className: `heading-option ${!editor.isActive("heading") ? "is-active" : ""}`,
476
+ onClick: () => {
477
+ editor.chain().focus().setParagraph().run();
478
+ onClose();
479
+ },
480
+ children: "Paragraph"
481
+ }
482
+ ),
483
+ [1, 2, 3, 4, 5, 6].map((level) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
484
+ "button",
485
+ {
486
+ className: `heading-option h${level} ${editor.isActive("heading", { level }) ? "is-active" : ""}`,
487
+ onClick: () => {
488
+ editor.chain().focus().toggleHeading({ level }).run();
489
+ onClose();
490
+ },
491
+ children: [
492
+ "Heading ",
493
+ level
494
+ ]
495
+ },
496
+ level
497
+ ))
498
+ ] })
499
+ ] });
450
500
  var FontGroup = ({ editor, isReadOnly, showMenu, onToggle, onClose }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", display: "inline-flex" }, children: [
451
501
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
452
502
  "button",
@@ -622,12 +672,12 @@ var ListGroup = ({ editor, isReadOnly }) => /* @__PURE__ */ (0, import_jsx_runti
622
672
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
623
673
  "button",
624
674
  {
625
- title: "Bullet list",
675
+ title: "Bulleted list",
626
676
  onClick: () => editor.chain().focus().toggleBulletList().run(),
627
677
  onMouseDown: (e) => e.preventDefault(),
628
678
  disabled: isReadOnly,
629
679
  className: editor.isActive("bulletList") ? "is-active" : "",
630
- "aria-label": "Bullet list",
680
+ "aria-label": "Bulleted list",
631
681
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BulletListIcon, {})
632
682
  }
633
683
  ),
@@ -905,6 +955,7 @@ var TiptapEditor = ({
905
955
  const [showTextColorMenu, setShowTextColorMenu] = import_react.default.useState(false);
906
956
  const [showFontMenu, setShowFontMenu] = import_react.default.useState(false);
907
957
  const [showFontSizeMenu, setShowFontSizeMenu] = import_react.default.useState(false);
958
+ const [showHeadingMenu, setShowHeadingMenu] = import_react.default.useState(false);
908
959
  const [showLinkMenu, setShowLinkMenu] = import_react.default.useState(false);
909
960
  const [showTableMenu, setShowTableMenu] = import_react.default.useState(false);
910
961
  const [tableHoverSize, setTableHoverSize] = import_react.default.useState({ rows: 0, cols: 0 });
@@ -918,6 +969,7 @@ var TiptapEditor = ({
918
969
  setShowTextColorMenu(false);
919
970
  setShowFontMenu(false);
920
971
  setShowFontSizeMenu(false);
972
+ setShowHeadingMenu(false);
921
973
  setShowLinkMenu(false);
922
974
  setShowTableMenu(false);
923
975
  }, []);
@@ -1079,7 +1131,7 @@ var TiptapEditor = ({
1079
1131
  editor.chain().focus().run();
1080
1132
  const imagesHtml = uploadResults.map(
1081
1133
  (res) => `<img src="${res.url}" alt="${res.name}" />`
1082
- ).join("&nbsp;");
1134
+ ).join("<br/>");
1083
1135
  editor.chain().insertContent(imagesHtml).run();
1084
1136
  } catch (err) {
1085
1137
  alertFn(err.message || "Image upload failed");
@@ -1129,7 +1181,7 @@ var TiptapEditor = ({
1129
1181
  );
1130
1182
  const attachmentsHtml = uploadResults.map(
1131
1183
  (res) => `<a href="${res.url}" target="_blank" rel="noopener noreferrer" data-attachment="true">${res.name}</a>`
1132
- ).join("&nbsp;");
1184
+ ).join("<br/>");
1133
1185
  editor.chain().focus().insertContent(attachmentsHtml).run();
1134
1186
  } catch (err) {
1135
1187
  alertFn(err.message || "Attachment upload failed");
@@ -1161,7 +1213,13 @@ var TiptapEditor = ({
1161
1213
  editor.chain().focus().extendMarkRange("link").unsetLink().run();
1162
1214
  } else {
1163
1215
  const formattedUrl = /^https?:\/\//.test(linkUrl) ? linkUrl : `https://${linkUrl}`;
1164
- editor.chain().focus().extendMarkRange("link").setLink({ href: formattedUrl }).run();
1216
+ const { from, to } = editor.state.selection;
1217
+ const hasSelection = from !== to;
1218
+ if (hasSelection) {
1219
+ editor.chain().focus().extendMarkRange("link").setLink({ href: formattedUrl }).run();
1220
+ } else {
1221
+ editor.chain().focus().insertContent(`<a href="${formattedUrl}">${linkUrl}</a>`).run();
1222
+ }
1165
1223
  }
1166
1224
  setShowLinkMenu(false);
1167
1225
  }, [editor, linkUrl]);
@@ -1192,6 +1250,7 @@ var TiptapEditor = ({
1192
1250
  ] });
1193
1251
  const defaultGroups = [
1194
1252
  "history",
1253
+ "heading",
1195
1254
  "font",
1196
1255
  "fontSize",
1197
1256
  "textColor",
@@ -1208,6 +1267,20 @@ var TiptapEditor = ({
1208
1267
  const getToolbar = () => {
1209
1268
  const toolbarComponents = {
1210
1269
  history: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HistoryGroup, { editor, isReadOnly }),
1270
+ heading: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1271
+ HeadingGroup,
1272
+ {
1273
+ editor,
1274
+ isReadOnly,
1275
+ showMenu: showHeadingMenu,
1276
+ onToggle: () => {
1277
+ const nextState = !showHeadingMenu;
1278
+ closeAllMenus();
1279
+ setShowHeadingMenu(nextState);
1280
+ },
1281
+ onClose: () => setShowHeadingMenu(false)
1282
+ }
1283
+ ),
1211
1284
  font: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1212
1285
  FontGroup,
1213
1286
  {