@jbpark/live-editor 1.7.0 → 1.8.1
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/{ast-DxgO-X_f.mjs → ast-DiVN0l7x.mjs} +6 -2
- package/dist/ast-DiVN0l7x.mjs.map +1 -0
- package/dist/{document-kU_tXfS_.mjs → document-DJDRM79h.mjs} +54 -14
- package/dist/document-DJDRM79h.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +80 -61
- package/dist/index.mjs.map +1 -1
- package/dist/utils/ast/index.mjs +2 -2
- package/dist/utils/index.mjs +2 -2
- package/dist/{utils-qt78kxvP.mjs → utils-D1tlgtgj.mjs} +4 -14
- package/dist/{utils-qt78kxvP.mjs.map → utils-D1tlgtgj.mjs.map} +1 -1
- package/package.json +3 -3
- package/dist/ast-DxgO-X_f.mjs.map +0 -1
- package/dist/document-kU_tXfS_.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -49,6 +49,7 @@ interface Props$6 {
|
|
|
49
49
|
children: React$1.ReactNode;
|
|
50
50
|
fallback?: (message?: string) => React$1.ReactNode;
|
|
51
51
|
onError?: (e: Error, info: React$1.ErrorInfo) => void;
|
|
52
|
+
resetKeys?: readonly unknown[];
|
|
52
53
|
}
|
|
53
54
|
interface State {
|
|
54
55
|
hasError: boolean;
|
|
@@ -58,6 +59,7 @@ declare class ErrorBoundary extends React$1.Component<Props$6, State> {
|
|
|
58
59
|
constructor(props: Props$6);
|
|
59
60
|
static getDerivedStateFromError(error: Error): State;
|
|
60
61
|
componentDidCatch(error: Error, errorInfo: React$1.ErrorInfo): void;
|
|
62
|
+
componentDidUpdate(prevProps: Props$6): void;
|
|
61
63
|
render(): string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<React$1.ReactNode> | Promise<string | number | bigint | boolean | React$1.ReactPortal | React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>> | Iterable<React$1.ReactNode> | null | undefined> | null | undefined;
|
|
62
64
|
}
|
|
63
65
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as DRAGGABLE_ITEMS, b as __toESM, d as require_lib$1, f as require_lib, g as DEFAULT_TEMPLATE, p as BINDING_PROP } from "./document-
|
|
2
|
-
import { a as detectTypeScript, c as generateSections, d as replaceSections, i as compile, l as getCachedScriptBlob, n as clearCompilationCache, o as extractSections, r as cn, s as generateSection, t as baseModules, u as preloadScripts } from "./utils-
|
|
3
|
-
import { _ as parseArrayExpression, c as extract, d as getCurrentValue, f as parseBinding, g as extractObjectProperties, h as extractNodeValue, i as replaceIds, l as nanoid, m as createNodeFromValue, n as clone, o as update, p as arrayExpressionToCode, r as fillIds, t as validateBindingValue, u as findEditableChildren, v as parseValue, y as generateCode } from "./ast-
|
|
1
|
+
import { _ as DRAGGABLE_ITEMS, b as __toESM, d as require_lib$1, f as require_lib, g as DEFAULT_TEMPLATE, p as BINDING_PROP } from "./document-DJDRM79h.mjs";
|
|
2
|
+
import { a as detectTypeScript, c as generateSections, d as replaceSections, i as compile, l as getCachedScriptBlob, n as clearCompilationCache, o as extractSections, r as cn, s as generateSection, t as baseModules, u as preloadScripts } from "./utils-D1tlgtgj.mjs";
|
|
3
|
+
import { _ as parseArrayExpression, c as extract, d as getCurrentValue, f as parseBinding, g as extractObjectProperties, h as extractNodeValue, i as replaceIds, l as nanoid, m as createNodeFromValue, n as clone, o as update, p as arrayExpressionToCode, r as fillIds, t as validateBindingValue, u as findEditableChildren, v as parseValue, y as generateCode } from "./ast-DiVN0l7x.mjs";
|
|
4
4
|
import { generateTailwindCSS } from "./utils/tailwind/index.mjs";
|
|
5
5
|
import "@jbpark/ui-kit/style.css";
|
|
6
6
|
import React, { createContext, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
@@ -44,8 +44,12 @@ const useError = () => {
|
|
|
44
44
|
//#endregion
|
|
45
45
|
//#region src/components/context/context.tsx
|
|
46
46
|
const ContextProvider = ({ children }) => {
|
|
47
|
-
const [code,
|
|
47
|
+
const [code, setCodeState] = useState(DEFAULT_TEMPLATE);
|
|
48
48
|
const [error, setError] = useState(null);
|
|
49
|
+
const setCode = useCallback((next) => {
|
|
50
|
+
setError(null);
|
|
51
|
+
setCodeState(next);
|
|
52
|
+
}, []);
|
|
49
53
|
useEffect(() => {
|
|
50
54
|
return () => {
|
|
51
55
|
clearCompilationCache();
|
|
@@ -72,7 +76,9 @@ const EMPTY_STRING_ARRAY = [];
|
|
|
72
76
|
const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_STRING_ARRAY, styles = EMPTY_STRING_ARRAY, stylesheets = EMPTY_STRING_ARRAY, autoHeight = false, syncStyle = false, children, onLoaded, ...props }) => {
|
|
73
77
|
const iframeRef = useRef(null);
|
|
74
78
|
const [mountNode, setMountNode] = useState(null);
|
|
75
|
-
const
|
|
79
|
+
const loadedScriptsRef = useRef(/* @__PURE__ */ new Set());
|
|
80
|
+
const prevStyleCountRef = useRef(0);
|
|
81
|
+
const prevStylesheetCountRef = useRef(0);
|
|
76
82
|
const shouldAutoHeight = autoHeight && style.height == null;
|
|
77
83
|
const styleManagerRef = useRef({
|
|
78
84
|
copiedLinks: /* @__PURE__ */ new Set(),
|
|
@@ -129,9 +135,10 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
129
135
|
}
|
|
130
136
|
setMountNode(node);
|
|
131
137
|
applyStyle();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
const pendingScripts = scripts.filter((src) => !loadedScriptsRef.current.has(src));
|
|
139
|
+
if (pendingScripts.length) {
|
|
140
|
+
pendingScripts.forEach((src) => loadedScriptsRef.current.add(src));
|
|
141
|
+
Promise.all(pendingScripts.map(getCachedScriptBlob)).then((blobUrls) => {
|
|
135
142
|
if (!doc.head) return;
|
|
136
143
|
const fragment = doc.createDocumentFragment();
|
|
137
144
|
blobUrls.forEach((blobUrl) => {
|
|
@@ -184,6 +191,8 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
184
191
|
}
|
|
185
192
|
if (styleEl.textContent !== css) styleEl.textContent = css;
|
|
186
193
|
});
|
|
194
|
+
for (let index = styles.length; index < prevStyleCountRef.current; index++) doc.getElementById(`injected-style-${index}`)?.remove();
|
|
195
|
+
prevStyleCountRef.current = styles.length;
|
|
187
196
|
stylesheets.forEach((href, index) => {
|
|
188
197
|
const linkId = `injected-stylesheet-${index}`;
|
|
189
198
|
let linkEl = doc.getElementById(linkId);
|
|
@@ -195,6 +204,8 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
195
204
|
}
|
|
196
205
|
if (linkEl.href !== href) linkEl.href = href;
|
|
197
206
|
});
|
|
207
|
+
for (let index = stylesheets.length; index < prevStylesheetCountRef.current; index++) doc.getElementById(`injected-stylesheet-${index}`)?.remove();
|
|
208
|
+
prevStylesheetCountRef.current = stylesheets.length;
|
|
198
209
|
}, [styles, stylesheets]);
|
|
199
210
|
useEffect(() => {
|
|
200
211
|
if (!shouldAutoHeight || !mountNode || !iframeRef.current) return;
|
|
@@ -295,41 +306,6 @@ const Shadow = ({ children }) => {
|
|
|
295
306
|
renderTargetRef.current = target;
|
|
296
307
|
setRenderTarget(target);
|
|
297
308
|
}
|
|
298
|
-
const onClick = (e) => {
|
|
299
|
-
const eventInit = {
|
|
300
|
-
bubbles: true,
|
|
301
|
-
cancelable: true,
|
|
302
|
-
composed: true
|
|
303
|
-
};
|
|
304
|
-
let newEvent;
|
|
305
|
-
if (e instanceof MouseEvent) newEvent = new MouseEvent(e.type, {
|
|
306
|
-
...eventInit,
|
|
307
|
-
clientX: e.clientX,
|
|
308
|
-
clientY: e.clientY,
|
|
309
|
-
button: e.button
|
|
310
|
-
});
|
|
311
|
-
else if (e instanceof PointerEvent) newEvent = new PointerEvent(e.type, {
|
|
312
|
-
...eventInit,
|
|
313
|
-
clientX: e.clientX,
|
|
314
|
-
clientY: e.clientY,
|
|
315
|
-
pointerId: e.pointerId
|
|
316
|
-
});
|
|
317
|
-
else newEvent = new Event(e.type, eventInit);
|
|
318
|
-
hostRef.current?.dispatchEvent(newEvent);
|
|
319
|
-
};
|
|
320
|
-
const eventTypes = [
|
|
321
|
-
"click",
|
|
322
|
-
"pointerdown",
|
|
323
|
-
"pointerup"
|
|
324
|
-
];
|
|
325
|
-
eventTypes.forEach((type) => {
|
|
326
|
-
target.addEventListener(type, onClick, true);
|
|
327
|
-
});
|
|
328
|
-
return () => {
|
|
329
|
-
eventTypes.forEach((type) => {
|
|
330
|
-
target?.removeEventListener(type, onClick, true);
|
|
331
|
-
});
|
|
332
|
-
};
|
|
333
309
|
}, []);
|
|
334
310
|
useLayoutEffect(() => {
|
|
335
311
|
if (renderTargetRef.current && !renderTarget) setRenderTarget(renderTargetRef.current);
|
|
@@ -402,7 +378,16 @@ const Renderer = ({ preview, headers, modules, frame, provider }) => {
|
|
|
402
378
|
...baseModules,
|
|
403
379
|
...modules
|
|
404
380
|
}), [modules]);
|
|
405
|
-
const module = useMemo(() =>
|
|
381
|
+
const module = useMemo(() => {
|
|
382
|
+
try {
|
|
383
|
+
return compile(preview, memoizedModules);
|
|
384
|
+
} catch (e) {
|
|
385
|
+
return {
|
|
386
|
+
exports: {},
|
|
387
|
+
error: e instanceof Error ? e.message : "Module transformation error"
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
}, [preview, memoizedModules]);
|
|
406
391
|
const renderProvider = (component) => {
|
|
407
392
|
return provider ? provider(component) : component;
|
|
408
393
|
};
|
|
@@ -11722,6 +11707,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
11722
11707
|
};
|
|
11723
11708
|
const addItem = () => {
|
|
11724
11709
|
const firstItem = objectItems[0];
|
|
11710
|
+
if (!firstItem) return;
|
|
11725
11711
|
const clonedElement = cloneObjectItemElement(firstItem);
|
|
11726
11712
|
const editableProperties = extractObjectProperties(clonedElement);
|
|
11727
11713
|
const nextItems = [...objectItems];
|
|
@@ -11845,6 +11831,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
11845
11831
|
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
11846
11832
|
variant: "solid",
|
|
11847
11833
|
color: "green",
|
|
11834
|
+
disabled: objectItems.length === 0,
|
|
11848
11835
|
onClick: addItem,
|
|
11849
11836
|
children: "Add Item"
|
|
11850
11837
|
})]
|
|
@@ -12382,7 +12369,7 @@ const Field = ({ binding, id, value, onChange }) => {
|
|
|
12382
12369
|
return;
|
|
12383
12370
|
}
|
|
12384
12371
|
setValidationError(null);
|
|
12385
|
-
if (next
|
|
12372
|
+
if (next !== value) onChange?.({
|
|
12386
12373
|
id,
|
|
12387
12374
|
label: binding.label,
|
|
12388
12375
|
value: next
|
|
@@ -12472,7 +12459,7 @@ const Field = ({ binding, id, value, onChange }) => {
|
|
|
12472
12459
|
return;
|
|
12473
12460
|
}
|
|
12474
12461
|
setValidationError(null);
|
|
12475
|
-
if (next
|
|
12462
|
+
if (next !== value) onChange?.({
|
|
12476
12463
|
id,
|
|
12477
12464
|
label: binding.label,
|
|
12478
12465
|
value: next
|
|
@@ -12493,7 +12480,7 @@ const Field = ({ binding, id, value, onChange }) => {
|
|
|
12493
12480
|
return;
|
|
12494
12481
|
}
|
|
12495
12482
|
setValidationError(null);
|
|
12496
|
-
if (next
|
|
12483
|
+
if (next !== value) onChange?.({
|
|
12497
12484
|
id,
|
|
12498
12485
|
label: binding.label,
|
|
12499
12486
|
value: next
|
|
@@ -12933,6 +12920,15 @@ var ErrorBoundary = class extends React.Component {
|
|
|
12933
12920
|
console.error("🚨 [Boundary] Rendering error:", error, errorInfo);
|
|
12934
12921
|
this.props.onError?.(error, errorInfo);
|
|
12935
12922
|
}
|
|
12923
|
+
componentDidUpdate(prevProps) {
|
|
12924
|
+
if (!this.state.hasError) return;
|
|
12925
|
+
const prevKeys = prevProps.resetKeys ?? [];
|
|
12926
|
+
const nextKeys = this.props.resetKeys ?? [];
|
|
12927
|
+
if (prevKeys.length !== nextKeys.length || nextKeys.some((key, i) => key !== prevKeys[i])) this.setState({
|
|
12928
|
+
hasError: false,
|
|
12929
|
+
error: void 0
|
|
12930
|
+
});
|
|
12931
|
+
}
|
|
12936
12932
|
render() {
|
|
12937
12933
|
if (this.state.hasError) return this.props.fallback ? /* @__PURE__ */ jsx(Fragment, { children: this.props.fallback(this.state.error?.message) }) : /* @__PURE__ */ jsx(Error$2, {
|
|
12938
12934
|
message: this.state.error?.message,
|
|
@@ -12954,7 +12950,7 @@ const Guard = ({ children, onError }) => {
|
|
|
12954
12950
|
const errorHandled = useRef(false);
|
|
12955
12951
|
useEffect(() => {
|
|
12956
12952
|
if (!containerRef.current) return;
|
|
12957
|
-
const
|
|
12953
|
+
const handleWindowError = (event) => {
|
|
12958
12954
|
if (errorHandled.current) return;
|
|
12959
12955
|
errorHandled.current = true;
|
|
12960
12956
|
const errorMessage = event.error?.message || event.message || "Unknown error";
|
|
@@ -12967,7 +12963,7 @@ const Guard = ({ children, onError }) => {
|
|
|
12967
12963
|
}, 100);
|
|
12968
12964
|
return true;
|
|
12969
12965
|
};
|
|
12970
|
-
const
|
|
12966
|
+
const handleUnhandledRejection = (event) => {
|
|
12971
12967
|
if (errorHandled.current) return;
|
|
12972
12968
|
errorHandled.current = true;
|
|
12973
12969
|
const errorMessage = event.reason?.message || "Promise rejection";
|
|
@@ -12978,11 +12974,11 @@ const Guard = ({ children, onError }) => {
|
|
|
12978
12974
|
errorHandled.current = false;
|
|
12979
12975
|
}, 100);
|
|
12980
12976
|
};
|
|
12981
|
-
window.addEventListener("error",
|
|
12982
|
-
window.addEventListener("unhandledrejection",
|
|
12977
|
+
window.addEventListener("error", handleWindowError, true);
|
|
12978
|
+
window.addEventListener("unhandledrejection", handleUnhandledRejection, true);
|
|
12983
12979
|
return () => {
|
|
12984
|
-
window.removeEventListener("error",
|
|
12985
|
-
window.removeEventListener("unhandledrejection",
|
|
12980
|
+
window.removeEventListener("error", handleWindowError, true);
|
|
12981
|
+
window.removeEventListener("unhandledrejection", handleUnhandledRejection, true);
|
|
12986
12982
|
};
|
|
12987
12983
|
}, [onError]);
|
|
12988
12984
|
if (error) return /* @__PURE__ */ jsx(Error$2, {
|
|
@@ -13041,9 +13037,10 @@ const Client = ({ code: _code = "", className, showError, props = {}, modules =
|
|
|
13041
13037
|
...baseModules,
|
|
13042
13038
|
...modules
|
|
13043
13039
|
};
|
|
13040
|
+
const effectiveCode = _code || code;
|
|
13044
13041
|
let module = null;
|
|
13045
|
-
if (
|
|
13046
|
-
module = compile(
|
|
13042
|
+
if (effectiveCode) try {
|
|
13043
|
+
module = compile(effectiveCode, mergedModules);
|
|
13047
13044
|
} catch (e) {
|
|
13048
13045
|
module = {
|
|
13049
13046
|
exports: {},
|
|
@@ -13068,6 +13065,7 @@ const Client = ({ code: _code = "", className, showError, props = {}, modules =
|
|
|
13068
13065
|
children: /* @__PURE__ */ jsx(Frame, {
|
|
13069
13066
|
...frame,
|
|
13070
13067
|
children: (container) => /* @__PURE__ */ jsx(Error$1.Boundary, {
|
|
13068
|
+
resetKeys: [effectiveCode],
|
|
13071
13069
|
onError: (e) => setError(e.message),
|
|
13072
13070
|
children: renderProvider(/* @__PURE__ */ jsx(Error$1.Guard, {
|
|
13073
13071
|
onError: (e) => setError(e.message),
|
|
@@ -13086,6 +13084,7 @@ const Client = ({ code: _code = "", className, showError, props = {}, modules =
|
|
|
13086
13084
|
containerType: "inline-size"
|
|
13087
13085
|
},
|
|
13088
13086
|
children: /* @__PURE__ */ jsx(Error$1.Boundary, {
|
|
13087
|
+
resetKeys: [effectiveCode],
|
|
13089
13088
|
onError: (e) => setError(e.message),
|
|
13090
13089
|
children: renderProvider(/* @__PURE__ */ jsx(Error$1.Guard, {
|
|
13091
13090
|
onError: (e) => setError(e.message),
|
|
@@ -13100,12 +13099,23 @@ const Client = ({ code: _code = "", className, showError, props = {}, modules =
|
|
|
13100
13099
|
const Preview = ({ code, props = {}, modules = {}, dynamicTailwind = false, provider, ...restProps }) => {
|
|
13101
13100
|
const [runtimeError, setRuntimeError] = useState(null);
|
|
13102
13101
|
const [dynamicCSS, setDynamicCSS] = useState("");
|
|
13102
|
+
const [prevCode, setPrevCode] = useState(code);
|
|
13103
|
+
if (code !== prevCode) {
|
|
13104
|
+
setPrevCode(code);
|
|
13105
|
+
setRuntimeError(null);
|
|
13106
|
+
}
|
|
13103
13107
|
const renderProvider = (component) => {
|
|
13104
13108
|
return provider ? provider(component) : component;
|
|
13105
13109
|
};
|
|
13106
13110
|
useEffect(() => {
|
|
13107
13111
|
if (!code || !dynamicTailwind) return;
|
|
13108
|
-
|
|
13112
|
+
let cancelled = false;
|
|
13113
|
+
generateTailwindCSS(code).then((css) => {
|
|
13114
|
+
if (!cancelled) setDynamicCSS(css);
|
|
13115
|
+
});
|
|
13116
|
+
return () => {
|
|
13117
|
+
cancelled = true;
|
|
13118
|
+
};
|
|
13109
13119
|
}, [code, dynamicTailwind]);
|
|
13110
13120
|
if (runtimeError) return /* @__PURE__ */ jsx(Error$1, {
|
|
13111
13121
|
title: "Runtime Error",
|
|
@@ -13114,10 +13124,18 @@ const Preview = ({ code, props = {}, modules = {}, dynamicTailwind = false, prov
|
|
|
13114
13124
|
onReset: () => setRuntimeError(null)
|
|
13115
13125
|
});
|
|
13116
13126
|
if (code) {
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13127
|
+
let module;
|
|
13128
|
+
try {
|
|
13129
|
+
module = compile(code, {
|
|
13130
|
+
...baseModules,
|
|
13131
|
+
...modules
|
|
13132
|
+
});
|
|
13133
|
+
} catch (e) {
|
|
13134
|
+
module = {
|
|
13135
|
+
exports: {},
|
|
13136
|
+
error: e instanceof Error ? e.message : "Module transformation error"
|
|
13137
|
+
};
|
|
13138
|
+
}
|
|
13121
13139
|
if (module.error) return /* @__PURE__ */ jsx(Error$1, {
|
|
13122
13140
|
title: "Compile Error",
|
|
13123
13141
|
message: module.error,
|
|
@@ -13129,13 +13147,14 @@ const Preview = ({ code, props = {}, modules = {}, dynamicTailwind = false, prov
|
|
|
13129
13147
|
className: "mx-5 mt-25"
|
|
13130
13148
|
});
|
|
13131
13149
|
return /* @__PURE__ */ jsx(Error$1.Boundary, {
|
|
13150
|
+
resetKeys: [code],
|
|
13132
13151
|
fallback: (message) => /* @__PURE__ */ jsx(Error$1, {
|
|
13133
13152
|
title: "Rendering Error",
|
|
13134
13153
|
message
|
|
13135
13154
|
}),
|
|
13136
13155
|
children: renderProvider(/* @__PURE__ */ jsxs(Error$1.Guard, {
|
|
13137
13156
|
onError: (e) => setRuntimeError(e.message),
|
|
13138
|
-
children: [/* @__PURE__ */ jsx(Component, { ...props }), dynamicCSS && /* @__PURE__ */ jsx("style", { children: dynamicCSS })]
|
|
13157
|
+
children: [/* @__PURE__ */ jsx(Component, { ...props }), dynamicTailwind && dynamicCSS && /* @__PURE__ */ jsx("style", { children: dynamicCSS })]
|
|
13139
13158
|
}))
|
|
13140
13159
|
});
|
|
13141
13160
|
}
|