@@ -168,6 +168,7 @@ export function migrate(source, { filename, use_ts } = {}) {
168
168
legacy_imports : new Set ( ) ,
169
169
script_insertions : new Set ( ) ,
170
170
derived_components : new Map ( ) ,
171
+ derived_conflicting_slots : new Map ( ) ,
171
172
derived_labeled_statements : new Set ( ) ,
172
173
has_svelte_self : false ,
173
174
uses_ts :
@@ -199,6 +200,7 @@ export function migrate(source, { filename, use_ts } = {}) {
199
200
const need_script =
200
201
state . legacy_imports . size > 0 ||
201
202
state . derived_components . size > 0 ||
203
+ state . derived_conflicting_slots . size > 0 ||
202
204
state . script_insertions . size > 0 ||
203
205
state . props . length > 0 ||
204
206
analysis . uses_rest_props ||
@@ -365,6 +367,13 @@ export function migrate(source, { filename, use_ts } = {}) {
365
367
) ;
366
368
}
367
369
370
+ if ( state . derived_conflicting_slots . size > 0 ) {
371
+ str . appendRight (
372
+ insertion_point ,
373
+ `\n${ indent } ${ [ ...state . derived_conflicting_slots . entries ( ) ] . map ( ( [ name , init ] ) => `const ${ name } = $derived(${ init } );` ) . join ( `\n${ indent } ` ) } \n`
374
+ ) ;
375
+ }
376
+
368
377
if ( state . props . length > 0 && state . analysis . accessors ) {
369
378
str . appendRight (
370
379
insertion_point ,
@@ -414,6 +423,7 @@ export function migrate(source, { filename, use_ts } = {}) {
414
423
* legacy_imports: Set<string>;
415
424
* script_insertions: Set<string>;
416
425
* derived_components: Map<string, string>;
426
+ * derived_conflicting_slots: Map<string, string>;
417
427
* derived_labeled_statements: Set<LabeledStatement>;
418
428
* has_svelte_self: boolean;
419
429
* uses_ts: boolean;
@@ -1133,6 +1143,7 @@ const template = {
1133
1143
let name = 'children' ;
1134
1144
let slot_name = 'default' ;
1135
1145
let slot_props = '{ ' ;
1146
+ let aliased_slot_name ;
1136
1147
1137
1148
for ( const attr of node . attributes ) {
1138
1149
if ( attr . type === 'SpreadAttribute' ) {
@@ -1144,6 +1155,37 @@ const template = {
1144
1155
1145
1156
if ( attr . name === 'name' ) {
1146
1157
slot_name = /** @type {any } */ ( attr . value ) [ 0 ] . data ;
1158
+ // if some of the parents or this node itself har a slot
1159
+ // attribute with the sane name of this slot
1160
+ // we want to create a derived or the migrated snippet
1161
+ // will shadow the slot prop
1162
+ if (
1163
+ path . some (
1164
+ ( parent ) =>
1165
+ ( parent . type === 'RegularElement' ||
1166
+ parent . type === 'SvelteElement' ||
1167
+ parent . type === 'Component' ||
1168
+ parent . type === 'SvelteComponent' ||
1169
+ parent . type === 'SvelteFragment' ) &&
1170
+ parent . attributes . some (
1171
+ ( attribute ) =>
1172
+ attribute . type === 'Attribute' &&
1173
+ attribute . name === 'slot' &&
1174
+ is_text_attribute ( attribute ) &&
1175
+ attribute . value [ 0 ] . data === slot_name
1176
+ )
1177
+ ) ||
1178
+ node . attributes . some (
1179
+ ( attribute ) =>
1180
+ attribute . type === 'Attribute' &&
1181
+ attribute . name === 'slot' &&
1182
+ is_text_attribute ( attribute ) &&
1183
+ attribute . value [ 0 ] . data === slot_name
1184
+ )
1185
+ ) {
1186
+ aliased_slot_name = `${ slot_name } _render` ;
1187
+ state . derived_conflicting_slots . set ( aliased_slot_name , slot_name ) ;
1188
+ }
1147
1189
} else {
1148
1190
const attr_value =
1149
1191
attr . value === true || Array . isArray ( attr . value ) ? attr . value : [ attr . value ] ;
@@ -1200,6 +1242,8 @@ const template = {
1200
1242
existing_prop . needs_refine_type = false ;
1201
1243
}
1202
1244
1245
+ name = aliased_slot_name ?? name ;
1246
+
1203
1247
if ( node . fragment . nodes . length > 0 ) {
1204
1248
next ( ) ;
1205
1249
state . str . update (
0 commit comments