Skip to content

Commit 8d94333

Browse files
yash-builderYash Wadhia
and
Yash Wadhia
authored
Handle key attribute correctly for Svelte (#1725)
* fix: handling key attribute in svelte * docs: changeset * fix: moving key handling logic on top of blockToSvelte * fix: tests snap * fix: moving key handler code to the top of blockToSvelte and updating changeset message --------- Co-authored-by: Yash Wadhia <[email protected]>
1 parent 16f0dbb commit 8d94333

File tree

3 files changed

+133
-114
lines changed

3 files changed

+133
-114
lines changed

Diff for: .changeset/fresh-bulldogs-judge.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@builder.io/mitosis': patch
3+
---
4+
5+
[Svelte] Bug: Fixed handling for key attribute due to its unique syntax and absence in the standard props

Diff for: packages/core/src/__tests__/__snapshots__/svelte.test.ts.snap

+116-114
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,9 @@ exports[`Svelte > jsx > Javascript Test > Image State 1`] = `
10791079

10801080
<div>
10811081
{#each images as item, itemIndex}
1082-
<img class=\\"custom-class\\" src={item} key={itemIndex} />
1082+
{#key itemIndex}
1083+
<img class=\\"custom-class\\" src={item} />
1084+
{/key}
10831085
{/each}
10841086
</div>"
10851087
`;
@@ -1105,16 +1107,17 @@ exports[`Svelte > jsx > Javascript Test > Img 1`] = `
11051107
}
11061108
</script>
11071109

1108-
<img
1109-
style={stringifyStyles({
1110-
objectFit: backgroundSize || \\"cover\\",
1111-
objectPosition: backgroundPosition || \\"center\\",
1112-
})}
1113-
{...attributes}
1114-
key={(Builder.isEditing && imgSrc) || \\"default-key\\"}
1115-
alt={altText}
1116-
src={imgSrc}
1117-
/>"
1110+
{#key (Builder.isEditing && imgSrc) || \\"default-key\\"}
1111+
<img
1112+
style={stringifyStyles({
1113+
objectFit: backgroundSize || \\"cover\\",
1114+
objectPosition: backgroundPosition || \\"center\\",
1115+
})}
1116+
{...attributes}
1117+
alt={altText}
1118+
src={imgSrc}
1119+
/>
1120+
{/key}"
11181121
`;
11191122

11201123
exports[`Svelte > jsx > Javascript Test > Input 1`] = `
@@ -1131,19 +1134,20 @@ exports[`Svelte > jsx > Javascript Test > Input 1`] = `
11311134
export let onChange;
11321135
</script>
11331136

1134-
<input
1135-
{...attributes}
1136-
key={Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
1137-
{placeholder}
1138-
{type}
1139-
{name}
1140-
{value}
1141-
{defaultValue}
1142-
{required}
1143-
on:change={(event) => {
1144-
onChange?.(event.target.value);
1145-
}}
1146-
/>"
1137+
{#key Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
1138+
<input
1139+
{...attributes}
1140+
{placeholder}
1141+
{type}
1142+
{name}
1143+
{value}
1144+
{defaultValue}
1145+
{required}
1146+
on:change={(event) => {
1147+
onChange?.(event.target.value);
1148+
}}
1149+
/>
1150+
{/key}"
11471151
`;
11481152

11491153
exports[`Svelte > jsx > Javascript Test > InputParent 1`] = `
@@ -1261,19 +1265,15 @@ exports[`Svelte > jsx > Javascript Test > Select 1`] = `
12611265
export let options;
12621266
</script>
12631267

1264-
<select
1265-
{...attributes}
1266-
{value}
1267-
key={Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
1268-
{defaultValue}
1269-
{name}
1270-
>
1271-
{#each options as option, index}
1272-
<option value={option.value} data-index={index}
1273-
>{option.name || option.value}</option
1274-
>
1275-
{/each}
1276-
</select>"
1268+
{#key Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
1269+
<select {...attributes} {value} {defaultValue} {name}>
1270+
{#each options as option, index}
1271+
<option value={option.value} data-index={index}
1272+
>{option.name || option.value}</option
1273+
>
1274+
{/each}
1275+
</select>
1276+
{/key}"
12771277
`;
12781278

12791279
exports[`Svelte > jsx > Javascript Test > SlotDefault 1`] = `"<div><slot><div class=\\"default-slot\\">Default content</div></slot></div>"`;
@@ -1554,26 +1554,27 @@ exports[`Svelte > jsx > Javascript Test > Video 1`] = `
15541554
}
15551555
</script>
15561556

1557-
<video
1558-
style={stringifyStyles({
1559-
width: \\"100%\\",
1560-
height: \\"100%\\",
1561-
...attributes?.style,
1562-
objectFit: fit,
1563-
objectPosition: position,
1564-
// Hack to get object fit to work as expected and
1565-
// not have the video overflow
1566-
borderRadius: 1,
1567-
})}
1568-
preload=\\"none\\"
1569-
{...attributes}
1570-
key={video || \\"no-src\\"}
1571-
poster={posterImage}
1572-
autoplay={autoPlay}
1573-
{muted}
1574-
{controls}
1575-
{loop}
1576-
/>"
1557+
{#key video || \\"no-src\\"}
1558+
<video
1559+
style={stringifyStyles({
1560+
width: \\"100%\\",
1561+
height: \\"100%\\",
1562+
...attributes?.style,
1563+
objectFit: fit,
1564+
objectPosition: position,
1565+
// Hack to get object fit to work as expected and
1566+
// not have the video overflow
1567+
borderRadius: 1,
1568+
})}
1569+
preload=\\"none\\"
1570+
{...attributes}
1571+
poster={posterImage}
1572+
autoplay={autoPlay}
1573+
{muted}
1574+
{controls}
1575+
{loop}
1576+
/>
1577+
{/key}"
15771578
`;
15781579

15791580
exports[`Svelte > jsx > Javascript Test > arrowFunctionInUseStore 1`] = `
@@ -4670,7 +4671,9 @@ exports[`Svelte > jsx > Typescript Test > Image State 1`] = `
46704671

46714672
<div>
46724673
{#each images as item, itemIndex}
4673-
<img class=\\"custom-class\\" src={item} key={itemIndex} />
4674+
{#key itemIndex}
4675+
<img class=\\"custom-class\\" src={item} />
4676+
{/key}
46744677
{/each}
46754678
</div>"
46764679
`;
@@ -4715,16 +4718,17 @@ exports[`Svelte > jsx > Typescript Test > Img 1`] = `
47154718
}
47164719
</script>
47174720

4718-
<img
4719-
style={stringifyStyles({
4720-
objectFit: backgroundSize || \\"cover\\",
4721-
objectPosition: backgroundPosition || \\"center\\",
4722-
})}
4723-
{...attributes}
4724-
key={(Builder.isEditing && imgSrc) || \\"default-key\\"}
4725-
alt={altText}
4726-
src={imgSrc}
4727-
/>"
4721+
{#key (Builder.isEditing && imgSrc) || \\"default-key\\"}
4722+
<img
4723+
style={stringifyStyles({
4724+
objectFit: backgroundSize || \\"cover\\",
4725+
objectPosition: backgroundPosition || \\"center\\",
4726+
})}
4727+
{...attributes}
4728+
alt={altText}
4729+
src={imgSrc}
4730+
/>
4731+
{/key}"
47284732
`;
47294733

47304734
exports[`Svelte > jsx > Typescript Test > Input 1`] = `
@@ -4754,19 +4758,20 @@ exports[`Svelte > jsx > Typescript Test > Input 1`] = `
47544758
export let onChange: FormInputProps[\\"onChange\\"] = undefined;
47554759
</script>
47564760

4757-
<input
4758-
{...attributes}
4759-
key={Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
4760-
{placeholder}
4761-
{type}
4762-
{name}
4763-
{value}
4764-
{defaultValue}
4765-
{required}
4766-
on:change={(event) => {
4767-
onChange?.(event.target.value);
4768-
}}
4769-
/>"
4761+
{#key Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
4762+
<input
4763+
{...attributes}
4764+
{placeholder}
4765+
{type}
4766+
{name}
4767+
{value}
4768+
{defaultValue}
4769+
{required}
4770+
on:change={(event) => {
4771+
onChange?.(event.target.value);
4772+
}}
4773+
/>
4774+
{/key}"
47704775
`;
47714776

47724777
exports[`Svelte > jsx > Typescript Test > InputParent 1`] = `
@@ -4927,19 +4932,15 @@ exports[`Svelte > jsx > Typescript Test > Select 1`] = `
49274932
export let options: FormSelectProps[\\"options\\"] = undefined;
49284933
</script>
49294934

4930-
<select
4931-
{...attributes}
4932-
{value}
4933-
key={Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
4934-
{defaultValue}
4935-
{name}
4936-
>
4937-
{#each options as option, index}
4938-
<option value={option.value} data-index={index}
4939-
>{option.name || option.value}</option
4940-
>
4941-
{/each}
4942-
</select>"
4935+
{#key Builder.isEditing && defaultValue ? defaultValue : \\"default-key\\"}
4936+
<select {...attributes} {value} {defaultValue} {name}>
4937+
{#each options as option, index}
4938+
<option value={option.value} data-index={index}
4939+
>{option.name || option.value}</option
4940+
>
4941+
{/each}
4942+
</select>
4943+
{/key}"
49434944
`;
49444945

49454946
exports[`Svelte > jsx > Typescript Test > SlotDefault 1`] = `
@@ -5329,26 +5330,27 @@ exports[`Svelte > jsx > Typescript Test > Video 1`] = `
53295330
}
53305331
</script>
53315332

5332-
<video
5333-
style={stringifyStyles({
5334-
width: \\"100%\\",
5335-
height: \\"100%\\",
5336-
...attributes?.style,
5337-
objectFit: fit,
5338-
objectPosition: position,
5339-
// Hack to get object fit to work as expected and
5340-
// not have the video overflow
5341-
borderRadius: 1,
5342-
})}
5343-
preload=\\"none\\"
5344-
{...attributes}
5345-
key={video || \\"no-src\\"}
5346-
poster={posterImage}
5347-
autoplay={autoPlay}
5348-
{muted}
5349-
{controls}
5350-
{loop}
5351-
/>"
5333+
{#key video || \\"no-src\\"}
5334+
<video
5335+
style={stringifyStyles({
5336+
width: \\"100%\\",
5337+
height: \\"100%\\",
5338+
...attributes?.style,
5339+
objectFit: fit,
5340+
objectPosition: position,
5341+
// Hack to get object fit to work as expected and
5342+
// not have the video overflow
5343+
borderRadius: 1,
5344+
})}
5345+
preload=\\"none\\"
5346+
{...attributes}
5347+
poster={posterImage}
5348+
autoplay={autoPlay}
5349+
{muted}
5350+
{controls}
5351+
{loop}
5352+
/>
5353+
{/key}"
53525354
`;
53535355

53545356
exports[`Svelte > jsx > Typescript Test > arrowFunctionInUseStore 1`] = `

Diff for: packages/core/src/generators/svelte/blocks.ts

+12
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,18 @@ const stringifyBinding =
254254
};
255255

256256
export const blockToSvelte: BlockToSvelte = ({ json, options, parentComponent }) => {
257+
// Handling key binding by wrapping the element in a #key block
258+
if (json.bindings.key) {
259+
const keyCode = json.bindings.key.code;
260+
delete json.bindings.key;
261+
const str = `
262+
{#key ${keyCode}}
263+
${blockToSvelte({ json, options, parentComponent })}
264+
{/key}
265+
`;
266+
return str;
267+
}
268+
257269
if (mappers[json.name as keyof typeof mappers]) {
258270
return mappers[json.name as keyof typeof mappers]({
259271
json: json as any,

0 commit comments

Comments
 (0)