efficient-storefront-blocks 0.0.0 → 0.11.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 (36) hide show
  1. package/CHANGELOG.md +397 -0
  2. package/LICENSE +10 -0
  3. package/README.md +279 -2
  4. package/dist/chunks/EditorPreviewCheckout-J27HMNBW.js +4 -0
  5. package/dist/chunks/PreviewFooter-BMBCVZQC.js +1 -0
  6. package/dist/chunks/SectionEditorShell-K4OEOAY4.js +1 -0
  7. package/dist/chunks/SiteEditorProvider-ECGZVKLG.js +1 -0
  8. package/dist/chunks/StorefrontEditorChrome-T6DTL7T7.js +1 -0
  9. package/dist/chunks/chunk-3J4FEDNZ.js +2 -0
  10. package/dist/chunks/chunk-6CP4D6VJ.js +1 -0
  11. package/dist/chunks/chunk-6XRKNA2E.js +1 -0
  12. package/dist/chunks/chunk-C2CHF6AL.js +15 -0
  13. package/dist/chunks/chunk-C2CHF6AL.js.LEGAL.txt +27 -0
  14. package/dist/chunks/chunk-ENDWECYV.js +1 -0
  15. package/dist/chunks/chunk-HVOO2GNE.js +1 -0
  16. package/dist/chunks/chunk-MYSIADXX.js +1 -0
  17. package/dist/chunks/chunk-NJXX5BI2.js +1 -0
  18. package/dist/chunks/chunk-RRHBLOH4.js +1 -0
  19. package/dist/chunks/chunk-TGIEMCNA.js +1 -0
  20. package/dist/chunks/chunk-THATLL5Z.js +230 -0
  21. package/dist/chunks/chunk-TOY67YUY.js +153 -0
  22. package/dist/chunks/chunk-TOY67YUY.js.LEGAL.txt +4 -0
  23. package/dist/chunks/chunk-UBWM4USZ.js +1 -0
  24. package/dist/chunks/chunk-Y6SLVHK3.js +1 -0
  25. package/dist/chunks/fitment-data-BXI7KQRZ.js +1 -0
  26. package/dist/chunks/gallery-builds-data-SWA6XKFF.js +1 -0
  27. package/dist/chunks/headers-VF4VTX37.js +1 -0
  28. package/dist/chunks/render-client-UQ5CUPRL.js +1 -0
  29. package/dist/contract.d.ts +48 -0
  30. package/dist/contract.js +1 -0
  31. package/dist/editor.css +1 -0
  32. package/dist/index.d.ts +721 -0
  33. package/dist/index.js +11361 -0
  34. package/dist/links.d.ts +86 -0
  35. package/dist/links.js +1 -0
  36. package/package.json +54 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,397 @@
1
+ # Changelog
2
+
3
+ ## 0.11.0 — 2026-10-07
4
+
5
+ - **Renamed: `efficient-web-builder` is now `efficient-storefront-blocks`.**
6
+ This package is the website builder assembled with the storefront's own
7
+ sections and EFFICIENT's backend, built from the storefront repository. The
8
+ name `efficient-web-builder` goes to the builder alone, published from its
9
+ own repository (doc/adr/0002, *Names and end state*). Nothing else moved:
10
+ the entries (`.`, `./contract`, `./links`, `./editor.css`), every export and
11
+ the `storefront-editor:*` messages are what 0.10.0 published.
12
+
13
+ To migrate, install `efficient-storefront-blocks@^0.11.0`, remove
14
+ `efficient-web-builder`, and change the module name in each import:
15
+
16
+ ```diff
17
+ -import "efficient-web-builder/editor.css";
18
+ -import { WebsiteEditor, createEditorHost } from "efficient-web-builder";
19
+ +import "efficient-storefront-blocks/editor.css";
20
+ +import { WebsiteEditor, createEditorHost } from "efficient-storefront-blocks";
21
+ ```
22
+
23
+ `efficient-web-builder` 0.10.0 and earlier stay on the registry as they
24
+ were published. Do not alias the old name to this package: a host that later
25
+ installs the builder itself needs that name free.
26
+
27
+ - **Needs `efficient-easel` 0.101.0 or later** (peer `^0.101.0`, was
28
+ `^0.100.0`). Every list in the editor is efficient-easel's one list, which
29
+ 0.101 ships.
30
+
31
+ ## 0.10.0 — 2026-10-07
32
+
33
+ - **The preview has square corners.** The canvas's desktop frame had a rounded
34
+ corner where the page meets the toolbar and the panel, and the tablet and
35
+ phone frames were drawn with a device's rounded edge. All three clipped the
36
+ corners of the website inside. They are square; the tablet and phone frames
37
+ are still told apart from the well by their width and outline.
38
+ - **A website that has not set Corners is drawn square.** In Site styles ▸
39
+ Corners, "Not set" used to leave small built-in rounded corners on inputs,
40
+ panels and some pictures. The canvas now draws such a site square, as the
41
+ live storefront does; a site that chose a value keeps it. The Mockup
42
+ section's address bar and stat chips and the integrations chips, which were
43
+ pill-shaped on every site, follow the site's Corners too.
44
+
45
+ - **The part panel takes the final text box.** Clicking a run of text opens
46
+ efficient-easel's final text box: a two-row toolbar (Bold, Italic, Underline,
47
+ Strikethrough, Color, Link, Superscript, Subscript, Undo / Left, Center,
48
+ Right, Justify, lists, Aa AA aa) and six number cells — Font size, Line
49
+ spacing (%), Letter spacing (px), Paragraph spacing, Padding and Width. The
50
+ Style section below holds the style card, Font (easel's one dropdown) and a
51
+ Color row of the section's theme colours plus Any color. The Weight row is
52
+ gone (B is the bold); a weight already stored still draws. The bundle now also imports
53
+ `efficient-easel/gold.css` and `efficient-easel/text-styles.css`, which the
54
+ host's bundler resolves from its own efficient-easel.
55
+ - **Old part settings draw the same.** A stored line or letter nudge is read
56
+ as the number the published page has always drawn for it and is never
57
+ rewritten. The editor canvas now draws a nudged part exactly as the live
58
+ page does.
59
+
60
+ ## 0.9.0 — 2026-10-07
61
+
62
+ - **The Product Grid title keeps its words in the canvas.** When the head row
63
+ is crowded (in the editor, an empty supporting line and link draw their
64
+ placeholders), the supporting line now truncates first, and the title, "View
65
+ all" and the count stay whole. Before, the title split inside its words at
66
+ 912 wide. Published heads that are not crowded are unchanged.
67
+
68
+ - **Needs `efficient-easel` 0.100.0 or later** (peer `^0.100.0`, was
69
+ `^0.99.2`). 0.100 removes the deprecated `Editor…` names, which this package
70
+ no longer uses. The copy box's bar no longer draws the ◆ Emphasis button
71
+ (E5a), and the "press the highlighter" hint under four copy rows is gone with
72
+ it. Saved `==words==` still shows in the theme colour.
73
+
74
+ - **`backend.media.maxUploadBytes` — the media field's size cap is the
75
+ backend's.** An optional number on the `media` group: the largest file a
76
+ media field takes before handing it to the host's panel or picker. Without it
77
+ the editor refuses no file for its size. It was EFFICIENT's published cap,
78
+ applied to every host.
79
+
80
+ - **`backend.social` — the social links join the backend contract.** A new
81
+ optional group on `WebsiteBackend`: `social.get(scope?)` and
82
+ `social.update(patch, scope?)` over `SocialLinkSettings` — one address per
83
+ platform, under the platform's name. The editor's Social links rows read and
84
+ save through it and no longer call EFFICIENT's client.
85
+ - **`WebsiteBackendError.fields`.** An `invalid` rejection may name the inputs
86
+ it refused, each with the reason (`{ instagram: "Enter a valid URL." }`); the
87
+ editor shows it beside that input. `social.update` is the first to use it.
88
+
89
+ - **`backend.chat` — the live chat joins the backend contract.** A new optional
90
+ group on `WebsiteBackend`: `chat.get(scope?)` and `chat.update(patch, scope?)`
91
+ over `ChatSettings` (enabled, title, subtitle, greeting). The editor's Live
92
+ chat panel reads and saves through it and no longer calls EFFICIENT's client.
93
+ Under EFFICIENT's backend nothing changes.
94
+
95
+ - **`backend.pages.linkTargets` — the link picker's pages join the backend
96
+ contract.** A new optional method on the `pages` group: every page a link
97
+ may point at, as `LinkTargetPage`s (id, slug, the page's name, and its
98
+ layout), in one call. The link picker reads it for its "Page" and "Anchor"
99
+ targets and no longer calls EFFICIENT's client. A host's backend without it
100
+ still has its pages listed — from `pages.list` — with no section anchors.
101
+ Under EFFICIENT's backend nothing changes.
102
+
103
+ - **`backend.blog` — the website's blog joins the backend contract.** A new
104
+ optional group on `WebsiteBackend`: `blog.posts(scope?)` answers the
105
+ website's published posts as `BlogPostRow`s (slug, title, excerpt, category,
106
+ an absolute cover address, the publish date, and the post's own path). The
107
+ editor reads it in two places — a section's "Blog post source", and the link
108
+ picker's "Blog post" target — and no longer calls EFFICIENT's client for
109
+ either. A host that passes its own `backend` with a `blog` gets both; one
110
+ without gets what it had before: a block already linked to a post says so and
111
+ can only be unlinked, and the link picker offers no "Blog post". Under
112
+ EFFICIENT's backend (no `backend` passed, or `createEfficientBackend()`)
113
+ nothing changes.
114
+
115
+ - **The Visual sitemap is out of the editor.** The rail's "Visual sitemap"
116
+ button and the page-card overlay it opened are removed. A host that wants a
117
+ bird's-eye view of a website's pages draws its own, outside the editor:
118
+ EFFICIENT's admin shows it as the Sitemap section of its Storefront Console.
119
+ Nothing else in the rail moves, and no prop or host message changes
120
+ (`storefront-editor:open-page` and `storefront-editor:new-page` are still
121
+ sent by the Pages panel).
122
+
123
+ - **`backend.theme` — a website's appearance joins the backend contract.** A
124
+ new optional group on `WebsiteBackend`: `theme.get(scope?)` and
125
+ `theme.update(patch, scope?)` over `SiteThemeRow` — the row behind Site
126
+ styles, key for key as it is stored. The editor seeds its appearance and
127
+ saves every Site styles change through it and no longer calls EFFICIENT's
128
+ client. Site styles is now offered to ANY backend that has the group
129
+ (`hasSiteTheme` was EFFICIENT-only); one without it is unchanged.
130
+
131
+ ## 0.8.1 — 2026-10-07
132
+
133
+ - **The held hero frame stays on screen.** A hero slide with a video and no
134
+ poster holds on the video's first frame (0.8.0). That frame was a paused,
135
+ never-played `<video>`, and the browser does not always paint one: it could
136
+ go blank, for example after the editor window was resized, leaving the pale
137
+ surface under the slide's white words. The frame is now drawn once onto a
138
+ canvas, and the source video is dropped as soon as it is drawn.
139
+
140
+ A patch cut from 0.8.0 with this one fix (branch `release/web-builder-0.8.1`),
141
+ so it did not carry the 0.9.0 changes above. The fix is on `main` too
142
+ (#1582), so 0.9.0 has it.
143
+
144
+ ## 0.8.0 — 2026-10-06
145
+
146
+ - **A hero slide with a video and no poster shows in the canvas.** A hero's
147
+ video is held in the editor until "Play video" is pressed. A held slide that
148
+ has no poster drew nothing, so the canvas showed a pale blank under white
149
+ words where the published page plays the video. It now shows the video's
150
+ first frame as a still: nothing plays, and only the start of the file is
151
+ fetched. A slide that has a poster mounts no video while held, as before.
152
+
153
+ - **`efficient-web-builder/links` — the link rules, for a host's own link picker.**
154
+ A new light entry (one file, no imports, like `/contract`): the link kinds,
155
+ each thing's live URL, a saved link read back to its kind, the product
156
+ listing read off a page's layout, the ONE filter a listing link may carry
157
+ (any field the listing filters on, in the listing's own query param), the
158
+ filters and catalogue values a listing link may offer, and the addresses
159
+ that are refused. Built from the file the editor's own Link field reads, so
160
+ the admin's menu picker writes links by the same rules. The editor itself is
161
+ unchanged.
162
+
163
+ ## 0.7.1 — 2026-10-06
164
+
165
+ - **The Fitment Finder and the gallery builds load in a host's editor.** Their
166
+ calls to the website's own public routes (`/api/v1/fitment/*`,
167
+ `/api/v1/gallery-builds`) carried an `X-Portal-Audience` header. Those routes
168
+ answer a cross-origin caller with open CORS that allows only `Accept` and
169
+ `Content-Type`, so the browser's preflight refused the call: the Fitment
170
+ Finder showed "Vehicle list unavailable" and the gallery came back empty.
171
+ These calls now send no audience; every other call is unchanged.
172
+
173
+ - **The engine peer is `efficient-easel ^0.99.2`** (it was `^0.99.0`). This
174
+ package now imports the engine by its Easel names (`createEasel`,
175
+ `useEasel`, `EaselProvider`, `efficient-easel/easel`), which 0.99.2 added.
176
+ The engine still exports the old names, so a host's own code does not have
177
+ to change; a host only needs 0.99.2 or later installed. Nothing an operator
178
+ sees changes.
179
+
180
+ - **One media panel head for both editors.** The Media panel's head is
181
+ efficient-easel's `MediaPanelHead`, the same head the campaign designer
182
+ draws over the same library (owner ruling 2026-10-06: a part exists once, in
183
+ efficient-easel). Nothing it says or does changed; the Cancel button's sides
184
+ are 12px (were 10px), on the spacing scale. Needs the efficient-easel release
185
+ that ships `MediaPanelHead`.
186
+
187
+ - **Grid cells fill their height in the canvas.** A block in a Grid cell now
188
+ stretches to the cell's height in the editor, as it does on the published
189
+ page. The canvas sheet (built from the storefront's `app/globals.css`) makes
190
+ the editor's drag wrapper in a Grid a one-column grid, so the block inside it
191
+ stretches. Published pages are unchanged.
192
+ - **Box rows fill their height in the canvas.** The same fix for a Box laid out
193
+ in one row and a Slide box set to One row: when the row stretches (Align
194
+ Stretch, or not set), the drag wrapper is a one-column grid, so the block
195
+ inside it is the row's height as on the published page. Start, Center and End
196
+ rows and Stacked boxes are unchanged. Published pages are unchanged.
197
+
198
+ - **The editor opens a page with its live prices.** Under the EFFICIENT
199
+ backend, `pages.load` by slug now only finds the page, then reads it by id.
200
+ Only that read re-prices the wheel copy a linked Product Grid or Product
201
+ Hero keeps in the page, the same way the published page does. Before, a
202
+ stale copy (USD 0) drew "Price on request" on cards the live page priced.
203
+ An embedder's own backend is not affected.
204
+
205
+ - **The canvas gets the live page's head.** The editor's canvas frame now runs
206
+ the same fit-words boot the published `<body>` runs (`lib/fit-words.ts`), so
207
+ a heading word wider than its box shrinks to fit instead of breaking inside
208
+ the word ("THE UNPAVE / D", "Monoblo / ck"). It runs in the frame's own
209
+ document; the embedder's page is never touched.
210
+ - **The canvas fonts fall back as the live page's do.** Each `--font-*`
211
+ variable is bound to next/font's stack (`'Family', 'Family Fallback'`) and
212
+ the canvas sheet declares next/font's metric-matched `"<Family> Fallback"`
213
+ faces, so a glyph outside a web font's subset (→, ″) and text drawn before
214
+ the web font arrives take the widths the live page gives them. The faces are
215
+ local fonts: an editor over an embedder's own backend (no Google Fonts sheet)
216
+ gets them too.
217
+ - **The Mobile canvas is 390px wide** (it was 388: the device frame's 1px
218
+ border sat inside its width), and Tablet is 800 (was 798). The device edge
219
+ is now an outline that takes no width.
220
+ - **An empty slot no longer covers the picture behind it.** The editor sheet
221
+ (`dist/editor.css`) no longer paints its own solid fill on efficient-easel's
222
+ empty-slot cell, so the slot looks as easel 0.99.1 draws it: nothing at
223
+ rest, so a hero's picture or video shows; the outline and "+ Add block" on
224
+ hover or focus. Published pages are unchanged.
225
+
226
+ ## 0.7.0 — 2026-10-05
227
+
228
+ - **Renamed: `efficient-web` is now `efficient-web-builder`.** 0.7.0 is the
229
+ first release under this name, and `efficient-web` stops at 0.3.0. 0.4.0,
230
+ 0.5.0 and 0.6.0 below were never published under either name, so an embedder
231
+ moving from `efficient-web` 0.3.0 takes all four sets of changes together.
232
+ - **To migrate:** change the dependency name (`"efficient-web": "^0.3.0"`
233
+ becomes `"efficient-web-builder": "^0.7.0"`) and the import specifiers:
234
+ `efficient-web` becomes `efficient-web-builder`, and
235
+ `efficient-web/editor.css` becomes `efficient-web-builder/editor.css`. An
236
+ install that lists the package by name (pnpm's `minimumReleaseAgeExclude`)
237
+ renames that entry too.
238
+ - The messages the package logs or throws now open with
239
+ `efficient-web-builder:` instead of `efficient-web:`.
240
+ - **A host chooses which blocks its editor offers.** `WebsiteEditor` and
241
+ `WebsiteSectionEditor` take an optional `blocks`: the `sets` offered
242
+ (`general`, `commerce`, `service`), an `allow` and a `deny` list, the host's
243
+ own blocks (`host`, each an `efficient-easel/blocks` `ComponentConfig`), the
244
+ Add-panel group each stands in (`categories`), and live `metadata` every
245
+ block receives as `puck.metadata`. See the README.
246
+ - **Without `blocks` nothing changes.** The editor is given the same block
247
+ registry, the same object, and offers every block it has. An embedder that
248
+ passes nothing compiles and behaves as in 0.6.0.
249
+ - **Every block has a set.** `general` blocks draw from their own props and
250
+ what the host hands them; `commerce` blocks are the shop; `service` blocks
251
+ need one of the EFFICIENT backend's site services (forms, bookings, reviews,
252
+ the newsletter, the blog, menus). 105 blocks: 53 general, 27 commerce, 25
253
+ service.
254
+ - **Offered, not registered.** A block a host leaves out is in no Add-panel
255
+ group, no slot's menu and no drop target, and no section is seeded with it. A
256
+ page that already holds one still draws it and it can be deleted.
257
+ - **A section is offered only with the blocks it is built from.** A Hero is not
258
+ offered where its slides are not; a section that is merely wrapped in a Box
259
+ when it is added lands whole instead.
260
+ - **With a set left out, the controls that need it are not drawn**: a link has
261
+ no "Blog post" or "Product" target, a section's optional "Blog post source"
262
+ is hidden, the Form picker is inert, and the pinned Header and Footer are
263
+ not seeded.
264
+ - **`blocks.metadata` is live.** Change the object and the blocks in the canvas
265
+ redraw in place; it is never written to the page or the undo history. The
266
+ rest of `blocks` is read once, when the editor mounts.
267
+ - **A host's own block gets none of the rows the editor adds to its own
268
+ sections** (padding, width, anchor, theme, animation). It is drawn by its own
269
+ `render`, edited with the fields it declares, added from the Add panel, and
270
+ hidden by the Layers tree's eye.
271
+ - **New entry: `efficient-web-builder/contract`.** One small file with no imports, for
272
+ a host's server: `BLOCK_SETS`, `GENERAL_BLOCKS`, `COMMERCE_BLOCKS`,
273
+ `SERVICE_BLOCKS`, `blockSetOf(type)` and `blockTypesIn(layout)` — every block
274
+ type a saved page uses, including inside slots. Hiding a block in the editor
275
+ is not a security boundary; checking the saved page is.
276
+ - New types: `WebsiteEditorBlocks`, `WebsiteBlockCategory`, `WebsiteBlockSet`.
277
+ `ComponentConfig` is the engine's (`efficient-easel/blocks`).
278
+
279
+ ## 0.6.0 — 2026-10-05
280
+
281
+ - **The engine peer is `efficient-easel`.** The engine is called Efficient
282
+ Easel, and its package was renamed from `efficient-editor` at 0.96.0. This
283
+ package now imports `efficient-easel/*` and asks for `efficient-easel`
284
+ `^0.96.0` in place of `efficient-editor` `^0.94.1`. A host moves the two
285
+ together: install `efficient-easel` and import its sheets from
286
+ `efficient-easel/*.css`.
287
+ - The engine's sheets inside `efficient-web/editor.css` are 0.96.0's. That
288
+ release is 0.95.0 under the new name: no class, variable or rendered byte
289
+ differs, and the `es-` classes keep their names.
290
+
291
+ ## 0.5.0 — 2026-10-04
292
+
293
+ - **Built on efficient-editor 0.94.1.** The peer range moves from `^0.93.0` to
294
+ `^0.94.1`, and the engine's sheets inside `efficient-web/editor.css` are
295
+ 0.94.1's. Install the two together: the formatting bar above a copy box is
296
+ drawn by the engine and styled by this package's sheet, so 0.94's bar on
297
+ 0.93's sheet would not match.
298
+ - The formatting bar's buttons take the engine's 0.94 look: 32px, 6px corners,
299
+ and a pressed button that stays tinted under the pointer. Their tooltips are
300
+ the engine's: Strong, Italic, Strikethrough and Emphasis, each with the mark
301
+ it writes.
302
+ - **Two word styles are renamed on the bar: Emphasis is now Highlight, and
303
+ Strong is now Bold**, because the engine's own buttons took those two words.
304
+ The stored keys (`highlight`, `strong`) and the marks (`@@`, `++`) do not move.
305
+
306
+ ## 0.4.0 — 2026-10-04
307
+
308
+ - **The editor can run on a backend that is not EFFICIENT's.** `WebsiteEditor`
309
+ and `WebsiteSectionEditor` take an optional `backend`: the embedder's own
310
+ implementation of `WebsiteBackend` — pages (list, load, save, version,
311
+ publish, create, remove), the edit lock, the site record, media, section
312
+ templates, website templates, the Preview link. `pages`, `site.get` and
313
+ `media.resolve` are required; every other group or method is optional, and
314
+ the editor draws no control for one that is missing. See the README and
315
+ `doc/adr/0002`.
316
+ - **Without `backend` nothing changes.** It is `createEfficientBackend()`:
317
+ `/api/storefront/*`, authorised by the token the host delivers with
318
+ `storefront-editor:auth`, with `auth-expired` on a 401 — as in 0.3.0. An
319
+ embedder that passes nothing compiles and behaves as before.
320
+ - **Failures are kinds, not HTTP bodies.** A backend rejects with
321
+ `WebsiteBackendError` (`unauthorized`, `changed-elsewhere`, `lock-taken`,
322
+ `not-found`, `invalid`, `unavailable`); a refused save carries who saved, a
323
+ taken page who holds it.
324
+ - **`PageBundle`** — a page is saved as `{ layout, translations?, seo? }`.
325
+ 0.4.0 edits `layout`; `translations` and `seo` are reserved for per-language
326
+ content, so a host's storage is shaped once.
327
+ - **Under an embedder's backend the package makes no request of its own**: no
328
+ token is waited for (`ready` is announced once), its own HTTP client is
329
+ closed, the canvas loads no remote font sheet, and stored media is resolved
330
+ by `backend.media.resolve`.
331
+ - **One session per mounted editor.** The token, the website being edited and
332
+ the editor's caches belong to the mount, so a re-mount for another website
333
+ starts from nothing (one editor at a time is still the rule).
334
+ - New exports: `createEfficientBackend`, `WebsiteBackendError`, and the types
335
+ `WebsiteBackend`, `WebsitePages`, `WebsiteEditLock`, `WebsiteSite`,
336
+ `WebsiteMedia`, `WebsiteSectionTemplates`, `WebsiteTemplates`,
337
+ `WebsitePreview`, `PageBundle`, `PageDocument`, `PageLayout`, `PageRef`,
338
+ `SiteScope`, `NewPageInput`, `SaveExpectation`, `EditorPageRow`, `SiteRecord`,
339
+ `SiteRecordPatch`, `SaveConflict`, `LockHolder`, `SectionNode`,
340
+ `SectionTemplate`, `SectionTemplateRecord`, `WebsiteBackendErrorKind`,
341
+ `EfficientBackendOptions`.
342
+ - Not behind the interface yet (unchanged under EFFICIENT's backend, absent
343
+ under another): site styles, the pinned header and footer, live chat, social
344
+ links, menus, blog, forms, the catalog, the sitemap panel and "duplicate to
345
+ page". A Form section's picker (0.3.0) is inert under another backend: no
346
+ list, no "New form", no `storefront-editor:open-form`.
347
+
348
+ ## 0.3.0 — 2026-10-04
349
+
350
+ - **Editing a form waits for nothing.** A Form picker's "Edit form" sends
351
+ `storefront-editor:open-form` with `mode: "edit"` and **no `requestId`**, and
352
+ does not wait for an answer: the embedder's form builder is a window the
353
+ merchant works in beside the editor, not a question the picker asked. The
354
+ picker's buttons are no longer disabled while the builder is open.
355
+ `requestId` is now optional on the message type.
356
+ - **A block follows a renamed form by id.** When a forms re-read no longer
357
+ explains a block's stored slug but still holds the form that slug last
358
+ resolved to, the block is re-pointed at the form's new slug. This replaces
359
+ following the slug on the reply to an edit request, and also covers a rename
360
+ made outside the editor. A deleted form is never replaced by another.
361
+ - **"New form" still asks and waits** (`mode: "create"`, with a `requestId`,
362
+ answered by `form-saved` / `form-closed`). An embedder is expected to answer
363
+ it quickly, for example with a popup that names and creates the form; one
364
+ that answers with its whole form builder still works, and the fifteen-minute
365
+ reply backstop stays for it.
366
+ - An embedder that answered an edit request with `form-closed` keeps working:
367
+ the reply is for a request nobody is waiting on, and is ignored.
368
+
369
+ ## 0.2.0 — 2026-10-04
370
+
371
+ - **The media library is a panel of the editor.** `WebsiteEditor` and
372
+ `WebsiteSectionEditor` take an optional `mediaPanel`: the embedder's media
373
+ library, as a component the editor draws in its own left panel. The rail's
374
+ Media button opens it as a view beside Pages, Layers and Site styles, and
375
+ every image field opens it in pick mode ("Choose image · Background image"),
376
+ so the field's choice is made in the editor instead of in a second window.
377
+ New types: `MediaPanelComponent`, `MediaPanelProps`, `MediaPickRequest`.
378
+ - Without `mediaPanel` nothing changes: fields ask the host to open its picker
379
+ window with `storefront-editor:open-media-picker`, as in 0.1.0.
380
+ - **One head for every side panel, on both sides.** Pages, Layers, Site styles,
381
+ the Media library, Add, Choose image and the right-hand settings panel all
382
+ wear the engine's `InspectorHead`: a glyph, the name, what it is about, the
383
+ panel's own buttons, then **Hide panel**, now on the right panel too. No ✕ in a panel head any
384
+ more: Add leaves with **Done**, choosing an image with **Cancel**, and Layers'
385
+ collapse-all glyph no longer reads as a second ✕.
386
+ - **No panel toggles in the top bar.** They duplicated the heads' Hide panel
387
+ button. A hidden panel leaves a 40px strip at its edge with **Show panel**
388
+ (the same picture), the way back for both sides.
389
+
390
+ ## 0.1.0 — 2026-10-03
391
+
392
+ - **First release.** The storefront website editor (page and template editor,
393
+ standalone section editor) for an app that mounts it in its own page: an
394
+ in-process host (`createEditorHost`) in place of the shop's postMessage
395
+ bridge, the shop's sections with Next.js replaced at the module boundary, and
396
+ the canvas styled from the storefront's own compiled stylesheet inside its
397
+ frame.
package/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Copyright (c) 2026 Efficient Pty Ltd. All rights reserved.
2
+
3
+ This software and its documentation are proprietary to Efficient Pty Ltd and
4
+ are confidential. No licence is granted to use, copy, modify, merge, publish,
5
+ distribute, sublicense or sell this software, in whole or in part, except
6
+ under a written agreement with Efficient Pty Ltd.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.