UNPKG

@measured/puck

Version:

The open-source visual editor for React

1,598 lines (1,541 loc) • 312 kB
import { SlotRender, SlotRenderPure, __async, __commonJS, __objRest, __spreadProps, __spreadValues, __toESM, defaultAppState, defaultSlots, defaultViewports, expandNode, getChanged, getSlotTransform, init_react_import, resolveComponentData, rootAreaId, rootDroppableId, rootZone, setupZone, useFieldTransforms, useSlots, walkAppState, walkField, walkTree } from "./chunk-62KOMFGG.mjs"; // ../../node_modules/classnames/index.js var require_classnames = __commonJS({ "../../node_modules/classnames/index.js"(exports, module) { "use strict"; init_react_import(); (function() { "use strict"; var hasOwn = {}.hasOwnProperty; function classNames() { var classes = ""; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (arg) { classes = appendClass(classes, parseValue(arg)); } } return classes; } function parseValue(arg) { if (typeof arg === "string" || typeof arg === "number") { return arg; } if (typeof arg !== "object") { return ""; } if (Array.isArray(arg)) { return classNames.apply(null, arg); } if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) { return arg.toString(); } var classes = ""; for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes = appendClass(classes, key); } } return classes; } function appendClass(value, newClass) { if (!newClass) { return value; } if (value) { return value + " " + newClass; } return value + newClass; } if (typeof module !== "undefined" && module.exports) { classNames.default = classNames; module.exports = classNames; } else if (typeof define === "function" && typeof define.amd === "object" && define.amd) { define("classnames", [], function() { return classNames; }); } else { window.classNames = classNames; } })(); } }); // types/API/Overrides.ts init_react_import(); var overrideKeys = [ "header", "headerActions", "fields", "fieldLabel", "drawer", "drawerItem", "componentOverlay", "outline", "puck", "preview" ]; // components/ActionBar/index.tsx init_react_import(); // lib/get-class-name-factory.ts init_react_import(); var import_classnames = __toESM(require_classnames()); var getClassNameFactory = (rootClass, styles2, config = { baseClass: "" }) => (options = {}) => { if (typeof options === "string") { const descendant = options; const style = styles2[`${rootClass}-${descendant}`]; if (style) { return config.baseClass + styles2[`${rootClass}-${descendant}`] || ""; } return ""; } else if (typeof options === "object") { const modifiers = options; const prefixedModifiers = {}; for (let modifier in modifiers) { prefixedModifiers[styles2[`${rootClass}--${modifier}`]] = modifiers[modifier]; } const c = styles2[rootClass]; return config.baseClass + (0, import_classnames.default)(__spreadValues({ [c]: !!c }, prefixedModifiers)); } else { return config.baseClass + styles2[rootClass] || ""; } }; var get_class_name_factory_default = getClassNameFactory; // css-module:/home/runner/work/puck/puck/packages/core/components/ActionBar/styles.module.css#css-module init_react_import(); var styles_module_default = { "ActionBar": "_ActionBar_rvadt_1", "ActionBar-label": "_ActionBar-label_rvadt_18", "ActionBar-action": "_ActionBar-action_rvadt_30", "ActionBar-group": "_ActionBar-group_rvadt_38" }; // components/ActionBar/index.tsx import { jsx, jsxs } from "react/jsx-runtime"; var getClassName = get_class_name_factory_default("ActionBar", styles_module_default); var ActionBar = ({ label, children }) => /* @__PURE__ */ jsxs( "div", { className: getClassName(), onClick: (e) => { e.stopPropagation(); }, children: [ label && /* @__PURE__ */ jsx(ActionBar.Group, { children: /* @__PURE__ */ jsx("div", { className: getClassName("label"), children: label }) }), children ] } ); var Action = ({ children, label, onClick }) => /* @__PURE__ */ jsx( "button", { type: "button", className: getClassName("action"), onClick, title: label, children } ); var Group = ({ children }) => /* @__PURE__ */ jsx("div", { className: getClassName("group"), children }); var Label = ({ label }) => /* @__PURE__ */ jsx("div", { className: getClassName("label"), children: label }); ActionBar.Action = Action; ActionBar.Label = Label; ActionBar.Group = Group; // components/IconButton/IconButton.tsx init_react_import(); import { useState } from "react"; // css-module:/home/runner/work/puck/puck/packages/core/components/IconButton/IconButton.module.css#css-module init_react_import(); var IconButton_module_default = { "IconButton": "_IconButton_swpni_1", "IconButton--disabled": "_IconButton--disabled_swpni_20", "IconButton-title": "_IconButton-title_swpni_33" }; // components/Loader/index.tsx init_react_import(); // lib/index.ts init_react_import(); // lib/filter.ts init_react_import(); // lib/data/reorder.ts init_react_import(); var reorder = (list, startIndex, endIndex) => { const result = Array.from(list); const [removed] = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); return result; }; // lib/data/replace.ts init_react_import(); var replace = (list, index, newItem) => { const result = Array.from(list); result.splice(index, 1); result.splice(index, 0, newItem); return result; }; // lib/use-reset-auto-zoom.ts init_react_import(); // store/index.ts init_react_import(); // reducer/index.ts init_react_import(); // reducer/actions/set.ts init_react_import(); var setAction = (state, action, appStore) => { if (typeof action.state === "object") { const newState = __spreadValues(__spreadValues({}, state), action.state); if (action.state.indexes) { return newState; } console.warn( "`set` is expensive and may cause unnecessary re-renders. Consider using a more atomic action instead." ); return walkAppState(newState, appStore.config); } return __spreadValues(__spreadValues({}, state), action.state(state)); }; // reducer/actions/insert.ts init_react_import(); // lib/data/insert.ts init_react_import(); var insert = (list, index, item) => { const result = Array.from(list || []); result.splice(index, 0, item); return result; }; // lib/generate-id.ts init_react_import(); import { v4 as uuidv4 } from "uuid"; var generateId = (type) => type ? `${type}-${uuidv4()}` : uuidv4(); // lib/data/get-ids-for-parent.ts init_react_import(); var getIdsForParent = (zoneCompound, state) => { const [parentId] = zoneCompound.split(":"); const node = state.indexes.nodes[parentId]; return ((node == null ? void 0 : node.path) || []).map((p) => p.split(":")[0]); }; // lib/data/populate-ids.ts init_react_import(); var populateIds = (data, config, override = false) => { const id = generateId(data.type); return walkTree( __spreadProps(__spreadValues({}, data), { props: override ? __spreadProps(__spreadValues({}, data.props), { id }) : __spreadValues({}, data.props) }), config, (contents) => contents.map((item) => { const id2 = generateId(item.type); return __spreadProps(__spreadValues({}, item), { props: override ? __spreadProps(__spreadValues({}, item.props), { id: id2 }) : __spreadValues({ id: id2 }, item.props) }); }) ); }; // reducer/actions/insert.ts function insertAction(state, action, appStore) { const id = action.id || generateId(action.componentType); const emptyComponentData = populateIds( { type: action.componentType, props: __spreadProps(__spreadValues({}, appStore.config.components[action.componentType].defaultProps || {}), { id }) }, appStore.config ); const [parentId] = action.destinationZone.split(":"); const idsInPath = getIdsForParent(action.destinationZone, state); return walkAppState( state, appStore.config, (content, zoneCompound) => { if (zoneCompound === action.destinationZone) { return insert( content || [], action.destinationIndex, emptyComponentData ); } return content; }, (childItem, path) => { if (childItem.props.id === id || childItem.props.id === parentId) { return childItem; } else if (idsInPath.includes(childItem.props.id)) { return childItem; } else if (path.includes(action.destinationZone)) { return childItem; } return null; } ); } // reducer/actions/replace.ts init_react_import(); var replaceAction = (state, action, appStore) => { const [parentId] = action.destinationZone.split(":"); const idsInPath = getIdsForParent(action.destinationZone, state); const originalId = state.indexes.zones[action.destinationZone].contentIds[action.destinationIndex]; const idChanged = originalId !== action.data.props.id; if (idChanged) { throw new Error( `Can't change the id during a replace action. Please us "remove" and "insert" to define a new node.` ); } const newSlotIds = []; const data = walkTree(action.data, appStore.config, (contents, opts) => { newSlotIds.push(`${opts.parentId}:${opts.propName}`); return contents.map((item) => { const id = generateId(item.type); return __spreadProps(__spreadValues({}, item), { props: __spreadValues({ id }, item.props) }); }); }); const stateWithDeepSlotsRemoved = __spreadValues({}, state); Object.keys(state.indexes.zones).forEach((zoneCompound) => { const id = zoneCompound.split(":")[0]; if (id === originalId) { if (!newSlotIds.includes(zoneCompound)) { delete stateWithDeepSlotsRemoved.indexes.zones[zoneCompound]; } } }); return walkAppState( stateWithDeepSlotsRemoved, appStore.config, (content, zoneCompound) => { const newContent = [...content]; if (zoneCompound === action.destinationZone) { newContent[action.destinationIndex] = data; } return newContent; }, (childItem, path) => { const pathIds = path.map((p) => p.split(":")[0]); if (childItem.props.id === data.props.id) { return data; } else if (childItem.props.id === parentId) { return childItem; } else if (idsInPath.indexOf(childItem.props.id) > -1) { return childItem; } else if (pathIds.indexOf(data.props.id) > -1) { return childItem; } return null; } ); }; // reducer/actions/replace-root.ts init_react_import(); var replaceRootAction = (state, action, appStore) => { return walkAppState( state, appStore.config, (content) => content, (childItem) => { if (childItem.props.id === "root") { return __spreadProps(__spreadValues({}, childItem), { props: __spreadValues(__spreadValues({}, childItem.props), action.root.props), readOnly: action.root.readOnly }); } return childItem; } ); }; // reducer/actions/duplicate.ts init_react_import(); // lib/data/get-item.ts init_react_import(); function getItem(selector, state) { var _a, _b; const zone = (_a = state.indexes.zones) == null ? void 0 : _a[selector.zone || rootDroppableId]; return zone ? (_b = state.indexes.nodes[zone.contentIds[selector.index]]) == null ? void 0 : _b.data : void 0; } // reducer/actions/duplicate.ts function duplicateAction(state, action, appStore) { const item = getItem( { index: action.sourceIndex, zone: action.sourceZone }, state ); const idsInPath = getIdsForParent(action.sourceZone, state); const newItem = __spreadProps(__spreadValues({}, item), { props: __spreadProps(__spreadValues({}, item.props), { id: generateId(item.type) }) }); const modified = walkAppState( state, appStore.config, (content, zoneCompound) => { if (zoneCompound === action.sourceZone) { return insert(content, action.sourceIndex + 1, item); } return content; }, (childItem, path, index) => { const zoneCompound = path[path.length - 1]; const parents = path.map((p) => p.split(":")[0]); if (parents.indexOf(newItem.props.id) > -1) { return __spreadProps(__spreadValues({}, childItem), { props: __spreadProps(__spreadValues({}, childItem.props), { id: generateId(childItem.type) }) }); } if (zoneCompound === action.sourceZone && index === action.sourceIndex + 1) { return newItem; } const [sourceZoneParent] = action.sourceZone.split(":"); if (sourceZoneParent === childItem.props.id || idsInPath.indexOf(childItem.props.id) > -1) { return childItem; } return null; } ); return __spreadProps(__spreadValues({}, modified), { ui: __spreadProps(__spreadValues({}, modified.ui), { itemSelector: { index: action.sourceIndex + 1, zone: action.sourceZone } }) }); } // reducer/actions/reorder.ts init_react_import(); // reducer/actions/move.ts init_react_import(); // lib/data/remove.ts init_react_import(); var remove = (list, index) => { const result = Array.from(list); result.splice(index, 1); return result; }; // reducer/actions/move.ts var moveAction = (state, action, appStore) => { if (action.sourceZone === action.destinationZone && action.sourceIndex === action.destinationIndex) { return state; } const item = getItem( { zone: action.sourceZone, index: action.sourceIndex }, state ); if (!item) return state; const idsInSourcePath = getIdsForParent(action.sourceZone, state); const idsInDestinationPath = getIdsForParent(action.destinationZone, state); return walkAppState( state, appStore.config, (content, zoneCompound) => { if (zoneCompound === action.sourceZone && zoneCompound === action.destinationZone) { return insert( remove(content, action.sourceIndex), action.destinationIndex, item ); } else if (zoneCompound === action.sourceZone) { return remove(content, action.sourceIndex); } else if (zoneCompound === action.destinationZone) { return insert(content, action.destinationIndex, item); } return content; }, (childItem, path) => { const [sourceZoneParent] = action.sourceZone.split(":"); const [destinationZoneParent] = action.destinationZone.split(":"); const childId = childItem.props.id; if (sourceZoneParent === childId || destinationZoneParent === childId || item.props.id === childId || idsInSourcePath.indexOf(childId) > -1 || idsInDestinationPath.indexOf(childId) > -1 || path.includes(action.destinationZone)) { return childItem; } return null; } ); }; // reducer/actions/reorder.ts var reorderAction = (state, action, appStore) => { return moveAction( state, { type: "move", sourceIndex: action.sourceIndex, sourceZone: action.destinationZone, destinationIndex: action.destinationIndex, destinationZone: action.destinationZone }, appStore ); }; // reducer/actions/remove.ts init_react_import(); var removeAction = (state, action, appStore) => { const item = getItem({ index: action.index, zone: action.zone }, state); const nodesToDelete = Object.entries(state.indexes.nodes).reduce( (acc, [nodeId, nodeData]) => { const pathIds = nodeData.path.map((p) => p.split(":")[0]); if (pathIds.includes(item.props.id)) { return [...acc, nodeId]; } return acc; }, [item.props.id] ); const newState = walkAppState( state, appStore.config, (content, zoneCompound) => { if (zoneCompound === action.zone) { return remove(content, action.index); } return content; } ); Object.keys(newState.data.zones || {}).forEach((zoneCompound) => { const parentId = zoneCompound.split(":")[0]; if (nodesToDelete.includes(parentId) && newState.data.zones) { delete newState.data.zones[zoneCompound]; } }); Object.keys(newState.indexes.zones).forEach((zoneCompound) => { const parentId = zoneCompound.split(":")[0]; if (nodesToDelete.includes(parentId)) { delete newState.indexes.zones[zoneCompound]; } }); nodesToDelete.forEach((id) => { delete newState.indexes.nodes[id]; }); return newState; }; // reducer/actions/register-zone.ts init_react_import(); var zoneCache = {}; function registerZoneAction(state, action) { if (zoneCache[action.zone]) { return __spreadProps(__spreadValues({}, state), { data: __spreadProps(__spreadValues({}, state.data), { zones: __spreadProps(__spreadValues({}, state.data.zones), { [action.zone]: zoneCache[action.zone] }) }), indexes: __spreadProps(__spreadValues({}, state.indexes), { zones: __spreadProps(__spreadValues({}, state.indexes.zones), { [action.zone]: __spreadProps(__spreadValues({}, state.indexes.zones[action.zone]), { contentIds: zoneCache[action.zone].map((item) => item.props.id), type: "dropzone" }) }) }) }); } return __spreadProps(__spreadValues({}, state), { data: setupZone(state.data, action.zone) }); } function unregisterZoneAction(state, action) { const _zones = __spreadValues({}, state.data.zones || {}); const zoneIndex = __spreadValues({}, state.indexes.zones || {}); if (_zones[action.zone]) { zoneCache[action.zone] = _zones[action.zone]; delete _zones[action.zone]; } delete zoneIndex[action.zone]; return __spreadProps(__spreadValues({}, state), { data: __spreadProps(__spreadValues({}, state.data), { zones: _zones }), indexes: __spreadProps(__spreadValues({}, state.indexes), { zones: zoneIndex }) }); } // reducer/actions/set-data.ts init_react_import(); var setDataAction = (state, action, appStore) => { if (typeof action.data === "object") { console.warn( "`setData` is expensive and may cause unnecessary re-renders. Consider using a more atomic action instead." ); return walkAppState( __spreadProps(__spreadValues({}, state), { data: __spreadValues(__spreadValues({}, state.data), action.data) }), appStore.config ); } return walkAppState( __spreadProps(__spreadValues({}, state), { data: __spreadValues(__spreadValues({}, state.data), action.data(state.data)) }), appStore.config ); }; // reducer/actions/set-ui.ts init_react_import(); var setUiAction = (state, action) => { if (typeof action.ui === "object") { return __spreadProps(__spreadValues({}, state), { ui: __spreadValues(__spreadValues({}, state.ui), action.ui) }); } return __spreadProps(__spreadValues({}, state), { ui: __spreadValues(__spreadValues({}, state.ui), action.ui(state.ui)) }); }; // lib/data/make-state-public.ts init_react_import(); var makeStatePublic = (state) => { const { data, ui } = state; return { data, ui }; }; // reducer/actions.tsx init_react_import(); // reducer/index.ts function storeInterceptor(reducer, record, onAction) { return (state, action) => { const newAppState = reducer(state, action); const isValidType = ![ "registerZone", "unregisterZone", "setData", "setUi", "set" ].includes(action.type); if (typeof action.recordHistory !== "undefined" ? action.recordHistory : isValidType) { if (record) record(newAppState); } onAction == null ? void 0 : onAction(action, makeStatePublic(newAppState), makeStatePublic(state)); return newAppState; }; } function createReducer({ record, onAction, appStore }) { return storeInterceptor( (state, action) => { if (action.type === "set") { return setAction(state, action, appStore); } if (action.type === "insert") { return insertAction(state, action, appStore); } if (action.type === "replace") { return replaceAction(state, action, appStore); } if (action.type === "replaceRoot") { return replaceRootAction(state, action, appStore); } if (action.type === "duplicate") { return duplicateAction(state, action, appStore); } if (action.type === "reorder") { return reorderAction(state, action, appStore); } if (action.type === "move") { return moveAction(state, action, appStore); } if (action.type === "remove") { return removeAction(state, action, appStore); } if (action.type === "registerZone") { return registerZoneAction(state, action); } if (action.type === "unregisterZone") { return unregisterZoneAction(state, action); } if (action.type === "setData") { return setDataAction(state, action, appStore); } if (action.type === "setUi") { return setUiAction(state, action); } return state; }, record, onAction ); } // store/index.ts import { create as create2, useStore } from "zustand"; import { subscribeWithSelector as subscribeWithSelector2 } from "zustand/middleware"; import { createContext, useContext } from "react"; // store/slices/history.ts init_react_import(); import { useEffect as useEffect2 } from "react"; // lib/use-hotkey.ts init_react_import(); import { useEffect } from "react"; import { create } from "zustand"; import { subscribeWithSelector } from "zustand/middleware"; var keyCodeMap = { ControlLeft: "ctrl", ControlRight: "ctrl", MetaLeft: "meta", MetaRight: "meta", ShiftLeft: "shift", ShiftRight: "shift", KeyA: "a", KeyB: "b", KeyC: "c", KeyD: "d", KeyE: "e", KeyF: "f", KeyG: "g", KeyH: "h", KeyI: "i", KeyJ: "j", KeyK: "k", KeyL: "l", KeyM: "m", KeyN: "n", KeyO: "o", KeyP: "p", KeyQ: "q", KeyR: "r", KeyS: "s", KeyT: "t", KeyU: "u", KeyV: "v", KeyW: "w", KeyX: "x", KeyY: "y", KeyZ: "z" }; var useHotkeyStore = create()( subscribeWithSelector((set) => ({ held: {}, hold: (key) => set((s) => s.held[key] ? s : { held: __spreadProps(__spreadValues({}, s.held), { [key]: true }) }), release: (key) => set((s) => s.held[key] ? { held: __spreadProps(__spreadValues({}, s.held), { [key]: false }) } : s), reset: (held = {}) => set(() => ({ held })), triggers: {} })) ); var monitorHotkeys = (doc) => { const onKeyDown = (e) => { const key = keyCodeMap[e.code]; if (key) { useHotkeyStore.getState().hold(key); const { held, triggers } = useHotkeyStore.getState(); Object.values(triggers).forEach(({ combo, cb }) => { const conditionMet = Object.entries(combo).every( ([key2, value]) => value === !!held[key2] ) && Object.entries(held).every( ([key2, value]) => value === !!combo[key2] ); if (conditionMet) { e.preventDefault(); cb(); } }); if (key !== "meta" && key !== "ctrl" && key !== "shift") { useHotkeyStore.getState().release(key); } } }; const onKeyUp = (e) => { const key = keyCodeMap[e.code]; if (key) { if (key === "meta") { useHotkeyStore.getState().reset(); } else { useHotkeyStore.getState().release(key); } } }; const onVisibilityChanged = (e) => { if (document.visibilityState === "hidden") { useHotkeyStore.getState().reset(); } }; doc.addEventListener("keydown", onKeyDown); doc.addEventListener("keyup", onKeyUp); doc.addEventListener("visibilitychange", onVisibilityChanged); return () => { doc.removeEventListener("keydown", onKeyDown); doc.removeEventListener("keyup", onKeyUp); doc.removeEventListener("visibilitychange", onVisibilityChanged); }; }; var useMonitorHotkeys = () => { useEffect(() => monitorHotkeys(document), []); }; var useHotkey = (combo, cb) => { useEffect( () => useHotkeyStore.setState((s) => ({ triggers: __spreadProps(__spreadValues({}, s.triggers), { [`${Object.keys(combo).join("+")}`]: { combo, cb } }) })), [] ); }; // store/slices/history.ts var EMPTY_HISTORY_INDEX = 0; function debounce(func, timeout3 = 300) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func(...args); }, timeout3); }; } var tidyState = (state) => { return __spreadProps(__spreadValues({}, state), { ui: __spreadProps(__spreadValues({}, state.ui), { field: { focus: null } }) }); }; var createHistorySlice = (set, get) => { const record = debounce((state) => { const { histories, index } = get().history; const history = { state, id: generateId("history") }; const newHistories = [...histories.slice(0, index + 1), history]; set({ history: __spreadProps(__spreadValues({}, get().history), { histories: newHistories, index: newHistories.length - 1 }) }); }, 250); return { initialAppState: {}, index: EMPTY_HISTORY_INDEX, histories: [], hasPast: () => get().history.index > EMPTY_HISTORY_INDEX, hasFuture: () => get().history.index < get().history.histories.length - 1, prevHistory: () => { const { history } = get(); return history.hasPast() ? history.histories[history.index - 1] : null; }, nextHistory: () => { const s = get().history; return s.hasFuture() ? s.histories[s.index + 1] : null; }, currentHistory: () => get().history.histories[get().history.index], back: () => { var _a; const { history, dispatch } = get(); if (history.hasPast()) { const state = tidyState( ((_a = history.prevHistory()) == null ? void 0 : _a.state) || history.initialAppState ); dispatch({ type: "set", state }); set({ history: __spreadProps(__spreadValues({}, history), { index: history.index - 1 }) }); } }, forward: () => { var _a; const { history, dispatch } = get(); if (history.hasFuture()) { const state = (_a = history.nextHistory()) == null ? void 0 : _a.state; dispatch({ type: "set", state: state ? tidyState(state) : {} }); set({ history: __spreadProps(__spreadValues({}, history), { index: history.index + 1 }) }); } }, setHistories: (histories) => { var _a; const { dispatch, history } = get(); dispatch({ type: "set", state: ((_a = histories[histories.length - 1]) == null ? void 0 : _a.state) || history.initialAppState }); set({ history: __spreadProps(__spreadValues({}, history), { histories, index: histories.length - 1 }) }); }, setHistoryIndex: (index) => { var _a; const { dispatch, history } = get(); dispatch({ type: "set", state: ((_a = history.histories[index]) == null ? void 0 : _a.state) || history.initialAppState }); set({ history: __spreadProps(__spreadValues({}, history), { index }) }); }, record }; }; function useRegisterHistorySlice(appStore, { histories, index, initialAppState }) { useEffect2( () => appStore.setState({ history: __spreadProps(__spreadValues({}, appStore.getState().history), { histories, index, initialAppState }) }), [histories, index, initialAppState] ); const back = () => { appStore.getState().history.back(); }; const forward = () => { appStore.getState().history.forward(); }; useHotkey({ meta: true, z: true }, back); useHotkey({ meta: true, shift: true, z: true }, forward); useHotkey({ meta: true, y: true }, forward); useHotkey({ ctrl: true, z: true }, back); useHotkey({ ctrl: true, shift: true, z: true }, forward); useHotkey({ ctrl: true, y: true }, forward); } // store/slices/nodes.ts init_react_import(); var createNodesSlice = (set, get) => ({ nodes: {}, registerNode: (id, node) => { const s = get().nodes; const emptyNode = { id, methods: { sync: () => null, hideOverlay: () => null, showOverlay: () => null }, element: null }; const existingNode = s.nodes[id]; set({ nodes: __spreadProps(__spreadValues({}, s), { nodes: __spreadProps(__spreadValues({}, s.nodes), { [id]: __spreadProps(__spreadValues(__spreadValues(__spreadValues({}, emptyNode), existingNode), node), { id }) }) }) }); }, unregisterNode: (id) => { const s = get().nodes; const existingNode = s.nodes[id]; if (existingNode) { const newNodes = __spreadValues({}, s.nodes); delete newNodes[id]; set({ nodes: __spreadProps(__spreadValues({}, s), { nodes: newNodes }) }); } } }); // store/slices/permissions.ts init_react_import(); import { useEffect as useEffect3 } from "react"; // lib/data/flatten-data.ts init_react_import(); var flattenData = (state, config) => { const data = []; walkAppState( state, config, (content) => content, (item) => { data.push(item); return null; } ); return data; }; // store/slices/permissions.ts var createPermissionsSlice = (set, get) => { const resolvePermissions = (..._0) => __async(void 0, [..._0], function* (params = {}, force) { const { state, permissions, config } = get(); const { cache, globalPermissions } = permissions; const resolveDataForItem = (item2, force2 = false) => __async(void 0, null, function* () { var _a, _b, _c; const { config: config2, state: appState, setComponentLoading } = get(); const componentConfig = item2.type === "root" ? config2.root : config2.components[item2.type]; if (!componentConfig) { return; } const initialPermissions = __spreadValues(__spreadValues({}, globalPermissions), componentConfig.permissions); if (componentConfig.resolvePermissions) { const changed = getChanged(item2, (_a = cache[item2.props.id]) == null ? void 0 : _a.lastData); if (Object.values(changed).some((el) => el === true) || force2) { const clearTimeout2 = setComponentLoading(item2.props.id, true, 50); const resolvedPermissions = yield componentConfig.resolvePermissions( item2, { changed, lastPermissions: ((_b = cache[item2.props.id]) == null ? void 0 : _b.lastPermissions) || null, permissions: initialPermissions, appState: makeStatePublic(appState), lastData: ((_c = cache[item2.props.id]) == null ? void 0 : _c.lastData) || null } ); const latest = get().permissions; set({ permissions: __spreadProps(__spreadValues({}, latest), { cache: __spreadProps(__spreadValues({}, latest.cache), { [item2.props.id]: { lastData: item2, lastPermissions: resolvedPermissions } }), resolvedPermissions: __spreadProps(__spreadValues({}, latest.resolvedPermissions), { [item2.props.id]: resolvedPermissions }) }) }); clearTimeout2(); } } }); const resolveDataForRoot = (force2 = false) => { const { state: appState } = get(); resolveDataForItem( // Shim the root data in by conforming to component data shape { type: "root", props: __spreadProps(__spreadValues({}, appState.data.root.props), { id: "root" }) }, force2 ); }; const { item, type, root } = params; if (item) { yield resolveDataForItem(item, force); } else if (type) { flattenData(state, config).filter((item2) => item2.type === type).map((item2) => __async(void 0, null, function* () { yield resolveDataForItem(item2, force); })); } else if (root) { resolveDataForRoot(force); } else { flattenData(state, config).map((item2) => __async(void 0, null, function* () { yield resolveDataForItem(item2, force); })); } }); const refreshPermissions = (params) => resolvePermissions(params, true); return { cache: {}, globalPermissions: { drag: true, edit: true, delete: true, duplicate: true, insert: true }, resolvedPermissions: {}, getPermissions: ({ item, type, root } = {}) => { const { config, permissions } = get(); const { globalPermissions, resolvedPermissions } = permissions; if (item) { const componentConfig = config.components[item.type]; const initialPermissions = __spreadValues(__spreadValues({}, globalPermissions), componentConfig == null ? void 0 : componentConfig.permissions); const resolvedForItem = resolvedPermissions[item.props.id]; return resolvedForItem ? __spreadValues(__spreadValues({}, globalPermissions), resolvedForItem) : initialPermissions; } else if (type) { const componentConfig = config.components[type]; return __spreadValues(__spreadValues({}, globalPermissions), componentConfig == null ? void 0 : componentConfig.permissions); } else if (root) { const rootConfig = config.root; const initialPermissions = __spreadValues(__spreadValues({}, globalPermissions), rootConfig == null ? void 0 : rootConfig.permissions); const resolvedForItem = resolvedPermissions["root"]; return resolvedForItem ? __spreadValues(__spreadValues({}, globalPermissions), resolvedForItem) : initialPermissions; } return globalPermissions; }, resolvePermissions, refreshPermissions }; }; var useRegisterPermissionsSlice = (appStore, globalPermissions) => { useEffect3(() => { const { permissions } = appStore.getState(); const { globalPermissions: existingGlobalPermissions } = permissions; appStore.setState({ permissions: __spreadProps(__spreadValues({}, permissions), { globalPermissions: __spreadValues(__spreadValues({}, existingGlobalPermissions), globalPermissions) }) }); permissions.resolvePermissions(); }, [globalPermissions]); useEffect3(() => { return appStore.subscribe( (s) => s.state.data, () => { appStore.getState().permissions.resolvePermissions(); } ); }, []); useEffect3(() => { return appStore.subscribe( (s) => s.config, () => { appStore.getState().permissions.resolvePermissions(); } ); }, []); }; // store/slices/fields.ts init_react_import(); import { useCallback, useEffect as useEffect4 } from "react"; var createFieldsSlice = (_set, _get) => { return { fields: {}, loading: false, lastResolvedData: {}, id: void 0 }; }; var useRegisterFieldsSlice = (appStore, id) => { const resolveFields = useCallback( (reset) => __async(void 0, null, function* () { var _a, _b; const { fields, lastResolvedData } = appStore.getState().fields; const nodes = appStore.getState().state.indexes.nodes; const node = nodes[id || "root"]; const componentData = node == null ? void 0 : node.data; const parentNode = (node == null ? void 0 : node.parentId) ? nodes[node.parentId] : null; const parent = (parentNode == null ? void 0 : parentNode.data) || null; const { getComponentConfig, state } = appStore.getState(); const componentConfig = getComponentConfig(componentData == null ? void 0 : componentData.type); if (!componentData || !componentConfig) return; const defaultFields2 = componentConfig.fields || {}; const resolver = componentConfig.resolveFields; let lastFields = fields; if (reset) { appStore.setState((s) => ({ fields: __spreadProps(__spreadValues({}, s.fields), { fields: defaultFields2, id }) })); lastFields = defaultFields2; } if (resolver) { const timeout3 = setTimeout(() => { appStore.setState((s) => ({ fields: __spreadProps(__spreadValues({}, s.fields), { loading: true }) })); }, 50); const lastData = ((_a = lastResolvedData.props) == null ? void 0 : _a.id) === id ? lastResolvedData : null; const changed = getChanged(componentData, lastData); const newFields = yield resolver(componentData, { changed, fields: defaultFields2, lastFields, lastData, appState: makeStatePublic(state), parent }); clearTimeout(timeout3); if (((_b = appStore.getState().selectedItem) == null ? void 0 : _b.props.id) !== id) { return; } appStore.setState({ fields: { fields: newFields, loading: false, lastResolvedData: componentData, id } }); } else { appStore.setState((s) => ({ fields: __spreadProps(__spreadValues({}, s.fields), { fields: defaultFields2, id }) })); } }), [id] ); useEffect4(() => { resolveFields(true); return appStore.subscribe( (s) => s.state.indexes.nodes[id || "root"], () => resolveFields() ); }, [id]); }; // lib/data/to-root.ts init_react_import(); var toRoot = (item) => { if ("type" in item && item.type !== "root") { throw new Error("Converting non-root item to root."); } const { readOnly } = item; if (item.props) { if ("id" in item.props) { const _a = item.props, { id } = _a, props = __objRest(_a, ["id"]); return { props, readOnly }; } return { props: item.props, readOnly }; } return { props: {}, readOnly }; }; // store/index.ts var defaultPageFields = { title: { type: "text" } }; var createAppStore = (initialAppStore) => create2()( subscribeWithSelector2((set, get) => { var _a, _b; return __spreadProps(__spreadValues({ state: defaultAppState, config: { components: {} }, componentState: {}, plugins: [], overrides: {}, viewports: defaultViewports, zoomConfig: { autoZoom: 1, rootHeight: 0, zoom: 1 }, status: "LOADING", iframe: {}, metadata: {}, fieldTransforms: {} }, initialAppStore), { fields: createFieldsSlice(set, get), history: createHistorySlice(set, get), nodes: createNodesSlice(set, get), permissions: createPermissionsSlice(set, get), getComponentConfig: (type) => { var _a2; const { config, selectedItem } = get(); const rootFields = ((_a2 = config.root) == null ? void 0 : _a2.fields) || defaultPageFields; return type && type !== "root" ? config.components[type] : selectedItem ? config.components[selectedItem.type] : __spreadProps(__spreadValues({}, config.root), { fields: rootFields }); }, selectedItem: ((_a = initialAppStore == null ? void 0 : initialAppStore.state) == null ? void 0 : _a.ui.itemSelector) ? getItem( (_b = initialAppStore == null ? void 0 : initialAppStore.state) == null ? void 0 : _b.ui.itemSelector, initialAppStore.state ) : null, dispatch: (action) => set((s) => { var _a2, _b2; const { record } = get().history; const dispatch = createReducer({ record, appStore: s }); const state = dispatch(s.state, action); const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state) : null; (_b2 = (_a2 = get()).onAction) == null ? void 0 : _b2.call(_a2, action, state, get().state); return __spreadProps(__spreadValues({}, s), { state, selectedItem }); }), setZoomConfig: (zoomConfig) => set({ zoomConfig }), setStatus: (status) => set({ status }), setComponentState: (componentState) => set({ componentState }), pendingLoadTimeouts: {}, setComponentLoading: (id, loading = true, defer2 = 0) => { const { setComponentState, pendingLoadTimeouts } = get(); const loadId = generateId(); const setLoading = () => { var _a2; const { componentState } = get(); setComponentState(__spreadProps(__spreadValues({}, componentState), { [id]: __spreadProps(__spreadValues({}, componentState[id]), { loadingCount: (((_a2 = componentState[id]) == null ? void 0 : _a2.loadingCount) || 0) + 1 }) })); }; const unsetLoading = () => { var _a2; const { componentState } = get(); clearTimeout(timeout3); delete pendingLoadTimeouts[loadId]; set({ pendingLoadTimeouts }); setComponentState(__spreadProps(__spreadValues({}, componentState), { [id]: __spreadProps(__spreadValues({}, componentState[id]), { loadingCount: Math.max( (((_a2 = componentState[id]) == null ? void 0 : _a2.loadingCount) || 0) - 1, 0 ) }) })); }; const timeout3 = setTimeout(() => { if (loading) { setLoading(); } else { unsetLoading(); } delete pendingLoadTimeouts[loadId]; set({ pendingLoadTimeouts }); }, defer2); set({ pendingLoadTimeouts: __spreadProps(__spreadValues({}, pendingLoadTimeouts), { [id]: timeout3 }) }); return unsetLoading; }, unsetComponentLoading: (id) => { const { setComponentLoading } = get(); setComponentLoading(id, false); }, // Helper setUi: (ui, recordHistory) => set((s) => { const dispatch = createReducer({ record: () => { }, appStore: s }); const state = dispatch(s.state, { type: "setUi", ui, recordHistory }); const selectedItem = state.ui.itemSelector ? getItem(state.ui.itemSelector, state) : null; return __spreadProps(__spreadValues({}, s), { state, selectedItem }); }), resolveComponentData: (componentData, trigger) => __async(void 0, null, function* () { const { config, metadata, setComponentLoading, permissions } = get(); const timeouts = {}; return yield resolveComponentData( componentData, config, metadata, (item) => { const id = "id" in item.props ? item.props.id : "root"; timeouts[id] = setComponentLoading(id, true, 50); }, (item) => __async(void 0, null, function* () { const id = "id" in item.props ? item.props.id : "root"; if ("type" in item) { yield permissions.refreshPermissions({ item }); } else { yield permissions.refreshPermissions({ root: true }); } timeouts[id](); }), trigger ); }), resolveAndCommitData: () => __async(void 0, null, function* () { const { config, state, dispatch, resolveComponentData: resolveComponentData2 } = get(); walkAppState( state, config, (content) => content, (childItem) => { resolveComponentData2(childItem, "load").then((resolved) => { const { state: state2 } = get(); const node = state2.indexes.nodes[resolved.node.props.id]; if (node && resolved.didChange) { if (resolved.node.props.id === "root") { dispatch({ type: "replaceRoot", root: toRoot(resolved.node) }); } else { const zoneCompound = `${node.parentId}:${node.zone}`; const parentZone = state2.indexes.zones[zoneCompound]; const index = parentZone.contentIds.indexOf( resolved.node.props.id ); dispatch({ type: "replace", data: resolved.node, destinationIndex: index, destinationZone: zoneCompound }); } } }); return childItem; } ); }) }); }) ); var appStoreContext = createContext(createAppStore()); function useAppStore(selector) { const context = useContext(appStoreContext); return useStore(context, selector); } function useAppStoreApi() { return useContext(appStoreContext); } // lib/get-zoom-config.ts init_react_import(); // ../../node_modules/css-box-model/dist/css-box-model.esm.js init_react_import(); // ../../node_modules/tiny-invariant/dist/esm/tiny-invariant.js init_react_import(); var isProduction = process.env.NODE_ENV === "production"; var prefix = "Invariant failed"; function invariant(condition, message) { if (condition) { return; } if (isProduction) { throw new Error(prefix); } var provided = typeof message === "function" ? message() : message; var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix; throw new Error(value); } // ../../node_modules/css-box-model/dist/css-box-model.esm.js var getRect = function getRect2(_ref) { var top = _ref.top, right = _ref.right, bottom = _ref.bottom, left = _ref.left; var width = right - left; var height = bottom - top; var rect = { top, right, bottom, left, width, height, x: left, y: top, center: { x: (right + left) / 2, y: (bottom + top) / 2 } }; return rect; }; var expand = function expand2(target, expandBy) { return { top: target.top - expandBy.top, left: target.left - expandBy.left, bottom: target.bottom + expandBy.bottom, right: target.right + expandBy.right }; }; var shrink = function shrink2(target, shrinkBy) { return { top: target.top + shrinkBy.top, left: target.left + shrinkBy.left, bottom: target.bottom - shrinkBy.bottom, right: target.right - shrinkBy.right }; }; var noSpacing = { top: 0, right: 0, bottom: 0, left: 0 }; var createBox = function createBox2(_ref2) { var borderBox = _ref2.borderBox, _ref2$margin = _ref2.margin, margin = _ref2$margin === void 0 ? noSpacing : _ref2$margin, _ref2$border = _ref2.border, border = _ref2$border === void 0 ? noSpacing : _ref2$border, _ref2$padding = _ref2.padding, padding = _ref2$padding === void 0 ? noSpacing : _ref2$padding; var marginBox = getRect(expand(borderBox, margin)); var paddingBox = getRect(shrink(borderBox, border)); var contentBox = getRect(shrink(paddingBox, padding)); return { marginBox, borderBox: getRect(borderBox), paddingBox, contentBox, margin, border, padding }; }; var parse = function parse2(raw) { var value = raw.slice(0, -2); var suffix = raw.slice(-2); if (suffix !== "px") { return 0; } var result = Number(value); !!isNaN(result) ? process.env.NODE_ENV !== "production" ? invariant(false, "Could not parse value [raw: " + raw + ", without suffix: " + value + "]") : invariant(false) : void 0; return result; }; var calculateBox = function calculateBox2(borderBox, styles2) { var margin = { top: parse(styles2.marginTop), right: parse(styles2.marginRight), bottom: parse(styles2.marginBottom), left: parse(styles2.marginLeft) }; var padding = { top: parse(styles2.paddingTop), right: parse(styles2.paddingRight), bottom: parse(styles2.paddingBottom), left: parse(styles2.paddingLeft) }; var border = { top: parse(styles2.borderTopWidth), right: parse(styles2.borderRightWidth), bottom: parse(styles2.borderBottomWidth), left: parse(styles2.borderLeftWidth) }; return createBox({ borderBox, margin, padding, border }); }; var getBox = function getBox2(el) { var borderBox = el.getBoundingClientRect(); var styles2 = window.getComputedStyle(el); return calculateBox(borderBox, styles2); }; // lib/get-zoom-config.ts var RESET_ZOOM_SMALLER_THAN_FRAME = true; var getZoomConfig = (uiViewport, frame, zoom) => { const box = getBox(frame); const { width: frameWidth, height: frameHeight } = box.contentBox; const viewportHeight = uiViewport.height === "auto" ? frameHeight : uiViewport.height; let rootHeight = 0; let autoZoom = 1; if (uiViewport.width > frameWidth || viewportHeight > frameHeight) { const widthZoom = Math.min(frameWidth / uiViewport.width, 1); const heightZoom = Math.min(frameHeight / viewportHeight, 1); zoom = widthZoom; if (widthZoom < heightZoom) { rootHeight = viewportHeight / zoom; } else { rootHeight = viewportHeight; zoom = heightZoom; } autoZoom = zoom; } else { if (RESET_ZOOM_SMALLER_THAN_FRAME) { autoZoom = 1; zoom = 1; rootHeight = viewportHeight; } } return { autoZoom, rootHeight, zoom }; }; // lib/use-reset-auto-zoom.ts var useResetAutoZoom = (frameRef) => { const appStoreApi = useAppStoreApi(); const resetAutoZoom = (options) => { const { state, zoomConfig, setZoomConfig } = appStoreApi.getState(); const { viewports } = state.ui; cons