@pixerate/editor 0.5.0 → 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.
- package/dist/extensions/index.cjs +157 -15
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +35 -1
- package/dist/extensions/index.d.ts +35 -1
- package/dist/extensions/index.js +151 -14
- package/dist/extensions/index.js.map +1 -1
- package/dist/index.cjs +155 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +150 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -8,6 +8,8 @@ import { MentionOptions as MentionOptions$1 } from '@tiptap/extension-mention';
|
|
|
8
8
|
import { SuggestionOptions } from '@tiptap/suggestion';
|
|
9
9
|
import { MarkdownOptions } from 'tiptap-markdown';
|
|
10
10
|
export { MarkdownOptions } from 'tiptap-markdown';
|
|
11
|
+
import { ImageOptions as ImageOptions$1 } from '@tiptap/extension-image';
|
|
12
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
11
13
|
|
|
12
14
|
interface GradientTextOptions {
|
|
13
15
|
templateColorMap: Map<string, ColorGradient>;
|
|
@@ -100,6 +102,37 @@ declare function createMentionExtension(options?: Partial<MentionOptions>): _tip
|
|
|
100
102
|
*/
|
|
101
103
|
declare const Markdown: any;
|
|
102
104
|
|
|
105
|
+
interface ImageOptions extends Partial<ImageOptions$1> {
|
|
106
|
+
/**
|
|
107
|
+
* Custom upload handler called when an image is pasted or dropped.
|
|
108
|
+
* Resolves to the uploaded image URL string.
|
|
109
|
+
*/
|
|
110
|
+
upload?: (file: File) => Promise<string> | string;
|
|
111
|
+
/**
|
|
112
|
+
* Whether to enable automatic image pasting from clipboard. Defaults to true.
|
|
113
|
+
*/
|
|
114
|
+
enablePaste?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Whether to enable automatic image drop. Defaults to true.
|
|
117
|
+
*/
|
|
118
|
+
enableDrop?: boolean;
|
|
119
|
+
}
|
|
120
|
+
declare const imagePastePluginKey: PluginKey<any>;
|
|
121
|
+
/**
|
|
122
|
+
* Inserts an image node into the editor view at the current selection.
|
|
123
|
+
*/
|
|
124
|
+
declare function insertImageNode(view: any, src: string, alt?: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* Updates an existing image node's src attribute across document positions.
|
|
127
|
+
*/
|
|
128
|
+
declare function updateImageSrc(view: any, oldSrc: string, newSrc: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Handles inserting a pasted or dropped image file, supporting both async upload
|
|
131
|
+
* handlers and direct base64/object-URL fallbacks.
|
|
132
|
+
*/
|
|
133
|
+
declare function handleImageInsertion(view: any, file: File, options: ImageOptions): void;
|
|
134
|
+
declare const Image: any;
|
|
135
|
+
|
|
103
136
|
interface RichTextPresetOptions {
|
|
104
137
|
placeholder?: string | ((props: {
|
|
105
138
|
node: any;
|
|
@@ -111,10 +144,11 @@ interface RichTextPresetOptions {
|
|
|
111
144
|
headingLevels?: (1 | 2 | 3 | 4 | 5 | 6)[];
|
|
112
145
|
mention?: MentionOptions | boolean;
|
|
113
146
|
markdown?: MarkdownOptions | boolean;
|
|
147
|
+
image?: ImageOptions | boolean;
|
|
114
148
|
}
|
|
115
149
|
/**
|
|
116
150
|
* Creates a standard rich-text extensions bundle with full formatting support.
|
|
117
151
|
*/
|
|
118
152
|
declare function createRichTextPreset(options?: RichTextPresetOptions): Extensions;
|
|
119
153
|
|
|
120
|
-
export { ColorHighlighter, FontSize, GradientText, type GradientTextOptions, LoadingNode, Markdown, Mention, type MentionEntity, type MentionOptions, type RichTextPresetOptions, type SlashCommandMatchData, SlashCommands, type SlashCommandsOptions, SmilieReplacer, TemplateSuggestions, type TemplateSuggestionsOptions, createMentionExtension, createRichTextPreset, findHexColors };
|
|
154
|
+
export { ColorHighlighter, FontSize, GradientText, type GradientTextOptions, Image, type ImageOptions, LoadingNode, Markdown, Mention, type MentionEntity, type MentionOptions, type RichTextPresetOptions, type SlashCommandMatchData, SlashCommands, type SlashCommandsOptions, SmilieReplacer, TemplateSuggestions, type TemplateSuggestionsOptions, createMentionExtension, createRichTextPreset, findHexColors, handleImageInsertion, imagePastePluginKey, insertImageNode, updateImageSrc };
|
|
@@ -8,6 +8,8 @@ import { MentionOptions as MentionOptions$1 } from '@tiptap/extension-mention';
|
|
|
8
8
|
import { SuggestionOptions } from '@tiptap/suggestion';
|
|
9
9
|
import { MarkdownOptions } from 'tiptap-markdown';
|
|
10
10
|
export { MarkdownOptions } from 'tiptap-markdown';
|
|
11
|
+
import { ImageOptions as ImageOptions$1 } from '@tiptap/extension-image';
|
|
12
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
11
13
|
|
|
12
14
|
interface GradientTextOptions {
|
|
13
15
|
templateColorMap: Map<string, ColorGradient>;
|
|
@@ -100,6 +102,37 @@ declare function createMentionExtension(options?: Partial<MentionOptions>): _tip
|
|
|
100
102
|
*/
|
|
101
103
|
declare const Markdown: any;
|
|
102
104
|
|
|
105
|
+
interface ImageOptions extends Partial<ImageOptions$1> {
|
|
106
|
+
/**
|
|
107
|
+
* Custom upload handler called when an image is pasted or dropped.
|
|
108
|
+
* Resolves to the uploaded image URL string.
|
|
109
|
+
*/
|
|
110
|
+
upload?: (file: File) => Promise<string> | string;
|
|
111
|
+
/**
|
|
112
|
+
* Whether to enable automatic image pasting from clipboard. Defaults to true.
|
|
113
|
+
*/
|
|
114
|
+
enablePaste?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Whether to enable automatic image drop. Defaults to true.
|
|
117
|
+
*/
|
|
118
|
+
enableDrop?: boolean;
|
|
119
|
+
}
|
|
120
|
+
declare const imagePastePluginKey: PluginKey<any>;
|
|
121
|
+
/**
|
|
122
|
+
* Inserts an image node into the editor view at the current selection.
|
|
123
|
+
*/
|
|
124
|
+
declare function insertImageNode(view: any, src: string, alt?: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* Updates an existing image node's src attribute across document positions.
|
|
127
|
+
*/
|
|
128
|
+
declare function updateImageSrc(view: any, oldSrc: string, newSrc: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Handles inserting a pasted or dropped image file, supporting both async upload
|
|
131
|
+
* handlers and direct base64/object-URL fallbacks.
|
|
132
|
+
*/
|
|
133
|
+
declare function handleImageInsertion(view: any, file: File, options: ImageOptions): void;
|
|
134
|
+
declare const Image: any;
|
|
135
|
+
|
|
103
136
|
interface RichTextPresetOptions {
|
|
104
137
|
placeholder?: string | ((props: {
|
|
105
138
|
node: any;
|
|
@@ -111,10 +144,11 @@ interface RichTextPresetOptions {
|
|
|
111
144
|
headingLevels?: (1 | 2 | 3 | 4 | 5 | 6)[];
|
|
112
145
|
mention?: MentionOptions | boolean;
|
|
113
146
|
markdown?: MarkdownOptions | boolean;
|
|
147
|
+
image?: ImageOptions | boolean;
|
|
114
148
|
}
|
|
115
149
|
/**
|
|
116
150
|
* Creates a standard rich-text extensions bundle with full formatting support.
|
|
117
151
|
*/
|
|
118
152
|
declare function createRichTextPreset(options?: RichTextPresetOptions): Extensions;
|
|
119
153
|
|
|
120
|
-
export { ColorHighlighter, FontSize, GradientText, type GradientTextOptions, LoadingNode, Markdown, Mention, type MentionEntity, type MentionOptions, type RichTextPresetOptions, type SlashCommandMatchData, SlashCommands, type SlashCommandsOptions, SmilieReplacer, TemplateSuggestions, type TemplateSuggestionsOptions, createMentionExtension, createRichTextPreset, findHexColors };
|
|
154
|
+
export { ColorHighlighter, FontSize, GradientText, type GradientTextOptions, Image, type ImageOptions, LoadingNode, Markdown, Mention, type MentionEntity, type MentionOptions, type RichTextPresetOptions, type SlashCommandMatchData, SlashCommands, type SlashCommandsOptions, SmilieReplacer, TemplateSuggestions, type TemplateSuggestionsOptions, createMentionExtension, createRichTextPreset, findHexColors, handleImageInsertion, imagePastePluginKey, insertImageNode, updateImageSrc };
|
package/dist/extensions/index.js
CHANGED
|
@@ -1552,20 +1552,140 @@ var Markdown = Extension6.create({
|
|
|
1552
1552
|
var resolveExt = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
|
|
1553
1553
|
var Markdown2 = resolveExt(Markdown, "Markdown");
|
|
1554
1554
|
|
|
1555
|
-
// src/extensions/
|
|
1555
|
+
// src/extensions/image.ts
|
|
1556
|
+
import * as _Image from "@tiptap/extension-image";
|
|
1557
|
+
import { Plugin as Plugin5, PluginKey as PluginKey2 } from "@tiptap/pm/state";
|
|
1556
1558
|
var resolveExt2 = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
|
|
1557
|
-
var
|
|
1558
|
-
var
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1559
|
+
var BaseImage = resolveExt2(_Image, "Image");
|
|
1560
|
+
var imagePastePluginKey = new PluginKey2("imagePasteHandler");
|
|
1561
|
+
function insertImageNode(view, src, alt) {
|
|
1562
|
+
const { schema } = view.state;
|
|
1563
|
+
const imageType = schema.nodes.image;
|
|
1564
|
+
if (!imageType) return;
|
|
1565
|
+
const node = imageType.create({ src, alt: alt || "" });
|
|
1566
|
+
const tr = view.state.tr.replaceSelectionWith(node);
|
|
1567
|
+
view.dispatch(tr);
|
|
1568
|
+
}
|
|
1569
|
+
function updateImageSrc(view, oldSrc, newSrc) {
|
|
1570
|
+
const { doc } = view.state;
|
|
1571
|
+
let foundPos = null;
|
|
1572
|
+
let foundAttrs = null;
|
|
1573
|
+
doc.descendants((node, pos) => {
|
|
1574
|
+
if (node.type.name === "image" && node.attrs.src === oldSrc) {
|
|
1575
|
+
foundPos = pos;
|
|
1576
|
+
foundAttrs = node.attrs;
|
|
1577
|
+
return false;
|
|
1578
|
+
}
|
|
1579
|
+
});
|
|
1580
|
+
if (foundPos !== null && foundAttrs) {
|
|
1581
|
+
const tr = view.state.tr.setNodeMarkup(foundPos, void 0, {
|
|
1582
|
+
...foundAttrs,
|
|
1583
|
+
src: newSrc
|
|
1584
|
+
});
|
|
1585
|
+
view.dispatch(tr);
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
function handleImageInsertion(view, file, options) {
|
|
1589
|
+
if (typeof options.upload === "function") {
|
|
1590
|
+
const hasObjectUrl = typeof URL !== "undefined" && typeof URL.createObjectURL === "function";
|
|
1591
|
+
const tempUrl = hasObjectUrl ? URL.createObjectURL(file) : null;
|
|
1592
|
+
if (tempUrl) {
|
|
1593
|
+
insertImageNode(view, tempUrl, file.name);
|
|
1594
|
+
}
|
|
1595
|
+
Promise.resolve(options.upload(file)).then((uploadedUrl) => {
|
|
1596
|
+
if (!uploadedUrl) return;
|
|
1597
|
+
if (tempUrl) {
|
|
1598
|
+
updateImageSrc(view, tempUrl, uploadedUrl);
|
|
1599
|
+
if (typeof URL.revokeObjectURL === "function") {
|
|
1600
|
+
URL.revokeObjectURL(tempUrl);
|
|
1601
|
+
}
|
|
1602
|
+
} else {
|
|
1603
|
+
insertImageNode(view, uploadedUrl, file.name);
|
|
1604
|
+
}
|
|
1605
|
+
}).catch((err) => {
|
|
1606
|
+
console.error("Failed to upload pasted image:", err);
|
|
1607
|
+
});
|
|
1608
|
+
} else if (options.allowBase64 !== false) {
|
|
1609
|
+
if (typeof FileReader !== "undefined") {
|
|
1610
|
+
const reader = new FileReader();
|
|
1611
|
+
reader.onload = () => {
|
|
1612
|
+
const src = reader.result;
|
|
1613
|
+
if (src) {
|
|
1614
|
+
insertImageNode(view, src, file.name);
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
reader.readAsDataURL(file);
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
var Image2 = BaseImage.extend({
|
|
1622
|
+
addOptions() {
|
|
1623
|
+
return {
|
|
1624
|
+
...this.parent?.(),
|
|
1625
|
+
allowBase64: true,
|
|
1626
|
+
enablePaste: true,
|
|
1627
|
+
enableDrop: true,
|
|
1628
|
+
upload: void 0,
|
|
1629
|
+
HTMLAttributes: {
|
|
1630
|
+
class: "rounded-md max-w-full h-auto my-2"
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
},
|
|
1634
|
+
addProseMirrorPlugins() {
|
|
1635
|
+
const parentPlugins = this.parent?.() || [];
|
|
1636
|
+
const options = this.options;
|
|
1637
|
+
if (!options.enablePaste && !options.enableDrop) {
|
|
1638
|
+
return parentPlugins;
|
|
1639
|
+
}
|
|
1640
|
+
const pastePlugin = new Plugin5({
|
|
1641
|
+
key: imagePastePluginKey,
|
|
1642
|
+
props: {
|
|
1643
|
+
handlePaste(view, event) {
|
|
1644
|
+
if (!options.enablePaste) return false;
|
|
1645
|
+
const items = Array.from(event.clipboardData?.items || []);
|
|
1646
|
+
const imageItems = items.filter(
|
|
1647
|
+
(item) => item.kind === "file" && item.type.startsWith("image/")
|
|
1648
|
+
);
|
|
1649
|
+
if (imageItems.length === 0) return false;
|
|
1650
|
+
event.preventDefault();
|
|
1651
|
+
for (const item of imageItems) {
|
|
1652
|
+
const file = item.getAsFile();
|
|
1653
|
+
if (!file) continue;
|
|
1654
|
+
handleImageInsertion(view, file, options);
|
|
1655
|
+
}
|
|
1656
|
+
return true;
|
|
1657
|
+
},
|
|
1658
|
+
handleDrop(view, event) {
|
|
1659
|
+
if (!options.enableDrop) return false;
|
|
1660
|
+
const files = Array.from(event.dataTransfer?.files || []);
|
|
1661
|
+
const imageFiles = files.filter((f) => f.type.startsWith("image/"));
|
|
1662
|
+
if (imageFiles.length === 0) return false;
|
|
1663
|
+
event.preventDefault();
|
|
1664
|
+
for (const file of imageFiles) {
|
|
1665
|
+
handleImageInsertion(view, file, options);
|
|
1666
|
+
}
|
|
1667
|
+
return true;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
});
|
|
1671
|
+
return [...parentPlugins, pastePlugin];
|
|
1672
|
+
}
|
|
1673
|
+
});
|
|
1674
|
+
|
|
1675
|
+
// src/extensions/rich-text-preset.ts
|
|
1676
|
+
var resolveExt3 = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
|
|
1677
|
+
var StarterKit = resolveExt3(_StarterKit, "StarterKit");
|
|
1678
|
+
var Color = resolveExt3(_Color, "Color");
|
|
1679
|
+
var Highlight = resolveExt3(_Highlight, "Highlight");
|
|
1680
|
+
var Link2 = resolveExt3(_Link, "Link");
|
|
1681
|
+
var TaskList2 = resolveExt3(_TaskList, "TaskList");
|
|
1682
|
+
var TaskItem2 = resolveExt3(_TaskItem, "TaskItem");
|
|
1683
|
+
var TextAlign = resolveExt3(_TextAlign, "TextAlign");
|
|
1684
|
+
var TextStyle = resolveExt3(_TextStyle, "TextStyle");
|
|
1685
|
+
var Typography = resolveExt3(_Typography, "Typography");
|
|
1686
|
+
var Underline = resolveExt3(_Underline, "Underline");
|
|
1687
|
+
var Placeholder = resolveExt3(_Placeholder, "Placeholder");
|
|
1688
|
+
var CharacterCount = resolveExt3(_CharacterCount, "CharacterCount");
|
|
1569
1689
|
function createRichTextPreset(options = {}) {
|
|
1570
1690
|
const {
|
|
1571
1691
|
placeholder = "Start typing...",
|
|
@@ -1687,12 +1807,25 @@ function createRichTextPreset(options = {}) {
|
|
|
1687
1807
|
})
|
|
1688
1808
|
);
|
|
1689
1809
|
}
|
|
1810
|
+
if (options.image !== false) {
|
|
1811
|
+
const imageConfig = typeof options.image === "object" ? options.image : {};
|
|
1812
|
+
extensions2.push(
|
|
1813
|
+
Image2.configure({
|
|
1814
|
+
HTMLAttributes: {
|
|
1815
|
+
class: "rounded-md max-w-full h-auto my-2",
|
|
1816
|
+
...imageConfig.HTMLAttributes || {}
|
|
1817
|
+
},
|
|
1818
|
+
...imageConfig
|
|
1819
|
+
})
|
|
1820
|
+
);
|
|
1821
|
+
}
|
|
1690
1822
|
return extensions2;
|
|
1691
1823
|
}
|
|
1692
1824
|
export {
|
|
1693
1825
|
ColorHighlighter,
|
|
1694
1826
|
FontSize,
|
|
1695
1827
|
GradientText,
|
|
1828
|
+
Image2 as Image,
|
|
1696
1829
|
LoadingNode,
|
|
1697
1830
|
Markdown2 as Markdown,
|
|
1698
1831
|
Mention,
|
|
@@ -1701,6 +1834,10 @@ export {
|
|
|
1701
1834
|
TemplateSuggestions,
|
|
1702
1835
|
createMentionExtension,
|
|
1703
1836
|
createRichTextPreset,
|
|
1704
|
-
findHexColors
|
|
1837
|
+
findHexColors,
|
|
1838
|
+
handleImageInsertion,
|
|
1839
|
+
imagePastePluginKey,
|
|
1840
|
+
insertImageNode,
|
|
1841
|
+
updateImageSrc
|
|
1705
1842
|
};
|
|
1706
1843
|
//# sourceMappingURL=index.js.map
|