@blankdotpage/cake 0.1.37 → 0.1.39
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/cake/core/runtime.d.ts.map +1 -1
- package/dist/cake/core/runtime.js +53 -20
- package/dist/cake/editor/cake-editor.d.ts +43 -2
- package/dist/cake/editor/cake-editor.d.ts.map +1 -1
- package/dist/cake/editor/cake-editor.js +155 -29
- package/dist/cake/extensions/index.d.ts +2 -1
- package/dist/cake/extensions/index.d.ts.map +1 -1
- package/dist/cake/extensions/index.js +2 -1
- package/dist/cake/extensions/link/link-popover.d.ts.map +1 -1
- package/dist/cake/extensions/link/link-popover.js +3 -11
- package/dist/cake/extensions/mention/index.d.ts +2 -0
- package/dist/cake/extensions/mention/index.d.ts.map +1 -0
- package/dist/cake/extensions/mention/index.js +1 -0
- package/dist/cake/extensions/mention/mention.d.ts +61 -0
- package/dist/cake/extensions/mention/mention.d.ts.map +1 -0
- package/dist/cake/extensions/mention/mention.js +460 -0
- package/dist/cake/react/index.d.ts +2 -0
- package/dist/cake/react/index.d.ts.map +1 -1
- package/dist/cake/react/index.js +70 -10
- package/dist/cake/test/harness.d.ts.map +1 -1
- package/dist/cake/test/harness.js +5 -1
- package/package.json +2 -1
package/dist/cake/react/index.js
CHANGED
|
@@ -13,7 +13,9 @@ function toEngineSelection(selection) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
export const CakeEditor = forwardRef(function CakeEditor(props, outerRef) {
|
|
16
|
+
const rootRef = useRef(null);
|
|
16
17
|
const containerRef = useRef(null);
|
|
18
|
+
const extensionsRootRef = useRef(null);
|
|
17
19
|
const engineRef = useRef(null);
|
|
18
20
|
const onChangeRef = useRef(props.onChange);
|
|
19
21
|
const onSelectionChangeRef = useRef(props.onSelectionChange);
|
|
@@ -33,8 +35,49 @@ export const CakeEditor = forwardRef(function CakeEditor(props, outerRef) {
|
|
|
33
35
|
if (!container) {
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
38
|
+
const extensionsRoot = document.createElement("div");
|
|
39
|
+
extensionsRoot.className = "cake-extension-overlay";
|
|
40
|
+
extensionsRoot.contentEditable = "false";
|
|
41
|
+
document.body.appendChild(extensionsRoot);
|
|
42
|
+
extensionsRootRef.current = extensionsRoot;
|
|
43
|
+
let rafId = null;
|
|
44
|
+
const syncOverlayPosition = () => {
|
|
45
|
+
rafId = null;
|
|
46
|
+
if (!extensionsRootRef.current) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const rect = container.getBoundingClientRect();
|
|
50
|
+
const overlay = extensionsRootRef.current;
|
|
51
|
+
overlay.style.position = "fixed";
|
|
52
|
+
overlay.style.top = `${rect.top}px`;
|
|
53
|
+
overlay.style.left = `${rect.left}px`;
|
|
54
|
+
overlay.style.width = `${rect.width}px`;
|
|
55
|
+
overlay.style.height = `${rect.height}px`;
|
|
56
|
+
overlay.style.pointerEvents = "none";
|
|
57
|
+
// Important: allow popovers (e.g. mentions) to overflow editor bounds without being clipped.
|
|
58
|
+
overlay.style.overflow = "visible";
|
|
59
|
+
};
|
|
60
|
+
const scheduleSync = () => {
|
|
61
|
+
if (rafId !== null) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
rafId = window.requestAnimationFrame(syncOverlayPosition);
|
|
65
|
+
};
|
|
66
|
+
// Initial positioning before engine mounts overlays.
|
|
67
|
+
syncOverlayPosition();
|
|
68
|
+
document.addEventListener("scroll", scheduleSync, {
|
|
69
|
+
capture: true,
|
|
70
|
+
passive: true,
|
|
71
|
+
});
|
|
72
|
+
window.addEventListener("resize", scheduleSync, { passive: true });
|
|
73
|
+
let resizeObserver = null;
|
|
74
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
75
|
+
resizeObserver = new ResizeObserver(scheduleSync);
|
|
76
|
+
resizeObserver.observe(container);
|
|
77
|
+
}
|
|
36
78
|
const engine = new CakeEditorEngine({
|
|
37
79
|
container,
|
|
80
|
+
extensionsRoot,
|
|
38
81
|
value: props.value,
|
|
39
82
|
selection: props.selection ?? undefined,
|
|
40
83
|
extensions: extensionsRef.current,
|
|
@@ -54,9 +97,17 @@ export const CakeEditor = forwardRef(function CakeEditor(props, outerRef) {
|
|
|
54
97
|
engineRef.current = engine;
|
|
55
98
|
setUiComponents(engine.getUIComponents());
|
|
56
99
|
return () => {
|
|
100
|
+
document.removeEventListener("scroll", scheduleSync, { capture: true });
|
|
101
|
+
window.removeEventListener("resize", scheduleSync);
|
|
102
|
+
if (rafId !== null) {
|
|
103
|
+
window.cancelAnimationFrame(rafId);
|
|
104
|
+
}
|
|
105
|
+
resizeObserver?.disconnect();
|
|
57
106
|
engine.destroy();
|
|
58
107
|
engineRef.current = null;
|
|
59
108
|
setUiComponents([]);
|
|
109
|
+
extensionsRootRef.current = null;
|
|
110
|
+
extensionsRoot.remove();
|
|
60
111
|
};
|
|
61
112
|
}, []);
|
|
62
113
|
useEffect(() => {
|
|
@@ -179,16 +230,25 @@ export const CakeEditor = forwardRef(function CakeEditor(props, outerRef) {
|
|
|
179
230
|
getActiveMarks: () => engineRef.current?.getActiveMarks() ?? [],
|
|
180
231
|
};
|
|
181
232
|
}, [props.value]);
|
|
182
|
-
const
|
|
183
|
-
? { ...props.style }
|
|
184
|
-
: {};
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
? `cake ${props.
|
|
190
|
-
: "cake";
|
|
191
|
-
|
|
233
|
+
const rootStyle = props.style
|
|
234
|
+
? { ...props.style, position: props.style.position ?? "relative" }
|
|
235
|
+
: { position: "relative" };
|
|
236
|
+
const rootClassName = props.className
|
|
237
|
+
? `cake-root ${props.className}`
|
|
238
|
+
: "cake-root";
|
|
239
|
+
const scrollerClassName = props.scrollerClassName
|
|
240
|
+
? `cake-scroller ${props.scrollerClassName}`
|
|
241
|
+
: "cake-scroller";
|
|
242
|
+
const scrollerBaselineStyle = {
|
|
243
|
+
height: "100%",
|
|
244
|
+
width: "100%",
|
|
245
|
+
overflowY: "auto",
|
|
246
|
+
overflowX: "hidden",
|
|
247
|
+
};
|
|
248
|
+
const scrollerStyle = props.scrollerStyle
|
|
249
|
+
? { ...scrollerBaselineStyle, ...props.scrollerStyle }
|
|
250
|
+
: scrollerBaselineStyle;
|
|
251
|
+
return (_jsxs("div", { ref: rootRef, className: rootClassName, style: rootStyle, children: [_jsx("div", { ref: containerRef, className: scrollerClassName, "data-placeholder": props.placeholder, style: scrollerStyle, onBlur: (event) => {
|
|
192
252
|
props.onBlur?.(event.nativeEvent);
|
|
193
253
|
} }), engineRef.current && uiComponents.length > 0
|
|
194
254
|
? createPortal(uiComponents.map((Component, index) => (_jsx(Component, { editor: engineRef.current }, index))), engineRef.current.getOverlayRoot())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/cake/test/harness.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../src/cake/test/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,8 @@ export function createTestHarness(valueOrOptions) {
|
|
|
9
9
|
? { value: valueOrOptions }
|
|
10
10
|
: valueOrOptions;
|
|
11
11
|
const container = document.createElement("div");
|
|
12
|
-
|
|
12
|
+
// Keep `cake` for backwards-compat in tests, but the production scroller class is `cake-scroller`.
|
|
13
|
+
container.className = "cake cake-scroller";
|
|
13
14
|
container.style.width = "400px";
|
|
14
15
|
container.style.height = "200px";
|
|
15
16
|
container.style.position = "absolute";
|
|
@@ -225,6 +226,9 @@ export function createTestHarness(valueOrOptions) {
|
|
|
225
226
|
if (!caret) {
|
|
226
227
|
return null;
|
|
227
228
|
}
|
|
229
|
+
if (caret.style.display === "none") {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
228
232
|
return {
|
|
229
233
|
top: parseFloat(caret.style.top),
|
|
230
234
|
left: parseFloat(caret.style.left),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blankdotpage/cake",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"test": "vitest run",
|
|
29
29
|
"test:browser": "vitest run --project browser",
|
|
30
30
|
"test:browser:ios": "vitest run --project browser-ios",
|
|
31
|
+
"test:e2e": "playwright test",
|
|
31
32
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
32
33
|
"lint": "eslint .",
|
|
33
34
|
"format": "prettier --write .",
|