fs.writeFileSync('src/compile/internal-exports.ts',`// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
fs.writeFileSync('src/compiler/compile/internal_exports.ts',`// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
@ -13,7 +16,11 @@ Start the server with `npm run dev`, and navigate to [localhost:3000](http://loc
## 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). Please note that the local REPL only works with `npm run dev` and not when building the site for production usage.
## REPL GitHub integration
@ -28,6 +35,13 @@ In order for the REPL's GitHub integration to work properly when running locally
GITHUB_CLIENT_SECRET=[your app's Client Secret]
BASEURL=http://localhost:3000
```
## Building the site
To build the website, run `npm run sapper`. The output can be found in `__sapper__/build`.
@ -44,9 +44,11 @@ In the terminal, you can instantly create a new project like so:
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
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:
@ -28,38 +28,60 @@ A `<script>` block contains JavaScript that runs when a component instance is cr
---
Svelte uses the `export` keyword to mark a variable declaration as a *property* or *prop*, which means it becomes accessible to consumers of the component:
Svelte uses the `export` keyword to mark a variable declaration as a *property* or *prop*, which means it becomes accessible to consumers of the component (see the section on [attributes and props](docs#Attributes_and_props) for more information).
```html
<script>
// these properties can be set externally
export let foo;
// Values that are passed in as props
// are immediately available
console.log({ foo });
</script>
```
---
You can specify a default value, which will be used if the component's consumer doesn't specify a prop.
In development mode (see the [compiler options](docs#svelte_compile)), a warning will be printed if no default is provided and the consumer does not specify a value. To squelch this warning, ensure that a default is specified, even if it is `undefined`.
```html
<script>
export let bar = 'optional default value';
export let baz = undefined;
</script>
```
// you can use export { ... as ... } to have
// props whose names are reserved keywords
let clazz;
export { clazz as class };
---
// this property is readonly externally
export const buzz = 'buzz';
If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however.
// Values that are passed in as props
// are immediately available
console.log(foo, bar);
```html
<script>
// these are readonly
export const thisIs = 'readonly';
// function declarations cannot be set externally,
// but can be accessed from outside
export function instanceMethod() {
alert(foo);
export function greet(name) {
alert(`hello ${name}!`);
}
// you can also use export { ... as ... } to have
// methods whose names are reserved keywords
function del() {
do_something();
}
export { del as delete };
// this is a prop
export let format = n => n.toFixed(2);
</script>
```
---
You can use reserved words as prop names.
```html
<script>
let className;
// creates a `class` property, even
// though it is a reserved word
export { className as class };
</script>
```
@ -78,8 +100,8 @@ Because Svelte's reactivity is based on assignments, using array methods like `.
@ -20,7 +20,7 @@ A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag
```
### Attributes
### Attributes and props
---
@ -76,6 +76,16 @@ When the attribute name and value match (`name={name}`), they can be replaced wi
---
By convention, values passed to components are referred to as *properties* or *props* rather than *attributes*, which are a feature of the DOM.
As with elements, `name={name}` can be replaced with the `{name}` shorthand.
```html
<Widgetfoo={bar}answer={42}text="hello"/>
```
---
*Spread attributes* allow many attributes or properties to be passed to an element or component at once.
An element or component can have multiple spread attributes, interspersed with regular ones.
@ -101,27 +111,7 @@ Text can also contain JavaScript expressions:
```
### HTML expressions
```sv
{@html expression}
```
---
In a text expression, characters like `<` and `>` are escaped. With HTML expressions, they're not.
> Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability.
```html
<divclass="blog-post">
<h1>{post.title}</h1>
{@html post.content}
</div>
```
### If blocks
### {#if ...}
```sv
{#if expression}...{/if}
@ -158,7 +148,7 @@ Additional conditions can be added with `{:else if expression}`, optionally endi
```
### Each blocks
### {#each ...}
```sv
{#each expression as name}...{/each}
@ -208,12 +198,20 @@ If a *key* expression is provided — which must uniquely identify each list ite
---
You can freely use destructuring patterns in each blocks.
You can freely use destructuring and rest patterns in each blocks.
@ -283,7 +281,80 @@ If you don't care about the pending state, you can also omit the initial block.
```
### DOM events
### {@html ...}
```sv
{@html expression}
```
---
In a text expression, characters like `<` and `>` are escaped. With HTML expressions, they're not.
> Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability.
```html
<divclass="blog-post">
<h1>{post.title}</h1>
{@html post.content}
</div>
```
### {@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.
### Element directives
As well as attributes, elements can have *directives*, which control the element's behaviour in some way.
#### [on:*eventname*](on_component_event)
```sv
on:eventname={handler}
@ -324,6 +395,13 @@ Handlers can be declared inline with no performance penalty. As with attributes,
Add *modifiers* to DOM events with the `|` character.
```html
<formon:submit|preventDefault={handleSubmit}>
<!-- the `submit` event's default is prevented,
so the page won't reload -->
</form>
```
The following modifiers are available:
* `preventDefault` — calls `event.preventDefault()` before running the handler
@ -334,13 +412,6 @@ The following modifiers are available:
Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
```html
<formon:submit|preventDefault={handleSubmit}>
<!-- the `submit` event's default is prevented,
so the page won't reload -->
</form>
```
---
If the `on:` directive is used without a value, the component will *forward* the event, meaning that a consumer of the component can listen for it.
@ -351,40 +422,30 @@ If the `on:` directive is used without a value, the component will *forward* the
</button>
```
### Component events
```sv
on:eventname={handler}
```
---
Components can emit events using [createEventDispatcher](docs#createEventDispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
It's possible to have multiple event listeners for the same event:
```html
<SomeComponenton:whatever={handler}/>
```
---
<script>
let counter = 0;
function increment() {
counter = counter + 1;
}
As with DOM events, if the `on:` directive is used without a value, the component will *forward* the event, meaning that a consumer of the component can listen for it.
You can bind to component props using the same mechanism.
To get a reference to a DOM node, use `bind:this`.
```html
<Keypadbind:value={pin}/>
```
---
Components also support `bind:this`, allowing you to interact with component instances programmatically.
<script>
import { onMount } from 'svelte';
> Note that we can do `{cart.empty}` rather than `{() => cart.empty()}`, since component methods are closures. You don't need to worry about the value of `this` when calling them.
let canvasElement;
```html
<ShoppingCartbind:this={cart}/>
onMount(() => {
const ctx = canvasElement.getContext('2d');
drawStuff(ctx);
});
</script>
<buttonon:click={cart.empty}>
Empty shopping cart
</button>
<canvasbind:this={canvasElement}></canvas>
```
### Classes
#### class:*name*
```sv
class:name={value}
@ -612,7 +658,7 @@ A `class:` directive provides a shorter way of toggling a class on an element.
```
### Actions
#### use:*action*
```sv
use:action
@ -677,43 +723,19 @@ An action can have parameters. If the returned value has an `update` method, it
A transition is triggered by an element entering or leaving the DOM as a result of a state change. Transitions do not run when a component is first mounted, but only on subsequent updates.
A transition is triggered by an element entering or leaving the DOM as a result of a state change.
Elements inside an *outroing* block are kept in the DOM until all current transitions have completed.
@ -743,21 +765,9 @@ The `transition:` directive indicates a *bidirectional* transition, which means
{/if}
```
---
The `in:` and `out:` directives are not bidirectional. An in transition will continue to 'play' alongside the out transition, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.
```html
{#if visible}
<divin:flyout:fade>
flies in, fades out
</div>
{/if}
```
> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](docs#Client-side_component_API).
#### Transition parameters
##### Transition parameters
---
@ -773,7 +783,7 @@ Like actions, transitions can have parameters.
{/if}
```
#### Custom transition functions
##### Custom transition functions
---
@ -849,7 +859,7 @@ A custom transition function can also return a `tick` function, which is called
If a transition returns a function instead of a transition object, the function will be called in the next microtask. This allows multiple transitions to coordinate, making [crossfade effects](tutorial/deferred-transitions) possible.
#### Transition events
##### Transition events
---
@ -893,7 +903,51 @@ Local transitions only play when the block they belong to is created or destroye
```
### Animations
#### in:*fn*/out:*fn*
```sv
in:fn
```
```sv
in:fn={params}
```
```sv
in:fn|local
```
```sv
in:fn|local={params}
```
```sv
out:fn
```
```sv
out:fn={params}
```
```sv
out:fn|local
```
```sv
out:fn|local={params}
```
---
Similar to `transition:`, but only applies to elements entering (`in:`) or leaving (`out:`) the DOM.
Unlike with `transition:`, transitions applied with `in:` and `out:` are not bidirectional — an in transition will continue to 'play' alongside the out transition, rather than reversing, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.
```html
{#if visible}
<divin:flyout:fade>
flies in, fades out
</div>
{/if}
```
#### animate:
```sv
animate:name
@ -939,7 +993,7 @@ Animations can be used with Svelte's [built-in animation functions](docs#svelte_
{/each}
```
#### Animation Parameters
##### Animation Parameters
---
@ -953,7 +1007,7 @@ As with actions and transitions, animations can have parameters.
{/each}
```
#### Custom animation functions
##### Custom animation functions
---
@ -1027,9 +1081,68 @@ A custom animation function can also return a `tick` function, which is called *
{/each}
```
### Component directives
#### [on:*eventname*](on_component_event)
```sv
on:eventname={handler}
```
---
Components can emit events using [createEventDispatcher](docs#createEventDispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
```html
<SomeComponenton:whatever={handler}/>
```
---
### Slots
As with DOM events, if the `on:` directive is used without a value, the component will *forward* the event, meaning that a consumer of the component can listen for it.
```html
<SomeComponenton:whatever/>
```
#### [bind:*property*](bind_component_property)
```sv
bind:property={variable}
```
---
You can bind to component props using the same mechanism.
```html
<Keypadbind:value={pin}/>
```
#### [bind:this](bind_component)
```sv
bind:this={component_instance}
```
---
Components also support `bind:this`, allowing you to interact with component instances programmatically.
> Note that we can't do `{cart.empty}` since `cart` is `undefined` when the button is first rendered and throws an error.
```html
<ShoppingCartbind:this={cart}/>
<buttonon:click={()=> cart.empty()}>
Empty shopping cart
</button>
```
### `<slot>`
```sv
<slot><!-- optional fallback --></slot>
@ -1061,6 +1174,8 @@ The content is exposed in the child component using the `<slot>` element, which
</div>
```
#### [`<slot name="`*name*`">`](slot_name)
---
Named slots allow consumers to target specific areas. They can also have fallback content.
@ -1080,6 +1195,8 @@ Named slots allow consumers to target specific areas. They can also have fallbac
Slots can be rendered zero or more times, and can pass values *back* to the parent using props. The parent exposes the values to the slot template using the `let:` directive.
@ -1126,7 +1243,7 @@ Named slots can also expose values. The `let:` directive goes on the element wit
```
### <svelte:self>
### `<svelte:self>`
---
@ -1147,10 +1264,10 @@ It cannot appear at the top level of your markup; it must be inside an if or eac
{/if}
```
### <svelte:component>
### `<svelte:component>`
```sv
<svelte:componentthis={expression}>
<svelte:componentthis={expression}/>
```
---
@ -1164,7 +1281,7 @@ If `this` is falsy, no component is rendered.
```
### <svelte:window>
### `<svelte:window>`
```sv
<svelte:windowon:event={handler}/>
@ -1206,7 +1323,7 @@ All except `scrollX` and `scrollY` are readonly.
```
### <svelte:body>
### `<svelte:body>`
```sv
<svelte:bodyon:event={handler}/>
@ -1224,10 +1341,10 @@ As with `<svelte:window>`, this element allows you to add listeners to events on
```
### <svelte:head>
### `<svelte:head>`
```sv
<svelte:head>
<svelte:head>...</svelte:head>
```
---
@ -1241,10 +1358,10 @@ This element makes it possible to insert elements into `document.head`. During s
@ -19,10 +19,10 @@ When building web apps, it's important to make sure that they're *accessible* to
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:
```html
<imgsrc={src}alt="A man dancing">
<imgsrc={src}alt="A man dances.">
```
We can use curly braces *inside* attributes. Try changing it to `"{name} dancing"` — remember to declare a `name` variable in the `<script>` block.
We can use curly braces *inside* attributes. Try changing it to `"{name} dances."` — remember to declare a `name` variable in the `<script>` block.
## Shorthand attributes
@ -30,6 +30,6 @@ We can use curly braces *inside* attributes. Try changing it to `"{name} dancing
It's not uncommon to have an attribute where the name and value are the same, like `src={src}`. Svelte gives us a convenient shorthand for these cases:
You can use similar patterns to replace `pop`, `shift`, `unshift` and `splice`.
> Assignments to *properties* of arrays and objects — e.g. `obj.foo += 1` or `array[i] = x` — work the same way as assignments to the values themselves.
Assignments to *properties* of arrays and objects — e.g. `obj.foo += 1` or `array[i] = x` — work the same way as assignments to the values themselves.
@ -27,7 +27,7 @@ import { pannable } from './pannable.js';
></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:
@ -84,4 +84,3 @@ export function pannable(node) {
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.
<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 699.7,122.7 -3.3,3.3 -3.3,-3.3 c -0.2,-0.2 -0.6,-0.2 -0.8,0 l -3.3,3.3 -3.3,-3.3 c -0.2,-0.2 -0.6,-0.2 -0.8,0 -0.2,0.2 -0.2,0.6 0,0.8 l 3.7,3.7 c 0.2,0.2 0.6,0.2 0.8,0 l 3.3,-3.3 3.3,3.3 c 0.1,0.1 0.3,0.2 0.4,0.2 0.2,0 0.3,-0.1 0.4,-0.2 l 3.7,-3.7 c 0.2,-0.2 0.2,-0.6 0,-0.8 -0.2,-0.2 -0.6,-0.2 -0.8,0 z"
id="path3837"
inkscape:connector-curvature="0" />
<path
class="st6"
d="m 704.2,116.4 c -0.2,-0.2 -0.6,-0.2 -0.8,0 l -3.3,3.3 -3.3,-3.3 c -0.2,-0.2 -0.6,-0.2 -0.8,0 l -3.3,3.3 -3.3,-3.3 c -0.2,-0.2 -0.6,-0.2 -0.8,0 l -3.3,3.3 -3.3,-3.3 c -0.2,-0.2 -0.6,-0.2 -0.8,0 -0.2,0.2 -0.2,0.6 0,0.8 l 3.7,3.7 c 0.2,0.2 0.6,0.2 0.8,0 l 3.3,-3.3 3.3,3.3 c 0.1,0.1 0.3,0.2 0.4,0.2 0.2,0 0.3,-0.1 0.4,-0.2 l 3.3,-3.3 3.3,3.3 c 0.2,0.2 0.6,0.2 0.8,0 l 3.7,-3.7 c 0.2,-0.2 0.2,-0.5 0,-0.8 z"
id="path3839"
inkscape:connector-curvature="0" />
</g>
<circle
class="st16"
cx="5.7272587"
cy="288.69696"
r="1.5874799"
id="circle3843"
style="fill:none;stroke-width:0.26458001" />
</g>
<path
id="path5193"
d="m -2.5511142,295.33257 c -0.189742,-0.14893 -0.428331,-0.23772 -0.68711,-0.23772 -0.6096081,0 -1.105673,0.49172 -1.121304,1.10437 -0.629146,0.23859 -1.077017,0.85253 -1.077017,1.57199 0,0.85015 0.625021,1.55246 1.4356599,1.6634 v 0.0152 h 5.7424231 v -0.003 c 0.800652,-0.0469 1.435659,-0.71837 1.435659,-1.53986 0,-0.79219 -0.590502,-1.44478 -1.350775,-1.53271 0.003,-0.0482 0.0048,-0.097 0.0048,-0.1461 0,-1.22768 -1.024479,-2.22285 -2.28798204,-2.22285 -0.93525196,0 -1.73894386,0.54534 -2.09433096,1.32646"
inkscape:connector-curvature="0"
style="fill:url(#1);stroke-width:0.21709661" />
<path
id="path5195"
d="m 11.002773,295.27147 c 0.252287,-0.1981 0.570045,-0.31578 0.912918,-0.31578 0.809914,0 1.468852,0.6533 1.489735,1.46744 0.836159,0.3172 1.431037,1.13163 1.431037,2.08885 0,1.1288 -0.830233,2.06288 -1.907391,2.20991 v 0.0203 H 5.298379 v -0.004 c -1.063895,-0.0624 -1.907391,-0.9544 -1.907391,-2.04595 0,-1.05261 0.784516,-1.91953 1.794793,-2.03608 -0.0042,-0.0641 -0.0065,-0.12896 -0.0065,-0.19415 0,-1.63112 1.361052,-2.95351 3.040143,-2.95351 1.2428086,0 2.311219,0.72441 2.782776,1.76234"
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"
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}/>`