Skip to content

Fragment/x for reorder - #69

Open
rameel wants to merge 2 commits into
mainfrom
fragment/x-for-reorder
Open

rameel wants to merge 2 commits into
mainfrom
fragment/x-for-reorder

Conversation

@rameel

@rameel rameel commented Oct 20, 2026

Copy link
Copy Markdown
Owner

No description provided.

rameel and others added 2 commits October 18, 2026 22:13
Since Alpine 3.15.9, keyed x-for moves only the item element and,
for x-if, its single rendered element. The content of x-fragment, x-when
and x-match was rendered before the template and was left behind, so
reordering mixed up the blocks.

Render the content after the template, like x-if, and expose its last
node through _x_currentIfEl and _x_lastRenderedEl, so x-for treats the
whole block as the item. The shared mutation observer then restores
the content of every block in the affected parent right after its
template, following nested blocks and x-if.

The observer also handles removed nodes and the records produced by
deleting nested blocks, and works with Alpine versions that do not
expose the last rendered item of x-for or destroy x-if content.

Fixes #62
Cover reordering, adding, removing and toggling the items of a keyed
x-for for x-fragment, x-when and x-match, checking the exact node
layout and that the existing nodes are moved rather than recreated.
For x-fragment, check all transitions between the orders of four items.

Also cover nested blocks, x-if inside a block and vice versa, a block
containing a keyed x-for of blocks, restoring a moved node of a block,
keeping the initial content of nested x-if and x-for, and that the
observer settles without a feedback loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

📦 Bundle size comparison

Name Size Gzip Brotli Δ
alpinegear-bound.esm.min.js 3.91 KiB 1.80 KiB 1.56 KiB
alpinegear-bound.min.js 3.95 KiB 1.82 KiB 1.58 KiB
alpinegear-destroy.esm.min.js 128 B 123 B 91 B
alpinegear-destroy.min.js 191 B 167 B 123 B
alpinegear-dialog.esm.min.js 1.75 KiB 951 B 811 B
alpinegear-dialog.min.js 1.79 KiB 967 B 822 B
alpinegear-format.esm.min.js 1.18 KiB 645 B 579 B
alpinegear-format.min.js 1.25 KiB 680 B 587 B
alpinegear-fragment.esm.min.js 1.91 KiB (+912 B) 891 B (+352 B) 788 B (+326 B) 🔴
alpinegear-fragment.min.js 1.97 KiB (+912 B) 922 B (+351 B) 813 B (+325 B) 🔴
alpinegear-hotkey.esm.min.js 1.97 KiB 1.08 KiB 964 B
alpinegear-hotkey.min.js 2.03 KiB 1.10 KiB 996 B
alpinegear-main.esm.min.js 8.11 KiB (+912 B) 3.24 KiB (+319 B) 2.88 KiB (+305 B) 🔴
alpinegear-main.min.js 8.08 KiB (+912 B) 3.20 KiB (+322 B) 2.84 KiB (+305 B) 🔴
alpinegear-markdown.esm.min.js 19.27 KiB 7.26 KiB 6.61 KiB
alpinegear-markdown.min.js 19.32 KiB 7.27 KiB 6.63 KiB
alpinegear-match.esm.min.js 2.38 KiB (+912 B) 1.08 KiB (+338 B) 975 B (+305 B) 🔴
alpinegear-match.min.js 2.44 KiB (+912 B) 1.11 KiB (+338 B) 1005 B (+315 B) 🔴
alpinegear-router.esm.min.js 9.40 KiB 4.03 KiB 3.59 KiB
alpinegear-router.min.js 9.42 KiB 4.04 KiB 3.60 KiB
alpinegear-safehtml.esm.min.js 806 B 543 B 457 B
alpinegear-safehtml.min.js 853 B 569 B 485 B
alpinegear-template.esm.min.js 421 B 294 B 219 B
alpinegear-template.min.js 483 B 326 B 246 B
alpinegear-typegrab.esm.min.js 471 B 333 B 277 B
alpinegear-typegrab.min.js 509 B 348 B 294 B
alpinegear-when.esm.min.js 2.10 KiB (+912 B) 988 B (+343 B) 875 B (+319 B) 🔴
alpinegear-when.min.js 2.17 KiB (+912 B) 1018 B (+343 B) 899 B (+319 B) 🔴

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant