@pixerate/editor 0.5.1 → 0.6.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.
@@ -33,6 +33,7 @@ __export(extensions_exports, {
33
33
  ColorHighlighter: () => ColorHighlighter,
34
34
  FontSize: () => FontSize,
35
35
  GradientText: () => GradientText,
36
+ Image: () => Image2,
36
37
  LoadingNode: () => LoadingNode,
37
38
  Markdown: () => Markdown2,
38
39
  Mention: () => Mention,
@@ -41,7 +42,11 @@ __export(extensions_exports, {
41
42
  TemplateSuggestions: () => TemplateSuggestions,
42
43
  createMentionExtension: () => createMentionExtension,
43
44
  createRichTextPreset: () => createRichTextPreset,
44
- findHexColors: () => findHexColors
45
+ findHexColors: () => findHexColors,
46
+ handleImageInsertion: () => handleImageInsertion,
47
+ imagePastePluginKey: () => imagePastePluginKey,
48
+ insertImageNode: () => insertImageNode,
49
+ updateImageSrc: () => updateImageSrc
45
50
  });
46
51
  module.exports = __toCommonJS(extensions_exports);
47
52
 
@@ -1594,20 +1599,140 @@ var Markdown = import_core8.Extension.create({
1594
1599
  var resolveExt = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
1595
1600
  var Markdown2 = resolveExt(Markdown, "Markdown");
1596
1601
 
1597
- // src/extensions/rich-text-preset.ts
1602
+ // src/extensions/image.ts
1603
+ var _Image = __toESM(require("@tiptap/extension-image"), 1);
1604
+ var import_state5 = require("@tiptap/pm/state");
1598
1605
  var resolveExt2 = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
1599
- var StarterKit = resolveExt2(_StarterKit, "StarterKit");
1600
- var Color = resolveExt2(_Color, "Color");
1601
- var Highlight = resolveExt2(_Highlight, "Highlight");
1602
- var Link2 = resolveExt2(_Link, "Link");
1603
- var TaskList2 = resolveExt2(_TaskList, "TaskList");
1604
- var TaskItem2 = resolveExt2(_TaskItem, "TaskItem");
1605
- var TextAlign = resolveExt2(_TextAlign, "TextAlign");
1606
- var TextStyle = resolveExt2(_TextStyle, "TextStyle");
1607
- var Typography = resolveExt2(_Typography, "Typography");
1608
- var Underline = resolveExt2(_Underline, "Underline");
1609
- var Placeholder = resolveExt2(_Placeholder, "Placeholder");
1610
- var CharacterCount = resolveExt2(_CharacterCount, "CharacterCount");
1606
+ var BaseImage = resolveExt2(_Image, "Image");
1607
+ var imagePastePluginKey = new import_state5.PluginKey("imagePasteHandler");
1608
+ function insertImageNode(view, src, alt) {
1609
+ const { schema } = view.state;
1610
+ const imageType = schema.nodes.image;
1611
+ if (!imageType) return;
1612
+ const node = imageType.create({ src, alt: alt || "" });
1613
+ const tr = view.state.tr.replaceSelectionWith(node);
1614
+ view.dispatch(tr);
1615
+ }
1616
+ function updateImageSrc(view, oldSrc, newSrc) {
1617
+ const { doc } = view.state;
1618
+ let foundPos = null;
1619
+ let foundAttrs = null;
1620
+ doc.descendants((node, pos) => {
1621
+ if (node.type.name === "image" && node.attrs.src === oldSrc) {
1622
+ foundPos = pos;
1623
+ foundAttrs = node.attrs;
1624
+ return false;
1625
+ }
1626
+ });
1627
+ if (foundPos !== null && foundAttrs) {
1628
+ const tr = view.state.tr.setNodeMarkup(foundPos, void 0, {
1629
+ ...foundAttrs,
1630
+ src: newSrc
1631
+ });
1632
+ view.dispatch(tr);
1633
+ }
1634
+ }
1635
+ function handleImageInsertion(view, file, options) {
1636
+ if (typeof options.upload === "function") {
1637
+ const hasObjectUrl = typeof URL !== "undefined" && typeof URL.createObjectURL === "function";
1638
+ const tempUrl = hasObjectUrl ? URL.createObjectURL(file) : null;
1639
+ if (tempUrl) {
1640
+ insertImageNode(view, tempUrl, file.name);
1641
+ }
1642
+ Promise.resolve(options.upload(file)).then((uploadedUrl) => {
1643
+ if (!uploadedUrl) return;
1644
+ if (tempUrl) {
1645
+ updateImageSrc(view, tempUrl, uploadedUrl);
1646
+ if (typeof URL.revokeObjectURL === "function") {
1647
+ URL.revokeObjectURL(tempUrl);
1648
+ }
1649
+ } else {
1650
+ insertImageNode(view, uploadedUrl, file.name);
1651
+ }
1652
+ }).catch((err) => {
1653
+ console.error("Failed to upload pasted image:", err);
1654
+ });
1655
+ } else if (options.allowBase64 !== false) {
1656
+ if (typeof FileReader !== "undefined") {
1657
+ const reader = new FileReader();
1658
+ reader.onload = () => {
1659
+ const src = reader.result;
1660
+ if (src) {
1661
+ insertImageNode(view, src, file.name);
1662
+ }
1663
+ };
1664
+ reader.readAsDataURL(file);
1665
+ }
1666
+ }
1667
+ }
1668
+ var Image2 = BaseImage.extend({
1669
+ addOptions() {
1670
+ return {
1671
+ ...this.parent?.(),
1672
+ allowBase64: true,
1673
+ enablePaste: true,
1674
+ enableDrop: true,
1675
+ upload: void 0,
1676
+ HTMLAttributes: {
1677
+ class: "rounded-md max-w-full h-auto my-2"
1678
+ }
1679
+ };
1680
+ },
1681
+ addProseMirrorPlugins() {
1682
+ const parentPlugins = this.parent?.() || [];
1683
+ const options = this.options;
1684
+ if (!options.enablePaste && !options.enableDrop) {
1685
+ return parentPlugins;
1686
+ }
1687
+ const pastePlugin = new import_state5.Plugin({
1688
+ key: imagePastePluginKey,
1689
+ props: {
1690
+ handlePaste(view, event) {
1691
+ if (!options.enablePaste) return false;
1692
+ const items = Array.from(event.clipboardData?.items || []);
1693
+ const imageItems = items.filter(
1694
+ (item) => item.kind === "file" && item.type.startsWith("image/")
1695
+ );
1696
+ if (imageItems.length === 0) return false;
1697
+ event.preventDefault();
1698
+ for (const item of imageItems) {
1699
+ const file = item.getAsFile();
1700
+ if (!file) continue;
1701
+ handleImageInsertion(view, file, options);
1702
+ }
1703
+ return true;
1704
+ },
1705
+ handleDrop(view, event) {
1706
+ if (!options.enableDrop) return false;
1707
+ const files = Array.from(event.dataTransfer?.files || []);
1708
+ const imageFiles = files.filter((f) => f.type.startsWith("image/"));
1709
+ if (imageFiles.length === 0) return false;
1710
+ event.preventDefault();
1711
+ for (const file of imageFiles) {
1712
+ handleImageInsertion(view, file, options);
1713
+ }
1714
+ return true;
1715
+ }
1716
+ }
1717
+ });
1718
+ return [...parentPlugins, pastePlugin];
1719
+ }
1720
+ });
1721
+
1722
+ // src/extensions/rich-text-preset.ts
1723
+ var resolveExt3 = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
1724
+ var StarterKit = resolveExt3(_StarterKit, "StarterKit");
1725
+ var Color = resolveExt3(_Color, "Color");
1726
+ var Highlight = resolveExt3(_Highlight, "Highlight");
1727
+ var Link2 = resolveExt3(_Link, "Link");
1728
+ var TaskList2 = resolveExt3(_TaskList, "TaskList");
1729
+ var TaskItem2 = resolveExt3(_TaskItem, "TaskItem");
1730
+ var TextAlign = resolveExt3(_TextAlign, "TextAlign");
1731
+ var TextStyle = resolveExt3(_TextStyle, "TextStyle");
1732
+ var Typography = resolveExt3(_Typography, "Typography");
1733
+ var Underline = resolveExt3(_Underline, "Underline");
1734
+ var Placeholder = resolveExt3(_Placeholder, "Placeholder");
1735
+ var CharacterCount = resolveExt3(_CharacterCount, "CharacterCount");
1611
1736
  function createRichTextPreset(options = {}) {
1612
1737
  const {
1613
1738
  placeholder = "Start typing...",
@@ -1729,6 +1854,18 @@ function createRichTextPreset(options = {}) {
1729
1854
  })
1730
1855
  );
1731
1856
  }
1857
+ if (options.image !== false) {
1858
+ const imageConfig = typeof options.image === "object" ? options.image : {};
1859
+ extensions2.push(
1860
+ Image2.configure({
1861
+ HTMLAttributes: {
1862
+ class: "rounded-md max-w-full h-auto my-2",
1863
+ ...imageConfig.HTMLAttributes || {}
1864
+ },
1865
+ ...imageConfig
1866
+ })
1867
+ );
1868
+ }
1732
1869
  return extensions2;
1733
1870
  }
1734
1871
  // Annotate the CommonJS export names for ESM import in node:
@@ -1736,6 +1873,7 @@ function createRichTextPreset(options = {}) {
1736
1873
  ColorHighlighter,
1737
1874
  FontSize,
1738
1875
  GradientText,
1876
+ Image,
1739
1877
  LoadingNode,
1740
1878
  Markdown,
1741
1879
  Mention,
@@ -1744,6 +1882,10 @@ function createRichTextPreset(options = {}) {
1744
1882
  TemplateSuggestions,
1745
1883
  createMentionExtension,
1746
1884
  createRichTextPreset,
1747
- findHexColors
1885
+ findHexColors,
1886
+ handleImageInsertion,
1887
+ imagePastePluginKey,
1888
+ insertImageNode,
1889
+ updateImageSrc
1748
1890
  });
1749
1891
  //# sourceMappingURL=index.cjs.map