@kedataindo/docflow-plugins 0.0.31 → 0.0.33

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.js CHANGED
@@ -853,7 +853,91 @@ var highlightPlugin = definePlugin16({
853
853
  import { Extension as Extension2 } from "@tiptap/core";
854
854
  import { Plugin, PluginKey } from "@tiptap/pm/state";
855
855
  import { Decoration, DecorationSet } from "@tiptap/pm/view";
856
+ import { Markdown } from "tiptap-markdown";
856
857
  import { definePlugin as definePlugin17 } from "@kedataindo/docflow-core";
858
+
859
+ // src/markdownInsert.ts
860
+ import { createNodeFromContent } from "@tiptap/core";
861
+ import { Fragment } from "@tiptap/pm/model";
862
+ import { Selection } from "@tiptap/pm/state";
863
+ import { ReplaceAroundStep, ReplaceStep } from "@tiptap/pm/transform";
864
+ function mdParser(editor) {
865
+ const storage = editor.storage.markdown;
866
+ if (!storage || typeof storage !== "object") return void 0;
867
+ const parser = storage.parser;
868
+ if (!parser || typeof parser !== "object" || !("parse" in parser)) return void 0;
869
+ return parser;
870
+ }
871
+ function markdownToFragment(editor, markdown, opts) {
872
+ const parser = mdParser(editor);
873
+ if (!parser) return null;
874
+ let html;
875
+ try {
876
+ html = parser.parse(markdown, { inline: opts.inline });
877
+ } catch {
878
+ return null;
879
+ }
880
+ if (typeof html !== "string") return null;
881
+ const content = createNodeFromContent(html, editor.schema, {
882
+ slice: true,
883
+ parseOptions: { preserveWhitespace: "full" }
884
+ });
885
+ if (content instanceof Fragment) return content;
886
+ return Fragment.from(content);
887
+ }
888
+ function selectionToInsertionEnd(tr, startLen, bias) {
889
+ const last = tr.steps.length - 1;
890
+ if (last < startLen) return;
891
+ const step = tr.steps[last];
892
+ if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return;
893
+ const map = tr.mapping.maps[last];
894
+ let end = 0;
895
+ map.forEach((_from, _to, _newFrom, newTo) => {
896
+ if (end === 0) end = newTo;
897
+ });
898
+ tr.setSelection(Selection.near(tr.doc.resolve(end), bias));
899
+ }
900
+ function insertMarkdownBlock(editor, view, from, to, markdown) {
901
+ const fragment = markdownToFragment(editor, markdown, { inline: false });
902
+ if (!fragment) {
903
+ view.dispatch(view.state.tr.insertText(markdown, from, to));
904
+ return;
905
+ }
906
+ const tr = view.state.tr;
907
+ let f = from;
908
+ let t = to;
909
+ if (f === t) {
910
+ let onlyBlock = true;
911
+ fragment.forEach((n) => {
912
+ if (!n.isBlock) onlyBlock = false;
913
+ });
914
+ if (onlyBlock) {
915
+ const $pos = tr.doc.resolve(f);
916
+ const parent = $pos.parent;
917
+ if (parent.isTextblock && !parent.type.spec.code && !parent.childCount) {
918
+ f -= 1;
919
+ t += 1;
920
+ }
921
+ }
922
+ }
923
+ let onlyText = true;
924
+ fragment.forEach((n) => {
925
+ if (!n.isText || n.marks.length > 0) onlyText = false;
926
+ });
927
+ if (onlyText) {
928
+ let text = "";
929
+ fragment.forEach((n) => {
930
+ if (n.isText) text += n.text ?? "";
931
+ });
932
+ tr.insertText(text, f, t);
933
+ } else {
934
+ tr.replaceWith(f, t, fragment);
935
+ }
936
+ selectionToInsertionEnd(tr, 0, -1);
937
+ view.dispatch(tr);
938
+ }
939
+
940
+ // src/ai.ts
857
941
  var aiPluginKey = new PluginKey("docflow-ai");
858
942
  var CONTEXT_CHARS = 1500;
859
943
  function getAIPreview(editor) {
@@ -991,7 +1075,12 @@ var AIExtension = Extension2.create({
991
1075
  if (!dispatch) return true;
992
1076
  const tr = state.tr;
993
1077
  if (preview.text.trim()) {
994
- tr.replaceWith(preview.from, preview.to, state.schema.text(preview.text));
1078
+ const fragment = markdownToFragment(editor, preview.text, { inline: true });
1079
+ if (fragment) {
1080
+ tr.replaceWith(preview.from, preview.to, fragment);
1081
+ } else {
1082
+ tr.replaceWith(preview.from, preview.to, state.schema.text(preview.text));
1083
+ }
995
1084
  }
996
1085
  tr.setMeta(aiPluginKey, { type: "clear" });
997
1086
  dispatch(tr);
@@ -1203,7 +1292,15 @@ var AIExtension = Extension2.create({
1203
1292
  });
1204
1293
  var aiPlugin = definePlugin17({
1205
1294
  id: "ai",
1206
- tiptapExtensions: [AIExtension],
1295
+ // The `tiptap-markdown` `Markdown` extension is registered alongside AI so
1296
+ // that `editor.storage.markdown.parser` is available on every editor that
1297
+ // can stream AI content. It adds a schema-aware markdown↔HTML bridge
1298
+ // (markdown-it under the hood) used by the AI Insert/accept paths to turn
1299
+ // streamed `| col | col |` tables / `# headings` / `**bold**` into real
1300
+ // nodes instead of literal pipe/asterisk text. Its `insertContentAt` /
1301
+ // `setContent` command overrides are intentionally NOT used by the AI
1302
+ // paths (they force `inline:true`); see `markdownInsert.ts`.
1303
+ tiptapExtensions: [AIExtension, Markdown.configure({ html: true, linkify: true, breaks: false })],
1207
1304
  slashCommands: [{ name: "AI", description: "Generate text with AI", command: "aiGenerate" }]
1208
1305
  });
1209
1306
 
@@ -1247,10 +1344,440 @@ var commentPlugin = {
1247
1344
  commands: {}
1248
1345
  };
1249
1346
 
1347
+ // src/smartElements.ts
1348
+ import { Node as Node5, mergeAttributes as mergeAttributes6 } from "@tiptap/core";
1349
+ import { definePlugin as definePlugin18 } from "@kedataindo/docflow-core";
1350
+ function todayISO() {
1351
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1352
+ }
1353
+ function formatDate(iso) {
1354
+ if (!iso) return "Pick a date";
1355
+ const d = /* @__PURE__ */ new Date(iso + "T00:00:00");
1356
+ if (isNaN(d.getTime())) return "Pick a date";
1357
+ return d.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
1358
+ }
1359
+ function initialOf(name) {
1360
+ return (name || "?").trim().charAt(0).toUpperCase() || "?";
1361
+ }
1362
+ var DEFAULT_STATUSES = ["To Do", "In Progress", "Review", "Approved"];
1363
+ function slugify(s) {
1364
+ return s.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
1365
+ }
1366
+ var DateChipNode = Node5.create({
1367
+ name: "dateChip",
1368
+ group: "inline",
1369
+ inline: true,
1370
+ selectable: true,
1371
+ draggable: false,
1372
+ atom: true,
1373
+ addAttributes() {
1374
+ return {
1375
+ date: {
1376
+ default: todayISO(),
1377
+ parseHTML: (el) => el.getAttribute("data-date") ?? todayISO(),
1378
+ renderHTML: (attrs) => ({ "data-date": attrs.date ?? "" })
1379
+ }
1380
+ };
1381
+ },
1382
+ parseHTML() {
1383
+ return [{ tag: 'span[data-node-type="date-chip"]' }];
1384
+ },
1385
+ renderHTML({ node, HTMLAttributes }) {
1386
+ return ["span", mergeAttributes6(HTMLAttributes, {
1387
+ "data-node-type": "date-chip",
1388
+ class: "docs-chip docs-chip--date"
1389
+ }), formatDate(node.attrs.date)];
1390
+ },
1391
+ addNodeView() {
1392
+ return (props) => {
1393
+ let currentNode = props.node;
1394
+ const getPos = props.getPos;
1395
+ const view = props.view;
1396
+ const dom = document.createElement("span");
1397
+ dom.className = "docs-chip docs-chip--date";
1398
+ dom.setAttribute("data-node-type", "date-chip");
1399
+ dom.setAttribute("contenteditable", "false");
1400
+ const render = () => {
1401
+ if (dom.querySelector("input")) return;
1402
+ dom.textContent = formatDate(currentNode.attrs.date);
1403
+ dom.setAttribute("data-date", currentNode.attrs.date);
1404
+ };
1405
+ render();
1406
+ dom.addEventListener("click", (e) => {
1407
+ e.preventDefault();
1408
+ e.stopPropagation();
1409
+ if (dom.querySelector("input")) return;
1410
+ const input = document.createElement("input");
1411
+ input.type = "date";
1412
+ input.value = currentNode.attrs.date;
1413
+ input.className = "docs-chip-date-input";
1414
+ dom.replaceChildren(input);
1415
+ input.focus();
1416
+ const commit = () => {
1417
+ const newVal = input.value;
1418
+ const pos = getPos();
1419
+ if (typeof pos === "number") {
1420
+ view.dispatch(view.state.tr.setNodeMarkup(pos, void 0, { date: newVal }));
1421
+ }
1422
+ setTimeout(render, 30);
1423
+ };
1424
+ input.addEventListener("change", commit);
1425
+ input.addEventListener("blur", () => setTimeout(render, 30));
1426
+ });
1427
+ return {
1428
+ dom,
1429
+ update(updatedNode) {
1430
+ if (updatedNode.type.name !== "dateChip") return false;
1431
+ currentNode = updatedNode;
1432
+ render();
1433
+ return true;
1434
+ }
1435
+ };
1436
+ };
1437
+ }
1438
+ });
1439
+ var PeopleChipNode = Node5.create({
1440
+ name: "peopleChip",
1441
+ group: "inline",
1442
+ inline: true,
1443
+ selectable: true,
1444
+ draggable: false,
1445
+ atom: true,
1446
+ addAttributes() {
1447
+ return {
1448
+ userId: {
1449
+ default: "",
1450
+ parseHTML: (el) => el.getAttribute("data-user-id") ?? "",
1451
+ renderHTML: (attrs) => attrs.userId ? { "data-user-id": attrs.userId } : {}
1452
+ },
1453
+ name: {
1454
+ default: "",
1455
+ parseHTML: (el) => el.getAttribute("data-name") ?? "",
1456
+ renderHTML: (attrs) => ({ "data-name": attrs.name ?? "" })
1457
+ }
1458
+ };
1459
+ },
1460
+ parseHTML() {
1461
+ return [{ tag: 'span[data-node-type="people-chip"]' }];
1462
+ },
1463
+ renderHTML({ node, HTMLAttributes }) {
1464
+ return ["span", mergeAttributes6(HTMLAttributes, {
1465
+ "data-node-type": "people-chip",
1466
+ class: "docs-chip docs-chip--people"
1467
+ }), `@${node.attrs.name || "user"}`];
1468
+ },
1469
+ addNodeView() {
1470
+ return (props) => {
1471
+ let currentNode = props.node;
1472
+ const dom = document.createElement("span");
1473
+ dom.className = "docs-chip docs-chip--people";
1474
+ dom.setAttribute("data-node-type", "people-chip");
1475
+ dom.setAttribute("contenteditable", "false");
1476
+ const render = () => {
1477
+ const name = currentNode.attrs.name || "user";
1478
+ dom.innerHTML = "";
1479
+ const avatar = document.createElement("span");
1480
+ avatar.className = "docs-chip-avatar";
1481
+ avatar.textContent = initialOf(name);
1482
+ dom.appendChild(avatar);
1483
+ const label = document.createElement("span");
1484
+ label.className = "docs-chip-label";
1485
+ label.textContent = "@" + name;
1486
+ dom.appendChild(label);
1487
+ };
1488
+ render();
1489
+ return {
1490
+ dom,
1491
+ update(updatedNode) {
1492
+ if (updatedNode.type.name !== "peopleChip") return false;
1493
+ currentNode = updatedNode;
1494
+ render();
1495
+ return true;
1496
+ }
1497
+ };
1498
+ };
1499
+ }
1500
+ });
1501
+ var FileChipNode = Node5.create({
1502
+ name: "fileChip",
1503
+ group: "inline",
1504
+ inline: true,
1505
+ selectable: true,
1506
+ draggable: false,
1507
+ atom: true,
1508
+ addAttributes() {
1509
+ return {
1510
+ fileId: {
1511
+ default: "",
1512
+ parseHTML: (el) => el.getAttribute("data-file-id") ?? "",
1513
+ renderHTML: (attrs) => attrs.fileId ? { "data-file-id": attrs.fileId } : {}
1514
+ },
1515
+ name: {
1516
+ default: "",
1517
+ parseHTML: (el) => el.getAttribute("data-name") ?? "",
1518
+ renderHTML: (attrs) => ({ "data-name": attrs.name ?? "" })
1519
+ }
1520
+ };
1521
+ },
1522
+ parseHTML() {
1523
+ return [{ tag: 'span[data-node-type="file-chip"]' }];
1524
+ },
1525
+ renderHTML({ node, HTMLAttributes }) {
1526
+ return ["span", mergeAttributes6(HTMLAttributes, {
1527
+ "data-node-type": "file-chip",
1528
+ class: "docs-chip docs-chip--file"
1529
+ }), node.attrs.name || "file"];
1530
+ },
1531
+ addNodeView() {
1532
+ return (props) => {
1533
+ let currentNode = props.node;
1534
+ const dom = document.createElement("span");
1535
+ dom.className = "docs-chip docs-chip--file";
1536
+ dom.setAttribute("data-node-type", "file-chip");
1537
+ dom.setAttribute("contenteditable", "false");
1538
+ const render = () => {
1539
+ const name = currentNode.attrs.name || "Untitled file";
1540
+ dom.innerHTML = "";
1541
+ const icon = document.createElement("span");
1542
+ icon.className = "docs-chip-icon";
1543
+ icon.textContent = "\u{1F5CE}";
1544
+ dom.appendChild(icon);
1545
+ const label = document.createElement("span");
1546
+ label.className = "docs-chip-label";
1547
+ label.textContent = name;
1548
+ dom.appendChild(label);
1549
+ };
1550
+ render();
1551
+ return {
1552
+ dom,
1553
+ update(updatedNode) {
1554
+ if (updatedNode.type.name !== "fileChip") return false;
1555
+ currentNode = updatedNode;
1556
+ render();
1557
+ return true;
1558
+ }
1559
+ };
1560
+ };
1561
+ }
1562
+ });
1563
+ var DropdownChipNode = Node5.create({
1564
+ name: "dropdownChip",
1565
+ group: "inline",
1566
+ inline: true,
1567
+ selectable: true,
1568
+ draggable: false,
1569
+ atom: true,
1570
+ addAttributes() {
1571
+ return {
1572
+ options: {
1573
+ default: DEFAULT_STATUSES,
1574
+ parseHTML: (el) => {
1575
+ const raw = el.getAttribute("data-options") ?? "";
1576
+ const list = raw ? raw.split("|") : [];
1577
+ return list.length ? list : DEFAULT_STATUSES;
1578
+ },
1579
+ renderHTML: (attrs) => ({
1580
+ "data-options": (attrs.options ?? []).join("|")
1581
+ })
1582
+ },
1583
+ selected: {
1584
+ default: DEFAULT_STATUSES[0],
1585
+ parseHTML: (el) => el.getAttribute("data-selected") ?? DEFAULT_STATUSES[0],
1586
+ renderHTML: (attrs) => ({ "data-selected": attrs.selected ?? "" })
1587
+ }
1588
+ };
1589
+ },
1590
+ parseHTML() {
1591
+ return [{ tag: 'span[data-node-type="dropdown-chip"]' }];
1592
+ },
1593
+ renderHTML({ node, HTMLAttributes }) {
1594
+ return ["span", mergeAttributes6(HTMLAttributes, {
1595
+ "data-node-type": "dropdown-chip",
1596
+ class: "docs-chip docs-chip--dropdown"
1597
+ }), node.attrs.selected || ""];
1598
+ },
1599
+ addNodeView() {
1600
+ return (props) => {
1601
+ let currentNode = props.node;
1602
+ const getPos = props.getPos;
1603
+ const view = props.view;
1604
+ const dom = document.createElement("span");
1605
+ dom.className = "docs-chip docs-chip--dropdown";
1606
+ dom.setAttribute("data-node-type", "dropdown-chip");
1607
+ dom.setAttribute("contenteditable", "false");
1608
+ const render = () => {
1609
+ const opts = currentNode.attrs.options ?? DEFAULT_STATUSES;
1610
+ const sel = currentNode.attrs.selected ?? (opts[0] ?? "");
1611
+ dom.innerHTML = "";
1612
+ const select = document.createElement("select");
1613
+ select.className = "docs-chip-select";
1614
+ select.addEventListener("mousedown", (e) => e.stopPropagation());
1615
+ for (const opt of opts) {
1616
+ const o = document.createElement("option");
1617
+ o.value = opt;
1618
+ o.textContent = opt;
1619
+ if (opt === sel) o.selected = true;
1620
+ select.appendChild(o);
1621
+ }
1622
+ select.addEventListener("change", () => {
1623
+ const pos = getPos();
1624
+ if (typeof pos === "number") {
1625
+ view.dispatch(view.state.tr.setNodeMarkup(pos, void 0, {
1626
+ ...currentNode.attrs,
1627
+ selected: select.value
1628
+ }));
1629
+ }
1630
+ });
1631
+ dom.appendChild(select);
1632
+ };
1633
+ render();
1634
+ return {
1635
+ dom,
1636
+ update(updatedNode) {
1637
+ if (updatedNode.type.name !== "dropdownChip") return false;
1638
+ currentNode = updatedNode;
1639
+ render();
1640
+ return true;
1641
+ }
1642
+ };
1643
+ };
1644
+ }
1645
+ });
1646
+ var LocationChipNode = Node5.create({
1647
+ name: "locationChip",
1648
+ group: "inline",
1649
+ inline: true,
1650
+ selectable: true,
1651
+ draggable: false,
1652
+ atom: true,
1653
+ addAttributes() {
1654
+ return {
1655
+ label: {
1656
+ default: "",
1657
+ parseHTML: (el) => el.getAttribute("data-label") ?? "",
1658
+ renderHTML: (attrs) => ({ "data-label": attrs.label ?? "" })
1659
+ },
1660
+ lat: {
1661
+ default: null,
1662
+ parseHTML: (el) => {
1663
+ const v = el.getAttribute("data-lat");
1664
+ return v === null ? null : Number(v);
1665
+ },
1666
+ renderHTML: (attrs) => attrs.lat != null ? { "data-lat": attrs.lat } : {}
1667
+ },
1668
+ lng: {
1669
+ default: null,
1670
+ parseHTML: (el) => {
1671
+ const v = el.getAttribute("data-lng");
1672
+ return v === null ? null : Number(v);
1673
+ },
1674
+ renderHTML: (attrs) => attrs.lng != null ? { "data-lng": attrs.lng } : {}
1675
+ }
1676
+ };
1677
+ },
1678
+ parseHTML() {
1679
+ return [{ tag: 'span[data-node-type="location-chip"]' }];
1680
+ },
1681
+ renderHTML({ node, HTMLAttributes }) {
1682
+ return ["span", mergeAttributes6(HTMLAttributes, {
1683
+ "data-node-type": "location-chip",
1684
+ class: "docs-chip docs-chip--location"
1685
+ }), node.attrs.label || ""];
1686
+ },
1687
+ addNodeView() {
1688
+ return (props) => {
1689
+ let currentNode = props.node;
1690
+ const dom = document.createElement("span");
1691
+ dom.className = "docs-chip docs-chip--location";
1692
+ dom.setAttribute("data-node-type", "location-chip");
1693
+ dom.setAttribute("contenteditable", "false");
1694
+ const render = () => {
1695
+ const label = currentNode.attrs.label || "Add location";
1696
+ dom.innerHTML = "";
1697
+ const icon = document.createElement("span");
1698
+ icon.className = "docs-chip-icon";
1699
+ icon.textContent = "\u{1F4CD}";
1700
+ dom.appendChild(icon);
1701
+ const lbl = document.createElement("span");
1702
+ lbl.className = "docs-chip-label";
1703
+ lbl.textContent = label;
1704
+ dom.appendChild(lbl);
1705
+ };
1706
+ render();
1707
+ return {
1708
+ dom,
1709
+ update(updatedNode) {
1710
+ if (updatedNode.type.name !== "locationChip") return false;
1711
+ currentNode = updatedNode;
1712
+ render();
1713
+ return true;
1714
+ }
1715
+ };
1716
+ };
1717
+ }
1718
+ });
1719
+ var smartElementsPlugin = definePlugin18({
1720
+ id: "smart-elements",
1721
+ tiptapExtensions: [
1722
+ DateChipNode,
1723
+ PeopleChipNode,
1724
+ FileChipNode,
1725
+ DropdownChipNode,
1726
+ LocationChipNode
1727
+ ],
1728
+ slashCommands: [
1729
+ { name: "Date", command: "insertDateChip" },
1730
+ { name: "People", command: "insertPeopleChip" },
1731
+ { name: "File", command: "insertFileChip" },
1732
+ { name: "Dropdown", command: "insertDropdownChip" },
1733
+ { name: "Location", command: "insertLocationChip" }
1734
+ ],
1735
+ commands: {
1736
+ insertDateChip: (editor) => {
1737
+ return editor.chain().focus().insertContent({
1738
+ type: "dateChip",
1739
+ attrs: { date: todayISO() }
1740
+ }).run();
1741
+ },
1742
+ insertPeopleChip: (editor) => {
1743
+ const name = typeof window !== "undefined" && typeof window.prompt === "function" ? window.prompt("Enter user name:", "") ?? "" : "";
1744
+ if (!name.trim()) return false;
1745
+ const trimmed = name.trim();
1746
+ return editor.chain().focus().insertContent({
1747
+ type: "peopleChip",
1748
+ attrs: { userId: slugify(trimmed), name: trimmed }
1749
+ }).run();
1750
+ },
1751
+ insertFileChip: (editor) => {
1752
+ const name = typeof window !== "undefined" && typeof window.prompt === "function" ? window.prompt("Enter file/document name:", "") ?? "" : "";
1753
+ if (!name.trim()) return false;
1754
+ const trimmed = name.trim();
1755
+ return editor.chain().focus().insertContent({
1756
+ type: "fileChip",
1757
+ attrs: { fileId: slugify(trimmed), name: trimmed }
1758
+ }).run();
1759
+ },
1760
+ insertDropdownChip: (editor) => {
1761
+ return editor.chain().focus().insertContent({
1762
+ type: "dropdownChip",
1763
+ attrs: { options: DEFAULT_STATUSES, selected: DEFAULT_STATUSES[0] }
1764
+ }).run();
1765
+ },
1766
+ insertLocationChip: (editor) => {
1767
+ const label = typeof window !== "undefined" && typeof window.prompt === "function" ? window.prompt("Enter location name:", "") ?? "" : "";
1768
+ if (!label.trim()) return false;
1769
+ return editor.chain().focus().insertContent({
1770
+ type: "locationChip",
1771
+ attrs: { label: label.trim() }
1772
+ }).run();
1773
+ }
1774
+ }
1775
+ });
1776
+
1250
1777
  // src/slashMenu.ts
1251
1778
  import { Extension as Extension3 } from "@tiptap/core";
1252
1779
  import { Plugin as Plugin2, PluginKey as PluginKey2 } from "@tiptap/pm/state";
1253
- import { definePlugin as definePlugin18 } from "@kedataindo/docflow-core";
1780
+ import { definePlugin as definePlugin19 } from "@kedataindo/docflow-core";
1254
1781
  var slashState = {
1255
1782
  open: false,
1256
1783
  query: "",
@@ -1395,7 +1922,7 @@ var SlashMenuExtension = Extension3.create({
1395
1922
  ];
1396
1923
  }
1397
1924
  });
1398
- var slashMenuPlugin = definePlugin18({
1925
+ var slashMenuPlugin = definePlugin19({
1399
1926
  id: "slash-menu",
1400
1927
  tiptapExtensions: [SlashMenuExtension],
1401
1928
  hooks: {
@@ -1426,7 +1953,8 @@ var defaultPlugins = [
1426
1953
  highlightPlugin,
1427
1954
  citationPlugin,
1428
1955
  aiPlugin,
1429
- commentPlugin
1956
+ commentPlugin,
1957
+ smartElementsPlugin
1430
1958
  ];
1431
1959
  export {
1432
1960
  AIExtension,
@@ -1438,9 +1966,14 @@ export {
1438
1966
  CiteEngine,
1439
1967
  CommentMark as CommentMarkExtension,
1440
1968
  DEFAULT_CSL_STYLE,
1969
+ DateChipNode,
1970
+ DropdownChipNode,
1971
+ FileChipNode,
1441
1972
  FontSizeExtension,
1442
1973
  FootnoteNode,
1974
+ LocationChipNode,
1443
1975
  PageBreak,
1976
+ PeopleChipNode,
1444
1977
  SlashMenuExtension,
1445
1978
  TocEntryNode,
1446
1979
  TocNode,
@@ -1464,8 +1997,10 @@ export {
1464
1997
  headingsPlugin,
1465
1998
  highlightPlugin,
1466
1999
  imagePlugin,
2000
+ insertMarkdownBlock,
1467
2001
  linkPlugin,
1468
2002
  listsPlugin,
2003
+ markdownToFragment,
1469
2004
  nextCitationId,
1470
2005
  onSlashStateChange,
1471
2006
  pageBreakPlugin,
@@ -1475,6 +2010,7 @@ export {
1475
2010
  sanitizeCiteprocHtml,
1476
2011
  slashMenuPlugin,
1477
2012
  slashState,
2013
+ smartElementsPlugin,
1478
2014
  tablePlugin,
1479
2015
  textColorPlugin,
1480
2016
  tocPlugin
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kedataindo/docflow-plugins",
3
3
  "license": "UNLICENSED",
4
- "version": "0.0.31",
4
+ "version": "0.0.33",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -30,7 +30,8 @@
30
30
  "@tiptap/extension-highlight": "^2.27.2",
31
31
  "@tiptap/pm": "^2.11.0",
32
32
  "citeproc": "^2.4.63",
33
- "@kedataindo/docflow-core": "0.0.29"
33
+ "tiptap-markdown": "0.8.10",
34
+ "@kedataindo/docflow-core": "0.0.31"
34
35
  },
35
36
  "peerDependencies": {
36
37
  "@tiptap/core": "^2.11.0",