@skirbi/sugar 0.1.2 → 0.1.3

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/Changes CHANGED
@@ -1,5 +1,40 @@
1
1
  Revision history for @skirbi/sugar
2
2
 
3
+ 0.1.3 2026-06-05 23:23:43Z
4
+
5
+ * Add Livewire integration module
6
+
7
+ Add @skirbi/sugar/livewire.mjs. An optional side-effect module that
8
+ fixes structural mismatches between Livewire's morphing algorithm and
9
+ Sugar web components.
10
+
11
+ Problem? Yes.
12
+ Livewire sends new HTML in its authored (dehydrated) state. Custom
13
+ elements in that HTML have not yet run connectedCallback, so their
14
+ DOM structure differs from the current rendered (hydrated) DOM.
15
+ Alpine's morph algorithm compares these two structurally different
16
+ trees, sees mismatches, and calls swapElements — replacing entire
17
+ subtrees, disconnecting all custom element descendants, triggering
18
+ cascading connectedCallback re-renders, and causing focus loss on
19
+ every Livewire update.
20
+
21
+ Fix, days:
22
+ Before Livewire's morph runs, parse the new HTML into a hidden
23
+ staging element and wait two microtasks for custom elements to
24
+ hydrate. Alpine then morphs two fully hydrated trees — apples to
25
+ apples — no structural mismatches, no swaps, no cascade, no focus
26
+ loss.
27
+
28
+ Usage:
29
+ import '@skirbi/sugar/livewire';
30
+
31
+ Only import when using Sugar/Semtic/Skirbi components inside a Livewire
32
+ application. The guard on typeof document makes it safe in SSR/Node
33
+ environments.
34
+
35
+ This fix is a candidate for upstreaming to Livewire once it has been
36
+ validated.
37
+
3
38
  0.1.2 2026-06-05 13:39:51Z
4
39
 
5
40
  * Add replaceChildrenSugarSafe to allow repaints without focus loss
package/lib/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // SPDX-License-Identifier: MIT
4
4
 
5
- const VERSION = "0.1.2";
5
+ const VERSION = "0.1.3";
6
6
 
7
7
  export { HTMLElementSugar } from './htmlelement.mjs';
8
8
  export { HTMLElementSugarInput } from './htmlelement-input.mjs';
@@ -0,0 +1,42 @@
1
+ // SPDX-FileCopyrightText: 2026 Wesley Schwengle <wesleys@opperschaap.net>
2
+ //
3
+ // SPDX-License-Identifier: MIT
4
+
5
+ /**
6
+ * @skirbi/sugar — Livewire integration
7
+ *
8
+ * Hydrates custom elements in Livewire's new HTML before morphing starts.
9
+ * This ensures Alpine morphs hydrated vs hydrated trees — apples to apples —
10
+ * preventing structural mismatches that cause swapElements cascades,
11
+ * disconnected/reconnected custom elements, and focus loss on every update.
12
+ *
13
+ * Usage:
14
+ * import '@skirbi/sugar/livewire';
15
+ *
16
+ * Only import this when using Sugar components inside a Livewire application.
17
+ */
18
+
19
+ if (typeof document !== 'undefined') {
20
+ document.addEventListener('livewire:init', () => {
21
+ window.Livewire.hook('component.init', ({ component }) => {
22
+ const original = component.processEffects.bind(component);
23
+
24
+ component.processEffects = function(effects) {
25
+ if (!effects.html) return original(effects);
26
+ if (effects._sugarHydrated) return original(effects);
27
+
28
+ const staging = document.createElement('div');
29
+ staging.style.display = 'none';
30
+ document.body.appendChild(staging);
31
+ staging.innerHTML = effects.html;
32
+
33
+ Promise.resolve().then(() => Promise.resolve().then(() => {
34
+ effects.html = staging.innerHTML;
35
+ effects._sugarHydrated = true;
36
+ staging.remove();
37
+ original(effects);
38
+ }));
39
+ };
40
+ });
41
+ });
42
+ }
package/package.json CHANGED
@@ -24,6 +24,7 @@
24
24
  "./htmlelement": "./lib/htmlelement.mjs",
25
25
  "./htmlelement-input": "./lib/htmlelement-input.mjs",
26
26
  "./htmlelement-select": "./lib/htmlelement-select.mjs",
27
+ "./livewire": "./lib/livewire.mjs",
27
28
  "./testing": "./lib/testing.mjs",
28
29
  "./with-connected-sugar": "./lib/with-connected-sugar.mjs"
29
30
  },
@@ -52,5 +53,5 @@
52
53
  },
53
54
  "sideEffects": false,
54
55
  "type": "module",
55
- "version": "0.1.2"
56
+ "version": "0.1.3"
56
57
  }