pagepilot-visual-editor 1.0.26 → 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.
- package/CHANGELOG.md +22 -0
- package/dist/render-core/repeatRowManagement.d.ts +96 -0
- package/dist/render.cjs +150 -150
- package/dist/render.d.ts +2 -0
- package/dist/render.js +6951 -6380
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,28 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.0.27] — 2026-09-21
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `render-core/repeatRowManagement.ts`, exported from the `./render` subpath:
|
|
13
|
+
`reconcileRepeatFieldRowCount(documentTree, field, targetRowCount, growDirection?)`
|
|
14
|
+
— grows or shrinks a container-repeat field's materialized row-block count
|
|
15
|
+
(cloning via `addRepeatRow`/growing the container via `growContainerToFit`,
|
|
16
|
+
or removing trailing row subtrees via `removeSubtree` +
|
|
17
|
+
`shrinkContainerToFit`) to match a target row count, e.g. so
|
|
18
|
+
server-side-regenerated HTML can show exactly as many cards as a live API
|
|
19
|
+
response returned, not just whatever was authored at Save time. Pure port
|
|
20
|
+
of the editor's `documentUtils.ts` block-tree mutators (`cloneSubtree`,
|
|
21
|
+
`addRepeatRow`, `removeSubtree`, `growContainerToFit`,
|
|
22
|
+
`shrinkContainerToFit`, `findRepeatableContainerOf`,
|
|
23
|
+
`getRepeatableContainerInfo`), rewritten to thread a plain document value
|
|
24
|
+
instead of the editor's Zustand-backed store — no new dependencies, no
|
|
25
|
+
editor/MUI imports, safe for the render-only bundle (same precedent as the
|
|
26
|
+
already-ported `collectSubtreeIds`). Grid's two-axis growth direction has
|
|
27
|
+
no default encoded in the pure logic (the editor asks the author via
|
|
28
|
+
`GrowDirectionDialog`); callers must pass `growDirection` explicitly for
|
|
29
|
+
serve-time use.
|
|
30
|
+
|
|
9
31
|
## [1.0.0] — 2026-07-06
|
|
10
32
|
|
|
11
33
|
Initial public release.
|
|
@@ -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;
|