@symbiotejs/symbiote 3.3.6 → 3.3.7

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,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.3.7
4
+
5
+ ### Fixed
6
+
7
+ - **SSR hydration: Itemize list duplication.**
8
+ Fixed itemize SSR hydration creating duplicate items. The processor now adopts the existing SSR item tag name and element class, skips the initial subscription fire, and sets `isoMode` on the item class so upgraded elements hydrate their existing content instead of re-rendering.
9
+
3
10
  ## 3.3.6
4
11
 
5
12
  ### Improved
@@ -9,6 +9,8 @@ import { initPropFallback } from './initPropFallback.js';
9
9
  * @param {T} fnCtx
10
10
  */
11
11
  export function itemizeProcessor(fr, fnCtx) {
12
+ let clientSSR = fnCtx.ssrMode && !globalThis.__SYMBIOTE_SSR;
13
+
12
14
  ownElements(fr, `[${DICT.LIST_ATTR}]`).filter((el) => {
13
15
  return !el.matches(`[${DICT.LIST_ATTR}] [${DICT.LIST_ATTR}]`);
14
16
  }).forEach((el) => {
@@ -18,20 +20,37 @@ export function itemizeProcessor(fr, fnCtx) {
18
20
  itemClass = window.customElements.get(itemTag);
19
21
  }
20
22
  if (!itemClass) {
21
- itemClass = class extends fnCtx.Symbiote {
22
- constructor() {
23
- super();
24
- this.ssrMode = fnCtx.ssrMode;
25
- this.isoMode = fnCtx.isoMode;
26
- if (!itemTag) {
27
- this.style.display = 'contents';
28
- }
23
+ // During hydration, adopt existing SSR item tag and derive template
24
+ if (clientSSR && el.children.length > 0) {
25
+ let ssrTag = el.children[0].localName;
26
+ itemClass = window.customElements.get(ssrTag);
27
+ if (!itemClass) {
28
+ itemClass = class extends fnCtx.Symbiote {
29
+ constructor() {
30
+ super();
31
+ this.isoMode = true;
32
+ if (!itemTag) {
33
+ this.style.display = 'contents';
34
+ }
35
+ }
36
+ };
37
+ itemClass.template = el.children[0].innerHTML;
38
+ itemClass.reg(ssrTag);
29
39
  }
30
- };
31
- itemClass.template = el.querySelector('template')?.innerHTML || el.innerHTML;
32
- itemClass.reg(itemTag);
40
+ } else {
41
+ itemClass = class extends fnCtx.Symbiote {
42
+ constructor() {
43
+ super();
44
+ if (!itemTag) {
45
+ this.style.display = 'contents';
46
+ }
47
+ }
48
+ };
49
+ itemClass.template = el.querySelector('template')?.innerHTML || el.innerHTML;
50
+ itemClass.reg(itemTag);
51
+ }
33
52
  }
34
- if (!(fnCtx.ssrMode && !globalThis.__SYMBIOTE_SSR)) {
53
+ if (!clientSSR) {
35
54
  while (el.firstChild) {
36
55
  el.firstChild.remove();
37
56
  }
@@ -91,7 +110,7 @@ export function itemizeProcessor(fr, fnCtx) {
91
110
  } else {
92
111
  console.warn(`[Symbiote] <${fnCtx.localName}>: itemize data must be Array or Object, got ${typeof data}:`, data);
93
112
  }
94
- });
113
+ }, !clientSSR);
95
114
  if (!globalThis.__SYMBIOTE_SSR) {
96
115
  el.removeAttribute(DICT.LIST_ATTR);
97
116
  el.removeAttribute(DICT.LIST_ITEM_TAG_ATTR);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@symbiotejs/symbiote",
4
- "version": "3.3.6",
4
+ "version": "3.3.7",
5
5
  "description": "Symbiote.js - zero-dependency close-to-platform frontend library to build super-powered web components",
6
6
  "author": "team@rnd-pro.com",
7
7
  "license": "MIT",
@@ -1 +1 @@
1
- {"version":3,"file":"itemizeProcessor.d.ts","sourceRoot":"","sources":["../../core/itemizeProcessor.js"],"names":[],"mappings":"AAUA,iCAJgD,CAAC,SAApC,qCAAkC,MACpC,gBAAgB,SAChB,CAAC,QA2FX"}
1
+ {"version":3,"file":"itemizeProcessor.d.ts","sourceRoot":"","sources":["../../core/itemizeProcessor.js"],"names":[],"mappings":"AAUA,iCAJgD,CAAC,SAApC,qCAAkC,MACpC,gBAAgB,SAChB,CAAC,QA8GX"}