From 1e0c10bebcf57b9eca6bb60fe213853c792322df Mon Sep 17 00:00:00 2001 From: josh-brainbox <71662743+josh-brainbox@users.noreply.github.com> Date: Mon, 11 Apr 2022 03:36:17 -0400 Subject: [PATCH 01/11] [docs] fix tutorial/keyed-each-blocks (#7218) --- site/content/tutorial/04-logic/05-keyed-each-blocks/text.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. From e50be669cc73063eb9f66d0c2c4b7d3b61d0488d Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 12 Apr 2022 16:38:08 +0800 Subject: [PATCH 02/11] fix const declared without let: binding get ignored (#7434) --- src/compiler/compile/nodes/SlotTemplate.ts | 5 +--- .../Component.svelte | 2 ++ .../_config.js | 15 ++++++++++++ .../main.svelte | 24 +++++++++++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 test/runtime/samples/const-tag-component-without-let/Component.svelte create mode 100644 test/runtime/samples/const-tag-component-without-let/_config.js create mode 100644 test/runtime/samples/const-tag-component-without-let/main.svelte 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/test/runtime/samples/const-tag-component-without-let/Component.svelte b/test/runtime/samples/const-tag-component-without-let/Component.svelte new file mode 100644 index 0000000000..e9e76f19b9 --- /dev/null +++ b/test/runtime/samples/const-tag-component-without-let/Component.svelte @@ -0,0 +1,2 @@ + + diff --git a/test/runtime/samples/const-tag-component-without-let/_config.js b/test/runtime/samples/const-tag-component-without-let/_config.js new file mode 100644 index 0000000000..047e034ce9 --- /dev/null +++ b/test/runtime/samples/const-tag-component-without-let/_config.js @@ -0,0 +1,15 @@ +export default { + html: ` +
static dynamic
+
static dynamic
+
static dynamic
+ `, + async test({ component, target, assert }) { + component.props = 'xxx'; + assert.htmlEqual(target.innerHTML, ` +
static xxx
+
static xxx
+
static xxx
+ `); + } +}; diff --git a/test/runtime/samples/const-tag-component-without-let/main.svelte b/test/runtime/samples/const-tag-component-without-let/main.svelte new file mode 100644 index 0000000000..9bee015c98 --- /dev/null +++ b/test/runtime/samples/const-tag-component-without-let/main.svelte @@ -0,0 +1,24 @@ + + + + + {@const foo = "static"} + {@const bar = props} +
{foo} {bar}
+
+ + + {@const foo = "static"} + {@const bar = props} +
{foo} {bar}
+
+
+ + + {@const foo = "static"} + {@const bar = props} +
{foo} {bar}
+
From fc19537995c8d2563345a4570e65ec6f08eb872d Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 12 Apr 2022 16:40:34 +0800 Subject: [PATCH 03/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fa6ec5796..2a7b5ee0a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 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) ## 3.47.0 From d9687da63202633845e60e0538b3e075c5636ff8 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 12 Apr 2022 16:48:09 +0800 Subject: [PATCH 04/11] each animate allow having comment siblings (#7435) Co-authored-by: GHOST Co-authored-by: GHOST --- src/compiler/compile/nodes/EachBlock.ts | 5 ++++- .../samples/animation-comment-siblings/errors.json | 1 + .../samples/animation-comment-siblings/input.svelte | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/validator/samples/animation-comment-siblings/errors.json create mode 100644 test/validator/samples/animation-comment-siblings/input.svelte 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/test/validator/samples/animation-comment-siblings/errors.json b/test/validator/samples/animation-comment-siblings/errors.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/test/validator/samples/animation-comment-siblings/errors.json @@ -0,0 +1 @@ +[] diff --git a/test/validator/samples/animation-comment-siblings/input.svelte b/test/validator/samples/animation-comment-siblings/input.svelte new file mode 100644 index 0000000000..1c8170950b --- /dev/null +++ b/test/validator/samples/animation-comment-siblings/input.svelte @@ -0,0 +1,9 @@ + + +{#each things as thing (thing)} + +
+{/each} \ No newline at end of file From f100d96898b4845ebef666c8c887ae6add3b0952 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 12 Apr 2022 16:49:59 +0800 Subject: [PATCH 05/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a7b5ee0a2..947173fd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * 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)) ## 3.47.0 From c371c3fd3c70f35ef5b7e9b65d3539f6ef205767 Mon Sep 17 00:00:00 2001 From: tarunama Date: Tue, 12 Apr 2022 17:57:11 +0900 Subject: [PATCH 06/11] execute `npm audit fix` (#7421) --- package-lock.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) 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" } }, From 0f94c890f5fde899c40f2be05bce8e87579f26f3 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Tue, 12 Apr 2022 22:52:22 +0800 Subject: [PATCH 07/11] [feat] dispatch cancelable custom events (#7064) --- CHANGELOG.md | 1 + site/content/docs/03-run-time.md | 25 +++++++++++++++++++++++-- src/runtime/internal/dev.ts | 2 +- src/runtime/internal/dom.ts | 4 ++-- src/runtime/internal/lifecycle.ts | 21 ++++++++++++++++----- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 947173fd4d..0b2bb5d7fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * 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)) ## 3.47.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/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; }; } From 9276f85768337c8eb4ba91c02a55271f24cb99a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henning=20Gro=C3=9F?= <57948036+henninggross@users.noreply.github.com> Date: Tue, 12 Apr 2022 18:22:11 +0200 Subject: [PATCH 08/11] [feat] improve error message for animate used in a non-keyed each block (#6838) * introdcued new compiler error * making use of newly created compiler error * updated test for animation not in keyed each * removed unneeded conditions --- src/compiler/compile/compiler_errors.ts | 4 ++++ src/compiler/compile/nodes/Animation.ts | 7 ++++++- .../samples/animation-not-in-keyed-each/errors.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) 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/test/validator/samples/animation-not-in-keyed-each/errors.json b/test/validator/samples/animation-not-in-keyed-each/errors.json index 3e0b2d3c0c..a21579ce4f 100644 --- a/test/validator/samples/animation-not-in-keyed-each/errors.json +++ b/test/validator/samples/animation-not-in-keyed-each/errors.json @@ -1,6 +1,6 @@ [{ "code": "invalid-animation", - "message": "An element that uses the animate directive must be the immediate child of a keyed each block", + "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?", "start": { "line": 6, "column": 6, From 39d2dfcbcdbd1bb28748f826635a1617987f7bec Mon Sep 17 00:00:00 2001 From: gtmnayan <50981692+gtm-nayan@users.noreply.github.com> Date: Tue, 12 Apr 2022 23:46:32 +0545 Subject: [PATCH 09/11] [docs] style directive tutorial (#7161) --- .../01-classes/app-a/App.svelte | 0 .../01-classes/app-b/App.svelte | 0 .../01-classes/text.md | 0 .../02-class-shorthand/app-a/App.svelte | 0 .../02-class-shorthand/app-b/App.svelte | 0 .../02-class-shorthand/text.md | 0 .../03-inline-styles/app-a/App.svelte | 15 +++++++++++++++ .../03-inline-styles/app-b/App.svelte | 15 +++++++++++++++ .../03-inline-styles/text.md | 10 ++++++++++ .../04-style-directive/app-a/App.svelte | 15 +++++++++++++++ .../04-style-directive/app-b/App.svelte | 15 +++++++++++++++ .../04-style-directive/text.md | 18 ++++++++++++++++++ .../tutorial/13-advanced-styling/meta.json | 3 +++ site/content/tutorial/13-classes/meta.json | 3 --- 14 files changed, 91 insertions(+), 3 deletions(-) rename site/content/tutorial/{13-classes => 13-advanced-styling}/01-classes/app-a/App.svelte (100%) rename site/content/tutorial/{13-classes => 13-advanced-styling}/01-classes/app-b/App.svelte (100%) rename site/content/tutorial/{13-classes => 13-advanced-styling}/01-classes/text.md (100%) rename site/content/tutorial/{13-classes => 13-advanced-styling}/02-class-shorthand/app-a/App.svelte (100%) rename site/content/tutorial/{13-classes => 13-advanced-styling}/02-class-shorthand/app-b/App.svelte (100%) rename site/content/tutorial/{13-classes => 13-advanced-styling}/02-class-shorthand/text.md (100%) create mode 100644 site/content/tutorial/13-advanced-styling/03-inline-styles/app-a/App.svelte create mode 100644 site/content/tutorial/13-advanced-styling/03-inline-styles/app-b/App.svelte create mode 100644 site/content/tutorial/13-advanced-styling/03-inline-styles/text.md create mode 100644 site/content/tutorial/13-advanced-styling/04-style-directive/app-a/App.svelte create mode 100644 site/content/tutorial/13-advanced-styling/04-style-directive/app-b/App.svelte create mode 100644 site/content/tutorial/13-advanced-styling/04-style-directive/text.md create mode 100644 site/content/tutorial/13-advanced-styling/meta.json delete mode 100644 site/content/tutorial/13-classes/meta.json 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 From 4aff59b08034e1ce10944a7d8946fdd652d89218 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Wed, 13 Apr 2022 23:34:40 +0800 Subject: [PATCH 10/11] [fix] correctly track dependencies of let: bindings (#7448) Fixes #7440 --- CHANGELOG.md | 1 + .../compile/nodes/shared/Expression.ts | 2 +- .../component-slot-let-in-slot-2/Inner.svelte | 1 + .../component-slot-let-in-slot-2/Outer.svelte | 5 ++++ .../component-slot-let-in-slot-2/_config.js | 25 +++++++++++++++++++ .../component-slot-let-in-slot-2/main.svelte | 11 ++++++++ 6 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/component-slot-let-in-slot-2/Inner.svelte create mode 100644 test/runtime/samples/component-slot-let-in-slot-2/Outer.svelte create mode 100644 test/runtime/samples/component-slot-let-in-slot-2/_config.js create mode 100644 test/runtime/samples/component-slot-let-in-slot-2/main.svelte diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b2bb5d7fb..904c927a86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * 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/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/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 @@ + + + +