Skip to content

Commit 7238e1d

Browse files
authored
fix: improve each block index handling (#9889)
1 parent bdd63c8 commit 7238e1d

File tree

5 files changed

+24
-4
lines changed

5 files changed

+24
-4
lines changed

.changeset/wise-dancers-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: improve each block index handling

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2236,6 +2236,12 @@ export const template_visitors = {
22362236
const item = b.id(each_node_meta.item_name);
22372237
const binding = /** @type {import('#compiler').Binding} */ (context.state.scope.get(item.name));
22382238
binding.expression = each_item_is_reactive ? b.call('$.unwrap', item) : item;
2239+
if (node.index) {
2240+
const index_binding = /** @type {import('#compiler').Binding} */ (
2241+
context.state.scope.get(node.index)
2242+
);
2243+
index_binding.expression = each_item_is_reactive ? b.call('$.unwrap', index) : index;
2244+
}
22392245

22402246
/** @type {import('estree').Statement[]} */
22412247
const declarations = [];
@@ -2291,7 +2297,7 @@ export const template_visitors = {
22912297
const key_function =
22922298
node.key && ((each_type & EACH_ITEM_REACTIVE) !== 0 || context.state.options.dev)
22932299
? b.arrow(
2294-
[node.context.type === 'Identifier' ? node.context : b.id('$$item')],
2300+
[node.context.type === 'Identifier' ? node.context : b.id('$$item'), index],
22952301
b.block(
22962302
declarations.concat(
22972303
b.return(/** @type {import('estree').Expression} */ (context.visit(node.key)))

packages/svelte/src/internal/client/validate.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { untrack } from './runtime.js';
1+
import { EACH_INDEX_REACTIVE } from '../../constants.js';
2+
import { source, untrack } from './runtime.js';
23
import { is_array } from './utils.js';
34

45
/** regex of all html void element names */
@@ -65,7 +66,7 @@ export function validate_dynamic_element_tag(tag_fn) {
6566

6667
/**
6768
* @param {() => any} collection
68-
* @param {(item: any) => string} key_fn
69+
* @param {(item: any, index: number) => string} key_fn
6970
* @returns {void}
7071
*/
7172
export function validate_each_keys(collection, key_fn) {
@@ -78,7 +79,7 @@ export function validate_each_keys(collection, key_fn) {
7879
: Array.from(maybe_array);
7980
const length = array.length;
8081
for (let i = 0; i < length; i++) {
81-
const key = key_fn(array[i]);
82+
const key = key_fn(array[i], i);
8283
if (keys.has(key)) {
8384
throw new Error(
8485
`Cannot have duplicate keys in a keyed each: Keys at index ${keys.get(
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
html: `<div>0</div><div>1</div>`
5+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{#each {length: 2} as item, i (`${i}`)}
2+
<div>{i}</div>
3+
{/each}

0 commit comments

Comments
 (0)