pagepilot-visual-editor 1.0.33 → 1.0.35

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 (58) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/editor/publish/PagePublishDialog.d.ts +2 -0
  3. package/dist/editor-sample/App/InspectorDrawer/ConfigurationPanel/input-panels/helpers/inputs/VariableLinkHint.d.ts +12 -0
  4. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/ChangeDesignFlow.d.ts +16 -0
  5. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/ChangeTemplateCompareDialog.d.ts +25 -0
  6. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/ChangeTemplateVariablesPane.d.ts +14 -0
  7. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/SectionLibraryTab.d.ts +9 -0
  8. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/SectionsModal.d.ts +9 -0
  9. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/TemplatePreviewDialog.d.ts +5 -1
  10. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/index.d.ts +1 -0
  11. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/templateCategory.d.ts +1 -0
  12. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/templateHelpers.d.ts +14 -26
  13. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/ArrayFieldEditor.d.ts +3 -0
  14. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/DataReferencePanel.d.ts +3 -1
  15. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/EditVariableDialog.d.ts +9 -0
  16. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/RowCard.d.ts +10 -2
  17. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/ScalarFieldRow.d.ts +3 -1
  18. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/dataReferenceUtils.d.ts +20 -5
  19. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/useAutoRefreshDataSources.d.ts +8 -0
  20. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/useAutoRegisterTokenFields.d.ts +5 -0
  21. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/variableEditActions.d.ts +32 -0
  22. package/dist/editor-sample/App/InspectorDrawer/components/DateFieldControls.d.ts +2 -1
  23. package/dist/editor-sample/App/InspectorDrawer/components/DateTimeFieldControls.d.ts +2 -1
  24. package/dist/editor-sample/App/InspectorDrawer/components/MiniRichTextInput.d.ts +1 -0
  25. package/dist/editor-sample/App/InspectorDrawer/components/ScalarFieldInput.d.ts +2 -1
  26. package/dist/editor-sample/App/InspectorDrawer/components/TimeFieldControls.d.ts +2 -1
  27. package/dist/editor-sample/App/hooks/page/useSaveHandler.d.ts +1 -0
  28. package/dist/editor-sample/App/shared/SectionsDropdown.d.ts +2 -2
  29. package/dist/editor-sample/App/shared/pageSections.d.ts +7 -0
  30. package/dist/editor-sample/documents/blocks/MenuPicker/MenuPropsSchema.d.ts +3 -0
  31. package/dist/editor-sample/documents/blocks/MenuPicker/menuBlockLabel.d.ts +4 -0
  32. package/dist/editor-sample/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/ScopePickerMenu.d.ts +3 -2
  33. package/dist/editor-sample/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/index.d.ts +2 -1
  34. package/dist/editor-sample/documents/blocks/helpers/block-wrappers/saveAsTemplateUtils.d.ts +10 -0
  35. package/dist/editor-sample/documents/blocks/helpers/documentUtils.d.ts +6 -0
  36. package/dist/editor-sample/documents/editor/EditorContext.d.ts +2 -2
  37. package/dist/editor-sample/documents/editor/changeSectionDesign.d.ts +36 -0
  38. package/dist/editor-sample/documents/editor/core.d.ts +3 -0
  39. package/dist/editor-sample/documents/editor/sectionScope.d.ts +73 -0
  40. package/dist/editor-sample/documents/editor/templateVariables.d.ts +11 -2
  41. package/dist/email-builder-core/blocks/MenuPicker/MenuColumns.d.ts +3 -1
  42. package/dist/email-builder-core/blocks/MenuPicker/MenuPropsSchema.d.ts +6 -0
  43. package/dist/host-stubs/config.d.ts +4 -0
  44. package/dist/host-stubs/modules/content/view/contentViewSelectors.d.ts +4 -0
  45. package/dist/host-stubs/view/page/form/dialog/PageVariablesPreview.d.ts +5 -0
  46. package/dist/host-stubs/view/template/form/fields/renameFieldTokens.d.ts +26 -0
  47. package/dist/host-stubs/view/template/form/fields/types.d.ts +101 -0
  48. package/dist/{index-BfIWhBCR.cjs → index-BoRfsMEk.cjs} +327 -327
  49. package/dist/{index-BONR8bWR.js → index-BzP_d1Tz.js} +1 -1
  50. package/dist/{index-CFA3aG_U.cjs → index-CQKG85qV.cjs} +1 -1
  51. package/dist/{index-B_cb-ZLC.js → index-CZDJUpCA.js} +37245 -35216
  52. package/dist/index.cjs +1 -1
  53. package/dist/index.js +1 -1
  54. package/dist/render.cjs +115 -115
  55. package/dist/render.js +1616 -1592
  56. package/dist/{xlsx-CBpoXUEM.cjs → xlsx-Bc8RxjL3.cjs} +1 -1
  57. package/dist/{xlsx-DSqBw3Em.js → xlsx-ChzvWWQV.js} +1 -1
  58. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
  ## [Unreleased]
8
8
 
9
9
  ### Changed
10
+ - Synced ahd-fe bc20f58b2 (auto refresh minutes):
11
+ - Pages data source now GETs `/tenant/:id/client/page` with only the mapped
12
+ fields (`buildPagesUrl`) and maps raw page rows onto sub-field ids
13
+ client-side (`mapPageRows`), in the panel and in editor auto-refresh.
14
+ Field list / mapping guesses updated (`groups`, `createdAt`, `heroImage`);
15
+ a saved mapping to an unlisted field stays selectable.
16
+ - Per-source TTL inputs removed from the API / Pages source forms; auto
17
+ refresh is now page-level: "Auto Refresh (minutes)" in the publish dialog,
18
+ sent as `ttlMinutes` on `upsert-page-item` and merged into the record.
19
+ - Re-synced the vendored editor with ahd-fe `plugin-integration` (2aa96315d),
20
+ covering everything since the 67f2b933 sync. Upstream behaviour pulled in
21
+ includes:
22
+ - "Change design" in the block tune menu: swap a template section for
23
+ another design, carrying content over (`sectionScope`,
24
+ `changeSectionDesign`, `ChangeDesignFlow`, compare dialog + variables pane).
25
+ - "Edit variable" dialog: rename a `{{token}}` across the page or convert it
26
+ back to plain text, from the Variables tab, bound inputs or the canvas.
27
+ - MenuPicker: sub-menu text color / font size / font weight, header /
28
+ footer / navigation labels, page-link picker for site pages.
29
+ - Layers panel: section category in labels, copy/paste whole page buttons
30
+ disabled when there's nothing to copy/paste.
31
+ - Add-block keeps preassigned IDs, "Edit Content" in the add menu, Section
32
+ Library "View all" / "All sections", Video / Rating / Progress token fields.
33
+ - Inline text caret is restored correctly on undo/redo.
34
+ - Host stubs: `modules/content/view/contentViewSelectors` (no record),
35
+ trimmed `view/page/form/dialog/PageVariablesPreview`, full
36
+ `view/template/form/fields/types` + `renameFieldTokens`; i18n defaults
37
+ regenerated with the new keys.
10
38
  - Re-synced the vendored editor with ahd-fe `master` (9661ba36b), on top of
11
39
  the 82ec6ec4b sync below. Upstream behaviour pulled in includes:
12
40
  - Host-application theme support (theme slots, surface lock, dark-host
@@ -24,6 +24,8 @@ interface PagePublishDialogProps {
24
24
  injectCarouselScript?: boolean;
25
25
  injectPaginationScript?: boolean;
26
26
  injectAnimationScript?: boolean;
27
+ /** Page-level auto refresh in minutes (0 = off). */
28
+ ttlMinutes?: number;
27
29
  }) => Promise<boolean>;
28
30
  }
29
31
  export default function PagePublishDialog({ open, onClose, record, apiClient, onSubmit, }: PagePublishDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,16 @@
1
1
  import { default as React } from 'react';
2
+ /** Inline "Edit variable" link — rename the token(s) behind `value` or convert them to text. */
3
+ export declare function EditVariableLink({ value }: {
4
+ value: string;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ /**
7
+ * Compact pencil (fits inside a locked input's end adornment) opening "Edit
8
+ * variable". Opts back into pointer events — VariableBoundClickArea switches
9
+ * them off on the input — and stops the click reaching that wrapper.
10
+ */
11
+ export declare function EditVariableIcon({ value }: {
12
+ value: string;
13
+ }): import("react/jsx-runtime").JSX.Element;
2
14
  /**
3
15
  * Wraps a locked, variable-bound input so clicking anywhere on it jumps to the
4
16
  * Variables tab (a disabled input swallows clicks itself, so its own pointer
@@ -0,0 +1,16 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * "Change design" for one section: pick a block template (the library opens
4
+ * on the section's category), review the section before/after, then swap it
5
+ * in place keeping the section's content. See changeSectionDesign.
6
+ */
7
+ declare const ChangeDesignFlow: React.FC<{
8
+ blockId: string;
9
+ open: boolean;
10
+ onClose: () => void;
11
+ /** Render the library in the sidebar (Section library tab) instead of a dialog. */
12
+ inline?: boolean;
13
+ /** Offer "Add as new section" in the compare dialog; inserts the picked section. */
14
+ onInsert?: (block: any, preassignedId?: string) => void;
15
+ }>;
16
+ export default ChangeDesignFlow;
@@ -0,0 +1,25 @@
1
+ import { default as React } from 'react';
2
+ import { FieldPatches } from './templateHelpers';
3
+ interface ChangeTemplateCompareDialogProps {
4
+ open: boolean;
5
+ templateId?: string;
6
+ before: any;
7
+ after: any;
8
+ loading?: boolean;
9
+ onConfirm: (fieldPatches?: FieldPatches) => void;
10
+ onClose: () => void;
11
+ title?: string;
12
+ description?: string;
13
+ confirmLabel?: string;
14
+ secondaryLabel?: string;
15
+ onSecondary?: () => void;
16
+ notes?: string[];
17
+ }
18
+ /**
19
+ * "Change template" confirm: the current page on the left, the page as it
20
+ * will look after the change on the right — either rendered, or as each
21
+ * side's variables. The right side's variable values can be edited; the
22
+ * edits ride along with the confirm.
23
+ */
24
+ declare const ChangeTemplateCompareDialog: React.FC<ChangeTemplateCompareDialogProps>;
25
+ export default ChangeTemplateCompareDialog;
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ import { TemplateFormField } from '../../../documents/editor/templateVariables';
3
+ /**
4
+ * A page's variables (`root.data.formFields`), grouped the way the editor's
5
+ * Variables tab groups them. The "Change template" compare shows one per
6
+ * side, so the user sees which values the new template keeps; with
7
+ * `onPatch` the values can be edited before the change is applied, without
8
+ * it the same fields render disabled.
9
+ */
10
+ declare const ChangeTemplateVariablesPane: React.FC<{
11
+ document: any;
12
+ onPatch?: (fieldId: string, patch: Partial<TemplateFormField>) => void;
13
+ }>;
14
+ export default ChangeTemplateVariablesPane;
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * Section library sidebar tab. With a section selected on the canvas it works
4
+ * like the tune menu's "Change design" (opens on the section's category, pick →
5
+ * before/after compare → swap in place, or "Add as new section" from the
6
+ * compare dialog); otherwise picking appends a section.
7
+ */
8
+ declare const SectionLibraryTab: React.FC;
9
+ export default SectionLibraryTab;
@@ -2,6 +2,15 @@ interface SectionsModalProps {
2
2
  open: boolean;
3
3
  onClose: () => void;
4
4
  onInsert?: (block: any, preassignedId?: string) => void;
5
+ /** Category tab to open on (falls back to "Overall" when it has no templates). */
6
+ initialCategory?: string;
7
+ /** Pick mode ("Change design"): hand the fetched template back instead of inserting it. */
8
+ onPick?: (record: any) => void;
9
+ title?: string;
10
+ /** Render without the Dialog, laid out for the narrow left-panel tab. */
11
+ inline?: boolean;
5
12
  }
13
+ /** Insert a fetched section template into the page (as a new section). */
14
+ export declare function insertSectionRecord(record: any, onInsert?: (block: any, preassignedId?: string) => void): void;
6
15
  declare const SectionsModal: React.FC<SectionsModalProps>;
7
16
  export default SectionsModal;
@@ -12,5 +12,9 @@ export interface TemplatePreviewDialogProps {
12
12
  changeLoading?: boolean;
13
13
  /** True when the template is gated to a plan the tenant doesn't have. */
14
14
  locked?: boolean;
15
+ /** Hide the "Choose design" (use whole template) button, e.g. in the Section library. */
16
+ hideUse?: boolean;
17
+ /** Dialog title; defaults to "Template Preview". */
18
+ title?: string;
15
19
  }
16
- export default function TemplatePreviewDialog({ open, template, onClose, onUse, onUseStyles, onAppend, loading, styleLoading, appendLoading, onChangeTemplate, changeLoading, locked, }: TemplatePreviewDialogProps): import("react/jsx-runtime").JSX.Element;
20
+ export default function TemplatePreviewDialog({ open, template, onClose, onUse, onUseStyles, onAppend, loading, styleLoading, appendLoading, onChangeTemplate, changeLoading, locked, hideUse, title, }: TemplatePreviewDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -2,5 +2,6 @@ interface LayoutPanelProps {
2
2
  record?: any;
3
3
  onUpdateRecord?: (record: any) => void;
4
4
  }
5
+ export declare const appendSectionToRoot: (block: any, preassignedId?: string) => void;
5
6
  declare const LayoutPanel: (_props: LayoutPanelProps) => import("react/jsx-runtime").JSX.Element;
6
7
  export default LayoutPanel;
@@ -0,0 +1 @@
1
+ export declare function humanizeCategory(category: string): string;
@@ -79,32 +79,12 @@ export declare function mergeTemplateFormFields(templateRecord: any, idMapping?:
79
79
  [oldId: string]: string;
80
80
  }): void;
81
81
  /**
82
- * Merge incoming formFields into the existing ones. Used by "Add this section"
83
- * so adding Template B that shares {{name}} with Template A keeps the typed
84
- * value and only appends B's new fields. Then jumps to Variables.
85
- *
86
- * Two dedupe rules — different because these fields mean different things:
87
- *
88
- * - Scalar / plain-array fields are dedupe'd by `id`. A page-level `{{name}}`
89
- * is a single slot; inserting Template B that also references `{{name}}`
90
- * should reuse Template A's (possibly user-filled) value, not stomp it.
91
- *
92
- * - Container-repeat fields (`type === 'array' && sourceBlockId`) are dedupe'd
93
- * by `sourceBlockId`. Each such field is scoped to ONE container instance
94
- * (a specific Grid / FlexColumns / Carousel), and its `sourceBlockId` gets
95
- * remapped per insertion. Inserting a testimonial section twice produces
96
- * two independent grid instances; BOTH need their own field or the second
97
- * grid's `{{this.subField}}` tokens can't find their row in
98
- * `buildRepeatRowIndex` (which keys off sourceBlockId/rowIds) and render as
99
- * bare pills. Same-token-id but different sourceBlockId → different field.
100
- *
101
- * When a new container-repeat field's id collides with an already-registered
102
- * field (either a scalar sharing that name, or the same section inserted
103
- * before), we suffix the id with its sourceBlockId so `buildContext` doesn't
104
- * silently overwrite the earlier field. Sub-field tokens (`{{this.X}}`) are
105
- * resolved via the row index by block id, so they don't care about the outer
106
- * field's id.
82
+ * "Choose design" with a multi-section page template: replaces the page's
83
+ * sections with the template's (each carrying its own prefilled variables),
84
+ * loads the first internal section onto the canvas and returns its index so
85
+ * the caller can make it active.
107
86
  */
87
+ export declare function applyPageSectionsTemplate(configuration: any, templateRecord: any, record: any, onUpdateRecord: (record: any) => void, resetDocument: (doc: any) => void): number;
108
88
  export declare function appendTemplateFormFields(templateRecord: any, idMapping?: {
109
89
  [oldId: string]: string;
110
90
  }): void;
@@ -119,7 +99,15 @@ export declare const buildChangeTemplateDocument: (configuration: any, document:
119
99
  fields: any[];
120
100
  current: any;
121
101
  } | null;
122
- export declare const applyChangeTemplate: (configuration: any, document: any, resetDocument: (doc: any) => void, templateRecord?: any) => void;
102
+ export type FieldPatches = Record<string, Record<string, any>>;
103
+ /**
104
+ * Apply field edits (field id → patch) made in the "Change template" compare
105
+ * to a document's `root.data.formFields`. An items-array field's rows are
106
+ * mirrored onto its block's items too — those blocks render from their own
107
+ * props, not from the field.
108
+ */
109
+ export declare const applyFieldPatches: (doc: any, patches: FieldPatches) => any;
110
+ export declare const applyChangeTemplate: (configuration: any, document: any, resetDocument: (doc: any) => void, templateRecord?: any, fieldPatches?: FieldPatches) => void;
123
111
  /**
124
112
  * "Use this Styles" for non-tour modules (pages, FAQ, app-banner, tooltip,
125
113
  * template). Applies the template's styling — the root canvas AND every
@@ -1,4 +1,7 @@
1
1
  import { TemplateArrayRow, TemplateFormField } from '../../../documents/editor/templateVariables';
2
+ /** Window event `{ fieldId, rowIndex }` — expand that row (canvas selection
3
+ * landed inside a repeated copy). */
4
+ export declare const FOCUS_REPEAT_ROW_EVENT = "variables:focus-repeat-row";
2
5
  type ArrayFieldEditorProps = {
3
6
  field: TemplateFormField;
4
7
  onChange: (rows: TemplateArrayRow[]) => void;
@@ -8,6 +8,8 @@ type DataReferencePanelProps = {
8
8
  addRow: () => void;
9
9
  removeRow: (rowIndex: number) => void;
10
10
  updateCell: (rowIndex: number, key: string, value: string) => void;
11
+ /** Drag-and-drop reorder of the item list. */
12
+ moveRow?: (from: number, to: number) => void;
11
13
  onPatch?: (patch: Partial<TemplateFormField>) => void;
12
14
  };
13
15
  /**
@@ -16,5 +18,5 @@ type DataReferencePanelProps = {
16
18
  * an API endpoint, or a Menu. JSON/API/Menu seed one copy per object, mapping
17
19
  * object keys → sub-field ids.
18
20
  */
19
- export default function DataReferencePanel({ field, rows, itemFields, expandedRow, toggleRow, addRow, removeRow, updateCell, onPatch, }: DataReferencePanelProps): import("react/jsx-runtime").JSX.Element;
21
+ export default function DataReferencePanel({ field, rows, itemFields, expandedRow, toggleRow, addRow, removeRow, updateCell, moveRow, onPatch, }: DataReferencePanelProps): import("react/jsx-runtime").JSX.Element;
20
22
  export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * "Edit variable" — rename a declared `{{token}}` / `{{this.token}}` (every
3
+ * use on the page is rewritten, the value is kept) or turn it back into plain
4
+ * text. Opened via `openEditVariable` from the Variables tab, a bound input in
5
+ * the block sidebar, or the canvas tune menu — the last two pass EVERY
6
+ * variable they use (a Button's label + link), so one "Convert to text" frees
7
+ * the whole block.
8
+ */
9
+ export default function EditVariableDialog(): import("react/jsx-runtime").JSX.Element;
@@ -9,15 +9,23 @@ type RowCardProps = {
9
9
  onRemove: null | (() => void);
10
10
  updateCell: (rowIndex: number, key: string, value: string) => void;
11
11
  headerLabel: string;
12
+ /** Read-only: the row still expands, its inputs are disabled. */
13
+ disabled?: boolean;
14
+ /** Shows an "Edit variable" icon per sub-field (`{{this.subId}}` rename/unlink/delete). */
15
+ onEditSub?: (subId: string) => void;
16
+ /** When set, a drag handle is shown in the header (drag-and-drop reorder). */
17
+ dragHandleProps?: React.HTMLAttributes<HTMLElement> & {
18
+ draggable?: boolean;
19
+ };
12
20
  };
13
21
  /**
14
22
  * The bare list of sub-field inputs for one row — no card chrome. Used inside
15
23
  * RowCard (behind its collapse) and directly by the Template Modifier, which
16
24
  * doesn't need a second collapsible layer around its single template row.
17
25
  */
18
- export declare function RowFields({ rowIndex, row, itemFields, updateCell, sx, }: Pick<RowCardProps, 'rowIndex' | 'row' | 'itemFields' | 'updateCell'> & {
26
+ export declare function RowFields({ rowIndex, row, itemFields, updateCell, sx, disabled, onEditSub, }: Pick<RowCardProps, 'rowIndex' | 'row' | 'itemFields' | 'updateCell' | 'disabled' | 'onEditSub'> & {
19
27
  sx?: object;
20
28
  }): import("react/jsx-runtime").JSX.Element;
21
29
  /** One collapsible copy/template card in the Variables array editor. */
22
- export default function RowCard({ rowIndex, row, itemFields, isExpanded, onToggle, onRemove, updateCell, headerLabel, }: RowCardProps): import("react/jsx-runtime").JSX.Element;
30
+ export default function RowCard({ rowIndex, row, itemFields, isExpanded, onToggle, onRemove, updateCell, headerLabel, disabled, onEditSub, dragHandleProps, }: RowCardProps): import("react/jsx-runtime").JSX.Element;
23
31
  export {};
@@ -5,11 +5,13 @@ type Props = {
5
5
  onPatch: (patch: Partial<TemplateFormField>) => void;
6
6
  /** Optional control rendered at the right of the label row (e.g. "locate in canvas"). */
7
7
  headerAction?: ReactNode;
8
+ /** Read-only: shows the value and its controls, all disabled. */
9
+ disabled?: boolean;
8
10
  };
9
11
  /**
10
12
  * One scalar variable row: name, a type selector (Text / Number / Date / Time /
11
13
  * Image), the value input, and — for `date` / `time` — the format + timezone
12
14
  * controls.
13
15
  */
14
- export default function ScalarFieldRow({ field, onPatch, headerAction }: Props): import("react/jsx-runtime").JSX.Element;
16
+ export default function ScalarFieldRow({ field, onPatch, headerAction, disabled }: Props): import("react/jsx-runtime").JSX.Element;
15
17
  export {};
@@ -26,12 +26,14 @@ export declare function buildReferenceJson(itemFields: TemplateFormField['itemFi
26
26
  */
27
27
  export declare function extractArrayFromResponse(body: any, path?: string): Record<string, any>[] | null;
28
28
  /**
29
- * GET a URL and return the array of objects from its JSON response. Throws with
30
- * a user-facing message on a bad URL, network error, non-OK status, non-JSON
31
- * body, or a response that carries no array. Only GET is supported today
32
- * (POST is planned — the panel disables it).
29
+ * GET (or POST with a JSON `body`) a URL and return the array of objects from
30
+ * its JSON response. Throws with a user-facing message on a bad URL, network
31
+ * error, non-OK status, non-JSON body, or a response that carries no array.
33
32
  */
34
- export declare function fetchApiRows(url: string, responsePath?: string): Promise<Record<string, any>[]>;
33
+ export declare function fetchApiRows(url: string, responsePath?: string, request?: {
34
+ method?: 'GET' | 'POST';
35
+ body?: unknown;
36
+ }): Promise<Record<string, any>[]>;
35
37
  /**
36
38
  * GET a URL and return a SINGLE object from its JSON response, for scalar
37
39
  * (non-repeatable) variables. When `responsePath` is given, resolve it via
@@ -50,3 +52,16 @@ export declare function fetchApiObject(url: string, responsePath?: string): Prom
50
52
  export declare function fetchApiRaw(url: string): Promise<string>;
51
53
  /** Copy `text` to the clipboard, toasting success/failure. */
52
54
  export declare function copyToClipboard(text: string): Promise<void>;
55
+ /** Page fields offered in the Pages source mapping (same list as the docs' Endpoint builder). */
56
+ export declare const PAGE_FIELD_OPTIONS: readonly ["slug", "name", "title", "metaDescription", "thumbnailImage", "heroImage", "tags", "groups", "createdAt", "updatedAt"];
57
+ /** Best-guess page field for each sub-field id (unmatched sub-fields are left out). */
58
+ export declare function guessPageFieldMap(itemFields: TemplateFormField['itemFields']): Record<string, string>;
59
+ /** `pageGroup` value meaning "every live page, no group filter". */
60
+ export declare const ALL_PAGES_GROUP = "__all__";
61
+ /**
62
+ * Absolute `client/page` URL for the Pages source — absolute so the backend
63
+ * refresh can call it too. Selects only the mapped fields, never sections.
64
+ */
65
+ export declare function buildPagesUrl(backendUrl: string, tenantId: string, group: string, map: Record<string, string>): string;
66
+ /** Key each raw page row by sub-field id, using the Pages source mapping. */
67
+ export declare function mapPageRows(rows: Record<string, any>[], map: Record<string, string>): Record<string, any>[];
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Live refresh for repeatable fields bound to an `api` / `pages` source with
3
+ * `dataSource.ttlMinutes` set: every N minutes the saved request is re-run and
4
+ * the field reseeded, so the canvas keeps up with the source while the page is
5
+ * open (the published page refreshes server-side on the same interval).
6
+ * Silent: failures keep the current rows; a grid that's too small grows by rows.
7
+ */
8
+ export default function useAutoRefreshDataSources(): void;
@@ -4,5 +4,10 @@
4
4
  * token with no matching form field. Once added it's no longer "missing", so
5
5
  * this can't loop. Mounted from the always-present inspector drawer so the
6
6
  * variable already exists when the Variables tab is opened.
7
+ *
8
+ * A token edited away (present on the previous scan, gone now) drops its
9
+ * field. When exactly one token vanished and one new token appeared it's a
10
+ * rename (`{{old}}` → `{{new}}`): the field is re-keyed in place so its value
11
+ * and settings carry over instead of leaving both variables behind.
7
12
  */
8
13
  export default function useAutoRegisterTokenFields(): void;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A variable the "Edit variable" dialog acts on: a top-level `{{id}}` field,
3
+ * or a `{{this.subId}}` sub-field of a container-repeat field.
4
+ */
5
+ export type VariableEditTarget = {
6
+ fieldId: string;
7
+ subId?: string;
8
+ };
9
+ export type VariableIdError = 'invalid' | 'duplicate';
10
+ /** Opens the dialog for one variable, or every variable a block / input uses. */
11
+ export declare const openEditVariable: (targets: VariableEditTarget | VariableEditTarget[]) => void;
12
+ export declare const closeEditVariable: () => void;
13
+ export declare const useEditVariableState: () => {
14
+ open: boolean;
15
+ targets: VariableEditTarget[];
16
+ openId: number;
17
+ };
18
+ export declare const VARIABLE_ID_RE: RegExp;
19
+ /** All variables a block's own token-bearing props use (a Button: label + link). */
20
+ export declare const getBlockVariableTargets: (blockId: string) => VariableEditTarget[];
21
+ /** All variables behind one bound input value. */
22
+ export declare const getValueVariableTargets: (value: string, blockId: string | null) => VariableEditTarget[];
23
+ /**
24
+ * Per-target reason `nextIds[i]` can't be used, or null when it's fine (or
25
+ * unchanged). Keys must be unique against the page's other variables and
26
+ * against each other within the dialog.
27
+ */
28
+ export declare function validateVariableIds(targets: VariableEditTarget[], nextIds: string[]): (VariableIdError | null)[];
29
+ /** Renames every changed key, as ONE undo step. */
30
+ export declare function renameVariables(targets: VariableEditTarget[], nextIds: string[]): void;
31
+ /** Turns every target back into plain text, as ONE undo step. */
32
+ export declare function unlinkVariables(targets: VariableEditTarget[]): void;
@@ -2,11 +2,12 @@ import { TemplateFormField } from '../../../documents/editor/templateVariables';
2
2
  type Props = {
3
3
  field: TemplateFormField;
4
4
  onPatch: (patch: Partial<TemplateFormField>) => void;
5
+ disabled?: boolean;
5
6
  };
6
7
  /**
7
8
  * Format + timezone controls for a `date` scalar variable, shown under the
8
9
  * datetime input. `relative` recomputes in the reader's browser at view time;
9
10
  * every other preset is a fixed string baked in `dateTz` on publish.
10
11
  */
11
- export default function DateFieldControls({ field, onPatch }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export default function DateFieldControls({ field, onPatch, disabled }: Props): import("react/jsx-runtime").JSX.Element;
12
13
  export {};
@@ -2,6 +2,7 @@ import { TemplateFormField } from '../../../documents/editor/templateVariables';
2
2
  type Props = {
3
3
  field: TemplateFormField;
4
4
  onPatch: (patch: Partial<TemplateFormField>) => void;
5
+ disabled?: boolean;
5
6
  };
6
7
  /**
7
8
  * Controls for a `datetime` scalar variable: one ISO value, exposed as two
@@ -10,5 +11,5 @@ type Props = {
10
11
  * may be `relative` (recomputed in the reader's browser); the time part is
11
12
  * always a fixed string.
12
13
  */
13
- export default function DateTimeFieldControls({ field, onPatch }: Props): import("react/jsx-runtime").JSX.Element;
14
+ export default function DateTimeFieldControls({ field, onPatch, disabled }: Props): import("react/jsx-runtime").JSX.Element;
14
15
  export {};
@@ -3,6 +3,7 @@ type Props = {
3
3
  value: string;
4
4
  onChange: (value: string) => void;
5
5
  fieldId?: string;
6
+ disabled?: boolean;
6
7
  };
7
8
  declare const MiniRichTextInput: React.FC<Props>;
8
9
  export default MiniRichTextInput;
@@ -6,6 +6,7 @@ type Props = {
6
6
  onChange: (value: string) => void;
7
7
  onPaperBackground?: boolean;
8
8
  fieldId?: string;
9
+ disabled?: boolean;
9
10
  };
10
- declare const ScalarFieldInput: ({ type, label, value, onChange, onPaperBackground, fieldId }: Props) => import("react/jsx-runtime").JSX.Element;
11
+ declare const ScalarFieldInput: ({ type, label, value, onChange, onPaperBackground, fieldId, disabled, }: Props) => import("react/jsx-runtime").JSX.Element;
11
12
  export default ScalarFieldInput;
@@ -2,11 +2,12 @@ import { TemplateFormField } from '../../../documents/editor/templateVariables';
2
2
  type Props = {
3
3
  field: TemplateFormField;
4
4
  onPatch: (patch: Partial<TemplateFormField>) => void;
5
+ disabled?: boolean;
5
6
  };
6
7
  /**
7
8
  * Format + timezone controls for a `time` scalar variable, shown under the
8
9
  * datetime input. `time` always bakes to a fixed string (24h or AM/PM) rendered
9
10
  * in the chosen timezone — there's no view-time / relative mode.
10
11
  */
11
- export default function TimeFieldControls({ field, onPatch }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export default function TimeFieldControls({ field, onPatch, disabled }: Props): import("react/jsx-runtime").JSX.Element;
12
13
  export {};
@@ -8,6 +8,7 @@ type UseSaveHandlerReturn = {
8
8
  startDate?: Date | null;
9
9
  endDate?: Date | null;
10
10
  };
11
+ ttlMinutes?: number;
11
12
  }) => Promise<any>;
12
13
  loading: boolean | undefined;
13
14
  };
@@ -3,8 +3,8 @@ type Props = {
3
3
  sections: PageSection[];
4
4
  activeSectionIndex: number;
5
5
  onSelectSection: (index: number) => void;
6
- onDeleteSection: (index: number) => void;
7
- onEditSection: (index: number) => void;
6
+ onDeleteSection?: (index: number) => void;
7
+ onEditSection?: (index: number) => void;
8
8
  onReorderSections?: (fromIndex: number, toIndex: number) => void;
9
9
  };
10
10
  declare const SectionsDropdown: ({ sections, activeSectionIndex, onSelectSection, onDeleteSection, onEditSection, onReorderSections, }: Props) => import("react/jsx-runtime").JSX.Element;
@@ -24,5 +24,12 @@ export declare const isExternalSection: (section: Partial<PageSection> | undefin
24
24
  * Identifier is auto-generated as `${sectionType}-${Date.now()}`.
25
25
  */
26
26
  export declare const createPageSectionFromDraft: (draft: SectionDraft, defaultDocument: TEditorConfiguration) => PageSection;
27
+ /**
28
+ * Turns a multi-section page template's `sections` into page sections, giving
29
+ * each internal section's root the `formFields` tagged for it (`stepIndex` =
30
+ * section index, tag stripped). `existing` sections at the same index keep
31
+ * their `_id` / `identifier` so applying onto a saved page updates in place.
32
+ */
33
+ export declare const buildSectionsFromTemplate: (templateSections: PageSection[], formFields?: any[], existing?: PageSection[]) => PageSection[];
27
34
  /** Writes the live editor document back into the active section before switching or saving. */
28
35
  export declare const mergeCurrentDocumentIntoSections: (sections: PageSection[], activeSectionIndex: number, document: TEditorConfiguration) => PageSection[];
@@ -34,6 +34,9 @@ declare const MenuPropsSchema: z.ZodObject<{
34
34
  submenuBackgroundColor: z.ZodNullable<z.ZodOptional<z.ZodString>>;
35
35
  submenuRadius: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
36
36
  submenuIconSize: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
37
+ submenuTextColor: z.ZodNullable<z.ZodOptional<z.ZodString>>;
38
+ submenuFontSize: z.ZodNullable<z.ZodOptional<z.ZodString>>;
39
+ submenuFontWeight: z.ZodNullable<z.ZodOptional<z.ZodString>>;
37
40
  submenuPadding: z.ZodNullable<z.ZodOptional<z.ZodObject<{
38
41
  top: z.ZodNumber;
39
42
  right: z.ZodNumber;
@@ -0,0 +1,4 @@
1
+ export declare const menuBlockLabel: (props?: {
2
+ navRole?: string | null;
3
+ orientation?: string;
4
+ } | null) => string;
@@ -7,8 +7,9 @@ export type ScopeOption = {
7
7
  };
8
8
  type Props = {
9
9
  anchorEl: HTMLElement | null;
10
- options: [ScopeOption, ScopeOption];
10
+ options: ScopeOption[];
11
11
  onClose: () => void;
12
+ title?: string;
12
13
  };
13
- export default function ScopePickerMenu({ anchorEl, options, onClose }: Props): import("react/jsx-runtime").JSX.Element;
14
+ export default function ScopePickerMenu({ anchorEl, options, onClose, title }: Props): import("react/jsx-runtime").JSX.Element;
14
15
  export {};
@@ -11,6 +11,7 @@ type Props = {
11
11
  containerNeighbors?: ContainerNeighbor[];
12
12
  onInsertIntoContainer?: (block: TEditorBlock, containerId: string, insertAt: 'start' | 'end') => void;
13
13
  insertAboveCallback?: (block: TEditorBlock) => void;
14
+ onEditContent?: () => void;
14
15
  };
15
- export default function AddBlockButton({ onSelect, onPaste, placeholder, suppressAdd, containerNeighbors, onInsertIntoContainer, insertAboveCallback, }: Props): import("react/jsx-runtime").JSX.Element;
16
+ export default function AddBlockButton({ onSelect, onPaste, placeholder, suppressAdd, containerNeighbors, onInsertIntoContainer, insertAboveCallback, onEditContent, }: Props): import("react/jsx-runtime").JSX.Element;
16
17
  export {};
@@ -33,6 +33,8 @@ export type BlockTemplateConfiguration = {
33
33
  * type's own child-id layout) into a flat `{ id: block }` map.
34
34
  */
35
35
  export declare function collectBlockSubtree(document: BlockMap, rootBlockId: string): BlockMap;
36
+ /** `firstName` → "First Name" for a human-readable field label. */
37
+ export declare const humanize: (id: string) => string;
36
38
  export declare function extractFormFieldsFromBlocks(blocks: BlockMap, rootBlockId: string): FormField[];
37
39
  /**
38
40
  * Scalar `{{id}}` tokens present in the live document that have no matching
@@ -43,6 +45,14 @@ export declare function extractFormFieldsFromBlocks(blocks: BlockMap, rootBlockI
43
45
  * explicit repeatable-container flow.
44
46
  */
45
47
  export declare function detectMissingScalarFields(document: BlockMap, forms: FormField[]): FormField[];
48
+ /**
49
+ * Add every `{{this.sub}}` token found inside a container-repeat field's own
50
+ * blocks (source + row subtrees) to that field's `itemFields`, so a row token
51
+ * typed after the repeat was set up shows in the Variables panel and survives
52
+ * save. Blocks belonging to a nested repeat are skipped — their tokens are
53
+ * that inner field's. Returns `forms` itself when nothing was added.
54
+ */
55
+ export declare function mergeDetectedRowSubFields(document: BlockMap, forms: FormField[]): FormField[];
46
56
  /**
47
57
  * Convert one live root field into an authoring field for the template dialog.
48
58
  * Only the DEFINITION is kept (id, name, type, itemFields, target blocks);
@@ -299,6 +299,12 @@ export declare const duplicateBlock: (documentTree: Record<string, any>, rootId:
299
299
  updatedDocument: Record<string, any>;
300
300
  newRootId: string;
301
301
  };
302
+ /**
303
+ * Re-point a repeat field at its copied blocks. Items-array fields (MenuPicker
304
+ * custom menu) follow their block; container-repeat fields keep a row per
305
+ * copied row block. Null when the field's blocks weren't copied.
306
+ */
307
+ export declare function cloneRepeatField(f: any, idMap: Record<string, string>): any | null;
302
308
  export declare const cloneCopiedBlocks: (copiedConfig: {
303
309
  rootBlockId: string;
304
310
  blocks: Record<string, any>;
@@ -6,7 +6,7 @@ type TValue = {
6
6
  document: TEditorConfiguration;
7
7
  record: any | null;
8
8
  selectedBlockId: string | null;
9
- selectedSidebarTab: 'block-configuration' | 'styles' | 'behaviour' | 'layout' | 'settings' | 'background' | 'page-pilot-ai' | 'layers' | 'brand' | 'seo' | 'variables' | 'research';
9
+ selectedSidebarTab: 'block-configuration' | 'styles' | 'behaviour' | 'layout' | 'settings' | 'background' | 'page-pilot-ai' | 'layers' | 'brand' | 'seo' | 'variables' | 'research' | 'sections';
10
10
  selectedMainTab: 'editor' | 'preview' | 'json' | 'html';
11
11
  selectedScreenSize: 'desktop' | 'mobile' | 'tablet';
12
12
  previewHostTheme: PreviewHostTheme;
@@ -189,7 +189,7 @@ type SetActiveStepIndexOptions = {
189
189
  };
190
190
  export declare function setActiveStepIndex(activeStepIndex: number, options?: SetActiveStepIndexOptions): void;
191
191
  export declare function setSelectedMainTab(selectedMainTab: TValue['selectedMainTab']): void;
192
- export declare function useSelectedSidebarTab(): "layout" | "background" | "behaviour" | "block-configuration" | "styles" | "settings" | "page-pilot-ai" | "layers" | "brand" | "seo" | "variables" | "research";
192
+ export declare function useSelectedSidebarTab(): "layout" | "background" | "behaviour" | "block-configuration" | "styles" | "settings" | "page-pilot-ai" | "layers" | "brand" | "seo" | "variables" | "research" | "sections";
193
193
  export declare function useInspectorDrawerOpen(): boolean;
194
194
  export declare function useSamplesDrawerOpen(): boolean;
195
195
  export declare function useInlineEditingEnabled(): boolean;