@skirbi/sugar 0.1.2 → 0.1.4

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,46 @@
1
1
  Revision history for @skirbi/sugar
2
2
 
3
+ 0.1.4 2026-06-06 16:41:57Z
4
+
5
+ * Semtic already had this, but sugar in itself also has side-effects.
6
+ In the future we'll probably note which things have side-effects, but for
7
+ now we treat ourselves as fully side-effect-ish.
8
+
9
+ 0.1.3 2026-06-05 23:23:43Z
10
+
11
+ * Add Livewire integration module
12
+
13
+ Add @skirbi/sugar/livewire.mjs. An optional side-effect module that
14
+ fixes structural mismatches between Livewire's morphing algorithm and
15
+ Sugar web components.
16
+
17
+ Problem? Yes.
18
+ Livewire sends new HTML in its authored (dehydrated) state. Custom
19
+ elements in that HTML have not yet run connectedCallback, so their
20
+ DOM structure differs from the current rendered (hydrated) DOM.
21
+ Alpine's morph algorithm compares these two structurally different
22
+ trees, sees mismatches, and calls swapElements — replacing entire
23
+ subtrees, disconnecting all custom element descendants, triggering
24
+ cascading connectedCallback re-renders, and causing focus loss on
25
+ every Livewire update.
26
+
27
+ Fix, days:
28
+ Before Livewire's morph runs, parse the new HTML into a hidden
29
+ staging element and wait two microtasks for custom elements to
30
+ hydrate. Alpine then morphs two fully hydrated trees — apples to
31
+ apples — no structural mismatches, no swaps, no cascade, no focus
32
+ loss.
33
+
34
+ Usage:
35
+ import '@skirbi/sugar/livewire';
36
+
37
+ Only import when using Sugar/Semtic/Skirbi components inside a Livewire
38
+ application. The guard on typeof document makes it safe in SSR/Node
39
+ environments.
40
+
41
+ This fix is a candidate for upstreaming to Livewire once it has been
42
+ validated.
43
+
3
44
  0.1.2 2026-06-05 13:39:51Z
4
45
 
5
46
  * 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.4";
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.4"
56
57
  }