diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fa6ec5796..904c927a86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## Unreleased * Return the context object in `setContext` [#7427](https://github.com/sveltejs/svelte/issues/7427) +* Fix `{@const}` tag not working inside Component when there's no `let:` [#7189](https://github.com/sveltejs/svelte/issues/7189) +* Ignore comments in `{#each}` blocks when containing elements with `animate:` ([#3999](https://github.com/sveltejs/svelte/issues/3999)) +* Add a third parameter to the returned function of `createEventDispatcher` that allows passing an object of `{ cancelable: true }` to create a cancelable custom event. The returned function when called will also return a boolean depending on whether the event is cancelled ([#7064](https://github.com/sveltejs/svelte/pull/7064)) +* Fix value of `let:` bindings not updating in certain cases ([#7440](https://github.com/sveltejs/svelte/issues/7440)) ## 3.47.0 diff --git a/package-lock.json b/package-lock.json index f42a96a32c..0b5a130992 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2989,9 +2989,9 @@ "dev": true }, "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "node_modules/json-schema-traverse": { @@ -3025,18 +3025,18 @@ } }, "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, "node_modules/kleur": { @@ -7426,9 +7426,9 @@ "dev": true }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "json-schema-traverse": { @@ -7459,14 +7459,14 @@ } }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" } }, diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md index a0d3f4148c..c6423f408c 100644 --- a/site/content/docs/03-run-time.md +++ b/site/content/docs/03-run-time.md @@ -221,14 +221,14 @@ Retrieves the whole context map that belongs to the closest parent component. Mu #### `createEventDispatcher` ```js -dispatch: ((name: string, detail?: any) => void) = createEventDispatcher(); +dispatch: ((name: string, detail?: any, options?: DispatchOptions) => boolean) = createEventDispatcher(); ``` --- Creates an event dispatcher that can be used to dispatch [component events](/docs#template-syntax-component-directives-on-eventname). Event dispatchers are functions that can take two arguments: `name` and `detail`. -Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture) and are not cancellable with `event.preventDefault()`. The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data. +Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture). The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data. ```sv +``` + ### `svelte/store` The `svelte/store` module exports functions for creating [readable](/docs#run-time-svelte-store-readable), [writable](/docs#run-time-svelte-store-writable) and [derived](/docs#run-time-svelte-store-derived) stores. diff --git a/site/content/faq/1100-is-svelte-v2-still-availabile.md b/site/content/faq/1100-is-svelte-v2-still-available.md similarity index 100% rename from site/content/faq/1100-is-svelte-v2-still-availabile.md rename to site/content/faq/1100-is-svelte-v2-still-available.md diff --git a/site/content/faq/1200-how-do-i-do-hmr.md b/site/content/faq/1200-how-do-i-do-hmr.md index 9160617537..37fb121c02 100644 --- a/site/content/faq/1200-how-do-i-do-hmr.md +++ b/site/content/faq/1200-how-do-i-do-hmr.md @@ -2,4 +2,4 @@ question: How do I do hot module reloading? --- -We recommend using [SvelteKit](https://kit.svelte.dev/), which supports HMR out of the box and is built on top of Vite and svelte-hmr. There are also community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/rixo/svelte-loader-hot). +We recommend using [SvelteKit](https://kit.svelte.dev/), which supports HMR out of the box and is built on top of [Vite](https://vitejs.dev/) and [svelte-hmr](https://github.com/sveltejs/svelte-hmr). There are also community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/rixo/svelte-loader-hot). diff --git a/site/content/faq/200-are-there-any-third-party-resources.md b/site/content/faq/200-are-there-any-third-party-resources.md new file mode 100644 index 0000000000..a4da9628a6 --- /dev/null +++ b/site/content/faq/200-are-there-any-third-party-resources.md @@ -0,0 +1,5 @@ +--- +question: Are there any third-party resources? +--- + +Svelte Society maintains a [list of books and videos](https://sveltesociety.dev/resources). diff --git a/site/content/faq/200-are-there-any-video-courses.md b/site/content/faq/200-are-there-any-video-courses.md deleted file mode 100644 index f5e49207ae..0000000000 --- a/site/content/faq/200-are-there-any-video-courses.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -question: Are there any video courses? ---- - -Rich Harris, the creator of Svelte, taught a course: - -- [Frontend Masters](https://frontendmasters.com/courses/svelte/) - -There are also a number of third-party courses: - -- [Egghead](https://egghead.io/browse/frameworks/svelte) -- [Udemy](https://www.udemy.com/courses/search/?q=sveltejs+svelte) (Note: Udemy frequently has discounts over 90%) -- [Pluralsight](https://www.pluralsight.com/search?q=svelte) - -Finally, there are also YouTube channels and playlists that teach Svelte: - -- [Svelte Master](https://www.youtube.com/channel/UCg6SQd5jnWo5Y70rZD9SQFA) -- [Svelte Tutorial for Beginners](https://www.youtube.com/watch?v=zojEMeQGGHs&list=PL4cUxeGkcC9hlbrVO_2QFVqVPhlZmz7tO) by The Net Ninja diff --git a/site/content/faq/250-are-there-any-books.md b/site/content/faq/250-are-there-any-books.md deleted file mode 100644 index c21106e540..0000000000 --- a/site/content/faq/250-are-there-any-books.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -question: Are there any books? ---- - -There are a few books: - -- [Svelte Handbook](https://flaviocopes.com/page/svelte-handbook/) by Flavio Copes -- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/) by Alessandro Segala -- [Svelte and Sapper in Action](https://www.manning.com/books/svelte-and-sapper-in-action) by R. Mark Volkmann diff --git a/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md b/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md index b990dead95..76d8322fb0 100644 --- a/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md +++ b/site/content/tutorial/04-logic/05-keyed-each-blocks/text.md @@ -4,7 +4,7 @@ title: Keyed each blocks By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want. -It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice what happens: It removes the first `` component, but the *last* DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji. +It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice what happens: it does not remove the first `` component, but rather the *last* DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji. Instead, we'd like to remove only the first `` component and its DOM node, and leave the others unaffected. diff --git a/site/content/tutorial/13-classes/01-classes/app-a/App.svelte b/site/content/tutorial/13-advanced-styling/01-classes/app-a/App.svelte similarity index 100% rename from site/content/tutorial/13-classes/01-classes/app-a/App.svelte rename to site/content/tutorial/13-advanced-styling/01-classes/app-a/App.svelte diff --git a/site/content/tutorial/13-classes/01-classes/app-b/App.svelte b/site/content/tutorial/13-advanced-styling/01-classes/app-b/App.svelte similarity index 100% rename from site/content/tutorial/13-classes/01-classes/app-b/App.svelte rename to site/content/tutorial/13-advanced-styling/01-classes/app-b/App.svelte diff --git a/site/content/tutorial/13-classes/01-classes/text.md b/site/content/tutorial/13-advanced-styling/01-classes/text.md similarity index 100% rename from site/content/tutorial/13-classes/01-classes/text.md rename to site/content/tutorial/13-advanced-styling/01-classes/text.md diff --git a/site/content/tutorial/13-classes/02-class-shorthand/app-a/App.svelte b/site/content/tutorial/13-advanced-styling/02-class-shorthand/app-a/App.svelte similarity index 100% rename from site/content/tutorial/13-classes/02-class-shorthand/app-a/App.svelte rename to site/content/tutorial/13-advanced-styling/02-class-shorthand/app-a/App.svelte diff --git a/site/content/tutorial/13-classes/02-class-shorthand/app-b/App.svelte b/site/content/tutorial/13-advanced-styling/02-class-shorthand/app-b/App.svelte similarity index 100% rename from site/content/tutorial/13-classes/02-class-shorthand/app-b/App.svelte rename to site/content/tutorial/13-advanced-styling/02-class-shorthand/app-b/App.svelte diff --git a/site/content/tutorial/13-classes/02-class-shorthand/text.md b/site/content/tutorial/13-advanced-styling/02-class-shorthand/text.md similarity index 100% rename from site/content/tutorial/13-classes/02-class-shorthand/text.md rename to site/content/tutorial/13-advanced-styling/02-class-shorthand/text.md diff --git a/site/content/tutorial/13-advanced-styling/03-inline-styles/app-a/App.svelte b/site/content/tutorial/13-advanced-styling/03-inline-styles/app-a/App.svelte new file mode 100644 index 0000000000..b86665ce55 --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/03-inline-styles/app-a/App.svelte @@ -0,0 +1,15 @@ + + + + +

This is a paragraph.

+ + diff --git a/site/content/tutorial/13-advanced-styling/03-inline-styles/app-b/App.svelte b/site/content/tutorial/13-advanced-styling/03-inline-styles/app-b/App.svelte new file mode 100644 index 0000000000..58280f71ad --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/03-inline-styles/app-b/App.svelte @@ -0,0 +1,15 @@ + + + + +

This is a paragraph.

+ + diff --git a/site/content/tutorial/13-advanced-styling/03-inline-styles/text.md b/site/content/tutorial/13-advanced-styling/03-inline-styles/text.md new file mode 100644 index 0000000000..f558958358 --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/03-inline-styles/text.md @@ -0,0 +1,10 @@ +--- +title: Inline styles +--- + +Apart from adding styles inside style tags, you can also add styles to individual elements using the style attribute. Usually you will want to do styling through CSS, but this can come in handy for dynamic styles, especially when combined with CSS custom properties. + +Add the following style attribute to the paragraph element: +`style="color: {color}; --opacity: {bgOpacity};"` + +Great, now you can style the paragraph using variables that change based on your input without having to make a class for every possible value. diff --git a/site/content/tutorial/13-advanced-styling/04-style-directive/app-a/App.svelte b/site/content/tutorial/13-advanced-styling/04-style-directive/app-a/App.svelte new file mode 100644 index 0000000000..58280f71ad --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/04-style-directive/app-a/App.svelte @@ -0,0 +1,15 @@ + + + + +

This is a paragraph.

+ + diff --git a/site/content/tutorial/13-advanced-styling/04-style-directive/app-b/App.svelte b/site/content/tutorial/13-advanced-styling/04-style-directive/app-b/App.svelte new file mode 100644 index 0000000000..aade861b43 --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/04-style-directive/app-b/App.svelte @@ -0,0 +1,15 @@ + + + + +

This is a paragraph.

+ + diff --git a/site/content/tutorial/13-advanced-styling/04-style-directive/text.md b/site/content/tutorial/13-advanced-styling/04-style-directive/text.md new file mode 100644 index 0000000000..88b4e05885 --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/04-style-directive/text.md @@ -0,0 +1,18 @@ +--- +title: The style directive +--- + +Being able to set CSS properties dynamically is nice. However, this can get unwieldy if you have to write a long string. Mistakes like missing any of the semicolons could make the whole string invalid. Therefore, Svelte provides a nicer way to write inline styles with the style directive. + +Change the style attribute of the paragraph to the following: + +```html +

+``` + +The style directive shares a few qualities with the class directive. You can use a shorthand when the name of the property and the variable are the same. So `style:color="{color}"` can be written as just `style:color`. + +Similar to the class directive, the style directive will take precedence if you try to set the same property through a style attribute. diff --git a/site/content/tutorial/13-advanced-styling/meta.json b/site/content/tutorial/13-advanced-styling/meta.json new file mode 100644 index 0000000000..2b76d024e4 --- /dev/null +++ b/site/content/tutorial/13-advanced-styling/meta.json @@ -0,0 +1,3 @@ +{ + "title": "Advanced styling" +} \ No newline at end of file diff --git a/site/content/tutorial/13-classes/meta.json b/site/content/tutorial/13-classes/meta.json deleted file mode 100644 index 9c2b8a41f6..0000000000 --- a/site/content/tutorial/13-classes/meta.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "title": "Classes" -} \ No newline at end of file diff --git a/src/compiler/compile/compiler_errors.ts b/src/compiler/compile/compiler_errors.ts index a04780e375..3099e6cca1 100644 --- a/src/compiler/compile/compiler_errors.ts +++ b/src/compiler/compile/compiler_errors.ts @@ -242,6 +242,10 @@ export default { code: 'invalid-animation', message: 'An element that uses the animate directive must be the immediate child of a keyed each block' }, + invalid_animation_key: { + code: 'invalid-animation', + message: 'An element that uses the animate directive must be used inside a keyed each block. Did you forget to add a key to your each block?' + }, invalid_animation_sole: { code: 'invalid-animation', message: 'An element that uses the animate directive must be the sole child of a keyed each block' diff --git a/src/compiler/compile/nodes/Animation.ts b/src/compiler/compile/nodes/Animation.ts index 507aa1df04..c05a2d8669 100644 --- a/src/compiler/compile/nodes/Animation.ts +++ b/src/compiler/compile/nodes/Animation.ts @@ -26,12 +26,17 @@ export default class Animation extends Node { } const block = parent.parent; - if (!block || block.type !== 'EachBlock' || !block.key) { + if (!block || block.type !== 'EachBlock') { // TODO can we relax the 'immediate child' rule? component.error(this, compiler_errors.invalid_animation_immediate); return; } + if (!block.key) { + component.error(this, compiler_errors.invalid_animation_key); + return; + } + (block as EachBlock).has_animation = true; this.expression = info.expression diff --git a/src/compiler/compile/nodes/EachBlock.ts b/src/compiler/compile/nodes/EachBlock.ts index bb78845dd9..bea6fb7910 100644 --- a/src/compiler/compile/nodes/EachBlock.ts +++ b/src/compiler/compile/nodes/EachBlock.ts @@ -63,7 +63,7 @@ export default class EachBlock extends AbstractBlock { ([this.const_tags, this.children] = get_const_tags(info.children, component, this, this)); if (this.has_animation) { - this.children = this.children.filter(child => !isEmptyNode(child)); + this.children = this.children.filter(child => !isEmptyNode(child) && !isCommentNode(child)); if (this.children.length !== 1) { const child = this.children.find(child => !!(child as Element).animation); @@ -83,3 +83,6 @@ export default class EachBlock extends AbstractBlock { function isEmptyNode(node: INode) { return node.type === 'Text' && node.data.trim() === ''; } +function isCommentNode(node: INode) { + return node.type === 'Comment'; +} diff --git a/src/compiler/compile/nodes/SlotTemplate.ts b/src/compiler/compile/nodes/SlotTemplate.ts index cd18859603..90299c8e39 100644 --- a/src/compiler/compile/nodes/SlotTemplate.ts +++ b/src/compiler/compile/nodes/SlotTemplate.ts @@ -27,10 +27,7 @@ export default class SlotTemplate extends Node { this.validate_slot_template_placement(); - const has_let = info.attributes.some((node) => node.type === 'Let'); - if (has_let) { - scope = scope.child(); - } + scope = scope.child(); info.attributes.forEach((node) => { switch (node.type) { diff --git a/src/compiler/compile/nodes/shared/Expression.ts b/src/compiler/compile/nodes/shared/Expression.ts index 751b739564..a773355e31 100644 --- a/src/compiler/compile/nodes/shared/Expression.ts +++ b/src/compiler/compile/nodes/shared/Expression.ts @@ -90,7 +90,7 @@ export default class Expression { } if (template_scope.is_let(name)) { - if (!function_expression) { // TODO should this be `!lazy` ? + if (!lazy) { contextual_dependencies.add(name); dependencies.add(name); } diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts index 4501771c0a..0ba47f7e86 100644 --- a/src/runtime/internal/dev.ts +++ b/src/runtime/internal/dev.ts @@ -2,7 +2,7 @@ import { custom_event, append, append_hydration, insert, insert_hydration, detac import { SvelteComponent } from './Component'; export function dispatch_dev(type: string, detail?: T) { - document.dispatchEvent(custom_event(type, { version: '__VERSION__', ...detail }, true)); + document.dispatchEvent(custom_event(type, { version: '__VERSION__', ...detail }, { bubbles: true })); } export function append_dev(target: Node, node: Node) { diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 287c16b5fc..e2a7420236 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -634,9 +634,9 @@ export function toggle_class(element, name, toggle) { element.classList[toggle ? 'add' : 'remove'](name); } -export function custom_event(type: string, detail?: T, bubbles: boolean = false) { +export function custom_event(type: string, detail?: T, { bubbles = false, cancelable = false } = {}): CustomEvent { const e: CustomEvent = document.createEvent('CustomEvent'); - e.initCustomEvent(type, bubbles, false, detail); + e.initCustomEvent(type, bubbles, cancelable, detail); return e; } diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 3b3c2f5f71..fbbeca9a67 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -27,22 +27,33 @@ export function onDestroy(fn: () => any) { get_current_component().$$.on_destroy.push(fn); } -export function createEventDispatcher< - EventMap extends {} = any ->(): >(type: EventKey, detail?: EventMap[EventKey]) => void { +export interface DispatchOptions { + cancelable?: boolean; +} + +export function createEventDispatcher(): < + EventKey extends Extract +>( + type: EventKey, + detail?: EventMap[EventKey], + options?: DispatchOptions +) => boolean { const component = get_current_component(); - return (type: string, detail?: any) => { + return (type: string, detail?: any, { cancelable = false } = {}): boolean => { const callbacks = component.$$.callbacks[type]; if (callbacks) { // TODO are there situations where events could be dispatched // in a server (non-DOM) environment? - const event = custom_event(type, detail); + const event = custom_event(type, detail, { cancelable }); callbacks.slice().forEach(fn => { fn.call(component, event); }); + return !event.defaultPrevented; } + + return true; }; } diff --git a/test/runtime/samples/component-slot-let-in-slot-2/Inner.svelte b/test/runtime/samples/component-slot-let-in-slot-2/Inner.svelte new file mode 100644 index 0000000000..d0ea817d54 --- /dev/null +++ b/test/runtime/samples/component-slot-let-in-slot-2/Inner.svelte @@ -0,0 +1 @@ + diff --git a/test/runtime/samples/component-slot-let-in-slot-2/Outer.svelte b/test/runtime/samples/component-slot-let-in-slot-2/Outer.svelte new file mode 100644 index 0000000000..590a70564a --- /dev/null +++ b/test/runtime/samples/component-slot-let-in-slot-2/Outer.svelte @@ -0,0 +1,5 @@ + + + diff --git a/test/runtime/samples/component-slot-let-in-slot-2/_config.js b/test/runtime/samples/component-slot-let-in-slot-2/_config.js new file mode 100644 index 0000000000..96c43497db --- /dev/null +++ b/test/runtime/samples/component-slot-let-in-slot-2/_config.js @@ -0,0 +1,25 @@ +let logs; +function log(value) { + logs.push(value); +} + +export default { + props: { + prop: 'a', + log + }, + html: '', + before_test() { + logs = []; + }, + async test({ assert, component, target, window }) { + const button = target.querySelector('button'); + await button.dispatchEvent(new window.MouseEvent('click')); + + assert.deepEqual(logs, ['a']); + + component.prop = 'b'; + await button.dispatchEvent(new window.MouseEvent('click')); + assert.deepEqual(logs, ['a', 'b']); + } +}; diff --git a/test/runtime/samples/component-slot-let-in-slot-2/main.svelte b/test/runtime/samples/component-slot-let-in-slot-2/main.svelte new file mode 100644 index 0000000000..214b0895ae --- /dev/null +++ b/test/runtime/samples/component-slot-let-in-slot-2/main.svelte @@ -0,0 +1,11 @@ + + + +