* master: (87 commits)
-> v3.4.3
always add raw property to text nodes
flesh out in/out transition tutorial chapter (#2792)
code style
fix test
fix tests
Fix CRUD example to allow changing input values.
Fixes#2714
treat requestAnimationFrame as a noop on the server
site: actions tutorial: destroy is not required (#2776)
Allow binding of <details> open
site: add /faq redirect to GitHub wiki FAQ
fix case sensitive import name, improve tsconfig
type declarations for bundled files
convert everything to TypeScript
check for unknown props when creating component
cleanup, improve comments
typecheck npm script
workarond for estree-walker related typings conflict
compile/render-dom and other remaining typings
...
# Conflicts:
# src/compile/render-dom/wrappers/Element/index.ts
@ -9,10 +9,19 @@ import pkg from './package.json';
constis_publish=!!process.env.PUBLISH;
constis_publish=!!process.env.PUBLISH;
consttsPlugin=is_publish
?typescript({
include:'src/**',
typescript:require('typescript')
})
:sucrase({
transforms:['typescript']
});
exportdefault[
exportdefault[
/* internal.[m]js */
/* internal.[m]js */
{
{
input:`src/internal/index.js`,
input:`src/internal/index.ts`,
output:[
output:[
{
{
file:`internal.mjs`,
file:`internal.mjs`,
@ -26,19 +35,22 @@ export default [
}
}
],
],
external:id=>id.startsWith('svelte/'),
external:id=>id.startsWith('svelte/'),
plugins:[{
generateBundle(options,bundle){
plugins:[
constmod=bundle['internal.mjs'];
tsPlugin,
if(mod){
{
fs.writeFileSync('src/compile/internal-exports.ts',`// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
generateBundle(options,bundle){
constmod=bundle['internal.mjs'];
if(mod){
fs.writeFileSync('src/compile/internal-exports.ts',`// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
@ -13,7 +13,11 @@ Start the server with `npm run dev`, and navigate to [localhost:3000](http://loc
## Using a local copy of Svelte
## Using a local copy of Svelte
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. To use the local copy of the compiler and runtime from this repo, you can navigate to [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). To produce the proper browser-compatible UMD build, you will need to run `npm run build` with the `PUBLISH` environment variable set (to any non-empty string).
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. When running the site locally, you can also use your local copy of Svelte.
To produce the proper browser-compatible UMD build of the compiler, you will need to run `npm run build` (or `npm run dev`) in the root of this repository with the `PUBLISH` environment variable set to any non-empty string.
Then visit the REPL at [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local).
@ -44,9 +44,11 @@ In the terminal, you can instantly create a new project like so:
npx degit sveltejs/template my-svelte-project
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
cd my-svelte-project
npm install
npm install
npm run dev& open http://localhost:5000
npm run dev
```
```
This will create a new project in the `my-svelte-project` directory, install its dependencies, and start a server on http://localhost:5000.
Once you've tinkered a bit and understood how everything fits together, you can fork [sveltejs/template](https://github.com/sveltejs/template) and start doing this instead:
Once you've tinkered a bit and understood how everything fits together, you can fork [sveltejs/template](https://github.com/sveltejs/template) and start doing this instead:
@ -48,10 +48,13 @@ Svelte uses the `export` keyword to mark a variable declaration as a *property*
// are immediately available
// are immediately available
console.log(foo, bar);
console.log(foo, bar);
// function declarations cannot be set externally,
// Function expressions can also be props
// but can be accessed from outside
export let format = (number) => (number.toFixed(2));
export function instanceMethod() {
alert(foo);
// Function declarations are added as methods
// on the component, rather than props
export function greetMethod() {
alert(`I'm a <${this.constructor.name}>!`);
}
}
// you can also use export { ... as ... } to have
// you can also use export { ... as ... } to have
@ -89,7 +92,7 @@ Because Svelte's reactivity is based on assignments, using array methods like `.
---
---
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:` label. Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:`[JS label syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.
An animation is triggered when the contents of a [keyed each block](docs#Each_blocks) are re-ordered. Animations do not run when an element is removed, only when the each block's data is reordered. Animate directives must be on an element that is an *immediate* child of a keyed each block.
Animations can be used with Svelte's [built-in animation functions](docs#svelte_animate) or [custom animation functions](docs#Custom_animation_functions).
```html
<!-- When `list` is reordered the animation will run-->
{#each list as item, index (item)}
<lianimate:flip>{item}</li>
{/each}
```
#### Animation Parameters
---
As with actions and transitions, animations can have parameters.
(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)
```html
{#each list as item, index (item)}
<lianimate:flip="{{ delay: 500 }}">{item}</li>
{/each}
```
#### Custom animation functions
---
Animations can use custom functions that provide the `node`, an `animation` object and any `paramaters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.
If the returned object has a `css` method, Svelte will create a CSS animation that plays on the element.
The `t` argument passed to `css` is a value that goes from `0` and `1` after the `easing` function has been applied. The `u` argument is equal to `1 - t`.
The function is called repeatedly *before* the animation begins, with different `t` and `u` arguments.
A custom animation function can also return a `tick` function, which is called *during* the animation with the same `t` and `u` arguments.
> If it's possible to use `css` instead of `tick`, do so — CSS animations can run off the main thread, preventing jank on slower devices.
```html
<script>
import { cubicOut } from 'svelte/easing';
function whizz(node, { from, to }, params) {
const dx = from.left - to.left;
const dy = from.top - to.top;
const d = Math.sqrt(dx * dx + dy * dy);
return {
delay: 0,
duration: Math.sqrt(d) * 120,
easing: cubicOut,
tick: (t, u) =>
Object.assign(node.style, {
color: t > 0.5 ? 'Pink' : 'Blue'
});
};
}
</script>
{#each list as item, index (item)}
<divanimate:whizz>{item}</div>
{/each}
```
### Slots
### Slots
@ -1130,3 +1279,50 @@ The `<svelte:options>` element provides a place to specify per-component compile
```html
```html
<svelte:optionstag="my-custom-element"/>
<svelte:optionstag="my-custom-element"/>
```
```
### @debug
```sv
{@debug}
```
```sv
{@debug var1, var2, ..., varN}
```
---
The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.
It accepts a comma-separated list of variable names (not arbitrary expressions).
```html
<script>
let user = {
firstname: 'Ada',
lastname: 'Lovelace'
};
</script>
{@debug user}
<h1>Hello {user.firstname}!</h1>
```
---
`{@debug ...}` accepts a comma-separated list of variable names (not arbitrary expressions).
```html
<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}
<!-- WON'T compile -->
{@debug user.firstname}
{@debug myArray[0]}
{@debug !isReady}
{@debug typeof user === 'object'}
```
The `{@debug}` tag without any arguments will insert a `debugger` statement that gets triggered when *any* state changes, as opposed to the specified variables.
In both cases, an array of arguments can be passed as the first argument instead of a single store.
In both cases, an array of arguments can be passed as the first argument instead of a single store.
@ -503,10 +517,204 @@ Both `set` and `update` can take a second argument — an object with `hard` or
### `svelte/transition`
### `svelte/transition`
TODO
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
#### `fade`
```sv
transition:fade={params}
```
```sv
in:fade={params}
```
```sv
out:fade={params}
```
---
Animates the opacity of an element from 0 to the current opacity for `in` transitions and from the current opacity to 0 for `out` transitions.
`fade` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
You can see the `fade` transition in action in the [transition tutorial](tutorial/transition).
Animates the x and y positions and the opacity of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
`fly` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `x` (`number`, default 0) - the x offset to animate out to and in from
* `y` (`number`, default 0) - the y offset to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
You can see the `fly` transition in action in the [transition tutorial](tutorial/adding-parameters-to-transitions).
Animates the opacity and scale of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
`scale` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `start` (`number`, default 0) - the scale value to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
Animates the stroke of an SVG element, like a snake in a tube. `in` transitions begin with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erase the path. `draw` only works with elements that have a `getTotalLength` method, like `<path>` and `<polyline>`.
`scale` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `speed` (`number`, default undefined) - the speed of the animation, see below.
* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is modifier that is applied to the length of the path: `duration = length / speed`. A path that is 1000 pixels with a speed of 1 will have a duration of `1000ms`, setting the speed to `0.5` will halve that duration and setting it to `2` will double it.
@ -16,7 +16,7 @@ That's better. But Svelte is giving us a warning:
When building web apps, it's important to make sure that they're *accessible* to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup.
When building web apps, it's important to make sure that they're *accessible* to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup.
In this case, we're missing the `alt`tag that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
In this case, we're missing the `alt`attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
As a general rule, data flow in Svelte is *top down* — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around.
As a general rule, data flow in Svelte is *top down* — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around.
Sometimes it's useful to break that rule. Take the case of the `<input>` element in this component — we *could* add an `on:input` event handler that set the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other kinds of form element, as we'll see.
Sometimes it's useful to break that rule. Take the case of the `<input>` element in this component — we *could* add an `on:input` event handler that set the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other form elements, as we'll see.
@ -27,7 +27,7 @@ import { pannable } from './pannable.js';
></div>
></div>
```
```
Open the `pannable.js` file. Like transition functions, an action function receives a `node` and some optional parameters, and returns an action object. That object must have a `destroy` function, which is called when the element is unmounted.
Open the `pannable.js` file. Like transition functions, an action function receives a `node` and some optional parameters, and returns an action object. That object can have a `destroy` function, which is called when the element is unmounted.
We want to fire `panstart` event when the user mouses down on the element, `panmove` events (with `dx` and `dy` properties showing how far the mouse moved) when they drag it, and `panend` events when they mouse up. One possible implementation looks like this:
We want to fire `panstart` event when the user mouses down on the element, `panmove` events (with `dx` and `dy` properties showing how far the mouse moved) when they drag it, and `panend` events when they mouse up. One possible implementation looks like this:
@ -84,4 +84,3 @@ export function pannable(node) {
Update the `pannable` function and try moving the box around.
Update the `pannable` function and try moving the box around.
> This implementation is for demonstration purposes — a more complete one would also consider touch events.
> This implementation is for demonstration purposes — a more complete one would also consider touch events.
<atarget="_blank"rel="noopener"href="https://github.com/sveltejs/svelte/blob/master/site/src/routes/_components/WhosUsingSvelte.svelte"class="add-yourself"><span>+ your company?</span></a>
<atarget="_blank"rel="noopener"href="https://github.com/sveltejs/svelte/blob/master/site/src/routes/_components/WhosUsingSvelte.svelte"class="add-yourself"><span>+ your company?</span></a>
d="m -814.90625,747.83984 v 0.0137 h -15.81836 v 97.19726 c 0,12.68484 4.7555,17.75977 17.91602,17.75977 h 23.62695 c 13.16052,0 17.91601,-5.07493 17.91602,-17.75977 v -97.19726 h -16.49805 v -0.0137 l -11.50586,40.55664 h 19.56055 l -29.33985,55.51563 7.76758,-41.70899 h -16.9707 l 14.60742,-54.36328 z"
d="m 454.281,769.98869 c 1.92,0 2.496,0.96 2.496,2.688 v 84.864 c 0,2.112 -0.384,2.88 -2.688,2.88 h -13.056 v -90.432 z m 30.144,-7.488 c 0,-10.176 -5.568,-16.896 -16.512,-16.896 h -54.528 v 139.2 h 49.344 c 15.936,0 21.696,-6.144 21.696,-21.504 z"
d="m 605.982,769.98869 c 1.92,0 2.688,1.152 2.688,2.88 v 42.24 c 0,2.112 -0.576,2.88 -2.688,2.88 H 592.35 v -48 z m 30.144,-6.336 c 0,-10.944 -5.76,-18.048 -18.816,-18.048 h -52.8 v 139.2 h 27.84 v -44.352 h 3.648 l 13.44,44.352 h 28.8 l -14.592,-44.352 c 8.064,0 12.48,-6.144 12.48,-12.288 z"
d="m 689.031,769.98869 c 1.92,0 2.496,0.96 2.496,2.688 v 84.864 c 0,2.112 -0.384,2.88 -2.688,2.88 h -13.056 v -90.432 z m 30.144,-7.488 c 0,-10.176 -5.568,-16.896 -16.512,-16.896 h -54.528 v 139.2 h 49.344 c 15.936,0 21.696,-6.144 21.696,-21.504 z"
d="m 772.107,769.98869 c 1.92,0 2.496,0.96 2.496,2.688 v 84.864 c 0,2.112 -0.384,2.88 -2.688,2.88 h -10.56 c -2.304,0 -2.688,-0.768 -2.688,-2.88 v -84.864 c 0,-1.728 0.576,-2.688 2.496,-2.688 z m 30.72,-6.336 c 0,-10.944 -5.76,-18.048 -18.816,-18.048 h -34.56 c -13.056,0 -18.816,7.104 -18.816,18.048 v 101.376 c 0,10.56 4.416,19.776 19.968,19.776 h 32.256 c 15.552,0 19.968,-9.216 19.968,-19.776 z"
thrownewError(`Cannot compile to a custom element without specifying a tag name via options.tag or <svelte:options>`);
this.warn(svelteOptions,{
code:'custom-element-no-tag',
message:`No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>`