efficient-easel 20.2.1 → 21.1.0
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/README.md +30 -9
- package/dist/{CanvasDragLayer-ARfaivCu.d.ts → CanvasDragLayer-CFUcBbgc.d.ts} +2 -2
- package/dist/{ScreenDocumentContext-CFJeqqKk.d.ts → ScreenDocumentContext-1RgtGKWR.d.ts} +4 -0
- package/dist/blocks/index.d.ts +5 -3
- package/dist/{buckets-Tj-nkBpg.d.ts → buckets-Sw94ll9I.d.ts} +1 -1
- package/dist/canvas/index.d.ts +8 -6
- package/dist/canvas/index.js +1 -1
- package/dist/chunk-2C7W64S5.js +8 -0
- package/dist/chunk-2L6KWUBC.js +1 -0
- package/dist/chunk-467WWV4I.js +1 -0
- package/dist/chunk-4FD7TAOE.js +1 -0
- package/dist/chunk-67HCYOW4.js +1 -0
- package/dist/chunk-A2VVB4RH.js +0 -0
- package/dist/{chunk-2GVCAIPX.js → chunk-BDSLF5BR.js} +1 -1
- package/dist/{chunk-U66YKDAR.js → chunk-BIK3AO2V.js} +1 -1
- package/dist/chunk-BTDI7JAA.js +2 -0
- package/dist/chunk-DDH2DYQP.js +1 -0
- package/dist/{chunk-I7BROL77.js → chunk-DNQ7AF6K.js} +1 -1
- package/dist/{chunk-HK6I3NVO.js → chunk-E52W3M5I.js} +1 -1
- package/dist/chunk-EB6NI2VK.js +1 -0
- package/dist/chunk-FM6JO4WF.js +2 -0
- package/dist/{chunk-JQXD3TDE.js → chunk-GWYNMSIP.js} +1 -1
- package/dist/{chunk-7YVEYQDE.js → chunk-I67UW5UG.js} +3 -3
- package/dist/chunk-JACEEVVF.js +1 -0
- package/dist/{chunk-QAJAEWCZ.js → chunk-KFWNGPW3.js} +5 -5
- package/dist/{chunk-FGYJ5DJY.js → chunk-KWLHKKZO.js} +1 -1
- package/dist/chunk-MLQKNED6.js +1 -0
- package/dist/chunk-MZ5GSSZ3.js +7 -0
- package/dist/{chunk-43AEUUNQ.js → chunk-N3MJOHAG.js} +1 -1
- package/dist/{chunk-BVN33R76.js → chunk-N7E6264U.js} +1 -1
- package/dist/chunk-OHZHYROJ.js +5 -0
- package/dist/chunk-PFFH7ASD.js +21 -0
- package/dist/chunk-PRHBWA5V.js +0 -0
- package/dist/chunk-S3DUFDQ6.js +6 -0
- package/dist/chunk-SNF5764Q.js +1 -0
- package/dist/chunk-SSRYU3YG.js +1 -0
- package/dist/chunk-SWBADIQT.js +1 -0
- package/dist/{chunk-GOTN2KY4.js → chunk-TIAWIOGD.js} +1 -1
- package/dist/chunk-TQ5Y6S2X.js +1 -0
- package/dist/chunk-TUXLORVR.js +15 -0
- package/dist/{chunk-FGNR22NY.js → chunk-U5DNBT63.js} +1 -1
- package/dist/chunk-U7TFWHST.js +5 -0
- package/dist/chunk-WHS6Y55E.js +10 -0
- package/dist/chunk-WJJ7H42G.js +18 -0
- package/dist/{chunk-ZOBSIXRD.js → chunk-Y2T3JX7K.js} +1 -1
- package/dist/chunk-YIUE4US7.js +0 -0
- package/dist/{chunk-O7Q4DDJT.js → chunk-YM4UEGBV.js} +1 -1
- package/dist/chunk-YVFYWAYU.js +65 -0
- package/dist/{chunk-UJ46J7QW.js → chunk-ZOSEBPAI.js} +1 -1
- package/dist/copy/index.d.ts +2 -2
- package/dist/copy/index.js +13 -13
- package/dist/drag/drag.css +3 -9
- package/dist/drag/index.d.ts +3 -3
- package/dist/drag/index.js +1 -1
- package/dist/draw/client.d.ts +1 -1
- package/dist/draw/client.js +1 -1
- package/dist/draw/index.d.ts +9 -9
- package/dist/draw/index.js +1 -1
- package/dist/easel/easel.css +3 -1
- package/dist/easel/index.d.ts +2 -2
- package/dist/easel/index.js +1 -1
- package/dist/fields/fields.css +2 -2
- package/dist/fields/index.d.ts +5 -5
- package/dist/fields/index.js +1 -1
- package/dist/panel/index.d.ts +39 -140
- package/dist/panel/index.js +15 -15
- package/dist/panel/panel.css +53 -347
- package/dist/render/index.d.ts +2 -2
- package/dist/render/index.js +5 -5
- package/dist/{repeat-Czi-6zPX.d.ts → repeat-BNgSq2Nw.d.ts} +1 -1
- package/dist/screen/components/AddBlockRow.d.ts +1 -1
- package/dist/screen/components/AddBlockRow.js +1 -1
- package/dist/screen/components/AddSidePanel.d.ts +2 -2
- package/dist/screen/components/AddSidePanel.js +1 -1
- package/dist/screen/components/NodeContextMenu.d.ts +15 -15
- package/dist/screen/components/NodeContextMenu.js +1 -1
- package/dist/screen/components/PageEditGuardNotices.js +1 -1
- package/dist/screen/components/PreviewPartsContext.d.ts +2 -2
- package/dist/screen/components/PreviewPartsContext.js +1 -1
- package/dist/screen/components/SaveControls.d.ts +9 -9
- package/dist/screen/components/ScreenChrome.js +1 -1
- package/dist/screen/components/ScreenDocumentContext.d.ts +2 -2
- package/dist/screen/components/ScreenDocumentContext.js +1 -1
- package/dist/screen/components/ScreenMount.d.ts +9 -9
- package/dist/screen/components/ScreenMount.js +1 -1
- package/dist/screen/components/ScreenStoreProvider.d.ts +9 -9
- package/dist/screen/components/ScreenStoreProvider.js +1 -1
- package/dist/screen/components/SectionScreenShell.js +17 -17
- package/dist/screen/components/SlotChildActionsContext.d.ts +1 -1
- package/dist/screen/components/usePartBridge.d.ts +9 -9
- package/dist/screen/components/usePartBridge.js +1 -1
- package/dist/screen/index.d.ts +10 -10
- package/dist/screen/index.js +1 -1
- package/dist/screen/lib/admin-bridge.d.ts +1 -1
- package/dist/screen/lib/admin-bridge.js +1 -1
- package/dist/screen/lib/content/view-tiers.d.ts +15 -3
- package/dist/screen/lib/content/view-tiers.js +1 -1
- package/dist/screen/lib/document/add-target-types.d.ts +55 -0
- package/dist/screen/lib/document/add-target-types.js +1 -0
- package/dist/screen/lib/document/block-choice.d.ts +64 -0
- package/dist/screen/lib/document/block-choice.js +1 -0
- package/dist/screen/lib/document/block-types-in.d.ts +39 -0
- package/dist/screen/lib/document/block-types-in.js +1 -0
- package/dist/screen/lib/document/content-tree.d.ts +222 -0
- package/dist/screen/lib/document/content-tree.js +1 -0
- package/dist/screen/lib/document/device-fields.d.ts +128 -0
- package/dist/screen/lib/document/device-fields.js +1 -0
- package/dist/screen/lib/document/field-buckets.d.ts +36 -0
- package/dist/screen/lib/document/field-buckets.js +1 -0
- package/dist/screen/lib/document/field-markers.d.ts +205 -0
- package/dist/screen/lib/document/field-markers.js +1 -0
- package/dist/screen/lib/document/hidable.d.ts +44 -0
- package/dist/screen/lib/document/hidable.js +1 -0
- package/dist/screen/lib/document/palette-sections.d.ts +103 -0
- package/dist/screen/lib/document/palette-sections.js +1 -0
- package/dist/screen/lib/document/panel-fields.d.ts +47 -0
- package/dist/screen/lib/document/panel-fields.js +1 -0
- package/dist/screen/lib/document/panel-no-control-mark.d.ts +74 -0
- package/dist/screen/lib/document/panel-no-control-mark.js +1 -0
- package/dist/screen/lib/document/part-id.d.ts +23 -0
- package/dist/screen/lib/document/part-id.js +1 -0
- package/dist/screen/lib/document/preview-click.d.ts +49 -0
- package/dist/screen/lib/document/preview-click.js +1 -0
- package/dist/screen/lib/document/preview-dom.d.ts +8 -0
- package/dist/screen/lib/document/preview-dom.js +1 -0
- package/dist/screen/lib/document/preview-events.d.ts +25 -0
- package/dist/screen/lib/document/preview-events.js +1 -0
- package/dist/screen/lib/document/preview-selection-context.d.ts +72 -0
- package/dist/screen/lib/document/preview-selection-context.js +1 -0
- package/dist/screen/lib/document/section-doc.d.ts +24 -0
- package/dist/screen/lib/document/section-doc.js +1 -0
- package/dist/screen/lib/document/slot-child-name.d.ts +225 -0
- package/dist/screen/lib/document/slot-child-name.js +1 -0
- package/dist/screen/lib/document/slot-heal.d.ts +5 -0
- package/dist/screen/lib/document/slot-heal.js +1 -0
- package/dist/screen/lib/document/slot-section-spec.d.ts +96 -0
- package/dist/screen/lib/document/slot-section-spec.js +1 -0
- package/dist/screen/lib/document/style-clipboard.d.ts +144 -0
- package/dist/screen/lib/document/style-clipboard.js +1 -0
- package/dist/screen/lib/document/text-control-kinds.d.ts +71 -0
- package/dist/screen/lib/document/text-control-kinds.js +1 -0
- package/dist/screen/lib/document/tree-reveal.d.ts +62 -0
- package/dist/screen/lib/document/tree-reveal.js +1 -0
- package/dist/screen/lib/document/use-section-ops.d.ts +110 -0
- package/dist/screen/lib/document/use-section-ops.js +1 -0
- package/dist/screen/lib/document-addressing.d.ts +2 -2
- package/dist/screen/lib/document-switch.d.ts +1 -1
- package/dist/screen/lib/host.d.ts +2 -2
- package/dist/screen/lib/key-scope.d.ts +1 -1
- package/dist/screen/lib/key-scope.js +1 -1
- package/dist/screen/lib/media-panel.d.ts +2 -2
- package/dist/screen/lib/media-picker.d.ts +2 -2
- package/dist/screen/lib/page-lock.d.ts +1 -1
- package/dist/screen/lib/puck/add-target-types.d.ts +3 -55
- package/dist/screen/lib/puck/add-target-types.js +1 -0
- package/dist/screen/lib/puck/block-choice.d.ts +1 -64
- package/dist/screen/lib/puck/block-choice.js +1 -1
- package/dist/screen/lib/puck/block-types-in.d.ts +1 -39
- package/dist/screen/lib/puck/block-types-in.js +1 -1
- package/dist/screen/lib/puck/content-tree.d.ts +1 -222
- package/dist/screen/lib/puck/content-tree.js +1 -1
- package/dist/screen/lib/puck/device-fields.d.ts +3 -127
- package/dist/screen/lib/puck/device-fields.js +1 -1
- package/dist/screen/lib/puck/field-buckets.d.ts +2 -36
- package/dist/screen/lib/puck/field-buckets.js +1 -1
- package/dist/screen/lib/puck/field-markers.d.ts +2 -205
- package/dist/screen/lib/puck/field-markers.js +1 -1
- package/dist/screen/lib/puck/hidable.d.ts +1 -44
- package/dist/screen/lib/puck/hidable.js +1 -1
- package/dist/screen/lib/puck/palette-sections.d.ts +2 -97
- package/dist/screen/lib/puck/palette-sections.js +1 -1
- package/dist/screen/lib/puck/panel-fields.d.ts +1 -47
- package/dist/screen/lib/puck/panel-fields.js +1 -1
- package/dist/screen/lib/puck/panel-no-control-mark.d.ts +2 -74
- package/dist/screen/lib/puck/panel-no-control-mark.js +1 -1
- package/dist/screen/lib/puck/part-id.d.ts +1 -23
- package/dist/screen/lib/puck/part-id.js +1 -1
- package/dist/screen/lib/puck/preview-click.d.ts +1 -49
- package/dist/screen/lib/puck/preview-click.js +1 -1
- package/dist/screen/lib/puck/preview-dom.d.ts +1 -8
- package/dist/screen/lib/puck/preview-dom.js +1 -1
- package/dist/screen/lib/puck/preview-events.d.ts +1 -25
- package/dist/screen/lib/puck/preview-events.js +1 -1
- package/dist/screen/lib/puck/preview-selection-context.d.ts +2 -72
- package/dist/screen/lib/puck/preview-selection-context.js +1 -1
- package/dist/screen/lib/puck/section-doc.d.ts +3 -18
- package/dist/screen/lib/puck/section-doc.js +1 -1
- package/dist/screen/lib/puck/slot-child-name.d.ts +1 -225
- package/dist/screen/lib/puck/slot-child-name.js +1 -1
- package/dist/screen/lib/puck/slot-heal.d.ts +2 -5
- package/dist/screen/lib/puck/slot-heal.js +1 -1
- package/dist/screen/lib/puck/slot-section-spec.d.ts +1 -96
- package/dist/screen/lib/puck/slot-section-spec.js +1 -0
- package/dist/screen/lib/puck/style-clipboard.d.ts +14 -116
- package/dist/screen/lib/puck/style-clipboard.js +1 -1
- package/dist/screen/lib/puck/text-control-kinds.d.ts +1 -71
- package/dist/screen/lib/puck/text-control-kinds.js +1 -1
- package/dist/screen/lib/puck/tree-reveal.d.ts +1 -62
- package/dist/screen/lib/puck/tree-reveal.js +1 -1
- package/dist/screen/lib/puck/use-section-ops.d.ts +4 -105
- package/dist/screen/lib/puck/use-section-ops.js +1 -1
- package/dist/screen/lib/screen-parts.d.ts +27 -20
- package/dist/screen/lib/screen-parts.js +1 -1
- package/dist/screen/lib/section-template-types.d.ts +1 -1
- package/dist/screen/lib/section-templates.d.ts +1 -1
- package/dist/screen/lib/section-templates.js +1 -1
- package/dist/screen/lib/session-context.d.ts +1 -1
- package/dist/screen/lib/session-context.js +1 -1
- package/dist/screen/lib/session.d.ts +3 -3
- package/dist/screen/lib/session.js +1 -1
- package/dist/screen/lib/shared-section-types.d.ts +1 -1
- package/dist/screen/lib/shared-sections.d.ts +1 -1
- package/dist/screen/lib/shared-sections.js +1 -1
- package/dist/screen/screen.css +5 -9
- package/dist/screen/words.d.ts +4 -0
- package/dist/screen/words.js +1 -1
- package/dist/strings/index.d.ts +4 -4
- package/dist/strings/index.js +2 -2
- package/dist/text-styles/index.js +33 -33
- package/dist/tree/index.d.ts +5 -5
- package/dist/tree/index.js +1 -1
- package/dist/{types-CDX6vd6A.d.ts → types-B8NwXKlE.d.ts} +1 -1
- package/dist/{types-Bqq6ya0y.d.ts → types-DBy3L69b.d.ts} +11 -4
- package/dist/{watch-BTYOJpQU.d.ts → watch-D8xZow3y.d.ts} +2 -2
- package/dist/{words-vhnV8sM7.d.ts → words-CFkb8XtN.d.ts} +5 -0
- package/dist/{words-BeX5eGq7.d.ts → words-CmEnDoOe.d.ts} +1 -1
- package/dist/{words-CvwYvkJm.d.ts → words-SD4neL0n.d.ts} +6 -0
- package/package.json +156 -12
- package/dist/chunk-23DYNW6S.js +0 -1
- package/dist/chunk-23VM4PMV.js +0 -7
- package/dist/chunk-276MBG5P.js +0 -2
- package/dist/chunk-6FWAE2RN.js +0 -1
- package/dist/chunk-7LYKFL3Q.js +0 -21
- package/dist/chunk-A6Z4SD3I.js +0 -10
- package/dist/chunk-BHRC3ASL.js +0 -1
- package/dist/chunk-EFHV56BO.js +0 -15
- package/dist/chunk-I54UCYOU.js +0 -1
- package/dist/chunk-JBOSEHIX.js +0 -1
- package/dist/chunk-KAML3KQH.js +0 -1
- package/dist/chunk-L2Y3PF2R.js +0 -4
- package/dist/chunk-LQV5FZTQ.js +0 -18
- package/dist/chunk-MEHLY5Q4.js +0 -1
- package/dist/chunk-PAOZMXEI.js +0 -5
- package/dist/chunk-QIDRJH3S.js +0 -1
- package/dist/chunk-R5KEFI55.js +0 -8
- package/dist/chunk-RC25EGHD.js +0 -5
- package/dist/chunk-RSCMJIWS.js +0 -1
- package/dist/chunk-TNGOL65V.js +0 -1
- package/dist/chunk-VANKQVOW.js +0 -8
- package/dist/chunk-WEIE2FBC.js +0 -1
- package/dist/chunk-WRFD4EXD.js +0 -1
- package/dist/chunk-XJ2WXGFJ.js +0 -65
- /package/dist/{chunk-MQNBD6AB.js → chunk-3QB2ZQXK.js} +0 -0
- /package/dist/{chunk-LER7RKTO.js → chunk-5XL2RXFU.js} +0 -0
- /package/dist/{chunk-6W7WLPZH.js → chunk-6UAEFOJ4.js} +0 -0
- /package/dist/{chunk-26OOWIJJ.js → chunk-7OCEPOEJ.js} +0 -0
- /package/dist/{chunk-IQ5TA7AM.js → chunk-AJ2SUSET.js} +0 -0
- /package/dist/{chunk-DUVRZ456.js → chunk-ANPOR6EY.js} +0 -0
- /package/dist/{chunk-5ZBY24K7.js → chunk-CPL43ZLJ.js} +0 -0
- /package/dist/{chunk-PIND6KE7.js → chunk-I6SK6ZDT.js} +0 -0
- /package/dist/{chunk-7F52SZOI.js → chunk-INRERJU4.js} +0 -0
- /package/dist/{chunk-R5L2E7JX.js → chunk-MGVI67QV.js} +0 -0
- /package/dist/{chunk-IYT6NN2J.js → chunk-R4AUZVA3.js} +0 -0
- /package/dist/{chunk-M2Z775ZC.js → chunk-RUQOIQWI.js} +0 -0
- /package/dist/{chunk-PLVEGYK6.js → chunk-TCAAOYQY.js} +0 -0
- /package/dist/{chunk-PA3PNTVV.js → chunk-VKPOH6MK.js} +0 -0
|
@@ -1,222 +1 @@
|
|
|
1
|
-
|
|
2
|
-
type: string;
|
|
3
|
-
props: {
|
|
4
|
-
id: string;
|
|
5
|
-
[key: string]: unknown;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
type SlotConfigView = {
|
|
9
|
-
components?: Record<string, unknown>;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Which of a component type's props are SLOTS — the prop names that hold child
|
|
13
|
-
* Blocks, read off the config's field map.
|
|
14
|
-
*
|
|
15
|
-
* Puck 0.20 stores slot children INLINE on the parent's props
|
|
16
|
-
* (`props.<slotName> = [{type,props}, …]`), NOT in `data.zones` — so a walker
|
|
17
|
-
* that wants a section's children has to know which prop names to look under.
|
|
18
|
-
* That set is per-component and lives in exactly one place, `config.components`:
|
|
19
|
-
* `Grid`/`Flex` call theirs `content`, but `Hero` calls it `slides`,
|
|
20
|
-
* `Collections` `cards`, `GalleryB` `items`, `ProductGrid` `products` and
|
|
21
|
-
* `Footer`/`FooterGroup` `blocks`.
|
|
22
|
-
*
|
|
23
|
-
* This is the ONE reader of that set. Hard-coding `"content"` instead is how the
|
|
24
|
-
* heading/SEO audit came to be blind to every heading nested in a Hero slide
|
|
25
|
-
* (card 66067): the walker recursed on a prop name only two of the eight slots
|
|
26
|
-
* happen to use, so a page with two H1s reported as fine. A type the config does
|
|
27
|
-
* not know has no slots — and cannot render either, so there is nothing to walk.
|
|
28
|
-
*/
|
|
29
|
-
declare function slotFieldsOf(config: SlotConfigView, type: string): string[];
|
|
30
|
-
/**
|
|
31
|
-
* What a component type's config ALLOWS of the two actions that make another
|
|
32
|
-
* node or take one away (0.103.0): its `permissions.duplicate` and
|
|
33
|
-
* `permissions.delete`, each true unless the config says false — the reading
|
|
34
|
-
* Puck gave a config that carried none. The campaign designer's Product keeps
|
|
35
|
-
* its Price line this way (`{ delete: false, duplicate: false }`).
|
|
36
|
-
*
|
|
37
|
-
* The screen's tree rows, its menu and the inspector head it hands this to
|
|
38
|
-
* (`ScreenInspectorPanelProps.nodeActions`) all ask HERE, so the three cannot
|
|
39
|
-
* come to disagree about one block. Only the config's own, never the
|
|
40
|
-
* easel-wide permissions the edit lock sets: a document somebody else holds is
|
|
41
|
-
* refused at the writes, as it always was, and draws the rows it drew.
|
|
42
|
-
*
|
|
43
|
-
* A type the config does not know allows both, as one with no `permissions`.
|
|
44
|
-
*/
|
|
45
|
-
declare function blockNodeActions(config: SlotConfigView, type: string): {
|
|
46
|
-
duplicate: boolean;
|
|
47
|
-
delete: boolean;
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* A slot child, addressed the way the Layers tree selects it: the node, the
|
|
51
|
-
* compound zone key "<parentId>:<slotName>" Puck's ops take, and its index in
|
|
52
|
-
* that slot.
|
|
53
|
-
*/
|
|
54
|
-
type SlotChild = {
|
|
55
|
-
child: TreeItem;
|
|
56
|
-
zone: string;
|
|
57
|
-
index: number;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Every slot child of `item`, across EVERY slot field its type declares — so a
|
|
61
|
-
* type with two slots reports both, and nesting is general: the result's `child`
|
|
62
|
-
* is itself an item this function accepts.
|
|
63
|
-
*
|
|
64
|
-
* Puck 0.20 stores slot children INLINE on the parent's props, so this reads the
|
|
65
|
-
* arrays rather than `data.zones` (which stays empty for slots).
|
|
66
|
-
*/
|
|
67
|
-
declare function childSlotsOf(config: SlotConfigView, item: TreeItem): SlotChild[];
|
|
68
|
-
/**
|
|
69
|
-
* The children of ONE slot of `item`, addressed as {@link childSlotsOf}
|
|
70
|
-
* addresses them (0.105.0): what the Layers tree draws under a slot it draws
|
|
71
|
-
* as a row of its own (`ScreenBlockRules.slotsOf`). A slot the node holds
|
|
72
|
-
* nothing in, or no array in, has none.
|
|
73
|
-
*/
|
|
74
|
-
declare function slotChildrenIn(item: TreeItem, slot: string): SlotChild[];
|
|
75
|
-
/**
|
|
76
|
-
* WHERE a node sits in the document — the node itself, the zone key its own
|
|
77
|
-
* array is addressed by, and its index in that array. Exactly the three
|
|
78
|
-
* arguments a Puck `replace` / `remove` / `reorder` op takes.
|
|
79
|
-
*/
|
|
80
|
-
type NodeLocation = {
|
|
81
|
-
item: TreeItem;
|
|
82
|
-
zone: string;
|
|
83
|
-
index: number;
|
|
84
|
-
};
|
|
85
|
-
/**
|
|
86
|
-
* Find a node by id and say WHERE IT IS, anywhere in the document — the root
|
|
87
|
-
* list or any slot at any depth.
|
|
88
|
-
*
|
|
89
|
-
* ── WHY A PANEL NEEDS THIS ──────────────────────────────────────────────────
|
|
90
|
-
* `useEasel((s) => s)` hands a field the SELECTED node and, in `ui.itemSelector`, the
|
|
91
|
-
* zone and index of that node. A control that has to rewrite the node's PARENT
|
|
92
|
-
* — "Apply to all cards" writes the whole Collections node once, so one press is
|
|
93
|
-
* one undo step — gets only half of what it needs: the selector's zone is the
|
|
94
|
-
* compound `"<parentId>:cards"`, which names the parent but says nothing about
|
|
95
|
-
* where the PARENT itself lives. Without that, the write has nowhere to go.
|
|
96
|
-
*
|
|
97
|
-
* ⚠️ IT IS NOT `enclosingSectionProps`, AND THE DIFFERENCE IS NOT COSMETIC.
|
|
98
|
-
* That one answers "which TOP-LEVEL section is this inside", returns props, and
|
|
99
|
-
* deliberately returns `null` for the immediate parent when the parent is not a
|
|
100
|
-
* root section. This one answers "where is THIS node", returns an address, and
|
|
101
|
-
* is happy to name a node nested inside a Box inside a Box. Its own docblock
|
|
102
|
-
* asks for a third question to be a third function rather than a third shape
|
|
103
|
-
* returned by the same walker; this is that function.
|
|
104
|
-
*
|
|
105
|
-
* ⚠️ AND IT IS NOT `childSlotsOf` WITH A FILTER. That lists one node's children;
|
|
106
|
-
* this searches a whole document. It is BUILT on `childSlotsOf` so the set of
|
|
107
|
-
* slot prop names stays read in exactly one place — hard-coding `"content"`
|
|
108
|
-
* instead is how the heading audit went blind to every heading nested in a Hero
|
|
109
|
-
* slide (card 66067), and the reason is written out on `slotFieldsOf`.
|
|
110
|
-
*
|
|
111
|
-
* ⚠️ THE CHROME ALREADY ANSWERS THIS, AND THAT IS NOT A DUPLICATE OF THIS.
|
|
112
|
-
* `ScreenChrome` memoises a Map of EVERY node's address (plus each
|
|
113
|
-
* zone's whole sibling list) and hands the lookup to the context menu as
|
|
114
|
-
* `locate`. That map is built once per document for a surface that needs all of
|
|
115
|
-
* it; this finds ONE node and is reachable from a Puck field, which the map is
|
|
116
|
-
* not — it lives in a component's closure and rides no context. What must not
|
|
117
|
-
* be two things is the set of SLOT PROP NAMES, and it is not: both walk through
|
|
118
|
-
* `childSlotsOf`, so an address here and an address there cannot disagree.
|
|
119
|
-
* Puck's own `getSelectorForId` is a third reader of the same fact, and the one
|
|
120
|
-
* a live store already offers — it is a hook-bound function, so a guard cannot
|
|
121
|
-
* call it, which is the whole reason this one is written pure.
|
|
122
|
-
*
|
|
123
|
-
* PURE, and takes the config as an argument, so a guard can assert against it
|
|
124
|
-
* without a Puck store, a React tree or a hook.
|
|
125
|
-
*
|
|
126
|
-
* `null` when no node carries the id — the honest answer for a stale selection,
|
|
127
|
-
* and every caller treats it as "there is nothing to write".
|
|
128
|
-
*/
|
|
129
|
-
declare function locateNode(config: SlotConfigView, content: ReadonlyArray<TreeItem>, id: string): NodeLocation | null;
|
|
130
|
-
/**
|
|
131
|
-
* How many levels of slot children the Layers tree draws below a top-level row.
|
|
132
|
-
*
|
|
133
|
-
* The tree is a ~288px panel that already scrolls and each level costs 10px of
|
|
134
|
-
* indent (`.sf-subtree`'s `padding-left`, storefront-editor.css — it was 25px
|
|
135
|
-
* until card 66199 took the drag grip out of the flow and moved the caret to the
|
|
136
|
-
* row's right end), so the depth is capped rather than unbounded: `Grid.content`
|
|
137
|
-
* is an open slot that accepts a Grid, so a document CAN nest without limit and a
|
|
138
|
-
* tree that followed it would run out of width.
|
|
139
|
-
*
|
|
140
|
-
* ⚠️ 3 SINCE CARD 66273, and the level it buys is the one a merchant was stuck
|
|
141
|
-
* on. A hero group's blocks are the THIRD level — Hero → slide → group → blocks
|
|
142
|
-
* — and at 2 a group row was a LEAF: no `.sf-subtree` was rendered under it, so
|
|
143
|
-
* the "Add block" row that lives inside that subtree had nowhere to go, and a
|
|
144
|
-
* merchant who made a group in the tree could not put anything into it. The
|
|
145
|
-
* number was 2 because the Footer's chain (Footer → blocks → Group → blocks) was
|
|
146
|
-
* the only one that existed when the cap was named; the hero's is one level
|
|
147
|
-
* deeper.
|
|
148
|
-
*
|
|
149
|
-
* The Footer is unaffected, measured rather than hoped: `FooterGroup.blocks`
|
|
150
|
-
* allows FooterText / FooterEmailSignup / FooterMenu / FooterDivider and none of
|
|
151
|
-
* those owns a slot, so no footer row grows a third level. What DOES gain one is
|
|
152
|
-
* a container nested inside a container (a Box in a Box) —
|
|
153
|
-
* blocks a merchant can already build and could not see.
|
|
154
|
-
*/
|
|
155
|
-
declare const TREE_MAX_DEPTH = 6;
|
|
156
|
-
/**
|
|
157
|
-
* Does the Layers tree draw a subtree under a node of `type` sitting at `depth`?
|
|
158
|
-
* True only when the type owns at least one slot AND the level is inside the cap.
|
|
159
|
-
* `depth` is 1 for a section's own children (the first `.sf-subtree`).
|
|
160
|
-
*
|
|
161
|
-
* The ONE place the cap is decided — both tree renderers and the "collapse all"
|
|
162
|
-
* gather read it here, so a row that folds and a row that draws children can
|
|
163
|
-
* never disagree about which rows those are.
|
|
164
|
-
*/
|
|
165
|
-
declare function nestsInTree(config: SlotConfigView, type: string, depth: number): boolean;
|
|
166
|
-
declare const newNodeId: (type: string) => string;
|
|
167
|
-
declare const HEADER_TYPE = "Header";
|
|
168
|
-
declare const FOOTER_TYPE = "Footer";
|
|
169
|
-
declare const ROOT_ZONE = "root:default-zone";
|
|
170
|
-
/**
|
|
171
|
-
* Indices of the DUPLICATE pinned chrome sections in a top-level content array —
|
|
172
|
-
* every Header/Footer node PAST the first of its type, in ascending order. Empty
|
|
173
|
-
* when the array already holds at most one of each (the healthy case), so a caller
|
|
174
|
-
* can skip the rewrite. Keeping the FIRST of each type matches exactly what the
|
|
175
|
-
* Sections tree shows (footerIndex/findIndex), so healing never surprises the
|
|
176
|
-
* author by dropping the copy they were looking at. Accepts a loose node shape so
|
|
177
|
-
* both the editor's `TreeItem[]` and the published render's untyped content pass.
|
|
178
|
-
*/
|
|
179
|
-
declare function pinnedDuplicateIndices(content: ReadonlyArray<{
|
|
180
|
-
type?: string;
|
|
181
|
-
}>): number[];
|
|
182
|
-
/**
|
|
183
|
-
* Ids of the DUPLICATE pinned chrome sections — the id-anchored counterpart of
|
|
184
|
-
* pinnedDuplicateIndices, derived FROM it so the two can never disagree about
|
|
185
|
-
* which copy is the keeper (the first of each type).
|
|
186
|
-
*
|
|
187
|
-
* A LIVE store must be edited by identity, never by position: an index computed
|
|
188
|
-
* from a render snapshot addresses whatever has since shifted into that slot,
|
|
189
|
-
* which is how the old editor heal deleted real sections. Ids survive that skew
|
|
190
|
-
* — the worst a stale read can do is name a node that is no longer there. A
|
|
191
|
-
* duplicate carrying no id is skipped (it cannot be named in a remove); the
|
|
192
|
-
* published render's index-based dedupe still drops it.
|
|
193
|
-
*/
|
|
194
|
-
declare function pinnedDuplicateIds(content: ReadonlyArray<{
|
|
195
|
-
type?: string;
|
|
196
|
-
props?: {
|
|
197
|
-
id?: unknown;
|
|
198
|
-
};
|
|
199
|
-
}>): string[];
|
|
200
|
-
/**
|
|
201
|
-
* Which pinned chrome types a document is MISSING, and a load-time seed must
|
|
202
|
-
* therefore create. A type counts as missing only when it is absent from BOTH:
|
|
203
|
-
*
|
|
204
|
-
* - `live` — the editor's Puck store, read at the moment of the write; and
|
|
205
|
-
* - `persisted` — the document exactly as it was LOADED from the backend.
|
|
206
|
-
*
|
|
207
|
-
* Requiring both is what makes seeding idempotent, and neither check can be
|
|
208
|
-
* dropped. Trusting `live` alone was the duplicate-Header bug: a remount re-armed
|
|
209
|
-
* the seed's per-mount guard while a snapshot that lagged the store reported "no
|
|
210
|
-
* Header", so a second one was appended next to the first. Trusting `persisted`
|
|
211
|
-
* alone would re-seed a node this session has already inserted but not yet saved.
|
|
212
|
-
*
|
|
213
|
-
* Returned in no particular order — the CALLER owns the insert order, because
|
|
214
|
-
* only it knows that the Footer is pinned last and the Header first.
|
|
215
|
-
*/
|
|
216
|
-
declare function missingPinnedTypes(live: ReadonlyArray<{
|
|
217
|
-
type?: string;
|
|
218
|
-
}>, persisted: ReadonlyArray<{
|
|
219
|
-
type?: string;
|
|
220
|
-
}>): string[];
|
|
221
|
-
|
|
222
|
-
export { FOOTER_TYPE, HEADER_TYPE, type NodeLocation, ROOT_ZONE, type SlotChild, type SlotConfigView, TREE_MAX_DEPTH, type TreeItem, blockNodeActions, childSlotsOf, locateNode, missingPinnedTypes, nestsInTree, newNodeId, pinnedDuplicateIds, pinnedDuplicateIndices, slotChildrenIn, slotFieldsOf };
|
|
1
|
+
export { FOOTER_TYPE, HEADER_TYPE, NodeLocation, ROOT_ZONE, SlotChild, SlotConfigView, TREE_MAX_DEPTH, TreeItem, blockNodeActions, childSlotsOf, locateNode, missingPinnedTypes, nestsInTree, newNodeId, pinnedDuplicateIds, pinnedDuplicateIndices, slotChildrenIn, slotFieldsOf } from '../document/content-tree.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{FOOTER_TYPE,HEADER_TYPE,ROOT_ZONE,TREE_MAX_DEPTH,blockNodeActions,childSlotsOf,locateNode,missingPinnedTypes,nestsInTree,newNodeId,pinnedDuplicateIds,pinnedDuplicateIndices,slotChildrenIn,slotFieldsOf}from"../../../chunk-
|
|
1
|
+
import"../../../chunk-PRHBWA5V.js";export{FOOTER_TYPE,HEADER_TYPE,ROOT_ZONE,TREE_MAX_DEPTH,blockNodeActions,childSlotsOf,locateNode,missingPinnedTypes,nestsInTree,newNodeId,pinnedDuplicateIds,pinnedDuplicateIndices,slotChildrenIn,slotFieldsOf}from"../../../chunk-TCAAOYQY.js";
|
|
@@ -1,128 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
export { DEVICE_FIELD_MARKER, DEVICE_HIDDEN_ATTR, DEVICE_NOTE, DeviceFieldMeta, DeviceTier, deviceField, deviceMetaOf, deviceNote, shownTier, withoutDeviceGate } from '../document/device-fields.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '../../components/PreviewDeviceContext.js';
|
|
3
4
|
import '../content/view-tiers.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* lib/puck/device-fields.tsx — show the setting for the device the merchant is
|
|
7
|
-
* currently looking at, and only that one.
|
|
8
|
-
*
|
|
9
|
-
* THE PROBLEM. A section that can be sized differently on a phone stores TWO
|
|
10
|
-
* props and the panel drew BOTH, side by side, told apart only by a "(desktop)"
|
|
11
|
-
* / "(mobile)" suffix on the label. The canvas already knows which device is on
|
|
12
|
-
* screen; the panel ignored it, so the merchant read labels to find the control
|
|
13
|
-
* that matched what they were looking at.
|
|
14
|
-
*
|
|
15
|
-
* THE MECHANISM, and why this one. A Puck `resolveFields` cannot do it: in this
|
|
16
|
-
* Puck version the fields slice re-resolves only when the selected node's DATA
|
|
17
|
-
* changes (`useRegisterFieldsSlice` subscribes to `state.indexes.nodes[id]`), and
|
|
18
|
-
* switching device changes no data — the panel would keep whatever field set the
|
|
19
|
-
* last edit produced. So the decision is made where it can re-render freely: in
|
|
20
|
-
* the FIELD ITSELF, off the React context the editor chrome already publishes
|
|
21
|
-
* (`components/PreviewDeviceContext`, which the per-view Footer controls read
|
|
22
|
-
* for the same reason). One context, no prop threaded anywhere, and every house
|
|
23
|
-
* control is already a `type: "custom"` render, so wrapping one costs nothing.
|
|
24
|
-
*
|
|
25
|
-
* ⚠️ HIDDEN IS NOT DELETED. {@link deviceField} returns the SAME field object
|
|
26
|
-
* with the same markers (`__media`, `__text`, …) and the same key; only its
|
|
27
|
-
* paint is gated. Both props keep existing, keep their keys, keep their values
|
|
28
|
-
* and keep their `defaultProps`. Switch to Phone, type a size, switch back — the
|
|
29
|
-
* desktop size is exactly where it was, because nothing ever wrote to it.
|
|
30
|
-
* `scripts/test-device-fields.tsx` pins that round trip.
|
|
31
|
-
*
|
|
32
|
-
* TABLET (owner ruling, card 66066). There are no tablet-specific stored values
|
|
33
|
-
* today, and inventing them would mean a new stored prop on every section — a
|
|
34
|
-
* different card. So tablet shows the DESKTOP values and the panel SAYS SO
|
|
35
|
-
* ({@link DEVICE_NOTE}); it never presents desktop values as if they were
|
|
36
|
-
* tablet's. {@link shownTier} is the single place that ruling is written down.
|
|
37
|
-
*
|
|
38
|
-
* WHY THE HIDDEN FIELD LEAVES NO GAP. Puck wraps every top-level field in its
|
|
39
|
-
* own padded `_PuckFields-field_` box before it calls `render`, so a field that
|
|
40
|
-
* renders nothing would still cost ~37px of empty panel. The gate instead paints
|
|
41
|
-
* a zero-size marker and this package's `screen.css` collapses the
|
|
42
|
-
* wrapper that contains one — the same "reach the wrapper Puck owns" trick the
|
|
43
|
-
* fold reflow in `controls.tsx` already relies on, expressed as one CSS rule
|
|
44
|
-
* instead of a second DOM pass (so it cannot race the fold's).
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
/** The two tiers a stored value can belong to. Tablet is not one — see
|
|
48
|
-
* {@link shownTier}. */
|
|
49
|
-
type DeviceTier = "desktop" | "mobile";
|
|
50
|
-
/**
|
|
51
|
-
* Which tier's stored values the panel shows for a given preview device.
|
|
52
|
-
*
|
|
53
|
-
* The owner ruling in one expression: phone shows the phone values, everything
|
|
54
|
-
* else — desktop AND tablet — shows the desktop values.
|
|
55
|
-
*/
|
|
56
|
-
declare function shownTier(device: PreviewDevice): DeviceTier;
|
|
57
|
-
/**
|
|
58
|
-
* The quiet line the panel puts above a section's settings, so a merchant can
|
|
59
|
-
* always tell WHICH device's value they are editing without reading the canvas.
|
|
60
|
-
*
|
|
61
|
-
* Desktop says nothing: it is the resting state, and a banner that is always
|
|
62
|
-
* there is a banner nobody reads. Tablet says the ruling out loud rather than
|
|
63
|
-
* letting the desktop values pass for tablet's own.
|
|
64
|
-
*/
|
|
65
|
-
declare const DEVICE_NOTE: Readonly<Record<PreviewDevice, string | null>>;
|
|
66
|
-
/** The attribute the stylesheet looks for to collapse a gated-off field's Puck
|
|
67
|
-
* wrapper. Declared here, matched once in this package's `screen.css`, which
|
|
68
|
-
* every host that mounts the screen loads (it sat in the website's sheet until
|
|
69
|
-
* 0.103.0, so a second host's hidden rows kept their space). */
|
|
70
|
-
declare const DEVICE_HIDDEN_ATTR = "data-sf-device-hidden";
|
|
71
|
-
/** A house control's render, seen from outside: the builders in `controls.tsx`
|
|
72
|
-
* each type their own props, so the gate takes the widest shape that can be
|
|
73
|
-
* passed straight back through. */
|
|
74
|
-
type FieldRender = (props: Record<string, unknown>) => ReactElement;
|
|
75
|
-
/** Any house control — every one of them is a `type: "custom"` field whose
|
|
76
|
-
* `render` is a plain function of its props. */
|
|
77
|
-
type AnyCustomField = {
|
|
78
|
-
type: "custom";
|
|
79
|
-
render: FieldRender;
|
|
80
|
-
};
|
|
81
|
-
/** Marker carried by every gated field, in the same style as
|
|
82
|
-
* {@link import("./controls").FOLD_FIELD_MARKER}: the tier and the field it
|
|
83
|
-
* wraps live ON the field object, never only inside the render closure. Without
|
|
84
|
-
* it a gated control is opaque to every static walk — and the fold guard in
|
|
85
|
-
* `scripts/test-section-groups.ts` genuinely needs to see the header underneath
|
|
86
|
-
* to check its label against what it draws. Puck ignores extra keys. */
|
|
87
|
-
declare const DEVICE_FIELD_MARKER: "__device";
|
|
88
|
-
/** The payload on {@link DEVICE_FIELD_MARKER}. */
|
|
89
|
-
type DeviceFieldMeta = {
|
|
90
|
-
tier: DeviceTier;
|
|
91
|
-
inner: unknown;
|
|
92
|
-
};
|
|
93
|
-
/** Read a field's device payload, or null when it is not gated. The ONE place
|
|
94
|
-
* that knows the marker's shape. */
|
|
95
|
-
declare function deviceMetaOf(field: unknown): DeviceFieldMeta | null;
|
|
96
|
-
/** The field a gate wraps, or the field itself when it wraps nothing — what a
|
|
97
|
-
* static walk wants to look at. */
|
|
98
|
-
declare function withoutDeviceGate(field: unknown): unknown;
|
|
99
|
-
/**
|
|
100
|
-
* Paint `field` only while the canvas is showing `tier`.
|
|
101
|
-
*
|
|
102
|
-
* Everything else about the field is preserved by identity-spread — its `type`,
|
|
103
|
-
* its manifest markers, its data keys — so the media and neutralization walks,
|
|
104
|
-
* the field-key census and every stored prop see exactly what they saw before.
|
|
105
|
-
*/
|
|
106
|
-
declare function deviceField<F extends {
|
|
107
|
-
type: "custom";
|
|
108
|
-
render: (p: never) => ReactElement;
|
|
109
|
-
}>(tier: DeviceTier, field: F): F;
|
|
110
|
-
/**
|
|
111
|
-
* The panel's device indicator — one quiet line, and only when there is
|
|
112
|
-
* something to say (see {@link DEVICE_NOTE}).
|
|
113
|
-
*
|
|
114
|
-
* Declared as a FIELD rather than painted by the chrome so it sits inside the
|
|
115
|
-
* settings panel it describes, above the first group, and so a section that has
|
|
116
|
-
* no device-varying control never shows it. It edits nothing: like `group()` /
|
|
117
|
-
* `section()` it is a header, with no prop behind it.
|
|
118
|
-
*
|
|
119
|
-
* …WHICH IS WHY IT SAYS SO ON THE FIELD (card 66201). A note is not a control, so
|
|
120
|
-
* a heading with nothing but this under it is a heading over nothing — and it is
|
|
121
|
-
* the whole reason the Hero's Content tab was empty: `_dDevice` is the section's
|
|
122
|
-
* first field, so it opened the implicit leading Content run and gave the panel a
|
|
123
|
-
* Content tab with only a banner in it, while the hero's actual copy is edited in
|
|
124
|
-
* the Text sub-panel.
|
|
125
|
-
*/
|
|
126
|
-
declare function deviceNote(): AnyCustomField;
|
|
127
|
-
|
|
128
|
-
export { DEVICE_FIELD_MARKER, DEVICE_HIDDEN_ATTR, DEVICE_NOTE, type DeviceFieldMeta, type DeviceTier, deviceField, deviceMetaOf, deviceNote, shownTier, withoutDeviceGate };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{DEVICE_FIELD_MARKER,DEVICE_HIDDEN_ATTR,DEVICE_NOTE,deviceField,deviceMetaOf,deviceNote,shownTier,withoutDeviceGate}from"../../../chunk-
|
|
1
|
+
export{DEVICE_FIELD_MARKER,DEVICE_HIDDEN_ATTR,DEVICE_NOTE,deviceField,deviceMetaOf,deviceNote,shownTier,withoutDeviceGate}from"../../../chunk-KWLHKKZO.js";import"../../../chunk-INRERJU4.js";import"../../../chunk-EB6NI2VK.js";import"../../../chunk-MFIRYGHW.js";import"../../../chunk-BSPCSC45.js";
|
|
@@ -1,36 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* lib/puck/field-buckets.ts — the two settings buckets a section's fields are
|
|
5
|
-
* sorted into (Design, Animation: owner 2026-10-08, final 2026-10-10), the
|
|
6
|
-
* field key each bucket's header is emitted under, and the field key of each
|
|
7
|
-
* Design group's heading.
|
|
8
|
-
*
|
|
9
|
-
* Moved out of lib/puck/field-groups (which re-exports both) so the editor's
|
|
10
|
-
* screen can read a header's key — the style clipboard copies a look by the
|
|
11
|
-
* groups it sits in — without importing the field builders that sort a
|
|
12
|
-
* section's fields (doc/adr/0004). The reasoning behind the buckets themselves
|
|
13
|
-
* stays in field-groups, beside the pass that applies them.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
type Bucket = SettingsBucket;
|
|
17
|
-
/**
|
|
18
|
-
* The field key each bucket's header is emitted under. `_s*` because these are
|
|
19
|
-
* level-1 headers (`section()`), matching the `_s*` convention the sections that
|
|
20
|
-
* already carry level-1 headers use (`_sText`, `_sImage`, `_sSetup`, …).
|
|
21
|
-
*/
|
|
22
|
-
declare const BUCKET_KEY: Record<Bucket, string>;
|
|
23
|
-
/**
|
|
24
|
-
* The field key of each Design group's heading, inside the Design bucket. The
|
|
25
|
-
* HOST emits them, in `DESIGN_GROUPS` order, one for each group it has; a row
|
|
26
|
-
* belongs to the heading above it. `_dContent` is a marker that draws no
|
|
27
|
-
* heading (the Content part has none), and the rows before the first group
|
|
28
|
-
* heading of Design are Content too. `_d*` for Design's own headings, apart
|
|
29
|
-
* from the `_s*` bucket headers and the `_g*` group headers a section draws.
|
|
30
|
-
* Only these six keys are group headings: `_dDevice` (the device note,
|
|
31
|
-
* ./device-fields) shares the prefix and is not one, so never read a group off
|
|
32
|
-
* the prefix.
|
|
33
|
-
*/
|
|
34
|
-
declare const DESIGN_GROUP_KEY: Record<DesignGroup, string>;
|
|
35
|
-
|
|
36
|
-
export { BUCKET_KEY, type Bucket, DESIGN_GROUP_KEY };
|
|
1
|
+
export { BUCKET_KEY, Bucket, DESIGN_GROUP_KEY } from '../document/field-buckets.js';
|
|
2
|
+
import '../../../buckets-Sw94ll9I.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{BUCKET_KEY,DESIGN_GROUP_KEY}from"../../../chunk-
|
|
1
|
+
export{BUCKET_KEY,DESIGN_GROUP_KEY}from"../../../chunk-3QB2ZQXK.js";
|
|
@@ -1,205 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* field-markers — what a field DECLARES about itself, readable without the
|
|
5
|
-
* inspector.
|
|
6
|
-
*
|
|
7
|
-
* A control factory in `lib/puck/controls` stamps a marker on the field object
|
|
8
|
-
* it returns: this prop holds authored copy, this one a link, this row array
|
|
9
|
-
* draws these scaffold rows while it is empty. Two kinds of code read those
|
|
10
|
-
* stamps. The inspector does, and so does the RENDER side — the part walk that
|
|
11
|
-
* makes a headline clickable (`lib/puck/text-parts`), the typing bridge
|
|
12
|
-
* (`lib/puck/part-text`, `lib/puck/part-rows`) — and a section's own option
|
|
13
|
-
* module may be typed by a control's vocabulary (`lib/sections/ticker-scroll`
|
|
14
|
-
* names the pad cell each direction sits in).
|
|
15
|
-
*
|
|
16
|
-
* ⚠️ WHY THIS IS ITS OWN FILE. The markers were born in `controls.tsx` beside
|
|
17
|
-
* the factories that stamp them, and `controls.tsx` is the inspector: React, the
|
|
18
|
-
* editor shell, the link picker, the form picker, and through them the API
|
|
19
|
-
* client and the cart. A render-side module that only wanted the string
|
|
20
|
-
* `"__text"` imported all of it, which is what kept a general section from being
|
|
21
|
-
* drawn anywhere the inspector cannot go (doc/adr/0002). The same split, for the
|
|
22
|
-
* same reason, that `lib/puck/hidable` and `lib/puck/text-control-kinds` already
|
|
23
|
-
* made.
|
|
24
|
-
*
|
|
25
|
-
* This file imports nothing but that kinds leaf. `controls.tsx` re-exports
|
|
26
|
-
* every name, so an inspector-side import site is unchanged; a render-side
|
|
27
|
-
* module imports from HERE. `scripts/test-general-sections-import-boundary.ts`
|
|
28
|
-
* fails when one goes back to `controls`.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/** Marker carried by every AUTHORED-TEXT field object, mirroring
|
|
32
|
-
* {@link MEDIA_FIELD_MARKER} below. The neutralization manifest
|
|
33
|
-
* GENERATOR (`scripts/gen-neutralization-manifest.ts`) walks the built config
|
|
34
|
-
* looking for it, so the text factories are the single source of truth for
|
|
35
|
-
* "this prop holds customer-authored copy" — a new text field is covered the
|
|
36
|
-
* moment it is declared, with no list to maintain anywhere (Puck ignores extra
|
|
37
|
-
* keys).
|
|
38
|
-
*
|
|
39
|
-
* Unlike the media marker this carries a PAYLOAD, because the neutralizer needs
|
|
40
|
-
* more than a boolean: the declared `placeholder` IS the neutral replacement
|
|
41
|
-
* copy (the greyed hint the designer already wrote for an empty field), and
|
|
42
|
-
* `control` says which value shape the prop stores — `text`/`textarea` persist
|
|
43
|
-
* `{ text, hidden }` once edited, the `plain*` variants stay bare strings, and
|
|
44
|
-
* `textList` stores `{ text }[]`. A neutralizer that assumed "string" would
|
|
45
|
-
* silently skip most EDITED copy. */
|
|
46
|
-
declare const TEXT_FIELD_MARKER: "__text";
|
|
47
|
-
/** Marker carried by every LINK-DESTINATION field. A destination is not authored
|
|
48
|
-
* prose — it is a tenant-specific target (an internal path, an absolute URL, a
|
|
49
|
-
* `mailto:`/`tel:`, or an in-page `#anchor`) — so it neutralizes by its own rule
|
|
50
|
-
* rather than to placeholder copy. Kept separate from {@link TEXT_FIELD_MARKER}
|
|
51
|
-
* so the two can never be conflated. */
|
|
52
|
-
declare const LINK_FIELD_MARKER: "__link";
|
|
53
|
-
/**
|
|
54
|
-
* Marker carrying the rows a ROW-ARRAY field draws in the editor preview while
|
|
55
|
-
* its stored value is still empty — the `phRows` scaffold, declared on the field
|
|
56
|
-
* instead of only at the render call.
|
|
57
|
-
*
|
|
58
|
-
* WHY IT HAS TO BE ON THE FIELD. A scalar text control already declares its own
|
|
59
|
-
* greyed hint (`placeholder` above), and everything that asks "what does this
|
|
60
|
-
* prop put on screen?" — the neutralizer, the part walk — reads it there. A row
|
|
61
|
-
* array had no equivalent: `config.tsx` passes the scaffold constant straight
|
|
62
|
-
* into `phRows(value, SCAFFOLD, puck)` inside the render, where nothing outside
|
|
63
|
-
* the component can see it. So a freshly-dropped section drew three grey rows of
|
|
64
|
-
* scaffold copy that `lib/puck/text-parts` could not name, and clicking that copy
|
|
65
|
-
* opened the whole section instead of the one control behind it (card 66072).
|
|
66
|
-
*
|
|
67
|
-
* It is the SAME constant the render passes — `withScaffold` (in
|
|
68
|
-
* `lib/puck/controls`) takes it as an argument rather than copying it — so the
|
|
69
|
-
* preview and the walk cannot drift. Puck ignores extra keys on a field, exactly
|
|
70
|
-
* as it does for the two markers above.
|
|
71
|
-
*/
|
|
72
|
-
declare const SCAFFOLD_FIELD_MARKER: "__scaffold";
|
|
73
|
-
/**
|
|
74
|
-
* How the SECTION consuming a `textList` draws each row — and therefore whether
|
|
75
|
-
* the list may offer a formatting bar at all.
|
|
76
|
-
*
|
|
77
|
-
* This is the `COPY_FIELD_TOOLS` rule (`lib/markup.ts`) applied one level up. Upstream, the
|
|
78
|
-
* button set is derived from the grammar so a tool whose output the parser cannot
|
|
79
|
-
* read back can never appear. Here the same question is asked of the CONSUMER: a
|
|
80
|
-
* `"markup"` list is one whose rows go through `renderGold`, so every mark the
|
|
81
|
-
* grammar writes is drawn; a `"verbatim"` list is printed as-is (an Integrations
|
|
82
|
-
* chip, a ContactRouting meta line, a Mockup kanban card), where `**bold**` would
|
|
83
|
-
* reach the shopper as four literal asterisks. A mark stored where nothing renders
|
|
84
|
-
* it is a bug, not a feature — so a verbatim list gets no bar.
|
|
85
|
-
*
|
|
86
|
-
* DELIBERATELY REQUIRED, with no default. The two facts — what a field offers and
|
|
87
|
-
* what its section renders — sit in different files, and a default would let them
|
|
88
|
-
* agree by luck: whichever way it pointed, the next `textList` would inherit an
|
|
89
|
-
* answer nobody checked. Stating it at the call site puts the question in front of
|
|
90
|
-
* whoever adds the field, next to the render that answers it.
|
|
91
|
-
*/
|
|
92
|
-
type TextListRendering =
|
|
93
|
-
/** Rows render through `renderGold` — the shared grammar parses them back. */
|
|
94
|
-
"markup"
|
|
95
|
-
/** Rows are printed exactly as stored; a delimiter would reach the shopper. */
|
|
96
|
-
| "verbatim";
|
|
97
|
-
/** The payload on {@link TEXT_FIELD_MARKER}: what a text field says about the
|
|
98
|
-
* copy it holds. The `with…` wrappers that set its optional facts, and the
|
|
99
|
-
* readers that pair with them, are in `lib/puck/controls`. */
|
|
100
|
-
type TextFieldMeta = {
|
|
101
|
-
control: TextControlKind;
|
|
102
|
-
/** The control's inspector label — a classification signal when a field
|
|
103
|
-
* declares no placeholder (labels read "Heading …", "Body …", "Alt text"). */
|
|
104
|
-
label: string;
|
|
105
|
-
/** The declared greyed hint. PRIMARY source of the neutral replacement copy. */
|
|
106
|
-
placeholder?: string;
|
|
107
|
-
/** The one-line caption UNDER the box, where the field carries one. Recorded
|
|
108
|
-
* here for the same reason the two above are: it is merchant-facing copy, so
|
|
109
|
-
* the walks that ask "what words does this panel show?" — the neutralizer,
|
|
110
|
-
* `test-accent-syntax-taught`, `test-panel-plain-words` — must be able to see
|
|
111
|
-
* it without rendering. It is NOT a neutralization source: a hint explains
|
|
112
|
-
* the control and belongs to the product, not to the tenant's content. */
|
|
113
|
-
hint?: string;
|
|
114
|
-
/**
|
|
115
|
-
* DECLARED: these words never reach a shopper (card 66280). Set only by
|
|
116
|
-
* `withOffPage`, and only on a prop whose copy no render puts on the
|
|
117
|
-
* storefront — a join key, a tab reference, a tree label. The section screen's
|
|
118
|
-
* entry row then says so instead of previewing the value.
|
|
119
|
-
*
|
|
120
|
-
* ABSENT MEANS ON THE PAGE, and that default is the point. It cannot be
|
|
121
|
-
* derived: the walk that builds the entry rows reads fields, and only a
|
|
122
|
-
* component's RENDER knows whether a prop reaches a shopper. The costs of
|
|
123
|
-
* being wrong are not symmetric either — a field wrongly marked hides a
|
|
124
|
-
* merchant's own words behind a note, while a field wrongly left unmarked
|
|
125
|
-
* merely previews its stored value, which is true. So the default takes the
|
|
126
|
-
* harmless side and the exception is typed.
|
|
127
|
-
*/
|
|
128
|
-
offPage?: true;
|
|
129
|
-
/**
|
|
130
|
-
* DECLARED: this row NAMES the thing rather than saying anything to a shopper
|
|
131
|
-
* — a slide's own name, a box's name in the Layers tree, a card's display
|
|
132
|
-
* override. The Text entry list draws these in a folded group of their own, so
|
|
133
|
-
* a panel opens on the words a merchant is writing and not on the labels the
|
|
134
|
-
* editor needs (owner 2026-09-04, pointing at a Hero Slide's `Slide name` and
|
|
135
|
-
* `Category tag`: "every panel carries this, I think it is wrong").
|
|
136
|
-
*
|
|
137
|
-
* ⚠️ IT IS NOT {@link offPage}, AND THE TWO ARE INDEPENDENT. `offPage` answers
|
|
138
|
-
* "do the words reach a shopper"; this answers "is the row a name or is it
|
|
139
|
-
* copy". Three of the four fields that carry this ARE on the page — a slide
|
|
140
|
-
* name is printed in the reel rail — so deriving one from the other would have
|
|
141
|
-
* folded away a merchant's published copy. `Box name` is the only one that is
|
|
142
|
-
* both, and it is the coincidence that makes the pair look derivable.
|
|
143
|
-
*
|
|
144
|
-
* FOLDED, NOT DROPPED, and that is the whole design. The entry list is the
|
|
145
|
-
* ONLY way back into a part with no clickable words on the canvas
|
|
146
|
-
* (`components/SectionTextEntries.tsx`), and an EMPTY field never has any: an
|
|
147
|
-
* unset `Alt name` draws the category's name, not its own, so a row that
|
|
148
|
-
* vanished once hidden would stand the merchant up with no way to set one.
|
|
149
|
-
* A fold keeps every row reachable in one press and still answers the owner.
|
|
150
|
-
*/
|
|
151
|
-
identifier?: true;
|
|
152
|
-
/** For `textList`, the key each row stores its copy under. */
|
|
153
|
-
itemKey?: string;
|
|
154
|
-
/** For `textList`, whether its rows go through `renderGold` — the same answer
|
|
155
|
-
* {@link TextListRendering} makes the call site state, recorded here so a
|
|
156
|
-
* ROW opened on its own (card 66090) offers the formatting bar exactly when
|
|
157
|
-
* the whole list does. Without it the row control would have to guess, and a
|
|
158
|
-
* bar on a `verbatim` list writes markers the shopper reads as asterisks. */
|
|
159
|
-
rendering?: TextListRendering;
|
|
160
|
-
};
|
|
161
|
-
/** Which of an edge pad's four live squares an answer sits in — the cell a
|
|
162
|
-
* direction option names beside its value (`lib/sections/ticker-scroll`), and
|
|
163
|
-
* the one the pad in `lib/puck/controls` lights. */
|
|
164
|
-
type EdgeCell = "top" | "right" | "bottom" | "left";
|
|
165
|
-
/** Marker carried by every media field object. The manifest GENERATOR walks the
|
|
166
|
-
* built config looking for it, so the factory below is the single source of
|
|
167
|
-
* truth for "this prop holds media" — a new media field is covered the moment
|
|
168
|
-
* it is declared, with no list to maintain anywhere (Puck ignores extra keys). */
|
|
169
|
-
declare const MEDIA_FIELD_MARKER: "__media";
|
|
170
|
-
/** Marker carried by every heading {@link group} / {@link section} builds — and
|
|
171
|
-
* by every bucket header {@link bucketHeader} builds, whose "heading" a
|
|
172
|
-
* merchant reads as a TAB. Same style as {@link TEXT_FIELD_MARKER} / {@link LINK_FIELD_MARKER}:
|
|
173
|
-
* the label and the level ON the field object, not only inside the render
|
|
174
|
-
* closure. Without it a header's label is unreadable at runtime — the closure
|
|
175
|
-
* is all there is — and the four-bucket pass (`lib/puck/field-groups.ts`) would
|
|
176
|
-
* have to re-derive it by parsing `config.tsx`, i.e. a second source of truth
|
|
177
|
-
* for something the field already knows. Puck ignores extra keys, and the
|
|
178
|
-
* neutralization walk classifies by its own markers / `type` / prop name, so a
|
|
179
|
-
* header stays exactly as invisible to it as it was (see
|
|
180
|
-
* `scripts/gen-neutralization-manifest.ts`). */
|
|
181
|
-
declare const FOLD_FIELD_MARKER: "__fold";
|
|
182
|
-
type FoldFieldMeta = {
|
|
183
|
-
label: string;
|
|
184
|
-
level: 1 | 2;
|
|
185
|
-
};
|
|
186
|
-
/** Read a field's fold-header payload, or null when it is not a header. The ONE
|
|
187
|
-
* place that knows the marker's shape. */
|
|
188
|
-
declare function foldMetaOf(field: unknown): FoldFieldMeta | null;
|
|
189
|
-
/**
|
|
190
|
-
* Does this field DECLARE itself a name rather than copy? The read that pairs
|
|
191
|
-
* with {@link withIdentifier}'s write, so the one fact has one reader — the same
|
|
192
|
-
* shape as {@link textFieldOffPage}, and false for anything that is not a text
|
|
193
|
-
* field at all rather than throwing.
|
|
194
|
-
*/
|
|
195
|
-
declare function textFieldIdentifier(field: unknown): boolean;
|
|
196
|
-
/**
|
|
197
|
-
* The keys `anchorFields()` (lib/puck/controls) declares: the anchor's group
|
|
198
|
-
* header and its name row. The style clipboard leaves them out of a copied
|
|
199
|
-
* look — an anchor is the section's address, not its style — and reads them
|
|
200
|
-
* here rather than calling the builder, so it needs nothing of the inspector's
|
|
201
|
-
* field builders. scripts/test-anchor-field-keys.ts holds the two equal.
|
|
202
|
-
*/
|
|
203
|
-
declare const ANCHOR_FIELD_KEYS: readonly ["_gAnchor", "anchor"];
|
|
204
|
-
|
|
205
|
-
export { ANCHOR_FIELD_KEYS, type EdgeCell, FOLD_FIELD_MARKER, type FoldFieldMeta, LINK_FIELD_MARKER, MEDIA_FIELD_MARKER, SCAFFOLD_FIELD_MARKER, TEXT_FIELD_MARKER, type TextFieldMeta, type TextListRendering, foldMetaOf, textFieldIdentifier };
|
|
1
|
+
export { ANCHOR_FIELD_KEYS, EdgeCell, FOLD_FIELD_MARKER, FoldFieldMeta, LINK_FIELD_MARKER, MEDIA_FIELD_MARKER, SCAFFOLD_FIELD_MARKER, TEXT_FIELD_MARKER, TextFieldMeta, TextListRendering, foldMetaOf, textFieldIdentifier } from '../document/field-markers.js';
|
|
2
|
+
import '../document/text-control-kinds.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{ANCHOR_FIELD_KEYS,FOLD_FIELD_MARKER,LINK_FIELD_MARKER,MEDIA_FIELD_MARKER,SCAFFOLD_FIELD_MARKER,TEXT_FIELD_MARKER,foldMetaOf,textFieldIdentifier}from"../../../chunk-
|
|
1
|
+
export{ANCHOR_FIELD_KEYS,FOLD_FIELD_MARKER,LINK_FIELD_MARKER,MEDIA_FIELD_MARKER,SCAFFOLD_FIELD_MARKER,TEXT_FIELD_MARKER,foldMetaOf,textFieldIdentifier}from"../../../chunk-ANPOR6EY.js";
|