efficient-easel 16.1.0 → 18.0.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.
Files changed (149) hide show
  1. package/README.md +28 -65
  2. package/dist/autosave/index.d.ts +4 -4
  3. package/dist/blocks/index.d.ts +2 -2
  4. package/dist/chrome/index.d.ts +3 -3
  5. package/dist/chrome/index.js +1 -1
  6. package/dist/chunk-43AEUUNQ.js +1 -0
  7. package/dist/{chunk-K6EM4F5N.js → chunk-5VD2LGIZ.js} +18 -18
  8. package/dist/{chunk-ATOXCKEE.js → chunk-7TOQCTHV.js} +3 -3
  9. package/dist/chunk-A6Z4SD3I.js +10 -0
  10. package/dist/{chunk-V6VKM2QX.js → chunk-A7FF65FL.js} +1 -1
  11. package/dist/chunk-BHRC3ASL.js +1 -0
  12. package/dist/chunk-BRMYJBMB.js +8 -0
  13. package/dist/chunk-C2RHV42O.js +1 -0
  14. package/dist/chunk-F7FDF6NS.js +4 -0
  15. package/dist/{chunk-IE55HNMA.js → chunk-GWIVPLOX.js} +11 -11
  16. package/dist/{chunk-2H3W5OLQ.js → chunk-HGV3FWOB.js} +1 -1
  17. package/dist/chunk-LLDHIBYG.js +18 -0
  18. package/dist/chunk-M2Z775ZC.js +1 -0
  19. package/dist/{chunk-2L2L7G5L.js → chunk-MPF5QZJ7.js} +1 -1
  20. package/dist/chunk-N3VPBHR6.js +62 -0
  21. package/dist/chunk-QEAUF632.js +14 -0
  22. package/dist/{chunk-UVQR7W6I.js → chunk-RFE7ZG3Y.js} +1 -1
  23. package/dist/chunk-STWSCR25.js +2 -0
  24. package/dist/{chunk-TZIIRGVY.js → chunk-U277UX5I.js} +1 -1
  25. package/dist/chunk-VEZPDGDQ.js +1 -0
  26. package/dist/{chunk-JQOYUH4A.js → chunk-W2GEGVUY.js} +4 -4
  27. package/dist/{chunk-GPLMNRHR.js → chunk-WOETW3H6.js} +1 -1
  28. package/dist/chunk-X3TYRF5V.js +1 -0
  29. package/dist/{chunk-62VPYC7F.js → chunk-XDZHKYQX.js} +1 -1
  30. package/dist/{chunk-HV56SLR2.js → chunk-XHHVMAGM.js} +1 -1
  31. package/dist/chunk-XHSGRH42.js +5 -0
  32. package/dist/{chunk-XQGV2XAK.js → chunk-YI4QXOVJ.js} +1 -1
  33. package/dist/{chunk-RFSLDGDA.js → chunk-YLQYEDUQ.js} +1 -1
  34. package/dist/copy/index.js +23 -11
  35. package/dist/drag/drag.css +8 -0
  36. package/dist/drag/index.d.ts +15 -1
  37. package/dist/drag/index.js +1 -1
  38. package/dist/draw/client.js +1 -1
  39. package/dist/draw/index.js +1 -1
  40. package/dist/easel/easel.css +8 -0
  41. package/dist/easel/index.d.ts +45 -6
  42. package/dist/easel/index.js +1 -1
  43. package/dist/fields/index.js +1 -1
  44. package/dist/gold/gold.css +1 -1
  45. package/dist/{host-DGmdCaNL.d.ts → host-epHo7r8P.d.ts} +12 -5
  46. package/dist/icons/index.d.ts +0 -2
  47. package/dist/node-ops/index.d.ts +2 -2
  48. package/dist/node-ops/index.js +1 -1
  49. package/dist/panel/index.js +1 -1
  50. package/dist/{plan-CGREINRO.d.ts → plan-CZS902DV.d.ts} +27 -1
  51. package/dist/rail/index.d.ts +2 -2
  52. package/dist/screen/components/AddBlockRow.js +1 -1
  53. package/dist/screen/components/AddSidePanel.d.ts +6 -1
  54. package/dist/screen/components/AddSidePanel.js +1 -1
  55. package/dist/screen/components/MediaSidePanel.d.ts +4 -3
  56. package/dist/screen/components/MediaSidePanel.js +1 -1
  57. package/dist/screen/components/NodeContextMenu.d.ts +8 -7
  58. package/dist/screen/components/NodeContextMenu.js +1 -1
  59. package/dist/screen/components/PageEditGuardNotices.js +1 -1
  60. package/dist/screen/components/SaveControls.d.ts +7 -6
  61. package/dist/screen/components/SaveControls.js +1 -1
  62. package/dist/screen/components/ScreenChrome.js +1 -1
  63. package/dist/screen/components/ScreenDocumentContext.d.ts +4 -3
  64. package/dist/screen/components/ScreenDocumentContext.js +1 -1
  65. package/dist/screen/components/ScreenMount.d.ts +7 -6
  66. package/dist/screen/components/ScreenMount.js +1 -1
  67. package/dist/screen/components/ScreenStoreProvider.d.ts +7 -6
  68. package/dist/screen/components/ScreenStoreProvider.js +1 -1
  69. package/dist/screen/components/SectionScreenShell.js +15 -15
  70. package/dist/screen/components/SidePanelHead.js +1 -1
  71. package/dist/screen/components/panel-widths.js +1 -1
  72. package/dist/screen/components/usePartBridge.d.ts +7 -6
  73. package/dist/screen/components/usePartBridge.js +1 -1
  74. package/dist/screen/index.d.ts +8 -7
  75. package/dist/screen/index.js +1 -1
  76. package/dist/screen/lib/admin-bridge.d.ts +3 -2
  77. package/dist/screen/lib/document-addressing.d.ts +4 -3
  78. package/dist/screen/lib/document-hooks.d.ts +2 -2
  79. package/dist/screen/lib/host-chrome.d.ts +0 -10
  80. package/dist/screen/lib/host.d.ts +4 -3
  81. package/dist/screen/lib/key-scope.js +1 -1
  82. package/dist/screen/lib/media-panel.d.ts +4 -3
  83. package/dist/screen/lib/media-picker.d.ts +7 -9
  84. package/dist/screen/lib/page-lock.d.ts +3 -2
  85. package/dist/screen/lib/puck/block-choice.d.ts +13 -1
  86. package/dist/screen/lib/puck/block-choice.js +1 -1
  87. package/dist/screen/lib/puck/device-fields.js +1 -1
  88. package/dist/screen/lib/puck/palette-sections.d.ts +2 -2
  89. package/dist/screen/lib/puck/section-doc.d.ts +2 -2
  90. package/dist/screen/lib/puck/slot-child-name.js +1 -1
  91. package/dist/screen/lib/puck/style-clipboard.d.ts +7 -6
  92. package/dist/screen/lib/puck/style-clipboard.js +1 -1
  93. package/dist/screen/lib/puck/use-section-ops.d.ts +2 -2
  94. package/dist/screen/lib/puck/use-section-ops.js +1 -1
  95. package/dist/screen/lib/save-status.d.ts +2 -2
  96. package/dist/screen/lib/screen-parts.d.ts +71 -29
  97. package/dist/screen/lib/screen-parts.js +1 -1
  98. package/dist/screen/lib/section-templates.d.ts +3 -2
  99. package/dist/screen/lib/session-context.d.ts +3 -2
  100. package/dist/screen/lib/session.d.ts +6 -2
  101. package/dist/screen/lib/shared-section-types.d.ts +71 -0
  102. package/dist/screen/lib/shared-section-types.js +1 -0
  103. package/dist/screen/lib/shared-sections.d.ts +34 -0
  104. package/dist/screen/lib/shared-sections.js +1 -0
  105. package/dist/screen/screen.css +7 -0
  106. package/dist/screen/words.d.ts +49 -3
  107. package/dist/screen/words.js +1 -1
  108. package/dist/shell/shell.css +6 -1
  109. package/dist/strings/index.d.ts +134 -20
  110. package/dist/strings/index.js +2 -2
  111. package/dist/text-styles/index.js +23 -23
  112. package/dist/tree/index.d.ts +3 -3
  113. package/dist/tree/index.js +1 -1
  114. package/dist/tree/tree.css +17 -0
  115. package/dist/{types-D8P9q-BG.d.ts → types-Bqq6ya0y.d.ts} +9 -0
  116. package/dist/{types-NQozKWEz.d.ts → types-Cq53lL8d.d.ts} +1 -1
  117. package/dist/{types-CsgMwHHa.d.ts → types-Cy7rdmXt.d.ts} +1 -1
  118. package/dist/{types-DGyDHiJV.d.ts → types-DT8ywrFQ.d.ts} +1 -1
  119. package/dist/{useNodeOps-BHRkUFfG.d.ts → useNodeOps-fIDWzftn.d.ts} +3 -1
  120. package/dist/{words-pgIK0I6g.d.ts → words-DkWcK1rh.d.ts} +2 -2
  121. package/package.json +16 -43
  122. package/dist/chunk-44COUKXO.js +0 -5
  123. package/dist/chunk-4BGYVIDQ.js +0 -57
  124. package/dist/chunk-4JSBIW5H.js +0 -9
  125. package/dist/chunk-ECM5F6JJ.js +0 -1
  126. package/dist/chunk-H4UMY7QF.js +0 -13
  127. package/dist/chunk-HMXIAMCU.js +0 -1
  128. package/dist/chunk-HQ4VVRIC.js +0 -1
  129. package/dist/chunk-IN22IYOM.js +0 -1
  130. package/dist/chunk-L2VGRQ4R.js +0 -4
  131. package/dist/chunk-L3GSW4XI.js +0 -1
  132. package/dist/chunk-POSLNRTO.js +0 -18
  133. package/dist/chunk-QX7GVECM.js +0 -13
  134. package/dist/chunk-TBF5CVPA.js +0 -1
  135. package/dist/chunk-U25CP5VX.js +0 -5
  136. package/dist/chunk-VVPZMWJE.js +0 -1
  137. package/dist/chunk-ZZ64CEC2.js +0 -2
  138. package/dist/gold/index.d.ts +0 -283
  139. package/dist/gold/index.js +0 -1
  140. package/dist/icons/meanings.d.ts +0 -1
  141. package/dist/icons/meanings.js +0 -1
  142. package/dist/index.d.ts +0 -6
  143. package/dist/index.js +0 -1
  144. package/dist/markup/index.d.ts +0 -1
  145. package/dist/markup/index.js +0 -1
  146. package/dist/shell/index.d.ts +0 -195
  147. package/dist/shell/index.js +0 -1
  148. package/dist/strings/catalogue.d.ts +0 -139
  149. package/dist/strings/catalogue.js +0 -1
@@ -1,11 +1,11 @@
1
1
  import { Data } from '../../blocks/index.js';
2
2
  import { EaselCapabilities } from './document-contract.js';
3
3
  import 'react';
4
- import '../../types-NQozKWEz.js';
4
+ import '../../types-Cq53lL8d.js';
5
5
  import '../../data/index.js';
6
6
  import '../../types-41704JE4.js';
7
7
  import '../../resolve-D68pb3Bx.js';
8
- import '../../plan-CGREINRO.js';
8
+ import '../../plan-CZS902DV.js';
9
9
 
10
10
  /**
11
11
  * WHAT A HOST DOES TO A DOCUMENT AS IT OPENS AND AS IT IS STORED.
@@ -109,19 +109,9 @@ interface EaselChrome {
109
109
  * header the settings of the host's pinned header, opened by selecting
110
110
  * the header in the canvas or its row in the tree. Without it the
111
111
  * inspector has no such panel.
112
- *
113
- * …and one the host adds to a panel of the editor's:
114
- *
115
- * chromePage drawn under the page settings of the page that STORES the
116
- * site's chrome (its footer page), on a document with a website
117
- * behind it. The storefront's is "Switch to Box header", which
118
- * builds the header group there from the shop's header row. It
119
- * takes no props: it reads the open document like any other part
120
- * of the editor (`useScreenDocument`, `useEasel`).
121
112
  */
122
113
  panels?: {
123
114
  header?: ComponentType<HostPanelProps>;
124
- chromePage?: ComponentType;
125
115
  };
126
116
  /**
127
117
  * A group of the host's own rows in the Pages panel, under the host's own
@@ -1,11 +1,11 @@
1
1
  import 'react';
2
- export { D as DETACHED_EASEL_HOST, E as EaselHost, b as EaselHostAddress, c as EaselHostContext, d as EaselHostProvider, e as EaselMessageType, f as EaselToHostMessage, H as HostPickedMedia, g as HostToEaselMessage, I as InboundHostMessage, S as SectionScreenTarget, h as SendToHost, i as createEaselHost, u as useEaselHost, j as useHostEscape } from '../../host-DGmdCaNL.js';
2
+ export { D as DETACHED_EASEL_HOST, E as EaselHost, b as EaselHostAddress, c as EaselHostContext, d as EaselHostProvider, e as EaselMessageType, f as EaselToHostMessage, H as HostPickedMedia, g as HostToEaselMessage, I as InboundHostMessage, P as PickedMediaSource, S as SectionScreenTarget, h as SendToHost, i as createEaselHost, u as useEaselHost, j as useHostEscape } from '../../host-epHo7r8P.js';
3
3
  import '../../blocks/index.js';
4
- import '../../types-NQozKWEz.js';
4
+ import '../../types-Cq53lL8d.js';
5
5
  import '../../data/index.js';
6
6
  import '../../types-41704JE4.js';
7
7
  import '../../resolve-D68pb3Bx.js';
8
- import '../../plan-CGREINRO.js';
8
+ import '../../plan-CZS902DV.js';
9
9
  import './document-contract.js';
10
10
  import './session.js';
11
11
  import './backend-error.js';
@@ -16,6 +16,7 @@ import 'efficient-shell/ui';
16
16
  import './document-hooks.js';
17
17
  import './section-template-types.js';
18
18
  import './puck/content-tree.js';
19
+ import './shared-section-types.js';
19
20
  import './document-switch.js';
20
21
  import '../../engine-CvXpFE86.js';
21
22
  import './admin-bridge.js';
@@ -1 +1 @@
1
- export{editorRootFocus,isSaveShortcut,useEaselKeyTarget,useEaselSaveKey,useEaselUndoKeys}from"../../chunk-RFSLDGDA.js";import"../../chunk-U3JP4VGF.js";import"../../chunk-QX7GVECM.js";import"../../chunk-TBY3DFKS.js";import"../../chunk-ECM5F6JJ.js";import"../../chunk-YRLPFZW3.js";import"../../chunk-X4T6JT3M.js";import"../../chunk-KRXQM65X.js";import"../../chunk-NKB3KVAB.js";import"../../chunk-23VM4PMV.js";import"../../chunk-B4JN227A.js";import"../../chunk-MFIRYGHW.js";
1
+ export{editorRootFocus,isSaveShortcut,useEaselKeyTarget,useEaselSaveKey,useEaselUndoKeys}from"../../chunk-YLQYEDUQ.js";import"../../chunk-U3JP4VGF.js";import"../../chunk-QEAUF632.js";import"../../chunk-TBY3DFKS.js";import"../../chunk-YRLPFZW3.js";import"../../chunk-X3TYRF5V.js";import"../../chunk-23VM4PMV.js";import"../../chunk-B4JN227A.js";import"../../chunk-MFIRYGHW.js";import"../../chunk-X4T6JT3M.js";import"../../chunk-KRXQM65X.js";import"../../chunk-NKB3KVAB.js";
@@ -1,12 +1,12 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentType, ReactNode } from 'react';
3
- import { H as HostPickedMedia, E as EaselHost } from '../../host-DGmdCaNL.js';
3
+ import { H as HostPickedMedia, E as EaselHost } from '../../host-epHo7r8P.js';
4
4
  import '../../blocks/index.js';
5
- import '../../types-NQozKWEz.js';
5
+ import '../../types-Cq53lL8d.js';
6
6
  import '../../data/index.js';
7
7
  import '../../types-41704JE4.js';
8
8
  import '../../resolve-D68pb3Bx.js';
9
- import '../../plan-CGREINRO.js';
9
+ import '../../plan-CZS902DV.js';
10
10
  import './document-contract.js';
11
11
  import './session.js';
12
12
  import './backend-error.js';
@@ -17,6 +17,7 @@ import 'efficient-shell/ui';
17
17
  import './document-hooks.js';
18
18
  import './section-template-types.js';
19
19
  import './puck/content-tree.js';
20
+ import './shared-section-types.js';
20
21
  import './document-switch.js';
21
22
  import '../../engine-CvXpFE86.js';
22
23
  import './admin-bridge.js';
@@ -1,11 +1,11 @@
1
- import { E as EaselHost } from '../../host-DGmdCaNL.js';
1
+ import { H as HostPickedMedia, E as EaselHost } from '../../host-epHo7r8P.js';
2
2
  import 'react';
3
3
  import '../../blocks/index.js';
4
- import '../../types-NQozKWEz.js';
4
+ import '../../types-Cq53lL8d.js';
5
5
  import '../../data/index.js';
6
6
  import '../../types-41704JE4.js';
7
7
  import '../../resolve-D68pb3Bx.js';
8
- import '../../plan-CGREINRO.js';
8
+ import '../../plan-CZS902DV.js';
9
9
  import './document-contract.js';
10
10
  import './session.js';
11
11
  import './backend-error.js';
@@ -16,6 +16,7 @@ import 'efficient-shell/ui';
16
16
  import './document-hooks.js';
17
17
  import './section-template-types.js';
18
18
  import './puck/content-tree.js';
19
+ import './shared-section-types.js';
19
20
  import './document-switch.js';
20
21
  import '../../engine-CvXpFE86.js';
21
22
  import './admin-bridge.js';
@@ -41,7 +42,7 @@ import './admin-bridge.js';
41
42
  * → posts `storefront-editor:open-media-picker` { requestId, accept, title, file }
42
43
  * to the host (lib/host — over postMessage when framed).
43
44
  * The admin (PageBlockEditor) relays the window's result back down:
44
- * `storefront-editor:media-picked` { requestId, media:{id,url,kind} } → resolve(media)
45
+ * `storefront-editor:media-picked` { requestId, media:{id,url,kind,source?} } → resolve(media)
45
46
  * `storefront-editor:media-pick-cancelled`{ requestId } → resolve(null)
46
47
  * resolveMediaPick(requestId, …) is called by the central message listener
47
48
  * (ScreenDocumentContext) to settle the pending promise, correlated by id.
@@ -50,11 +51,8 @@ import './admin-bridge.js';
50
51
  * custom fields (the media slots) can't receive the listener as a prop.
51
52
  */
52
53
 
53
- interface PickedMedia {
54
- id: string;
55
- url: string;
56
- kind: "image" | "video";
57
- }
54
+ /** The chosen file: the host's own answer, one type for both paths. */
55
+ type PickedMedia = HostPickedMedia;
58
56
  /**
59
57
  * Choose media for a slot; resolves with the chosen media, or null if the user
60
58
  * cancelled (or there's no host to ask). `file` is a file dropped straight on
@@ -2,11 +2,11 @@ import { EditLock } from '../../edit-lock/index.js';
2
2
  import { EaselSession } from './session.js';
3
3
  import '../../blocks/index.js';
4
4
  import 'react';
5
- import '../../types-NQozKWEz.js';
5
+ import '../../types-Cq53lL8d.js';
6
6
  import '../../data/index.js';
7
7
  import '../../types-41704JE4.js';
8
8
  import '../../resolve-D68pb3Bx.js';
9
- import '../../plan-CGREINRO.js';
9
+ import '../../plan-CZS902DV.js';
10
10
  import './backend-error.js';
11
11
  import './host-chrome.js';
12
12
  import './links/link-filters.js';
@@ -15,6 +15,7 @@ import './document-contract.js';
15
15
  import './document-hooks.js';
16
16
  import './section-template-types.js';
17
17
  import './puck/content-tree.js';
18
+ import './shared-section-types.js';
18
19
 
19
20
  /**
20
21
  * The storefront editor's binding of the SHARED edit lock.
@@ -15,7 +15,19 @@ type BlockChoice = {
15
15
  type: string;
16
16
  label: string;
17
17
  group?: string;
18
+ /**
19
+ * RETIRED: Add does not offer it, and a node of it already in a slot still
20
+ * belongs there (card [MERGE] One Text Block And Click Through Parts). The
21
+ * website's Heading and Eyebrow blocks: the Text block took their job, so
22
+ * nobody starts a new one, and every stored one still draws, edits, moves
23
+ * and pastes. Read through {@link offeredChoices} wherever a list is shown
24
+ * to ADD from; the whole list is still the slot's answer to "does this slot
25
+ * take it?", so a move or a paste reads it unfiltered.
26
+ */
27
+ retired?: boolean;
18
28
  };
29
+ /** The choices Add offers: every one that is not {@link BlockChoice.retired}, in order. */
30
+ declare function offeredChoices<C extends BlockChoice>(choices: readonly C[]): C[];
19
31
  /**
20
32
  * One run of consecutive choices sharing a `group` — what a menu draws under one
21
33
  * heading.
@@ -49,4 +61,4 @@ type BlockChoiceRun = {
49
61
  };
50
62
  declare function blockRuns(choices: BlockChoice[]): BlockChoiceRun[];
51
63
 
52
- export { type BlockChoice, type BlockChoiceRun, blockRuns };
64
+ export { type BlockChoice, type BlockChoiceRun, blockRuns, offeredChoices };
@@ -1 +1 @@
1
- export{blockRuns}from"../../../chunk-HQ4VVRIC.js";
1
+ export{blockRuns,offeredChoices}from"../../../chunk-M2Z775ZC.js";
@@ -1 +1 @@
1
- export{DEVICE_FIELD_MARKER,DEVICE_HIDDEN_ATTR,DEVICE_NOTE,deviceField,deviceMetaOf,deviceNote,shownTier,withoutDeviceGate}from"../../../chunk-HV56SLR2.js";import"../../../chunk-7F52SZOI.js";import"../../../chunk-VVPZMWJE.js";import"../../../chunk-MFIRYGHW.js";import"../../../chunk-BSPCSC45.js";
1
+ export{DEVICE_FIELD_MARKER,DEVICE_HIDDEN_ATTR,DEVICE_NOTE,deviceField,deviceMetaOf,deviceNote,shownTier,withoutDeviceGate}from"../../../chunk-XHHVMAGM.js";import"../../../chunk-7F52SZOI.js";import"../../../chunk-C2RHV42O.js";import"../../../chunk-MFIRYGHW.js";import"../../../chunk-BSPCSC45.js";
@@ -1,10 +1,10 @@
1
1
  import { Config } from '../../../blocks/index.js';
2
2
  import 'react';
3
- import '../../../types-NQozKWEz.js';
3
+ import '../../../types-Cq53lL8d.js';
4
4
  import '../../../data/index.js';
5
5
  import '../../../types-41704JE4.js';
6
6
  import '../../../resolve-D68pb3Bx.js';
7
- import '../../../plan-CGREINRO.js';
7
+ import '../../../plan-CZS902DV.js';
8
8
 
9
9
  /** One offerable section, with the category it is grouped under. */
10
10
  type PaletteSection = {
@@ -1,11 +1,11 @@
1
1
  import { Data } from '../../../blocks/index.js';
2
2
  import { TreeItem } from './content-tree.js';
3
3
  import 'react';
4
- import '../../../types-NQozKWEz.js';
4
+ import '../../../types-Cq53lL8d.js';
5
5
  import '../../../data/index.js';
6
6
  import '../../../types-41704JE4.js';
7
7
  import '../../../resolve-D68pb3Bx.js';
8
- import '../../../plan-CGREINRO.js';
8
+ import '../../../plan-CZS902DV.js';
9
9
 
10
10
  declare function nodeToDoc(node: TreeItem): Data;
11
11
  declare function docToNode(data: Data): TreeItem | null;
@@ -1 +1 @@
1
- export{rootRowName,sectionRenameProp,slotChildName,slotChildRenameProp,slotChildRowName}from"../../../chunk-TBF5CVPA.js";import"../../../chunk-DUVRZ456.js";import"../../../chunk-6W7WLPZH.js";
1
+ export{rootRowName,sectionRenameProp,slotChildName,slotChildRenameProp,slotChildRowName}from"../../../chunk-BHRC3ASL.js";import"../../../chunk-6W7WLPZH.js";import"../../../chunk-DUVRZ456.js";
@@ -5,28 +5,29 @@ import { panelFieldsOf } from './panel-fields.js';
5
5
  import '../../../types-BsyPh6EW.js';
6
6
  import 'react';
7
7
  import '../../../blocks/index.js';
8
- import '../../../types-NQozKWEz.js';
8
+ import '../../../types-Cq53lL8d.js';
9
9
  import '../../../data/index.js';
10
10
  import '../../../types-41704JE4.js';
11
11
  import '../../../resolve-D68pb3Bx.js';
12
- import '../../../plan-CGREINRO.js';
12
+ import '../../../plan-CZS902DV.js';
13
13
  import '../../../watch-BTYOJpQU.js';
14
- import '../../../types-DGyDHiJV.js';
15
- import '../../../types-CsgMwHHa.js';
14
+ import '../../../types-DT8ywrFQ.js';
15
+ import '../../../types-Cy7rdmXt.js';
16
16
  import '../../../wordFit-7XpmhcaW.js';
17
17
  import '../../../edit-lock/index.js';
18
18
  import '../../../panelWidths-D9hTLR25.js';
19
19
  import '../../../CanvasDragLayer-dZCPbQCP.js';
20
20
  import '../../../session-DSQFmIvx.js';
21
21
  import '../../../words-CvwYvkJm.js';
22
- import '../../../types-D8P9q-BG.js';
22
+ import '../../../types-Bqq6ya0y.js';
23
23
  import 'efficient-shell/ui';
24
24
  import '../../../words-Cl9xMUYY.js';
25
25
  import '../../components/AddSidePanel.js';
26
26
  import '../section-template-types.js';
27
27
  import './content-tree.js';
28
+ import '../shared-section-types.js';
28
29
  import './block-choice.js';
29
- import '../../../host-DGmdCaNL.js';
30
+ import '../../../host-epHo7r8P.js';
30
31
  import '../document-contract.js';
31
32
  import '../session.js';
32
33
  import '../backend-error.js';
@@ -1 +1 @@
1
- export{copyNodeStyle,nodeStyleRows,planNodePaste,shopFieldKind,siteStyleScope,styleClipboardOf}from"../../../chunk-L3GSW4XI.js";import"../../../chunk-HV56SLR2.js";import"../../../chunk-MQNBD6AB.js";import"../../../chunk-LER7RKTO.js";import"../../../chunk-7F52SZOI.js";import"../../../chunk-VVPZMWJE.js";import"../../../chunk-V7U33NF2.js";import"../../../chunk-6WY6ZXJG.js";import"../../../chunk-DUVRZ456.js";import"../../../chunk-BPXEFVSQ.js";import"../../../chunk-MFIRYGHW.js";import"../../../chunk-BSPCSC45.js";
1
+ export{copyNodeStyle,nodeStyleRows,planNodePaste,shopFieldKind,siteStyleScope,styleClipboardOf}from"../../../chunk-VEZPDGDQ.js";import"../../../chunk-LER7RKTO.js";import"../../../chunk-XHHVMAGM.js";import"../../../chunk-7F52SZOI.js";import"../../../chunk-MQNBD6AB.js";import"../../../chunk-C2RHV42O.js";import"../../../chunk-V7U33NF2.js";import"../../../chunk-6WY6ZXJG.js";import"../../../chunk-DUVRZ456.js";import"../../../chunk-BPXEFVSQ.js";import"../../../chunk-MFIRYGHW.js";import"../../../chunk-BSPCSC45.js";
@@ -1,9 +1,9 @@
1
- import { N as NodeSelection } from '../../../plan-CGREINRO.js';
1
+ import { N as NodeSelection } from '../../../plan-CZS902DV.js';
2
2
  import { Data } from '../../../blocks/index.js';
3
3
  import { TreeItem } from './content-tree.js';
4
4
  import '../../../types-41704JE4.js';
5
5
  import 'react';
6
- import '../../../types-NQozKWEz.js';
6
+ import '../../../types-Cq53lL8d.js';
7
7
  import '../../../data/index.js';
8
8
  import '../../../resolve-D68pb3Bx.js';
9
9
 
@@ -1 +1 @@
1
- export{useSectionOps}from"../../../chunk-V6VKM2QX.js";import"../../../chunk-U25CP5VX.js";import"../../../chunk-R6WTQWAC.js";import"../../../chunk-U3JP4VGF.js";import"../../../chunk-PLVEGYK6.js";import"../../../chunk-QX7GVECM.js";import"../../../chunk-TBY3DFKS.js";import"../../../chunk-ECM5F6JJ.js";import"../../../chunk-K6EM4F5N.js";import"../../../chunk-BPXEFVSQ.js";import"../../../chunk-XWFH2NHZ.js";import"../../../chunk-4JSBIW5H.js";import"../../../chunk-K56YDHYQ.js";import"../../../chunk-BALFHI3G.js";import"../../../chunk-RC25EGHD.js";import"../../../chunk-KFV7N2DJ.js";import"../../../chunk-67GNT6PF.js";import"../../../chunk-P2VEMZH5.js";import"../../../chunk-YRLPFZW3.js";import"../../../chunk-X4T6JT3M.js";import"../../../chunk-KRXQM65X.js";import"../../../chunk-NKB3KVAB.js";import"../../../chunk-23VM4PMV.js";import"../../../chunk-B4JN227A.js";import"../../../chunk-2XMHLXMA.js";import"../../../chunk-G3GWAP5R.js";import"../../../chunk-WRFD4EXD.js";import"../../../chunk-36LVP5WD.js";import"../../../chunk-MFIRYGHW.js";
1
+ export{useSectionOps}from"../../../chunk-A7FF65FL.js";import"../../../chunk-XHSGRH42.js";import"../../../chunk-R6WTQWAC.js";import"../../../chunk-U3JP4VGF.js";import"../../../chunk-PLVEGYK6.js";import"../../../chunk-QEAUF632.js";import"../../../chunk-TBY3DFKS.js";import"../../../chunk-5VD2LGIZ.js";import"../../../chunk-BPXEFVSQ.js";import"../../../chunk-A6Z4SD3I.js";import"../../../chunk-BALFHI3G.js";import"../../../chunk-K56YDHYQ.js";import"../../../chunk-XWFH2NHZ.js";import"../../../chunk-YRLPFZW3.js";import"../../../chunk-RC25EGHD.js";import"../../../chunk-KFV7N2DJ.js";import"../../../chunk-X3TYRF5V.js";import"../../../chunk-23VM4PMV.js";import"../../../chunk-B4JN227A.js";import"../../../chunk-2XMHLXMA.js";import"../../../chunk-G3GWAP5R.js";import"../../../chunk-WRFD4EXD.js";import"../../../chunk-36LVP5WD.js";import"../../../chunk-MFIRYGHW.js";import"../../../chunk-67GNT6PF.js";import"../../../chunk-P2VEMZH5.js";import"../../../chunk-X4T6JT3M.js";import"../../../chunk-KRXQM65X.js";import"../../../chunk-NKB3KVAB.js";
@@ -1,7 +1,7 @@
1
1
  import { A as AutosaveSnapshot } from '../../engine-CvXpFE86.js';
2
- import { a as SaveIconState } from '../../types-DGyDHiJV.js';
2
+ import { a as SaveIconState } from '../../types-DT8ywrFQ.js';
3
3
  import { ScreenSaveStatusWords } from '../words.js';
4
- import '../../types-CsgMwHHa.js';
4
+ import '../../types-Cy7rdmXt.js';
5
5
  import '../../wordFit-7XpmhcaW.js';
6
6
  import 'react';
7
7
  import '../../edit-lock/index.js';
@@ -2,23 +2,24 @@ import * as react from 'react';
2
2
  import { ReactNode, MouseEvent, ComponentType } from 'react';
3
3
  import { Data } from '../../blocks/index.js';
4
4
  import { C as CanvasTarget } from '../../watch-BTYOJpQU.js';
5
- import { D as DeviceOption } from '../../types-DGyDHiJV.js';
5
+ import { D as DeviceOption } from '../../types-DT8ywrFQ.js';
6
6
  import { P as Place } from '../../types-41704JE4.js';
7
7
  import { M as MeasuredCanvas, C as CanvasDragModel } from '../../CanvasDragLayer-dZCPbQCP.js';
8
8
  import { E as EaselContextMenuItem } from '../../types-BsyPh6EW.js';
9
- import { a as EaselRailItem } from '../../types-CsgMwHHa.js';
9
+ import { E as EaselRailItem } from '../../types-Cy7rdmXt.js';
10
10
  import { StyleRow } from '../../style-clipboard/index.js';
11
- import { T as TreeRowMark } from '../../types-D8P9q-BG.js';
11
+ import { T as TreeRowMark } from '../../types-Bqq6ya0y.js';
12
12
  import { AddKey } from '../components/AddSidePanel.js';
13
- import { k as AnyScreenTarget } from '../../host-DGmdCaNL.js';
13
+ import { k as AnyScreenTarget } from '../../host-epHo7r8P.js';
14
14
  import { HostProduct } from './host-chrome.js';
15
15
  import { EaselSession } from './session.js';
16
+ import { SharedSectionUse, SharedSection } from './shared-section-types.js';
16
17
  import { AddTarget } from './puck/add-target-types.js';
17
18
  import { SlotConfigView } from './puck/content-tree.js';
18
- import '../../types-NQozKWEz.js';
19
+ import '../../types-Cq53lL8d.js';
19
20
  import '../../data/index.js';
20
21
  import '../../resolve-D68pb3Bx.js';
21
- import '../../plan-CGREINRO.js';
22
+ import '../../plan-CZS902DV.js';
22
23
  import '../../edit-lock/index.js';
23
24
  import '../../panelWidths-D9hTLR25.js';
24
25
  import '../../session-DSQFmIvx.js';
@@ -518,28 +519,6 @@ interface ScreenBridges {
518
519
  * from that part's own panel. A layer with nowhere to keep them hands none,
519
520
  * and the panel draws no door. */
520
521
  openStyles?: () => void;
521
- /**
522
- * The open document is the one that STORES what the layer pins: the node
523
- * every other document shows pinned and does not hold (the website's: the
524
- * page that keeps the site's one footer). It is edited there in place, so
525
- * the screen draws that document's tree without the rows an ordinary one has
526
- * round its own sections, and without the row that leads to it. Absent, the
527
- * document is an ordinary one.
528
- */
529
- pinnedSource?: boolean;
530
- /** …and the way to edit what is pinned from a document that only shows it:
531
- * what a press on its row in the tree does. Where it leads is the layer's
532
- * (the website opens its footer's editor over the page). */
533
- editPinnedSource?: () => void;
534
- /**
535
- * The layer's own way to bring the canvas to a node the screen has selected,
536
- * for a document where the screen's plain scroll does not hold: one the
537
- * layer draws something above, which reflows and takes the scroll back (the
538
- * website's footer, edited under the page it was opened from). Handed back
539
- * only for such a document, and the screen then calls it in place of its
540
- * scroll; absent, the screen scrolls.
541
- */
542
- holdCanvasOn?: (id: string) => void;
543
522
  /**
544
523
  * THE LAYER'S OWN ROWS IN A NODE'S RIGHT-CLICK MENU (0.105.0), by the group
545
524
  * each joins (`ScreenMenuRows`): the campaign designer's "Check this image
@@ -555,6 +534,31 @@ interface ScreenBridges {
555
534
  * is the screen; what it returns is rendered in the screen's place. */
556
535
  wrap?: (screen: ReactNode) => ReactNode;
557
536
  }
537
+ /** The document's half of a shared section (`ScreenPinnedNodes.shared`). */
538
+ interface ScreenSharedSections {
539
+ /** The pages that use this top-level node, this page among them, when it is
540
+ * a shared section; null when it is this page's own, or the header or
541
+ * footer. */
542
+ usedOn: (node: ScreenNode) => readonly SharedSectionUse[] | null;
543
+ /** Open one of those pages (a press in On N pages ▸). */
544
+ openPage: (page: SharedSectionUse) => void;
545
+ /** MAKE SHARED: the store made `section` from `node`. From now on the layer
546
+ * holds `node`, where it stands, as that shared section; the page looks the
547
+ * same, and its row turns green. */
548
+ adopt: (node: ScreenNode, section: SharedSection) => void;
549
+ /** What Add puts on the page for `section` — the node the layer holds as it
550
+ * — or null when it cannot go on this page: it is on it already (once per
551
+ * page). */
552
+ nodeOf: (section: SharedSection) => ScreenNode | null;
553
+ /** DETACH FROM SHARED: this page's own copy of the shared `node`, every id
554
+ * fresh (efficient-easel/data `copyNode`). The screen puts it in the node's
555
+ * place, one undo step, and the layer holds it as the page's own from then
556
+ * on. The other pages keep the shared section. */
557
+ detach: (node: ScreenNode) => ScreenNode;
558
+ /** A shared section was deleted: every page that used it now holds its own
559
+ * copy, this one included, and the layer takes that in. Optional. */
560
+ removed?: (section: SharedSection) => void;
561
+ }
558
562
  /** A layer's own rows in a node's menu, by the group of the menu each goes at
559
563
  * the end of (efficient-easel/node-ops `nodeMenuItems`' `extras`): `pick`
560
564
  * (Select layer), `make` (Duplicate … Paste), `change` (Rename, Hide …) and
@@ -1109,6 +1113,44 @@ interface ScreenPinnedNodes {
1109
1113
  * as it was.
1110
1114
  */
1111
1115
  groupBadge?: string;
1116
+ /**
1117
+ * SHARED, AND HOW FAR (Shared section design v4, Lewis 2026-10-21): how far
1118
+ * a top-level node reaches when many pages use it live — "On every page",
1119
+ * "On 3 pages" — or null for a node that is this page's own. Asked of each
1120
+ * top-level node, the header and footer and their groups included. For a
1121
+ * node it answers, the screen draws ONE look, green with the shell's
1122
+ * `shared` mark, colour never alone:
1123
+ * · its Layers row in the shell's shared tone, the mark at the row's end
1124
+ * and these words in the mark's Tooltip — in place of `groupBadge`;
1125
+ * · its canvas tab, while it or anything in it is selected or under the
1126
+ * pointer: the green badge with the mark and the row's name, these words
1127
+ * in the tab's Tooltip — in place of `groupTab`'s words;
1128
+ * · its selected and hover outline on the canvas in green
1129
+ * (`CanvasSharedContext`).
1130
+ * `groupTab` and `groupBadge` still say what they switch (the in-place tree,
1131
+ * the click chain). Absent: nothing is shared, and the screen is as it was.
1132
+ */
1133
+ sharedReach?: (node: ScreenNode) => string | null;
1134
+ /**
1135
+ * …and the DOCUMENT'S HALF of a shared section (Shared section design v4,
1136
+ * Lewis 2026-10-21): the layer holds which top-level nodes are shared
1137
+ * sections, and how a page's document stores them (a reference in its top
1138
+ * level, the section in a document of its own). The screen draws the rows
1139
+ * and asks the store (lib/shared-sections); what changes in the document is
1140
+ * asked here. Handed with a store (`SessionBackend.sharedSections`), the
1141
+ * screen offers:
1142
+ * · a page's own section's menu: Make shared — a name asked in a dialog,
1143
+ * the store makes the shared section, `adopt` takes the node in;
1144
+ * · a shared section's menu: On N pages ▸ (`usedOn`, a press `openPage`),
1145
+ * Detach from shared (`detach`), and Remove from this page in place of
1146
+ * Delete, its Layers trash saying so too;
1147
+ * · Add's "Shared sections" group above "Your templates": a card puts
1148
+ * `nodeOf` on the page (a reference, never a copy), and the card's menu
1149
+ * deletes the shared section (`removed`).
1150
+ * Absent: none of these. The header and footer are shared (`sharedReach`)
1151
+ * but answer `usedOn` with null: they keep the menu they have.
1152
+ */
1153
+ shared?: ScreenSharedSections;
1112
1154
  /**
1113
1155
  * …what the screen says ONCE per editing session (the easel session), the
1114
1156
  * first time an edit changes a pinned node or a group of sections: the
@@ -1473,4 +1515,4 @@ declare function useScreenCanvasTarget(): CanvasTarget | null;
1473
1515
  * engine's plain rows for the selection. */
1474
1516
  declare function useScreenInspectorPanel(): ComponentType<ScreenInspectorPanelProps>;
1475
1517
 
1476
- export { type NodeDefaults, SELECTION_MODE, type ScreenBlockLook, type ScreenBlockRules, type ScreenBridges, type ScreenCanvas, type ScreenCanvasDrag, type ScreenCanvasDragContext, type ScreenCanvasHeadProps, ScreenCanvasTargetProvider, type ScreenDevices, type ScreenDocumentOps, type ScreenDragItem, type ScreenInspector, type ScreenInspectorMode, type ScreenInspectorPanelProps, type ScreenLeftPanel, type ScreenLeftView, type ScreenLeftViewFrame, type ScreenLeftViewRules, type ScreenMainAction, type ScreenMenuItem, type ScreenMenuRows, type ScreenNewNode, type ScreenNode, type ScreenNodeActions, type ScreenNodeLevel, type ScreenNodeMaker, type ScreenPartMode, type ScreenParts, ScreenPartsProvider, type ScreenPinnedBand, type ScreenPinnedNodes, type ScreenRailItem, type ScreenSelector, type ScreenSlot, type ScreenSlotAction, type ScreenSlotMode, type ScreenStyleClipboard, type ScreenStyleDocument, type ScreenStylePastePlan, type ScreenToastExtra, type ScreenTree, type ScreenTreeFolds, type ScreenTreeRows, isPinnedFirst, isPinnedLast, isSlotMode, sameInspectorMode, screenSlotsOf, useScreenBlockLook, useScreenBlockRules, useScreenBridges, useScreenCanvasDrag, useScreenCanvasFrame, useScreenCanvasHead, useScreenCanvasTarget, useScreenDevices, useScreenDocumentLabel, useScreenDocumentPass, useScreenInspectorPanel, useScreenLeftView, useScreenNodeKeys, useScreenNotify, useScreenOwnerName, useScreenParts, useScreenPickFollowsSelection, useScreenPinned, useScreenSaveSwitch, useScreenStorageNamespace, useScreenStyleClipboard, useStandaloneScreenBridges };
1518
+ export { type NodeDefaults, SELECTION_MODE, type ScreenBlockLook, type ScreenBlockRules, type ScreenBridges, type ScreenCanvas, type ScreenCanvasDrag, type ScreenCanvasDragContext, type ScreenCanvasHeadProps, ScreenCanvasTargetProvider, type ScreenDevices, type ScreenDocumentOps, type ScreenDragItem, type ScreenInspector, type ScreenInspectorMode, type ScreenInspectorPanelProps, type ScreenLeftPanel, type ScreenLeftView, type ScreenLeftViewFrame, type ScreenLeftViewRules, type ScreenMainAction, type ScreenMenuItem, type ScreenMenuRows, type ScreenNewNode, type ScreenNode, type ScreenNodeActions, type ScreenNodeLevel, type ScreenNodeMaker, type ScreenPartMode, type ScreenParts, ScreenPartsProvider, type ScreenPinnedBand, type ScreenPinnedNodes, type ScreenRailItem, type ScreenSelector, type ScreenSharedSections, type ScreenSlot, type ScreenSlotAction, type ScreenSlotMode, type ScreenStyleClipboard, type ScreenStyleDocument, type ScreenStylePastePlan, type ScreenToastExtra, type ScreenTree, type ScreenTreeFolds, type ScreenTreeRows, isPinnedFirst, isPinnedLast, isSlotMode, sameInspectorMode, screenSlotsOf, useScreenBlockLook, useScreenBlockRules, useScreenBridges, useScreenCanvasDrag, useScreenCanvasFrame, useScreenCanvasHead, useScreenCanvasTarget, useScreenDevices, useScreenDocumentLabel, useScreenDocumentPass, useScreenInspectorPanel, useScreenLeftView, useScreenNodeKeys, useScreenNotify, useScreenOwnerName, useScreenParts, useScreenPickFollowsSelection, useScreenPinned, useScreenSaveSwitch, useScreenStorageNamespace, useScreenStyleClipboard, useStandaloneScreenBridges };
@@ -1 +1 @@
1
- export{SELECTION_MODE,ScreenCanvasTargetProvider,ScreenPartsProvider,isPinnedFirst,isPinnedLast,isSlotMode,sameInspectorMode,screenSlotsOf,useScreenBlockLook,useScreenBlockRules,useScreenBridges,useScreenCanvasDrag,useScreenCanvasFrame,useScreenCanvasHead,useScreenCanvasTarget,useScreenDevices,useScreenDocumentLabel,useScreenDocumentPass,useScreenInspectorPanel,useScreenLeftView,useScreenNodeKeys,useScreenNotify,useScreenOwnerName,useScreenParts,useScreenPickFollowsSelection,useScreenPinned,useScreenSaveSwitch,useScreenStorageNamespace,useScreenStyleClipboard,useStandaloneScreenBridges}from"../../chunk-U25CP5VX.js";import"../../chunk-R6WTQWAC.js";import"../../chunk-U3JP4VGF.js";import"../../chunk-PLVEGYK6.js";import"../../chunk-QX7GVECM.js";import"../../chunk-TBY3DFKS.js";import"../../chunk-ECM5F6JJ.js";import"../../chunk-K6EM4F5N.js";import"../../chunk-BPXEFVSQ.js";import"../../chunk-XWFH2NHZ.js";import"../../chunk-4JSBIW5H.js";import"../../chunk-K56YDHYQ.js";import"../../chunk-BALFHI3G.js";import"../../chunk-RC25EGHD.js";import"../../chunk-KFV7N2DJ.js";import"../../chunk-67GNT6PF.js";import"../../chunk-P2VEMZH5.js";import"../../chunk-YRLPFZW3.js";import"../../chunk-X4T6JT3M.js";import"../../chunk-KRXQM65X.js";import"../../chunk-NKB3KVAB.js";import"../../chunk-23VM4PMV.js";import"../../chunk-B4JN227A.js";import"../../chunk-2XMHLXMA.js";import"../../chunk-G3GWAP5R.js";import"../../chunk-WRFD4EXD.js";import"../../chunk-36LVP5WD.js";import"../../chunk-MFIRYGHW.js";
1
+ export{SELECTION_MODE,ScreenCanvasTargetProvider,ScreenPartsProvider,isPinnedFirst,isPinnedLast,isSlotMode,sameInspectorMode,screenSlotsOf,useScreenBlockLook,useScreenBlockRules,useScreenBridges,useScreenCanvasDrag,useScreenCanvasFrame,useScreenCanvasHead,useScreenCanvasTarget,useScreenDevices,useScreenDocumentLabel,useScreenDocumentPass,useScreenInspectorPanel,useScreenLeftView,useScreenNodeKeys,useScreenNotify,useScreenOwnerName,useScreenParts,useScreenPickFollowsSelection,useScreenPinned,useScreenSaveSwitch,useScreenStorageNamespace,useScreenStyleClipboard,useStandaloneScreenBridges}from"../../chunk-XHSGRH42.js";import"../../chunk-R6WTQWAC.js";import"../../chunk-U3JP4VGF.js";import"../../chunk-PLVEGYK6.js";import"../../chunk-QEAUF632.js";import"../../chunk-TBY3DFKS.js";import"../../chunk-5VD2LGIZ.js";import"../../chunk-BPXEFVSQ.js";import"../../chunk-A6Z4SD3I.js";import"../../chunk-BALFHI3G.js";import"../../chunk-K56YDHYQ.js";import"../../chunk-XWFH2NHZ.js";import"../../chunk-YRLPFZW3.js";import"../../chunk-RC25EGHD.js";import"../../chunk-KFV7N2DJ.js";import"../../chunk-X3TYRF5V.js";import"../../chunk-23VM4PMV.js";import"../../chunk-B4JN227A.js";import"../../chunk-2XMHLXMA.js";import"../../chunk-G3GWAP5R.js";import"../../chunk-WRFD4EXD.js";import"../../chunk-36LVP5WD.js";import"../../chunk-MFIRYGHW.js";import"../../chunk-67GNT6PF.js";import"../../chunk-P2VEMZH5.js";import"../../chunk-X4T6JT3M.js";import"../../chunk-KRXQM65X.js";import"../../chunk-NKB3KVAB.js";
@@ -3,11 +3,11 @@ import { EaselSession } from './session.js';
3
3
  import './puck/content-tree.js';
4
4
  import '../../blocks/index.js';
5
5
  import 'react';
6
- import '../../types-NQozKWEz.js';
6
+ import '../../types-Cq53lL8d.js';
7
7
  import '../../data/index.js';
8
8
  import '../../types-41704JE4.js';
9
9
  import '../../resolve-D68pb3Bx.js';
10
- import '../../plan-CGREINRO.js';
10
+ import '../../plan-CZS902DV.js';
11
11
  import './backend-error.js';
12
12
  import '../../edit-lock/index.js';
13
13
  import './host-chrome.js';
@@ -15,6 +15,7 @@ import './links/link-filters.js';
15
15
  import 'efficient-shell/ui';
16
16
  import './document-contract.js';
17
17
  import './document-hooks.js';
18
+ import './shared-section-types.js';
18
19
 
19
20
  /**
20
21
  * The section templates of the editor on this page — whichever store its
@@ -2,11 +2,11 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { EaselSession } from './session.js';
4
4
  import '../../blocks/index.js';
5
- import '../../types-NQozKWEz.js';
5
+ import '../../types-Cq53lL8d.js';
6
6
  import '../../data/index.js';
7
7
  import '../../types-41704JE4.js';
8
8
  import '../../resolve-D68pb3Bx.js';
9
- import '../../plan-CGREINRO.js';
9
+ import '../../plan-CZS902DV.js';
10
10
  import './backend-error.js';
11
11
  import '../../edit-lock/index.js';
12
12
  import './host-chrome.js';
@@ -16,6 +16,7 @@ import './document-contract.js';
16
16
  import './document-hooks.js';
17
17
  import './section-template-types.js';
18
18
  import './puck/content-tree.js';
19
+ import './shared-section-types.js';
19
20
 
20
21
  /**
21
22
  * Hand `session` to the editor below, and make it the page's current one for
@@ -4,12 +4,13 @@ import { EaselChrome } from './host-chrome.js';
4
4
  import { WebsiteEditLock } from './document-contract.js';
5
5
  import { EaselDocumentHooks } from './document-hooks.js';
6
6
  import { SectionTemplateStore } from './section-template-types.js';
7
+ import { SharedSectionStore } from './shared-section-types.js';
7
8
  import 'react';
8
- import '../../types-NQozKWEz.js';
9
+ import '../../types-Cq53lL8d.js';
9
10
  import '../../data/index.js';
10
11
  import '../../types-41704JE4.js';
11
12
  import '../../resolve-D68pb3Bx.js';
12
- import '../../plan-CGREINRO.js';
13
+ import '../../plan-CZS902DV.js';
13
14
  import '../../edit-lock/index.js';
14
15
  import './links/link-filters.js';
15
16
  import 'efficient-shell/ui';
@@ -79,6 +80,9 @@ interface SessionBackend {
79
80
  /** Where the editor's saved sections are kept (lib/section-templates).
80
81
  * Without it there are none to list and none to open. */
81
82
  sectionTemplates?: SectionTemplateStore;
83
+ /** Where the website's shared sections are kept (lib/shared-sections; Shared
84
+ * section design v4). Without it there are none to add and none to make. */
85
+ sharedSections?: SharedSectionStore;
82
86
  }
83
87
  /**
84
88
  * The mark `createEfficientBackend` puts on what it returns, so a session can
@@ -0,0 +1,71 @@
1
+ import { TreeItem } from './puck/content-tree.js';
2
+
3
+ /**
4
+ * A SHARED SECTION, AND THE STORE A WEBSITE KEEPS THEM IN — the types alone.
5
+ *
6
+ * Shared section design v4 (Lewis 2026-10-21): one section that many pages of a
7
+ * website use live. Change it once, and every page that uses it changes. It is
8
+ * kept beside the section templates (`section-template-types`) and is their
9
+ * opposite: a template is COPIED onto a page and keeps no tie to it; a shared
10
+ * section is put on a page as a REFERENCE to the one section.
11
+ *
12
+ * The backend keeps one as a page of kind `section` whose document holds the one
13
+ * section (efficient-backend `storefront/shared_sections.py`,
14
+ * `/api/storefront/shared-sections/`), per website. A backend implements the
15
+ * store; EFFICIENT's adapter is efficient-storefront-blocks
16
+ * `src/editor/lib/api/shared-sections`. Its draft is saved, renamed and
17
+ * published as a page, through the pages the backend already has: this store
18
+ * lists, makes and deletes.
19
+ */
20
+
21
+ /** A page that uses a shared section, as the backend names it. */
22
+ interface SharedSectionUse {
23
+ id: string;
24
+ slug: string;
25
+ title: string;
26
+ }
27
+ /** A stored shared section, as the backend serializes it (snake_case). */
28
+ interface SharedSectionRecord {
29
+ id: string;
30
+ /** The website it belongs to. */
31
+ site: string;
32
+ /** Its name, as Add and the Layers row say it. */
33
+ title: string;
34
+ /** Its draft document: the one section is `content[0]`. */
35
+ layout: {
36
+ content?: readonly TreeItem[];
37
+ } | null;
38
+ layout_updated_at: string | null;
39
+ is_published: boolean;
40
+ /** The pages that use it, in their draft or in their live copy. */
41
+ used_on: readonly SharedSectionUse[];
42
+ }
43
+ /** A shared section with its one section — what the port hands its callers to
44
+ * draw or put on a page. */
45
+ interface SharedSection extends SharedSectionRecord {
46
+ /** The one section, from its draft. */
47
+ node: TreeItem;
48
+ }
49
+ /** The one section a record's draft holds, or null when it holds none. The
50
+ * store's adapters build a {@link SharedSection} with it, so there is one rule
51
+ * for where the section is (the backend's `the_section`). */
52
+ declare function sharedSectionOf(record: SharedSectionRecord): SharedSection | null;
53
+ interface SharedSectionStore {
54
+ /** This website's shared sections, by name. One whose draft holds no section
55
+ * is left out: there is nothing to put on a page. */
56
+ list(): Promise<SharedSection[]>;
57
+ /**
58
+ * MAKE SHARED: make a shared section of this website from `node`, named
59
+ * `title`. It is unpublished; the site's Publish puts it live with the page
60
+ * that uses it.
61
+ */
62
+ create(title: string, node: TreeItem): Promise<SharedSection>;
63
+ /**
64
+ * DELETE: every page that used it gets its own copy, in its draft and in its
65
+ * live copy, so nothing disappears from the website; then it is gone (a soft
66
+ * delete, kept in the versions).
67
+ */
68
+ remove(id: string): Promise<void>;
69
+ }
70
+
71
+ export { type SharedSection, type SharedSectionRecord, type SharedSectionStore, type SharedSectionUse, sharedSectionOf };
@@ -0,0 +1 @@
1
+ function t(t){const n=t.layout?.content?.[0];return n&&"object"==typeof n&&"string"==typeof n.type?{...t,node:n}:null}export{t as sharedSectionOf};