pagepilot-visual-editor 1.0.25 → 1.0.27

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 +22 -0
  2. package/dist/blocks-internal/block-list/src/index.d.ts +1 -1
  3. package/dist/blocks-internal/block-stepper/src/index.d.ts +1 -1
  4. package/dist/editor-sample/App/InspectorDrawer/ConfigurationPanel/input-panels/FormsPickerSidebarPanel.d.ts +1 -0
  5. package/dist/editor-sample/App/InspectorDrawer/ConfigurationPanel/input-panels/helpers/inputs/ColorInput/Picker.d.ts +4 -1
  6. package/dist/editor-sample/App/InspectorDrawer/LayersPanelStyles.d.ts +1 -1
  7. package/dist/editor-sample/App/InspectorDrawer/LayoutPanel/templateApplyHelpers.d.ts +22 -4
  8. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/GroupBlockPreview.d.ts +7 -0
  9. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/ItemsArrayRepeatSection.d.ts +14 -0
  10. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/ScalarDataReferencePanel.d.ts +24 -0
  11. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/ScalarFieldRow.d.ts +12 -0
  12. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/VariableGroupList.d.ts +8 -0
  13. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/VariablesPanelContext.d.ts +10 -0
  14. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/dataReferenceUtils.d.ts +24 -6
  15. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/index.d.ts +8 -1
  16. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/repeatRowActions.d.ts +27 -0
  17. package/dist/editor-sample/App/InspectorDrawer/VariablesPanel/styles.d.ts +20 -0
  18. package/dist/editor-sample/App/InspectorDrawer/components/DateFieldControls.d.ts +12 -0
  19. package/dist/editor-sample/App/InspectorDrawer/components/DateTimeFieldControls.d.ts +14 -0
  20. package/dist/editor-sample/App/InspectorDrawer/components/TimeFieldControls.d.ts +12 -0
  21. package/dist/editor-sample/App/shared/editor.styles.d.ts +2 -2
  22. package/dist/editor-sample/documents/blocks/FormsPicker/FormsPropsSchema.d.ts +2 -0
  23. package/dist/editor-sample/documents/blocks/Table/TableImportDialog.styles.d.ts +4 -4
  24. package/dist/editor-sample/documents/blocks/TabsBlock/TabsBlockPropsSchema.d.ts +14 -0
  25. package/dist/editor-sample/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/blockMenuStyles.d.ts +2 -0
  26. package/dist/editor-sample/documents/blocks/helpers/EditorChildrenIds/AddBlockMenu/buttons.d.ts +3 -4
  27. package/dist/editor-sample/documents/blocks/helpers/InlineTextToolbar/hooks/useToolbarCommands.d.ts +17 -1
  28. package/dist/editor-sample/documents/blocks/helpers/InlineTextToolbar/popovers/ResponsiveFontSizePopover.d.ts +43 -0
  29. package/dist/editor-sample/documents/blocks/helpers/InlineTextToolbar/types.d.ts +7 -0
  30. package/dist/editor-sample/documents/blocks/helpers/documentUtils.d.ts +93 -2
  31. package/dist/editor-sample/documents/blocks/helpers/responsiveFontSizeCss.d.ts +72 -0
  32. package/dist/editor-sample/documents/blocks/helpers/variableBinding.d.ts +5 -0
  33. package/dist/editor-sample/documents/editor/core.d.ts +17 -2
  34. package/dist/editor-sample/documents/editor/templateVariables.d.ts +3 -3
  35. package/dist/email-builder-core/blocks/FormsPicker/FormsPropsSchema.d.ts +1 -0
  36. package/dist/email-builder-core/blocks/TabsBlock/TabsBlockPropsSchema.d.ts +14 -0
  37. package/dist/email-builder-core/renderers/pageScripts.d.ts +1 -0
  38. package/dist/email-builder-core/utils/substituteTemplateVars.d.ts +32 -0
  39. package/dist/host-stubs/view/shared/common/InfoTooltip.d.ts +19 -0
  40. package/dist/host-stubs/view/shared/timeZones.d.ts +4 -0
  41. package/dist/{index-RcTlEXS2.cjs → index-BNqa-SV3.cjs} +317 -288
  42. package/dist/{index-uAL1Hpt1.js → index-C4zNSWXe.js} +1 -1
  43. package/dist/{index-Cx_nuxVE.cjs → index-Cu-dtp0Q.cjs} +1 -1
  44. package/dist/{index-txCEAgzG.js → index-Dk7bp7l0.js} +29768 -26808
  45. package/dist/index.cjs +1 -1
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.js +15 -12
  48. package/dist/render-core/apiDataSource.d.ts +50 -0
  49. package/dist/render-core/dateFormats.d.ts +67 -0
  50. package/dist/render-core/repeatRowManagement.d.ts +96 -0
  51. package/dist/render-core/templateBaking.d.ts +105 -2
  52. package/dist/render.cjs +186 -163
  53. package/dist/render.d.ts +4 -2
  54. package/dist/render.js +8297 -7057
  55. package/dist/renderToStaticHtml.d.ts +58 -3
  56. package/dist/{xlsx-CMNIZUaT.cjs → xlsx-C6JQXDb3.cjs} +1 -1
  57. package/dist/{xlsx-DSQPVb8u.js → xlsx-Cd1etxFW.js} +1 -1
  58. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-RcTlEXS2.cjs");exports.EditorContext=e.EditorContext;exports.PagePilotEditor=e.PagePilotEditor;exports.PagepilotApiClient=e.PagepilotApiClient;exports.Reader=e.Reader;exports.ReaderBlock=e.ReaderBlock;exports.ReaderBlockSchema=e.ReaderBlockSchema;exports.ReaderDocumentSchema=e.ReaderDocumentSchema;exports.pagePilotEditorDarkTheme=e.pagePilotEditorDarkTheme;exports.pagePilotEditorLightTheme=e.pagePilotEditorLightTheme;exports.renderToStaticHtml=e.renderToStaticHtml;exports.renderToStaticMarkup=e.renderToStaticMarkup;exports.resetDocument=e.resetDocument;exports.resetPagePilotEditorTranslations=e.resetPagePilotEditorTranslations;exports.setDocument=e.setDocument;exports.setPagePilotEditorTranslations=e.setPagePilotEditorTranslations;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BNqa-SV3.cjs");exports.EditorContext=e.EditorContext;exports.PagePilotEditor=e.PagePilotEditor;exports.PagepilotApiClient=e.PagepilotApiClient;exports.Reader=e.Reader;exports.ReaderBlock=e.ReaderBlock;exports.ReaderBlockSchema=e.ReaderBlockSchema;exports.ReaderDocumentSchema=e.ReaderDocumentSchema;exports.extractApiRows=e.extractApiRows;exports.pagePilotEditorDarkTheme=e.pagePilotEditorDarkTheme;exports.pagePilotEditorLightTheme=e.pagePilotEditorLightTheme;exports.refreshApiDataSources=e.refreshApiDataSources;exports.refreshDocumentApiDataSources=e.refreshDocumentApiDataSources;exports.renderToStaticHtml=e.renderToStaticHtml;exports.renderToStaticMarkup=e.renderToStaticMarkup;exports.resetDocument=e.resetDocument;exports.resetPagePilotEditorTranslations=e.resetPagePilotEditorTranslations;exports.setDocument=e.setDocument;exports.setPagePilotEditorTranslations=e.setPagePilotEditorTranslations;
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@ export type { BlockKey, BlockToggles } from './editor/blockToggles';
4
4
  export { pagePilotEditorLightTheme, pagePilotEditorDarkTheme, } from './editor/theme';
5
5
  export { setPagePilotEditorTranslations, resetPagePilotEditorTranslations, } from './host-stubs/i18n';
6
6
  export { Reader, ReaderBlock, renderToStaticMarkup, ReaderBlockSchema, ReaderDocumentSchema, } from './email-builder-core';
7
- export { renderToStaticHtml } from './renderToStaticHtml';
8
- export type { RenderToStaticHtmlOptions, RenderToStaticHtmlSyncOptions, RenderToStaticHtmlPageOptions, RenderToStaticHtmlTemplateOptions, } from './renderToStaticHtml';
7
+ export { renderToStaticHtml, refreshApiDataSources, refreshDocumentApiDataSources, extractApiRows, } from './renderToStaticHtml';
8
+ export type { RenderToStaticHtmlOptions, RenderToStaticHtmlSyncOptions, RenderToStaticHtmlPageOptions, RenderToStaticHtmlPagePathOptions, RenderToStaticHtmlTemplateOptions, RefreshApiDataSourcesOptions, RefreshApiDataSourcesResult, } from './renderToStaticHtml';
9
9
  export type { TReaderBlock, TReaderDocument, TReaderBlockProps, TReaderProps, } from './email-builder-core';
10
10
  export * as EditorContext from './editor-sample/documents/editor/EditorContext';
11
11
  export { PagepilotApiClient } from './api/PagepilotApiClient';
package/dist/index.js CHANGED
@@ -1,18 +1,21 @@
1
- import { E as t, P as o, b as s, R as r, d as i, e as d, f as l, p as n, h as P, r as c, i as m, j as g, k as p, s as E, l as h } from "./index-txCEAgzG.js";
1
+ import { E as t, P as s, b as r, R as o, d as i, e as c, f as d, h as l, p as n, i as m, r as p, j as P, k as h, l as g, m as u, n as D, s as E, o as R } from "./index-Dk7bp7l0.js";
2
2
  export {
3
3
  t as EditorContext,
4
- o as PagePilotEditor,
5
- s as PagepilotApiClient,
6
- r as Reader,
4
+ s as PagePilotEditor,
5
+ r as PagepilotApiClient,
6
+ o as Reader,
7
7
  i as ReaderBlock,
8
- d as ReaderBlockSchema,
9
- l as ReaderDocumentSchema,
8
+ c as ReaderBlockSchema,
9
+ d as ReaderDocumentSchema,
10
+ l as extractApiRows,
10
11
  n as pagePilotEditorDarkTheme,
11
- P as pagePilotEditorLightTheme,
12
- c as renderToStaticHtml,
13
- m as renderToStaticMarkup,
14
- g as resetDocument,
15
- p as resetPagePilotEditorTranslations,
12
+ m as pagePilotEditorLightTheme,
13
+ p as refreshApiDataSources,
14
+ P as refreshDocumentApiDataSources,
15
+ h as renderToStaticHtml,
16
+ g as renderToStaticMarkup,
17
+ u as resetDocument,
18
+ D as resetPagePilotEditorTranslations,
16
19
  E as setDocument,
17
- h as setPagePilotEditorTranslations
20
+ R as setPagePilotEditorTranslations
18
21
  };
@@ -0,0 +1,50 @@
1
+ import { TemplateFormField } from './templateBaking';
2
+ export interface RefreshApiDataSourcesOptions {
3
+ /** Optional custom fetch. Defaults to global `fetch`. */
4
+ fetchFn?: typeof fetch;
5
+ /** Per-request timeout in ms. Defaults to 10000. */
6
+ timeoutMs?: number;
7
+ /** Extra headers sent with every API-datasource GET (e.g. auth). */
8
+ headers?: Record<string, string>;
9
+ /**
10
+ * Called for each field whose refetch failed (bad URL, network error,
11
+ * non-OK status, non-JSON body, no array found). The field's existing
12
+ * `value` is left untouched so the render still succeeds with the last
13
+ * known-good rows.
14
+ */
15
+ onError?: (field: TemplateFormField, error: Error) => void;
16
+ }
17
+ export interface RefreshApiDataSourcesResult {
18
+ /** The (possibly) updated fields — same array identity only if nothing changed. */
19
+ fields: TemplateFormField[];
20
+ /** How many `api` datasource fields were found. */
21
+ attempted: number;
22
+ /** How many were successfully refetched and re-seeded. */
23
+ refreshed: number;
24
+ /** field id → error message, for any that failed. */
25
+ errors: Record<string, string>;
26
+ }
27
+ /**
28
+ * Pull the array of row-objects out of an arbitrary API response.
29
+ *
30
+ * - If `apiItemPath` is set, resolve that dot-path first (supports both
31
+ * "the array itself lives at this path" and "each row's real payload is
32
+ * nested one level under this key inside an already-found array").
33
+ * - Otherwise fall back to: top-level array, or a common wrapper key
34
+ * (data / rows / results / items / records).
35
+ */
36
+ export declare function extractApiRows(body: any, apiItemPath?: string): Record<string, any>[] | null;
37
+ /**
38
+ * Re-fetch every `array`-type formField whose `dataSource.type === 'api'`
39
+ * and replace its `value` with freshly-extracted rows. Fields with any other
40
+ * (or no) `dataSource.type` pass through unchanged. Failures are isolated
41
+ * per-field — one bad endpoint never aborts the whole render; that field
42
+ * simply keeps its last-saved `value`.
43
+ */
44
+ export declare function refreshApiDataSources(fields: TemplateFormField[] | null | undefined, options?: RefreshApiDataSourcesOptions): Promise<RefreshApiDataSourcesResult>;
45
+ /**
46
+ * Convenience wrapper: refresh a document's OWN `root.data.formFields`
47
+ * (the shape every saved section/page/template uses) in place and return
48
+ * the updated field list, ready to pass into `bakeTemplateValues`.
49
+ */
50
+ export declare function refreshDocumentApiDataSources(document: any, options?: RefreshApiDataSourcesOptions): Promise<RefreshApiDataSourcesResult>;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Preset date display formats offered to the author. `relative` is recomputed at
3
+ * view time (see formatRelativeDate); every other preset is a fixed absolute
4
+ * format resolved via `Intl.DateTimeFormat` in a chosen timezone.
5
+ */
6
+ export type DateFormatPreset = 'relative' | 'do-mmm-yyyy' | 'mmm-d-yyyy' | 'd-mmm-yyyy' | 'dd-mm-yyyy' | 'mm-dd-yyyy' | 'yyyy-mm-dd' | 'do-mmm' | 'full';
7
+ export declare const DEFAULT_DATE_FORMAT: DateFormatPreset;
8
+ export declare const DATE_FORMAT_PRESETS: {
9
+ value: DateFormatPreset;
10
+ label: string;
11
+ }[];
12
+ /**
13
+ * Time display formats offered for a `time` scalar variable. Unlike `date`,
14
+ * `time` has no `relative` mode — it always bakes to a fixed string, rendered
15
+ * in the field's chosen `dateTz` (reusing the timezone control).
16
+ * - `24h` → "20:42"
17
+ * - `12h` → "8:42 PM"
18
+ */
19
+ export type TimeFormatPreset = '24h' | '12h';
20
+ export declare const DEFAULT_TIME_FORMAT: TimeFormatPreset;
21
+ export declare const TIME_FORMAT_PRESETS: {
22
+ value: TimeFormatPreset;
23
+ label: string;
24
+ }[];
25
+ /**
26
+ * Friendly relative label for a date, compared against `now` in the HOST's local
27
+ * timezone (the reader's browser, or the app user's machine):
28
+ *
29
+ * -1 day → "Yesterday"
30
+ * 0 day → "Today"
31
+ * +1 day → "Tomorrow"
32
+ * ±2..6 → weekday ("Mon", "Sat")
33
+ * further → "Mar 25", or "Mar 25, 2027" when not the current year
34
+ *
35
+ * Returns '' for a missing/invalid input.
36
+ *
37
+ * NOTE: keep this ladder in sync with `formatRelativeDateLabel` in
38
+ * `src/email-builder-core/utils/substituteTemplateVars.ts` (the standalone
39
+ * copy the marker-span runtime uses) and the inlined copy in
40
+ * `src/email-builder-core/renderers/pageScripts.ts`.
41
+ */
42
+ export declare function formatRelativeDate(value: string | number | Date | null | undefined, opts?: {
43
+ now?: Date;
44
+ locale?: string;
45
+ }): string;
46
+ /**
47
+ * Format a date value with one of the presets.
48
+ * - `relative` → formatRelativeDate (host-local day math; `tz` is ignored)
49
+ * - any other → the value's Y/M/D in `tz` (defaults to the host's local
50
+ * zone), assembled into the preset's pattern.
51
+ *
52
+ * `tz` is an IANA name (e.g. "America/New_York"). Returns '' for a
53
+ * missing/invalid input.
54
+ */
55
+ export declare function formatDateValue(value: string | number | Date | null | undefined, preset?: DateFormatPreset, opts?: {
56
+ tz?: string;
57
+ now?: Date;
58
+ locale?: string;
59
+ }): string;
60
+ /**
61
+ * Format the time portion of a date value with one of the time presets, in the
62
+ * given IANA `tz` (defaults to the host's local zone). Returns '' for a
63
+ * missing/invalid input.
64
+ */
65
+ export declare function formatTimeValue(value: string | number | Date | null | undefined, preset?: TimeFormatPreset, opts?: {
66
+ tz?: string;
67
+ }): string;
@@ -0,0 +1,96 @@
1
+ export type TemplateArrayRow = Record<string, string>;
2
+ /**
3
+ * Deep-clone a subtree under fresh block ids. Returns the new blocks keyed
4
+ * by new id, the idMap (oldId → newId) and the new root id. Pure — caller
5
+ * splices.
6
+ */
7
+ export declare function cloneSubtree(documentTree: Record<string, any>, rootId: string): {
8
+ newBlocks: Record<string, any>;
9
+ idMap: Record<string, string>;
10
+ newRootId: string;
11
+ };
12
+ export declare function insertDocument(documentTree: Record<string, any>, targetChildId: string, insertedChildId: string): {
13
+ parentId: string;
14
+ updatedParent: any;
15
+ } | null;
16
+ /**
17
+ * Materialize one repeat row: clone the `sourceBlockId` subtree and place
18
+ * the clone after `afterBlockId` (the previous row's block). Returns the
19
+ * updated document + the new clone's root id, or `null` when the
20
+ * container has no room and can't auto-grow (caller decides whether to
21
+ * grow the container first via `growContainerToFit` and retry).
22
+ */
23
+ export declare function addRepeatRow(documentTree: Record<string, any>, sourceBlockId: string, afterBlockId: string): {
24
+ updatedDocument: Record<string, any>;
25
+ newRootId: string;
26
+ } | null;
27
+ /**
28
+ * Remove a set of block ids and filter them out of every parent's
29
+ * child-id arrays. Used to delete a repeat row's cloned container
30
+ * subtree.
31
+ */
32
+ export declare function removeSubtree(documentTree: Record<string, any>, idsToRemove: Set<string>): Record<string, any>;
33
+ export type RepeatableSlot = {
34
+ childrenIds: string[];
35
+ };
36
+ export type RepeatableContainerInfo = {
37
+ containerId: string;
38
+ type: "Grid" | "FlexColumns" | "Carousel" | "Marquee" | "Pagination" | "TabsBlock";
39
+ slotCount: number;
40
+ slots: RepeatableSlot[];
41
+ firstFilledSlot: number;
42
+ emptySlotCount: number;
43
+ };
44
+ export declare function isRepeatableContainerType(type: string | undefined): boolean;
45
+ export declare function getRepeatableContainerInfo(documentTree: Record<string, any>, containerId: string): RepeatableContainerInfo | null;
46
+ /** Find the repeatable container whose slots hold `childId`. */
47
+ export declare function findRepeatableContainerOf(documentTree: Record<string, any>, childId: string): string | null;
48
+ /**
49
+ * Grow a repeatable container so it has at least `neededSlots` slots.
50
+ * Grid is the one two-axis case needing a `direction` choice (no default
51
+ * encoded in the pure logic — there's no human to ask at serve time, so
52
+ * callers must pass one explicitly). Every other container type ignores
53
+ * `direction` and grows its single axis. Capped by each block type's
54
+ * schema max (Carousel 20, Marquee 30, TabsBlock 10) — returns the
55
+ * unchanged document if the cap is already hit.
56
+ */
57
+ export declare function growContainerToFit(documentTree: Record<string, any>, containerId: string, neededSlots: number, direction: "rows" | "columns"): Record<string, any>;
58
+ /**
59
+ * Shrink a repeatable container back down to `neededSlots`. Only trailing
60
+ * EMPTY slots are dropped — a filled slot always stops the shrink, so
61
+ * authored content already emptied by a prior `removeSubtree` call is what
62
+ * actually gets trimmed here, never content that's still in use.
63
+ */
64
+ export declare function shrinkContainerToFit(documentTree: Record<string, any>, containerId: string, neededSlots: number): Record<string, any>;
65
+ export interface ReconcileRowCountResult {
66
+ /** Updated document tree (same reference as input if nothing changed). */
67
+ document: Record<string, any>;
68
+ /** The field's new sourceBlockId (only ever changes if row 0 itself had to move — in
69
+ * practice it never does; kept for symmetry/future-proofing). */
70
+ sourceBlockId: string;
71
+ /** The field's new rowIds (one per materialized row beyond row 0). */
72
+ rowIds: string[];
73
+ /** How many rows are actually materialized after this call (1 + rowIds.length). */
74
+ achievedRowCount: number;
75
+ /** True if `achievedRowCount < targetRowCount` — the container ran out of room
76
+ * and could not grow further (e.g. a full non-auto-growing Grid/Carousel/Marquee). */
77
+ capacityLimited: boolean;
78
+ }
79
+ /**
80
+ * Reconcile a container-repeat field's materialized row-block count to
81
+ * exactly `targetRowCount`. Grows by cloning (`addRepeatRow`, growing the
82
+ * container first via `growContainerToFit` if every slot is already full)
83
+ * or shrinks by removing trailing rows' subtrees (`removeSubtree` +
84
+ * `shrinkContainerToFit`). Never touches row 0 (the field's own
85
+ * `sourceBlockId`) — `targetRowCount` is clamped to at least 1.
86
+ *
87
+ * Pure: does not mutate `documentTree`. Fails open in the sense that if
88
+ * growth runs out of room partway through, it returns whatever was
89
+ * achieved (`capacityLimited: true`) rather than throwing — callers decide
90
+ * how to handle a partial reconciliation (e.g. drop the data beyond what
91
+ * fit, log a warning).
92
+ */
93
+ export declare function reconcileRepeatFieldRowCount(documentTree: Record<string, any>, field: {
94
+ sourceBlockId?: string;
95
+ rowIds?: string[];
96
+ }, targetRowCount: number, growDirection?: "rows" | "columns"): ReconcileRowCountResult | null;
@@ -1,10 +1,30 @@
1
- export type TemplateScalarType = 'text' | 'textarea' | 'number' | 'image';
1
+ import { DateFormatPreset, TimeFormatPreset } from './dateFormats';
2
+ /**
3
+ * The kinds of single-value template field. `array` is repeatable and handled
4
+ * separately. `text` / `textarea` substitute as plain strings, `number` as a
5
+ * numeric string, `image` as an image URL (used in Image/Avatar/Logo blocks),
6
+ * `date` an ISO date string rendered through a display format (see `dateFormat`).
7
+ * `time` an ISO date string rendered as just its time portion (see `timeFormat`).
8
+ * `datetime` one ISO string exposing TWO sub-tokens — `{{id.date}}` (formatted
9
+ * via `dateFormat`) and `{{id.time}}` (via `timeFormat`) — so a single value /
10
+ * API mapping can print its date and time in separate blocks.
11
+ */
12
+ export type TemplateScalarType = 'text' | 'textarea' | 'number' | 'image' | 'date' | 'time' | 'datetime';
2
13
  export type TemplateFormType = TemplateScalarType | 'array';
14
+ /** All scalar types — used by both top-level fields and array sub-fields. */
15
+ export declare const TEMPLATE_SCALAR_TYPES: TemplateScalarType[];
3
16
  export type TemplateItemFieldDef = {
4
17
  id: string;
5
18
  name: string;
19
+ /** Sub-field input kind. Defaults to `text` when absent (legacy rows). */
6
20
  type?: TemplateScalarType;
21
+ /** Author-set default value, used to prefill the row when a template is applied. */
7
22
  defaultValue?: string;
23
+ /** `date` sub-fields only — see the same fields on TemplateFormField. */
24
+ dateFormat?: DateFormatPreset;
25
+ /** `time` sub-fields only — 24h / AM/PM. Timezone reuses `dateTz`. */
26
+ timeFormat?: TimeFormatPreset;
27
+ dateTz?: string;
8
28
  };
9
29
  export type TemplateArrayRow = Record<string, string>;
10
30
  export type TemplateFormField = {
@@ -16,20 +36,103 @@ export type TemplateFormField = {
16
36
  itemFields?: TemplateItemFieldDef[];
17
37
  sourceBlockId?: string;
18
38
  rowIds?: string[];
39
+ /**
40
+ * `date` fields only. How the ISO `value` is displayed:
41
+ * - `relative` (default) → "Today" / "Tomorrow" / "Mar 25", recomputed in the
42
+ * reader's browser at view time (emitted as a `data-ahd-date` marker span,
43
+ * NOT baked to a fixed string). Uses the reader's local timezone.
44
+ * - any absolute preset → a fixed string ("9th Sep 2026" …) resolved at bake
45
+ * time in `dateTz`.
46
+ * See `dateFormats.ts` for the preset list.
47
+ */
48
+ dateFormat?: DateFormatPreset;
49
+ /**
50
+ * `time` fields only. How the ISO `value`'s time portion is displayed:
51
+ * - `24h` (default) → "20:42"
52
+ * - `12h` → "8:42 PM"
53
+ */
54
+ timeFormat?: TimeFormatPreset;
55
+ /**
56
+ * `date` fields with an absolute `dateFormat`, and all `time` fields. IANA
57
+ * timezone the value is rendered in (e.g. "America/New_York"). Ignored by
58
+ * `date`'s `relative` preset.
59
+ */
60
+ dateTz?: string;
61
+ /**
62
+ * Set on a container-repeat array field driven from the Variables tab's
63
+ * "Repeatable container" flow: the id of the Grid/FlexColumns/ColumnsContainer
64
+ * whose EMPTY slots get stamped with clones of `sourceBlockId`'s subtree.
65
+ * (`sourceBlockId` = the block sitting in the container's first filled slot;
66
+ * `rowIds` = the stamped clones' roots, one per filled empty slot.)
67
+ */
19
68
  containerId?: string;
69
+ /**
70
+ * Set on a direct items-array data-source field: the id of the block whose
71
+ * OWN `data.props.items` gets seeded straight from the Data Reference
72
+ * source. Unlike `sourceBlockId`, there's no cloned subtree — `itemsBlockId`
73
+ * points at the block itself, and rows write directly into its `items`
74
+ * array. Presence of `itemsBlockId` (instead of `sourceBlockId`) is what
75
+ * routes ArrayFieldEditor/DataReferencePanel down the items-array path
76
+ * instead of the container-repeat path.
77
+ */
78
+ itemsBlockId?: string;
79
+ /**
80
+ * Author flag set from "Set template details" → Template Fields: marks this
81
+ * field's content as intended to be repeated once the template is applied
82
+ * (e.g. across grid cells / carousel slides). Pure metadata — carried through
83
+ * from the saved template record, doesn't drive any runtime behavior itself.
84
+ */
20
85
  repeatable?: boolean;
86
+ /**
87
+ * The id of the block template this repeatable field is bound to — captured
88
+ * when the field's block is saved via the Variables-panel "Save as New
89
+ * Template" shortcut.
90
+ */
21
91
  templateId?: string;
92
+ /**
93
+ * "Data Reference" binding for a repeatable field: where the repetition data
94
+ * comes from. `custom` = the manual rows editor (default). `api`/`menu` pull
95
+ * an array of objects whose keys map to this field's sub-field ids; each
96
+ * object seeds one repeated copy. `customJson` holds the pasted JSON text for
97
+ * the `custom-json` source.
98
+ */
22
99
  dataSource?: {
100
+ /** `api` = fetch an array of objects from a REST endpoint. */
23
101
  type: 'custom' | 'custom-json' | 'api' | 'menu';
102
+ /** Raw JSON text for `custom-json`. */
24
103
  customJson?: string;
104
+ /** Endpoint URL for the `api` source. Persisted in config. */
25
105
  apiUrl?: string;
106
+ /** HTTP method for the `api` source. Only GET works today; POST is planned. */
26
107
  apiMethod?: 'GET' | 'POST';
108
+ /**
109
+ * Optional dot-path (e.g. "data.ALL.games") into the response body where
110
+ * the array of objects lives. When empty, the array is auto-detected from
111
+ * common wrapper keys (data / rows / results / items / records).
112
+ */
113
+ apiResponsePath?: string;
114
+ /**
115
+ * REPEATABLE fields: optional dot-path applied to EACH array element before
116
+ * its keys are matched to sub-field ids. Use it when the fields you want are
117
+ * nested inside a wrapper on every row, e.g. `[{ "event": { "nextStart": … } }]`
118
+ * → set `apiItemPath: "event"` so `nextStart` maps directly.
119
+ * Works for the `api` and `custom-json` sources.
120
+ */
121
+ apiItemPath?: string;
122
+ /** Selected menu id for `menu`. */
27
123
  menuId?: string;
124
+ /**
125
+ * SCALAR fields only: dot-path into the fetched object for THIS field's
126
+ * value, overriding the default key lookup by field id. e.g. field `name`
127
+ * with `apiObjectPath: "user.fullName"` reads `body.user.fullName`.
128
+ * (`apiResponsePath` still points at the object itself within the response.)
129
+ */
130
+ apiObjectPath?: string;
28
131
  };
29
132
  };
30
133
  export declare function buildRepeatRowIndex(document: any | null | undefined, fields: TemplateFormField[] | null | undefined): Map<string, TemplateArrayRow>;
31
134
  export declare function getTextFieldsForType(type: string | undefined): string[] | undefined;
32
135
  export declare function getTemplateForms(document: any | null | undefined): TemplateFormField[];
33
136
  export declare function applyVariables(input: string | null | undefined, fields: TemplateFormField[] | null | undefined, rowContext?: TemplateArrayRow | null): string;
34
- export declare function substituteBlockText(block: any, fields: TemplateFormField[] | null | undefined, rowContext?: TemplateArrayRow | null): any;
137
+ export declare function substituteBlockText(block: any, fields: TemplateFormField[] | null | undefined, rowContext?: TemplateArrayRow | null, rowIndex?: Map<string, TemplateArrayRow> | null): any;
35
138
  export declare function bakeTemplateValues<T = any>(document: T, fields: TemplateFormField[] | null | undefined): T;