@standhigher/puck-page-builder 0.12.8 → 0.12.9

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.
Files changed (3) hide show
  1. package/dist/index.js +255 -201
  2. package/package.json +1 -1
  3. package/src/styles.css +19 -11
package/dist/index.js CHANGED
@@ -57,7 +57,7 @@ import {
57
57
  ViewIcon,
58
58
  XIcon
59
59
  } from "@shopify/polaris-icons";
60
- import { useRef, useState } from "react";
60
+ import { useRef as useRef2, useState } from "react";
61
61
 
62
62
  // src/adapters/puck/demo-preview.tsx
63
63
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -114,6 +114,39 @@ function createDemoPuckConfig(onSelect) {
114
114
  };
115
115
  }
116
116
 
117
+ // src/editor/shell/AdaptiveIframe.tsx
118
+ import { useLayoutEffect, useRef } from "react";
119
+ import { jsx as jsx2 } from "react/jsx-runtime";
120
+ function AdaptiveIframe({ document: document2, children }) {
121
+ const contentRef = useRef(null);
122
+ useLayoutEffect(() => {
123
+ const content = contentRef.current;
124
+ const frame = document2?.defaultView?.frameElement;
125
+ if (!content || !frame) return;
126
+ const previousHeight = frame.style.getPropertyValue("height");
127
+ const previousPriority = frame.style.getPropertyPriority("height");
128
+ let animationFrame;
129
+ const resize = () => {
130
+ if (animationFrame !== void 0) cancelAnimationFrame(animationFrame);
131
+ animationFrame = requestAnimationFrame(() => {
132
+ animationFrame = void 0;
133
+ const height = `${Math.ceil(content.getBoundingClientRect().height)}px`;
134
+ if (frame.style.height !== height) frame.style.height = height;
135
+ });
136
+ };
137
+ resize();
138
+ const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(resize);
139
+ observer?.observe(content);
140
+ return () => {
141
+ observer?.disconnect();
142
+ if (animationFrame !== void 0) cancelAnimationFrame(animationFrame);
143
+ if (previousHeight) frame.style.setProperty("height", previousHeight, previousPriority);
144
+ else frame.style.removeProperty("height");
145
+ };
146
+ }, [document2]);
147
+ return /* @__PURE__ */ jsx2("div", { ref: contentRef, style: { display: "flow-root", height: "auto", minHeight: 0 }, children });
148
+ }
149
+
117
150
  // src/editor/state/types.ts
118
151
  var initialBlocks = [
119
152
  {
@@ -158,7 +191,7 @@ var initialEditorState = {
158
191
  };
159
192
 
160
193
  // src/editor/shell/EditorShell.tsx
161
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
194
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
162
195
  var deviceLabels = {
163
196
  desktop: "Desktop",
164
197
  tablet: "Tablet",
@@ -180,12 +213,12 @@ function IconButton({
180
213
  disabled = false,
181
214
  pressed = false
182
215
  }) {
183
- return /* @__PURE__ */ jsx2(Tooltip, { content: label, children: /* @__PURE__ */ jsx2(Button, { accessibilityLabel: label, icon, onClick, disabled, pressed, variant: "tertiary" }) });
216
+ return /* @__PURE__ */ jsx3(Tooltip, { content: label, children: /* @__PURE__ */ jsx3(Button, { accessibilityLabel: label, icon, onClick, disabled, pressed, variant: "tertiary" }) });
184
217
  }
185
218
  function EditorShell({ initialState, iframe = true }) {
186
219
  const [state, setState] = useState({ ...initialEditorState, ...initialState });
187
220
  const [undoDepth, setUndoDepth] = useState(0);
188
- const nextBlockId = useRef(state.blocks.length);
221
+ const nextBlockId = useRef2(state.blocks.length);
189
222
  const selectedBlock = state.blocks.find((block) => block.id === state.selectedBlockId) ?? null;
190
223
  const update = (patch) => setState((current) => ({ ...current, ...patch }));
191
224
  const selectBlock = (id) => update({ selectedBlockId: id, saveState: "dirty" });
@@ -224,62 +257,62 @@ function EditorShell({ initialState, iframe = true }) {
224
257
  update({ saveState: "saving" });
225
258
  window.setTimeout(() => update({ saveState: "saved" }), 350);
226
259
  };
227
- return /* @__PURE__ */ jsx2(Puck, { config: puckConfig, data: puckData, iframe: { enabled: iframe }, children: /* @__PURE__ */ jsx2(Puck.Layout, { children: /* @__PURE__ */ jsxs2("div", { className: "pb-shell", "data-testid": "editor-shell", "data-preview-mode": state.previewMode, children: [
228
- /* @__PURE__ */ jsx2("header", { className: "pb-header", children: /* @__PURE__ */ jsxs2(InlineStack, { align: "space-between", blockAlign: "center", gap: "300", wrap: false, children: [
260
+ return /* @__PURE__ */ jsx3(Puck, { config: puckConfig, data: puckData, iframe: { enabled: iframe }, overrides: { iframe: AdaptiveIframe }, children: /* @__PURE__ */ jsx3(Puck.Layout, { children: /* @__PURE__ */ jsxs2("div", { className: "pb-shell", "data-testid": "editor-shell", "data-preview-mode": state.previewMode, children: [
261
+ /* @__PURE__ */ jsx3("header", { className: "pb-header", children: /* @__PURE__ */ jsxs2(InlineStack, { align: "space-between", blockAlign: "center", gap: "300", wrap: false, children: [
229
262
  /* @__PURE__ */ jsxs2(InlineStack, { gap: "200", blockAlign: "center", wrap: false, children: [
230
- /* @__PURE__ */ jsx2(IconButton, { label: "\u8FD4\u56DE\u9875\u9762\u5217\u8868", icon: ArrowLeftIcon }),
263
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u8FD4\u56DE\u9875\u9762\u5217\u8868", icon: ArrowLeftIcon }),
231
264
  /* @__PURE__ */ jsxs2("div", { className: "pb-page-title", children: [
232
- /* @__PURE__ */ jsx2(Text, { as: "h1", variant: "headingSm", children: "Tracking page" }),
233
- /* @__PURE__ */ jsx2(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "English (US)" })
265
+ /* @__PURE__ */ jsx3(Text, { as: "h1", variant: "headingSm", children: "Tracking page" }),
266
+ /* @__PURE__ */ jsx3(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "English (US)" })
234
267
  ] }),
235
- /* @__PURE__ */ jsx2(Badge, { tone: state.saveState === "failed" || state.saveState === "conflict" ? "critical" : "info", children: saveLabels[state.saveState] })
268
+ /* @__PURE__ */ jsx3(Badge, { tone: state.saveState === "failed" || state.saveState === "conflict" ? "critical" : "info", children: saveLabels[state.saveState] })
236
269
  ] }),
237
270
  /* @__PURE__ */ jsxs2(InlineStack, { gap: "150", blockAlign: "center", wrap: false, children: [
238
- /* @__PURE__ */ jsx2(IconButton, { label: "\u64A4\u9500", icon: UndoIcon, disabled: undoDepth === 0, onClick: () => setUndoDepth((depth) => Math.max(0, depth - 1)) }),
239
- /* @__PURE__ */ jsx2(IconButton, { label: "\u6062\u590D", icon: RedoIcon, disabled: true }),
240
- /* @__PURE__ */ jsx2(Button, { onClick: savePresentationState, children: "\u4FDD\u5B58\u8349\u7A3F" }),
241
- /* @__PURE__ */ jsx2(Button, { onClick: () => update({ previewMode: "mock-preview" }), icon: ViewIcon, children: "\u9884\u89C8" }),
242
- /* @__PURE__ */ jsx2(Button, { variant: "primary", disabled: true, children: "\u53D1\u5E03" })
271
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u64A4\u9500", icon: UndoIcon, disabled: undoDepth === 0, onClick: () => setUndoDepth((depth) => Math.max(0, depth - 1)) }),
272
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u6062\u590D", icon: RedoIcon, disabled: true }),
273
+ /* @__PURE__ */ jsx3(Button, { onClick: savePresentationState, children: "\u4FDD\u5B58\u8349\u7A3F" }),
274
+ /* @__PURE__ */ jsx3(Button, { onClick: () => update({ previewMode: "mock-preview" }), icon: ViewIcon, children: "\u9884\u89C8" }),
275
+ /* @__PURE__ */ jsx3(Button, { variant: "primary", disabled: true, children: "\u53D1\u5E03" })
243
276
  ] })
244
277
  ] }) }),
245
278
  /* @__PURE__ */ jsxs2("div", { className: "pb-workspace", children: [
246
279
  /* @__PURE__ */ jsxs2("nav", { className: "pb-tool-rail", "aria-label": "\u7F16\u8F91\u5668\u5DE5\u5177", children: [
247
- /* @__PURE__ */ jsx2(IconButton, { label: "\u533A\u5757", icon: LayoutSectionIcon, pressed: state.blockView === "blocks", onClick: () => update({ blockView: "blocks", isLeftRailOpen: true }) }),
248
- /* @__PURE__ */ jsx2(IconButton, { label: "\u7ED3\u6784", icon: MenuIcon, pressed: state.blockView === "outline", onClick: () => update({ blockView: "outline", isLeftRailOpen: true }) })
280
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u533A\u5757", icon: LayoutSectionIcon, pressed: state.blockView === "blocks", onClick: () => update({ blockView: "blocks", isLeftRailOpen: true }) }),
281
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u7ED3\u6784", icon: MenuIcon, pressed: state.blockView === "outline", onClick: () => update({ blockView: "outline", isLeftRailOpen: true }) })
249
282
  ] }),
250
283
  /* @__PURE__ */ jsxs2("aside", { className: `pb-left-panel ${state.isLeftRailOpen ? "" : "pb-panel--closed"}`, "aria-label": "Block navigation", children: [
251
284
  /* @__PURE__ */ jsxs2(InlineStack, { align: "space-between", blockAlign: "center", children: [
252
285
  /* @__PURE__ */ jsxs2("div", { children: [
253
- /* @__PURE__ */ jsx2(Text, { as: "h2", variant: "headingSm", children: state.blockView === "blocks" ? "\u533A\u5757" : "\u7ED3\u6784" }),
254
- /* @__PURE__ */ jsx2(Text, { as: "p", variant: "bodySm", tone: "subdued", children: state.blockView === "blocks" ? "\u9875\u9762\u533A\u5757\u4E0E\u5FEB\u6377\u64CD\u4F5C" : "\u5F53\u524D\u9875\u9762\u5C42\u7EA7" })
286
+ /* @__PURE__ */ jsx3(Text, { as: "h2", variant: "headingSm", children: state.blockView === "blocks" ? "\u533A\u5757" : "\u7ED3\u6784" }),
287
+ /* @__PURE__ */ jsx3(Text, { as: "p", variant: "bodySm", tone: "subdued", children: state.blockView === "blocks" ? "\u9875\u9762\u533A\u5757\u4E0E\u5FEB\u6377\u64CD\u4F5C" : "\u5F53\u524D\u9875\u9762\u5C42\u7EA7" })
255
288
  ] }),
256
- /* @__PURE__ */ jsx2(IconButton, { label: "\u6536\u8D77\u5DE6\u4FA7\u9762\u677F", icon: XIcon, onClick: () => update({ isLeftRailOpen: false }) })
289
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u6536\u8D77\u5DE6\u4FA7\u9762\u677F", icon: XIcon, onClick: () => update({ isLeftRailOpen: false }) })
257
290
  ] }),
258
- /* @__PURE__ */ jsx2(BlockList, { view: state.blockView, blocks: state.blocks, selectedBlockId: state.selectedBlockId, onSelect: selectBlock, onMove: moveBlock, onDuplicate: duplicateBlock, onDelete: deleteBlock }),
259
- /* @__PURE__ */ jsx2(Button, { fullWidth: true, icon: PlusIcon, onClick: () => update({ isPickerOpen: true }), children: "\u6DFB\u52A0\u6A21\u5757" })
291
+ /* @__PURE__ */ jsx3(BlockList, { view: state.blockView, blocks: state.blocks, selectedBlockId: state.selectedBlockId, onSelect: selectBlock, onMove: moveBlock, onDuplicate: duplicateBlock, onDelete: deleteBlock }),
292
+ /* @__PURE__ */ jsx3(Button, { fullWidth: true, icon: PlusIcon, onClick: () => update({ isPickerOpen: true }), children: "\u6DFB\u52A0\u6A21\u5757" })
260
293
  ] }),
261
294
  /* @__PURE__ */ jsxs2("main", { className: "pb-canvas-area", children: [
262
- /* @__PURE__ */ jsx2(CanvasToolbar, { device: state.device, zoom: state.zoom, onDevice: (device) => update({ device }), onZoom: (zoom) => update({ zoom }) }),
263
- /* @__PURE__ */ jsx2("div", { className: "pb-canvas-stage", children: /* @__PURE__ */ jsx2("div", { className: `pb-canvas-frame pb-canvas-frame--${state.device} pb-canvas-frame--zoom-${state.zoom}`, "data-device": state.device, "data-zoom": state.zoom, children: /* @__PURE__ */ jsx2(Puck.Preview, {}) }) }),
295
+ /* @__PURE__ */ jsx3(CanvasToolbar, { device: state.device, zoom: state.zoom, onDevice: (device) => update({ device }), onZoom: (zoom) => update({ zoom }) }),
296
+ /* @__PURE__ */ jsx3("div", { className: "pb-canvas-stage", children: /* @__PURE__ */ jsx3("div", { className: `pb-canvas-frame pb-canvas-frame--${state.device} pb-canvas-frame--zoom-${state.zoom}`, "data-device": state.device, "data-zoom": state.zoom, children: /* @__PURE__ */ jsx3(Puck.Preview, {}) }) }),
264
297
  !state.isLeftRailOpen || !state.isRightPanelOpen ? /* @__PURE__ */ jsxs2("div", { className: "pb-collapsed-actions", children: [
265
- !state.isLeftRailOpen ? /* @__PURE__ */ jsx2(Button, { onClick: () => update({ isLeftRailOpen: true }), children: "\u6253\u5F00\u533A\u5757\u9762\u677F" }) : null,
266
- !state.isRightPanelOpen ? /* @__PURE__ */ jsx2(Button, { onClick: () => update({ isRightPanelOpen: true }), children: "\u6253\u5F00\u5C5E\u6027\u9762\u677F" }) : null
298
+ !state.isLeftRailOpen ? /* @__PURE__ */ jsx3(Button, { onClick: () => update({ isLeftRailOpen: true }), children: "\u6253\u5F00\u533A\u5757\u9762\u677F" }) : null,
299
+ !state.isRightPanelOpen ? /* @__PURE__ */ jsx3(Button, { onClick: () => update({ isRightPanelOpen: true }), children: "\u6253\u5F00\u5C5E\u6027\u9762\u677F" }) : null
267
300
  ] }) : null
268
301
  ] }),
269
302
  /* @__PURE__ */ jsxs2("aside", { className: `pb-right-panel ${state.isRightPanelOpen ? "" : "pb-panel--closed"}`, "aria-label": "Block properties", children: [
270
303
  /* @__PURE__ */ jsxs2(InlineStack, { align: "space-between", blockAlign: "center", children: [
271
304
  /* @__PURE__ */ jsxs2("div", { children: [
272
- /* @__PURE__ */ jsx2(Text, { as: "h2", variant: "headingSm", children: "\u5C5E\u6027" }),
273
- /* @__PURE__ */ jsx2(Text, { as: "p", variant: "bodySm", tone: "subdued", children: selectedBlock?.label ?? "\u672A\u9009\u62E9\u533A\u5757" })
305
+ /* @__PURE__ */ jsx3(Text, { as: "h2", variant: "headingSm", children: "\u5C5E\u6027" }),
306
+ /* @__PURE__ */ jsx3(Text, { as: "p", variant: "bodySm", tone: "subdued", children: selectedBlock?.label ?? "\u672A\u9009\u62E9\u533A\u5757" })
274
307
  ] }),
275
- /* @__PURE__ */ jsx2(IconButton, { label: "\u6536\u8D77\u5C5E\u6027\u9762\u677F", icon: XIcon, onClick: () => update({ isRightPanelOpen: false }) })
308
+ /* @__PURE__ */ jsx3(IconButton, { label: "\u6536\u8D77\u5C5E\u6027\u9762\u677F", icon: XIcon, onClick: () => update({ isRightPanelOpen: false }) })
276
309
  ] }),
277
- selectedBlock ? /* @__PURE__ */ jsx2(PropertyPanel, { block: selectedBlock, editorLocale: state.editorLocale, pageLocale: state.pageLocale, onEditorLocale: (editorLocale) => update({ editorLocale }), onPageLocale: (pageLocale) => update({ pageLocale }) }) : /* @__PURE__ */ jsx2(Text, { as: "p", tone: "subdued", children: "\u9009\u62E9\u4E00\u4E2A\u533A\u5757\u4EE5\u67E5\u770B\u5C5E\u6027\u3002" })
310
+ selectedBlock ? /* @__PURE__ */ jsx3(PropertyPanel, { block: selectedBlock, editorLocale: state.editorLocale, pageLocale: state.pageLocale, onEditorLocale: (editorLocale) => update({ editorLocale }), onPageLocale: (pageLocale) => update({ pageLocale }) }) : /* @__PURE__ */ jsx3(Text, { as: "p", tone: "subdued", children: "\u9009\u62E9\u4E00\u4E2A\u533A\u5757\u4EE5\u67E5\u770B\u5C5E\u6027\u3002" })
278
311
  ] })
279
312
  ] }),
280
- /* @__PURE__ */ jsx2(Modal, { instant: true, open: state.isPickerOpen, onClose: () => update({ isPickerOpen: false }), title: "\u6DFB\u52A0\u6A21\u5757", primaryAction: { content: "\u5173\u95ED", onAction: () => update({ isPickerOpen: false }) }, children: /* @__PURE__ */ jsx2(Modal.Section, { children: /* @__PURE__ */ jsxs2(BlockStack, { gap: "300", children: [
281
- /* @__PURE__ */ jsx2(Text, { as: "p", tone: "subdued", children: "\u672C\u7248\u4EC5\u64CD\u4F5C\u672C\u5730\u6F14\u793A\u533A\u5757\uFF0C\u4E0D\u4F1A\u5199\u5165\u9875\u9762\u6570\u636E\u6216\u8C03\u7528\u4E1A\u52A1\u63A5\u53E3\u3002" }),
282
- /* @__PURE__ */ jsx2(InlineStack, { gap: "200", wrap: true, children: ["Hero", "TrackingForm", "Text"].map((type) => /* @__PURE__ */ jsx2(Button, { onClick: () => addBlock(type), children: type }, type)) })
313
+ /* @__PURE__ */ jsx3(Modal, { instant: true, open: state.isPickerOpen, onClose: () => update({ isPickerOpen: false }), title: "\u6DFB\u52A0\u6A21\u5757", primaryAction: { content: "\u5173\u95ED", onAction: () => update({ isPickerOpen: false }) }, children: /* @__PURE__ */ jsx3(Modal.Section, { children: /* @__PURE__ */ jsxs2(BlockStack, { gap: "300", children: [
314
+ /* @__PURE__ */ jsx3(Text, { as: "p", tone: "subdued", children: "\u672C\u7248\u4EC5\u64CD\u4F5C\u672C\u5730\u6F14\u793A\u533A\u5757\uFF0C\u4E0D\u4F1A\u5199\u5165\u9875\u9762\u6570\u636E\u6216\u8C03\u7528\u4E1A\u52A1\u63A5\u53E3\u3002" }),
315
+ /* @__PURE__ */ jsx3(InlineStack, { gap: "200", wrap: true, children: ["Hero", "TrackingForm", "Text"].map((type) => /* @__PURE__ */ jsx3(Button, { onClick: () => addBlock(type), children: type }, type)) })
283
316
  ] }) }) })
284
317
  ] }) }) });
285
318
  }
@@ -292,24 +325,24 @@ function BlockList({
292
325
  onDuplicate,
293
326
  onDelete
294
327
  }) {
295
- return /* @__PURE__ */ jsx2("div", { className: `pb-block-list pb-block-list--${view}`, "data-testid": `${view}-view`, children: blocks.map((block, index) => /* @__PURE__ */ jsxs2("article", { className: `pb-block-row ${block.id === selectedBlockId ? "pb-block-row--selected" : ""}`, children: [
296
- /* @__PURE__ */ jsx2("span", { className: "pb-block-handle", "aria-label": `${block.label} \u62D6\u52A8\u6392\u5E8F`, children: /* @__PURE__ */ jsx2(DragHandleIcon, {}) }),
328
+ return /* @__PURE__ */ jsx3("div", { className: `pb-block-list pb-block-list--${view}`, "data-testid": `${view}-view`, children: blocks.map((block, index) => /* @__PURE__ */ jsxs2("article", { className: `pb-block-row ${block.id === selectedBlockId ? "pb-block-row--selected" : ""}`, children: [
329
+ /* @__PURE__ */ jsx3("span", { className: "pb-block-handle", "aria-label": `${block.label} \u62D6\u52A8\u6392\u5E8F`, children: /* @__PURE__ */ jsx3(DragHandleIcon, {}) }),
297
330
  /* @__PURE__ */ jsxs2("button", { type: "button", className: "pb-block-select", onClick: () => onSelect(block.id), "aria-pressed": block.id === selectedBlockId, children: [
298
- /* @__PURE__ */ jsx2(Text, { as: "span", variant: "bodySm", fontWeight: "semibold", children: block.label }),
299
- view === "blocks" ? /* @__PURE__ */ jsx2(Text, { as: "span", variant: "bodySm", tone: "subdued", children: block.description }) : /* @__PURE__ */ jsx2(Text, { as: "span", variant: "bodySm", tone: "subdued", children: block.type })
331
+ /* @__PURE__ */ jsx3(Text, { as: "span", variant: "bodySm", fontWeight: "semibold", children: block.label }),
332
+ view === "blocks" ? /* @__PURE__ */ jsx3(Text, { as: "span", variant: "bodySm", tone: "subdued", children: block.description }) : /* @__PURE__ */ jsx3(Text, { as: "span", variant: "bodySm", tone: "subdued", children: block.type })
300
333
  ] }),
301
334
  /* @__PURE__ */ jsxs2("div", { className: "pb-block-actions", "aria-label": `${block.label} \u64CD\u4F5C`, children: [
302
- /* @__PURE__ */ jsx2(Button, { size: "slim", onClick: () => onMove(block.id, -1), disabled: index === 0, children: "\u4E0A\u79FB" }),
303
- /* @__PURE__ */ jsx2(Button, { size: "slim", onClick: () => onMove(block.id, 1), disabled: index === blocks.length - 1, children: "\u4E0B\u79FB" }),
304
- /* @__PURE__ */ jsx2(IconButton, { label: `\u590D\u5236 ${block.label}`, icon: DuplicateIcon, onClick: () => onDuplicate(block) }),
305
- /* @__PURE__ */ jsx2(IconButton, { label: `\u5220\u9664 ${block.label}`, icon: DeleteIcon, onClick: () => onDelete(block) })
335
+ /* @__PURE__ */ jsx3(Button, { size: "slim", onClick: () => onMove(block.id, -1), disabled: index === 0, children: "\u4E0A\u79FB" }),
336
+ /* @__PURE__ */ jsx3(Button, { size: "slim", onClick: () => onMove(block.id, 1), disabled: index === blocks.length - 1, children: "\u4E0B\u79FB" }),
337
+ /* @__PURE__ */ jsx3(IconButton, { label: `\u590D\u5236 ${block.label}`, icon: DuplicateIcon, onClick: () => onDuplicate(block) }),
338
+ /* @__PURE__ */ jsx3(IconButton, { label: `\u5220\u9664 ${block.label}`, icon: DeleteIcon, onClick: () => onDelete(block) })
306
339
  ] })
307
340
  ] }, block.id)) });
308
341
  }
309
342
  function CanvasToolbar({ device, zoom, onDevice, onZoom }) {
310
- return /* @__PURE__ */ jsx2("div", { className: "pb-canvas-toolbar", children: /* @__PURE__ */ jsxs2(InlineStack, { align: "space-between", blockAlign: "center", gap: "200", wrap: true, children: [
311
- /* @__PURE__ */ jsx2(ButtonGroup, { variant: "segmented", children: Object.keys(deviceLabels).map((item) => /* @__PURE__ */ jsx2(Button, { pressed: device === item, onClick: () => onDevice(item), children: deviceLabels[item] }, item)) }),
312
- /* @__PURE__ */ jsx2(Select, { label: "\u7F29\u653E", labelHidden: true, value: zoom, options: [{ label: "Auto", value: "auto" }, { label: "50%", value: "50" }, { label: "70%", value: "70" }, { label: "100%", value: "100" }], onChange: (value) => onZoom(value) })
343
+ return /* @__PURE__ */ jsx3("div", { className: "pb-canvas-toolbar", children: /* @__PURE__ */ jsxs2(InlineStack, { align: "space-between", blockAlign: "center", gap: "200", wrap: true, children: [
344
+ /* @__PURE__ */ jsx3(ButtonGroup, { variant: "segmented", children: Object.keys(deviceLabels).map((item) => /* @__PURE__ */ jsx3(Button, { pressed: device === item, onClick: () => onDevice(item), children: deviceLabels[item] }, item)) }),
345
+ /* @__PURE__ */ jsx3(Select, { label: "\u7F29\u653E", labelHidden: true, value: zoom, options: [{ label: "Auto", value: "auto" }, { label: "50%", value: "50" }, { label: "70%", value: "70" }, { label: "100%", value: "100" }], onChange: (value) => onZoom(value) })
313
346
  ] }) });
314
347
  }
315
348
  function PropertyPanel({
@@ -322,23 +355,23 @@ function PropertyPanel({
322
355
  const [tab, setTab] = useState(0);
323
356
  const tabs = ["\u5185\u5BB9", "\u6837\u5F0F", "\u9AD8\u7EA7"];
324
357
  return /* @__PURE__ */ jsxs2(BlockStack, { gap: "300", "data-testid": "property-panel", children: [
325
- /* @__PURE__ */ jsx2("div", { className: "pb-inspector-tabs", role: "tablist", "aria-label": "\u5C5E\u6027\u5206\u7C7B", children: tabs.map((label, index) => /* @__PURE__ */ jsx2("button", { type: "button", role: "tab", "aria-selected": tab === index, className: tab === index ? "pb-inspector-tab--selected" : "", onClick: () => setTab(index), children: label }, label)) }),
358
+ /* @__PURE__ */ jsx3("div", { className: "pb-inspector-tabs", role: "tablist", "aria-label": "\u5C5E\u6027\u5206\u7C7B", children: tabs.map((label, index) => /* @__PURE__ */ jsx3("button", { type: "button", role: "tab", "aria-selected": tab === index, className: tab === index ? "pb-inspector-tab--selected" : "", onClick: () => setTab(index), children: label }, label)) }),
326
359
  tab === 0 ? /* @__PURE__ */ jsxs2(BlockStack, { gap: "300", children: [
327
- /* @__PURE__ */ jsx2(Badge, { children: block.type }),
328
- /* @__PURE__ */ jsx2(Text, { as: "p", variant: "headingSm", children: block.label }),
329
- /* @__PURE__ */ jsx2(Divider, {}),
360
+ /* @__PURE__ */ jsx3(Badge, { children: block.type }),
361
+ /* @__PURE__ */ jsx3(Text, { as: "p", variant: "headingSm", children: block.label }),
362
+ /* @__PURE__ */ jsx3(Divider, {}),
330
363
  /* @__PURE__ */ jsxs2(Text, { as: "p", tone: "subdued", children: [
331
364
  "\u5F53\u524D\u9009\u4E2D\uFF1A",
332
365
  block.id
333
366
  ] }),
334
- /* @__PURE__ */ jsx2(Text, { as: "p", children: block.description }),
335
- /* @__PURE__ */ jsx2(Box, { padding: "300", background: "bg-surface-secondary", borderRadius: "200", children: /* @__PURE__ */ jsx2(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "\u5B57\u6BB5\u7F16\u8F91\u5C06\u5728 PageDocument \u7248\u672C\u5B9E\u73B0\uFF1BV0.1.1 \u4EC5\u63D0\u4F9B\u771F\u5B9E\u9875\u9762\u9884\u89C8\u548C\u9009\u62E9\u53CD\u9988\u3002" }) })
367
+ /* @__PURE__ */ jsx3(Text, { as: "p", children: block.description }),
368
+ /* @__PURE__ */ jsx3(Box, { padding: "300", background: "bg-surface-secondary", borderRadius: "200", children: /* @__PURE__ */ jsx3(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "\u5B57\u6BB5\u7F16\u8F91\u5C06\u5728 PageDocument \u7248\u672C\u5B9E\u73B0\uFF1BV0.1.1 \u4EC5\u63D0\u4F9B\u771F\u5B9E\u9875\u9762\u9884\u89C8\u548C\u9009\u62E9\u53CD\u9988\u3002" }) })
336
369
  ] }) : null,
337
- tab === 1 ? /* @__PURE__ */ jsx2(BlockStack, { gap: "300", children: /* @__PURE__ */ jsx2(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "\u6837\u5F0F\u914D\u7F6E\u5C06\u7531 Block Field \u4E0E Theme Token \u63D0\u4F9B\u3002\u672C\u7248\u4FDD\u6301 Storefront \u9875\u9762\u6837\u5F0F\u4E0E\u7F16\u8F91\u5668 UI \u9694\u79BB\u3002" }) }) : null,
370
+ tab === 1 ? /* @__PURE__ */ jsx3(BlockStack, { gap: "300", children: /* @__PURE__ */ jsx3(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "\u6837\u5F0F\u914D\u7F6E\u5C06\u7531 Block Field \u4E0E Theme Token \u63D0\u4F9B\u3002\u672C\u7248\u4FDD\u6301 Storefront \u9875\u9762\u6837\u5F0F\u4E0E\u7F16\u8F91\u5668 UI \u9694\u79BB\u3002" }) }) : null,
338
371
  tab === 2 ? /* @__PURE__ */ jsxs2(BlockStack, { gap: "300", children: [
339
- /* @__PURE__ */ jsx2(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "\u8BED\u8A00\u5165\u53E3\u5C5E\u4E8E Inspector\uFF0C\u907F\u514D\u5728\u4E3B\u5DE5\u5177\u680F\u91CD\u590D\u5360\u4F4D\u3002" }),
340
- /* @__PURE__ */ jsx2(Select, { label: "Editor Language", options: [{ label: "\u4E2D\u6587", value: "zh-CN" }, { label: "English", value: "en-US" }], value: editorLocale, onChange: onEditorLocale }),
341
- /* @__PURE__ */ jsx2(Select, { label: "Page Locale", options: [{ label: "English (US)", value: "en-US" }, { label: "\u4E2D\u6587", value: "zh-CN" }], value: pageLocale, onChange: onPageLocale })
372
+ /* @__PURE__ */ jsx3(Text, { as: "p", variant: "bodySm", tone: "subdued", children: "\u8BED\u8A00\u5165\u53E3\u5C5E\u4E8E Inspector\uFF0C\u907F\u514D\u5728\u4E3B\u5DE5\u5177\u680F\u91CD\u590D\u5360\u4F4D\u3002" }),
373
+ /* @__PURE__ */ jsx3(Select, { label: "Editor Language", options: [{ label: "\u4E2D\u6587", value: "zh-CN" }, { label: "English", value: "en-US" }], value: editorLocale, onChange: onEditorLocale }),
374
+ /* @__PURE__ */ jsx3(Select, { label: "Page Locale", options: [{ label: "English (US)", value: "en-US" }, { label: "\u4E2D\u6587", value: "zh-CN" }], value: pageLocale, onChange: onPageLocale })
342
375
  ] }) : null
343
376
  ] });
344
377
  }
@@ -346,15 +379,15 @@ function PropertyPanel({
346
379
  // src/editor/shell/PageDocumentEditorShell.tsx
347
380
  import { Puck as Puck2, usePuck } from "@puckeditor/core";
348
381
  import { Badge as Badge3, Banner, Button as Button2, ButtonGroup as ButtonGroup2, Frame, InlineStack as InlineStack3, Select as Select2, Text as Text3, TextField, Toast } from "@shopify/polaris";
349
- import { DragHandleIcon as DragHandleIcon2, LayoutSectionIcon as LayoutSectionIcon2, MenuIcon as MenuIcon2, ProductIcon, RedoIcon as RedoIcon2, UndoIcon as UndoIcon2, XIcon as XIcon2 } from "@shopify/polaris-icons";
350
- import { useCallback as useCallback2, useEffect as useEffect4, useLayoutEffect, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
382
+ import { DeleteIcon as DeleteIcon2, DragHandleIcon as DragHandleIcon2, LayoutSectionIcon as LayoutSectionIcon2, MenuIcon as MenuIcon2, ProductIcon, RedoIcon as RedoIcon2, UndoIcon as UndoIcon2, XIcon as XIcon2 } from "@shopify/polaris-icons";
383
+ import { useCallback as useCallback2, useEffect as useEffect4, useLayoutEffect as useLayoutEffect2, useMemo as useMemo2, useRef as useRef6, useState as useState4 } from "react";
351
384
 
352
385
  // src/adapters/puck/use-canvas-editing.ts
353
386
  import { registerOverlayPortal } from "@puckeditor/core";
354
- import { useEffect, useRef as useRef2 } from "react";
387
+ import { useEffect, useRef as useRef3 } from "react";
355
388
  var editingControlSelector = "input, textarea, select, button, a[href], [contenteditable]:not([contenteditable=false]), [role=textbox]";
356
389
  function useCanvasEditing(active) {
357
- const ref = useRef2(null);
390
+ const ref = useRef3(null);
358
391
  useEffect(() => {
359
392
  const root = ref.current;
360
393
  if (!active || !root) return;
@@ -374,10 +407,10 @@ function useCanvasEditing(active) {
374
407
  }
375
408
 
376
409
  // src/adapters/puck/canvas-extension-block.tsx
377
- import { jsx as jsx3 } from "react/jsx-runtime";
410
+ import { jsx as jsx4 } from "react/jsx-runtime";
378
411
  function CanvasExtensionBlock({ active, blockId, children, label, onSelect }) {
379
412
  const editorRef = useCanvasEditing(active);
380
- return /* @__PURE__ */ jsx3("div", { ref: editorRef, className: "pb-document-canvas__extension", "data-page-document-block-id": blockId, "aria-label": "Select " + label + " in canvas", role: "group", tabIndex: 0, onClick: onSelect, onKeyDown: (event) => {
413
+ return /* @__PURE__ */ jsx4("div", { ref: editorRef, className: "pb-document-canvas__extension", "data-page-document-block-id": blockId, "aria-label": "Select " + label + " in canvas", role: "group", tabIndex: 0, onClick: onSelect, onKeyDown: (event) => {
381
414
  if (event.target === event.currentTarget && (event.key === "Enter" || event.key === " ")) {
382
415
  event.preventDefault();
383
416
  onSelect();
@@ -386,15 +419,15 @@ function CanvasExtensionBlock({ active, blockId, children, label, onSelect }) {
386
419
  }
387
420
 
388
421
  // src/adapters/puck/canvas-core-blocks.tsx
389
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
422
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
390
423
  function CanvasTextBlock({ id, content, editable, onSelect, onPropsChange }) {
391
424
  const ref = useCanvasEditing(editable);
392
- return /* @__PURE__ */ jsx4("section", { ref, className: "pb-document-canvas__text", "data-page-document-block-id": id, "aria-label": "Select Text in canvas", role: "button", tabIndex: 0, onClick: () => onSelect(id), onKeyDown: (event) => {
425
+ return /* @__PURE__ */ jsx5("section", { ref, className: "pb-document-canvas__text", "data-page-document-block-id": id, "aria-label": "Select Text in canvas", role: "button", tabIndex: 0, onClick: () => onSelect(id), onKeyDown: (event) => {
393
426
  if (event.target === event.currentTarget && (event.key === "Enter" || event.key === " ")) {
394
427
  event.preventDefault();
395
428
  onSelect(id);
396
429
  }
397
- }, children: /* @__PURE__ */ jsx4("p", { contentEditable: editable, suppressContentEditableWarning: true, onInput: (event) => {
430
+ }, children: /* @__PURE__ */ jsx5("p", { contentEditable: editable, suppressContentEditableWarning: true, onInput: (event) => {
398
431
  if (editable) onPropsChange(id, { content: event.currentTarget.textContent ?? "" }, true);
399
432
  }, children: content }) });
400
433
  }
@@ -406,13 +439,13 @@ function CanvasImageBlock({ id, src, alt, editable, onSelect, onPropsChange }) {
406
439
  onSelect(id);
407
440
  }
408
441
  }, children: [
409
- /* @__PURE__ */ jsx4("img", { src, alt }),
410
- editable ? /* @__PURE__ */ jsx4("input", { "aria-label": "\u753B\u5E03\u56FE\u7247 URL", value: src, onChange: (event) => onPropsChange(id, { src: event.currentTarget.value }, true), onClick: (event) => event.stopPropagation() }) : null
442
+ /* @__PURE__ */ jsx5("img", { src, alt }),
443
+ editable ? /* @__PURE__ */ jsx5("input", { "aria-label": "\u753B\u5E03\u56FE\u7247 URL", value: src, onChange: (event) => onPropsChange(id, { src: event.currentTarget.value }, true), onClick: (event) => event.stopPropagation() }) : null
411
444
  ] });
412
445
  }
413
446
 
414
447
  // src/adapters/puck/page-document-config.tsx
415
- import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
448
+ import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
416
449
  function withBlockPermissions(component, type, resolvePermissions) {
417
450
  if (!resolvePermissions) return component;
418
451
  return {
@@ -430,11 +463,11 @@ function withBlockPermissions(component, type, resolvePermissions) {
430
463
  function canvasFieldFallback({ block, props, registry, onPropsChange }) {
431
464
  const fields = Object.entries(block.fields);
432
465
  if (!fields.length) return null;
433
- return /* @__PURE__ */ jsx5("div", { "aria-label": "Edit " + block.label + " values in canvas", onClick: (event) => event.stopPropagation(), style: { display: "grid", gap: 8, marginTop: 12, padding: 12, border: "1px dashed #94a3b8", borderRadius: 6, background: "#f8fafc" }, children: fields.map(([name, field]) => {
466
+ return /* @__PURE__ */ jsx6("div", { "aria-label": "Edit " + block.label + " values in canvas", onClick: (event) => event.stopPropagation(), style: { display: "grid", gap: 8, marginTop: 12, padding: 12, border: "1px dashed #94a3b8", borderRadius: 6, background: "#f8fafc" }, children: fields.map(([name, field]) => {
434
467
  const Field = registry?.getField(field.field)?.component;
435
468
  return Field ? /* @__PURE__ */ jsxs4("label", { style: { display: "grid", gap: 4, fontSize: 12, fontWeight: 600 }, children: [
436
469
  field.label ?? name,
437
- /* @__PURE__ */ jsx5(Field, { value: props[name], onChange: (value) => onPropsChange({ [name]: value }) })
470
+ /* @__PURE__ */ jsx6(Field, { value: props[name], onChange: (value) => onPropsChange({ [name]: value }) })
438
471
  ] }, name) : null;
439
472
  }) });
440
473
  }
@@ -447,8 +480,8 @@ function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId,
447
480
  const id = typeof props.id === "string" ? props.id : `unknown-${block.type}`;
448
481
  const EditorRenderer = block.render.editor;
449
482
  const active = id === selectedBlockId;
450
- return /* @__PURE__ */ jsx5(CanvasExtensionBlock, { active, blockId: id, label: block.label, onSelect: () => onSelect(id), children: EditorRenderer ? /* @__PURE__ */ jsx5(EditorRenderer, { ...props, blockId: id, selected: active, onPropsChange: (next) => onPropsChange(id, next) }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
451
- /* @__PURE__ */ jsx5(BlockRenderer, { ...props }),
483
+ return /* @__PURE__ */ jsx6(CanvasExtensionBlock, { active, blockId: id, label: block.label, onSelect: () => onSelect(id), children: EditorRenderer ? /* @__PURE__ */ jsx6(EditorRenderer, { ...props, blockId: id, selected: active, onPropsChange: (next) => onPropsChange(id, next) }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
484
+ /* @__PURE__ */ jsx6(BlockRenderer, { ...props }),
452
485
  active ? canvasFieldFallback({ block, props, registry, onPropsChange: (next) => onPropsChange(id, next) }) : null
453
486
  ] }) });
454
487
  }
@@ -461,7 +494,7 @@ function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId,
461
494
  const id = typeof props.id === "string" ? props.id : "unknown-text";
462
495
  const content = typeof props.content === "string" ? props.content : "";
463
496
  const editable = id === selectedBlockId;
464
- return /* @__PURE__ */ jsx5(CanvasTextBlock, { id, content, editable, onSelect, onPropsChange });
497
+ return /* @__PURE__ */ jsx6(CanvasTextBlock, { id, content, editable, onSelect, onPropsChange });
465
498
  }
466
499
  }, "core.text", resolveBlockPermissions),
467
500
  Image: withBlockPermissions({
@@ -470,7 +503,7 @@ function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId,
470
503
  const src = typeof props.src === "string" ? props.src : "";
471
504
  const alt = typeof props.alt === "string" ? props.alt : "";
472
505
  const editable = id === selectedBlockId;
473
- return /* @__PURE__ */ jsx5(CanvasImageBlock, { id, src, alt, editable, onSelect, onPropsChange });
506
+ return /* @__PURE__ */ jsx6(CanvasImageBlock, { id, src, alt, editable, onSelect, onPropsChange });
474
507
  }
475
508
  }, "core.image", resolveBlockPermissions),
476
509
  ...extensionComponents
@@ -519,7 +552,7 @@ function fromEngineData(data, base, registry) {
519
552
  }
520
553
 
521
554
  // src/editor/context/EditorContext.tsx
522
- import { createContext, useCallback, useContext, useEffect as useEffect2, useMemo, useReducer, useRef as useRef3, useState as useState2 } from "react";
555
+ import { createContext, useCallback, useContext, useEffect as useEffect2, useMemo, useReducer, useRef as useRef4, useState as useState2 } from "react";
523
556
 
524
557
  // src/editor/policy.ts
525
558
  function operationEnabled(operation, policy, blockPolicy) {
@@ -579,7 +612,7 @@ function canApplyCanvasDocument(previous, next, getDefinition, policy) {
579
612
  }
580
613
 
581
614
  // src/editor/context/EditorContext.tsx
582
- import { jsx as jsx6 } from "react/jsx-runtime";
615
+ import { jsx as jsx7 } from "react/jsx-runtime";
583
616
  function historyReducer(state, action) {
584
617
  if (action.type === "select") return { ...state, selectedBlockId: action.id };
585
618
  if (action.type === "device") return { ...state, device: action.device };
@@ -613,7 +646,7 @@ function defaultBlock(type, blocks, registry) {
613
646
  }
614
647
  function EditorProvider({ initialDocument, registry, policy, loadState = "ready", sessionState = "active", session, sessionMessage, leaveWarning = "You have unsaved changes.", onDocumentChange, children }) {
615
648
  const [history, dispatch] = useReducer(historyReducer, initialDocument, (document2) => ({ document: document2, selectedBlockId: document2.blocks[0]?.id ?? null, past: [], future: [], device: "desktop", savedDocument: document2 }));
616
- const historyRef = useRef3(history);
649
+ const historyRef = useRef4(history);
617
650
  useEffect2(() => {
618
651
  historyRef.current = history;
619
652
  }, [history]);
@@ -799,7 +832,7 @@ function EditorProvider({ initialDocument, registry, policy, loadState = "ready"
799
832
  markSaved: (document2 = historyRef.current.document) => dispatch({ type: "saved", document: document2 })
800
833
  };
801
834
  }, [canvasSelectionRequest, confirmCanvasSelection, editable, history, isDirty, loadState, pendingDeleteBlock, pendingDeleteBlockId, policy, registry, replace, requestCanvasSelection, selectedBlock, session, sessionMessage, sessionState, updateBlockPresentation, updateBlockProps, updateFromCanvas]);
802
- return /* @__PURE__ */ jsx6(EditorContext.Provider, { value, children });
835
+ return /* @__PURE__ */ jsx7(EditorContext.Provider, { value, children });
803
836
  }
804
837
  function useEditorContext() {
805
838
  const context = useContext(EditorContext);
@@ -809,16 +842,16 @@ function useEditorContext() {
809
842
 
810
843
  // src/editor/components/PageStatusCard.tsx
811
844
  import { Badge as Badge2, InlineStack as InlineStack2, Text as Text2 } from "@shopify/polaris";
812
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
845
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
813
846
  function PageStatusCard({ status, sessionState }) {
814
847
  const publicationTone = status.publicationStatus === "published" ? "success" : "attention";
815
848
  const sessionLabel = sessionState === "locked" ? `${status.editingBy ?? "\u5176\u4ED6\u4EBA"}\u6B63\u5728\u7F16\u8F91` : sessionState === "lost" ? "\u7F16\u8F91\u9501\u5DF2\u5931\u6548" : status.editingBy ? `${status.editingBy}\u6B63\u5728\u7F16\u8F91` : void 0;
816
849
  return /* @__PURE__ */ jsxs5("div", { className: "pb-page-status-card", "data-testid": "page-status-card", "data-publication-status": status.publicationStatus, "data-session-state": sessionState, children: [
817
850
  /* @__PURE__ */ jsxs5(InlineStack2, { gap: "150", blockAlign: "center", wrap: true, children: [
818
- /* @__PURE__ */ jsx7(Badge2, { tone: publicationTone, children: status.publicationStatus === "published" ? "\u7EBF\u4E0A" : "\u672A\u53D1\u5E03" }),
819
- status.draftLabel ? /* @__PURE__ */ jsx7(Text2, { as: "span", variant: "bodySm", tone: "subdued", children: status.draftLabel }) : null,
820
- status.publishedVersionLabel ? /* @__PURE__ */ jsx7(Text2, { as: "span", variant: "bodySm", tone: "subdued", children: status.publishedVersionLabel }) : null,
821
- sessionLabel ? /* @__PURE__ */ jsx7(Badge2, { tone: sessionState === "lost" ? "critical" : "attention", children: sessionLabel }) : null
851
+ /* @__PURE__ */ jsx8(Badge2, { tone: publicationTone, children: status.publicationStatus === "published" ? "\u7EBF\u4E0A" : "\u672A\u53D1\u5E03" }),
852
+ status.draftLabel ? /* @__PURE__ */ jsx8(Text2, { as: "span", variant: "bodySm", tone: "subdued", children: status.draftLabel }) : null,
853
+ status.publishedVersionLabel ? /* @__PURE__ */ jsx8(Text2, { as: "span", variant: "bodySm", tone: "subdued", children: status.publishedVersionLabel }) : null,
854
+ sessionLabel ? /* @__PURE__ */ jsx8(Badge2, { tone: sessionState === "lost" ? "critical" : "attention", children: sessionLabel }) : null
822
855
  ] }),
823
856
  status.lastSavedAt ? /* @__PURE__ */ jsxs5(Text2, { as: "p", variant: "bodySm", tone: "subdued", children: [
824
857
  "\u6700\u540E\u4FDD\u5B58\uFF1A",
@@ -966,7 +999,7 @@ function createAdminI18n(locale) {
966
999
  }
967
1000
 
968
1001
  // src/editor/shell/CanvasLibraryDropTarget.tsx
969
- import { useEffect as useEffect3, useRef as useRef4, useState as useState3 } from "react";
1002
+ import { useEffect as useEffect3, useRef as useRef5, useState as useState3 } from "react";
970
1003
 
971
1004
  // src/editor/shell/drop-position.ts
972
1005
  function nearestBlockIdAtY(blocks, y) {
@@ -997,7 +1030,7 @@ function beforeIdAfterPlacement(blockIds, targetId, placement) {
997
1030
  }
998
1031
 
999
1032
  // src/editor/shell/CanvasLibraryDropTarget.tsx
1000
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1033
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1001
1034
  function uniqueBlocks(blocks) {
1002
1035
  const seen = /* @__PURE__ */ new Set();
1003
1036
  return blocks.filter((block) => !seen.has(block.id) && seen.add(block.id));
@@ -1031,14 +1064,14 @@ function scrollElement(element, delta) {
1031
1064
  return true;
1032
1065
  }
1033
1066
  function CanvasLibraryDropTarget({ frameRef, blocks, label, onDrop, onCancel, adminLocale }) {
1034
- const targetRef = useRef4(null);
1035
- const latestPreview = useRef4(null);
1036
- const dragging = useRef4(false);
1037
- const completed = useRef4(false);
1038
- const pointerY = useRef4(0);
1039
- const animationFrame = useRef4(null);
1040
- const lastFrameTime = useRef4(null);
1041
- const callbacks = useRef4({ onDrop, onCancel });
1067
+ const targetRef = useRef5(null);
1068
+ const latestPreview = useRef5(null);
1069
+ const dragging = useRef5(false);
1070
+ const completed = useRef5(false);
1071
+ const pointerY = useRef5(0);
1072
+ const animationFrame = useRef5(null);
1073
+ const lastFrameTime = useRef5(null);
1074
+ const callbacks = useRef5({ onDrop, onCancel });
1042
1075
  useEffect3(() => {
1043
1076
  callbacks.current = { onDrop, onCancel };
1044
1077
  }, [onDrop, onCancel]);
@@ -1162,13 +1195,13 @@ function CanvasLibraryDropTarget({ frameRef, blocks, label, onDrop, onCancel, ad
1162
1195
  const style = { position: "absolute", inset: 0, zIndex: 2 };
1163
1196
  const markerLabel = english ? `Position ${position}` : `\u7B2C ${position} \u4E2A\u4F4D\u7F6E`;
1164
1197
  return /* @__PURE__ */ jsxs6("div", { ref: targetRef, className: "pb-canvas-drop-target", "data-testid": "canvas-drop-target", role: "region", "aria-label": english ? "Block drop area" : "\u533A\u5757\u6295\u653E\u533A", style, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [
1165
- /* @__PURE__ */ jsx8("span", { className: "pb-canvas-drop-target__hint", "aria-live": "polite", children: hint }),
1166
- preview ? /* @__PURE__ */ jsx8("span", { className: "pb-canvas-drop-marker", "aria-hidden": "true", style: { top: preview.markerTop, left: preview.markerLeft, width: preview.markerWidth }, children: /* @__PURE__ */ jsx8("span", { className: "pb-canvas-drop-marker__label", children: markerLabel }) }) : null
1198
+ /* @__PURE__ */ jsx9("span", { className: "pb-canvas-drop-target__hint", "aria-live": "polite", children: hint }),
1199
+ preview ? /* @__PURE__ */ jsx9("span", { className: "pb-canvas-drop-marker", "aria-hidden": "true", style: { top: preview.markerTop, left: preview.markerLeft, width: preview.markerWidth }, children: /* @__PURE__ */ jsx9("span", { className: "pb-canvas-drop-marker__label", children: markerLabel }) }) : null
1167
1200
  ] });
1168
1201
  }
1169
1202
 
1170
1203
  // src/editor/shell/PageDocumentEditorShell.tsx
1171
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1204
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1172
1205
  function scrollCanvasBlockIntoView(blockId, frame) {
1173
1206
  const selector = `[data-page-document-block-id="${CSS.escape(blockId)}"]`;
1174
1207
  const scroll = () => {
@@ -1191,6 +1224,13 @@ function blockTypeLabel(type, registry) {
1191
1224
  function validateDocumentBlocks(document2, registry) {
1192
1225
  return registry ? validatePageDocumentWithRegistry(document2, registry) : [];
1193
1226
  }
1227
+ function canvasZoomValue(zoom, autoZoom) {
1228
+ return zoom === "auto" ? autoZoom : Number(zoom) / 100;
1229
+ }
1230
+ function CanvasNativeZoom({ zoom, frameRef, className, dataDevice, canvasThemeStyle, children }) {
1231
+ const scale = canvasZoomValue(zoom, 1);
1232
+ return /* @__PURE__ */ jsx10("div", { ref: frameRef, className, "data-device": dataDevice, "data-zoom": zoom, "data-puck-zoom": scale, style: { ...canvasThemeStyle, transform: `scale(${scale})`, transformOrigin: "top center" }, children });
1233
+ }
1194
1234
  function useEditorSession(adapter, pageId) {
1195
1235
  const [managed, setManaged] = useState4(() => adapter ? { state: "acquiring" } : { state: "active" });
1196
1236
  useEffect4(() => {
@@ -1238,12 +1278,12 @@ function PageDocumentEditorShell(props) {
1238
1278
  useEffect4(() => {
1239
1279
  onSessionStateChange?.(managedSession.state);
1240
1280
  }, [managedSession.state, onSessionStateChange]);
1241
- return /* @__PURE__ */ jsx9(EditorProvider, { initialDocument: props.initialDocument, registry: props.registry, policy: props.policy, loadState: props.loadState, sessionState: managedSession.state, session: managedSession.session, sessionMessage: managedSession.message, leaveWarning: createAdminI18n(props.adminLocale).t("leaveWarning"), onDocumentChange: props.onDocumentChange, children: /* @__PURE__ */ jsx9(PageDocumentEditor, { ...props }) });
1281
+ return /* @__PURE__ */ jsx10(EditorProvider, { initialDocument: props.initialDocument, registry: props.registry, policy: props.policy, loadState: props.loadState, sessionState: managedSession.state, session: managedSession.session, sessionMessage: managedSession.message, leaveWarning: createAdminI18n(props.adminLocale).t("leaveWarning"), onDocumentChange: props.onDocumentChange, children: /* @__PURE__ */ jsx10(PageDocumentEditor, { ...props }) });
1242
1282
  }
1243
- function PageDocumentEditor({ iframe = false, registry, adminLocale, onSave, onPublish, draftPersistence, draftRevision: initialDraftRevision, autoSave = true, autoSaveDelayMs = 800, publishAction, assetPicker, inspectorSettings, productPicker, pageStatus, onBack, onHistory, onPreview, onAddToStore, deleteConfirmation, availableBlockTypes, appearanceControls = false }) {
1283
+ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPublish, draftPersistence, draftRevision: initialDraftRevision, autoSave = true, autoSaveDelayMs = 800, publishAction, assetPicker, inspectorSettings, productPicker, pageStatus, onBack, onHistory, onPreview, onAddToStore, deleteConfirmation, availableBlockTypes, appearanceControls = false }) {
1244
1284
  const editor = useEditorContext();
1245
- const editorRef = useRef5(editor);
1246
- useLayoutEffect(() => {
1285
+ const editorRef = useRef6(editor);
1286
+ useLayoutEffect2(() => {
1247
1287
  editorRef.current = editor;
1248
1288
  }, [editor]);
1249
1289
  const [blockView, setBlockView] = useState4("blocks");
@@ -1251,9 +1291,9 @@ function PageDocumentEditor({ iframe = false, registry, adminLocale, onSave, onP
1251
1291
  const [rightPanelOpen, setRightPanelOpen] = useState4(true);
1252
1292
  const [draggingLibraryType, setDraggingLibraryType] = useState4(null);
1253
1293
  const [draggingBlockId, setDraggingBlockId] = useState4(null);
1254
- const draggingBlockIdRef = useRef5(null);
1294
+ const draggingBlockIdRef = useRef6(null);
1255
1295
  const [dropTarget, setDropTarget] = useState4(null);
1256
- const canvasFrameRef = useRef5(null);
1296
+ const canvasFrameRef = useRef6(null);
1257
1297
  const [canvasMutationVersion, setCanvasMutationVersion] = useState4(0);
1258
1298
  const [canvasResetVersion, setCanvasResetVersion] = useState4(0);
1259
1299
  const [request, setRequest] = useState4("idle");
@@ -1341,8 +1381,8 @@ function PageDocumentEditor({ iframe = false, registry, adminLocale, onSave, onP
1341
1381
  setRequest("idle");
1342
1382
  }
1343
1383
  };
1344
- if (editor.loadState !== "ready" && editor.loadState !== "success") return /* @__PURE__ */ jsx9(EditorStatus, { state: editor.loadState });
1345
- if (editor.sessionState !== "active") return /* @__PURE__ */ jsx9(EditorSessionStatus, { state: editor.sessionState, message: editor.sessionMessage });
1384
+ if (editor.loadState !== "ready" && editor.loadState !== "success") return /* @__PURE__ */ jsx10(EditorStatus, { state: editor.loadState });
1385
+ if (editor.sessionState !== "active") return /* @__PURE__ */ jsx10(EditorSessionStatus, { state: editor.sessionState, message: editor.sessionMessage });
1346
1386
  const allBlockTypes = ["core.text", "core.image", ...registry?.blocks.map((block) => block.type) ?? []];
1347
1387
  const blockTypes = availableBlockTypes ? allBlockTypes.filter((type) => availableBlockTypes.includes(type)) : allBlockTypes;
1348
1388
  const orderedBlockTypes = libraryTypesInDocumentOrder(blockTypes, editor.document.blocks);
@@ -1376,57 +1416,57 @@ function PageDocumentEditor({ iframe = false, registry, adminLocale, onSave, onP
1376
1416
  };
1377
1417
  const dismissPublishedNotice = () => setNotice((current) => current === "published" ? null : current);
1378
1418
  return /* @__PURE__ */ jsxs7(Fragment2, { children: [
1379
- /* @__PURE__ */ jsx9(Puck2, { config, data: engineData, iframe: { enabled: iframe }, dnd: { behavior: "static" }, overrides: { actionBar: CanvasSelectionActionBar }, onChange: (data) => {
1419
+ /* @__PURE__ */ jsx10(Puck2, { config, data: engineData, iframe: { enabled: iframe }, dnd: { behavior: "static" }, overrides: { iframe: AdaptiveIframe, actionBar: CanvasSelectionActionBar }, onChange: (data) => {
1380
1420
  if (!editor.updateFromCanvas(fromEngineData(data, editor.document, registry))) setCanvasResetVersion((version) => version + 1);
1381
1421
  }, children: /* @__PURE__ */ jsxs7(Puck2.Layout, { children: [
1382
- /* @__PURE__ */ jsx9(CanvasSelectionBridge, { data: engineData, requestedBlockId: editor.canvasSelectionRequest, onCanvasSelected: confirmCanvasSelection, canvasMutationVersion, canvasResetVersion, permissionsVersion: `${editor.isEditable}:${editor.document.blocks.map((block) => `${block.id}:${block.type}`).join("|")}` }),
1422
+ /* @__PURE__ */ jsx10(CanvasSelectionBridge, { data: engineData, requestedBlockId: editor.canvasSelectionRequest, onCanvasSelected: confirmCanvasSelection, canvasMutationVersion, canvasResetVersion, permissionsVersion: `${editor.isEditable}:${editor.document.blocks.map((block) => `${block.id}:${block.type}`).join("|")}` }),
1383
1423
  /* @__PURE__ */ jsxs7("div", { className: "pb-shell pb-shell--v04", "data-testid": "page-document-editor", "data-page-id": editor.document.pageId, "data-dirty": editor.isDirty, "data-editor-state": editor.loadState, "data-editor-session-state": editor.sessionState, "data-save-state": resolvedSaveState, "data-left-panel": leftRailOpen ? "open" : "closed", "data-right-panel": rightPanelOpen ? "open" : "closed", children: [
1384
- /* @__PURE__ */ jsx9("header", { className: "pb-header", children: /* @__PURE__ */ jsxs7("div", { className: "pb-header-content", children: [
1424
+ /* @__PURE__ */ jsx10("header", { className: "pb-header", children: /* @__PURE__ */ jsxs7("div", { className: "pb-header-content", children: [
1385
1425
  /* @__PURE__ */ jsxs7("div", { className: "pb-header-title-group", children: [
1386
- onBack ? /* @__PURE__ */ jsx9(Button2, { variant: "tertiary", onClick: requestBack, children: i18n.t("back") }) : null,
1426
+ onBack ? /* @__PURE__ */ jsx10(Button2, { variant: "tertiary", onClick: requestBack, children: i18n.t("back") }) : null,
1387
1427
  /* @__PURE__ */ jsxs7("div", { className: "pb-page-title", children: [
1388
- /* @__PURE__ */ jsx9(Text3, { as: "h1", variant: "headingSm", children: editor.document.settings.seoTitle ?? editor.document.pageId }),
1389
- pageStatus ? /* @__PURE__ */ jsx9(PageStatusCard, { status: pageStatus, sessionState: editor.sessionState }) : null
1428
+ /* @__PURE__ */ jsx10(Text3, { as: "h1", variant: "headingSm", children: editor.document.settings.seoTitle ?? editor.document.pageId }),
1429
+ pageStatus ? /* @__PURE__ */ jsx10(PageStatusCard, { status: pageStatus, sessionState: editor.sessionState }) : null
1390
1430
  ] })
1391
1431
  ] }),
1392
- /* @__PURE__ */ jsx9("div", { className: "pb-header-controls", children: /* @__PURE__ */ jsxs7("div", { className: "pb-header-device-toolbar", children: [
1393
- /* @__PURE__ */ jsx9(ButtonGroup2, { variant: "segmented", children: Object.keys(deviceLabels2).map((device) => /* @__PURE__ */ jsx9(Button2, { pressed: editor.device === device, onClick: () => editor.setDevice(device), children: i18n.t(deviceLabels2[device]) }, device)) }),
1394
- /* @__PURE__ */ jsx9("div", { className: "pb-zoom-control", children: /* @__PURE__ */ jsx9(Select2, { label: i18n.t("zoom"), labelHidden: true, options: [{ label: i18n.t("zoomAuto"), value: "auto" }, { label: "50%", value: "50" }, { label: "70%", value: "70" }, { label: "100%", value: "100" }], value: zoom, onChange: (value) => setZoom(value) }) })
1432
+ /* @__PURE__ */ jsx10("div", { className: "pb-header-controls", children: /* @__PURE__ */ jsxs7("div", { className: "pb-header-device-toolbar", children: [
1433
+ /* @__PURE__ */ jsx10(ButtonGroup2, { variant: "segmented", children: Object.keys(deviceLabels2).map((device) => /* @__PURE__ */ jsx10(Button2, { pressed: editor.device === device, onClick: () => editor.setDevice(device), children: i18n.t(deviceLabels2[device]) }, device)) }),
1434
+ /* @__PURE__ */ jsx10("div", { className: "pb-zoom-control", children: /* @__PURE__ */ jsx10(Select2, { label: i18n.t("zoom"), labelHidden: true, options: [{ label: i18n.t("zoomAuto"), value: "auto" }, { label: "50%", value: "50" }, { label: "70%", value: "70" }, { label: "100%", value: "100" }], value: zoom, onChange: (value) => setZoom(value) }) })
1395
1435
  ] }) }),
1396
- /* @__PURE__ */ jsx9("div", { className: "pb-header-actions", children: /* @__PURE__ */ jsxs7(InlineStack3, { gap: "150", blockAlign: "center", wrap: true, children: [
1397
- /* @__PURE__ */ jsx9(Button2, { accessibilityLabel: i18n.t("undo"), icon: UndoIcon2, variant: "tertiary", disabled: !editor.actionState.canUndo, onClick: editor.undo }),
1398
- /* @__PURE__ */ jsx9(Button2, { accessibilityLabel: i18n.t("redo"), icon: RedoIcon2, variant: "tertiary", disabled: !editor.actionState.canRedo, onClick: editor.redo }),
1399
- resolvedSaveState === "saved" ? null : /* @__PURE__ */ jsx9(Badge3, { tone: saveBadgeTone, children: saveBadgeLabel }),
1400
- onHistory ? /* @__PURE__ */ jsx9("span", { "data-editor-history": "", children: /* @__PURE__ */ jsx9(Button2, { disabled: request !== "idle", onClick: () => onHistory({ document: editor.document, draftRevision, session: editor.session }), children: i18n.t("history") }) }) : null,
1401
- onPreview ? /* @__PURE__ */ jsx9(Button2, { disabled: request !== "idle" || !isOnline, onClick: () => void onPreview({ document: editor.document, draftRevision, session: editor.session }), children: i18n.t("preview") }) : null,
1402
- onAddToStore ? /* @__PURE__ */ jsx9(Button2, { disabled: request !== "idle" || pageStatus?.publicationStatus === "unpublished", onClick: () => void onAddToStore({ document: editor.document, session: editor.session }), children: i18n.t("addToStore") }) : null,
1403
- /* @__PURE__ */ jsx9(Button2, { variant: "primary", disabled: !publishAction && !onPublish || request !== "idle" || validationIssues.length > 0 || !isOnline, onClick: () => void publish(), children: request === "publishing" ? i18n.t("publishing") : i18n.t("publish") })
1436
+ /* @__PURE__ */ jsx10("div", { className: "pb-header-actions", children: /* @__PURE__ */ jsxs7(InlineStack3, { gap: "150", blockAlign: "center", wrap: true, children: [
1437
+ /* @__PURE__ */ jsx10(Button2, { accessibilityLabel: i18n.t("undo"), icon: UndoIcon2, variant: "tertiary", disabled: !editor.actionState.canUndo, onClick: editor.undo }),
1438
+ /* @__PURE__ */ jsx10(Button2, { accessibilityLabel: i18n.t("redo"), icon: RedoIcon2, variant: "tertiary", disabled: !editor.actionState.canRedo, onClick: editor.redo }),
1439
+ resolvedSaveState === "saved" ? null : /* @__PURE__ */ jsx10(Badge3, { tone: saveBadgeTone, children: saveBadgeLabel }),
1440
+ onHistory ? /* @__PURE__ */ jsx10("span", { "data-editor-history": "", children: /* @__PURE__ */ jsx10(Button2, { disabled: request !== "idle", onClick: () => onHistory({ document: editor.document, draftRevision, session: editor.session }), children: i18n.t("history") }) }) : null,
1441
+ onPreview ? /* @__PURE__ */ jsx10(Button2, { disabled: request !== "idle" || !isOnline, onClick: () => void onPreview({ document: editor.document, draftRevision, session: editor.session }), children: i18n.t("preview") }) : null,
1442
+ onAddToStore ? /* @__PURE__ */ jsx10(Button2, { disabled: request !== "idle" || pageStatus?.publicationStatus === "unpublished", onClick: () => void onAddToStore({ document: editor.document, session: editor.session }), children: i18n.t("addToStore") }) : null,
1443
+ /* @__PURE__ */ jsx10(Button2, { variant: "primary", disabled: !publishAction && !onPublish || request !== "idle" || validationIssues.length > 0 || !isOnline, onClick: () => void publish(), children: request === "publishing" ? i18n.t("publishing") : i18n.t("publish") })
1404
1444
  ] }) })
1405
1445
  ] }) }),
1406
- editor.loadState === "success" ? /* @__PURE__ */ jsx9(Banner, { tone: "success", children: i18n.t("success") }) : null,
1407
- notice && notice !== "published" ? /* @__PURE__ */ jsx9("div", { className: `pb-editor-notice pb-editor-notice--${notice}`, "data-testid": "editor-notice", "data-notice": notice, children: /* @__PURE__ */ jsx9(Banner, { tone: "critical", children: i18n.t(notice) }) }) : null,
1408
- validationIssues.length > 0 ? /* @__PURE__ */ jsx9(Banner, { tone: "critical", title: "\u533A\u5757\u5C5E\u6027\u672A\u901A\u8FC7\u6821\u9A8C", children: /* @__PURE__ */ jsx9("ul", { children: validationIssues.map((issue) => /* @__PURE__ */ jsxs7("li", { children: [
1446
+ editor.loadState === "success" ? /* @__PURE__ */ jsx10(Banner, { tone: "success", children: i18n.t("success") }) : null,
1447
+ notice && notice !== "published" ? /* @__PURE__ */ jsx10("div", { className: `pb-editor-notice pb-editor-notice--${notice}`, "data-testid": "editor-notice", "data-notice": notice, children: /* @__PURE__ */ jsx10(Banner, { tone: "critical", children: i18n.t(notice) }) }) : null,
1448
+ validationIssues.length > 0 ? /* @__PURE__ */ jsx10(Banner, { tone: "critical", title: "\u533A\u5757\u5C5E\u6027\u672A\u901A\u8FC7\u6821\u9A8C", children: /* @__PURE__ */ jsx10("ul", { children: validationIssues.map((issue) => /* @__PURE__ */ jsxs7("li", { children: [
1409
1449
  issue.path,
1410
1450
  ": ",
1411
1451
  issue.message
1412
1452
  ] }, `${issue.path}-${issue.message}`)) }) }) : null,
1413
1453
  /* @__PURE__ */ jsxs7("div", { className: `pb-workspace pb-workspace--document${leftRailOpen ? "" : " pb-workspace--left-closed"}${rightPanelOpen ? "" : " pb-workspace--right-closed"}`, "data-left-panel": leftRailOpen ? "open" : "closed", "data-right-panel": rightPanelOpen ? "open" : "closed", children: [
1414
1454
  /* @__PURE__ */ jsxs7("nav", { className: "pb-tool-rail", "aria-label": "\u7F16\u8F91\u5668\u5DE5\u5177", children: [
1415
- /* @__PURE__ */ jsx9(Button2, { accessibilityLabel: i18n.t("blocks"), icon: LayoutSectionIcon2, pressed: blockView === "blocks" && leftRailOpen, variant: "tertiary", onClick: () => {
1455
+ /* @__PURE__ */ jsx10(Button2, { accessibilityLabel: i18n.t("blocks"), icon: LayoutSectionIcon2, pressed: blockView === "blocks" && leftRailOpen, variant: "tertiary", onClick: () => {
1416
1456
  setBlockView("blocks");
1417
1457
  setLeftRailOpen(true);
1418
1458
  } }),
1419
- /* @__PURE__ */ jsx9(Button2, { accessibilityLabel: i18n.t("outline"), icon: MenuIcon2, pressed: blockView === "outline" && leftRailOpen, variant: "tertiary", onClick: () => {
1459
+ /* @__PURE__ */ jsx10(Button2, { accessibilityLabel: i18n.t("outline"), icon: MenuIcon2, pressed: blockView === "outline" && leftRailOpen, variant: "tertiary", onClick: () => {
1420
1460
  setBlockView("outline");
1421
1461
  setLeftRailOpen(true);
1422
1462
  } })
1423
1463
  ] }),
1424
1464
  /* @__PURE__ */ jsxs7("aside", { className: `pb-left-panel${leftRailOpen ? "" : " pb-panel--closed"}`, "aria-label": "PageDocument \u533A\u5757", children: [
1425
- /* @__PURE__ */ jsxs7(InlineStack3, { align: "space-between", blockAlign: "center", children: [
1426
- /* @__PURE__ */ jsx9(Text3, { as: "h2", variant: "headingSm", children: blockView === "blocks" ? i18n.t("blocks") : i18n.t("outline") }),
1427
- /* @__PURE__ */ jsx9(Button2, { accessibilityLabel: i18n.t("collapseLeft"), icon: XIcon2, variant: "tertiary", onClick: () => setLeftRailOpen(false) })
1428
- ] }),
1429
- blockView === "blocks" ? /* @__PURE__ */ jsx9("div", { className: "pb-block-list", "data-testid": "blocks-view", "aria-label": "\u533A\u5757\u7C7B\u578B\u5E93", role: "list", onDrop: cancelLibraryDrop, children: orderedBlockTypes.map((type) => {
1465
+ /* @__PURE__ */ jsx10("div", { className: "pb-panel-header", children: /* @__PURE__ */ jsxs7(InlineStack3, { align: "space-between", blockAlign: "center", wrap: false, children: [
1466
+ /* @__PURE__ */ jsx10(Text3, { as: "h2", variant: "headingSm", children: blockView === "blocks" ? i18n.t("blocks") : i18n.t("outline") }),
1467
+ /* @__PURE__ */ jsx10(Button2, { accessibilityLabel: i18n.t("collapseLeft"), icon: XIcon2, variant: "tertiary", onClick: () => setLeftRailOpen(false) })
1468
+ ] }) }),
1469
+ blockView === "blocks" ? /* @__PURE__ */ jsx10("div", { className: "pb-block-list", "data-testid": "blocks-view", "aria-label": "\u533A\u5757\u7C7B\u578B\u5E93", role: "list", onDrop: cancelLibraryDrop, children: orderedBlockTypes.map((type) => {
1430
1470
  const instance = editor.document.blocks.find((item) => item.type === type);
1431
1471
  const canAdd = editor.canAddBlock(type);
1432
1472
  const canReorder = Boolean(instance && editor.canDragBlock(instance.id));
@@ -1434,11 +1474,17 @@ function PageDocumentEditor({ iframe = false, registry, adminLocale, onSave, onP
1434
1474
  const selected = editor.selectedBlock?.type === type;
1435
1475
  const dropEdge = draggingBlockId && instance && dropTarget?.id === instance.id ? dropTarget.edge : void 0;
1436
1476
  const actionHint = canReorder && canAdd ? "\uFF0C\u62D6\u62FD\u6392\u5E8F\uFF0C\u6216\u62D6\u62FD\u81F3\u753B\u5E03\u4EE5\u6DFB\u52A0" : canReorder ? "\uFF0C\u62D6\u62FD\u6392\u5E8F" : canAdd ? "\uFF0C\u62D6\u62FD\u81F3\u753B\u5E03\u4EE5\u6DFB\u52A0" : "";
1437
- return /* @__PURE__ */ jsxs7("div", { className: `pb-document-block-row pb-document-block-row--library${selected ? " pb-document-block-row--selected" : ""}${draggingBlockId === instance?.id ? " pb-document-block-row--dragging" : ""}${dropEdge === "before" ? " pb-document-block-row--drop-before" : ""}${dropEdge === "after" ? " pb-document-block-row--drop-after" : ""}`, "data-block-type": type, "data-selected": selected, "data-drop-edge": dropEdge, role: "listitem", draggable, "aria-disabled": !draggable, "aria-label": `${blockTypeLabel(type, registry)}${actionHint}${selected ? "\uFF0C\u5F53\u524D\u9009\u4E2D\u7C7B\u578B" : ""}`, onClick: () => {
1477
+ const canDelete = Boolean(instance && editor.canDeleteBlock(instance.id));
1478
+ const label = blockTypeLabel(type, registry);
1479
+ return /* @__PURE__ */ jsxs7("div", { className: `pb-document-block-row pb-document-block-row--library${selected ? " pb-document-block-row--selected" : ""}${draggingBlockId === instance?.id ? " pb-document-block-row--dragging" : ""}${dropEdge === "before" ? " pb-document-block-row--drop-before" : ""}${dropEdge === "after" ? " pb-document-block-row--drop-after" : ""}`, "data-block-type": type, "data-selected": selected, "data-drop-edge": dropEdge, role: "listitem", draggable, "aria-disabled": !draggable, "aria-label": `${label}${actionHint}${selected ? "\uFF0C\u5F53\u524D\u9009\u4E2D\u7C7B\u578B" : ""}`, onClick: () => {
1438
1480
  if (!instance) return;
1439
1481
  editor.requestCanvasSelection(instance.id);
1440
1482
  scrollCanvasBlockIntoView(instance.id, canvasFrameRef.current);
1441
1483
  }, onDragStart: (event) => {
1484
+ if (event.target.closest("button")) {
1485
+ event.preventDefault();
1486
+ return;
1487
+ }
1442
1488
  if (!draggable) {
1443
1489
  event.preventDefault();
1444
1490
  return;
@@ -1471,65 +1517,73 @@ function PageDocumentEditor({ iframe = false, registry, adminLocale, onSave, onP
1471
1517
  clearLibraryDrag();
1472
1518
  }, onDragEnd: clearLibraryDrag, children: [
1473
1519
  /* @__PURE__ */ jsxs7("span", { className: "pb-library-block-title", children: [
1474
- /* @__PURE__ */ jsx9(Text3, { as: "span", variant: "bodySm", fontWeight: "semibold", children: blockTypeLabel(type, registry) }),
1475
- /* @__PURE__ */ jsx9("span", { className: "pb-library-block-drag-hint", "aria-hidden": "true", children: /* @__PURE__ */ jsx9(DragHandleIcon2, {}) })
1520
+ /* @__PURE__ */ jsx10(Text3, { as: "span", variant: "bodySm", fontWeight: "semibold", children: label }),
1521
+ /* @__PURE__ */ jsxs7("span", { className: "pb-library-block-controls", children: [
1522
+ /* @__PURE__ */ jsx10("span", { className: "pb-library-block-drag-hint", "aria-hidden": "true", children: /* @__PURE__ */ jsx10(DragHandleIcon2, {}) }),
1523
+ /* @__PURE__ */ jsx10("span", { draggable: false, onClick: (event) => event.stopPropagation(), onPointerDown: (event) => event.stopPropagation(), onDragStart: (event) => {
1524
+ event.preventDefault();
1525
+ event.stopPropagation();
1526
+ }, children: /* @__PURE__ */ jsx10(Button2, { icon: DeleteIcon2, variant: "tertiary", tone: canDelete ? "critical" : void 0, disabled: !canDelete, accessibilityLabel: `${i18n.t("remove")} ${label}`, onClick: () => {
1527
+ if (instance) editor.requestDeleteBlock(instance.id);
1528
+ } }) })
1529
+ ] })
1476
1530
  ] }),
1477
- /* @__PURE__ */ jsx9(Text3, { as: "span", variant: "bodySm", tone: "subdued", children: type })
1531
+ /* @__PURE__ */ jsx10(Text3, { as: "span", variant: "bodySm", tone: "subdued", children: type })
1478
1532
  ] }, type);
1479
- }) }) : editor.document.blocks.length === 0 ? /* @__PURE__ */ jsx9(Text3, { as: "p", tone: "subdued", children: i18n.t("empty") }) : /* @__PURE__ */ jsx9("div", { className: "pb-block-list", "data-testid": "outline-view", children: editor.document.blocks.map((block) => /* @__PURE__ */ jsxs7("button", { type: "button", className: `pb-document-block-row pb-document-block-row--library ${block.id === editor.selectedBlockId ? "pb-document-block-row--selected" : ""}`, "aria-pressed": block.id === editor.selectedBlockId, onClick: () => {
1533
+ }) }) : editor.document.blocks.length === 0 ? /* @__PURE__ */ jsx10(Text3, { as: "p", tone: "subdued", children: i18n.t("empty") }) : /* @__PURE__ */ jsx10("div", { className: "pb-block-list", "data-testid": "outline-view", children: editor.document.blocks.map((block) => /* @__PURE__ */ jsxs7("button", { type: "button", className: `pb-document-block-row pb-document-block-row--library ${block.id === editor.selectedBlockId ? "pb-document-block-row--selected" : ""}`, "aria-pressed": block.id === editor.selectedBlockId, onClick: () => {
1480
1534
  editor.requestCanvasSelection(block.id);
1481
1535
  scrollCanvasBlockIntoView(block.id, canvasFrameRef.current);
1482
1536
  }, children: [
1483
- /* @__PURE__ */ jsx9(Text3, { as: "span", variant: "bodySm", fontWeight: "semibold", children: blockLabel(block, registry) }),
1484
- /* @__PURE__ */ jsx9(Text3, { as: "span", variant: "bodySm", tone: "subdued", children: block.id })
1537
+ /* @__PURE__ */ jsx10(Text3, { as: "span", variant: "bodySm", fontWeight: "semibold", children: blockLabel(block, registry) }),
1538
+ /* @__PURE__ */ jsx10(Text3, { as: "span", variant: "bodySm", tone: "subdued", children: block.id })
1485
1539
  ] }, block.id)) })
1486
1540
  ] }),
1487
1541
  /* @__PURE__ */ jsxs7("main", { className: "pb-canvas-area", children: [
1488
- /* @__PURE__ */ jsxs7("div", { className: "pb-canvas-stage", children: [
1489
- /* @__PURE__ */ jsx9("div", { ref: canvasFrameRef, className: `pb-canvas-frame pb-canvas-frame--${editor.device}${zoom === "auto" ? "" : ` pb-canvas-frame--zoom-${zoom}`}`, "data-device": editor.device, "data-zoom": zoom, style: canvasThemeStyle, children: /* @__PURE__ */ jsx9(Puck2.Preview, {}) }),
1490
- draggingLibraryType ? /* @__PURE__ */ jsx9(CanvasLibraryDropTarget, { frameRef: canvasFrameRef, blocks: editor.document.blocks.map((block) => ({ id: block.id, label: blockLabel(block, registry) })), label: blockTypeLabel(draggingLibraryType, registry), adminLocale, onDrop: (beforeId) => {
1542
+ /* @__PURE__ */ jsx10("div", { className: "pb-canvas-stage", children: /* @__PURE__ */ jsxs7(CanvasNativeZoom, { frameRef: canvasFrameRef, className: `pb-canvas-frame pb-canvas-frame--${editor.device}${zoom === "auto" ? "" : ` pb-canvas-frame--zoom-${zoom}`}`, dataDevice: editor.device, canvasThemeStyle, zoom, children: [
1543
+ /* @__PURE__ */ jsx10(Puck2.Preview, {}),
1544
+ draggingLibraryType ? /* @__PURE__ */ jsx10(CanvasLibraryDropTarget, { frameRef: canvasFrameRef, blocks: editor.document.blocks.map((block) => ({ id: block.id, label: blockLabel(block, registry) })), label: blockTypeLabel(draggingLibraryType, registry), adminLocale, onDrop: (beforeId) => {
1491
1545
  addFromLibrary(draggingLibraryType, beforeId);
1492
1546
  setDraggingLibraryType(null);
1493
1547
  }, onCancel: () => setDraggingLibraryType(null) }) : null
1494
- ] }),
1548
+ ] }) }),
1495
1549
  !leftRailOpen || !rightPanelOpen ? /* @__PURE__ */ jsxs7("div", { className: "pb-collapsed-actions", children: [
1496
- !leftRailOpen ? /* @__PURE__ */ jsx9(Button2, { onClick: () => setLeftRailOpen(true), children: i18n.t("expandLeft") }) : null,
1497
- !rightPanelOpen ? /* @__PURE__ */ jsx9(Button2, { onClick: () => setRightPanelOpen(true), children: i18n.t("expandRight") }) : null
1550
+ !leftRailOpen ? /* @__PURE__ */ jsx10(Button2, { onClick: () => setLeftRailOpen(true), children: i18n.t("expandLeft") }) : null,
1551
+ !rightPanelOpen ? /* @__PURE__ */ jsx10(Button2, { onClick: () => setRightPanelOpen(true), children: i18n.t("expandRight") }) : null
1498
1552
  ] }) : null
1499
1553
  ] }),
1500
1554
  /* @__PURE__ */ jsxs7("aside", { className: `pb-right-panel${rightPanelOpen ? "" : " pb-panel--closed"}`, "aria-label": "PageDocument \u5C5E\u6027", children: [
1501
1555
  /* @__PURE__ */ jsxs7(InlineStack3, { align: "space-between", blockAlign: "center", children: [
1502
- /* @__PURE__ */ jsx9(Text3, { as: "h2", variant: "headingSm", children: i18n.t("properties") }),
1503
- /* @__PURE__ */ jsx9(Button2, { accessibilityLabel: i18n.t("collapseRight"), icon: XIcon2, variant: "tertiary", onClick: () => setRightPanelOpen(false) })
1556
+ /* @__PURE__ */ jsx10(Text3, { as: "h2", variant: "headingSm", children: i18n.t("properties") }),
1557
+ /* @__PURE__ */ jsx10(Button2, { accessibilityLabel: i18n.t("collapseRight"), icon: XIcon2, variant: "tertiary", onClick: () => setRightPanelOpen(false) })
1504
1558
  ] }),
1505
1559
  editor.selectedBlock ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
1506
- /* @__PURE__ */ jsx9(DocumentInspector, { settings: inspectorSettings?.[editor.selectedBlock.id] ?? inspectorSettings?.[editor.selectedBlock.type], pageId: editor.document.pageId, assetPicker, productPicker, i18n, block: editor.selectedBlock, registry, disabled: !editor.actionState.canEdit, appearanceControls, onChange: (props) => editor.updateBlockProps(editor.selectedBlock.id, props), onPresentationChange: (presentation) => updateBlockPresentation(editor.selectedBlock.id, presentation) }, editor.selectedBlock.id),
1507
- /* @__PURE__ */ jsx9(InspectorActions, { block: editor.selectedBlock, canDuplicate: editor.actionState.canDuplicate, canDelete: editor.actionState.canDelete, canMove: editor.actionState.canReorder, canMoveUp: editor.document.blocks[0]?.id !== editor.selectedBlock.id, canMoveDown: editor.document.blocks.at(-1)?.id !== editor.selectedBlock.id, i18n, onDuplicate: () => editor.duplicateBlock(editor.selectedBlock.id), onDelete: () => editor.requestDeleteBlock(editor.selectedBlock.id), onMove: (direction) => editor.moveBlock(editor.selectedBlock.id, direction) })
1508
- ] }) : /* @__PURE__ */ jsx9(Text3, { as: "p", tone: "subdued", children: i18n.t("selectBlock") })
1560
+ /* @__PURE__ */ jsx10(DocumentInspector, { settings: inspectorSettings?.[editor.selectedBlock.id] ?? inspectorSettings?.[editor.selectedBlock.type], pageId: editor.document.pageId, assetPicker, productPicker, i18n, block: editor.selectedBlock, registry, disabled: !editor.actionState.canEdit, appearanceControls, onChange: (props) => editor.updateBlockProps(editor.selectedBlock.id, props), onPresentationChange: (presentation) => updateBlockPresentation(editor.selectedBlock.id, presentation) }, editor.selectedBlock.id),
1561
+ /* @__PURE__ */ jsx10(InspectorActions, { block: editor.selectedBlock, canDuplicate: editor.actionState.canDuplicate, canDelete: editor.actionState.canDelete, canMove: editor.actionState.canReorder, canMoveUp: editor.document.blocks[0]?.id !== editor.selectedBlock.id, canMoveDown: editor.document.blocks.at(-1)?.id !== editor.selectedBlock.id, i18n, onDuplicate: () => editor.duplicateBlock(editor.selectedBlock.id), onDelete: () => editor.requestDeleteBlock(editor.selectedBlock.id), onMove: (direction) => editor.moveBlock(editor.selectedBlock.id, direction) })
1562
+ ] }) : /* @__PURE__ */ jsx10(Text3, { as: "p", tone: "subdued", children: i18n.t("selectBlock") })
1509
1563
  ] })
1510
1564
  ] }),
1511
- editor.pendingDeleteBlock ? /* @__PURE__ */ jsx9(DeleteConfirmation, { block: editor.pendingDeleteBlock, config: deleteConfirmation, i18n, onCancel: editor.cancelDeleteBlock, onConfirm: editor.confirmDeleteBlock }) : null,
1512
- confirmBack ? /* @__PURE__ */ jsx9(LeaveConfirmation, { i18n, onCancel: () => setConfirmBack(false), onConfirm: () => {
1565
+ editor.pendingDeleteBlock ? /* @__PURE__ */ jsx10(DeleteConfirmation, { block: editor.pendingDeleteBlock, config: deleteConfirmation, i18n, onCancel: editor.cancelDeleteBlock, onConfirm: editor.confirmDeleteBlock }) : null,
1566
+ confirmBack ? /* @__PURE__ */ jsx10(LeaveConfirmation, { i18n, onCancel: () => setConfirmBack(false), onConfirm: () => {
1513
1567
  setConfirmBack(false);
1514
1568
  onBack?.();
1515
1569
  } }) : null
1516
1570
  ] })
1517
1571
  ] }) }),
1518
- /* @__PURE__ */ jsx9("div", { className: "pb-toast-host", ...notice === "published" ? { "data-testid": "editor-notice", "data-notice": "published" } : {}, children: /* @__PURE__ */ jsx9(Frame, { children: notice === "published" ? /* @__PURE__ */ jsx9(Toast, { content: i18n.t("publishSuccessTitle"), onDismiss: dismissPublishedNotice }) : null }) })
1572
+ /* @__PURE__ */ jsx10("div", { className: "pb-toast-host", ...notice === "published" ? { "data-testid": "editor-notice", "data-notice": "published" } : {}, children: /* @__PURE__ */ jsx10(Frame, { children: notice === "published" ? /* @__PURE__ */ jsx10(Toast, { content: i18n.t("publishSuccessTitle"), onDismiss: dismissPublishedNotice }) : null }) })
1519
1573
  ] });
1520
1574
  }
1521
1575
  function CanvasSelectionActionBar({ label, children, parentAction }) {
1522
1576
  void label;
1523
1577
  void children;
1524
1578
  void parentAction;
1525
- return /* @__PURE__ */ jsx9(Fragment2, {});
1579
+ return /* @__PURE__ */ jsx10(Fragment2, {});
1526
1580
  }
1527
1581
  function CanvasSelectionBridge({ data, requestedBlockId, onCanvasSelected, canvasMutationVersion, canvasResetVersion, permissionsVersion }) {
1528
1582
  const puck = usePuck();
1529
- const lastSelectedId = useRef5(null);
1530
- const lastSyncedData = useRef5(null);
1531
- const lastCanvasMutationVersion = useRef5(0);
1532
- const lastCanvasResetVersion = useRef5(0);
1583
+ const lastSelectedId = useRef6(null);
1584
+ const lastSyncedData = useRef6(null);
1585
+ const lastCanvasMutationVersion = useRef6(0);
1586
+ const lastCanvasResetVersion = useRef6(0);
1533
1587
  const serializedData = JSON.stringify(data);
1534
1588
  const refreshPermissions = puck.refreshPermissions;
1535
1589
  useEffect4(() => {
@@ -1565,28 +1619,28 @@ function EditorStatus({ state }) {
1565
1619
  const i18n = createAdminI18n();
1566
1620
  const tone = state === "error" ? "critical" : state === "disabled" ? "warning" : "info";
1567
1621
  const message = state === "loading" ? i18n.t("loading") : state === "empty" ? i18n.t("empty") : state === "error" ? i18n.t("error") : i18n.t("disabled");
1568
- return /* @__PURE__ */ jsx9("div", { className: "pb-editor-status", "data-testid": "page-document-editor-state", "data-editor-state": state, children: /* @__PURE__ */ jsx9(Banner, { tone, title: message, children: state === "disabled" ? i18n.t("disabled") : message }) });
1622
+ return /* @__PURE__ */ jsx10("div", { className: "pb-editor-status", "data-testid": "page-document-editor-state", "data-editor-state": state, children: /* @__PURE__ */ jsx10(Banner, { tone, title: message, children: state === "disabled" ? i18n.t("disabled") : message }) });
1569
1623
  }
1570
1624
  function EditorSessionStatus({ state, message }) {
1571
1625
  const i18n = createAdminI18n();
1572
1626
  const tone = state === "locked" ? "warning" : state === "readonly" ? "info" : "critical";
1573
1627
  const title = state === "acquiring" ? i18n.t("acquiringLock") : state === "locked" ? i18n.t("locked") : state === "readonly" ? i18n.t("readonly") : i18n.t("lockLost");
1574
- return /* @__PURE__ */ jsx9("div", { className: "pb-editor-status", "data-testid": "page-document-editor-session-state", "data-editor-session-state": state, children: /* @__PURE__ */ jsx9(Banner, { tone, title, children: message ?? title }) });
1628
+ return /* @__PURE__ */ jsx10("div", { className: "pb-editor-status", "data-testid": "page-document-editor-session-state", "data-editor-session-state": state, children: /* @__PURE__ */ jsx10(Banner, { tone, title, children: message ?? title }) });
1575
1629
  }
1576
1630
  function InspectorSection({ title, children, defaultOpen = true }) {
1577
1631
  return /* @__PURE__ */ jsxs7("details", { className: "pb-inspector-section", open: defaultOpen, children: [
1578
1632
  /* @__PURE__ */ jsxs7("summary", { children: [
1579
- /* @__PURE__ */ jsx9("span", { children: title }),
1580
- /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: "\u2304" })
1633
+ /* @__PURE__ */ jsx10("span", { children: title }),
1634
+ /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", children: "\u2304" })
1581
1635
  ] }),
1582
- /* @__PURE__ */ jsx9("div", { className: "pb-inspector-section__body", children })
1636
+ /* @__PURE__ */ jsx10("div", { className: "pb-inspector-section__body", children })
1583
1637
  ] });
1584
1638
  }
1585
1639
  function InspectorTextControl({ label, value, control, maxLength, disabled, onChange }) {
1586
1640
  const stringValue = typeof value === "string" ? value : "";
1587
- if (control === "color") return /* @__PURE__ */ jsx9("input", { "aria-label": label, type: "color", value: /^#[\da-f]{6}$/i.test(stringValue) ? stringValue : "#000000", disabled, onChange: (event) => onChange(event.currentTarget.value) });
1641
+ if (control === "color") return /* @__PURE__ */ jsx10("input", { "aria-label": label, type: "color", value: /^#[\da-f]{6}$/i.test(stringValue) ? stringValue : "#000000", disabled, onChange: (event) => onChange(event.currentTarget.value) });
1588
1642
  const length = Array.from(stringValue).length;
1589
- const field = /* @__PURE__ */ jsx9(TextField, { label, labelHidden: true, value: stringValue, onChange: (next) => onChange(maxLength === void 0 ? next : Array.from(next).slice(0, maxLength).join("")), autoComplete: "off", disabled, multiline: control === "textarea" ? 4 : false, type: control === "url" ? "url" : "text", maxLength });
1643
+ const field = /* @__PURE__ */ jsx10(TextField, { label, labelHidden: true, value: stringValue, onChange: (next) => onChange(maxLength === void 0 ? next : Array.from(next).slice(0, maxLength).join("")), autoComplete: "off", disabled, multiline: control === "textarea" ? 4 : false, type: control === "url" ? "url" : "text", maxLength });
1590
1644
  if (maxLength === void 0) return field;
1591
1645
  return /* @__PURE__ */ jsxs7("div", { className: "pb-inspector-field__limited", children: [
1592
1646
  field,
@@ -1600,7 +1654,7 @@ function InspectorTextControl({ label, value, control, maxLength, disabled, onCh
1600
1654
  function InspectorAssetControl({ value, disabled, picker, pageId, blockId, i18n, onChange }) {
1601
1655
  const [busy, setBusy] = useState4(false);
1602
1656
  const [error, setError] = useState4(null);
1603
- const active = useRef5(true);
1657
+ const active = useRef6(true);
1604
1658
  useEffect4(() => {
1605
1659
  active.current = !disabled;
1606
1660
  return () => {
@@ -1609,9 +1663,9 @@ function InspectorAssetControl({ value, disabled, picker, pageId, blockId, i18n,
1609
1663
  }, [disabled]);
1610
1664
  const url = typeof value === "string" && validateFieldValue({ field: "", control: "asset" }, value).length === 0 ? value : "";
1611
1665
  return /* @__PURE__ */ jsxs7("div", { className: "pb-asset-picker", "data-testid": "asset-picker", children: [
1612
- url ? /* @__PURE__ */ jsx9("img", { src: url, alt: "", className: "pb-asset-picker__preview" }) : /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: i18n.t("emptyAsset") }),
1613
- url ? /* @__PURE__ */ jsx9(Button2, { fullWidth: true, variant: "tertiary", disabled: disabled || busy, onClick: () => onChange(""), children: i18n.t("removeAsset") }) : null,
1614
- /* @__PURE__ */ jsx9(Button2, { fullWidth: true, disabled: disabled || busy || !picker, onClick: () => void (async () => {
1666
+ url ? /* @__PURE__ */ jsx10("img", { src: url, alt: "", className: "pb-asset-picker__preview" }) : /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: i18n.t("emptyAsset") }),
1667
+ url ? /* @__PURE__ */ jsx10(Button2, { fullWidth: true, variant: "tertiary", disabled: disabled || busy, onClick: () => onChange(""), children: i18n.t("removeAsset") }) : null,
1668
+ /* @__PURE__ */ jsx10(Button2, { fullWidth: true, disabled: disabled || busy || !picker, onClick: () => void (async () => {
1615
1669
  if (!picker) return;
1616
1670
  setBusy(true);
1617
1671
  setError(null);
@@ -1627,7 +1681,7 @@ function InspectorAssetControl({ value, disabled, picker, pageId, blockId, i18n,
1627
1681
  setBusy(false);
1628
1682
  }
1629
1683
  })(), children: busy ? i18n.t("selectingAsset") : i18n.t("selectAsset") }),
1630
- error ? /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "critical", children: error }) : null
1684
+ error ? /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "critical", children: error }) : null
1631
1685
  ] });
1632
1686
  }
1633
1687
  function InspectorProductsControl({ value, disabled, picker, pageId, blockId, i18n, onChange }) {
@@ -1637,10 +1691,10 @@ function InspectorProductsControl({ value, disabled, picker, pageId, blockId, i1
1637
1691
  const preview = products.slice(0, 4);
1638
1692
  return /* @__PURE__ */ jsxs7("div", { className: "pb-product-picker", "data-testid": "product-picker", children: [
1639
1693
  /* @__PURE__ */ jsxs7("div", { className: "pb-product-picker__summary", children: [
1640
- preview.length ? /* @__PURE__ */ jsx9("span", { className: "pb-product-picker__thumbs", "aria-hidden": "true", children: preview.map((product, index) => /* @__PURE__ */ jsx9("span", { className: "pb-product-picker__thumb", style: { zIndex: preview.length - index }, children: product.imageUrl ? /* @__PURE__ */ jsx9("img", { src: product.imageUrl, alt: "" }) : /* @__PURE__ */ jsx9("span", { className: "pb-product-picker__thumb-fallback" }) }, product.id)) }) : null,
1641
- /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", children: products.length ? `${products.length} ${i18n.t("productCountSuffix")}` : i18n.t("emptyProducts") })
1694
+ preview.length ? /* @__PURE__ */ jsx10("span", { className: "pb-product-picker__thumbs", "aria-hidden": "true", children: preview.map((product, index) => /* @__PURE__ */ jsx10("span", { className: "pb-product-picker__thumb", style: { zIndex: preview.length - index }, children: product.imageUrl ? /* @__PURE__ */ jsx10("img", { src: product.imageUrl, alt: "" }) : /* @__PURE__ */ jsx10("span", { className: "pb-product-picker__thumb-fallback" }) }, product.id)) }) : null,
1695
+ /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", children: products.length ? `${products.length} ${i18n.t("productCountSuffix")}` : i18n.t("emptyProducts") })
1642
1696
  ] }),
1643
- /* @__PURE__ */ jsx9(Button2, { fullWidth: true, icon: ProductIcon, variant: "secondary", disabled: disabled || busy || !picker, onClick: () => void (async () => {
1697
+ /* @__PURE__ */ jsx10(Button2, { fullWidth: true, icon: ProductIcon, variant: "secondary", disabled: disabled || busy || !picker, onClick: () => void (async () => {
1644
1698
  if (!picker) return;
1645
1699
  setBusy(true);
1646
1700
  setError(null);
@@ -1653,7 +1707,7 @@ function InspectorProductsControl({ value, disabled, picker, pageId, blockId, i1
1653
1707
  setBusy(false);
1654
1708
  }
1655
1709
  })(), children: busy ? i18n.t("selectingProducts") : i18n.t("selectProducts") }),
1656
- error ? /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "critical", children: error }) : null
1710
+ error ? /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "critical", children: error }) : null
1657
1711
  ] });
1658
1712
  }
1659
1713
  function InspectorField({ name, field, value, registry, disabled, assetPicker, productPicker, pageId, blockId, i18n, onChange }) {
@@ -1662,41 +1716,41 @@ function InspectorField({ name, field, value, registry, disabled, assetPicker, p
1662
1716
  const Field = registry?.getField(field.field)?.component;
1663
1717
  return /* @__PURE__ */ jsxs7("div", { className: "pb-inspector-field", "data-control": field.control ?? "custom", children: [
1664
1718
  /* @__PURE__ */ jsxs7("div", { className: "pb-inspector-field__heading", children: [
1665
- /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", fontWeight: "semibold", children: label }),
1666
- field.description ? /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: field.description }) : null
1719
+ /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", fontWeight: "semibold", children: label }),
1720
+ field.description ? /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: field.description }) : null
1667
1721
  ] }),
1668
- field.control === "products" ? /* @__PURE__ */ jsx9(InspectorProductsControl, { value, disabled, picker: productPicker, pageId, blockId, i18n, onChange }) : field.control === "asset" ? /* @__PURE__ */ jsx9(InspectorAssetControl, { value, disabled, picker: assetPicker, pageId, blockId, i18n, onChange }) : field.control ? /* @__PURE__ */ jsx9(InspectorTextControl, { label, value, control: field.control, maxLength: field.validation?.maxLength, disabled, onChange: (next) => onChange(next) }) : Field ? /* @__PURE__ */ jsx9(Field, { value, onChange }) : null,
1669
- issues.map((issue) => /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "critical", children: issue.message }, issue.message))
1722
+ field.control === "products" ? /* @__PURE__ */ jsx10(InspectorProductsControl, { value, disabled, picker: productPicker, pageId, blockId, i18n, onChange }) : field.control === "asset" ? /* @__PURE__ */ jsx10(InspectorAssetControl, { value, disabled, picker: assetPicker, pageId, blockId, i18n, onChange }) : field.control ? /* @__PURE__ */ jsx10(InspectorTextControl, { label, value, control: field.control, maxLength: field.validation?.maxLength, disabled, onChange: (next) => onChange(next) }) : Field ? /* @__PURE__ */ jsx10(Field, { value, onChange }) : null,
1723
+ issues.map((issue) => /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "critical", children: issue.message }, issue.message))
1670
1724
  ] });
1671
1725
  }
1672
1726
  function InspectorActions({ block, canDuplicate, canDelete, canMove, canMoveUp, canMoveDown, i18n, onDuplicate, onDelete, onMove }) {
1673
1727
  return /* @__PURE__ */ jsxs7("div", { className: "pb-inspector-actions", "aria-label": `Actions for ${block.id}`, children: [
1674
1728
  /* @__PURE__ */ jsxs7(ButtonGroup2, { children: [
1675
- /* @__PURE__ */ jsx9(Button2, { disabled: !canMove || !canMoveUp, onClick: () => onMove(-1), children: i18n.t("moveUp") }),
1676
- /* @__PURE__ */ jsx9(Button2, { disabled: !canMove || !canMoveDown, onClick: () => onMove(1), children: i18n.t("moveDown") }),
1677
- /* @__PURE__ */ jsx9(Button2, { disabled: !canDuplicate, accessibilityLabel: canDuplicate ? i18n.t("duplicate") : i18n.t("duplicateUnavailable"), onClick: onDuplicate, children: i18n.t("duplicate") }),
1678
- /* @__PURE__ */ jsx9(Button2, { disabled: !canDelete, tone: "critical", onClick: onDelete, children: i18n.t("remove") })
1729
+ /* @__PURE__ */ jsx10(Button2, { disabled: !canMove || !canMoveUp, onClick: () => onMove(-1), children: i18n.t("moveUp") }),
1730
+ /* @__PURE__ */ jsx10(Button2, { disabled: !canMove || !canMoveDown, onClick: () => onMove(1), children: i18n.t("moveDown") }),
1731
+ /* @__PURE__ */ jsx10(Button2, { disabled: !canDuplicate, accessibilityLabel: canDuplicate ? i18n.t("duplicate") : i18n.t("duplicateUnavailable"), onClick: onDuplicate, children: i18n.t("duplicate") }),
1732
+ /* @__PURE__ */ jsx10(Button2, { disabled: !canDelete, tone: "critical", onClick: onDelete, children: i18n.t("remove") })
1679
1733
  ] }),
1680
- !canDuplicate ? /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: i18n.t("duplicateUnavailable") }) : null
1734
+ !canDuplicate ? /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: i18n.t("duplicateUnavailable") }) : null
1681
1735
  ] });
1682
1736
  }
1683
1737
  function DeleteConfirmation({ block, config, i18n, onCancel, onConfirm }) {
1684
- return /* @__PURE__ */ jsx9("div", { className: "pb-delete-confirmation-backdrop", role: "presentation", children: /* @__PURE__ */ jsxs7("section", { className: "pb-delete-confirmation", role: "dialog", "aria-modal": "true", "aria-labelledby": "pb-delete-confirmation-title", children: [
1685
- /* @__PURE__ */ jsx9(Text3, { as: "h2", variant: "headingMd", id: "pb-delete-confirmation-title", children: config?.title ?? i18n.t("confirmDeleteTitle") }),
1686
- /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodyMd", children: config?.message?.(block) ?? i18n.t("confirmDeleteMessage") }),
1738
+ return /* @__PURE__ */ jsx10("div", { className: "pb-delete-confirmation-backdrop", role: "presentation", children: /* @__PURE__ */ jsxs7("section", { className: "pb-delete-confirmation", role: "dialog", "aria-modal": "true", "aria-labelledby": "pb-delete-confirmation-title", children: [
1739
+ /* @__PURE__ */ jsx10(Text3, { as: "h2", variant: "headingMd", id: "pb-delete-confirmation-title", children: config?.title ?? i18n.t("confirmDeleteTitle") }),
1740
+ /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodyMd", children: config?.message?.(block) ?? i18n.t("confirmDeleteMessage") }),
1687
1741
  /* @__PURE__ */ jsxs7(ButtonGroup2, { children: [
1688
- /* @__PURE__ */ jsx9(Button2, { onClick: onCancel, children: config?.cancelLabel ?? i18n.t("cancel") }),
1689
- /* @__PURE__ */ jsx9(Button2, { tone: "critical", onClick: onConfirm, children: config?.confirmLabel ?? i18n.t("confirm") })
1742
+ /* @__PURE__ */ jsx10(Button2, { onClick: onCancel, children: config?.cancelLabel ?? i18n.t("cancel") }),
1743
+ /* @__PURE__ */ jsx10(Button2, { tone: "critical", onClick: onConfirm, children: config?.confirmLabel ?? i18n.t("confirm") })
1690
1744
  ] })
1691
1745
  ] }) });
1692
1746
  }
1693
1747
  function LeaveConfirmation({ i18n, onCancel, onConfirm }) {
1694
- return /* @__PURE__ */ jsx9("div", { className: "pb-delete-confirmation-backdrop", role: "presentation", children: /* @__PURE__ */ jsxs7("section", { className: "pb-delete-confirmation", role: "dialog", "aria-modal": "true", "aria-labelledby": "pb-leave-confirmation-title", children: [
1695
- /* @__PURE__ */ jsx9(Text3, { as: "h2", variant: "headingMd", id: "pb-leave-confirmation-title", children: i18n.t("confirmLeaveTitle") }),
1696
- /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodyMd", children: i18n.t("leaveWarning") }),
1748
+ return /* @__PURE__ */ jsx10("div", { className: "pb-delete-confirmation-backdrop", role: "presentation", children: /* @__PURE__ */ jsxs7("section", { className: "pb-delete-confirmation", role: "dialog", "aria-modal": "true", "aria-labelledby": "pb-leave-confirmation-title", children: [
1749
+ /* @__PURE__ */ jsx10(Text3, { as: "h2", variant: "headingMd", id: "pb-leave-confirmation-title", children: i18n.t("confirmLeaveTitle") }),
1750
+ /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodyMd", children: i18n.t("leaveWarning") }),
1697
1751
  /* @__PURE__ */ jsxs7(ButtonGroup2, { children: [
1698
- /* @__PURE__ */ jsx9(Button2, { onClick: onCancel, children: i18n.t("cancel") }),
1699
- /* @__PURE__ */ jsx9(Button2, { tone: "critical", onClick: onConfirm, children: i18n.t("leave") })
1752
+ /* @__PURE__ */ jsx10(Button2, { onClick: onCancel, children: i18n.t("cancel") }),
1753
+ /* @__PURE__ */ jsx10(Button2, { tone: "critical", onClick: onConfirm, children: i18n.t("leave") })
1700
1754
  ] })
1701
1755
  ] }) });
1702
1756
  }
@@ -1720,18 +1774,18 @@ function DocumentInspector({ settings, pageId, assetPicker, productPicker, i18n,
1720
1774
  }, {}) : {};
1721
1775
  return /* @__PURE__ */ jsxs7("div", { className: "pb-inspector", "data-testid": "document-inspector", children: [
1722
1776
  /* @__PURE__ */ jsxs7("header", { className: "pb-inspector__header", children: [
1723
- /* @__PURE__ */ jsx9(Badge3, { children: block.type }),
1777
+ /* @__PURE__ */ jsx10(Badge3, { children: block.type }),
1724
1778
  /* @__PURE__ */ jsxs7("div", { children: [
1725
- /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "headingSm", children: blockLabel(block, registry) }),
1726
- /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: definition?.category ?? "Core block" })
1779
+ /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "headingSm", children: blockLabel(block, registry) }),
1780
+ /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "subdued", children: definition?.category ?? "Core block" })
1727
1781
  ] })
1728
1782
  ] }),
1729
- block.type === "core.text" ? /* @__PURE__ */ jsx9(InspectorSection, { title: "Content", children: /* @__PURE__ */ jsx9(InspectorField, { name: "content", field: { field: "", label: "\u6587\u672C\u5185\u5BB9", control: "textarea", description: "\u652F\u6301\u8F83\u957F\u7684\u6B63\u6587\u5185\u5BB9\u3002" }, value: block.props.content, registry, disabled, productPicker, pageId, blockId: block.id, i18n, onChange: (content) => onChange({ content }) }) }) : null,
1783
+ block.type === "core.text" ? /* @__PURE__ */ jsx10(InspectorSection, { title: "Content", children: /* @__PURE__ */ jsx10(InspectorField, { name: "content", field: { field: "", label: "\u6587\u672C\u5185\u5BB9", control: "textarea", description: "\u652F\u6301\u8F83\u957F\u7684\u6B63\u6587\u5185\u5BB9\u3002" }, value: block.props.content, registry, disabled, productPicker, pageId, blockId: block.id, i18n, onChange: (content) => onChange({ content }) }) }) : null,
1730
1784
  block.type === "core.image" ? /* @__PURE__ */ jsxs7(InspectorSection, { title: "Image", children: [
1731
- /* @__PURE__ */ jsx9(InspectorField, { name: "src", field: { field: "", label: "\u56FE\u7247 URL", control: "url", description: "\u4F7F\u7528 HTTPS \u56FE\u7247\u5730\u5740\u3002" }, value: block.props.src, registry, disabled, productPicker, pageId, blockId: block.id, i18n, onChange: (src) => onChange({ src }) }),
1732
- /* @__PURE__ */ jsx9(InspectorField, { name: "alt", field: { field: "", label: "\u66FF\u4EE3\u6587\u672C", control: "text", description: "\u7528\u4E8E\u65E0\u969C\u788D\u9605\u8BFB\u548C\u56FE\u7247\u52A0\u8F7D\u5931\u8D25\u573A\u666F\u3002" }, value: block.props.alt, registry, disabled, productPicker, pageId, blockId: block.id, i18n, onChange: (alt) => onChange({ alt }) }),
1785
+ /* @__PURE__ */ jsx10(InspectorField, { name: "src", field: { field: "", label: "\u56FE\u7247 URL", control: "url", description: "\u4F7F\u7528 HTTPS \u56FE\u7247\u5730\u5740\u3002" }, value: block.props.src, registry, disabled, productPicker, pageId, blockId: block.id, i18n, onChange: (src) => onChange({ src }) }),
1786
+ /* @__PURE__ */ jsx10(InspectorField, { name: "alt", field: { field: "", label: "\u66FF\u4EE3\u6587\u672C", control: "text", description: "\u7528\u4E8E\u65E0\u969C\u788D\u9605\u8BFB\u548C\u56FE\u7247\u52A0\u8F7D\u5931\u8D25\u573A\u666F\u3002" }, value: block.props.alt, registry, disabled, productPicker, pageId, blockId: block.id, i18n, onChange: (alt) => onChange({ alt }) }),
1733
1787
  assetPicker ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
1734
- /* @__PURE__ */ jsx9(Button2, { disabled: disabled || selectingAsset, onClick: () => void (async () => {
1788
+ /* @__PURE__ */ jsx10(Button2, { disabled: disabled || selectingAsset, onClick: () => void (async () => {
1735
1789
  setSelectingAsset(true);
1736
1790
  setAssetError(null);
1737
1791
  try {
@@ -1743,13 +1797,13 @@ function DocumentInspector({ settings, pageId, assetPicker, productPicker, i18n,
1743
1797
  setSelectingAsset(false);
1744
1798
  }
1745
1799
  })(), children: selectingAsset ? "\u6B63\u5728\u9009\u62E9\u7D20\u6750\u2026" : "\u9009\u62E9\u7D20\u6750" }),
1746
- assetError ? /* @__PURE__ */ jsx9(Text3, { as: "p", variant: "bodySm", tone: "critical", children: assetError }) : null
1800
+ assetError ? /* @__PURE__ */ jsx10(Text3, { as: "p", variant: "bodySm", tone: "critical", children: assetError }) : null
1747
1801
  ] }) : null
1748
1802
  ] }) : null,
1749
- Object.entries(groupedFields).map(([group, fields]) => /* @__PURE__ */ jsx9(InspectorSection, { title: group, defaultOpen: group !== "Advanced", children: fields.map(([name, field]) => /* @__PURE__ */ jsx9(InspectorField, { name, field, value: field.persist === false ? settings?.values[name] : block.props[name], registry, disabled: disabled || field.persist === false && (!settings || Boolean(settings.disabled)), assetPicker, productPicker, pageId, blockId: block.id, i18n, onChange: (value) => field.persist === false ? settings?.onChange(name, value) : onChange({ [name]: value }) }, name)) }, group)),
1803
+ Object.entries(groupedFields).map(([group, fields]) => /* @__PURE__ */ jsx10(InspectorSection, { title: group, defaultOpen: group !== "Advanced", children: fields.map(([name, field]) => /* @__PURE__ */ jsx10(InspectorField, { name, field, value: field.persist === false ? settings?.values[name] : block.props[name], registry, disabled: disabled || field.persist === false && (!settings || Boolean(settings.disabled)), assetPicker, productPicker, pageId, blockId: block.id, i18n, onChange: (value) => field.persist === false ? settings?.onChange(name, value) : onChange({ [name]: value }) }, name)) }, group)),
1750
1804
  Object.values(definition?.fields ?? {}).some((field) => field.persist === false) ? settings?.footer : null,
1751
- appearanceControls && definition?.variants?.length ? /* @__PURE__ */ jsx9(InspectorSection, { title: "\u5916\u89C2", children: /* @__PURE__ */ jsx9(Select2, { label: "\u6837\u5F0F\u53D8\u4F53", options: definition.variants.map((variant) => ({ label: variant.label, value: variant.id })), value: block.variant, disabled, onChange: (variant) => onPresentationChange({ variant, style: block.style }) }) }) : null,
1752
- appearanceControls && definition ? /* @__PURE__ */ jsx9(InspectorSection, { title: "\u6837\u5F0F\u8986\u76D6", defaultOpen: false, children: appearanceTokens.map(([token, label]) => /* @__PURE__ */ jsx9(TextField, { label, value: block.style[token] ?? "", placeholder: "\u7EE7\u627F\u9875\u9762\u6216\u6A21\u677F\u8BBE\u7F6E", autoComplete: "off", disabled, onChange: (value) => {
1805
+ appearanceControls && definition?.variants?.length ? /* @__PURE__ */ jsx10(InspectorSection, { title: "\u5916\u89C2", children: /* @__PURE__ */ jsx10(Select2, { label: "\u6837\u5F0F\u53D8\u4F53", options: definition.variants.map((variant) => ({ label: variant.label, value: variant.id })), value: block.variant, disabled, onChange: (variant) => onPresentationChange({ variant, style: block.style }) }) }) : null,
1806
+ appearanceControls && definition ? /* @__PURE__ */ jsx10(InspectorSection, { title: "\u6837\u5F0F\u8986\u76D6", defaultOpen: false, children: appearanceTokens.map(([token, label]) => /* @__PURE__ */ jsx10(TextField, { label, value: block.style[token] ?? "", placeholder: "\u7EE7\u627F\u9875\u9762\u6216\u6A21\u677F\u8BBE\u7F6E", autoComplete: "off", disabled, onChange: (value) => {
1753
1807
  const style = { ...block.style };
1754
1808
  if (value.trim()) style[token] = value;
1755
1809
  else delete style[token];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@standhigher/puck-page-builder",
3
- "version": "0.12.8",
3
+ "version": "0.12.9",
4
4
  "description": "React PageDocument editor, extension registry, and web renderer for BestTrack page experiences.",
5
5
  "type": "module",
6
6
  "repository": {
package/src/styles.css CHANGED
@@ -27,7 +27,7 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
27
27
  .pb-zoom-control .Polaris-Select__Input { padding-top: 4px; padding-bottom: 4px; }
28
28
  .pb-page-status-card { display: grid; gap: 2px; margin-top: var(--builder-space-1); }
29
29
  .pb-page-status-card p { margin: 0; }
30
- .pb-workspace { display: grid; grid-template-columns: 64px minmax(260px, 300px) minmax(0, 1fr) minmax(300px, 320px); min-height: calc(100vh - 56px); }
30
+ .pb-workspace { display: grid; grid-template-columns: 64px minmax(260px, 300px) minmax(0, 1fr) minmax(260px, 320px); width: 100%; min-width: 0; min-height: calc(100vh - 56px); overflow-x: hidden; }
31
31
  .pb-workspace--left-closed:not(.pb-workspace--right-closed) { grid-template-columns: 64px minmax(0, 1fr) minmax(300px, 320px); }
32
32
  .pb-workspace--right-closed:not(.pb-workspace--left-closed) { grid-template-columns: 64px minmax(260px, 300px) minmax(0, 1fr); }
33
33
  .pb-workspace--left-closed.pb-workspace--right-closed { grid-template-columns: 64px minmax(0, 1fr); }
@@ -35,6 +35,9 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
35
35
  .pb-tool-rail .Polaris-Button { min-width: 44px; min-height: 44px; }
36
36
  .pb-left-panel, .pb-right-panel { display: flex; flex-direction: column; gap: var(--builder-space-4); min-width: 0; padding: var(--builder-space-4); overflow: auto; background: var(--builder-surface); }
37
37
  .pb-left-panel { border-right: 1px solid var(--builder-border); }
38
+ .pb-panel-header { width: 100%; }
39
+ .pb-panel-header .Polaris-InlineStack { width: 100%; }
40
+ .pb-panel-header .Polaris-Button { min-width: 32px; min-height: 32px; }
38
41
  .pb-right-panel { border-left: 1px solid var(--builder-border); background: #f8fafc; }
39
42
  .pb-right-panel > h2 { margin: 0; color: #475569; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }
40
43
  .pb-inspector { display: grid; gap: var(--builder-space-3); }
@@ -73,7 +76,10 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
73
76
  .pb-asset-picker { display: grid; gap: 8px; }
74
77
  .pb-asset-picker__preview { display: block; width: 100%; aspect-ratio: 20 / 9; object-fit: fill; object-position: center; border: 1px solid #e2e8f0; border-radius: 8px; background: #f8fafc; }
75
78
  .pb-inspector__hint { margin: 0; padding: 0 var(--builder-space-2); color: #64748b; font-size: 12px; line-height: 1.5; }
76
- .pb-inspector-actions { padding-top: var(--builder-space-2); border-top: 1px solid #e2e8f0; }
79
+ .pb-inspector-actions { min-width: 0; padding-top: var(--builder-space-2); border-top: 1px solid #e2e8f0; }
80
+ .pb-inspector-actions .Polaris-ButtonGroup { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; margin: 0; gap: var(--builder-space-2); }
81
+ .pb-inspector-actions .Polaris-ButtonGroup__Item { min-width: 0; margin: 0; }
82
+ .pb-inspector-actions .Polaris-ButtonGroup__Item .Polaris-Button { width: 100%; justify-content: center; }
77
83
  .pb-delete-confirmation-backdrop { position: fixed; z-index: 1000; inset: 0; display: grid; place-items: center; padding: var(--builder-space-4); background: rgb(15 23 42 / 42%); }
78
84
  .pb-delete-confirmation { display: grid; gap: var(--builder-space-4); width: min(100%, 420px); padding: var(--builder-space-5); border-radius: 12px; color: #0f172a; background: #fff; box-shadow: 0 20px 50px rgb(15 23 42 / 25%); }
79
85
  .pb-delete-confirmation h2, .pb-delete-confirmation p { margin: 0; }
@@ -90,9 +96,9 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
90
96
  .pb-canvas-area { display: flex; flex-direction: column; gap: var(--builder-space-3); min-width: 0; min-height: 0; padding: var(--builder-space-4); overflow: auto; background: var(--builder-canvas-bg); }
91
97
  .pb-canvas-toolbar { padding: var(--builder-space-2); border: 1px solid var(--builder-border); border-radius: var(--builder-panel-radius); background: var(--builder-surface); }
92
98
  .pb-canvas-stage { position: relative; display: block; padding: 0; height: auto; }
93
- .pb-canvas-frame { --puck-color-line-placeholder: var(--builder-accent); --puck-line-placeholder-width: 3px; width: 100%; height: auto; margin: 0 auto; overflow: visible; border: 1px solid var(--builder-border); border-radius: var(--builder-canvas-radius); background: var(--builder-surface); box-shadow: var(--builder-canvas-shadow); transition: width 160ms ease, transform 160ms ease; }
94
- .pb-canvas-frame iframe { display: block; width: 100%; height: auto !important; min-height: 0 !important; border: 0; }
95
- .pb-canvas-frame [class*="PuckPreview"] { position: relative; height: auto !important; }
99
+ .pb-canvas-frame { --puck-color-line-placeholder: var(--builder-accent); --puck-line-placeholder-width: 3px; width: 100%; height: auto; margin: 0 auto; overflow: visible; border: 1px solid var(--builder-border); border-radius: var(--builder-canvas-radius); background: var(--builder-surface); box-shadow: var(--builder-canvas-shadow); transform-origin: top center; transition: width 160ms ease, transform 160ms ease; }
100
+ .pb-canvas-frame iframe { display: block; width: 100%; height: auto; min-height: 0; border: 0; }
101
+ .pb-canvas-frame [class*="PuckPreview"]:not(iframe) { position: relative; height: auto !important; }
96
102
  .pb-canvas-frame [data-puck-component] { cursor: grab; }
97
103
  .pb-canvas-frame [data-puck-component]:active, .pb-canvas-frame [data-dnd-dragging] { cursor: grabbing; }
98
104
  .pb-canvas-frame [data-puck-disabled] { cursor: pointer; }
@@ -108,9 +114,7 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
108
114
  .pb-canvas-frame--tablet { width: min(100%, 768px); }
109
115
  .pb-canvas-frame--mobile { width: min(100%, 390px); }
110
116
  .pb-canvas-frame--full { width: 100%; }
111
- .pb-canvas-frame--zoom-50 { zoom: 0.5; }
112
- .pb-canvas-frame--zoom-70 { zoom: 0.7; }
113
- .pb-canvas-frame--zoom-100 { zoom: 1; }
117
+ .pb-canvas-frame--zoom-50, .pb-canvas-frame--zoom-70, .pb-canvas-frame--zoom-100 { transform-origin: top center; }
114
118
  .pb-canvas-overlay { position: absolute; top: var(--builder-space-2); left: 50%; display: flex; gap: var(--builder-space-2); padding: var(--builder-space-1) var(--builder-space-2); border: 2px solid var(--builder-accent); border-radius: var(--builder-control-radius); color: var(--builder-accent); background: var(--builder-surface); font-size: 12px; font-weight: 600; transform: translateX(-50%); box-shadow: var(--builder-canvas-shadow); pointer-events: none; }
115
119
  .pb-canvas-overlay span:last-child { color: var(--builder-text-muted); font-weight: 500; }
116
120
  .pb-collapsed-actions { display: flex; gap: var(--builder-space-2); }
@@ -124,7 +128,7 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
124
128
  .pb-document-block span { font-size: 14px; font-weight: 600; }
125
129
  .pb-document-block small { grid-column: 2; color: var(--builder-text-muted); }
126
130
  .pb-document-block-row { display: flex; align-items: center; gap: var(--builder-space-2); padding: var(--builder-space-2); border: 1px solid transparent; border-radius: var(--builder-panel-radius); background: transparent; }
127
- .pb-document-block-row--library { width: 100%; flex-direction: column; align-items: flex-start; text-align: left; color: var(--builder-text); font: inherit; cursor: grab; }
131
+ .pb-document-block-row--library { width: 100%; flex-direction: column; align-items: flex-start; padding-right: var(--builder-space-2); text-align: left; color: var(--builder-text); font: inherit; cursor: grab; }
128
132
  .pb-document-block-row--library:active { cursor: grabbing; }
129
133
  .pb-document-block-row--library[aria-disabled="true"] { cursor: default; }
130
134
  .pb-document-block-row--dragging { opacity: 0.55; }
@@ -132,8 +136,12 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
132
136
  .pb-document-block-row--drop-after { box-shadow: inset 0 -3px 0 0 var(--builder-accent); }
133
137
  .pb-document-block-row--library[type="button"] { cursor: pointer; }
134
138
  .pb-library-block-title { display: flex; align-items: center; justify-content: space-between; width: 100%; gap: var(--builder-space-2); }
135
- .pb-library-block-drag-hint { display: inline-flex; color: var(--builder-text-muted); pointer-events: none; }
136
- .pb-library-block-drag-hint svg { width: 16px; height: 16px; }
139
+ .pb-library-block-controls { display: inline-flex; align-items: center; gap: 0; flex: 0 0 auto; margin-right: 0; }
140
+ .pb-library-block-drag-hint { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; color: var(--builder-text-muted); pointer-events: none; }
141
+ .pb-library-block-drag-hint svg { width: 20px; height: 20px; }
142
+ .pb-library-block-controls .Polaris-Button { min-width: 32px; min-height: 32px; padding: 0; }
143
+ .pb-library-block-controls .Polaris-Button svg { width: 20px; height: 20px; }
144
+ .pb-library-block-controls .Polaris-Button:disabled { color: var(--builder-text-muted); opacity: .55; }
137
145
  .pb-document-block-row:hover { background: var(--builder-surface-subtle); }
138
146
  .pb-document-block-row--selected { border-color: var(--builder-accent); background: var(--builder-accent-subtle); }
139
147
  .pb-editor-status { display: grid; place-items: center; box-sizing: border-box; width: 100%; min-height: 100dvh; padding: var(--builder-space-6); }