@homepages/template-kit 0.8.0 → 0.8.1-dev-20260718020735

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @homepages/template-kit
2
2
 
3
+ ## 0.8.1-dev-20260718020735
4
+
5
+ ### Patch Changes
6
+
7
+ - 1c4c7dd: Island hydration is now nesting-safe: `hydrateIslands` skips any island marker
8
+ nested inside another marker, so an island can render another island without the
9
+ child being hydrated twice (once by its parent root, once independently). Enables
10
+ interactive islands (accordion, card-slider, carousel) to wrap existing leaf
11
+ islands (expandable-text) on published pages.
12
+
3
13
  ## 0.8.0
4
14
 
5
15
  ### Minor Changes
@@ -17,7 +17,7 @@ function createEditorPropsBridge(react) {
17
17
  }
18
18
  async function hydrateIslands(options) {
19
19
  const root = options.root ?? document;
20
- const markers = Array.from(root.querySelectorAll(`[${ATTR_ISLAND_KEY}]`)).filter((element) => !roots.has(element));
20
+ const markers = Array.from(root.querySelectorAll(`[${ATTR_ISLAND_KEY}]`)).filter((element) => !roots.has(element) && element.parentElement?.closest(`[${"data-tr-island"}]`) == null);
21
21
  if (markers.length === 0) return [];
22
22
  const payloads = /* @__PURE__ */ new Map();
23
23
  const duplicateIds = /* @__PURE__ */ new Set();
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.8.0";
2
+ var version = "0.8.1-dev-20260718020735";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/guide/islands.md CHANGED
@@ -2,7 +2,7 @@
2
2
  purpose: How interactivity works in a template — client components ("islands"), their props contract, and their editor options.
3
3
  status: living
4
4
  related: [INDEX.md, eslint.md, dev.md]
5
- updated: 2026-07-16
5
+ updated: 2026-07-18
6
6
  ---
7
7
 
8
8
  # Islands: interactivity in a template
@@ -141,6 +141,24 @@ hydrates:
141
141
  The marker is layout-invisible (`display:contents`), so an island can sit directly
142
142
  inside a grid or flex container without adding a box.
143
143
 
144
+ ## Nesting one island inside another
145
+
146
+ An island can render another island — for example, an accordion island whose expanded
147
+ content is itself an existing expandable-text island. Because the build wraps every
148
+ `"use client"` module in a marker, the nested island's marker ends up inside the parent
149
+ island's server-rendered output.
150
+
151
+ A nested marker is not hydrated as its own root. It is left to the marker that contains
152
+ it, which already renders — and hydrates — it as part of its own React tree. The nested
153
+ component still runs and stays interactive, but it loses its own root and its own editor
154
+ treatment:
155
+
156
+ - Its `editor.live`/`shieldMode`/`liveSurface`/`props` declaration has no independent
157
+ effect in the canvas — the parent island's declaration governs the whole subtree, since
158
+ there is no separate root for the editor to select or shield.
159
+ - Its props `<script>` still renders in the DOM (harmless) but goes unread; props reach
160
+ the nested component through the parent's own render instead.
161
+
144
162
  ## Hosting islands yourself
145
163
 
146
164
  `@homepages/template-kit/island-runtime` is the loader. It is not something a template
@@ -153,9 +171,10 @@ await hydrateIslands({ load: (key) => ISLANDS[key]() }); // ISLANDS: the build'
153
171
  unmountIslands(sectionEl); // before replacing sectionEl's HTML
154
172
  ```
155
173
 
156
- Each island is an independent React root: one island's state, re-renders, and errors
157
- never touch another's. Hydration is idempotent, so calling `hydrateIslands` again after
158
- injecting new markup is safe.
174
+ Each top-level island is an independent React root: one island's state, re-renders, and
175
+ errors never touch another's. An island nested inside another (see above) hydrates as
176
+ part of its parent's root instead. Hydration is idempotent, so calling `hydrateIslands`
177
+ again after injecting new markup is safe.
159
178
 
160
179
  ## Talking to HomePages from an island
161
180
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homepages/template-kit",
3
- "version": "0.8.0",
3
+ "version": "0.8.1-dev-20260718020735",
4
4
  "description": "Authoring kit for HomePages marketing-section templates: schema system, contract primitives, theme tokens, and the template-kit CLI.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",