@jbpark/live-editor 1.10.0 → 1.11.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/{ast-DiVN0l7x.mjs → ast-C0FNDLFQ.mjs} +2 -2
- package/dist/{ast-DiVN0l7x.mjs.map → ast-C0FNDLFQ.mjs.map} +1 -1
- package/dist/{document-DJDRM79h.mjs → document-CBw2uF_P.mjs} +39 -2
- package/dist/{document-DJDRM79h.mjs.map → document-CBw2uF_P.mjs.map} +1 -1
- package/dist/document-DqLm4Vqi.d.mts +1522 -0
- package/dist/index.mjs +150 -52
- package/dist/index.mjs.map +1 -1
- package/dist/utils/ast/index.d.mts +2 -1513
- package/dist/utils/ast/index.mjs +3 -3
- package/dist/utils/index.d.mts +2 -1
- package/dist/utils/index.mjs +3 -3
- package/dist/{utils-D1tlgtgj.mjs → utils-BjYg1Sh8.mjs} +2 -2
- package/dist/{utils-D1tlgtgj.mjs.map → utils-BjYg1Sh8.mjs.map} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { a as detectTypeScript,
|
|
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 DEFAULT_TEMPLATE, f as require_lib$1, m as BINDING_PROP, n as createSectionPreviewCache, p as require_lib, v as DRAGGABLE_ITEMS, x as __toESM } from "./document-CBw2uF_P.mjs";
|
|
2
|
+
import { a as detectTypeScript, 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-BjYg1Sh8.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-C0FNDLFQ.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";
|
|
@@ -9,7 +9,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
import { DndContext, DragOverlay, PointerSensor, closestCenter, useDndContext, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
|
|
10
10
|
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
11
11
|
import { SortableContext, arrayMove, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
12
|
-
import { useDebouncedValue, useEventListener, useMultiSelect, useMutationObserver, useResizeObserver, useResponsiveSize } from "@jbpark/use-hooks";
|
|
12
|
+
import { useDebounce, useDebouncedValue, useEventListener, useMultiSelect, useMutationObserver, useResizeObserver, useResponsiveSize } from "@jbpark/use-hooks";
|
|
13
13
|
import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Bell, Bookmark, Calendar, Camera, Check, ChevronDown, ChevronRight, Clock, Copy, Download, Edit, Eye, Filter, Heart, Home, Image, Info, LayoutGrid, Link, Mail, Map as Map$1, Menu, MessageCircle, Phone, Plus, Search, Settings, Share, ShoppingCart, Star, Trash, Upload as Upload$1, User, X } from "lucide-react";
|
|
14
14
|
import { v4 } from "uuid";
|
|
15
15
|
import { createPortal } from "react-dom";
|
|
@@ -70,6 +70,42 @@ const ContextProvider = ({ children }) => {
|
|
|
70
70
|
});
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/components/frame/measure.ts
|
|
75
|
+
const FALLBACK_PROBE_HEIGHT = 812;
|
|
76
|
+
const computeProbeHeight = (scrollContainerClientHeight, wrapperInsets) => {
|
|
77
|
+
const usable = scrollContainerClientHeight - wrapperInsets;
|
|
78
|
+
return usable > 0 ? usable : null;
|
|
79
|
+
};
|
|
80
|
+
const isVisuallyHidden = (computed) => computed.visibility === "hidden" || computed.opacity === "0";
|
|
81
|
+
const parseTranslateY = (transform) => {
|
|
82
|
+
if (!transform || transform === "none") return 0;
|
|
83
|
+
const translateYMatch = transform.match(/translateY\(\s*([+-]?\d*\.?\d+)/);
|
|
84
|
+
if (translateYMatch?.[1]) return parseFloat(translateYMatch[1]);
|
|
85
|
+
const translateMatch = transform.match(/translate\([^,]+,\s*([+-]?\d*\.?\d+)/);
|
|
86
|
+
if (translateMatch?.[1]) return parseFloat(translateMatch[1]);
|
|
87
|
+
const matrixMatch = transform.match(/matrix\(\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*[^,]+,\s*([+-]?\d*\.?\d+)/);
|
|
88
|
+
return matrixMatch?.[1] ? parseFloat(matrixMatch[1]) : 0;
|
|
89
|
+
};
|
|
90
|
+
const estimatePositionedElementHeight = (offsetHeight, transform, probeHeight) => {
|
|
91
|
+
const offsetY = parseTranslateY(transform);
|
|
92
|
+
return Math.min(offsetY + offsetHeight, probeHeight);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/components/frame/viewport-units.ts
|
|
97
|
+
const UNIT_MAP = {
|
|
98
|
+
vh: "cqh",
|
|
99
|
+
svh: "cqh",
|
|
100
|
+
lvh: "cqh",
|
|
101
|
+
dvh: "cqh",
|
|
102
|
+
vmin: "cqmin",
|
|
103
|
+
vmax: "cqmax"
|
|
104
|
+
};
|
|
105
|
+
const UNITS_PATTERN = Object.keys(UNIT_MAP).sort((a, b) => b.length - a.length).join("|");
|
|
106
|
+
const VIEWPORT_UNIT_RE = new RegExp(`(?<![\\w.-])(-?(?:\\d+\\.?\\d*|\\.\\d+))(${UNITS_PATTERN})(?![a-zA-Z0-9_-])`, "gi");
|
|
107
|
+
const convertViewportUnits = (css) => css.replace(VIEWPORT_UNIT_RE, (_match, number, unit) => number + UNIT_MAP[unit.toLowerCase()]);
|
|
108
|
+
|
|
73
109
|
//#endregion
|
|
74
110
|
//#region src/components/frame/iframe.tsx
|
|
75
111
|
const EMPTY_STRING_ARRAY = [];
|
|
@@ -113,7 +149,7 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
113
149
|
const fragment = doc.createDocumentFragment();
|
|
114
150
|
newStyles.forEach((content) => {
|
|
115
151
|
const style = doc.createElement("style");
|
|
116
|
-
style.textContent = content;
|
|
152
|
+
style.textContent = convertViewportUnits(content);
|
|
117
153
|
fragment.appendChild(style);
|
|
118
154
|
});
|
|
119
155
|
doc.head.appendChild(fragment);
|
|
@@ -187,7 +223,8 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
187
223
|
styleEl.id = styleId;
|
|
188
224
|
doc.head.appendChild(styleEl);
|
|
189
225
|
}
|
|
190
|
-
|
|
226
|
+
const convertedCss = convertViewportUnits(css);
|
|
227
|
+
if (styleEl.textContent !== convertedCss) styleEl.textContent = convertedCss;
|
|
191
228
|
});
|
|
192
229
|
for (let index = styles.length; index < prevStyleCountRef.current; index++) doc.getElementById(`injected-style-${index}`)?.remove();
|
|
193
230
|
prevStyleCountRef.current = styles.length;
|
|
@@ -205,50 +242,74 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
205
242
|
for (let index = stylesheets.length; index < prevStylesheetCountRef.current; index++) doc.getElementById(`injected-stylesheet-${index}`)?.remove();
|
|
206
243
|
prevStylesheetCountRef.current = stylesheets.length;
|
|
207
244
|
}, [styles, stylesheets]);
|
|
245
|
+
const CONTAINER_STYLE_ID = "autoheight-container";
|
|
246
|
+
const ensureContainerStyle = (doc, probeHeight) => {
|
|
247
|
+
let styleEl = doc.getElementById(CONTAINER_STYLE_ID);
|
|
248
|
+
if (!styleEl) {
|
|
249
|
+
styleEl = doc.createElement("style");
|
|
250
|
+
styleEl.id = CONTAINER_STYLE_ID;
|
|
251
|
+
doc.head?.appendChild(styleEl);
|
|
252
|
+
}
|
|
253
|
+
styleEl.textContent = `html { container-type: size !important; height: ${probeHeight}px !important; }`;
|
|
254
|
+
};
|
|
255
|
+
const MEASUREMENT_OVERRIDE_STYLE_ID = "autoheight-measurement-overrides";
|
|
256
|
+
const withMeasurementOverrides = (doc, measure) => {
|
|
257
|
+
let styleEl = doc.getElementById(MEASUREMENT_OVERRIDE_STYLE_ID);
|
|
258
|
+
if (!styleEl) {
|
|
259
|
+
styleEl = doc.createElement("style");
|
|
260
|
+
styleEl.id = MEASUREMENT_OVERRIDE_STYLE_ID;
|
|
261
|
+
styleEl.media = "not all";
|
|
262
|
+
styleEl.textContent = [
|
|
263
|
+
"*, *::before, *::after { transition: none !important; }",
|
|
264
|
+
"html, body { scrollbar-width: none !important; }",
|
|
265
|
+
"html::-webkit-scrollbar, body::-webkit-scrollbar { display: none !important; }"
|
|
266
|
+
].join("\n");
|
|
267
|
+
doc.head?.appendChild(styleEl);
|
|
268
|
+
}
|
|
269
|
+
styleEl.media = "all";
|
|
270
|
+
measure();
|
|
271
|
+
styleEl.media = "not all";
|
|
272
|
+
};
|
|
208
273
|
const updateHeight = useCallback(() => {
|
|
209
274
|
if (!shouldAutoHeight || !mountNode || !iframeRef.current) return;
|
|
210
275
|
const iframe = iframeRef.current;
|
|
276
|
+
const doc = iframe.contentDocument;
|
|
277
|
+
const win = doc?.defaultView;
|
|
278
|
+
if (!doc || !win) return;
|
|
211
279
|
const scrollParent = iframe.closest("[data-frame-container]");
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (el.offsetHeight > 0) {
|
|
237
|
-
let offsetY = 0;
|
|
238
|
-
const transform = el.style.transform;
|
|
239
|
-
if (transform) {
|
|
240
|
-
const match = transform.match(/translate\([^,]+,\s*([+-]?\d+(?:\.\d+)?)/);
|
|
241
|
-
if (match?.[1]) offsetY = parseFloat(match[1]);
|
|
242
|
-
}
|
|
243
|
-
const estimatedHeight = offsetY + el.offsetHeight;
|
|
244
|
-
childrenHeight = Math.max(childrenHeight, estimatedHeight);
|
|
280
|
+
let probeHeight;
|
|
281
|
+
if (!scrollParent) probeHeight = FALLBACK_PROBE_HEIGHT;
|
|
282
|
+
else {
|
|
283
|
+
let wrapperInsets = 0;
|
|
284
|
+
let node = iframe.parentElement;
|
|
285
|
+
while (node && node !== scrollParent) {
|
|
286
|
+
const style = win.getComputedStyle(node);
|
|
287
|
+
wrapperInsets += parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth) + parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
|
|
288
|
+
node = node.parentElement;
|
|
289
|
+
}
|
|
290
|
+
const computed = computeProbeHeight(scrollParent.clientHeight, wrapperInsets);
|
|
291
|
+
if (computed === null) return;
|
|
292
|
+
probeHeight = computed;
|
|
293
|
+
}
|
|
294
|
+
let contentHeight = 0;
|
|
295
|
+
withMeasurementOverrides(doc, () => {
|
|
296
|
+
ensureContainerStyle(doc, probeHeight);
|
|
297
|
+
contentHeight = mountNode.scrollHeight;
|
|
298
|
+
mountNode.querySelectorAll("*").forEach((el) => {
|
|
299
|
+
const style = win.getComputedStyle(el);
|
|
300
|
+
if (isVisuallyHidden(style)) return;
|
|
301
|
+
if ((style.position === "fixed" || style.position === "absolute") && el.offsetHeight > 0) {
|
|
302
|
+
const estimatedHeight = estimatePositionedElementHeight(el.offsetHeight, style.transform, probeHeight);
|
|
303
|
+
contentHeight = Math.max(contentHeight, estimatedHeight);
|
|
245
304
|
}
|
|
246
|
-
}
|
|
305
|
+
});
|
|
247
306
|
});
|
|
248
|
-
const contentHeight = Math.max(mountNode.scrollHeight, childrenHeight);
|
|
249
307
|
if (contentHeight > 0) iframe.style.height = `${Math.ceil(contentHeight)}px`;
|
|
250
|
-
if (scrollParent) scrollParent.scrollTop = savedScrollTop;
|
|
251
308
|
}, [shouldAutoHeight, mountNode]);
|
|
309
|
+
useEffect(() => {
|
|
310
|
+
if (shouldAutoHeight) return;
|
|
311
|
+
iframeRef.current?.contentDocument?.getElementById(CONTAINER_STYLE_ID)?.remove();
|
|
312
|
+
}, [shouldAutoHeight]);
|
|
252
313
|
useEffect(() => {
|
|
253
314
|
updateHeight();
|
|
254
315
|
}, [updateHeight]);
|
|
@@ -12236,6 +12297,43 @@ const parseDateValue = (value) => {
|
|
|
12236
12297
|
const formatDateValue = (date) => {
|
|
12237
12298
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
12238
12299
|
};
|
|
12300
|
+
const COLOR_COMMIT_DELAY = 75;
|
|
12301
|
+
const ColorPickerField = ({ id, label, value, onChange }) => {
|
|
12302
|
+
const [liveValue, setLiveValue] = useState(value);
|
|
12303
|
+
const [prevValue, setPrevValue] = useState(value);
|
|
12304
|
+
const lastCommittedRef = useRef(value);
|
|
12305
|
+
if (value !== prevValue) {
|
|
12306
|
+
setPrevValue(value);
|
|
12307
|
+
setLiveValue(value);
|
|
12308
|
+
}
|
|
12309
|
+
useEffect(() => {
|
|
12310
|
+
lastCommittedRef.current = value;
|
|
12311
|
+
}, [value]);
|
|
12312
|
+
const commit = (next) => {
|
|
12313
|
+
if (next === lastCommittedRef.current) return;
|
|
12314
|
+
lastCommittedRef.current = next;
|
|
12315
|
+
onChange?.({
|
|
12316
|
+
id,
|
|
12317
|
+
label,
|
|
12318
|
+
value: next
|
|
12319
|
+
});
|
|
12320
|
+
};
|
|
12321
|
+
const debouncedCommit = useDebounce(() => commit(liveValue), {
|
|
12322
|
+
delay: COLOR_COMMIT_DELAY,
|
|
12323
|
+
autoInvoke: false
|
|
12324
|
+
});
|
|
12325
|
+
return /* @__PURE__ */ jsx(ColorPicker, {
|
|
12326
|
+
showText: true,
|
|
12327
|
+
value: liveValue,
|
|
12328
|
+
onChange: (next) => {
|
|
12329
|
+
setLiveValue(next);
|
|
12330
|
+
debouncedCommit();
|
|
12331
|
+
},
|
|
12332
|
+
onOpenChange: (open) => {
|
|
12333
|
+
if (!open) commit(liveValue);
|
|
12334
|
+
}
|
|
12335
|
+
});
|
|
12336
|
+
};
|
|
12239
12337
|
const ICON_OPTIONS = Object.entries(ICON_MAP).map(([name, Icon]) => ({
|
|
12240
12338
|
label: /* @__PURE__ */ jsxs("span", {
|
|
12241
12339
|
className: "flex items-center gap-2",
|
|
@@ -12350,16 +12448,11 @@ const Field = ({ binding, id, value, onChange }) => {
|
|
|
12350
12448
|
});
|
|
12351
12449
|
}
|
|
12352
12450
|
});
|
|
12353
|
-
if (binding.type === "color" || isColorProperty(binding.property)) return /* @__PURE__ */ jsx(
|
|
12354
|
-
|
|
12451
|
+
if (binding.type === "color" || isColorProperty(binding.property)) return /* @__PURE__ */ jsx(ColorPickerField, {
|
|
12452
|
+
id,
|
|
12453
|
+
label: binding.label,
|
|
12355
12454
|
value: normalizeToHex(stringValue),
|
|
12356
|
-
onChange
|
|
12357
|
-
if (next !== value) onChange?.({
|
|
12358
|
-
id,
|
|
12359
|
-
label: binding.label,
|
|
12360
|
-
value: next
|
|
12361
|
-
});
|
|
12362
|
-
}
|
|
12455
|
+
onChange
|
|
12363
12456
|
});
|
|
12364
12457
|
if (binding.type === "date") return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(DatePicker, {
|
|
12365
12458
|
defaultValue: parseDateValue(stringValue),
|
|
@@ -12639,7 +12732,12 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
12639
12732
|
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 10 } }));
|
|
12640
12733
|
const value = _value || DEFAULT_TEMPLATE;
|
|
12641
12734
|
const sections = useMemo(() => extractSections(value), [value]);
|
|
12642
|
-
const
|
|
12735
|
+
const [previewCache] = useState(() => createSectionPreviewCache());
|
|
12736
|
+
const previews = useMemo(() => previewCache.compute(value, sections), [
|
|
12737
|
+
previewCache,
|
|
12738
|
+
sections,
|
|
12739
|
+
value
|
|
12740
|
+
]);
|
|
12643
12741
|
const onDragStart = (_) => {};
|
|
12644
12742
|
const onDragOver = (_e) => {};
|
|
12645
12743
|
const onDragEnd = (event) => {
|