fix: improve each block index handling (#9889)

pull/9893/head
Dominic Gannaway 1 year ago committed by GitHub
parent bdd63c8187
commit 7238e1d3ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: improve each block index handling

@ -2236,6 +2236,12 @@ export const template_visitors = {
const item = b.id(each_node_meta.item_name); const item = b.id(each_node_meta.item_name);
const binding = /** @type {import('#compiler').Binding} */ (context.state.scope.get(item.name)); const binding = /** @type {import('#compiler').Binding} */ (context.state.scope.get(item.name));
binding.expression = each_item_is_reactive ? b.call('$.unwrap', item) : item; binding.expression = each_item_is_reactive ? b.call('$.unwrap', item) : item;
if (node.index) {
const index_binding = /** @type {import('#compiler').Binding} */ (
context.state.scope.get(node.index)
);
index_binding.expression = each_item_is_reactive ? b.call('$.unwrap', index) : index;
}
/** @type {import('estree').Statement[]} */ /** @type {import('estree').Statement[]} */
const declarations = []; const declarations = [];
@ -2291,7 +2297,7 @@ export const template_visitors = {
const key_function = const key_function =
node.key && ((each_type & EACH_ITEM_REACTIVE) !== 0 || context.state.options.dev) node.key && ((each_type & EACH_ITEM_REACTIVE) !== 0 || context.state.options.dev)
? b.arrow( ? b.arrow(
[node.context.type === 'Identifier' ? node.context : b.id('$$item')], [node.context.type === 'Identifier' ? node.context : b.id('$$item'), index],
b.block( b.block(
declarations.concat( declarations.concat(
b.return(/** @type {import('estree').Expression} */ (context.visit(node.key))) b.return(/** @type {import('estree').Expression} */ (context.visit(node.key)))

@ -1,4 +1,5 @@
import { untrack } from './runtime.js'; import { EACH_INDEX_REACTIVE } from '../../constants.js';
import { source, untrack } from './runtime.js';
import { is_array } from './utils.js'; import { is_array } from './utils.js';
/** regex of all html void element names */ /** regex of all html void element names */
@ -65,7 +66,7 @@ export function validate_dynamic_element_tag(tag_fn) {
/** /**
* @param {() => any} collection * @param {() => any} collection
* @param {(item: any) => string} key_fn * @param {(item: any, index: number) => string} key_fn
* @returns {void} * @returns {void}
*/ */
export function validate_each_keys(collection, key_fn) { export function validate_each_keys(collection, key_fn) {
@ -78,7 +79,7 @@ export function validate_each_keys(collection, key_fn) {
: Array.from(maybe_array); : Array.from(maybe_array);
const length = array.length; const length = array.length;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
const key = key_fn(array[i]); const key = key_fn(array[i], i);
if (keys.has(key)) { if (keys.has(key)) {
throw new Error( throw new Error(
`Cannot have duplicate keys in a keyed each: Keys at index ${keys.get( `Cannot have duplicate keys in a keyed each: Keys at index ${keys.get(

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
html: `<div>0</div><div>1</div>`
});

@ -0,0 +1,3 @@
{#each {length: 2} as item, i (`${i}`)}
<div>{i}</div>
{/each}
Loading…
Cancel
Save