@standhigher/puck-page-builder 0.7.2 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions.d.ts +20 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +136 -70
- package/dist/runtime.d.ts +1 -1
- package/package.json +1 -1
- package/src/styles.css +24 -1
package/dist/extensions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentType, ReactNode } from 'react';
|
|
2
|
-
import { RenderTarget, PageDocument } from './schema.js';
|
|
2
|
+
import { RenderTarget, JsonValue, PageDocument } from './schema.js';
|
|
3
3
|
import { ThemeTokens } from './theme.js';
|
|
4
4
|
|
|
5
5
|
type ExtensionTarget = RenderTarget | "all";
|
|
@@ -12,12 +12,26 @@ type ValidationIssue = {
|
|
|
12
12
|
type FieldConfig = {
|
|
13
13
|
field: string;
|
|
14
14
|
label?: string;
|
|
15
|
+
/** Product-facing editor metadata. Custom field components remain supported. */
|
|
16
|
+
control?: "text" | "textarea" | "url";
|
|
17
|
+
description?: string;
|
|
18
|
+
group?: string;
|
|
15
19
|
required?: boolean;
|
|
16
20
|
};
|
|
17
21
|
type FieldProps<T = unknown> = {
|
|
18
22
|
value: T;
|
|
19
23
|
onChange(value: T): void;
|
|
20
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Props available only to an extension's editor-canvas renderer.
|
|
27
|
+
* They are separate from Web rendering so editor interaction cannot invoke a
|
|
28
|
+
* host Runtime or become persisted operational data.
|
|
29
|
+
*/
|
|
30
|
+
type BlockEditorProps<P = Record<string, unknown>> = P & {
|
|
31
|
+
blockId: string;
|
|
32
|
+
selected: boolean;
|
|
33
|
+
onPropsChange(props: Record<string, JsonValue>): void;
|
|
34
|
+
};
|
|
21
35
|
interface BlockDefinition<P = Record<string, unknown>> {
|
|
22
36
|
type: string;
|
|
23
37
|
version: number;
|
|
@@ -26,7 +40,10 @@ interface BlockDefinition<P = Record<string, unknown>> {
|
|
|
26
40
|
targets: ExtensionTarget[];
|
|
27
41
|
defaultProps: P;
|
|
28
42
|
fields: Record<string, FieldConfig>;
|
|
29
|
-
render: Partial<Record<RenderTarget, ComponentType<P
|
|
43
|
+
render: Partial<Record<RenderTarget, ComponentType<P>>> & {
|
|
44
|
+
/** Optional edit-mode renderer. WebRenderer never uses this surface. */
|
|
45
|
+
editor?: ComponentType<BlockEditorProps<P>>;
|
|
46
|
+
};
|
|
30
47
|
defaultVariant?: string;
|
|
31
48
|
variants?: BlockVariantDefinition[];
|
|
32
49
|
dataSources?: string[];
|
|
@@ -168,4 +185,4 @@ declare class ExtensionRegistry {
|
|
|
168
185
|
declare function createExtensionRegistry(extensions: PageBuilderExtension[], options?: ExtensionRegistryOptions): ExtensionRegistry;
|
|
169
186
|
declare function createTemplateRegistry(templates: TemplateDefinition[], blocks?: BlockDefinition[]): TemplateRegistry;
|
|
170
187
|
|
|
171
|
-
export { type BlockDefinition, type BlockVariantDefinition, type DataSourceDefinition, type EditorAction, type EditorActionPosition, type ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, type ExtensionRegistryErrorCode, type ExtensionRegistryOptions, type ExtensionTarget, type FieldConfig, type FieldDefinition, type FieldProps, type LifecycleHooks, type PageBuilderExtension, type RendererDefinition, type TemplateDefinition, TemplateRegistry, type TemplateSource, type UISlotContribution, type UISlotName, type ValidationIssue, createExtensionRegistry, createTemplateRegistry };
|
|
188
|
+
export { type BlockDefinition, type BlockEditorProps, type BlockVariantDefinition, type DataSourceDefinition, type EditorAction, type EditorActionPosition, type ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, type ExtensionRegistryErrorCode, type ExtensionRegistryOptions, type ExtensionTarget, type FieldConfig, type FieldDefinition, type FieldProps, type LifecycleHooks, type PageBuilderExtension, type RendererDefinition, type TemplateDefinition, TemplateRegistry, type TemplateSource, type UISlotContribution, type UISlotName, type ValidationIssue, createExtensionRegistry, createTemplateRegistry };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { ExtensionRegistry } from './extensions.js';
|
|
4
|
-
export { BlockDefinition, BlockVariantDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, TemplateRegistry, TemplateSource, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry, createTemplateRegistry } from './extensions.js';
|
|
4
|
+
export { BlockDefinition, BlockEditorProps, BlockVariantDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, TemplateRegistry, TemplateSource, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry, createTemplateRegistry } from './extensions.js';
|
|
5
5
|
import { PageDocument, BlockNode, JsonValue } from './schema.js';
|
|
6
6
|
export { BlockStyleOverrides, DataBinding, PageDocumentIssue, PageDocumentMigration, PageDocumentSchemaVersion, PageSettings, RenderTarget, createPageDocument, migratePageDocument, validatePageDocument } from './schema.js';
|
|
7
7
|
export { ThemeTokenName, ThemeTokens, mergeThemeTokens, normalizeThemeTokens, systemThemeTokens, toThemeStyle } from './theme.js';
|
package/dist/index.js
CHANGED
|
@@ -342,12 +342,35 @@ function PropertyPanel({
|
|
|
342
342
|
|
|
343
343
|
// src/editor/shell/PageDocumentEditorShell.tsx
|
|
344
344
|
import { Puck as Puck2, usePuck } from "@puckeditor/core";
|
|
345
|
-
import { Badge as Badge2, Banner,
|
|
345
|
+
import { Badge as Badge2, Banner, Button as Button2, ButtonGroup as ButtonGroup2, InlineStack as InlineStack2, Text as Text2, TextField } from "@shopify/polaris";
|
|
346
346
|
import { DragHandleIcon as DragHandleIcon2, LayoutSectionIcon as LayoutSectionIcon2, MenuIcon as MenuIcon2, RedoIcon as RedoIcon2, UndoIcon as UndoIcon2 } from "@shopify/polaris-icons";
|
|
347
|
-
import { useCallback as useCallback2, useEffect as
|
|
347
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef4, useState as useState3 } from "react";
|
|
348
|
+
|
|
349
|
+
// src/adapters/puck/canvas-extension-block.tsx
|
|
350
|
+
import { registerOverlayPortal } from "@puckeditor/core";
|
|
351
|
+
import { useEffect, useRef as useRef2 } from "react";
|
|
352
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
353
|
+
function CanvasExtensionBlock({ active, children, label, onSelect }) {
|
|
354
|
+
const editorRef = useRef2(null);
|
|
355
|
+
useEffect(() => active ? registerOverlayPortal(editorRef.current, { disableDrag: true }) : void 0, [active]);
|
|
356
|
+
return /* @__PURE__ */ jsx3("div", { ref: editorRef, className: "pb-document-canvas__extension", "aria-label": "Select " + label + " in canvas", role: "group", tabIndex: 0, onClick: onSelect, onKeyDown: (event) => {
|
|
357
|
+
if (event.key === "Enter" || event.key === " ") onSelect();
|
|
358
|
+
}, children });
|
|
359
|
+
}
|
|
348
360
|
|
|
349
361
|
// src/adapters/puck/page-document-config.tsx
|
|
350
|
-
import { jsx as
|
|
362
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
363
|
+
function canvasFieldFallback({ block, props, registry, onPropsChange }) {
|
|
364
|
+
const fields = Object.entries(block.fields);
|
|
365
|
+
if (!fields.length) return null;
|
|
366
|
+
return /* @__PURE__ */ jsx4("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]) => {
|
|
367
|
+
const Field = registry?.getField(field.field)?.component;
|
|
368
|
+
return Field ? /* @__PURE__ */ jsxs3("label", { style: { display: "grid", gap: 4, fontSize: 12, fontWeight: 600 }, children: [
|
|
369
|
+
field.label ?? name,
|
|
370
|
+
/* @__PURE__ */ jsx4(Field, { value: props[name], onChange: (value) => onPropsChange({ [name]: value }) })
|
|
371
|
+
] }, name) : null;
|
|
372
|
+
}) });
|
|
373
|
+
}
|
|
351
374
|
function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId, registry) {
|
|
352
375
|
const extensionComponents = Object.fromEntries((registry?.blocks ?? []).flatMap((block) => {
|
|
353
376
|
const BlockRenderer = block.render.web;
|
|
@@ -355,9 +378,12 @@ function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId,
|
|
|
355
378
|
return [[block.type, {
|
|
356
379
|
render: (props) => {
|
|
357
380
|
const id = typeof props.id === "string" ? props.id : `unknown-${block.type}`;
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
381
|
+
const EditorRenderer = block.render.editor;
|
|
382
|
+
const active = id === selectedBlockId;
|
|
383
|
+
return /* @__PURE__ */ jsx4(CanvasExtensionBlock, { active, label: block.label, onSelect: () => onSelect(id), children: EditorRenderer ? /* @__PURE__ */ jsx4(EditorRenderer, { ...props, blockId: id, selected: active, onPropsChange: (next) => onPropsChange(id, next) }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
384
|
+
/* @__PURE__ */ jsx4(BlockRenderer, { ...props }),
|
|
385
|
+
active ? canvasFieldFallback({ block, props, registry, onPropsChange: (next) => onPropsChange(id, next) }) : null
|
|
386
|
+
] }) });
|
|
361
387
|
}
|
|
362
388
|
}]];
|
|
363
389
|
}));
|
|
@@ -368,10 +394,10 @@ function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId,
|
|
|
368
394
|
const id = typeof props.id === "string" ? props.id : "unknown-text";
|
|
369
395
|
const content = typeof props.content === "string" ? props.content : "";
|
|
370
396
|
const editable = id === selectedBlockId;
|
|
371
|
-
return /* @__PURE__ */
|
|
397
|
+
return /* @__PURE__ */ jsx4("section", { 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) => {
|
|
372
398
|
if (event.key === "Enter" || event.key === " ") onSelect(id);
|
|
373
|
-
}, children: /* @__PURE__ */
|
|
374
|
-
if (editable) onPropsChange(id, { content: event.currentTarget.textContent ?? "" });
|
|
399
|
+
}, children: /* @__PURE__ */ jsx4("p", { contentEditable: editable, suppressContentEditableWarning: true, onInput: (event) => {
|
|
400
|
+
if (editable) onPropsChange(id, { content: event.currentTarget.textContent ?? "" }, true);
|
|
375
401
|
}, children: content }) });
|
|
376
402
|
}
|
|
377
403
|
},
|
|
@@ -384,8 +410,8 @@ function createPageDocumentPuckConfig(onSelect, onPropsChange, selectedBlockId,
|
|
|
384
410
|
return /* @__PURE__ */ jsxs3("figure", { className: "pb-document-canvas__image", "data-page-document-block-id": id, "aria-label": "Select Image in canvas", role: "button", tabIndex: 0, onClick: () => onSelect(id), onKeyDown: (event) => {
|
|
385
411
|
if (event.key === "Enter" || event.key === " ") onSelect(id);
|
|
386
412
|
}, children: [
|
|
387
|
-
/* @__PURE__ */
|
|
388
|
-
editable ? /* @__PURE__ */
|
|
413
|
+
/* @__PURE__ */ jsx4("img", { src, alt }),
|
|
414
|
+
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
|
|
389
415
|
] });
|
|
390
416
|
}
|
|
391
417
|
},
|
|
@@ -435,8 +461,8 @@ function fromEngineData(data, base, registry) {
|
|
|
435
461
|
}
|
|
436
462
|
|
|
437
463
|
// src/editor/context/EditorContext.tsx
|
|
438
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef as
|
|
439
|
-
import { jsx as
|
|
464
|
+
import { createContext, useCallback, useContext, useEffect as useEffect2, useMemo, useReducer, useRef as useRef3, useState as useState2 } from "react";
|
|
465
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
440
466
|
function historyReducer(state, action) {
|
|
441
467
|
if (action.type === "select") return { ...state, selectedBlockId: action.id };
|
|
442
468
|
if (action.type === "device") return { ...state, device: action.device };
|
|
@@ -470,8 +496,8 @@ function defaultBlock(type, blocks, registry) {
|
|
|
470
496
|
}
|
|
471
497
|
function EditorProvider({ initialDocument, registry, loadState = "ready", leaveWarning = "You have unsaved changes.", onDocumentChange, children }) {
|
|
472
498
|
const [history, dispatch] = useReducer(historyReducer, initialDocument, (document) => ({ document, selectedBlockId: document.blocks[0]?.id ?? null, past: [], future: [], device: "desktop", savedDocument: document }));
|
|
473
|
-
const historyRef =
|
|
474
|
-
|
|
499
|
+
const historyRef = useRef3(history);
|
|
500
|
+
useEffect2(() => {
|
|
475
501
|
historyRef.current = history;
|
|
476
502
|
}, [history]);
|
|
477
503
|
const [canvasSelectionRequest, setCanvasSelectionRequest] = useState2(null);
|
|
@@ -496,11 +522,11 @@ function EditorProvider({ initialDocument, registry, loadState = "ready", leaveW
|
|
|
496
522
|
const blocks = current.document.blocks.map((block) => block.id === id ? { ...block, props: { ...block.props, ...props } } : block);
|
|
497
523
|
replace({ ...current.document, blocks }, id);
|
|
498
524
|
}, [editable, replace]);
|
|
499
|
-
|
|
525
|
+
useEffect2(() => {
|
|
500
526
|
onDocumentChange?.(history.document);
|
|
501
527
|
}, [history.document, onDocumentChange]);
|
|
502
528
|
const isDirty = JSON.stringify(history.document) !== JSON.stringify(history.savedDocument);
|
|
503
|
-
|
|
529
|
+
useEffect2(() => {
|
|
504
530
|
if (!isDirty || typeof window === "undefined") return;
|
|
505
531
|
const confirmLeave = (event) => {
|
|
506
532
|
event.preventDefault();
|
|
@@ -509,7 +535,7 @@ function EditorProvider({ initialDocument, registry, loadState = "ready", leaveW
|
|
|
509
535
|
window.addEventListener("beforeunload", confirmLeave);
|
|
510
536
|
return () => window.removeEventListener("beforeunload", confirmLeave);
|
|
511
537
|
}, [isDirty, leaveWarning]);
|
|
512
|
-
|
|
538
|
+
useEffect2(() => {
|
|
513
539
|
if (typeof window === "undefined") return;
|
|
514
540
|
const keydown = (event) => {
|
|
515
541
|
const target = event.target;
|
|
@@ -604,7 +630,7 @@ function EditorProvider({ initialDocument, registry, loadState = "ready", leaveW
|
|
|
604
630
|
markSaved: () => dispatch({ type: "saved" })
|
|
605
631
|
};
|
|
606
632
|
}, [canvasSelectionRequest, confirmCanvasSelection, editable, history, isDirty, loadState, registry, replace, requestCanvasSelection, selectedBlock, updateBlockProps, updateFromCanvas]);
|
|
607
|
-
return /* @__PURE__ */
|
|
633
|
+
return /* @__PURE__ */ jsx5(EditorContext.Provider, { value, children });
|
|
608
634
|
}
|
|
609
635
|
function useEditorContext() {
|
|
610
636
|
const context = useContext(EditorContext);
|
|
@@ -692,7 +718,7 @@ function blockIdAtRelativeY(ids, relativeY) {
|
|
|
692
718
|
}
|
|
693
719
|
|
|
694
720
|
// src/editor/shell/PageDocumentEditorShell.tsx
|
|
695
|
-
import {
|
|
721
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
696
722
|
var deviceLabels2 = { desktop: "desktop", tablet: "tablet", mobile: "mobile" };
|
|
697
723
|
function blockLabel(block, registry) {
|
|
698
724
|
return blockTypeLabel(block.type, registry);
|
|
@@ -703,25 +729,25 @@ function blockTypeLabel(type, registry) {
|
|
|
703
729
|
return registry?.getBlock(type)?.label ?? type;
|
|
704
730
|
}
|
|
705
731
|
function PageDocumentEditorShell(props) {
|
|
706
|
-
return /* @__PURE__ */
|
|
732
|
+
return /* @__PURE__ */ jsx6(EditorProvider, { initialDocument: props.initialDocument, registry: props.registry, loadState: props.loadState, leaveWarning: createAdminI18n(props.adminLocale).t("leaveWarning"), onDocumentChange: props.onDocumentChange, children: /* @__PURE__ */ jsx6(PageDocumentEditor, { ...props }) });
|
|
707
733
|
}
|
|
708
734
|
function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPublish }) {
|
|
709
735
|
const editor = useEditorContext();
|
|
710
736
|
const [blockView, setBlockView] = useState3("blocks");
|
|
711
737
|
const [draggingLibraryType, setDraggingLibraryType] = useState3(null);
|
|
712
|
-
const canvasFrameRef =
|
|
738
|
+
const canvasFrameRef = useRef4(null);
|
|
713
739
|
const [canvasMutationVersion, setCanvasMutationVersion] = useState3(0);
|
|
714
740
|
const [request, setRequest] = useState3("idle");
|
|
715
741
|
const [notice, setNotice] = useState3(null);
|
|
716
742
|
const i18n = createAdminI18n(adminLocale);
|
|
717
743
|
const engineData = useMemo2(() => toEngineData(editor.document, registry), [editor.document, registry]);
|
|
718
744
|
const { confirmCanvasSelection, selectedBlockId, updateBlockProps } = editor;
|
|
719
|
-
const updateFromCanvasInput = useCallback2((id, props) => {
|
|
720
|
-
setCanvasMutationVersion((version) => version + 1);
|
|
745
|
+
const updateFromCanvasInput = useCallback2((id, props, preserveCanvasValue = false) => {
|
|
746
|
+
if (preserveCanvasValue) setCanvasMutationVersion((version) => version + 1);
|
|
721
747
|
updateBlockProps(id, props);
|
|
722
748
|
}, [updateBlockProps]);
|
|
723
749
|
const config = useMemo2(() => createPageDocumentPuckConfig(confirmCanvasSelection, updateFromCanvasInput, selectedBlockId, registry), [confirmCanvasSelection, registry, selectedBlockId, updateFromCanvasInput]);
|
|
724
|
-
if (editor.loadState !== "ready" && editor.loadState !== "success") return /* @__PURE__ */
|
|
750
|
+
if (editor.loadState !== "ready" && editor.loadState !== "success") return /* @__PURE__ */ jsx6(EditorStatus, { state: editor.loadState });
|
|
725
751
|
const blockTypes = ["core.text", "core.image", ...registry?.blocks.map((block) => block.type) ?? []];
|
|
726
752
|
const addFromLibrary = (type, beforeId) => {
|
|
727
753
|
const id = editor.addBlock(type, beforeId);
|
|
@@ -785,12 +811,12 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
|
|
|
785
811
|
setRequest("idle");
|
|
786
812
|
}
|
|
787
813
|
};
|
|
788
|
-
return /* @__PURE__ */
|
|
789
|
-
/* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ jsx6(Puck2, { config, data: engineData, iframe: { enabled: iframe }, onChange: (data) => editor.updateFromCanvas(fromEngineData(data, editor.document, registry)), children: /* @__PURE__ */ jsxs4(Puck2.Layout, { children: [
|
|
815
|
+
/* @__PURE__ */ jsx6(CanvasSelectionBridge, { data: engineData, requestedBlockId: editor.canvasSelectionRequest, onCanvasSelected: confirmCanvasSelection, canvasMutationVersion }),
|
|
790
816
|
/* @__PURE__ */ jsxs4("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, children: [
|
|
791
|
-
/* @__PURE__ */
|
|
817
|
+
/* @__PURE__ */ jsx6("header", { className: "pb-header", children: /* @__PURE__ */ jsxs4(InlineStack2, { align: "space-between", blockAlign: "center", gap: "300", wrap: false, children: [
|
|
792
818
|
/* @__PURE__ */ jsxs4("div", { className: "pb-page-title", children: [
|
|
793
|
-
/* @__PURE__ */
|
|
819
|
+
/* @__PURE__ */ jsx6(Text2, { as: "h1", variant: "headingSm", children: editor.document.settings.seoTitle ?? editor.document.pageId }),
|
|
794
820
|
/* @__PURE__ */ jsxs4(Text2, { as: "p", variant: "bodySm", tone: "subdued", children: [
|
|
795
821
|
"PageDocument V",
|
|
796
822
|
editor.document.schemaVersion,
|
|
@@ -799,54 +825,54 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
|
|
|
799
825
|
] })
|
|
800
826
|
] }),
|
|
801
827
|
/* @__PURE__ */ jsxs4(InlineStack2, { gap: "150", blockAlign: "center", wrap: false, children: [
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
804
|
-
/* @__PURE__ */
|
|
805
|
-
/* @__PURE__ */
|
|
806
|
-
/* @__PURE__ */
|
|
828
|
+
/* @__PURE__ */ jsx6(Badge2, { tone: editor.isDirty ? "attention" : "success", children: editor.isDirty ? i18n.t("unsaved") : i18n.t("saved") }),
|
|
829
|
+
/* @__PURE__ */ jsx6(Button2, { disabled: !onSave || !editor.isDirty || request !== "idle", onClick: () => void save(), children: request === "saving" ? i18n.t("saving") : i18n.t("save") }),
|
|
830
|
+
/* @__PURE__ */ jsx6(Button2, { variant: "primary", disabled: !onPublish || request !== "idle", onClick: () => void publish(), children: request === "publishing" ? i18n.t("publishing") : i18n.t("publish") }),
|
|
831
|
+
/* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("undo"), icon: UndoIcon2, variant: "tertiary", disabled: !editor.actionState.canUndo, onClick: editor.undo }),
|
|
832
|
+
/* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("redo"), icon: RedoIcon2, variant: "tertiary", disabled: !editor.actionState.canRedo, onClick: editor.redo })
|
|
807
833
|
] })
|
|
808
834
|
] }) }),
|
|
809
|
-
editor.loadState === "success" ? /* @__PURE__ */
|
|
810
|
-
notice ? /* @__PURE__ */
|
|
835
|
+
editor.loadState === "success" ? /* @__PURE__ */ jsx6(Banner, { tone: "success", children: i18n.t("success") }) : null,
|
|
836
|
+
notice ? /* @__PURE__ */ jsx6(Banner, { tone: notice === "published" ? "success" : "critical", children: i18n.t(notice) }) : null,
|
|
811
837
|
/* @__PURE__ */ jsxs4("div", { className: "pb-workspace pb-workspace--document", children: [
|
|
812
838
|
/* @__PURE__ */ jsxs4("nav", { className: "pb-tool-rail", "aria-label": "\u7F16\u8F91\u5668\u5DE5\u5177", children: [
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
839
|
+
/* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("blocks"), icon: LayoutSectionIcon2, pressed: blockView === "blocks", variant: "tertiary", onClick: () => setBlockView("blocks") }),
|
|
840
|
+
/* @__PURE__ */ jsx6(Button2, { accessibilityLabel: i18n.t("outline"), icon: MenuIcon2, pressed: blockView === "outline", variant: "tertiary", onClick: () => setBlockView("outline") })
|
|
815
841
|
] }),
|
|
816
842
|
/* @__PURE__ */ jsxs4("aside", { className: "pb-left-panel", "aria-label": "PageDocument \u533A\u5757", children: [
|
|
817
|
-
/* @__PURE__ */
|
|
818
|
-
blockView === "blocks" ? /* @__PURE__ */
|
|
843
|
+
/* @__PURE__ */ jsx6(InlineStack2, { align: "space-between", blockAlign: "center", children: /* @__PURE__ */ jsx6(Text2, { as: "h2", variant: "headingSm", children: blockView === "blocks" ? i18n.t("blocks") : i18n.t("outline") }) }),
|
|
844
|
+
blockView === "blocks" ? /* @__PURE__ */ jsx6("div", { className: "pb-block-list", "data-testid": "blocks-view", "aria-label": "\u533A\u5757\u7C7B\u578B\u5E93", role: "list", onDrop: cancelLibraryDrop, children: blockTypes.map((type) => /* @__PURE__ */ jsxs4("div", { className: `pb-document-block-row pb-document-block-row--library ${editor.selectedBlock?.type === type ? "pb-document-block-row--selected" : ""}`, "data-block-type": type, "data-selected": editor.selectedBlock?.type === type, role: "listitem", draggable: editor.actionState.canAdd, "aria-label": `${blockTypeLabel(type, registry)}\uFF0C\u62D6\u62FD\u81F3\u753B\u5E03\u4EE5\u6DFB\u52A0${editor.selectedBlock?.type === type ? "\uFF0C\u5F53\u524D\u9009\u4E2D\u7C7B\u578B" : ""}`, onDragStart: (event) => {
|
|
819
845
|
event.dataTransfer.setData("application/x-page-document-block", type);
|
|
820
846
|
event.dataTransfer.effectAllowed = "copy";
|
|
821
847
|
setDraggingLibraryType(type);
|
|
822
848
|
}, onDragEnd: () => setDraggingLibraryType(null), children: [
|
|
823
849
|
/* @__PURE__ */ jsxs4("span", { className: "pb-library-block-title", children: [
|
|
824
|
-
/* @__PURE__ */
|
|
825
|
-
/* @__PURE__ */
|
|
850
|
+
/* @__PURE__ */ jsx6(Text2, { as: "span", variant: "bodySm", fontWeight: "semibold", children: blockTypeLabel(type, registry) }),
|
|
851
|
+
/* @__PURE__ */ jsx6("span", { className: "pb-library-block-drag-hint", "aria-hidden": "true", children: /* @__PURE__ */ jsx6(DragHandleIcon2, {}) })
|
|
826
852
|
] }),
|
|
827
|
-
/* @__PURE__ */
|
|
828
|
-
] }, type)) }) : editor.document.blocks.length === 0 ? /* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
853
|
+
/* @__PURE__ */ jsx6(Text2, { as: "span", variant: "bodySm", tone: "subdued", children: type })
|
|
854
|
+
] }, type)) }) : editor.document.blocks.length === 0 ? /* @__PURE__ */ jsx6(Text2, { as: "p", tone: "subdued", children: i18n.t("empty") }) : /* @__PURE__ */ jsx6("div", { className: "pb-block-list", "data-testid": "outline-view", children: editor.document.blocks.map((block) => /* @__PURE__ */ jsxs4("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: () => editor.requestCanvasSelection(block.id), children: [
|
|
855
|
+
/* @__PURE__ */ jsx6(Text2, { as: "span", variant: "bodySm", fontWeight: "semibold", children: blockLabel(block, registry) }),
|
|
856
|
+
/* @__PURE__ */ jsx6(Text2, { as: "span", variant: "bodySm", tone: "subdued", children: block.id })
|
|
831
857
|
] }, block.id)) })
|
|
832
858
|
] }),
|
|
833
859
|
/* @__PURE__ */ jsxs4("main", { className: "pb-canvas-area", children: [
|
|
834
|
-
/* @__PURE__ */
|
|
860
|
+
/* @__PURE__ */ jsx6("div", { className: "pb-canvas-toolbar", children: /* @__PURE__ */ jsx6(ButtonGroup2, { variant: "segmented", children: Object.keys(deviceLabels2).map((device) => /* @__PURE__ */ jsx6(Button2, { pressed: editor.device === device, onClick: () => editor.setDevice(device), children: i18n.t(deviceLabels2[device]) }, device)) }) }),
|
|
835
861
|
/* @__PURE__ */ jsxs4("div", { className: "pb-canvas-stage", children: [
|
|
836
|
-
/* @__PURE__ */
|
|
862
|
+
/* @__PURE__ */ jsx6("div", { ref: canvasFrameRef, className: `pb-canvas-frame pb-canvas-frame--${editor.device}`, "data-device": editor.device, children: /* @__PURE__ */ jsx6(Puck2.Preview, {}) }),
|
|
837
863
|
draggingLibraryType ? /* @__PURE__ */ jsxs4("div", { className: "pb-canvas-drop-target", "data-testid": "canvas-drop-target", role: "region", "aria-label": "\u533A\u5757\u6295\u653E\u533A", onDragOver: (event) => event.preventDefault(), onDrop: dropFromLibrary, children: [
|
|
838
864
|
"\u677E\u5F00\u4EE5\u6DFB\u52A0 ",
|
|
839
865
|
blockTypeLabel(draggingLibraryType, registry)
|
|
840
866
|
] }) : null,
|
|
841
867
|
editor.selectedBlock ? /* @__PURE__ */ jsxs4("div", { className: "pb-canvas-overlay", "aria-label": `\u5DF2\u9009\u62E9 ${blockLabel(editor.selectedBlock, registry)}`, children: [
|
|
842
|
-
/* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
868
|
+
/* @__PURE__ */ jsx6("span", { children: blockLabel(editor.selectedBlock, registry) }),
|
|
869
|
+
/* @__PURE__ */ jsx6("span", { children: "Selected" })
|
|
844
870
|
] }) : null
|
|
845
871
|
] })
|
|
846
872
|
] }),
|
|
847
873
|
/* @__PURE__ */ jsxs4("aside", { className: "pb-right-panel", "aria-label": "PageDocument \u5C5E\u6027", children: [
|
|
848
|
-
/* @__PURE__ */
|
|
849
|
-
editor.selectedBlock ? /* @__PURE__ */
|
|
874
|
+
/* @__PURE__ */ jsx6(Text2, { as: "h2", variant: "headingSm", children: i18n.t("properties") }),
|
|
875
|
+
editor.selectedBlock ? /* @__PURE__ */ jsx6(DocumentInspector, { block: editor.selectedBlock, registry, disabled: !editor.actionState.canEdit, onChange: (props) => editor.updateBlockProps(editor.selectedBlock.id, props) }) : /* @__PURE__ */ jsx6(Text2, { as: "p", tone: "subdued", children: i18n.t("selectBlock") })
|
|
850
876
|
] })
|
|
851
877
|
] })
|
|
852
878
|
] })
|
|
@@ -854,11 +880,11 @@ function PageDocumentEditor({ iframe = true, registry, adminLocale, onSave, onPu
|
|
|
854
880
|
}
|
|
855
881
|
function CanvasSelectionBridge({ data, requestedBlockId, onCanvasSelected, canvasMutationVersion }) {
|
|
856
882
|
const puck = usePuck();
|
|
857
|
-
const lastSelectedId =
|
|
858
|
-
const lastSyncedData =
|
|
859
|
-
const lastCanvasMutationVersion =
|
|
883
|
+
const lastSelectedId = useRef4(null);
|
|
884
|
+
const lastSyncedData = useRef4(null);
|
|
885
|
+
const lastCanvasMutationVersion = useRef4(0);
|
|
860
886
|
const serializedData = JSON.stringify(data);
|
|
861
|
-
|
|
887
|
+
useEffect3(() => {
|
|
862
888
|
if (lastSyncedData.current === serializedData) return;
|
|
863
889
|
lastSyncedData.current = serializedData;
|
|
864
890
|
if (canvasMutationVersion > lastCanvasMutationVersion.current) {
|
|
@@ -867,13 +893,13 @@ function CanvasSelectionBridge({ data, requestedBlockId, onCanvasSelected, canva
|
|
|
867
893
|
}
|
|
868
894
|
puck.dispatch({ type: "setData", data });
|
|
869
895
|
}, [canvasMutationVersion, data, puck, serializedData]);
|
|
870
|
-
|
|
896
|
+
useEffect3(() => {
|
|
871
897
|
if (!requestedBlockId) return;
|
|
872
898
|
const selector = puck.getSelectorForId(requestedBlockId);
|
|
873
899
|
if (selector) puck.dispatch({ type: "setUi", ui: { itemSelector: selector } });
|
|
874
900
|
}, [puck, requestedBlockId]);
|
|
875
901
|
const selectedId = typeof puck.selectedItem?.props.id === "string" ? puck.selectedItem.props.id : null;
|
|
876
|
-
|
|
902
|
+
useEffect3(() => {
|
|
877
903
|
if (selectedId && lastSelectedId.current !== selectedId) {
|
|
878
904
|
lastSelectedId.current = selectedId;
|
|
879
905
|
onCanvasSelected(selectedId);
|
|
@@ -885,22 +911,62 @@ function EditorStatus({ state }) {
|
|
|
885
911
|
const i18n = createAdminI18n();
|
|
886
912
|
const tone = state === "error" ? "critical" : state === "disabled" ? "warning" : "info";
|
|
887
913
|
const message = state === "loading" ? i18n.t("loading") : state === "empty" ? i18n.t("empty") : state === "error" ? i18n.t("error") : i18n.t("disabled");
|
|
888
|
-
return /* @__PURE__ */
|
|
914
|
+
return /* @__PURE__ */ jsx6("div", { className: "pb-editor-status", "data-testid": "page-document-editor-state", "data-editor-state": state, children: /* @__PURE__ */ jsx6(Banner, { tone, title: message, children: state === "disabled" ? i18n.t("disabled") : message }) });
|
|
915
|
+
}
|
|
916
|
+
function InspectorSection({ title, children, defaultOpen = true }) {
|
|
917
|
+
return /* @__PURE__ */ jsxs4("details", { className: "pb-inspector-section", open: defaultOpen, children: [
|
|
918
|
+
/* @__PURE__ */ jsxs4("summary", { children: [
|
|
919
|
+
/* @__PURE__ */ jsx6("span", { children: title }),
|
|
920
|
+
/* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: "\u2304" })
|
|
921
|
+
] }),
|
|
922
|
+
/* @__PURE__ */ jsx6("div", { className: "pb-inspector-section__body", children })
|
|
923
|
+
] });
|
|
924
|
+
}
|
|
925
|
+
function InspectorTextControl({ label, value, control, disabled, onChange }) {
|
|
926
|
+
const stringValue = typeof value === "string" ? value : "";
|
|
927
|
+
return /* @__PURE__ */ jsx6(TextField, { label, labelHidden: true, value: stringValue, onChange, autoComplete: "off", disabled, multiline: control === "textarea" ? 4 : false, type: control === "url" ? "url" : "text" });
|
|
928
|
+
}
|
|
929
|
+
function InspectorField({ name, field, value, registry, disabled, onChange }) {
|
|
930
|
+
const label = field.label ?? name;
|
|
931
|
+
const Field = registry?.getField(field.field)?.component;
|
|
932
|
+
return /* @__PURE__ */ jsxs4("div", { className: "pb-inspector-field", "data-control": field.control ?? "custom", children: [
|
|
933
|
+
/* @__PURE__ */ jsxs4("div", { className: "pb-inspector-field__heading", children: [
|
|
934
|
+
/* @__PURE__ */ jsx6(Text2, { as: "p", variant: "bodySm", fontWeight: "semibold", children: label }),
|
|
935
|
+
field.description ? /* @__PURE__ */ jsx6(Text2, { as: "p", variant: "bodySm", tone: "subdued", children: field.description }) : null
|
|
936
|
+
] }),
|
|
937
|
+
field.control ? /* @__PURE__ */ jsx6(InspectorTextControl, { label, value, control: field.control, disabled, onChange: (next) => onChange(next) }) : Field ? /* @__PURE__ */ jsx6(Field, { value, onChange }) : null
|
|
938
|
+
] });
|
|
939
|
+
}
|
|
940
|
+
function inspectorFieldConfig(name, field) {
|
|
941
|
+
const key = name.toLowerCase();
|
|
942
|
+
const group = /(?:href|url)/.test(key) ? "Links" : /(?:default|shipment|query|hide)/.test(key) ? "Tracking settings" : /(?:id|variant|theme)/.test(key) ? "Advanced" : "Content";
|
|
943
|
+
const description = field.description ?? (field.control === "textarea" ? "\u9002\u5408\u8F83\u957F\u6216\u591A\u884C\u7684\u5C55\u793A\u6587\u6848\u3002" : field.control === "url" ? "\u4F7F\u7528\u7AD9\u5185\u76F8\u5BF9\u8DEF\u5F84\u6216 HTTPS \u5730\u5740\u3002" : key.includes("shipment") ? "\u591A\u4E2A\u5305\u88F9\u6807\u7B7E\u4F7F\u7528 | \u5206\u9694\u3002" : key.includes("default") ? "\u4EC5\u7528\u4E8E\u7F16\u8F91\u5668\u548C\u7A7A\u72B6\u6001\u9884\u89C8\u3002" : void 0);
|
|
944
|
+
return { ...field, group: field.group ?? group, description };
|
|
889
945
|
}
|
|
890
946
|
function DocumentInspector({ block, registry, disabled, onChange }) {
|
|
891
947
|
const definition = registry?.getBlock(block.type);
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
948
|
+
const groupedFields = definition ? Object.entries(definition.fields).reduce((groups, entry) => {
|
|
949
|
+
const [name, field] = entry;
|
|
950
|
+
const configuredField = inspectorFieldConfig(name, field);
|
|
951
|
+
const group = configuredField.group ?? "Content";
|
|
952
|
+
(groups[group] ??= []).push([name, configuredField]);
|
|
953
|
+
return groups;
|
|
954
|
+
}, {}) : {};
|
|
955
|
+
return /* @__PURE__ */ jsxs4("div", { className: "pb-inspector", "data-testid": "document-inspector", children: [
|
|
956
|
+
/* @__PURE__ */ jsxs4("header", { className: "pb-inspector__header", children: [
|
|
957
|
+
/* @__PURE__ */ jsx6(Badge2, { children: block.type }),
|
|
958
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
959
|
+
/* @__PURE__ */ jsx6(Text2, { as: "p", variant: "headingSm", children: blockLabel(block, registry) }),
|
|
960
|
+
/* @__PURE__ */ jsx6(Text2, { as: "p", variant: "bodySm", tone: "subdued", children: definition?.category ?? "Core block" })
|
|
961
|
+
] })
|
|
962
|
+
] }),
|
|
963
|
+
block.type === "core.text" ? /* @__PURE__ */ jsx6(InspectorSection, { title: "Content", children: /* @__PURE__ */ jsx6(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, onChange: (content) => onChange({ content }) }) }) : null,
|
|
964
|
+
block.type === "core.image" ? /* @__PURE__ */ jsxs4(InspectorSection, { title: "Image", children: [
|
|
965
|
+
/* @__PURE__ */ jsx6(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, onChange: (src) => onChange({ src }) }),
|
|
966
|
+
/* @__PURE__ */ jsx6(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, onChange: (alt) => onChange({ alt }) })
|
|
899
967
|
] }) : null,
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
return Field ? /* @__PURE__ */ jsx5(Field, { value: block.props[name], onChange: (value) => onChange({ ...block.props, [name]: value }) }, name) : null;
|
|
903
|
-
}) : null
|
|
968
|
+
Object.entries(groupedFields).map(([group, fields]) => /* @__PURE__ */ jsx6(InspectorSection, { title: group, defaultOpen: group !== "Advanced", children: fields.map(([name, field]) => /* @__PURE__ */ jsx6(InspectorField, { name, field, value: block.props[name], registry, disabled, onChange: (value) => onChange({ ...block.props, [name]: value }) }, name)) }, group)),
|
|
969
|
+
definition ? /* @__PURE__ */ jsx6("p", { className: "pb-inspector__hint", children: "\u753B\u5E03\u4E2D\u5E26\u865A\u7EBF\u8FB9\u6846\u7684\u5185\u5BB9\u53EF\u76F4\u63A5\u7F16\u8F91\u3002" }) : null
|
|
904
970
|
] });
|
|
905
971
|
}
|
|
906
972
|
export {
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { WebRenderer, WebRendererProps } from './renderer.js';
|
|
2
|
-
export { BlockDefinition, BlockVariantDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, TemplateRegistry, TemplateSource, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry, createTemplateRegistry } from './extensions.js';
|
|
2
|
+
export { BlockDefinition, BlockEditorProps, BlockVariantDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, TemplateRegistry, TemplateSource, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry, createTemplateRegistry } from './extensions.js';
|
|
3
3
|
export { BlockNode, BlockStyleOverrides, DataBinding, JsonPrimitive, JsonValue, PageDocument, PageDocumentIssue, PageDocumentMigration, PageDocumentSchemaVersion, PageDocumentValidation, PageSettings, RenderTarget, createPageDocument, migratePageDocument, validatePageDocument } from './schema.js';
|
|
4
4
|
export { ThemeTokenName, ThemeTokenValidation, ThemeTokens, mergeThemeTokens, normalizeThemeTokens, systemThemeTokens, toThemeStyle } from './theme.js';
|
|
5
5
|
import 'react';
|
package/package.json
CHANGED
package/src/styles.css
CHANGED
|
@@ -13,7 +13,30 @@ button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--b
|
|
|
13
13
|
.pb-tool-rail .Polaris-Button { min-width: 44px; min-height: 44px; }
|
|
14
14
|
.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); }
|
|
15
15
|
.pb-left-panel { border-right: 1px solid var(--builder-border); }
|
|
16
|
-
.pb-right-panel { border-left: 1px solid var(--builder-border); }
|
|
16
|
+
.pb-right-panel { border-left: 1px solid var(--builder-border); background: #f8fafc; }
|
|
17
|
+
.pb-right-panel > h2 { margin: 0; color: #475569; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; }
|
|
18
|
+
.pb-inspector { display: grid; gap: var(--builder-space-3); }
|
|
19
|
+
.pb-inspector__header { display: grid; gap: var(--builder-space-2); padding: var(--builder-space-3); border: 1px solid #e2e8f0; border-radius: 12px; background: #fff; box-shadow: 0 1px 2px rgb(15 23 42 / 4%); }
|
|
20
|
+
.pb-inspector__header .Polaris-Badge { width: fit-content; max-width: 100%; overflow: hidden; color: #1d4ed8; background: #eff6ff; font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
|
|
21
|
+
.pb-inspector__header p { margin: 0; }
|
|
22
|
+
.pb-inspector-section { overflow: hidden; border: 1px solid #e2e8f0; border-radius: 12px; background: #fff; box-shadow: 0 1px 2px rgb(15 23 42 / 3%); }
|
|
23
|
+
.pb-inspector-section > summary { display: flex; align-items: center; justify-content: space-between; min-height: 44px; padding: 0 var(--builder-space-3); color: #0f172a; font-size: 13px; font-weight: 650; cursor: pointer; list-style: none; }
|
|
24
|
+
.pb-inspector-section > summary::-webkit-details-marker { display: none; }
|
|
25
|
+
.pb-inspector-section > summary > span:last-child { color: #64748b; font-size: 16px; transition: transform 140ms ease; }
|
|
26
|
+
.pb-inspector-section:not([open]) > summary > span:last-child { transform: rotate(-90deg); }
|
|
27
|
+
.pb-inspector-section__body { display: grid; gap: var(--builder-space-3); padding: 0 var(--builder-space-3) var(--builder-space-3); border-top: 1px solid #f1f5f9; }
|
|
28
|
+
.pb-inspector-field { display: grid; gap: 6px; }
|
|
29
|
+
.pb-inspector-field__heading { display: grid; gap: 2px; }
|
|
30
|
+
.pb-inspector-field__heading p { margin: 0; }
|
|
31
|
+
.pb-inspector-field__heading p:first-child { color: #334155; font-size: 13px; }
|
|
32
|
+
.pb-inspector-field__heading p:last-child { color: #64748b; font-size: 12px; line-height: 1.45; }
|
|
33
|
+
.pb-inspector-field input, .pb-inspector-field textarea { width: 100%; min-height: 40px; padding: 9px 11px; border: 1px solid #cbd5e1; border-radius: 8px; outline: 0; color: #0f172a; background: #fff; font: inherit; font-size: 14px; line-height: 1.4; transition: border-color 140ms ease, box-shadow 140ms ease; }
|
|
34
|
+
.pb-inspector-field textarea { min-height: 96px; resize: vertical; }
|
|
35
|
+
.pb-inspector-field input[type="url"] { color: #334155; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
|
|
36
|
+
.pb-inspector-field input:hover, .pb-inspector-field textarea:hover { border-color: #94a3b8; }
|
|
37
|
+
.pb-inspector-field input:focus, .pb-inspector-field textarea:focus { border-color: #2563eb; box-shadow: 0 0 0 3px rgb(37 99 235 / 12%); }
|
|
38
|
+
.pb-inspector-field input:disabled, .pb-inspector-field textarea:disabled { color: #94a3b8; background: #f8fafc; cursor: not-allowed; }
|
|
39
|
+
.pb-inspector__hint { margin: 0; padding: 0 var(--builder-space-2); color: #64748b; font-size: 12px; line-height: 1.5; }
|
|
17
40
|
.pb-panel--closed { display: none; }
|
|
18
41
|
.pb-block-list { display: flex; flex: 1; flex-direction: column; gap: var(--builder-space-2); min-height: 0; }
|
|
19
42
|
.pb-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; transition: background-color 120ms ease, border-color 120ms ease; }
|