@@ -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;
@@ -1106,6 +1116,7 @@ const template = {
1106
1116
let name = 'children' ;
1107
1117
let slot_name = 'default' ;
1108
1118
let slot_props = '{ ' ;
1119
+ let aliased_slot_name ;
1109
1120
1110
1121
for ( const attr of node . attributes ) {
1111
1122
if ( attr . type === 'SpreadAttribute' ) {
@@ -1117,6 +1128,37 @@ const template = {
1117
1128
1118
1129
if ( attr . name === 'name' ) {
1119
1130
slot_name = /** @type {any } */ ( attr . value ) [ 0 ] . data ;
1131
+ // if some of the parents or this node itself har a slot
1132
+ // attribute with the sane name of this slot
1133
+ // we want to create a derived or the migrated snippet
1134
+ // will shadow the slot prop
1135
+ if (
1136
+ path . some (
1137
+ ( parent ) =>
1138
+ ( parent . type === 'RegularElement' ||
1139
+ parent . type === 'SvelteElement' ||
1140
+ parent . type === 'Component' ||
1141
+ parent . type === 'SvelteComponent' ||
1142
+ parent . type === 'SvelteFragment' ) &&
1143
+ parent . attributes . some (
1144
+ ( attribute ) =>
1145
+ attribute . type === 'Attribute' &&
1146
+ attribute . name === 'slot' &&
1147
+ is_text_attribute ( attribute ) &&
1148
+ attribute . value [ 0 ] . data === slot_name
1149
+ )
1150
+ ) ||
1151
+ node . attributes . some (
1152
+ ( attribute ) =>
1153
+ attribute . type === 'Attribute' &&
1154
+ attribute . name === 'slot' &&
1155
+ is_text_attribute ( attribute ) &&
1156
+ attribute . value [ 0 ] . data === slot_name
1157
+ )
1158
+ ) {
1159
+ aliased_slot_name = `${ slot_name } _render` ;
1160
+ state . derived_conflicting_slots . set ( aliased_slot_name , slot_name ) ;
1161
+ }
1120
1162
} else {
1121
1163
const attr_value =
1122
1164
attr . value === true || Array . isArray ( attr . value ) ? attr . value : [ attr . value ] ;
@@ -1173,6 +1215,8 @@ const template = {
1173
1215
existing_prop . needs_refine_type = false ;
1174
1216
}
1175
1217
1218
+ name = aliased_slot_name ?? name ;
1219
+
1176
1220
if ( node . fragment . nodes . length > 0 ) {
1177
1221
next ( ) ;
1178
1222
state . str . update (
0 commit comments