Merge branch 'master' into pr/5123

pull/5123/head
Conduitry 5 years ago
commit 24187fe97f

@ -1,5 +1,9 @@
# Svelte changelog # Svelte changelog
## Unreleased
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
## 3.24.0 ## 3.24.0
* Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972)) * Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972))

@ -30,7 +30,7 @@ Given that, what if the framework *didn't actually run in the browser*? What if,
Svelte is a new framework that does exactly that. You write your components using HTML, CSS and JavaScript (plus a few extra bits you can [learn in under 5 minutes](https://v2.svelte.dev/guide)), and during your build process Svelte compiles them into tiny standalone JavaScript modules. By statically analysing the component template, we can make sure that the browser does as little work as possible. Svelte is a new framework that does exactly that. You write your components using HTML, CSS and JavaScript (plus a few extra bits you can [learn in under 5 minutes](https://v2.svelte.dev/guide)), and during your build process Svelte compiles them into tiny standalone JavaScript modules. By statically analysing the component template, we can make sure that the browser does as little work as possible.
The [Svelte implementation of TodoMVC](http://svelte-todomvc.surge.sh/) weighs 3.6kb zipped. For comparison, React plus ReactDOM *without any app code* weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC. The [Svelte implementation of TodoMVC](https://svelte-todomvc.surge.sh/) weighs 3.6kb zipped. For comparison, React plus ReactDOM *without any app code* weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
And once your app *is* up and running, according to [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) **Svelte is fast as heck**. It's faster than React. It's faster than Vue. It's faster than Angular, or Ember, or Ractive, or Preact, or Riot, or Mithril. It's competitive with Inferno, which is probably the fastest UI framework in the world, for now, because [Dominic Gannaway](https://twitter.com/trueadm) is a wizard. (Svelte is slower at removing elements. We're [working on it](https://github.com/sveltejs/svelte/issues/26).) And once your app *is* up and running, according to [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) **Svelte is fast as heck**. It's faster than React. It's faster than Vue. It's faster than Angular, or Ember, or Ractive, or Preact, or Riot, or Mithril. It's competitive with Inferno, which is probably the fastest UI framework in the world, for now, because [Dominic Gannaway](https://twitter.com/trueadm) is a wizard. (Svelte is slower at removing elements. We're [working on it](https://github.com/sveltejs/svelte/issues/26).)

@ -74,8 +74,6 @@ This creates a new directory, `my-svelte-project`, adds files from the [sveltejs
In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application — `dev`, `build` and `start`. To launch your app in development mode, type the following: In the `package.json` file, there is a section called `"scripts"`. These scripts define shortcuts for working with your application — `dev`, `build` and `start`. To launch your app in development mode, type the following:
> TODO update the template, it needs... some work
```bash ```bash
npm run dev npm run dev
``` ```

@ -16,16 +16,10 @@
$: remaining = todos.filter(t => !t.done).length; $: remaining = todos.filter(t => !t.done).length;
</script> </script>
<style>
.done {
opacity: 0.4;
}
</style>
<h1>Todos</h1> <h1>Todos</h1>
{#each todos as todo} {#each todos as todo}
<div class:done={todo.done}> <div>
<input <input
type=checkbox type=checkbox
bind:checked={todo.done} bind:checked={todo.done}
@ -34,6 +28,7 @@
<input <input
placeholder="What needs to be done?" placeholder="What needs to be done?"
bind:value={todo.text} bind:value={todo.text}
disabled={todo.done}
> >
</div> </div>
{/each} {/each}

@ -0,0 +1,32 @@
---
question: How do I document my components?
---
In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments.
````svelte
<script>
/** What should we call the user? */
export let name = 'world';
</script>
<!--
@component
Here's some documentation for this component.
It will show up on hover.
- You can use markdown here.
- You can also use code blocks here.
- Usage:
```tsx
<main name="Arethra">
```
-->
<main>
<h1>
Hello, {name}
</h1>
</main>
````
Note: The `@component` is necessary in the HTML comment which describes your component.

@ -7,6 +7,7 @@ import { b, p, x } from 'code-red';
import { sanitize } from '../../../utils/names'; import { sanitize } from '../../../utils/names';
import add_to_set from '../../utils/add_to_set'; import add_to_set from '../../utils/add_to_set';
import get_slot_data from '../../utils/get_slot_data'; import get_slot_data from '../../utils/get_slot_data';
import { is_reserved_keyword } from '../../utils/reserved_keywords';
import Expression from '../../nodes/shared/Expression'; import Expression from '../../nodes/shared/Expression';
import is_dynamic from './shared/is_dynamic'; import is_dynamic from './shared/is_dynamic';
import { Identifier, ObjectExpression } from 'estree'; import { Identifier, ObjectExpression } from 'estree';
@ -94,11 +95,7 @@ export default class SlotWrapper extends Wrapper {
} }
}); });
const dynamic_dependencies = Array.from(attribute.dependencies).filter(name => { const dynamic_dependencies = Array.from(attribute.dependencies).filter((name) => this.is_dependency_dynamic(name));
if (this.node.scope.is_let(name)) return true;
const variable = renderer.component.var_lookup.get(name);
return is_dynamic(variable);
});
if (dynamic_dependencies.length > 0) { if (dynamic_dependencies.length > 0) {
changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`); changes.properties.push(p`${attribute.name}: ${renderer.dirty(dynamic_dependencies)}`);
@ -157,17 +154,10 @@ export default class SlotWrapper extends Wrapper {
b`@transition_out(${slot_or_fallback}, #local);` b`@transition_out(${slot_or_fallback}, #local);`
); );
const is_dependency_dynamic = name => { const dynamic_dependencies = Array.from(this.dependencies).filter((name) => this.is_dependency_dynamic(name));
if (name === '$$scope') return true;
if (this.node.scope.is_let(name)) return true;
const variable = renderer.component.var_lookup.get(name);
return is_dynamic(variable);
};
const dynamic_dependencies = Array.from(this.dependencies).filter(is_dependency_dynamic);
const fallback_dynamic_dependencies = has_fallback const fallback_dynamic_dependencies = has_fallback
? Array.from(this.fallback.dependencies).filter(is_dependency_dynamic) ? Array.from(this.fallback.dependencies).filter((name) => this.is_dependency_dynamic(name))
: []; : [];
const slot_update = b` const slot_update = b`
@ -201,4 +191,12 @@ export default class SlotWrapper extends Wrapper {
b`if (${slot_or_fallback}) ${slot_or_fallback}.d(detaching);` b`if (${slot_or_fallback}) ${slot_or_fallback}.d(detaching);`
); );
} }
is_dependency_dynamic(name: string) {
if (name === '$$scope') return true;
if (this.node.scope.is_let(name)) return true;
if (is_reserved_keyword(name)) return true;
const variable = this.renderer.component.var_lookup.get(name);
return is_dynamic(variable);
}
} }

@ -0,0 +1,21 @@
export default {
html: `
<h1>hi</h1>
<button>Change</button>
`,
async test({ assert, component, target, window }) {
const btn = target.querySelector("button");
const clickEvent = new window.MouseEvent("click");
await btn.dispatchEvent(clickEvent);
assert.htmlEqual(
target.innerHTML,
`
<h1>changed</h1>
<button>Change</button>
`
);
},
};

@ -0,0 +1,13 @@
<script>
import Comp from './Comp.svelte'
let p = "hi"
</script>
<Comp someprop={p} let:props>
<h1>
{props.someprop}
</h1>
</Comp>
<button on:click={()=> p = "changed"}>Change
</button>
Loading…
Cancel
Save