pull/8524/head
Puru Vijay 1 year ago
parent 45f2890261
commit 1e9e843ca5

@ -4,6 +4,9 @@
* Handle `width`/`height` attributes when spreading ([#6752](https://github.com/sveltejs/svelte/issues/6752))
* Add support for resize observer bindings (`<div bind:contentRect|contentBoxSize|borderBoxSize|devicePixelContentBoxSize>`) ([#8022](https://github.com/sveltejs/svelte/pull/8022))
* Update interpolated style directive properly when using spread ([#8438](https://github.com/sveltejs/svelte/issues/8438))
* Remove style directive property when value is `undefined` ([#8462](https://github.com/sveltejs/svelte/issues/8462))
* Ensure version is typed as `string` instead of the literal `__VERSION__` ([#8498](https://github.com/sveltejs/svelte/issues/8498))
## 3.58.0

@ -36,7 +36,9 @@ Svelte uses the `export` keyword to mark a variable declaration as a _property_
</script>
```
You can specify a default initial value for a prop. It will be used if the component's consumer doesn't specify the prop on the component (or if its initial value is `undefined`) when instantiating the component. Note that whenever a prop is removed by the consumer, its value is set to `undefined` rather than the initial value.
---
You can specify a default initial value for a prop. It will be used if the component's consumer doesn't specify the prop on the component (or if its initial value is `undefined`) when instantiating the component. Note that if the values of props are subsequently updated, then any prop whose value is not specified will be set to `undefined` (rather than its initial value).
In development mode (see the [compiler options](/docs/svelte-compiler#svelte-compile)), a warning will be printed if no default initial value is provided and the consumer does not specify a value. To squelch this warning, ensure that a default initial value is specified, even if it is `undefined`.

@ -1240,19 +1240,27 @@ export default class ElementWrapper extends Wrapper {
block.chunks.hydrate.push(updater);
const self_deps = expression.dynamic_dependencies();
const all_deps = new Set([
...self_deps,
...this.dynamic_style_dependencies
]);
let condition = block.renderer.dirty([...all_deps]);
// Assume that style has changed through the spread attribute
if (has_spread) {
if (should_cache && all_deps.size) {
// Update the cached value
block.chunks.update.push(b`
if (${condition}) {
${cached_snippet} = ${snippet};
}`
);
}
block.chunks.update.push(updater);
} else {
const self_deps = expression.dynamic_dependencies();
const all_deps = new Set([
...self_deps,
...this.dynamic_style_dependencies
]);
if (all_deps.size === 0) return;
let condition = block.renderer.dirty([...all_deps]);
if (all_deps.size === 0) return;
if (should_cache) {
condition = x`${condition} && ${cached_snippet} !== (${cached_snippet} = ${snippet})`;

@ -3,5 +3,5 @@ export { default as parse } from './parse/index';
export { default as preprocess } from './preprocess/index';
export { walk } from 'estree-walker';
export const VERSION = '__VERSION__';
export const VERSION: string = '__VERSION__';
// additional exports added through generate-type-definitions.js

@ -307,7 +307,7 @@ export function attr(node: Element, attribute: string, value?: string) {
else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value);
}
/**
/**
* List of attributes that should always be set through the attr method,
* because updating them through the property setter doesn't work reliably.
* In the example of `width`/`height`, the problem is that the setter only
@ -641,7 +641,7 @@ export function set_input_type(input, type) {
}
export function set_style(node, key, value, important) {
if (value === null) {
if (value == null) {
node.style.removeProperty(key);
} else {
node.style.setProperty(key, value, important ? 'important' : '');

@ -12,8 +12,15 @@ export type Updater<T> = (value: T) => T;
/** Cleanup logic callback. */
type Invalidator<T> = (value?: T) => void;
/** Start and stop notification callbacks. */
export type StartStopNotifier<T> = (set: Subscriber<T>) => Unsubscriber | void;
/**
* Start and stop notification callbacks.
* This function is called when the first subscriber subscribes.
*
* @param {(value: T) => void} set Function that sets the value of the store.
* @returns {void | (() => void)} Optionally, a cleanup function that is called when the last remaining
* subscriber unsubscribes.
*/
export type StartStopNotifier<T> = (set: (value: T) => void) => void | (() => void);
/** Readable interface for subscribing. */
export interface Readable<T> {
@ -48,7 +55,7 @@ const subscriber_queue = [];
/**
* Creates a `Readable` store that allows reading by subscription.
* @param value initial value
* @param {StartStopNotifier}start start and stop notifications for subscriptions
* @param {StartStopNotifier} [start]
*/
export function readable<T>(value?: T, start?: StartStopNotifier<T>): Readable<T> {
return {
@ -59,7 +66,7 @@ export function readable<T>(value?: T, start?: StartStopNotifier<T>): Readable<T
/**
* Create a `Writable` store that allows both updating and reading by subscription.
* @param {*=}value initial value
* @param {StartStopNotifier=}start start and stop notifications for subscriptions
* @param {StartStopNotifier=} start
*/
export function writable<T>(value?: T, start: StartStopNotifier<T> = noop): Writable<T> {
let stop: Unsubscriber;

@ -0,0 +1,18 @@
export default {
html: `
<div style="background-color: rgb(255, 0, 0);"></div>
`,
test({ assert, target, window, component }) {
const div = target.querySelector('div');
const styles = window.getComputedStyle(div);
assert.equal(styles.backgroundColor, 'rgb(255, 0, 0)');
{
component.backgroundColor = 128;
const div = target.querySelector('div');
const styles = window.getComputedStyle(div);
assert.equal(styles.backgroundColor, 'rgb(128, 0, 0)');
}
}
};

@ -0,0 +1,5 @@
<script lang="ts">
export let backgroundColor = 255;
</script>
<div style:background-color="rgb({backgroundColor}, 0, 0)" {...$$restProps} />

@ -0,0 +1,11 @@
export default {
async test({ assert, target, window }) {
const div = target.querySelector('div');
const click = new window.MouseEvent('click');
assert.htmlEqual(target.innerHTML, '<div style="background: red;"></div>');
await div.dispatchEvent(click);
await Promise.resolve();
assert.htmlEqual(target.innerHTML, '<div style=""></div>');
}
};

@ -0,0 +1,9 @@
<script>
let bg = "red";
const handle = () => {
bg = undefined;
};
</script>
<div style:background={bg} on:click={handle}></div>
Loading…
Cancel
Save