Skip to content

Commit 998c287

Browse files
committed
feature #1126 [LiveComponent] Fix morphing issues with an Alpine.js component, close #984 (Kocal)
This PR was merged into the 2.x branch. Discussion ---------- [LiveComponent] Fix morphing issues with an Alpine.js component, close #984 | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Tickets | Fix #984 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT <!-- Replace this notice by a short README for your feature/bugfix. This will help people understand your PR and can be used as a start for the documentation. Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - Never break backward compatibility (see https://symfony.com/bc). - Features and deprecations must be submitted against branch main. --> This PR is a proposal for #984. As I encountered the same issue than `@richardhj` when using Alpine.js with a LiveComponent, and I wanted to fix it ASAP. I've added some checks and errors messages in order to help the dev if needed. Commits ------- 52a5ddb [LiveComponent] Fix morphing issues with an Alpine.js component, close #984
2 parents b31d5e1 + 52a5ddb commit 998c287

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/LiveComponent/assets/dist/live_controller.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,15 @@ function executeMorphdom(rootFromElement, rootToElement, modifiedFieldElements,
12161216
return true;
12171217
}
12181218
if (fromEl instanceof HTMLElement && toEl instanceof HTMLElement) {
1219+
if (typeof fromEl.__x !== 'undefined') {
1220+
if (!window.Alpine) {
1221+
throw new Error('Unable to access Alpine.js though the global window.Alpine variable. Please make sure Alpine.js is loaded before Symfony UX LiveComponent.');
1222+
}
1223+
if (typeof window.Alpine.morph !== 'function') {
1224+
throw new Error('Unable to access Alpine.js morph function. Please make sure the Alpine.js Morph plugin is installed and loaded, see https://alpinejs.dev/plugins/morph for more information.');
1225+
}
1226+
window.Alpine.morph(fromEl.__x, toEl);
1227+
}
12191228
if (childComponentMap.has(fromEl)) {
12201229
const childComponent = childComponentMap.get(fromEl);
12211230
childComponent.updateFromNewElementFromParentRender(toEl);

src/LiveComponent/assets/src/morphdom.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,25 @@ export function executeMorphdom(
4242

4343
// skip special checking if this is, for example, an SVG
4444
if (fromEl instanceof HTMLElement && toEl instanceof HTMLElement) {
45+
// We assume fromEl is an Alpine component if it has `__x` property.
46+
// If it's the case, then we should morph `fromEl` to `ToEl` (thanks to https://alpinejs.dev/plugins/morph)
47+
// in order to keep the component state and UI in sync.
48+
if (typeof fromEl.__x !== 'undefined') {
49+
if (!window.Alpine) {
50+
throw new Error(
51+
'Unable to access Alpine.js though the global window.Alpine variable. Please make sure Alpine.js is loaded before Symfony UX LiveComponent.'
52+
);
53+
}
54+
55+
if (typeof window.Alpine.morph !== 'function') {
56+
throw new Error(
57+
'Unable to access Alpine.js morph function. Please make sure the Alpine.js Morph plugin is installed and loaded, see https://alpinejs.dev/plugins/morph for more information.'
58+
);
59+
}
60+
61+
window.Alpine.morph(fromEl.__x, toEl);
62+
}
63+
4564
if (childComponentMap.has(fromEl)) {
4665
const childComponent = childComponentMap.get(fromEl) as Component;
4766

0 commit comments

Comments
 (0)