Merge branch 'master' into pr/4295

pull/4295/head
Conduitry 5 years ago
commit 8e6e5fdb06

@ -2,7 +2,9 @@
**/expected.js
_output
test/*/samples/*/output.js
node_modules
# automatically generated
internal_exports.ts
# output files
animate/*.js

@ -1,65 +1,6 @@
module.exports = {
root: true,
rules: {
indent: 'off',
'no-unused-vars': 'off',
semi: [2, 'always'],
'keyword-spacing': [2, { before: true, after: true }],
'space-before-blocks': [2, 'always'],
'no-mixed-spaces-and-tabs': [2, 'smart-tabs'],
'no-cond-assign': 0,
'object-shorthand': [2, 'always'],
'no-const-assign': 2,
'no-class-assign': 2,
'no-this-before-super': 2,
'no-var': 2,
'no-unreachable': 2,
'valid-typeof': 2,
'quote-props': [2, 'as-needed'],
'one-var': [2, 'never'],
'prefer-arrow-callback': 2,
'prefer-const': [2, { destructuring: 'all' }],
'arrow-spacing': 2,
'no-inner-declarations': 0,
'require-atomic-updates': 'off',
'@typescript-eslint/indent': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/array-type': ['error', 'array-simple'],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_'
}
],
'@typescript-eslint/no-object-literal-type-assertion': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/prefer-interface': 'off'
},
globals: {
globalThis: false
},
env: {
es6: true,
browser: true,
node: true,
mocha: true
},
extends: [
'eslint:recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
'plugin:@typescript-eslint/recommended'
],
parserOptions: {
ecmaVersion: 9,
sourceType: 'module'
},
plugins: ['svelte3'],
extends: '@sveltejs',
settings: {
'import/core-modules': [
'svelte',
@ -69,20 +10,5 @@ module.exports = {
'estree'
],
'svelte3/compiler': require('./compiler')
},
overrides: [
{
files: ['*.js'],
rules: {
'@typescript-eslint/no-var-requires': 'off'
}
},
{
files: ['*.svelte'],
processor: 'svelte3/svelte3',
rules: {
'@typescript-eslint/indent': 'off'
}
}
]
}
};

@ -8,10 +8,13 @@ the issue. One way we prioritize issues is by the number of :+1: reactions on
their descriptions. Please DO NOT add `+1` or :+1: comments.
### Feature requests and proposals
We're excited to hear how we can make Svelte better. Please add as much detail
as you can on your use case.
as you can on your use case. To propose an implementation of a large feature or
change, please create an [RFC](https://github.com/sveltejs/rfcs).
### Bugs
If you're filing an issue about a bug please include as much information
as you can including the following.

@ -7,6 +7,11 @@ assignees: ''
---
<!--
If you'd like to propose an implementation for a large new feature or change then please create an RFC:
https://github.com/sveltejs/rfcs
-->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. For example: I'm always frustrated when [...]

@ -1,8 +1,7 @@
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR relates to an outstanding issue, so please reference it in your PR, or create an explanatory one for discussion. In many cases features are absent for a reason.
- [ ] This message body should clearly illustrate what problems it solves. If there are related issues, remember to reference them.
- [ ] Ideally, include a test that fails without this PR but passes with it. PRs will only be merged once they pass CI. (Remember to `npm run lint`!)
- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.
### Tests
- [ ] Run the tests tests with `npm test` or `yarn test`)
- [ ] Run the tests with `npm test` and lint the project with `npm run lint`

@ -3,12 +3,12 @@ on: [push, pull_request]
jobs:
Tests:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
matrix:
node-version: [8, 10, 12]
node-version: [8, 10, 12, 14]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
@ -19,7 +19,18 @@ jobs:
CI: true
Lint:
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: 'npm i && npm run lint'
Unit:
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: 'npm i && npm run test:unit'

1
.gitignore vendored

@ -1,6 +1,7 @@
.idea
.DS_Store
.nyc_output
.vscode
node_modules
*.map
/src/compiler/compile/internal_exports.ts

@ -0,0 +1,14 @@
module.exports = {
file: [
'test/test.ts'
],
require: [
'sucrase/register'
]
};
// add coverage options when running 'npx c8 mocha'
if (process.env.NODE_V8_COVERAGE) {
module.exports.fullTrace = true;
module.exports.require.push('source-map-support/register');
}

@ -1,3 +0,0 @@
useTabs: true
singleQuote: true
trailingComma: es5

@ -2,8 +2,231 @@
## Unreleased
* Add `EventSource` to known globals ([#5463](https://github.com/sveltejs/svelte/issues/5463))
* Fix compiler exception with `~`/`+` combinators and `{...spread}` attributes ([#5465](https://github.com/sveltejs/svelte/issues/5465))
## 3.28.0
* Add `{#key}` block for keying arbitrary content on an expression ([#1469](https://github.com/sveltejs/svelte/issues/1469))
## 3.27.0
* Add `|nonpassive` event modifier, explicitly passing `passive: false` ([#2068](https://github.com/sveltejs/svelte/issues/2068))
* Scope CSS selectors with `~` and `+` combinators ([#3104](https://github.com/sveltejs/svelte/issues/3104))
* Fix keyed `{#each}` not reacting to key changing ([#5444](https://github.com/sveltejs/svelte/issues/5444))
* Fix destructuring into store values ([#5449](https://github.com/sveltejs/svelte/issues/5449))
* Fix erroneous `missing-declaration` warning with `use:obj.method` ([#5451](https://github.com/sveltejs/svelte/issues/5451))
## 3.26.0
* Support `use:obj.method` as actions ([#3935](https://github.com/sveltejs/svelte/issues/3935))
* Support `_` as numeric separator ([#5407](https://github.com/sveltejs/svelte/issues/5407))
* Fix assignments to properties on store values ([#5412](https://github.com/sveltejs/svelte/issues/5412))
* Add special style scoping handling of `[open]` selectors on `<details>` elements ([#5421](https://github.com/sveltejs/svelte/issues/5421))
* Support `import.meta` in template expressions ([#5422](https://github.com/sveltejs/svelte/issues/5422))
## 3.25.1
* Fix specificity of certain styles involving a child selector ([#4795](https://github.com/sveltejs/svelte/issues/4795))
* Fix transitions that are parameterised with stores ([#5244](https://github.com/sveltejs/svelte/issues/5244))
* Fix scoping of styles involving child selector and `*` ([#5370](https://github.com/sveltejs/svelte/issues/5370))
* Fix destructuring which reassigns stores ([#5388](https://github.com/sveltejs/svelte/issues/5388))
* Fix `{#await}`s with no `{:catch}` getting stuck unresolved if the promise rejects ([#5401](https://github.com/sveltejs/svelte/issues/5401))
## 3.25.0
* Use `null` rather than `undefined` for coerced bound value of `<input type="number">` ([#1701](https://github.com/sveltejs/svelte/issues/1701))
* Expose object of which slots have received content in `$$slots` ([#2106](https://github.com/sveltejs/svelte/issues/2106))
* Correctly disallow using lifecycle hooks after synchronous component initialisation ([#4259](https://github.com/sveltejs/svelte/issues/4259), [#4899](https://github.com/sveltejs/svelte/issues/4899))
* Re-throw an unhandled rejection when an `{#await}` block with no `{:catch}` gets a rejection ([#5129](https://github.com/sveltejs/svelte/issues/5129))
* Add types to `createEventDispatcher` ([#5211](https://github.com/sveltejs/svelte/issues/5211))
* In SSR mode, do not automatically declare variables for reactive assignments to member expressions ([#5247](https://github.com/sveltejs/svelte/issues/5247))
* Include selector in message of `unused-css-selector` warning ([#5252](https://github.com/sveltejs/svelte/issues/5252))
* Fix using `<Namespaced.Component/>`s in child `{#await}`/`{#each}` contexts ([#5255](https://github.com/sveltejs/svelte/issues/5255))
* Fix using `<svelte:component>` in `{:catch}` ([#5259](https://github.com/sveltejs/svelte/issues/5259))
* Fix setting one-way bound `<input>` `value` to `undefined` when it has spread attributes ([#5270](https://github.com/sveltejs/svelte/issues/5270))
* Fix deep two-way bindings inside an `{#each}` involving a store ([#5286](https://github.com/sveltejs/svelte/issues/5286))
* Use valid XHTML for elements that are optimised and inserted with `.innerHTML` ([#5315](https://github.com/sveltejs/svelte/issues/5315))
* Fix reactivity of `$$props` in slot fallback content ([#5367](https://github.com/sveltejs/svelte/issues/5367))
## 3.24.1
* Prevent duplicate invalidation with certain two-way component bindings ([#3180](https://github.com/sveltejs/svelte/issues/3180), [#5117](https://github.com/sveltejs/svelte/issues/5117), [#5144](https://github.com/sveltejs/svelte/issues/5144))
* Fix reactivity when passing `$$props` to a `<slot>` ([#3364](https://github.com/sveltejs/svelte/issues/3364))
* Fix transitions on `{#each}` `{:else}` ([#4970](https://github.com/sveltejs/svelte/issues/4970))
* Fix unneeded invalidation of `$$props` and `$$restProps` ([#4993](https://github.com/sveltejs/svelte/issues/4993), [#5118](https://github.com/sveltejs/svelte/issues/5118))
* Provide better compiler error message when mismatched tags are due to autoclosing of tags ([#5049](https://github.com/sveltejs/svelte/issues/5049))
* Add `a11y-label-has-associated-control` warning ([#5074](https://github.com/sveltejs/svelte/pull/5074))
* Add `a11y-media-has-caption` warning ([#5075](https://github.com/sveltejs/svelte/pull/5075))
* Fix `bind:group` when using contextual reference ([#5174](https://github.com/sveltejs/svelte/issues/5174))
## 3.24.0
* Support nullish coalescing (`??`) and optional chaining (`?.`) operators ([#1972](https://github.com/sveltejs/svelte/issues/1972))
* Support `import.meta` ([#4379](https://github.com/sveltejs/svelte/issues/4379))
* Fix only setting `<input>` values when they're changed when there are spread attributes ([#4418](https://github.com/sveltejs/svelte/issues/4418))
* Fix placement of `{@html}` when used at the root of a slot, at the root of a component, or in `<svelte:head>` ([#5012](https://github.com/sveltejs/svelte/issues/5012), [#5071](https://github.com/sveltejs/svelte/pull/5071))
* Fix certain handling of two-way bound `contenteditable` elements ([#5018](https://github.com/sveltejs/svelte/issues/5018))
* Fix handling of `import`ed value that is used as a store and is also mutated ([#5019](https://github.com/sveltejs/svelte/issues/5019))
* Do not display `a11y-missing-content` warning on elements with `contenteditable` bindings ([#5020](https://github.com/sveltejs/svelte/issues/5020))
* Fix handling of `this` in inline function expressions in the template ([#5033](https://github.com/sveltejs/svelte/issues/5033))
* Fix collapsing HTML with static content ([#5040](https://github.com/sveltejs/svelte/issues/5040))
* Prevent use of `$store` at compile time when top-level `store` has been shadowed ([#5048](https://github.com/sveltejs/svelte/issues/5048))
* Update `<select>` with one-way `value` binding when the available `<option>`s change ([#5051](https://github.com/sveltejs/svelte/issues/5051))
* Fix published `tweened` types so the `.set()` and `.update()` options are optional ([#5062](https://github.com/sveltejs/svelte/issues/5062))
* Fix contextual `bind:this` inside `{#each}` block ([#5067](https://github.com/sveltejs/svelte/issues/5067))
* Preprocess self-closing `<script>` and `<style>` tags ([#5080](https://github.com/sveltejs/svelte/issues/5080))
* Fix types for animation- and transition-related param objects so each param is optional ([#5083](https://github.com/sveltejs/svelte/pull/5083))
## 3.23.2
* Fix `bind:group` inside `{#each}` ([#3243](https://github.com/sveltejs/svelte/issues/3243))
* Don't crash when using an arrow function as a statement ([#4617](https://github.com/sveltejs/svelte/issues/4617))
* Deconflict `bind:this` variable ([#4636](https://github.com/sveltejs/svelte/issues/4636))
## 3.23.1
* Fix checkbox `bind:group` when multiple options have the same value ([#4397](https://github.com/sveltejs/svelte/issues/4397))
* Fix `bind:this` to the value of an `{#each}` block ([#4517](https://github.com/sveltejs/svelte/issues/4517))
* Fix reactivity when assigning to contextual `{#each}` variable ([#4574](https://github.com/sveltejs/svelte/issues/4574), [#4744](https://github.com/sveltejs/svelte/issues/4744))
* Fix binding to contextual `{#each}` values that shadow outer names ([#4757](https://github.com/sveltejs/svelte/issues/4757))
* Work around EdgeHTML DOM issue when removing attributes during hydration ([#4911](https://github.com/sveltejs/svelte/pull/4911))
* Throw CSS parser error when `:global()` does not contain a selector ([#4930](https://github.com/sveltejs/svelte/issues/4930))
## 3.23.0
* Update `<select>` with `bind:value` when the available `<option>`s change ([#1764](https://github.com/sveltejs/svelte/issues/1764))
* Add `muted` binding for media elements ([#2998](https://github.com/sveltejs/svelte/issues/2998))
* Fix inconsistencies when setting a two-way bound `<input>` to `undefined` ([#3569](https://github.com/sveltejs/svelte/issues/3569))
* Fix setting `<select multiple>` when there are spread attributes ([#4392](https://github.com/sveltejs/svelte/issues/4392))
* Fix let-less `<slot>` with context overflow ([#4624](https://github.com/sveltejs/svelte/issues/4624))
* Fix resize listening on certain older browsers ([#4752](https://github.com/sveltejs/svelte/issues/4752))
* Add `a11y-no-onchange` warning ([#4788](https://github.com/sveltejs/svelte/pull/4788))
* Fix `use:` actions being recreated when a keyed `{#each}` is reordered ([#4693](https://github.com/sveltejs/svelte/issues/4693))
* Fix `{@html}` when using tags that can only appear inside certain tags ([#4852](https://github.com/sveltejs/svelte/issues/4852))
* Fix reactivity when binding directly to `{#each}` context ([#4879](https://github.com/sveltejs/svelte/issues/4879))
## 3.22.3
* Support default values and trailing commas in destructuring `{#await}` ([#4560](https://github.com/sveltejs/svelte/issues/4560), [#4810](https://github.com/sveltejs/svelte/issues/4810))
* Fix handling of `tweened` store when set using `duration: 0` ([#4799](https://github.com/sveltejs/svelte/issues/4799), [#4846](https://github.com/sveltejs/svelte/issues/4846))
* Fix setting `value` attribute with `bind:group` and attribute spread ([#4803](https://github.com/sveltejs/svelte/issues/4803))
* Fix issue with compound `{#if}` block involving static condition, dynamic condition, and inline component ([#4840](https://github.com/sveltejs/svelte/issues/4840))
* Update a11y warnings per ARIA 1.2 working draft ([#4844](https://github.com/sveltejs/svelte/issues/4844))
## 3.22.2
* Fix compiler exception with `a11y-img-redundant-alt` and value-less `alt` attribute ([#4777](https://github.com/sveltejs/svelte/issues/4777))
## 3.22.1
* Fix compiler exception with `a11y-img-redundant-alt` and dynamic `alt` attribute ([#4770](https://github.com/sveltejs/svelte/issues/4770))
## 3.22.0
* Fix misaligned line numbers in source maps ([#3906](https://github.com/sveltejs/svelte/issues/3906))
* Make setting a `tweened` store using `duration: 0` instantly update the value ([#4399](https://github.com/sveltejs/svelte/issues/4399))
* Fix reactivity with imported values that are then mutated ([#4555](https://github.com/sveltejs/svelte/issues/4555))
* Fix contextual dynamic `bind:this` inside `{#each}` block ([#4686](https://github.com/sveltejs/svelte/issues/4686))
* Do not display a11y warning about missing `href` for `<a>` with `name` or `id` ([#4697](https://github.com/sveltejs/svelte/issues/4697))
* Disable infinite loop guard inside generators ([#4698](https://github.com/sveltejs/svelte/issues/4698))
* Display `a11y-invalid-attribute` warning for `href="javascript:..."` ([#4733](https://github.com/sveltejs/svelte/pull/4733))
* Implement `a11y-img-redundant-alt` warning ([#4750](https://github.com/sveltejs/svelte/pull/4750))
* Fix variable name conflict with component called `<Anchor>` ([#4768](https://github.com/sveltejs/svelte/issues/4768))
## 3.21.0
* Support dimension bindings in cross-origin environments ([#2147](https://github.com/sveltejs/svelte/issues/2147))
* Fix several related outro bugs ([#3202](https://github.com/sveltejs/svelte/issues/3202), [#3410](https://github.com/sveltejs/svelte/issues/3410), [#3685](https://github.com/sveltejs/svelte/issues/3685), [#4620](https://github.com/sveltejs/svelte/issues/4620), [#4630](https://github.com/sveltejs/svelte/issues/4630))
* Try using `globalThis` rather than `globals` for the benefit of non-Node servers and web workers ([#3561](https://github.com/sveltejs/svelte/issues/3561), [#4545](https://github.com/sveltejs/svelte/issues/4545))
* Support `{#await ... catch ...}` syntax shorthand ([#3623](https://github.com/sveltejs/svelte/issues/3623))
* Fix attaching of JS debugging comments to HTML comments ([#4565](https://github.com/sveltejs/svelte/issues/4565))
* Fix `<svelte:component/>` within `<slot/>` ([#4597](https://github.com/sveltejs/svelte/issues/4597))
* Fix bug with updating simple `{#if}` blocks ([#4629](https://github.com/sveltejs/svelte/issues/4629))
* Fix issues with `<input type="number">` updates ([#4631](https://github.com/sveltejs/svelte/issues/4631), [#4687](https://github.com/sveltejs/svelte/issues/4687))
* Prevent illegal attribute names ([#4648](https://github.com/sveltejs/svelte/issues/4648))
* Fix `{#if}` block directly within `<slot/>` ([#4703](https://github.com/sveltejs/svelte/issues/4703))
## 3.20.1
* Fix compiler regression with slots ([#4562](https://github.com/sveltejs/svelte/issues/4562))
## 3.20.0
* Allow destructuring in `{#await}` blocks ([#1851](https://github.com/sveltejs/svelte/issues/1851))
* Allow `<svelte:self>` to be used in a slot ([#2798](https://github.com/sveltejs/svelte/issues/2798))
* Expose object of unknown props in `$$restProps` ([#2930](https://github.com/sveltejs/svelte/issues/2930))
* Prevent passing named slots other than from the top level within a component ([#3385](https://github.com/sveltejs/svelte/issues/3385))
* Allow transitions and animations to work within iframes ([#3624](https://github.com/sveltejs/svelte/issues/3624))
* Fix initialising slot fallbacks when unnecessary ([#3763](https://github.com/sveltejs/svelte/issues/3763))
* Disallow binding directly to `const` variables ([#4479](https://github.com/sveltejs/svelte/issues/4479))
* Fix re-attaching event handlers on keyed `{#each}` blocks ([#4491](https://github.com/sveltejs/svelte/issues/4491))
* Fix updating keyed `{#each}` blocks with `{:else}` ([#4536](https://github.com/sveltejs/svelte/issues/4536), [#4549](https://github.com/sveltejs/svelte/issues/4549))
* Fix hydration of top-level content ([#4542](https://github.com/sveltejs/svelte/issues/4542))
## 3.19.2
* In `dev` mode, display a runtime warning when a component is passed an unexpected slot ([#1020](https://github.com/sveltejs/svelte/issues/1020), [#1447](https://github.com/sveltejs/svelte/issues/1447))
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480))
* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092))
* Fix bitmask overflow for `{#if}` blocks ([#4263](https://github.com/sveltejs/svelte/issues/4263))
* In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323))
* Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463))
* Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481))
## 3.19.1
* Do not treat modifications to `$$props` as updates to a store called `$props` ([#4368](https://github.com/sveltejs/svelte/issues/4368))
* Deconflict `value` parameter name used in contextual bindings ([#4445](https://github.com/sveltejs/svelte/issues/4445))
* Fix dev mode validation of `{#each}` blocks using strings ([#4450](https://github.com/sveltejs/svelte/issues/4450))
## 3.19.0
* Fix indirect bindings involving elements with spreads ([#3680](https://github.com/sveltejs/svelte/issues/3680))
* `$capture_state`/`$inject_state` now act on the component's entire state, rather than its props ([#3822](https://github.com/sveltejs/svelte/pull/3822))
* Warn when using `<Foo/>` and `Foo` is dynamic ([#4331](https://github.com/sveltejs/svelte/issues/4331))
* Display compilation warnings in `svelte/register` in dev mode ([#4364](https://github.com/sveltejs/svelte/issues/4364))
* Fix unneeded updating of keyed each blocks ([#4373](https://github.com/sveltejs/svelte/issues/4373))
* Throw runtime error in dev mode for non-array-like values in `{#each}` blocks ([#4408](https://github.com/sveltejs/svelte/issues/4408))
## 3.18.2
* Fix binding to module-level variables ([#4086](https://github.com/sveltejs/svelte/issues/4086))
* Improve parsing error messages when there is a pending unclosed tag ([#4131](https://github.com/sveltejs/svelte/issues/4131))
* Disallow attribute/prop names from matching two-way-bound names or `{shorthand}` attribute/prop names ([#4325](https://github.com/sveltejs/svelte/issues/4325))
* Improve performance of `flush()` by not using `.shift()` ([#4356](https://github.com/sveltejs/svelte/pull/4356))
* Permit reserved keywords as destructuring keys in `{#each}` ([#4372](https://github.com/sveltejs/svelte/issues/4372))
* Disallow reserved keywords in `{expressions}` ([#4372](https://github.com/sveltejs/svelte/issues/4372))
* Fix code generation error with precedence of arrow functions ([#4384](https://github.com/sveltejs/svelte/issues/4384))
* Fix event handlers that are dynamic via reactive declarations or stores ([#4388](https://github.com/sveltejs/svelte/issues/4388))
* Fix invalidation in expressions like `++foo.bar` ([#4393](https://github.com/sveltejs/svelte/issues/4393))
## 3.18.1
* Fix code generation error with adjacent inline and block comments ([#4312](https://github.com/sveltejs/svelte/issues/4312))
* Fix detection of unused CSS selectors that begin with a `:global()` but contain a scoped portion ([#4314](https://github.com/sveltejs/svelte/issues/4314))
## 3.18.0
* Fix infinite loop when instantiating another component during `onMount` ([#3218](https://github.com/sveltejs/svelte/issues/3218))
* Make autosubscribing to a nullish store a no-op ([#2181](https://github.com/sveltejs/svelte/issues/2181))
## 3.17.3
* Fix updating a `<slot>` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292))
* Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298))
* Add dev mode check to disallow duplicate keys in a keyed `{#each}` ([#4301](https://github.com/sveltejs/svelte/issues/4301))
* Fix hydration of `<title>` when starting from SSR-generated code with `hydratable: true` ([#4310](https://github.com/sveltejs/svelte/issues/4310))
## 3.17.2
* Fix removing attributes during hydration ([#1733](https://github.com/sveltejs/svelte/issues/1733))
* Disallow two-way binding to a variable declared by an `{#await}` block ([#4012](https://github.com/sveltejs/svelte/issues/4012))
* Allow access to `let:` variables in sibling attributes on slot root ([#4173](https://github.com/sveltejs/svelte/issues/4173))
* Fix `~=` and class selector matching against values separated by any whitespace characters ([#4242](https://github.com/sveltejs/svelte/issues/4242))
* Fix code generation for `await`ed expressions that need parentheses ([#4267](https://github.com/sveltejs/svelte/issues/4267))
* Preserve JavaScript comments from the original component source where possible ([#4268](https://github.com/sveltejs/svelte/issues/4268))
* Add some more known globals ([#4276](https://github.com/sveltejs/svelte/pull/4276))
* Correctly apply event modifiers to `<svelte:body>` events ([#4278](https://github.com/sveltejs/svelte/issues/4278))

@ -43,13 +43,16 @@ When [opening a new issue](https://github.com/sveltejs/svelte/issues/new/choose)
- **One issue, one bug:** Please report a single bug per issue.
- **Provide reproduction steps:** List all the steps necessary to reproduce the issue. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort. If possible, use the [REPL](https://svelte.dev/repl) to create your reproduction.
## RFCs
If you'd like to propose an implementation for a large new feature or change then please [create an RFC](https://github.com/sveltejs/rfcs) to discuss it up front.
## Installation
1. Ensure you have [npm](https://www.npmjs.com/get-npm) installed.
1. After cloning the repository, run `npm install` in the root of the repository.
1. To start a development server, run `npm run dev`.
## Pull requests
### Your first pull request
@ -93,7 +96,7 @@ Test samples are kept in `/test/xxx/samples` folder.
#### Running tests
1. To run test, run `npm run test`
1. To run test, run `npm run test`.
1. To run test for a specific feature, you can use the `-g` (aka `--grep`) option. For example, to only run test involving transitions, run `npm run test -- -g transition`.
##### Running solo test
@ -130,7 +133,7 @@ The core Svelte team will be monitoring for pull requests. Do help us by making
### Code conventions
- `snake_case` for internal variable names and methods
- `snake_case` for internal variable names and methods.
- `camelCase` for public variable names and methods.
## License

@ -7,15 +7,6 @@
<img src="https://img.shields.io/npm/v/svelte.svg" alt="npm version">
</a>
<a href="https://packagephobia.now.sh/result?p=svelte">
<img src="https://packagephobia.now.sh/badge?p=svelte" alt="install size">
</a>
<a href="https://github.com/sveltejs/svelte/actions">
<img src="https://github.com/sveltejs/svelte/workflows/CI/badge.svg?branch=master"
alt="build status">
</a>
<a href="https://github.com/sveltejs/svelte/blob/master/LICENSE">
<img src="https://img.shields.io/npm/l/svelte.svg" alt="license">
</a>
@ -29,6 +20,15 @@ Svelte is a new way to build web applications. It's a compiler that takes your d
Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).
## Supporting Svelte
Svelte is an MIT-licensed open source project with its ongoing development made possible entirely by the support of awesome volunteers. If you'd like to support their efforts, please consider:
- [Becoming a backer on Open Collective](https://opencollective.com/svelte).
Funds donated via Open Collective will be used for compensating expenses related to Svelte's development such as hosting costs. If sufficient donations are received, funds may also be used to support Svelte's development more directly.
## Development
Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) and help us out!
@ -41,10 +41,7 @@ cd svelte
npm install
```
> Many tests depend on newlines being preserved as `<LF>`. On Windows, you can ensure this by cloning with:
> ```bash
> git -c core.autocrlf=false clone https://github.com/sveltejs/svelte.git
> ```
> Do not use Yarn to install the dependencies, as the specific package versions in `package-lock.json` are used to build and test Svelte.
To build the compiler, and all the other modules included in the package:
@ -76,14 +73,11 @@ npm run test -- -g transition
## svelte.dev
The source code for https://svelte.dev, including all the documentation, lives in the [site](site) directory. The site is built with [Sapper](https://sapper.svelte.dev). To develop locally:
The source code for https://svelte.dev, including all the documentation, lives in the [site](site) directory. The site is built with [Sapper](https://sapper.svelte.dev).
```bash
cd site
npm install && npm run update
npm run dev
```
### Is svelte.dev down?
Probably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402).
## License

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

@ -1,4 +0,0 @@
--require source-map-support/register
--full-trace
--recursive
test/test.js

@ -1 +0,0 @@
test/test.js

2016
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.17.1",
"version": "3.28.0",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -23,10 +23,10 @@
},
"types": "types/runtime/index.d.ts",
"scripts": {
"test": "mocha --opts mocha.opts",
"test": "mocha",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts",
"quicktest": "mocha --opts mocha.opts",
"precoverage": "c8 mocha --opts mocha.coverage.opts",
"quicktest": "mocha",
"precoverage": "c8 mocha",
"coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
"codecov": "codecov",
"precodecov": "npm run coverage",
@ -63,18 +63,19 @@
"@rollup/plugin-sucrase": "^3.0.0",
"@rollup/plugin-typescript": "^2.0.1",
"@rollup/plugin-virtual": "^2.0.0",
"@types/mocha": "^5.2.7",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.0.0",
"@types/mocha": "^7.0.0",
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^2.1.0",
"acorn": "^7.1.0",
"@typescript-eslint/eslint-plugin": "^3.0.2",
"@typescript-eslint/parser": "^3.0.2",
"acorn": "^7.4.0",
"agadoo": "^1.1.0",
"c8": "^5.0.1",
"code-red": "0.0.28",
"code-red": "^0.1.3",
"codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^6.3.0",
"eslint-plugin-import": "^2.18.2",
"eslint": "^7.1.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-svelte3": "^2.7.3",
"estree-walker": "^1.0.0",
"is-reference": "^1.1.4",
@ -82,9 +83,9 @@
"kleur": "^3.0.3",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"mocha": "^6.2.0",
"mocha": "^7.0.0",
"periscopic": "^2.0.1",
"puppeteer": "^1.19.0",
"puppeteer": "^2.1.1",
"rollup": "^1.27.14",
"source-map": "^0.7.3",
"source-map-support": "^0.5.13",

@ -36,7 +36,15 @@ function registerExtension(extension) {
format: 'cjs'
});
const { js } = compile(fs.readFileSync(filename, 'utf-8'), options);
const { js, warnings } = compile(fs.readFileSync(filename, 'utf-8'), options);
if (options.dev) {
warnings.forEach(warning => {
console.warn(`\nSvelte Warning in ${warning.filename}:`);
console.warn(warning.message);
console.warn(warning.frame);
})
}
return module._compile(js.code, filename);
};

@ -99,12 +99,20 @@ export default [
json(),
ts_plugin
],
output: {
file: 'compiler.js',
format: is_publish ? 'umd' : 'cjs',
name: 'svelte',
sourcemap: true,
},
output: [
{
file: 'compiler.js',
format: is_publish ? 'umd' : 'cjs',
name: 'svelte',
sourcemap: true,
},
{
file: 'compiler.mjs',
format: 'esm',
name: 'svelte',
sourcemap: true,
}
],
external: is_publish
? []
: id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree')

@ -1,3 +1,6 @@
# IMPORTANT: Don't use this Dockerfile in your own Sapper projects without also looking at the .dockerignore file.
# Without an appropriate .dockerignore, this Dockerfile will copy a large number of unneeded files into your image.
FROM mhart/alpine-node:12
# install dependencies

@ -9,14 +9,14 @@ sapper:
@echo "\n~> updating template & contributors list"
@npm run update
@echo "\n~> building Sapper app"
@npm run sapper
@npm run build
docker:
@echo "\n~> building docker image"
@gcloud builds submit -t $(IMAGE)
@gcloud builds submit --project $(PROJECT) -t $(IMAGE)
deploy: sapper docker
@echo "\n~> deploying $(SERVICE) to Cloud Run servers"
@gcloud beta run deploy $(SERVICE) --allow-unauthenticated --platform managed --region us-central1 --image $(IMAGE) --memory=512Mi
@gcloud run deploy $(SERVICE) --project $(PROJECT) --allow-unauthenticated --platform managed --region us-central1 --image $(IMAGE) --memory=512Mi

@ -1,24 +1,33 @@
## Running locally
Set up the project:
Set up the site sub-project:
```bash
git clone https://github.com/sveltejs/svelte.git
cd svelte
npm ci
PUBLISH=1 npm run build
cd site
npm ci
npm run update
npm run dev
```
Start the server with `npm run dev`, and navigate to [localhost:3000](http://localhost:3000).
and navigate to [localhost:3000](http://localhost:3000).
## Using a local copy of Svelte
## Running using the local copy of Svelte
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.
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:
```bash
git clone https://github.com/sveltejs/svelte.git
cd svelte
npm ci
PUBLISH=1 npm run build
cd site
npm ci
npm run update
npm run dev
```
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.
@ -35,14 +44,35 @@ 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`.
To build the website, run `npm run build`. The output can be found in `__sapper__/build`.
## Testing
Tests can be run using `npm run test`.
## Linking `@sveltejs/site-kit` and `@sveltejs/site-repl`
This site depends on `@sveltejs/site-kit`, a collection of styles, components and icons used in common by *.svelte.dev websites, and `@sveltejs/site-repl`.
In order to work on features that depend on those packages, you need to [link](https://docs.npmjs.com/cli/link) their repositories:
- `cd <somewhere>`
- `git clone https://github.com/sveltejs/site-kit`
- `git clone https://github.com/sveltejs/svelte-repl`
- `cd <somewhere>/site-kit`
- `npm link`
- `cd <somewhere>/svelte-repl`
- `npm link`
- `cd <svelte-repo>/site`
- `npm link @sveltejs/site-kit`
- `npm link @sveltejs/svelte-repl`
## Translating the API docs
Anchors are automatically generated using headings in the documentation and by default (for the english language) they are latinised to make sure the URL is always conforming to RFC3986.

@ -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.
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).)

@ -5,7 +5,7 @@ author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.technology), and the [starter template](https://github.com/sveltejs/sapper-template)
> Quickstart for the impatient: [the Sapper docs](https://sapper.svelte.dev), and the [starter template](https://github.com/sveltejs/sapper-template)
If you had to list the characteristics of the perfect Node.js web application framework, you'd probably come up with something like this:
@ -47,9 +47,9 @@ What happens if we use the new model as a starting point?
## Introducing Sapper
<aside><p>The <a href="https://sapper.svelte.technology/docs#why-the-name-">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
<aside><p>The <a href="https://sapper.svelte.dev/docs#Why_the_name">name comes from</a> the term for combat engineers, and is also short for Svelte app maker</p></aside>
[Sapper](https://sapper.svelte.technology) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
[Sapper](https://sapper.svelte.dev) is the answer to that question. **Sapper is a Next.js-style framework that aims to meet the eleven criteria at the top of this article while dramatically reducing the amount of code that gets sent to the browser.** It's implemented as Express-compatible middleware, meaning it's easy to understand and customise.
The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript *at all* for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing.
@ -57,7 +57,7 @@ What about a more 'real world' example? Conveniently, the [RealWorld](https://gi
<aside><p>Code-splitting isn't free — if the reference implementation used code-splitting, it would be larger still</p></aside>
The entire app costs 132.7kb (39.9kb zipped), which is significantly smaller than the reference React/Redux implementation at 327kb (85.7kb), but even if was as large it would *feel* faster because of code-splitting. And that's a crucial point. We're told we need to code-split our apps, but if your app uses a traditional framework like React or Vue then there's a hard lower bound on the size of your initial code-split chunk — the framework itself, which is likely to be a significant portion of your total app size. With the Svelte approach, that's no longer the case.
The entire app costs 132.7kb (39.9kb zipped), which is significantly smaller than the reference React/Redux implementation at 327kb (85.7kb), but even if it was as large it would *feel* faster because of code-splitting. And that's a crucial point. We're told we need to code-split our apps, but if your app uses a traditional framework like React or Vue then there's a hard lower bound on the size of your initial code-split chunk — the framework itself, which is likely to be a significant portion of your total app size. With the Svelte approach, that's no longer the case.
But size is only part of the story. Svelte apps are also extremely performant and memory-efficient, and the framework includes powerful features that you would sacrifice if you chose a 'minimal' or 'simple' UI library.

@ -30,7 +30,9 @@ To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the fol
## Vim/Neovim
To treat all `*.svelte` files as HTML, add the following line to your `init.vim`:
You can use the [coc-svelte extension](https://github.com/coc-extensions/coc-svelte) which utilises the official language-server.
As an alternative you can treat all `*.svelte` files as HTML. Add the following line to your `init.vim`:
```
au! BufNewFile,BufRead *.svelte set ft=html
@ -50,13 +52,7 @@ To set the filetype for a single file, use a [modeline](https://vim.fandom.com/w
## Visual Studio Code
To treat `*.svelte` files as HTML, add the following lines to your `settings.json` file:
```cson
"files.associations": {
"*.svelte": "html"
}
```
We recommend using the official [Svelte for VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
## JetBrains WebStorm

@ -18,7 +18,7 @@ You'll be using the *command line*, also known as the terminal. On Windows, you
The command line is a way to interact with your computer (or another computer! but that's a topic for another time) with more power and control than the GUI (graphical user interface) that most people use day-to-day.
Once on the command line, you can navigate the filesystem using `ls` to list the contents of your current directory, and `cd` to change the current directory. For example, if you had a `Development` directory of your projects inside your home directory, you would type
Once on the command line, you can navigate the filesystem using `ls` (`dir` on Windows) to list the contents of your current directory, and `cd` to change the current directory. For example, if you had a `Development` directory of your projects inside your home directory, you would type
```bash
cd Development
@ -34,7 +34,7 @@ cd svelte-projects
A full introduction to the command line is out of the scope of this guide, but here are a few more useful commands:
* `cd ..` — navigates to the parent of the current directory
* `cat my-file.txt` — on Mac/Linux, lists the contents of `my-file.txt`
* `cat my-file.txt` — on Mac/Linux (`type my-file.txt` on Windows), lists the contents of `my-file.txt`
* `open .` (or `start .` on Windows) — opens the current directory in Finder or File Explorer
@ -51,7 +51,7 @@ Once installed, you'll have access to three new commands:
## Installing a text editor
To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=JamesBirtles.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components).
To write code, you need a good editor. The most popular choice is [Visual Studio Code](https://code.visualstudio.com/) or VSCode, and justifiably so — it's well-designed and fully-featured, and has a wealth of extensions ([including one for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which provides syntax highlighting and diagnostic messages when you're writing components).
## Creating a project
@ -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:
> TODO update the template, it needs... some work
```bash
npm run dev
```

@ -159,6 +159,6 @@ In Vue, meanwhile, we have a default export with a `data` function that returns
## Death to boilerplate
These are just some of the ways that Svelte helps you build user interfaces with a minimum of fuss. There are plenty of others — for example, [reactive declarations](https://svelte.dev/tutorial/reactive-declarations) essentially do the work of React's `useMemo`, `useCallback` and `useEffect` without the boilerplate (or indeed the garbage collection overhead of creating inline functions and arrays on each state change).
These are just some of the ways that Svelte helps you build user interfaces with a minimum of fuss. There are plenty of others — for example, [reactive declarations](tutorial/reactive-declarations) essentially do the work of React's `useMemo`, `useCallback` and `useEffect` without the boilerplate (or indeed the garbage collection overhead of creating inline functions and arrays on each state change).
How? By choosing a different set of constraints. Because [Svelte is a compiler](blog/frameworks-without-the-framework), we're not bound to the peculiarities of JavaScript: we can *design* a component authoring experience, rather than having to fit it around the semantics of the language. Paradoxically, this results in *more* idiomatic code — for example using variables naturally rather than via proxies or hooks — while delivering significantly more performant apps.

@ -0,0 +1,141 @@
---
title: Svelte <3 TypeScript
description: Typernetically enhanced web apps
author: Orta Therox
authorURL: https://twitter.com/orta
---
It's been by far the most requested feature for a while, and it's finally here: Svelte officially supports TypeScript.
We think it'll give you a much nicer development experience — one that also scales beautifully to larger Svelte code bases — regardless of whether you use TypeScript or JavaScript.
<figure>
<img alt="Screenshot of TypeScript in Svelte" src="media/svelte-ts.png">
<figcaption>Image of TypeScript + Svelte in VS Code (theme is <a href="https://marketplace.visualstudio.com/items?itemName=karyfoundation.theme-karyfoundation-themes">Kary Pro</a>.)</figcaption>
</figure>
## Try it now
You can start a new Svelte TypeScript project using the [normal template](https://github.com/sveltejs/template) and by running `node scripts/setupTypeScript.js` before you do anything else:
```bash
npx degit sveltejs/template svelte-typescript-app
cd svelte-typescript-app
node scripts/setupTypeScript.js
```
If you're a VS Code user, make sure you're using the (new) [official extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), which replaces the popular extension by James Birtles.
Later in this blog post, we'll detail the individual steps involved in using TypeScript in an existing Svelte project.
## What does it mean to support TypeScript in Svelte?
TypeScript support in Svelte has been possible for a long time, but you had to mix a lot of disparate tools together and each project ran independently. Today, nearly all of these tools live under the Svelte organization and are maintained by a set of people who take responsibility over the whole pipeline and have common goals.
A week before COVID was declared a pandemic, [I pitched a consolidation](https://github.com/sveltejs/svelte/issues/4518) of the best Svelte tools and ideas from similar dev-ecosystems and provided a set of steps to get first class TypeScript support. Since then, many people have pitched in and written the code to get us there.
When we say that Svelte now supports TypeScript, we mean a few different things:
* You can use TypeScript inside your `<script>` blocks — just add the `lang="ts"` attribute
* Components with TypeScript can be type-checked with the `svelte-check` command
* You get autocompletion hints and type-checking as you're writing components, even in expressions inside markup
* TypeScript files understand the Svelte component API — no more red squiggles when you import a `.svelte` file into a `.ts` module
#### How does it work?
To understand the two main parts of TypeScript support, we'll compare it to the technique TypeScript uses to provide dev tools. There is a compiler `tsc` which you run on the command-line to convert `*.ts` to `*.js`, then there is a `TSServer` which is a node API that responds to requests from text editors. The `TSServer` is what provides all the JavaScript and TypeScript realtime introspection for editors while coding, and it has most of the compiler's code inside it.
For Svelte, we have the Svelte compiler, and now we have the [`svelte-language-server`](https://github.com/sveltejs/language-tools/tree/master/packages/language-server#svelte-language-server) which responds to text editor calls via the [Language Server Protocol standard](https://microsoft.github.io//language-server-protocol/overviews/lsp/overview/). First class TypeScript support means that _both_ of these two systems do a good job of handling TypeScript code.
The Svelte compiler support for TypeScript is handled by [Christian Kaisermann](https://github.com/kaisermann)'s [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess#svelte-preprocess) which is now an official Svelte project.
For the editor level, we took inspiration from [Pine's](https://github.com/octref) work in the [Vue](https://vuejs.org) ecosystem via [Vetur](https://github.com/vuejs/vetur). Vetur provides an [LSP](https://github.com/vuejs/vetur/blob/master/server), a VS Code extension and a [CLI](https://github.com/vuejs/vetur/blob/master/vti). Svelte now also has an [LSP](https://github.com/sveltejs/language-tools/blob/master/packages/language-server), a [VS Code extension](https://github.com/sveltejs/language-tools/blob/master/packages/svelte-vscode) and a [CLI](https://github.com/sveltejs/language-tools/blob/master/packages/svelte-check).
#### `*.svelte` Introspection
For the official Svelte VS Code extension, we built off the foundations which [James Birtles](https://github.com/UnwrittenFun) has created in [`UnwrittenFun/svelte-vscode`](https://github.com/UnwrittenFun/svelte-vscode) and [`UnwrittenFun/svelte-language-server`](https://github.com/UnwrittenFun/svelte-language-server/).
[Simon Holthausen](https://github.com/dummdidumm) and [Lyu, Wei-Da](https://github.com/jasonlyu123) have done great work improving the JavaScript and TypeScript introspection, including integrating [@halfnelson](https://github.com/halfnelson)'s [svelte2tsx](https://github.com/sveltejs/language-tools/tree/master/packages/svelte2tsx#svelte2tsx) which powers understanding the props on components in your codebase.
## Adding TypeScript to an existing project
Before getting started, add the dependencies:
```bash
npm install --save-dev @tsconfig/svelte typescript svelte-preprocess svelte-check
```
##### 1. Compiling TypeScript
You first need to set up [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess#svelte-preprocess), which passes the contents of your `<script lang="ts">` blocks through the TypeScript compiler.
In a Rollup project, that would look like this — note that we also need to install `@rollup/plugin-typescript` so that Rollup can handle `.ts` files:
```diff
+ import autoPreprocess from 'svelte-preprocess';
+ import typescript from '@rollup/plugin-typescript';
export default {
...,
plugins: [
svelte({
+ preprocess: autoPreprocess()
}),
+ typescript({ sourceMap: !production })
]
}
```
[Full instructions for other environments here](https://github.com/sveltejs/svelte-preprocess#usage).
To configure TypeScript, you will need to create a `tsconfig.json` in the root of your project:
```json
{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*", "src/node_modules"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}
```
Your `include`/`exclude` may differ per project — these are defaults that should work across most Svelte projects.
##### 2. Editor Support
Any editor [using an LSP](https://langserver.org/#implementations-client) can be supported. The [VS Code](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) extension has been our primary focus, but there is work in progress [on Atom](https://github.com/sveltejs/language-tools/pull/160), and Vim via [coc-svelte](https://github.com/coc-extensions/coc-svelte) has been updated with the latest LSP.
These editor extensions will improve your coding experience even if you only use JavaScript. The editor won't offer errors, but it will offer inference and refactoring tools. You can [add `// @ts-check`](https://www.staging-typescript.org/docs/handbook/intro-to-js-ts.html) to the top of a `<script>` tag using JavaScript to get better error messages with no infra changes.
To switch a `<script>` to use TypeScript, use `<script lang="ts">` and that should be it. Hopefully you won't be seeing an ocean of red squiggles.
##### 3. CI Checks
Having red squiggles is great, well, kinda. On the long run though, you want to be able to verify that there are no errors in your code. To verify your project is error free, you can use the CLI tool [`svelte-check`](https://www.npmjs.com/package/svelte-check). It acts like an editor asking for errors against all of your `.svelte` files.
You can add the dependency to your project and then add it to CI.
```bash
npx svelte-check
Loading svelte-check in workspace: /Users/ortatherox/dev/svelte/example-app
Getting Svelte diagnostics...
====================================
/Users/ortatherox/dev/svelte/example-app/src/App.svelte:3:2
Error: Type '123' is not assignable to type 'string'. (ts)
====================================
svelte-check found 1 error
error Command failed with exit code 1.
```
## What about TypeScript in Sapper projects?
TypeScript support was added to Sapper in 0.28, so if you're using an older version be sure to [upgrade](https://sapper.svelte.dev/migrating#0_27_to_0_28).
## How can I contribute?
We're so glad you asked. The work is happening in the [sveltejs/language-tools](https://github.com/sveltejs/language-tools) repo and in the [#language-tools](https://discord.gg/enV6v8K) channel in the Svelte Discord. If you'd like to report issues, submit fixes, or help out with extensions for new editors and so on, that's where you can find us. See you there!

@ -2,8 +2,10 @@
title: Before we begin
---
> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](chat). The [tutorial](tutorial) is more complete; start there.
This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte.
If that's not you (yet), you may prefer to visit the [interactive tutorial](tutorial) or the [examples](examples) before consulting this reference.
Don't be shy about asking for help in the [Discord chatroom](chat).
Using an older version of Svelte? Have a look at the [v2 docs](https://v2.svelte.dev).

@ -8,7 +8,7 @@ Components are the building blocks of Svelte applications. They are written into
All three sections — script, styles and markup — are optional.
```html
```sv
<script>
// logic goes here
</script>
@ -30,7 +30,7 @@ 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 (see the section on [attributes and props](docs#Attributes_and_props) for more information).
```html
```sv
<script>
export let foo;
@ -42,13 +42,13 @@ Svelte uses the `export` keyword to mark a variable declaration as a *property*
---
You can specify a default value, which will be used if the component's consumer doesn't specify a prop.
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.
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`.
In development mode (see the [compiler options](docs#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`.
```html
```sv
<script>
export let bar = 'optional default value';
export let bar = 'optional default initial value';
export let baz = undefined;
</script>
```
@ -57,7 +57,7 @@ In development mode (see the [compiler options](docs#svelte_compile)), a warning
If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however.
```html
```sv
<script>
// these are readonly
export const thisIs = 'readonly';
@ -75,7 +75,7 @@ If you export a `const`, `class` or `function`, it is readonly from outside the
You can use reserved words as prop names.
```html
```sv
<script>
let className;
@ -95,7 +95,7 @@ Update expressions (`count += 1`) and property assignments (`obj.x = y`) have th
Because Svelte's reactivity is based on assignments, using array methods like `.push()` and `.splice()` won't automatically trigger updates. Options for getting around this can be found in the [tutorial](tutorial/updating-arrays-and-objects).
```html
```sv
<script>
let count = 0;
@ -113,7 +113,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 `$:` [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.
```html
```sv
<script>
export let title;
@ -132,7 +132,7 @@ Any top-level statement (i.e. not inside a block or a function) can be made reac
If a statement consists entirely of an assignment to an undeclared variable, Svelte will inject a `let` declaration on your behalf.
```html
```sv
<script>
export let num;
@ -157,7 +157,7 @@ Note that the store must be declared at the top level of the component — not i
Local variables (that do not represent store values) must *not* have a `$` prefix.
```html
```sv
<script>
import { writable } from 'svelte/store';
@ -175,7 +175,7 @@ Local variables (that do not represent store values) must *not* have a `$` prefi
##### Store contract
```js
store = { subscribe: (subscription: (value: any) => void) => () => void, set?: (value: any) => void }
store = { subscribe: (subscription: (value: any) => void) => (() => void), set?: (value: any) => void }
```
You can create your own stores without relying on [`svelte/store`](docs#svelte_store), by implementing the *store contract*:
@ -197,9 +197,9 @@ You can `export` bindings from this block, and they will become exports of the c
You cannot `export default`, since the default export is the component itself.
> Variables defined in `module` scripts are not reactive — reassigning them will not trigger a rerender even though the variable itself will update. For values shared between multiple components, consider using a [store](https://svelte.dev/docs#svelte_store).
> Variables defined in `module` scripts are not reactive — reassigning them will not trigger a rerender even though the variable itself will update. For values shared between multiple components, consider using a [store](docs#svelte_store).
```html
```sv
<script context="module">
let totalComponents = 0;
@ -225,7 +225,7 @@ CSS inside a `<style>` block will be scoped to that component.
This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).
```html
```sv
<style>
p {
/* this will only affect <p> elements in this component */
@ -238,7 +238,7 @@ This works by adding a class to affected elements, which is based on a hash of t
To apply styles to a selector globally, use the `:global(...)` modifier.
```html
```sv
<style>
:global(body) {
/* this will apply to <body> */

@ -9,7 +9,7 @@ title: Template syntax
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag, such as `<Widget>` or `<Namespace.Widget>`, indicates a *component*.
```html
```sv
<script>
import Widget from './Widget.svelte';
</script>
@ -26,7 +26,7 @@ A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag
By default, attributes work exactly like their HTML counterparts.
```html
```sv
<div class="foo">
<button disabled>can't touch this</button>
</div>
@ -36,7 +36,7 @@ By default, attributes work exactly like their HTML counterparts.
As in HTML, values may be unquoted.
```html
```sv
<input type=checkbox>
```
@ -44,7 +44,7 @@ As in HTML, values may be unquoted.
Attribute values can contain JavaScript expressions.
```html
```sv
<a href="page/{p}">page {p}</a>
```
@ -52,15 +52,26 @@ Attribute values can contain JavaScript expressions.
Or they can *be* JavaScript expressions.
```html
```sv
<button disabled={!clickable}>...</button>
```
---
An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:
Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).
All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`).
```html
<input required={false} placeholder="This input field is not required">
<div title={null}>This div has no title attribute</div>
```
---
An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:
```sv
<button disabled="{number !== 42}">...</button>
```
@ -68,7 +79,7 @@ An expression might include characters that would cause syntax highlighting to f
When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.
```html
```sv
<!-- These are equivalent -->
<button disabled={disabled}>...</button>
<button {disabled}>...</button>
@ -80,7 +91,7 @@ By convention, values passed to components are referred to as *properties* or *p
As with elements, `name={name}` can be replaced with the `{name}` shorthand.
```html
```sv
<Widget foo={bar} answer={42} text="hello"/>
```
@ -90,18 +101,30 @@ As with elements, `name={name}` can be replaced with the `{name}` shorthand.
An element or component can have multiple spread attributes, interspersed with regular ones.
```html
```sv
<Widget {...things}/>
```
---
*`$$props`* references all props that are passed to a component including ones that are not declared with `export`. It is useful in rare cases, but not generally recommended, as it is difficult for Svelte to optimise.
*`$$props`* references all props that are passed to a component, including ones that are not declared with `export`. It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases for example, when you don't know at compile time what props might be passed to a component.
```html
```sv
<Widget {...$$props}/>
```
---
*`$$restProps`* contains only the props which are *not* declared with `export`. It can be used to pass down other unknown attributes to an element in a component. It shares the same optimisation problems as *`$$props`*, and is likewise not recommended.
```html
<input {...$$restProps}>
```
> The `value` attribute of an `input` element or its children `option` elements must not be set with spread attributes when using `bind:group` or `bind:checked`. Svelte needs to be able to see the element's `value` directly in the markup in these cases so that it can link it to the bound variable.
---
### Text expressions
@ -113,7 +136,7 @@ An element or component can have multiple spread attributes, interspersed with r
Text can also contain JavaScript expressions:
```html
```sv
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
```
@ -125,7 +148,7 @@ Text can also contain JavaScript expressions:
You can use HTML comments inside components.
```html
```sv
<!-- this is a comment! -->
<h1>Hello world</h1>
```
@ -134,7 +157,7 @@ You can use HTML comments inside components.
Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually these are accessibility warnings; make sure that you're disabling them for a good reason.
```html
```sv
<!-- svelte-ignore a11y-autofocus -->
<input bind:value={name} autofocus>
```
@ -156,7 +179,7 @@ Comments beginning with `svelte-ignore` disable warnings for the next block of m
Content that is conditionally rendered can be wrapped in an if block.
```html
```sv
{#if answer === 42}
<p>what was the question?</p>
{/if}
@ -166,7 +189,7 @@ Content that is conditionally rendered can be wrapped in an if block.
Additional conditions can be added with `{:else if expression}`, optionally ending in an `{:else}` clause.
```html
```sv
{#if porridge.temperature > 100}
<p>too hot!</p>
{:else if 80 > porridge.temperature}
@ -186,6 +209,9 @@ Additional conditions can be added with `{:else if expression}`, optionally endi
{#each expression as name, index}...{/each}
```
```sv
{#each expression as name (key)}...{/each}
```
```sv
{#each expression as name, index (key)}...{/each}
```
```sv
@ -196,7 +222,7 @@ Additional conditions can be added with `{:else if expression}`, optionally endi
Iterating over lists of values can be done with an each block.
```html
```sv
<h1>Shopping list</h1>
<ul>
{#each items as item}
@ -211,7 +237,7 @@ You can use each blocks to iterate over any array or array-like value — that i
An each block can also specify an *index*, equivalent to the second argument in an `array.map(...)` callback:
```html
```sv
{#each items as item, i}
<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
@ -221,7 +247,12 @@ An each block can also specify an *index*, equivalent to the second argument in
If a *key* expression is provided — which must uniquely identify each list item — Svelte will use it to diff the list when data changes, rather than adding or removing items at the end. The key can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change.
```html
```sv
{#each items as item (item.id)}
<li>{item.name} x {item.qty}</li>
{/each}
<!-- or with additional index value -->
{#each items as item, i (item.id)}
<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
@ -231,7 +262,7 @@ If a *key* expression is provided — which must uniquely identify each list ite
You can freely use destructuring and rest patterns in each blocks.
```html
```sv
{#each items as { id, name, qty }, i (id)}
<li>{i + 1}: {name} x {qty}</li>
{/each}
@ -249,7 +280,7 @@ You can freely use destructuring and rest patterns in each blocks.
An each block can also have an `{:else}` clause, which is rendered if the list is empty.
```html
```sv
{#each todos as todo}
<p>{todo.text}</p>
{:else}
@ -274,7 +305,7 @@ An each block can also have an `{:else}` clause, which is rendered if the list i
Await blocks allow you to branch on the three possible states of a Promise — pending, fulfilled or rejected.
```html
```sv
{#await promise}
<!-- promise is pending -->
<p>waiting for the promise to resolve...</p>
@ -291,7 +322,7 @@ Await blocks allow you to branch on the three possible states of a Promise — p
The `catch` block can be omitted if you don't need to render anything when the promise rejects (or no error is possible).
```html
```sv
{#await promise}
<!-- promise is pending -->
<p>waiting for the promise to resolve...</p>
@ -305,12 +336,39 @@ The `catch` block can be omitted if you don't need to render anything when the p
If you don't care about the pending state, you can also omit the initial block.
```html
```sv
{#await promise then value}
<p>The value is {value}</p>
{/await}
```
### {#key ...}
```sv
{#key expression}...{/key}
```
Key blocks destroy and recreate their contents when the value of an expression changes.
---
This is useful if you want an element to play its transition whenever a value changes.
```sv
{#key value}
<div transition:fade>{value}</div>
{/key}
```
---
When used around components, this will cause them to be reinstantiated and reinitialised.
```sv
{#key value}
<Component />
{/key}
```
### {@html ...}
@ -326,7 +384,7 @@ The expression should be valid standalone HTML — `{@html "<div>"}content{@html
> 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
```sv
<div class="blog-post">
<h1>{post.title}</h1>
{@html post.content}
@ -349,7 +407,7 @@ The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the
It accepts a comma-separated list of variable names (not arbitrary expressions).
```html
```sv
<script>
let user = {
firstname: 'Ada',
@ -366,7 +424,7 @@ It accepts a comma-separated list of variable names (not arbitrary expressions).
`{@debug ...}` accepts a comma-separated list of variable names (not arbitrary expressions).
```html
```sv
<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}
@ -400,7 +458,7 @@ on:eventname|modifiers={handler}
Use the `on:` directive to listen to DOM events.
```html
```sv
<script>
let count = 0;
@ -418,7 +476,7 @@ Use the `on:` directive to listen to DOM events.
Handlers can be declared inline with no performance penalty. As with attributes, directive values may be quoted for the sake of syntax highlighters.
```html
```sv
<button on:click="{() => count += 1}">
count: {count}
</button>
@ -428,7 +486,7 @@ Handlers can be declared inline with no performance penalty. As with attributes,
Add *modifiers* to DOM events with the `|` character.
```html
```sv
<form on:submit|preventDefault={handleSubmit}>
<!-- the `submit` event's default is prevented,
so the page won't reload -->
@ -440,8 +498,10 @@ The following modifiers are available:
* `preventDefault` — calls `event.preventDefault()` before running the handler
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
* `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself
Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
@ -449,7 +509,7 @@ Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
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
```sv
<button on:click>
The component itself will emit the click event
</button>
@ -459,7 +519,7 @@ If the `on:` directive is used without a value, the component will *forward* the
It's possible to have multiple event listeners for the same event:
```html
```sv
<script>
let counter = 0;
function increment() {
@ -486,7 +546,7 @@ Data ordinarily flows down, from parent to child. The `bind:` directive allows d
The simplest bindings reflect the value of a property, such as `input.value`.
```html
```sv
<input bind:value={name}>
<textarea bind:value={text}></textarea>
@ -497,7 +557,7 @@ The simplest bindings reflect the value of a property, such as `input.value`.
If the name matches the value, you can use a shorthand.
```html
```sv
<!-- These are equivalent -->
<input bind:value={value}>
<input bind:value>
@ -507,11 +567,26 @@ If the name matches the value, you can use a shorthand.
Numeric input values are coerced; even though `input.value` is a string as far as the DOM is concerned, Svelte will treat it as a number. If the input is empty or invalid (in the case of `type="number"`), the value is `undefined`.
```html
```sv
<input type="number" bind:value={num}>
<input type="range" bind:value={num}>
```
---
On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList).
```sv
<label for="avatar">Upload a picture:</label>
<input
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
```
##### Binding `<select>` value
@ -519,7 +594,7 @@ Numeric input values are coerced; even though `input.value` is a string as far a
A `<select>` value binding corresponds to the `value` property on the selected `<option>`, which can be any value (not just strings, as is normally the case in the DOM).
```html
```sv
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b}>b</option>
@ -531,7 +606,7 @@ A `<select>` value binding corresponds to the `value` property on the selected `
A `<select multiple>` element behaves similarly to a checkbox group.
```html
```sv
<select multiple bind:value={fillings}>
<option value="Rice">Rice</option>
<option value="Beans">Beans</option>
@ -544,7 +619,7 @@ A `<select multiple>` element behaves similarly to a checkbox group.
When the value of an `<option>` matches its text content, the attribute can be omitted.
```html
```sv
<select multiple bind:value={fillings}>
<option>Rice</option>
<option>Beans</option>
@ -557,7 +632,7 @@ When the value of an `<option>` matches its text content, the attribute can be o
Elements with the `contenteditable` attribute support `innerHTML` and `textContent` bindings.
```html
```sv
<div contenteditable="true" bind:innerHTML={html}></div>
```
@ -569,32 +644,35 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — six
* `duration` (readonly) — the total duration of the video, in seconds
* `buffered` (readonly) — an array of `{start, end}` objects
* `seekable` (readonly) — ditto
* `played` (readonly) — ditto
* `seekable` (readonly) — ditto
* `seeking` (readonly) — boolean
* `ended` (readonly) — boolean
...and four *two-way* bindings:
...and five *two-way* bindings:
* `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where 1 is 'normal'
* `currentTime` — the current playback time in the video, in seconds
* `playbackRate` — how fast or slow to play the video, where 1 is 'normal'
* `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1
* `muted` — a boolean value where `true` is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
```html
```sv
<video
src={clip}
bind:duration
bind:buffered
bind:played
bind:seekable
bind:seeking
bind:played
bind:ended
bind:currentTime
bind:playbackRate
bind:paused
bind:volume
bind:muted
bind:videoWidth
bind:videoHeight
></video>
@ -611,7 +689,7 @@ Block-level elements have 4 readonly bindings, measured using a technique simila
* `offsetWidth`
* `offsetHeight`
```html
```sv
<div
bind:offsetWidth={width}
bind:offsetHeight={height}
@ -630,7 +708,7 @@ bind:group={variable}
Inputs that work together can use `bind:group`.
```html
```sv
<script>
let tortilla = 'Plain';
let fillings = [];
@ -658,7 +736,7 @@ bind:this={dom_node}
To get a reference to a DOM node, use `bind:this`.
```html
```sv
<script>
import { onMount } from 'svelte';
@ -687,7 +765,7 @@ class:name
A `class:` directive provides a shorter way of toggling a class on an element.
```html
```sv
<!-- These are equivalent -->
<div class="{active ? 'active' : ''}">...</div>
<div class:active={active}>...</div>
@ -720,7 +798,7 @@ action = (node: HTMLElement, parameters: any) => {
Actions are functions that are called when an element is created. They can return an object with a `destroy` method that is called after the element is unmounted:
```html
```sv
<script>
function foo(node) {
// the node has been mounted in the DOM
@ -738,11 +816,11 @@ Actions are functions that are called when an element is created. They can retur
---
An action can have parameters. If the returned value has an `update` method, it will be called whenever those parameters change, immediately after Svelte has applied updates to the markup.
An action can have a parameter. If the returned value has an `update` method, it will be called whenever that parameter changes, immediately after Svelte has applied updates to the markup.
> Don't worry about the fact that we're redeclaring the `foo` function for every component instance — Svelte will hoist any functions that don't depend on local state out of the component definition.
```html
```sv
<script>
export let bar;
@ -795,11 +873,11 @@ transition = (node: HTMLElement, params: any) => {
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.
When a block is transitioning out, all elements inside the block, including those that do not have their own transitions, are kept in the DOM until every transition in the block has completed.
The `transition:` directive indicates a *bidirectional* transition, which means it can be smoothly reversed while the transition is in progress.
```html
```sv
{#if visible}
<div transition:fade>
fades in and out
@ -817,7 +895,7 @@ Like actions, transitions can have parameters.
(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)
```html
```sv
{#if visible}
<div transition:fade="{{ duration: 2000 }}">
flies in, fades out over two seconds
@ -835,7 +913,7 @@ The `t` argument passed to `css` is a value between `0` and `1` after the `easin
The function is called repeatedly *before* the transition begins, with different `t` and `u` arguments.
```html
```sv
<script>
import { elasticOut } from 'svelte/easing';
@ -866,14 +944,14 @@ A custom transition function can also return a `tick` function, which is called
> 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
```sv
<script>
export let visible = false;
function typewriter(node, { speed = 50 }) {
const valid = (
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === 3
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) return {};
@ -912,7 +990,7 @@ An element with transitions will dispatch the following events in addition to an
* `outrostart`
* `outroend`
```html
```sv
{#if visible}
<p
transition:fly="{{ y: 200, duration: 2000 }}"
@ -930,7 +1008,7 @@ An element with transitions will dispatch the following events in addition to an
Local transitions only play when the block they belong to is created or destroyed, *not* when parent blocks are created or destroyed.
```html
```sv
{#if x}
{#if y}
<p transition:fade>
@ -979,7 +1057,7 @@ Similar to `transition:`, but only applies to elements entering (`in:`) or leavi
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
```sv
{#if visible}
<div in:fly out:fade>
flies in, fades out
@ -1028,7 +1106,7 @@ An animation is triggered when the contents of a [keyed each block](docs#each) a
Animations can be used with Svelte's [built-in animation functions](docs#svelte_animate) or [custom animation functions](docs#Custom_animation_functions).
```html
```sv
<!-- When `list` is reordered the animation will run-->
{#each list as item, index (item)}
<li animate:flip>{item}</li>
@ -1043,7 +1121,7 @@ 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
```sv
{#each list as item, index (item)}
<li animate:flip="{{ delay: 500 }}">{item}</li>
{/each}
@ -1062,7 +1140,7 @@ The `t` argument passed to `css` is a value that goes from `0` and `1` after the
The function is called repeatedly *before* the animation begins, with different `t` and `u` arguments.
```html
```sv
<script>
import { cubicOut } from 'svelte/easing';
@ -1095,7 +1173,7 @@ A custom animation function can also return a `tick` function, which is called *
> 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
```sv
<script>
import { cubicOut } from 'svelte/easing';
@ -1135,7 +1213,7 @@ 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
```sv
<SomeComponent on:whatever={handler}/>
```
@ -1143,7 +1221,7 @@ Components can emit events using [createEventDispatcher](docs#createEventDispatc
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
```sv
<SomeComponent on:whatever/>
```
@ -1158,7 +1236,7 @@ bind:property={variable}
You can bind to component props using the same syntax as for elements.
```html
```sv
<Keypad bind:value={pin}/>
```
@ -1174,7 +1252,7 @@ Components also support `bind:this`, allowing you to interact with component ins
> Note that we can't do `{cart.empty}` since `cart` is `undefined` when the button is first rendered and throws an error.
```html
```sv
<ShoppingCart bind:this={cart}/>
<button on:click={() => cart.empty()}>
@ -1202,7 +1280,7 @@ Components can have child content, in the same way that elements can.
The content is exposed in the child component using the `<slot>` element, which can contain fallback content that is rendered if no children are provided.
```html
```sv
<!-- App.svelte -->
<Widget></Widget>
@ -1224,7 +1302,7 @@ The content is exposed in the child component using the `<slot>` element, which
Named slots allow consumers to target specific areas. They can also have fallback content.
```html
```sv
<!-- App.svelte -->
<Widget>
<h1 slot="header">Hello</h1>
@ -1247,17 +1325,17 @@ Slots can be rendered zero or more times, and can pass values *back* to the pare
The usual shorthand rules apply — `let:item` is equivalent to `let:item={item}`, and `<slot {item}>` is equivalent to `<slot item={item}>`.
```html
```sv
<!-- App.svelte -->
<FancyList {items} let:item={item}>
<div>{item.text}</div>
<FancyList {items} let:prop={thing}>
<div>{thing.text}</div>
</FancyList>
<!-- FancyList.svelte -->
<ul>
{#each items as item}
<li class="fancy">
<slot item={item}></slot>
<slot prop={item}></slot>
</li>
{/each}
</ul>
@ -1267,10 +1345,10 @@ The usual shorthand rules apply — `let:item` is equivalent to `let:item={item}
Named slots can also expose values. The `let:` directive goes on the element with the `slot` attribute.
```html
```sv
<!-- App.svelte -->
<FancyList {items}>
<div slot="item" let:item={item}>{item.text}</div>
<div slot="item" let:item>{item.text}</div>
<p slot="footer">Copyright (c) 2019 Svelte Industries</p>
</FancyList>
@ -1278,7 +1356,7 @@ Named slots can also expose values. The `let:` directive goes on the element wit
<ul>
{#each items as item}
<li class="fancy">
<slot name="item" item={item}></slot>
<slot name="item" {item}></slot>
</li>
{/each}
</ul>
@ -1295,7 +1373,7 @@ The `<svelte:self>` element allows a component to include itself, recursively.
It cannot appear at the top level of your markup; it must be inside an if or each block to prevent an infinite loop.
```html
```sv
<script>
export let count;
</script>
@ -1320,7 +1398,7 @@ The `<svelte:component>` element renders a component dynamically, using the comp
If `this` is falsy, no component is rendered.
```html
```sv
<svelte:component this={currentSelection.component} foo={bar}/>
```
@ -1338,7 +1416,7 @@ If `this` is falsy, no component is rendered.
The `<svelte:window>` element allows you to add event listeners to the `window` object without worrying about removing them when the component is destroyed, or checking for the existence of `window` when server-side rendering.
```html
```sv
<script>
function handleKeydown(event) {
alert(`pressed the ${event.key} key`);
@ -1362,7 +1440,7 @@ You can also bind to the following properties:
All except `scrollX` and `scrollY` are readonly.
```html
```sv
<svelte:window bind:scrollY={y}/>
```
@ -1377,7 +1455,7 @@ All except `scrollX` and `scrollY` are readonly.
As with `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave` which don't fire on `window`.
```html
```sv
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
@ -1395,7 +1473,7 @@ As with `<svelte:window>`, this element allows you to add listeners to events on
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `html` content.
```html
```sv
<svelte:head>
<link rel="stylesheet" href="tutorial/dark-theme.css">
</svelte:head>
@ -1419,6 +1497,6 @@ The `<svelte:options>` element provides a place to specify per-component compile
* `namespace="..."` — the namespace where this component will be used, most commonly "svg"
* `tag="..."` — the name to use when compiling this component as a custom element
```html
```sv
<svelte:options tag="my-custom-element"/>
```

@ -22,7 +22,7 @@ The `onMount` function schedules a callback to run as soon as the component has
`onMount` does not run inside a [server-side component](docs#Server-side_component_API).
```html
```sv
<script>
import { onMount } from 'svelte';
@ -36,7 +36,7 @@ The `onMount` function schedules a callback to run as soon as the component has
If a function is returned from `onMount`, it will be called when the component is unmounted.
```html
```sv
<script>
import { onMount } from 'svelte';
@ -50,6 +50,8 @@ If a function is returned from `onMount`, it will be called when the component i
</script>
```
> This behaviour will only work when the function passed to `onMount` *synchronously* returns a value. `async` functions always return a `Promise`, and as such cannot *synchronously* return a function.
#### `beforeUpdate`
```js
@ -62,7 +64,7 @@ Schedules a callback to run immediately before the component is updated after an
> The first time the callback runs will be before the initial `onMount`
```html
```sv
<script>
import { beforeUpdate } from 'svelte';
@ -82,7 +84,7 @@ afterUpdate(callback: () => void)
Schedules a callback to run immediately after the component has been updated.
```html
```sv
<script>
import { afterUpdate } from 'svelte';
@ -104,7 +106,7 @@ Schedules a callback to run once the component is unmounted.
Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the only one that runs inside a server-side component.
```html
```sv
<script>
import { onDestroy } from 'svelte';
@ -124,7 +126,7 @@ promise: Promise = tick()
Returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none.
```html
```sv
<script>
import { beforeUpdate, tick } from 'svelte';
@ -148,7 +150,7 @@ Associates an arbitrary `context` object with the current component and the spec
Like lifecycle functions, this must be called during component initialisation.
```html
```sv
<script>
import { setContext } from 'svelte';
@ -168,7 +170,7 @@ context: any = getContext(key: any)
Retrieves the context that belongs to the closest parent component with the specified `key`. Must be called during component initialisation.
```html
```sv
<script>
import { getContext } from 'svelte';
@ -188,7 +190,7 @@ Creates an event dispatcher that can be used to dispatch [component events](docs
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.
```html
```sv
<script>
import { createEventDispatcher } from 'svelte';
@ -202,7 +204,7 @@ Component events created with `createEventDispatcher` create a [CustomEvent](htt
Events dispatched from child components can be listened to in their parent. Any data provided when the event was dispatched is available on the `detail` property of the event object.
```html
```sv
<script>
function callbackFunction(event) {
console.log(`Notify fired! Detail: ${event.detail}`)
@ -287,7 +289,9 @@ The second argument to `readable` is the same as the second argument to `writabl
```js
import { readable } from 'svelte/store';
const time = readable(new Date(), set => {
const time = readable(null, set => {
set(new Date());
const interval = setInterval(() => {
set(new Date());
}, 1000);
@ -413,7 +417,7 @@ Both functions return a Promise that resolves when the tween completes. If the t
Out of the box, Svelte will interpolate between two numbers, two arrays or two objects (as long as the arrays and objects are the same 'shape', and their 'leaf' properties are also numbers).
```html
```sv
<script>
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
@ -452,7 +456,7 @@ $: $size = big ? 100 : 10;
The `interpolate` option allows you to tween between *any* arbitrary values. It must be an `(a, b) => t => value` function, where `a` is the starting value, `b` is the target value, `t` is a number between 0 and 1, and `value` is the result. For example, we can use the [d3-interpolate](https://github.com/d3/d3-interpolate) package to smoothly interpolate between two colours.
```html
```sv
<script>
import { interpolateLab } from 'd3-interpolate';
import { tweened } from 'svelte/motion';
@ -499,7 +503,7 @@ Both `set` and `update` can take a second argument — an object with `hard` or
[See a full example on the spring tutorial.](tutorial/spring)
```html
```sv
<script>
import { spring } from 'svelte/motion';
@ -521,7 +525,7 @@ $: $size = big ? 100 : 10;
### `svelte/transition`
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
The `svelte/transition` module exports seven functions: `fade`, `blur`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with Svelte [`transitions`](docs#transition_fn).
#### `fade`
@ -546,7 +550,7 @@ Animates the opacity of an element from 0 to the current opacity for `in` transi
You can see the `fade` transition in action in the [transition tutorial](tutorial/transition).
```html
```sv
<script>
import { fade } from 'svelte/transition';
</script>
@ -582,7 +586,7 @@ Animates a `blur` filter alongside an element's opacity.
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
* `amount` (`number`, default 5) - the size of the blur in pixels
```html
```sv
<script>
import { blur } from 'svelte/transition';
</script>
@ -621,7 +625,7 @@ Animates the x and y positions and the opacity of an element. `in` transitions a
You can see the `fly` transition in action in the [transition tutorial](tutorial/adding-parameters-to-transitions).
```html
```sv
<script>
import { fly } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -656,7 +660,7 @@ Slides an element in and out.
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
```html
```sv
<script>
import { slide } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -693,7 +697,7 @@ Animates the opacity and scale of an element. `in` transitions animate from an e
* `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
```html
```sv
<script>
import { scale } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -731,7 +735,7 @@ Animates the stroke of an SVG element, like a snake in a tube. `in` transitions
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 double that duration and setting it to `2` will halve it.
```html
```sv
<script>
import { draw } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
@ -758,7 +762,7 @@ The `speed` parameter is a means of setting the duration of the transition relat
### `svelte/animate`
The `svelte/animate` module exports one function for use with svelte [animations](docs#Animations).
The `svelte/animate` module exports one function for use with Svelte [animations](docs#animate_fn).
#### `flip`
@ -785,7 +789,7 @@ The `flip` function calculates the start and end position of an element and anim
You can see a full example on the [animations tutorial](tutorial/animate)
```html
```sv
<script>
import { flip } from 'svelte/animate';
import { quintOut } from 'svelte/easing';
@ -804,7 +808,7 @@ You can see a full example on the [animations tutorial](tutorial/animate)
### `svelte/easing`
Easing functions specificy the rate of change over time and are useful when working with Svelte's built-in transitions and animations as well as the tweened and spring utilities. `svelte/easing` contains 31 named exports, a `linear` ease and 3 variants of 10 different easing functions: `in`, `out` and `inOut`.
Easing functions specify the rate of change over time and are useful when working with Svelte's built-in transitions and animations as well as the tweened and spring utilities. `svelte/easing` contains 31 named exports, a `linear` ease and 3 variants of 10 different easing functions: `in`, `out` and `inOut`.
You can explore the various eases using the [ease visualiser](examples#easing) in the [examples section](examples).
@ -973,8 +977,8 @@ app.count += 1;
Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](docs#svelte_options).
```html
<svelte:options tag="my-element">
```sv
<svelte:options tag="my-element" />
<script>
export let name = 'world';

@ -76,7 +76,7 @@ The following options can be passed to the compiler. None are required:
| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to `false` and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.
| `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`**
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than optimised by Svelte.
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than removed or collapsed to a single space where possible.
| `outputFilename` | `null` | A `string` used for your JavaScript sourcemap.
| `cssOutputFilename` | `null` | A `string` used for your CSS sourcemap.
| `sveltePath` | `"svelte"` | The location of the `svelte` package. Any imports from `svelte` or `svelte/[module]` will be modified accordingly.
@ -113,7 +113,8 @@ const {
* `module` is `true` if the value is declared in a `context="module"` script
* `mutated` is `true` if the value's properties are assigned to inside the component
* `reassigned` is `true` if the value is reassigned inside the component
* `referenced` is `true` if the value is used outside the declaration
* `referenced` is `true` if the value is used in the template
* `referenced_from_script` is `true` if the value is used in the `<script>` outside the declaration
* `writable` is `true` if the value was declared with `let` or `var` (but not `const`, `class` or `function`)
* `stats` is an object used by the Svelte developer team for diagnosing the compiler. Avoid relying on it to stay the same!
@ -144,6 +145,7 @@ compiled: {
mutated: boolean,
reassigned: boolean,
referenced: boolean,
referenced_from_script: boolean,
writable: boolean
}>,
stats: {
@ -181,11 +183,15 @@ const ast = svelte.parse(source, { filename: 'App.svelte' });
### `svelte.preprocess`
A number of [community-maintained preprocessing plugins](https://github.com/sveltejs/integrations#preprocessors) are available to allow you to use Svelte with tools like TypeScript, PostCSS, SCSS, and Less.
You can write your own preprocessor using the `svelte.preprocess` API.
```js
result: {
code: string,
dependencies: Array<string>
} = svelte.preprocess(
} = await svelte.preprocess(
source: string,
preprocessors: Array<{
markup?: (input: { content: string, filename: string }) => Promise<{
@ -222,7 +228,7 @@ The `markup` function receives the entire component source text, along with the
```js
const svelte = require('svelte/compiler');
const { code } = svelte.preprocess(source, {
const { code } = await svelte.preprocess(source, {
markup: ({ content, filename }) => {
return {
code: content.replace(/foo/g, 'bar')
@ -244,7 +250,7 @@ const svelte = require('svelte/compiler');
const sass = require('node-sass');
const { dirname } = require('path');
const { code, dependencies } = svelte.preprocess(source, {
const { code, dependencies } = await svelte.preprocess(source, {
style: async ({ content, attributes, filename }) => {
// only process <style lang="sass">
if (attributes.lang !== 'sass') return;
@ -277,7 +283,7 @@ Multiple preprocessors can be used together. The output of the first becomes the
```js
const svelte = require('svelte/compiler');
const { code } = svelte.preprocess(source, [
const { code } = await svelte.preprocess(source, [
{
markup: () => {
console.log('this runs first');

@ -18,7 +18,7 @@
Remove first thing
</button>
<div style="display: grid; grid-template-columns: 1fr 1fr; grip-gap: 1em">
<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 1em">
<div>
<h2>Keyed</h2>
{#each things as thing (thing.id)}

@ -1,9 +1,9 @@
<script>
import FancyButton from './FancyButton.svelte';
import CustomButton from './CustomButton.svelte';
function handleClick() {
alert('clicked');
}
</script>
<FancyButton on:click={handleClick}/>
<CustomButton on:click={handleClick}/>

@ -0,0 +1,22 @@
<style>
button {
height: 4rem;
width: 8rem;
background-color: #aaa;
border-color: #f1c40f;
color: #f1c40f;
font-size: 1.25rem;
background-image: linear-gradient(45deg, #f1c40f 50%, transparent 50%);
background-position: 100%;
background-size: 400%;
transition: background 300ms ease-in-out;
}
button:hover {
background-position: 0;
color: #aaa;
}
</style>
<button on:click>
Click me
</button>

@ -1,15 +0,0 @@
<style>
button {
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
padding: 0.5em 1em;
color: royalblue;
background: gold;
border-radius: 1em;
box-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
</style>
<button on:click>
Click me
</button>

@ -0,0 +1,37 @@
<script>
let files;
$: if (files) {
// Note that `files` is of type `FileList`, not an Array:
// https://developer.mozilla.org/en-US/docs/Web/API/FileList
console.log(files);
for (const file of files) {
console.log(`${file.name}: ${file.size} bytes`);
}
}
</script>
<label for="avatar">Upload a picture:</label>
<input
accept="image/png, image/jpeg"
bind:files
id="avatar"
name="avatar"
type="file"
/>
<label for="many">Upload multiple files of any type:</label>
<input
bind:files
id="many"
multiple
type="file"
/>
{#if files}
<h2>Selected files:</h2>
{#each Array.from(files) as file}
<p>{file.name} ({file.size} bytes) </p>
{/each}
{/if}

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

@ -109,8 +109,8 @@
<div>
<video
poster="http://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="http://sveltejs.github.io/assets/caminandes-llamigos.mp4"
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
bind:currentTime={time}

@ -20,7 +20,7 @@
const t = window.performance.now();
const r = 64 + (128 * x / canvas.width) + (64 * Math.sin(t / 1000));
const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1000));
const g = 64 + (128 * y / canvas.height) + (64 * Math.cos(t / 1400));
const b = 128;
imageData.data[p + 0] = r;

@ -20,7 +20,7 @@
];
function handleKeydown(event) {
if (event.which === 13) {
if (event.key === 'Enter') {
const text = event.target.value;
if (!text) return;

@ -4,7 +4,7 @@
let text = `Select some text and hit the tab key to toggle uppercase`;
async function handleKeydown(event) {
if (event.which !== 9) return;
if (event.key !== 'Tab') return;
event.preventDefault();

@ -4,7 +4,7 @@
function typewriter(node, { speed = 50 }) {
const valid = (
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === 3
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) {

@ -112,7 +112,7 @@
<input
class="new-todo"
placeholder="what needs to be done?"
on:keydown="{event => event.which === 13 && add(event.target)}"
on:keydown="{event => event.key === 'Enter' && add(event.target)}"
>
<div class='left'>

@ -3,6 +3,8 @@
export let item;
export let returnTo;
$: url = !item.domain ? `https://news.ycombinator.com/${item.url}` : item.url;
</script>
<style>
@ -24,9 +26,11 @@
<a href={returnTo}>&laquo; back</a>
<article>
<a href="{item.url}">
<a href="{url}">
<h1>{item.title}</h1>
<small>{item.domain}</small>
{#if item.domain}
<small>{item.domain}</small>
{/if}
</a>
<p class="meta">submitted by {item.user} {item.time_ago}

@ -7,6 +7,8 @@
const c = item.comments_count;
return `${c} ${c === 1 ? 'comment' : 'comments'}`;
}
$: url = item.type === "ask" ? `https://news.ycombinator.com/${item.url}` : item.url;
</script>
<style>
@ -33,6 +35,6 @@
<article>
<span>{i + offset + 1}</span>
<h2><a target="_blank" href={item.url}>{item.title}</a></h2>
<h2><a target="_blank" href={url}>{item.title}</a></h2>
<p class="meta"><a href="#/item/{item.id}">{comment_text()}</a> by {item.user} {item.time_ago}</p>
</article>

@ -0,0 +1,7 @@
---
question: I'm new to Svelte. Where should I start?
---
We think the best way to get started is playing through the interactive [Tutorial](tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.

@ -0,0 +1,5 @@
---
question: How can I update my components written in Svelte v2?
---
svelte-upgrade isn't fully working for v2->v3 yet, [but it's close](https://github.com/sveltejs/svelte-upgrade/pull/12).

@ -0,0 +1,7 @@
---
question: Is Svelte v2 still available?
---
New features aren't being added to it, and bugs will probably only be fixed if they are extremely nasty or present some sort of security vulnerability.
The documentation is still available [here](https://v2.svelte.dev/guide).

@ -0,0 +1,5 @@
---
question: How do I do hot module reloading?
---
Use the community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/rixo/svelte-loader-hot).

@ -0,0 +1,14 @@
---
question: Are there any video courses?
---
Rich Harris, the creator of Svelte, taught a course:
- [Frontend Masters](https://frontendmasters.com/courses/svelte/)
There are also a number of third-party courses:
- [Egghead](https://egghead.io/browse/frameworks/svelte)
- [Udemy](https://www.udemy.com/courses/search/?q=sveltejs+svelte)
Note that Udemy very frequently has discounts over 90%.

@ -0,0 +1,9 @@
---
question: Are there any books?
---
There are a few books:
- [Svelte Handbook](https://flaviocopes.com/page/download-svelte-handbook/) by Flavio Copes
- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/) by Alessandro Segala
- [Svelte and Sapper in Action](https://www.manning.com/books/svelte-and-sapper-in-action) by R. Mark Volkmann

@ -0,0 +1,5 @@
---
question: How can I get VS Code to syntax-highlight my .svelte files?
---
There is an [official VS Code extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).

@ -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.

@ -0,0 +1,20 @@
---
question: What about TypeScript support?
---
You need to install a preprocessor such as [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess). You can run type checking from the command line with [svelte-check](https://www.npmjs.com/package/svelte-check).
To declare the type of a reactive variable in a Svelte template, you should use the following syntax:
```
let x: number;
$: x = count + 1;
```
To import a type or interface make sure to use [TypeScript's `type` modifier](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export):
```
import type { SomeInterface } from './SomeFile';
```
You must use the `type` modifier because `svelte-preprocess` doesn't know whether an import is a type or a value — it only transpiles one file at a time without knowledge of the other files and therefore can't safely erase imports which only contain types without this modifier present.

@ -0,0 +1,5 @@
---
question: Does Svelte scale?
---
There will be a blog post about this eventually, but in the meantime, check out [this issue](https://github.com/sveltejs/svelte/issues/2546).

@ -0,0 +1,5 @@
---
question: Is there a UI component library?
---
There are several UI component libraries. Find them under the [code section](https://svelte-community.netlify.com/code) of the Svelte Community website.

@ -0,0 +1,6 @@
---
question: How do I test Svelte apps?
---
We don't have a good answer to this yet, but it is a priority. There are a few approaches that people take when testing, but it generally involves compiling the component and mounting it to something and then performing the tests.
You essentially need to create a bundle for each component you're testing (since svelte is a compiler and not a normal library) and then mount them. You can mount to a JSDOM instance, or you can use Puppeteer if you need a real browser, or you can use a tool like Cypress. There is an example of this in the Sapper starter template.

@ -0,0 +1,13 @@
---
question: Is there a router?
---
You can use any router lib you want. A lot of people use [page.js](https://github.com/visionmedia/page.js). There's also [navaid](https://github.com/lukeed/navaid), which is very similar.
If you prefer a declarative HTML approach, there's [svelte-routing](https://github.com/EmilTholin/svelte-routing).
If you need hash-based routing on the client side, check out [svelte-spa-router](https://github.com/ItalyPaleAle/svelte-spa-router), or [abstract-state-router](https://github.com/TehShrike/abstract-state-router/), a mature router for business software.
For filesystem-based routing, you can take a look at [Routify](https://routify.dev).
For an official solution, there's nothing that's simply a routing library. There is, however, the official [Sapper](https://sapper.svelte.dev/) framework, a Next.js-style application framework built on Svelte, which includes its own filesystem-based routing.

@ -20,3 +20,5 @@ Add a `<script>` tag that imports `Nested.svelte`...
```
Notice that even though `Nested.svelte` has a `<p>` element, the styles from `App.svelte` don't leak in.
Also notice that the component name `Nested` is capitalised. This convention has been adopted to allow us to differentiate between user-defined components and regular HTML tags.

@ -13,7 +13,7 @@ First, you'll need to integrate Svelte with a build tool. There are officially m
Don't worry if you're relatively new to web development and haven't used these tools before. We've prepared a simple step-by-step guide, [Svelte for new developers](blog/svelte-for-new-developers), which walks you through the process.
You'll also want to configure your text editor to treat `.svelte` files the same as `.html` for the sake of syntax highlighting. [Read this guide to learn how](blog/setting-up-your-editor).
You'll also want to configure your text editor. If you're using VS Code, install the [Svelte extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), otherwise follow [this guide](blog/setting-up-your-editor) to configure your text editor to treat `.svelte` files the same as `.html` for the sake of syntax highlighting.
Then, once you've got your project set up, using Svelte components is easy. The compiler turns each component into a regular JavaScript class — just import it and instantiate with `new`:

@ -2,7 +2,7 @@
title: Default values
---
We can easily specify default values for props:
We can easily specify default values for props in `Nested.svelte`:
```html
<script>

@ -2,7 +2,7 @@
title: Spread props
---
If you have an object of properties, you can 'spread' them on to a component instead of specifying each one:
If you have an object of properties, you can 'spread' them onto a component instead of specifying each one:
```html
<Info {...pkg}/>

@ -21,6 +21,7 @@ The full list of modifiers:
* `preventDefault` — calls `event.preventDefault()` before running the handler. Useful for client-side form handling, for example.
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
* `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase ([MDN docs](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture))
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself

@ -1,9 +1,9 @@
<script>
import FancyButton from './FancyButton.svelte';
import CustomButton from './CustomButton.svelte';
function handleClick() {
alert('clicked');
}
</script>
<FancyButton on:click={handleClick}/>
<CustomButton on:click={handleClick}/>

@ -0,0 +1,22 @@
<style>
button {
height: 4rem;
width: 8rem;
background-color: #aaa;
border-color: #f1c40f;
color: #f1c40f;
font-size: 1.25rem;
background-image: linear-gradient(45deg, #f1c40f 50%, transparent 50%);
background-position: 100%;
background-size: 400%;
transition: background 300ms ease-in-out;
}
button:hover {
background-position: 0;
color: #aaa;
}
</style>
<button>
Click me
</button>

@ -1,15 +0,0 @@
<style>
button {
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
padding: 0.5em 1em;
color: royalblue;
background: gold;
border-radius: 1em;
box-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
</style>
<button>
Click me
</button>

@ -1,9 +1,9 @@
<script>
import FancyButton from './FancyButton.svelte';
import CustomButton from './CustomButton.svelte';
function handleClick() {
alert('clicked');
}
</script>
<FancyButton on:click={handleClick}/>
<CustomButton on:click={handleClick}/>

@ -0,0 +1,22 @@
<style>
button {
height: 4rem;
width: 8rem;
background-color: #aaa;
border-color: #f1c40f;
color: #f1c40f;
font-size: 1.25rem;
background-image: linear-gradient(45deg, #f1c40f 50%, transparent 50%);
background-position: 100%;
background-size: 400%;
transition: background 300ms ease-in-out;
}
button:hover {
background-position: 0;
color: #aaa;
}
</style>
<button on:click>
Click me
</button>

@ -1,15 +0,0 @@
<style>
button {
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
padding: 0.5em 1em;
color: royalblue;
background: gold;
border-radius: 1em;
box-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
</style>
<button on:click>
Click me
</button>

@ -4,7 +4,7 @@ title: DOM event forwarding
Event forwarding works for DOM events too.
We want to get notified of clicks on our `<FancyButton>` — to do that, we just need to forward `click` events on the `<button>` element in `FancyButton.svelte`:
We want to get notified of clicks on our `<CustomButton>` — to do that, we just need to forward `click` events on the `<button>` element in `CustomButton.svelte`:
```html
<button on:click>

@ -33,11 +33,12 @@ The complete set of bindings for `<audio>` and `<video>` is as follows — six *
* `seeking` (readonly) — boolean
* `ended` (readonly) — boolean
...and four *two-way* bindings:
...and five *two-way* bindings:
* `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where `1` is 'normal'
* `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1
* `muted` — a boolean value where true is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings.

@ -20,7 +20,7 @@
];
function handleKeydown(event) {
if (event.which === 13) {
if (event.key === 'Enter') {
const text = event.target.value;
if (!text) return;

@ -20,7 +20,7 @@
];
function handleKeydown(event) {
if (event.which === 13) {
if (event.key === 'Enter') {
const text = event.target.value;
if (!text) return;

@ -2,7 +2,7 @@
let text = `Select some text and hit the tab key to toggle uppercase`;
async function handleKeydown(event) {
if (event.which !== 9) return;
if (event.key !== 'Tab') return;
event.preventDefault();

@ -4,7 +4,7 @@
let text = `Select some text and hit the tab key to toggle uppercase`;
async function handleKeydown(event) {
if (event.which !== 9) return;
if (event.key !== 'Tab') return;
event.preventDefault();

@ -4,7 +4,7 @@ title: tick
The `tick` function is unlike other lifecycle functions in that you can call it any time, not just when the component first initialises. It returns a promise that resolves as soon as any pending state changes have been applied to the DOM (or immediately, if there are no pending state changes).
When you invalidate component state in Svelte, it doesn't update the DOM immediately. Instead, it waits until the next *microtask* to see if there are any other changes that need to be applied, including in other components. Doing so avoids unnecessary work and allows the browser to batch things more effectively.
When you update component state in Svelte, it doesn't update the DOM immediately. Instead, it waits until the next *microtask* to see if there are any other changes that need to be applied, including in other components. Doing so avoids unnecessary work and allows the browser to batch things more effectively.
You can see that behaviour in this example. Select a range of text and hit the tab key. Because the `<textarea>` value changes, the current selection is cleared and the cursor jumps, annoyingly, to the end. We can fix this by importing `tick`...

@ -4,7 +4,7 @@
function typewriter(node, { speed = 50 }) {
const valid = (
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === 3
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) {

@ -8,7 +8,7 @@ While you should generally use CSS for transitions as much as possible, there ar
function typewriter(node, { speed = 50 }) {
const valid = (
node.childNodes.length === 1 &&
node.childNodes[0].nodeType === 3
node.childNodes[0].nodeType === Node.TEXT_NODE
);
if (!valid) {

@ -56,7 +56,7 @@
<div class='board'>
<input
placeholder="what needs to be done?"
on:keydown={e => e.which === 13 && add(e.target)}
on:keydown={e => e.key === 'Enter' && add(e.target)}
>
<div class='left'>

@ -56,7 +56,7 @@
<div class='board'>
<input
placeholder="what needs to be done?"
on:keydown={e => e.which === 13 && add(e.target)}
on:keydown={e => e.key === 'Enter' && add(e.target)}
>
<div class='left'>

@ -56,7 +56,7 @@
<div class='board'>
<input
placeholder="what needs to be done?"
on:keydown={e => e.which === 13 && add(e.target)}
on:keydown={e => e.key === 'Enter' && add(e.target)}
>
<div class='left'>

@ -57,7 +57,7 @@
<div class='board'>
<input
placeholder="what needs to be done?"
on:keydown={e => e.which === 13 && add(e.target)}
on:keydown={e => e.key === 'Enter' && add(e.target)}
>
<div class='left'>

@ -7,23 +7,23 @@
display: block;
}
.active {
.selected {
background-color: #ff3e00;
color: white;
}
</style>
<button
class="{current === 'foo' ? 'active' : ''}"
class="{current === 'foo' ? 'selected' : ''}"
on:click="{() => current = 'foo'}"
>foo</button>
<button
class="{current === 'bar' ? 'active' : ''}"
class="{current === 'bar' ? 'selected' : ''}"
on:click="{() => current = 'bar'}"
>bar</button>
<button
class="{current === 'baz' ? 'active' : ''}"
class="{current === 'baz' ? 'selected' : ''}"
on:click="{() => current = 'baz'}"
>baz</button>

@ -7,23 +7,23 @@
display: block;
}
.active {
.selected {
background-color: #ff3e00;
color: white;
}
</style>
<button
class:active="{current === 'foo'}"
class:selected="{current === 'foo'}"
on:click="{() => current = 'foo'}"
>foo</button>
<button
class:active="{current === 'bar'}"
class:selected="{current === 'bar'}"
on:click="{() => current = 'bar'}"
>bar</button>
<button
class:active="{current === 'baz'}"
class:selected="{current === 'baz'}"
on:click="{() => current = 'baz'}"
>baz</button>

@ -6,7 +6,7 @@ Like any other attribute, you can specify classes with a JavaScript attribute, s
```html
<button
class="{current === 'foo' ? 'active' : ''}"
class="{current === 'foo' ? 'selected' : ''}"
on:click="{() => current = 'foo'}"
>foo</button>
```
@ -15,9 +15,9 @@ This is such a common pattern in UI development that Svelte includes a special d
```html
<button
class:active="{current === 'foo'}"
class:selected="{current === 'foo'}"
on:click="{() => current = 'foo'}"
>foo</button>
```
The `active` class is added to the element whenever the value of the expression is truthy, and removed when it's falsy.
The `selected` class is added to the element whenever the value of the expression is truthy, and removed when it's falsy.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save