@overlap/rte 0.1.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/README.md +269 -0
- package/dist/components/Dropdown.d.ts +19 -0
- package/dist/components/Dropdown.d.ts.map +1 -0
- package/dist/components/Editor.d.ts +4 -0
- package/dist/components/Editor.d.ts.map +1 -0
- package/dist/components/FloatingToolbar.d.ts +10 -0
- package/dist/components/FloatingToolbar.d.ts.map +1 -0
- package/dist/components/IconWrapper.d.ts +10 -0
- package/dist/components/IconWrapper.d.ts.map +1 -0
- package/dist/components/Icons.d.ts +32 -0
- package/dist/components/Icons.d.ts.map +1 -0
- package/dist/components/Toolbar.d.ts +10 -0
- package/dist/components/Toolbar.d.ts.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/index.d.ts +208 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +2080 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2116 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/base.d.ts +10 -0
- package/dist/plugins/base.d.ts.map +1 -0
- package/dist/plugins/clearFormatting.d.ts +6 -0
- package/dist/plugins/clearFormatting.d.ts.map +1 -0
- package/dist/plugins/colors.d.ts +4 -0
- package/dist/plugins/colors.d.ts.map +1 -0
- package/dist/plugins/fontSize.d.ts +3 -0
- package/dist/plugins/fontSize.d.ts.map +1 -0
- package/dist/plugins/headings.d.ts +3 -0
- package/dist/plugins/headings.d.ts.map +1 -0
- package/dist/plugins/image.d.ts +6 -0
- package/dist/plugins/image.d.ts.map +1 -0
- package/dist/plugins/index.d.ts +14 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/optional.d.ts +19 -0
- package/dist/plugins/optional.d.ts.map +1 -0
- package/dist/styles.css +638 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/clearFormatting.d.ts +21 -0
- package/dist/utils/clearFormatting.d.ts.map +1 -0
- package/dist/utils/content.d.ts +12 -0
- package/dist/utils/content.d.ts.map +1 -0
- package/dist/utils/history.d.ts +14 -0
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/listIndent.d.ts +9 -0
- package/dist/utils/listIndent.d.ts.map +1 -0
- package/dist/utils/stateReflection.d.ts +18 -0
- package/dist/utils/stateReflection.d.ts.map +1 -0
- package/package.json +48 -0
- package/src/components/Dropdown.tsx +103 -0
- package/src/components/Editor.css +2 -0
- package/src/components/Editor.tsx +785 -0
- package/src/components/FloatingToolbar.tsx +214 -0
- package/src/components/IconWrapper.tsx +14 -0
- package/src/components/Icons.tsx +145 -0
- package/src/components/Toolbar.tsx +137 -0
- package/src/components/index.ts +3 -0
- package/src/index.ts +19 -0
- package/src/plugins/base.tsx +91 -0
- package/src/plugins/clearFormatting.tsx +31 -0
- package/src/plugins/colors.tsx +122 -0
- package/src/plugins/fontSize.tsx +81 -0
- package/src/plugins/headings.tsx +76 -0
- package/src/plugins/image.tsx +189 -0
- package/src/plugins/index.ts +54 -0
- package/src/plugins/optional.tsx +221 -0
- package/src/styles.css +638 -0
- package/src/types.ts +92 -0
- package/src/utils/clearFormatting.ts +244 -0
- package/src/utils/content.ts +290 -0
- package/src/utils/history.ts +59 -0
- package/src/utils/listIndent.ts +171 -0
- package/src/utils/stateReflection.ts +175 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entfernt alle Formatierungen aus der aktuellen Selection
|
|
3
|
+
*/
|
|
4
|
+
export declare function clearFormatting(selection: Selection): void;
|
|
5
|
+
/**
|
|
6
|
+
* Entfernt nur Textfarbe
|
|
7
|
+
*/
|
|
8
|
+
export declare function clearTextColor(selection: Selection): void;
|
|
9
|
+
/**
|
|
10
|
+
* Entfernt nur Hintergrundfarbe
|
|
11
|
+
*/
|
|
12
|
+
export declare function clearBackgroundColor(selection: Selection): void;
|
|
13
|
+
/**
|
|
14
|
+
* Entfernt nur Font-Size
|
|
15
|
+
*/
|
|
16
|
+
export declare function clearFontSize(selection: Selection): void;
|
|
17
|
+
/**
|
|
18
|
+
* Entfernt Links (behält Text)
|
|
19
|
+
*/
|
|
20
|
+
export declare function clearLinks(selection: Selection): void;
|
|
21
|
+
//# sourceMappingURL=clearFormatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clearFormatting.d.ts","sourceRoot":"","sources":["../../src/utils/clearFormatting.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAiF1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAgCzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAgC/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAgCxD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CA0CrD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { EditorContent } from "../types";
|
|
3
|
+
export declare function domToContent(element: HTMLElement): EditorContent;
|
|
4
|
+
export declare function contentToDOM(content: EditorContent, container: HTMLElement, customLinkComponent?: React.ComponentType<{
|
|
5
|
+
href: string;
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}>, customHeadingRenderer?: (level: string, children: React.ReactNode) => React.ReactElement): void;
|
|
9
|
+
export declare function createEmptyContent(): EditorContent;
|
|
10
|
+
export declare function htmlToContent(htmlString: string): EditorContent;
|
|
11
|
+
export declare function contentToHTML(content: EditorContent): string;
|
|
12
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/utils/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAc,MAAM,UAAU,CAAC;AAErD,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,CAsKhE;AAED,wBAAgB,YAAY,CACxB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,WAAW,EACtB,mBAAmB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB,CAAC,EACF,qBAAqB,CAAC,EAAE,CACpB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,KAAK,CAAC,SAAS,KACxB,KAAK,CAAC,YAAY,GACxB,IAAI,CAwFN;AAED,wBAAgB,kBAAkB,IAAI,aAAa,CAIlD;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAI/D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAI5D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EditorContent } from '../types';
|
|
2
|
+
export declare class HistoryManager {
|
|
3
|
+
private history;
|
|
4
|
+
private currentIndex;
|
|
5
|
+
private maxHistorySize;
|
|
6
|
+
push(content: EditorContent): void;
|
|
7
|
+
undo(): EditorContent | null;
|
|
8
|
+
redo(): EditorContent | null;
|
|
9
|
+
canUndo(): boolean;
|
|
10
|
+
canRedo(): boolean;
|
|
11
|
+
getCurrent(): EditorContent | null;
|
|
12
|
+
reset(): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/utils/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,cAAc,CAAc;IAEpC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAelC,IAAI,IAAI,aAAa,GAAG,IAAI;IAQ5B,IAAI,IAAI,aAAa,GAAG,IAAI;IAQ5B,OAAO,IAAI,OAAO;IAIlB,OAAO,IAAI,OAAO;IAIlB,UAAU,IAAI,aAAa,GAAG,IAAI;IAOlC,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Erhöht den Einrückungs-Level eines List-Items (Tab)
|
|
3
|
+
*/
|
|
4
|
+
export declare function indentListItem(selection: Selection): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Reduziert den Einrückungs-Level eines List-Items (Shift+Tab)
|
|
7
|
+
*/
|
|
8
|
+
export declare function outdentListItem(selection: Selection): boolean;
|
|
9
|
+
//# sourceMappingURL=listIndent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listIndent.d.ts","sourceRoot":"","sources":["../../src/utils/listIndent.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CA+F5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAkE7D"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EditorAPI } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Liest die aktuelle Font-Size aus dem DOM an der Cursor-Position
|
|
4
|
+
*/
|
|
5
|
+
export declare function getCurrentFontSize(editor: EditorAPI): string | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Liest die aktuelle Textfarbe aus dem DOM an der Cursor-Position
|
|
8
|
+
*/
|
|
9
|
+
export declare function getCurrentTextColor(editor: EditorAPI): string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Liest die aktuelle Hintergrundfarbe aus dem DOM an der Cursor-Position
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCurrentBackgroundColor(editor: EditorAPI): string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Liest das aktuelle Heading-Level aus dem DOM an der Cursor-Position
|
|
16
|
+
*/
|
|
17
|
+
export declare function getCurrentHeading(editor: EditorAPI, availableHeadings: string[]): string | undefined;
|
|
18
|
+
//# sourceMappingURL=stateReflection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateReflection.d.ts","sourceRoot":"","sources":["../../src/utils/stateReflection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CA2BxE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAkDzE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAkD/E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CA0BpG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@overlap/rte",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A lightweight, extensible Rich Text Editor for React",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "rollup -c",
|
|
15
|
+
"dev": "rollup -c -w",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"react",
|
|
20
|
+
"rich-text-editor",
|
|
21
|
+
"rte",
|
|
22
|
+
"contenteditable",
|
|
23
|
+
"editor"
|
|
24
|
+
],
|
|
25
|
+
"author": "Almir Nakicevic <a.nakicevic@overlap.at>",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/overlap-dev/hendriks-rte"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": ">=18.0.0",
|
|
32
|
+
"react-dom": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"tslib": "^2.8.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
39
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
40
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
41
|
+
"@types/react": "^18.2.43",
|
|
42
|
+
"@types/react-dom": "^18.2.17",
|
|
43
|
+
"rollup": "^4.6.1",
|
|
44
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
45
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
46
|
+
"typescript": "^5.3.3"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { Icon } from './Icons';
|
|
3
|
+
|
|
4
|
+
interface DropdownProps {
|
|
5
|
+
icon: string;
|
|
6
|
+
label: string;
|
|
7
|
+
options: Array<{ value: string; label: string; icon?: string; color?: string; preview?: string; headingPreview?: string }>;
|
|
8
|
+
onSelect: (value: string) => void;
|
|
9
|
+
currentValue?: string;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Dropdown: React.FC<DropdownProps> = ({
|
|
14
|
+
icon,
|
|
15
|
+
label,
|
|
16
|
+
options,
|
|
17
|
+
onSelect,
|
|
18
|
+
currentValue,
|
|
19
|
+
disabled,
|
|
20
|
+
}) => {
|
|
21
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
22
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
26
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
27
|
+
setIsOpen(false);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (isOpen) {
|
|
32
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return () => {
|
|
36
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
37
|
+
};
|
|
38
|
+
}, [isOpen]);
|
|
39
|
+
|
|
40
|
+
const handleSelect = (value: string) => {
|
|
41
|
+
onSelect(value);
|
|
42
|
+
setIsOpen(false);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const currentOption = options.find(opt => opt.value === currentValue);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="rte-dropdown" ref={dropdownRef}>
|
|
49
|
+
<button
|
|
50
|
+
type="button"
|
|
51
|
+
onClick={() => !disabled && setIsOpen(!isOpen)}
|
|
52
|
+
disabled={disabled}
|
|
53
|
+
className={`rte-toolbar-button rte-dropdown-button ${currentOption ? 'rte-dropdown-button-has-value' : ''}`}
|
|
54
|
+
title={label}
|
|
55
|
+
aria-label={label}
|
|
56
|
+
>
|
|
57
|
+
<Icon icon={icon} width={18} height={18} />
|
|
58
|
+
{currentOption && (
|
|
59
|
+
<span className="rte-dropdown-value">{currentOption.label}</span>
|
|
60
|
+
)}
|
|
61
|
+
</button>
|
|
62
|
+
{isOpen && (
|
|
63
|
+
<div className="rte-dropdown-menu">
|
|
64
|
+
{options.map((option) => (
|
|
65
|
+
<button
|
|
66
|
+
key={option.value}
|
|
67
|
+
type="button"
|
|
68
|
+
className={`rte-dropdown-item ${currentValue === option.value ? 'rte-dropdown-item-active' : ''}`}
|
|
69
|
+
onClick={() => handleSelect(option.value)}
|
|
70
|
+
>
|
|
71
|
+
{option.color && (
|
|
72
|
+
<span
|
|
73
|
+
className={`rte-dropdown-color-preview ${currentValue === option.value ? 'active' : ''}`}
|
|
74
|
+
style={{ backgroundColor: option.color }}
|
|
75
|
+
/>
|
|
76
|
+
)}
|
|
77
|
+
{option.preview && !option.headingPreview && (
|
|
78
|
+
<span
|
|
79
|
+
className="rte-dropdown-fontsize-preview"
|
|
80
|
+
style={{ fontSize: `${option.preview}px` }}
|
|
81
|
+
>
|
|
82
|
+
Aa
|
|
83
|
+
</span>
|
|
84
|
+
)}
|
|
85
|
+
{option.headingPreview && (
|
|
86
|
+
<span
|
|
87
|
+
className={`rte-dropdown-heading-preview ${option.headingPreview}`}
|
|
88
|
+
>
|
|
89
|
+
{option.headingPreview === 'p' ? 'Normal' : option.headingPreview.toUpperCase()}
|
|
90
|
+
</span>
|
|
91
|
+
)}
|
|
92
|
+
{option.icon && <Icon icon={option.icon} width={16} height={16} />}
|
|
93
|
+
<span style={{ flex: 1, fontWeight: currentValue === option.value ? 600 : 400 }}>
|
|
94
|
+
{option.label}
|
|
95
|
+
</span>
|
|
96
|
+
</button>
|
|
97
|
+
))}
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|