Merge branch 'master' into dynamic-elements-implementation

pull/5481/head
Simon Holthausen 5 years ago
commit 7d308cbb95

@ -0,0 +1 @@
open_collective: svelte

@ -1,56 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'Bug'
assignees: ''
---
## Is this about svelte@next? This project is currently in a pre-release stage and breaking changes may occur at any time. Please do not post any kind of bug reports or questions on GitHub about it.
**Describe the bug**
A clear and concise description of what the bug is.
**Logs**
Please include browser console and server logs around the time this bug occurred.
**To Reproduce**
To help us help you, if you've found a bug please consider the following:
* If you can demonstrate the bug using https://svelte.dev/repl, please do.
* If that's not possible, we recommend creating a small repo that illustrates the problem.
* Reproductions should be small, self-contained, correct examples http://sscce.org.
Occasionally, this won't be possible, and that's fine we still appreciate you raising the issue. But please understand that Svelte is run by unpaid volunteers in their free time, and issues that follow these instructions will get fixed faster.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Stacktraces**
If you have a stack trace to include, we recommend putting inside a `<details>` block for the sake of the thread's readability:
<details>
<summary>Stack trace</summary>
Stack trace goes here...
</details>
**Information about your Svelte project:**
To make your life easier, just run `npx envinfo --system --npmPackages svelte,rollup,webpack --binaries --browsers` and paste the output here.
- Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, IE 10)
- Your operating system: (e.x. OS X 10, Ubuntu Linux 19.10, Windows XP, etc)
- Svelte version (Please check you can reproduce the issue with the latest release!)
- Whether your project uses Webpack or Rollup
**Severity**
How severe an issue is this bug to you? Is this annoying, blocking some users, blocking an upgrade or blocking your usage of Svelte entirely?
Note: the more honest and specific you are here the more we will take you seriously.
**Additional context**
Add any other context about the problem here.

@ -0,0 +1,50 @@
name: "\U0001F41E Bug report"
description: Report an issue with Svelte
labels: ["triage: bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: bug-description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
placeholder: Bug description
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction
description: Please provide a link to a repo or REPL that can reproduce the problem you ran into. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "need reproduction" label. If no reproduction is provided within a reasonable time-frame, the issue will be closed.
placeholder: Reproduction
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: "Please include browser console and server logs around the time this bug occurred. Optional if provided reproduction. Please try not to insert an image but copy paste the log text."
render: shell
- type: textarea
id: system-info
attributes:
label: System Info
description: Output of `npx envinfo --system --npmPackages svelte,rollup,webpack --binaries --browsers`
render: shell
placeholder: System, Binaries, Browsers
validations:
required: true
- type: dropdown
id: severity
attributes:
label: Severity
description: Select the severity of this issue
options:
- annoyance
- blocking an upgrade
- blocking all usage of svelte
validations:
required: true

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Discord Chat
url: https://svelte.dev/chat
about: Ask questions and discuss with other Svelte users in real time.

@ -1,28 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'New Feature'
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 [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**How important is this feature to you?**
Note: the more honest and specific you are here the more we will take you seriously.
**Additional context**
Add any other context or screenshots about the feature request here.

@ -0,0 +1,42 @@
name: "Feature Request"
description: Request a new Svelte feature
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to request this feature! If your feature request is complex or substantial enough to warrant in-depth discussion, maintainers may close the issue and ask you to open an [RFC](https://github.com/sveltejs/rfcs).
- type: textarea
id: problem
attributes:
label: Describe the problem
description: Please provide a clear and concise description the problem this feature would solve. The more information you can provide here, the better.
placeholder: I'm always frustrated when...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the proposed solution
description: Please provide a clear and concise description of what you would like to happen.
placeholder: I would like to see...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: "Please provide a clear and concise description of any alternative solutions or features you've considered."
validations:
required: true
- type: dropdown
id: importance
attributes:
label: Importance
description: How important is this feature to you?
options:
- nice to have
- would make my life easier
- i cannot use svelte without it
validations:
required: true

@ -1,12 +0,0 @@
---
name: Questions and help
about: If you think you need help with something related to Svelte
title: ''
labels: 'Question'
assignees: ''
---
This issue tracker is intended to collect bug reports and feature requests.
For help with installation, information on how features work, or questions about specific features of Svelte, please come and join us in the [Svelte Discord](https://svelte.dev/chat), or ask your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte). Any issues open for help requests will be closed to keep from clogging up the issue tracker.

@ -1,5 +1,6 @@
### Before submitting the PR, please make sure you do the following ### Before submitting the PR, please make sure you do the following
- [ ] 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 - [ ] 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
- [ ] Prefix your PR title with `[feat]`, `[fix]`, `[chore]`, or `[docs]`.
- [ ] This message body should clearly illustrate what problems it solves. - [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it. - [ ] Ideally, include a test that fails without this PR but passes with it.

52
.github/stale.yml vendored

@ -0,0 +1,52 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- popular
- pinned
- security
- bug
- "[Status] Maybe Later"
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale-bot
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
pulls:
daysUntilStale: 210
daysUntilClose: 25
markComment: >
This pull request has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
closeComment: >
This pull request has been closed as it was previously marked as stale and saw no subsequent activity.
issues:
daysUntilStale: 180
daysUntilClose: 14
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
closeComment: >
This issue has been closed as it was previously marked as stale and saw no subsequent activity.

@ -3,58 +3,39 @@ on: [push, pull_request]
jobs: jobs:
Tests: Tests:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 10 timeout-minutes: 15
strategy: strategy:
matrix: matrix:
node-version: [8, 10, 12, 14] node-version: [8, 10, 12, 14]
os: [ubuntu-latest, windows-latest, macOS-latest] os: [ubuntu-latest, windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- uses: actions/setup-node@v1 - uses: actions/setup-node@v2
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- id: npm-cache-dir cache: npm
run: echo "::set-output name=dir::$(npm config get cache)" - run: npm install
- uses: actions/cache@v2 - run: npm test
id: npm-cache env:
with: CI: true
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
- run: npm install
- run: npm test
env:
CI: true
Lint: Lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 2 timeout-minutes: 5
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- uses: actions/setup-node@v1 - uses: actions/setup-node@v2
- id: npm-cache-dir with:
run: echo "::set-output name=dir::$(npm config get cache)" cache: npm
- uses: actions/cache@v2 - run: 'npm i && npm run lint'
id: npm-cache
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
- run: 'npm i && npm run lint'
Unit: Unit:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 5 timeout-minutes: 10
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, windows-latest, macOS-latest] os: [ubuntu-latest, windows-latest, macOS-latest]
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- uses: actions/setup-node@v1 - uses: actions/setup-node@v2
- id: npm-cache-dir with:
run: echo "::set-output name=dir::$(npm config get cache)" cache: npm
- uses: actions/cache@v2 - run: 'npm i && npm run test:unit'
id: npm-cache
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-node-
- run: 'npm i && npm run test:unit'

@ -0,0 +1,28 @@
name: Docs
on:
push:
branches:
- master
paths:
- site/content/**
jobs:
release:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: my-app-install token
id: github-app
uses: getsentry/action-github-app-token@v1
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: run deploy docs workflow
uses: 'sveltejs/action-deploy-docs/dispatch@main'
with:
repo: 'svelte'
branch: 'master'
docs_path: 'site/content'
token: ${{ steps.github-app.outputs.token }}

3
.gitignore vendored

@ -8,6 +8,7 @@ node_modules
/compiler.d.ts /compiler.d.ts
/compiler.*js /compiler.*js
/index.*js /index.*js
/ssr.*js
/internal /internal
/store /store
/easing /easing
@ -30,8 +31,6 @@ _output
/site/static/svelte-app.json /site/static/svelte-app.json
/site/static/contributors.jpg /site/static/contributors.jpg
/site/static/workers /site/static/workers
/site/static/organisations
/site/scripts/svelte-app /site/scripts/svelte-app
/site/scripts/community /site/scripts/community
/site/src/routes/_contributors.js /site/src/routes/_contributors.js
/site/src/routes/_components/WhosUsingSvelte.*

@ -1,5 +1,149 @@
# Svelte changelog # Svelte changelog
## 3.43.0
* Use export map to expose no-op versions of lifecycle functions for SSR ([#6743](https://github.com/sveltejs/svelte/pull/6743))
* Prefer `context` passed to component constructor, even when running synchronously in another component ([#6753](https://github.com/sveltejs/svelte/issues/6753))
* Handle preprocessors that return empty sourcemaps ([#6757](https://github.com/sveltejs/svelte/pull/6757))
## 3.42.6
* Hide private preprocess typings ([#6622](https://github.com/sveltejs/svelte/issues/6622))
* Fix reactive function in `{:else if}` expression not being properly re-run ([#6727](https://github.com/sveltejs/svelte/pull/6727))
## 3.42.5
* In `draw` transition, account for `stroke-linecap` in determining length ([#4540](https://github.com/sveltejs/svelte/issues/4540))
* Fix regression with destructuring assignments with default values ([#6699](https://github.com/sveltejs/svelte/issues/6699))
## 3.42.4
* Only apply optimized `src` attribute handling when in an `html` namespace ([#6575](https://github.com/sveltejs/svelte/issues/6575))
* Fix styles for transitions and animations being attached to the wrong `document` in `<iframe>`s ([#6637](https://github.com/sveltejs/svelte/issues/6637))
* Fix `<select>` with a `{...spread}` attribute that didn't provide a `value` key getting its value improperly unset ([#6675](https://github.com/sveltejs/svelte/issues/6675))
## 3.42.3
* Add `BigInt` as a known global ([#6671](https://github.com/sveltejs/svelte/pull/6671))
* Fix regression where `onDestroy` in `svelte/ssr` was improperly a no-op ([#6676](https://github.com/sveltejs/svelte/issues/6676))
## 3.42.2
* Collapse whitespace in `class` and `style` attributes ([#6004](https://github.com/sveltejs/svelte/issues/6004))
* Deselect all `<option>`s in a `<select>` where the bound `value` doesn't match any of them ([#6126](https://github.com/sveltejs/svelte/issues/6126))
* In hydrated components, only rely on helpers for creating the types of elements present in the component ([#6555](https://github.com/sveltejs/svelte/issues/6555))
* Add `HTMLElement` and `SVGElement` as known globals ([#6643](https://github.com/sveltejs/svelte/issues/6643))
* Account for scaling in `flip` animations ([#6657](https://github.com/sveltejs/svelte/issues/6657))
## 3.42.1
* Fix regression with reordering keyed `{#each}` blocks when compiling with hydration enabled ([#6561](https://github.com/sveltejs/svelte/issues/6561))
## 3.42.0
* Allow `use:actions` to be used on `<svelte:body>` ([#3163](https://github.com/sveltejs/svelte/issues/3163))
* Improve parser errors for certain invalid components ([#6259](https://github.com/sveltejs/svelte/issues/6259), [#6288](https://github.com/sveltejs/svelte/issues/6288))
* Fix paths in generator JS sourcemaps to be relative ([#6598](https://github.com/sveltejs/svelte/pull/6598))
* Fix overzealous warnings about `context="module"` variables not being reactive ([#6606](https://github.com/sveltejs/svelte/issues/6606))
## 3.41.0
* Support `export { ... } from` syntax in components ([#2214](https://github.com/sveltejs/svelte/issues/2214))
* Support `export let { ... } =` syntax in components ([#5612](https://github.com/sveltejs/svelte/issues/5612))
* Support `{#await ... then/catch}` without a variable for the resolved/rejected value ([#6270](https://github.com/sveltejs/svelte/issues/6270))
## 3.40.3
* Fix `<slot>` data when a transition is cancelled before completing ([#5394](https://github.com/sveltejs/svelte/issues/5394))
* Fix destructuring into variables beginning with `$` so that they result in store updates ([#5653](https://github.com/sveltejs/svelte/issues/5653))
* Fix `in:` transition configuration not properly updating when it's changed after its initial creation ([#6505](https://github.com/sveltejs/svelte/issues/6505))
* Fix applying `:global()` for `>` selector combinator ([#6550](https://github.com/sveltejs/svelte/issues/6550))
* Fix mounting component at detached DOM node ([#6567](https://github.com/sveltejs/svelte/issues/6567))
## 3.40.2
* Fix dynamic `autofocus={...}` attribute handling ([#4995](https://github.com/sveltejs/svelte/issues/4995))
* Add filename to combined source map if needed ([#6089](https://github.com/sveltejs/svelte/pull/6089))
* In AST, parse empty attribute values as an empty string ([#6286](https://github.com/sveltejs/svelte/issues/6286))
* Fix tracking whether transition has started ([#6399](https://github.com/sveltejs/svelte/pull/6399))
* Fix incorrect scoping of `:global()` selectors ([#6550](https://github.com/sveltejs/svelte/issues/6550))
## 3.40.1
* Fix store reactivity regression when using reactive statements ([#6557](https://github.com/sveltejs/svelte/issues/6557))
## 3.40.0
* Support rendering a component in a shadow DOM ([#5869](https://github.com/sveltejs/svelte/issues/5869))
* Fix `:root` selector being erroneously scoped to component ([#4767](https://github.com/sveltejs/svelte/issues/4767))
* Fix `.end` in AST for expressions inside attributes ([#6258](https://github.com/sveltejs/svelte/issues/6258))
* Fix one-way `<select>` binding when it has a spread attribute ([#6433](https://github.com/sveltejs/svelte/issues/6433))
* Various hydration improvements and fixes ([#6449](https://github.com/sveltejs/svelte/pull/6449))
* Use smaller versions of internal helpers when compiling without hydration support ([#6462](https://github.com/sveltejs/svelte/issues/6462))
* Fix two-way binding of values when updating through synchronous component accessors ([#6502](https://github.com/sveltejs/svelte/issues/6502))
## 3.39.0
* Support `bind:group` in SSR ([#4621](https://github.com/sveltejs/svelte/pull/4621))
* Add a11y warning `a11y-mouse-events-have-key-events` which checks that `mouseover`/`mouseout` are accompanied by `focus`/`blur` event handlers ([#5938](https://github.com/sveltejs/svelte/pull/5938))
* Make it possible to silence more warnings ([#5954](https://github.com/sveltejs/svelte/issues/5954))
* Add `|trusted` event modifier ([#6137](https://github.com/sveltejs/svelte/issues/6137))
* Add `varsReport` compiler option to include all variables reference in the component in the `variables` report ([#6192](https://github.com/sveltejs/svelte/pull/6192))
* Add `errorMode` compiler option to try to continue compiling when an error is detected ([#6194](https://github.com/sveltejs/svelte/pull/6194))
* Expose `svelte/ssr` which exports lifecycle methods as no-ops ([#6416](https://github.com/sveltejs/svelte/pull/6416))
* Add `getAllContexts` ([#6447](https://github.com/sveltejs/svelte/issues/6447))
* Throw proper error for `export default function() {}` and `export default class {}` rather than crashing the compiler ([#3275](https://github.com/sveltejs/svelte/issues/3275))
* Fix SSR rendering of falsy `input` values ([#4551](https://github.com/sveltejs/svelte/issues/4551))
* Fix `preserveComments` in SSR mode ([#4730](https://github.com/sveltejs/svelte/issues/4730))
* Do not warn if `context="module"` variables are not the only dependencies in reactive statements ([#5954](https://github.com/sveltejs/svelte/issues/5954))
* Stop checking `a11y-media-has-caption` a11y warning on `<audio>` elements ([#6054](https://github.com/sveltejs/svelte/issues/6054))
* Fix erroneous "unknown prop" warning when using slot on a component ([#6065](https://github.com/sveltejs/svelte/pull/6065))
* Add sourcemaps to all HTML elements ([#6092](https://github.com/sveltejs/svelte/issues/6092))
* Relax `derived` function signature ([#6178](https://github.com/sveltejs/svelte/issues/6178))
* Throw compiler error when passing empty directive names ([#6299](https://github.com/sveltejs/svelte/issues/6299))
* Fix compiler error when using `:where()` inside `:global()` ([#6434](https://github.com/sveltejs/svelte/issues/6434))
* Fix ordering of elements in keyed `{#each}` ([#6444](https://github.com/sveltejs/svelte/issues/6444))
* Remove deprecated a11y warning `a11y-no-onchange warning` ([#6457](https://github.com/sveltejs/svelte/issues/6457))
* Fix `:global()` with pseudo element not being seen as global ([#6468](https://github.com/sveltejs/svelte/issues/6468))
* Allow `:global()` to contain multiple selectors when it is not part of a larger selector ([#6477](https://github.com/sveltejs/svelte/issues/6477))
* Make `<script>` and `<style>` end tag parsing more robust ([#6511](https://github.com/sveltejs/svelte/pull/6511))
## 3.38.3
* Speed up hydration by reducing amount of element reorderings ([#4308](https://github.com/sveltejs/svelte/issues/4308))
* Fix escaping attribute values when using a spread in SSR ([#5756](https://github.com/sveltejs/svelte/issues/5756))
* Throw compiler error when `:global()` contains multiple selectors ([#5907](https://github.com/sveltejs/svelte/issues/5907))
* Give explicit error rather than crashing when an attribute shorthand `{}` is empty ([#6086](https://github.com/sveltejs/svelte/issues/6086))
* Make `<textarea>` end tag parsing more robust ([#6276](https://github.com/sveltejs/svelte/issues/6276))
* Fix `:global(...):some-pseudoclass` selectors not being seen as global ([#6306](https://github.com/sveltejs/svelte/issues/6306))
* Fix type signatures of `writable` and `readable` so it's possible to call them without arguments ([#6291](https://github.com/sveltejs/svelte/issues/6291), [#6345](https://github.com/sveltejs/svelte/issues/6345))
* Preserve `this` in bubbled events ([#6310](https://github.com/sveltejs/svelte/issues/6310))
* Fix slot props not updating when transition is aborted ([#6386](https://github.com/sveltejs/svelte/issues/6386))
* Fix generic props relationship in `SvelteComponentTyped` ([#6400](https://github.com/sveltejs/svelte/pull/6400))
## 3.38.2
* Revert hydration optimisation for the time being ([#6279](https://github.com/sveltejs/svelte/issues/6279))
## 3.38.1
* Fix hydration regression ([#6274](https://github.com/sveltejs/svelte/issues/6274))
## 3.38.0
* Avoid recreating DOM elements during hydration ([#1067](https://github.com/sveltejs/svelte/issues/1067))
* Support passing CSS custom properties to component ([#5628](https://github.com/sveltejs/svelte/issues/5628))
* Support `:global()` as part of compound CSS selectors ([#6222](https://github.com/sveltejs/svelte/issues/6222))
* Fix updating `<slot>` contents when there's an aborted transition ([#3542](https://github.com/sveltejs/svelte/issues/3542))
* Fix setting boolean attributes on custom elements ([#5951](https://github.com/sveltejs/svelte/issues/5951))
* Add missing function overload for `derived` to allow explicitly setting an initial value for non-async derived stores ([#6172](https://github.com/sveltejs/svelte/pull/6172))
* Fix dynamic `href` values erroneously triggering a11y warnings ([#5990](https://github.com/sveltejs/svelte/issues/5990))
* Fix scope leak when updating an `{#await}` block ([#6173](https://github.com/sveltejs/svelte/issues/6173))
* Pass full markup source to `script`/`style` preprocessors ([#6169](https://github.com/sveltejs/svelte/pull/6169))
* Fix `crossfade` types to mark `fallback` as optional ([#6201](https://github.com/sveltejs/svelte/pull/6201))
* Add missing "context" typing to `SvelteComponent` constructor options ([#6236](https://github.com/sveltejs/svelte/pull/6236))
* Don't automatically switch to `svg` namespace when in `foreign` namespace ([#6257](https://github.com/sveltejs/svelte/issues/6257))
## 3.37.0 ## 3.37.0
* Allow root-level context to be passed to the component constructor ([#6032](https://github.com/sveltejs/svelte/pull/6032)) * Allow root-level context to be passed to the component constructor ([#6032](https://github.com/sveltejs/svelte/pull/6032))
@ -1897,7 +2041,7 @@ Also:
## 1.10.3 ## 1.10.3
* Prevent `'</script>'` string occurence breaking pages ([#349](https://github.com/sveltejs/svelte/pull/349)) * Prevent `'</script>'` string occurrence breaking pages ([#349](https://github.com/sveltejs/svelte/pull/349))
* Allow reference to whitelisted globals without properties ([#333](https://github.com/sveltejs/svelte/pull/333)) * Allow reference to whitelisted globals without properties ([#333](https://github.com/sveltejs/svelte/pull/333))
* Don't remove `&nbsp;` incorrectly ([#348](https://github.com/sveltejs/svelte/issues/348)) * Don't remove `&nbsp;` incorrectly ([#348](https://github.com/sveltejs/svelte/issues/348))
* `let` -> `var` in `addCss` block ([#351](https://github.com/sveltejs/svelte/pull/351)) * `let` -> `var` in `addCss` block ([#351](https://github.com/sveltejs/svelte/pull/351))

@ -12,7 +12,7 @@ The [Open Source Guides](https://opensource.guide/) website has a collection of
There are many ways to contribute to Svelte, and many of them do not involve writing any code. Here's a few ideas to get started: There are many ways to contribute to Svelte, and many of them do not involve writing any code. Here's a few ideas to get started:
- Simply start using Svelte. Go through the [Getting Started](https://svelte.dev/blog/the-easiest-way-to-get-started) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](#reporting-new-issues). - Simply start using Svelte. Go through the [Getting Started](https://svelte.dev/blog/the-easiest-way-to-get-started) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](#reporting-new-issues).
- Look through the [open issues](https://github.com/sveltejs/svelte/issues). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests). - Look through the [open issues](https://github.com/sveltejs/svelte/issues). A good starting point would be issues tagged [good first issue](https://github.com/sveltejs/svelte/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests).
- If you find an issue you would like to fix, [open a pull request](#your-first-pull-request). - If you find an issue you would like to fix, [open a pull request](#your-first-pull-request).
- Read through our [tutorials](https://svelte.dev/tutorial/basics). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this chapter" at the bottom left of the tutorial page. - Read through our [tutorials](https://svelte.dev/tutorial/basics). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this chapter" at the bottom left of the tutorial page.
- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/enhancement) by others in the community and consider opening a pull request if you see something you want to work on. - Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/enhancement) by others in the community and consider opening a pull request if you see something you want to work on.

@ -1,17 +1,7 @@
<p> [![Cybernetically enhanced web apps: Svelte](https://sveltejs.github.io/assets/banner.png)](https://svelte.dev)
<a href="https://svelte.dev">
<img alt="Cybernetically enhanced web apps: Svelte" src="https://sveltejs.github.io/assets/banner.png">
</a> [![npm version](https://img.shields.io/npm/v/svelte.svg)](https://www.npmjs.com/package/svelte) [![license](https://img.shields.io/npm/l/svelte.svg)](LICENSE.md) [![Chat](https://img.shields.io/discord/457912077277855764?label=chat&logo=discord)](https://svelte.dev/chat)
<a href="https://www.npmjs.com/package/svelte">
<img src="https://img.shields.io/npm/v/svelte.svg" alt="npm version">
</a>
<a href="https://github.com/sveltejs/svelte/blob/master/LICENSE">
<img src="https://img.shields.io/npm/l/svelte.svg" alt="license">
</a>
<a href="https://svelte.dev/chat">
<img src="https://img.shields.io/discord/457912077277855764?label=chat&logo=discord" alt="Chat">
</a>
</p>
## What is Svelte? ## What is Svelte?
@ -82,4 +72,4 @@ Probably not, but it's possible. If you can't seem to access any `.dev` sites, c
## License ## License
[MIT](LICENSE) [MIT](LICENSE.md)

7679
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
{ {
"name": "svelte", "name": "svelte",
"version": "3.37.0", "version": "3.43.0",
"description": "Cybernetically enhanced web apps", "description": "Cybernetically enhanced web apps",
"module": "index.mjs", "module": "index.mjs",
"main": "index", "main": "index",
@ -9,6 +9,7 @@
"compiler.*", "compiler.*",
"register.js", "register.js",
"index.*", "index.*",
"ssr.*",
"internal", "internal",
"store", "store",
"animate", "animate",
@ -21,6 +22,10 @@
"exports": { "exports": {
"./package.json": "./package.json", "./package.json": "./package.json",
".": { ".": {
"node": {
"import": "./ssr.mjs",
"require": "./ssr.js"
},
"import": "./index.mjs", "import": "./index.mjs",
"require": "./index.js" "require": "./index.js"
}, },
@ -54,6 +59,10 @@
"./transition": { "./transition": {
"import": "./transition/index.mjs", "import": "./transition/index.mjs",
"require": "./transition/index.js" "require": "./transition/index.js"
},
"./ssr": {
"import": "./ssr.mjs",
"require": "./ssr.js"
} }
}, },
"engines": { "engines": {
@ -102,28 +111,28 @@
"@rollup/plugin-sucrase": "^3.1.0", "@rollup/plugin-sucrase": "^3.1.0",
"@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-typescript": "^2.0.1",
"@rollup/plugin-virtual": "^2.0.0", "@rollup/plugin-virtual": "^2.0.0",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.6.0", "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.7.0",
"@types/mocha": "^7.0.0", "@types/mocha": "^7.0.0",
"@types/node": "^8.10.53", "@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^4.9.0", "@typescript-eslint/eslint-plugin": "^4.31.2",
"@typescript-eslint/parser": "^4.9.0", "@typescript-eslint/parser": "^4.31.2",
"acorn": "^7.4.0", "acorn": "^8.4.1",
"agadoo": "^1.1.0", "agadoo": "^1.1.0",
"c8": "^5.0.1", "c8": "^5.0.1",
"code-red": "^0.1.4", "code-red": "^0.2.2",
"codecov": "^3.5.0", "codecov": "^3.5.0",
"css-tree": "^1.1.2", "css-tree": "^1.1.2",
"eslint": "^7.15.0", "eslint": "^7.32.0",
"eslint-plugin-import": "^2.22.1", "eslint-plugin-import": "^2.24.2",
"eslint-plugin-svelte3": "^2.7.3", "eslint-plugin-svelte3": "^3.2.1",
"estree-walker": "^1.0.0", "estree-walker": "^3.0.0",
"is-reference": "^1.1.4", "is-reference": "^3.0.0",
"jsdom": "^15.1.1", "jsdom": "^15.2.1",
"kleur": "^3.0.3", "kleur": "^3.0.3",
"locate-character": "^2.0.5", "locate-character": "^2.0.5",
"magic-string": "^0.25.3", "magic-string": "^0.25.3",
"mocha": "^7.0.0", "mocha": "^7.0.0",
"periscopic": "^2.0.1", "periscopic": "^3.0.4",
"puppeteer": "^2.1.1", "puppeteer": "^2.1.1",
"rollup": "^1.27.14", "rollup": "^1.27.14",
"source-map": "^0.7.3", "source-map": "^0.7.3",

@ -42,6 +42,24 @@ export default [
plugins: [ts_plugin] plugins: [ts_plugin]
}, },
{
input: `src/runtime/ssr.ts`,
output: [
{
file: `ssr.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}/index.mjs`
},
{
file: `ssr.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}/index.js`
}
],
external,
plugins: [ts_plugin]
},
...fs.readdirSync('src/runtime') ...fs.readdirSync('src/runtime')
.filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory()) .filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory())
.map(dir => ({ .map(dir => ({

@ -6,12 +6,17 @@ Set up the site sub-project:
git clone https://github.com/sveltejs/svelte.git git clone https://github.com/sveltejs/svelte.git
cd site cd site
npm ci npm ci
npm run update
npm run dev npm run dev
``` ```
and navigate to [localhost:3000](http://localhost:3000). and navigate to [localhost:3000](http://localhost:3000).
The first time you run the site locally, it will update the list of Contributors and REPL dependencies. After this it won't run again unless you force it by running:
```bash
npm run update
```
## Running using the 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. 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.
@ -25,7 +30,6 @@ npm ci
PUBLISH=1 npm run build PUBLISH=1 npm run build
cd site cd site
npm ci npm ci
npm run update
npm run dev npm run dev
``` ```
@ -54,9 +58,9 @@ To build the website, run `npm run build`. The output can be found in `__sapper_
Tests can be run using `npm run test`. Tests can be run using `npm run test`.
## Linking `@sveltejs/site-kit` and `@sveltejs/site-repl` ## Linking `@sveltejs/site-kit` and `@sveltejs/svelte-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`. This site depends on `@sveltejs/site-kit` (a collection of styles, components and icons used in common by *.svelte.dev websites), and `@sveltejs/svelte-repl`.
In order to work on features that depend on those packages, you need to [link](https://docs.npmjs.com/cli/link) their repositories: In order to work on features that depend on those packages, you need to [link](https://docs.npmjs.com/cli/link) their repositories:

@ -1,5 +1,5 @@
--- ---
title: Frameworks without the framework: why didn't we think of this sooner? title: "Frameworks without the framework: why didn't we think of this sooner?"
description: You can't write serious applications in vanilla JavaScript without hitting a complexity wall. But a compiler can do it for you. description: You can't write serious applications in vanilla JavaScript without hitting a complexity wall. But a compiler can do it for you.
author: Rich Harris author: Rich Harris
authorURL: https://twitter.com/Rich_Harris authorURL: https://twitter.com/Rich_Harris

@ -1,5 +1,5 @@
--- ---
title: Sapper: Towards the ideal web app framework title: "Sapper: Towards the ideal web app framework"
description: Taking the next-plus-one step description: Taking the next-plus-one step
author: Rich Harris author: Rich Harris
authorURL: https://twitter.com/Rich_Harris authorURL: https://twitter.com/Rich_Harris

@ -1,5 +1,5 @@
--- ---
title: Svelte 3: Rethinking reactivity title: "Svelte 3: Rethinking reactivity"
description: It's finally here description: It's finally here
author: Rich Harris author: Rich Harris
authorURL: https://twitter.com/Rich_Harris authorURL: https://twitter.com/Rich_Harris

@ -41,7 +41,7 @@ When we say that Svelte now supports TypeScript, we mean a few different things:
* You get autocompletion hints and type-checking as you're writing components, even in expressions inside markup * 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 * 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? ### 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. 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.
@ -52,7 +52,7 @@ The Svelte compiler support for TypeScript is handled by [Christian Kaisermann](
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). 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 ### `*.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/). 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/).
@ -67,7 +67,7 @@ Before getting started, add the dependencies:
npm install --save-dev @tsconfig/svelte typescript svelte-preprocess svelte-check npm install --save-dev @tsconfig/svelte typescript svelte-preprocess svelte-check
``` ```
##### 1. Compiling TypeScript ### 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. 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.
@ -103,7 +103,7 @@ To configure TypeScript, you will need to create a `tsconfig.json` in the root o
Your `include`/`exclude` may differ per project — these are defaults that should work across most Svelte projects. Your `include`/`exclude` may differ per project — these are defaults that should work across most Svelte projects.
##### 2. Editor Support ### 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. 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.
@ -111,7 +111,7 @@ These editor extensions will improve your coding experience even if you only use
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. 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 ### 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. 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.

@ -1,5 +1,5 @@
--- ---
title: What's new in Svelte: October 2020 title: "What's new in Svelte: October 2020"
description: New object methods, in-depth learning resources and tons of integration examples! description: New object methods, in-depth learning resources and tons of integration examples!
author: Daniel Sandoval author: Daniel Sandoval
authorURL: https://desandoval.net authorURL: https://desandoval.net
@ -57,18 +57,18 @@ For all the features and bugfixes see the CHANGELOG for [Svelte](https://github.
- [Who are my representatives?](https://whoaremyrepresentatives.us/) is a website built with Svelte to help US residents get more info on their congressional representatives - [Who are my representatives?](https://whoaremyrepresentatives.us/) is a website built with Svelte to help US residents get more info on their congressional representatives
- [Pick Palette](https://github.com/bluwy/pick-palette) is a color palette manager made with Svelte! - [Pick Palette](https://github.com/bluwy/pick-palette) is a color palette manager made with Svelte!
#### In-depth learning: ### In-depth learning:
- [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/ref=cm_sw_r_tw_dp_x_OQMtFb3GPQCB2) is a new book about building production-ready static web apps with Svelte 3 - [Svelte 3 Up and Running](https://www.amazon.com/dp/B08D6T6BKS/ref=cm_sw_r_tw_dp_x_OQMtFb3GPQCB2) is a new book about building production-ready static web apps with Svelte 3
- [Sapper Tutorial (Crash Course)](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gdr4Qhx83gBBcID-KMe-PQ) walks through the ins-and-outs of Sapper, the Svelte-powered application framework - [Sapper Tutorial (Crash Course)](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gdr4Qhx83gBBcID-KMe-PQ) walks through the ins-and-outs of Sapper, the Svelte-powered application framework
- [Svelte Society Day France](https://france.sveltesociety.dev/) happened September 27th featuring a wide variety of topics all in French! You can find the full recording [here](https://www.youtube.com/watch?v=aS1TQ155JK4). - [Svelte Society Day France](https://france.sveltesociety.dev/) happened September 27th featuring a wide variety of topics all in French! You can find the full recording [here](https://www.youtube.com/watch?v=aS1TQ155JK4).
#### Plug-and-play components: ### Plug-and-play components:
- [svelte-zoom](https://github.com/vaheqelyan/svelte-zoom) brings "nearly native" pan-and-zoom to images on desktop and mobile - [svelte-zoom](https://github.com/vaheqelyan/svelte-zoom) brings "nearly native" pan-and-zoom to images on desktop and mobile
- [svelte-materialify](https://github.com/TheComputerM/svelte-materialify) is a Material component library for Svelte with over 50 components - [svelte-materialify](https://github.com/TheComputerM/svelte-materialify) is a Material component library for Svelte with over 50 components
- [svelte-undoable](https://github.com/macfja/svelte-undoable) makes it easy to introduce undo and redo functionality using `bind:` - [svelte-undoable](https://github.com/macfja/svelte-undoable) makes it easy to introduce undo and redo functionality using `bind:`
- [This Tilt component](https://svelte.dev/repl/7b23ad9d2693424482cd411b0378b55b?version=3.24.1) implements a common UX pattern where the hovered element tilts to follow the mouse - [This Tilt component](https://svelte.dev/repl/7b23ad9d2693424482cd411b0378b55b?version=3.24.1) implements a common UX pattern where the hovered element tilts to follow the mouse
#### Lots of examples of how use JS tech came out this month: ### Lots of examples of how use JS tech came out this month:
- [Sapper with PostCSS and Tailwind](https://codechips.me/sapper-with-postcss-and-tailwind/) - [Sapper with PostCSS and Tailwind](https://codechips.me/sapper-with-postcss-and-tailwind/)
- [PrismJS (Code block syntax highlighting)](https://github.com/phptuts/Svelte-PrismJS) - [PrismJS (Code block syntax highlighting)](https://github.com/phptuts/Svelte-PrismJS)
- [Filepond (Drag-and-drop file upload)](https://github.com/pqina/svelte-filepond) - [Filepond (Drag-and-drop file upload)](https://github.com/pqina/svelte-filepond)

@ -1,5 +1,5 @@
--- ---
title: What's new in Svelte: November 2020 title: "What's new in Svelte: November 2020"
description: Slot forwarding fixes, SvelteKit for faster local development, and more from Svelte Summit description: Slot forwarding fixes, SvelteKit for faster local development, and more from Svelte Summit
author: Daniel Sandoval author: Daniel Sandoval
authorURL: https://desandoval.net authorURL: https://desandoval.net

@ -1,5 +1,5 @@
--- ---
title: What's new in Svelte: December 2020 title: "What's new in Svelte: December 2020"
description: Better tooling, export maps and improvements to slots and context description: Better tooling, export maps and improvements to slots and context
author: Daniel Sandoval author: Daniel Sandoval
authorURL: https://desandoval.net authorURL: https://desandoval.net
@ -62,7 +62,7 @@ For all the features and bugfixes see the CHANGELOGs for [Svelte](https://github
- [svelte-store-router](https://github.com/zyxd/svelte-store-router) is a store-based router for Svelte that suggests that routing is just another global state and History API changes are just an optional side-effects of this state. - [svelte-store-router](https://github.com/zyxd/svelte-store-router) is a store-based router for Svelte that suggests that routing is just another global state and History API changes are just an optional side-effects of this state.
- [Routify](https://routify.dev/blog/routify-2-released) just released version 2 of its Svelte router. - [Routify](https://routify.dev/blog/routify-2-released) just released version 2 of its Svelte router.
- [svelte-error-boundary](https://www.npmjs.com/package/@crownframework/svelte-error-boundary) provides a simple error boundary component for Svelte that can be can be used with both DOM and SSR targets. - [svelte-error-boundary](https://www.npmjs.com/package/@crownframework/svelte-error-boundary) provides a simple error boundary component for Svelte that can be can be used with both DOM and SSR targets.
- [svelte2dts](https://www.npmjs.com/package/svelte2dts) generates d.ts files from svelte files, creating truly sharable and well typed components. - [svelte2dts](https://www.npmjs.com/package/svelte2dts) generates d.ts files from svelte files, creating truly shareable and well typed components.
## See you next month! ## See you next month!

@ -1,5 +1,5 @@
--- ---
title: What's new in Svelte: January 2021 title: "What's new in Svelte: January 2021"
description: A Svelte-packed showcase to kick-off the new year! description: A Svelte-packed showcase to kick-off the new year!
author: Daniel Sandoval author: Daniel Sandoval
authorURL: https://desandoval.net authorURL: https://desandoval.net

@ -1,5 +1,5 @@
--- ---
title: What's new in Svelte: February 2021 title: "What's new in Svelte: February 2021"
description: Integrations and improvements at lightning speed... description: Integrations and improvements at lightning speed...
author: Daniel Sandoval author: Daniel Sandoval
authorURL: https://desandoval.net authorURL: https://desandoval.net

@ -1,5 +1,5 @@
--- ---
title: What's new in Svelte: March 2021 title: "What's new in Svelte: March 2021"
description: Call for Svelte Summit Speakers! Improved SSR, non-HTML5 compilation targets, and ESLint TypeScript support description: Call for Svelte Summit Speakers! Improved SSR, non-HTML5 compilation targets, and ESLint TypeScript support
author: Daniel Sandoval author: Daniel Sandoval
authorURL: https://desandoval.net authorURL: https://desandoval.net

@ -0,0 +1,73 @@
---
title: "What's new in Svelte: April 2021"
description: SvelteKit beta and new way to use slots
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Two projects that have been months (even years) in the making have made their way out into the world. SvelteKit is now in public beta and slotted components are now available in Svelte!
## What's up with SvelteKit?
[SvelteKit](https://kit.svelte.dev/) - Svelte's versatile framework for building SSR, serverless applications, or SPAs - is now officially in public beta. Expect bugs! Lots more detail in the [latest blog post](https://svelte.dev/blog/sveltekit-beta). Want to know when 1.0 is close? Check out the milestone on [github](https://github.com/sveltejs/kit/milestone/2).
Want to learn more about how to get started, what's different compared to Sapper, new features and migration paths? Check out this week's [episode of Svelte Radio](https://www.svelteradio.com/episodes/svelte-kit-public-beta) for a deep dive with Antony, Kev and Swyx.
## New in Svelte & Language Tools
- Slotted components, including `<svelte:fragment slot="...">` lets component consumers target specific slots with rich content (**Svelte 3.35.0, Language Tools [104.5.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.5.0)**, check out the [docs](https://svelte.dev/docs#svelte_fragment) and the [tutorial](https://svelte.dev/tutorial/svelte-fragment))
- Linked editing now works for HTML in Svelte files (**Language Tools, [104.6.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.6.0)**)
- Type definitions `svelte.d.ts` are now resolved in order, allowing library authors to ship type definitions with their svelte components (**Language Tools, [104.7.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-104.7.0)**)
- [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) is available for general use of Svelte in Vite. `npm init @vitejs/app` includes Svelte options using this plugin.
---
## Community Showcase
**Apps & Sites**
- [Nagato](https://nagato.app/) is a task management tool that connects popular time tracking and to-do tools all in one place.
- [type-kana](https://type-kana.cass.moe/setup) is a quiz app to help you learn ひらがな (hiragana) and カタカナ (katakana), the Japanese syllabaries.
- [Pittsburgh Steps](https://pittsburgh-steps.samlearner.com/) is an interactive map of the more than 800 sets of public outdoor stairways in Pittsburgh, PA.
- [Music Mode Wheels](https://tobx.github.io/music-mode-wheels/) is a website that displays music modes as interactive wheels.
- [Critical Notes](https://www.critical-notes.com/) helps game masters and players keep track of their roleplaying games campaigns and adventures.
- [Svelte Game of Life](https://github.com/alanrsoares/svelte-game-of-life) is an educational implementation of Conway's Game of Life in TypeScript + Svelte
- [foxql](https://github.com/foxql) is a peer to peer full text search engine that runs on your browser.
**Demos, Libraries, Tools & Components**
- [svelte-nodegui](https://github.com/nodegui/svelte-nodegui) is a way to build performant, native and cross-platform desktop applications with Node.js and Svelte
- [Svelte Story Format](https://www.npmjs.com/package/@storybook/addon-svelte-csf) allows you to write your "stories" in Storybook using the Svelte syntax. More info in the [Storybook blog](https://storybook.js.org/blog/storybook-for-svelte/)
- [SelectMadu](https://github.com/pavish/select-madu) is a replacement for the select menu, with support for searching, multiple selections, async data loading and more.
- [Svelte Checklist](https://www.npmjs.com/package/svelte-checklist) is a customizable CheckList built with Svelte.
- [Suspense for Svelte](https://www.npmjs.com/package/@jamcart/suspense) is a Svelte component that implements the core idea of React's `<Suspense>`.
- [MiniRx](https://spierala.github.io/mini-rx-store/) is a RxJS Redux Store that works with Svelte and TypeScript
- [svelte-formly](https://github.com/arabdevelop/svelte-formly) generates dynamic forms for Svelte and Sapper
- [7ty](https://www.npmjs.com/package/@jamcart/7ty) is a static site generator that uses Svelte, supports partial hydration of components, and uses file based routing resembling Sapper and 11ty.
**Want to contribute your own component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Starters**
- [sveltekit-electron](https://github.com/FractalHQ/sveltekit-electron) is a starter kit for Electron using SvelteKit
- [sveltekit-tailwindcss-external-api](https://github.com/acidlake/sveltekit-tailwindcss-external-api) is everything you need to build a Svelte project with TailwindCSS and an external API, powered by create-svelte.
- [Sapper Netlify](https://www.npmjs.com/package/sapper-netlify) is a Sapper project that can run on a Netlify function.
**Looking for a particular starter?** Check out [svelte-adders](https://github.com/svelte-add/svelte-adders) and a number of other template examples at the community site [sveltesociety.dev](https://sveltesociety.dev/templates/)
**Learning Resources**
- [How to Build a Website with Svelte and SvelteKit](https://prismic.io/blog/svelte-sveltekit-tutorial) is a step-by-step tutorial walking through the new SvelteKit setup.
- [A Svelte store for prefers-reduced-motion](https://geoffrich.net/posts/svelte-prefers-reduced-motion-store/) demonstrates how to make a custom Svelte store whose value will indicate whether the user has requested reduced motion and improve accessibility.
- [TypeScript support in Svelte](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript) is an MDN guide to using TypeScript in Svelte.
- [How to merge cells with svelte-window](https://gradientdescent.de/merging-cells/) is a walkthrough of svelte-window, a port of the popular react-window tool for merging table cells. For more on this migration, see [from react-window 1:1 to svelte-window](https://gradientdescent.de/porting-react-window/).
- [Easy-to-Embed Svelte Components](https://codeandlife.com/2021/03/06/easy-to-embed-svelte-components/) explains how to use Rollup and a script tag to embed Svelte components anywhere.
- [Convert Svelte project from Rollup to Snowpack](https://www.youtube.com/watch?v=-sHcqj4YLeQ) walks through a common migration pattern on video.
- [How to internationalize routing in Svelte & Sapper](https://www.leaf.cloud/blog/how-to-internationalize-routing-in-svelte-sapper?utm_medium=story&utm_source=reddit.com&utm_campaign=awareness&utm_content=sapper_routing) explains how leaf.cloud translated their site to Dutch.
- [Svelte Store: Reactive context using Svelte Store](https://www.youtube.com/watch?v=-rTnWlbdjoY) is a video answer to the question, "How do we make [a] context value reactive?"
- [Creating Social Sharing Images with Cloudinary and Svelte](https://www.youtube.com/watch?v=-Si5o-R7KHY) is a video from Cloudinary that demonstrates how to dynamically develop Open Graph images and Twitter Cards for a JAMstack website.
## See you next month!
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!

@ -0,0 +1,76 @@
---
title: What's new in Svelte: May 2021
description: Working toward SvelteKit 1.0 and a showcase full of SvelteKit sites!
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Last week, Svelte Summit blew us away with a mountain of content! [Check out the full recording](https://www.youtube.com/watch?v=fnr9XWvjJHw) or an audio-only (p)review [on Svelte Radio](https://www.svelteradio.com/episodes/svelte-summit-party-episode). Now let's get into this month's news...
## New features in the Svelte Compiler
- `:global()` is now supported as part of compound CSS selectors (**3.38.0**, [Example](https://svelte.dev/repl/54148fd2af484f2c84977c94e523c7c5?version=3.38.0))
- CSS custom properties can now be passed to components for use cases such as theming (**3.38.0**, [Docs coming soon](https://github.com/sveltejs/svelte/issues/6268))
## New in SvelteKit
- [kit.svelte.dev](https://kit.svelte.dev/) has a fresh new look and the [SvelteKit Demo Site](https://netlify.demo.svelte.dev/) got a fresh set of paint. Check it out by running `npm init svelte@next`
- You can now use `@sveltejs/adapter-static` to create a single-page app or SPA by specifying a fallback page ([PR](https://github.com/sveltejs/kit/pull/1181), [Docs](https://github.com/sveltejs/kit/tree/master/packages/adapter-static))
- Disable Server-side Rendering (SSR) app-wide or on a page-by-page basis ([PR](https://github.com/sveltejs/kit/pull/713), [Docs](https://kit.svelte.dev/docs#ssr-and-javascript-ssr))
- Error messages thrown during pre-rendering are now much more informative and readable ([PR](https://github.com/sveltejs/kit/pull/1062), [Docs](https://kit.svelte.dev/docs#layouts-error-pages))
- Layouts can now be reset to prevent pages from inheriting the root layout. This is useful if you have a specific layout for a page or i18n variation ([PR](https://github.com/sveltejs/kit/pull/1061), [Docs](https://kit.svelte.dev/docs#layouts-resets))
- `fetch` in SvelteKit code will now use the environment-provided implementation, whenever possible. If `fetch` is unavailable, it will be polyfilled by adapters ([PR](https://github.com/sveltejs/kit/pull/1066), [Docs](https://kit.svelte.dev/docs#loading-input-fetch))
## New in Svelte & Language Tools
- `svelte-preprocess` now supports the "extends" field of the tsconfig.json (4.7.2)
- HTML `style` attributes now have hover & auto-complete. Foreign namespaces and ESM configs are now supported in the Svelte language server & extensions
- The Svelte language tools can now infer slot/event types from their props if a generic relationship between them was defined
---
## Community Showcase
**Apps & Sites**
- [gitpod.io](https://github.com/gitpod-io/website) recently rewrote its site with SvelteKit
- [highlight eel](https://highlighteel.com/) is a web-based editor to mark your favorite parts of any YouTube video to clip and share with anyone
- [The Far Star Mission](https://thefarstar.apotheus.net/) is an interactive audiobook companion to the album, The Far Star by Apotheus
- [JavaScript quiz](https://github.com/nclskfm/javascript-quiz) is a small quiz application that saves your answers locally
- [ExtensionPay](https://extensionpay.com/) lets developers accept secure payments in browser extensions with no backend server code.
- [mk48.io](https://mk48.io/) is a naval warship game made with SvelteKit
- [Frog Safety](https://frog-safety.vercel.app/) is a guide for African Dwarf Frogs and the API freshwater master kit
- [Stardew Valley Character Preview](https://github.com/overscore-media/stardew-valley-character-preview) loads your character's attributes from your Stardew Valley savefile and lets you play around with different outfits, colours, and accessories.
**Demos, Libraries, Tools & Components**
- [svelte-parallax](https://github.com/kindoflew/svelte-parallax) is a spring-based parallax component for Svelte
- [@svelte-plugins/viewable](https://github.com/svelte-plugins/viewable) is a simple rule-based approach to tracking element viewability.
- [Sveltekit-JUI](https://github.com/Wolfr/sveltekit-jui) is a kit of UI components to be used in conjunction with Svelte and Svelte Kit.
- [EZGesture](https://github.com/mhmd-22/ezgesture#integrating-with-other-frameworks) makes it easy to add gestures functionality with simple native DOM events
**Want to contribute your own component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Starters**
- [How to use Vercel Analytics with SvelteKit](https://ivoberger.com/posts/using-vercel-analytics-with-svelte-kit) teaches how to track Web Vitals across your users' devices
- [Asp.NETCore + Svelte + Vite](https://github.com/Kiho/aspcore-spa-cli/tree/master/samples/SviteSample) connects the three frameworks with SpaCliMiddleware (VS2019)
- [Add CoffeeScript to Svelte](https://github.com/Leftium/coffeescript-adder) is an experimental command to run to add CoffeeScript to your SvelteKit project or Vite-powered Svelte app
- [Adds Supabase to Svelte](https://github.com/joshnuss/svelte-supabase) is an experimental command to run to add Supabase to your SvelteKit project
- [svelte-babylon](https://github.com/SectorXUSA/svelte-babylon) lets you use BabylonJS like A-Frame through reactive Svelte Components
**Looking for a starter or integration?** Check out [svelte-adders](https://github.com/svelte-add/svelte-adders) and a number of other template examples at the community site [sveltesociety.dev](https://sveltesociety.dev/templates)
**Learning Resources**
- [Amazing macOS Dock animation in Svelte](https://dev.to/puruvj/amazing-macos-dock-animation-in-svelte-5hfb) demonstrates how nice Svelte and popmotion look together
- [Solving the Tower of Hanoi with recursive Svelte templates](https://geoffrich.net/posts/svelte-tower-of-hanoi/) incorporates the `<svelte:self>` element into a common computer science problem
- [DIY SvelteKit CDK adapter](https://dev.to/juranki/diy-sveltekit-cdk-adapter-3enp) puts together SvelteKit and AWS CDK
- Fireship's [Svelte in 100 Seconds](https://www.youtube.com/watch?v=rv3Yq-B8qp4) is a quick and easy introduction to Svelte's core concepts
- [Tech Downtime](https://www.youtube.com/watch?v=tsePBA2JC7o&list=PLualcIC6WNK1LHIYx2Tg9AQfTQDv4zNPu) has been diving into SvelteKit in this playlist - from getting up and running to debugging.
- lihautan's latest video updates in the [Svelte 101](https://www.youtube.com/watch?v=rwYgOU0WmVk&list=PLoKaNN3BjQX3mxDEVG3oGJx2ByXnue_gR&index=59) and [Svelte Store](https://www.youtube.com/watch?v=p4GmT0trCPE&list=PLoKaNN3BjQX3fG-XOSwsPHtnV8FUY6lgK&index=19) playlists cover slots, stores and context - and when to use which
- [DavidParkerW](https://www.youtube.com/c/DavidParkerW/playlists) has been exploring Svelte, Sapper and SvelteKit in some real-world scenarios, like [displaying a blog post list from an API](https://www.youtube.com/watch?v=kAPVFgFnxaM&list=PLPqKsyEGhUna6cvm6d4vZNI6gbt_0S4Xx&index=15)
## See you next month!
Got something to add? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!

@ -0,0 +1,65 @@
---
title: What's new in Svelte: June 2021
description: Progress towards SvelteKit 1.0 and tighter TypeScript/Svelte integrations in language tools
author: Daniel Sandoval
authorURL: https://desandoval.net
---
This month, we saw lots of contributions to SvelteKit and its docs. The language tools also got some new features, most notably deeper integration with Svelte files within JavaScript or TypeScript files. Let's jump into the updates...
## New in SvelteKit
- `svelte.config.js` config files are now loaded in ESM format (`.js` instead of `.cjs`).
- AMP pages will now use the rendered CSS, rather than emitted CSS
- `svelte-check` has been added to the TypeScript template ([sveltejs/kit#1556](https://github.com/sveltejs/kit/pull/1556))
- Support for https keypair [sveltejs/kit#1456](https://github.com/sveltejs/kit/pull/1456)
- Now bundling Vite with SvelteKit and using an upgraded version. Remove Vite from your `package.json` if it's there
- Etags for binary responses [sveltejs/kit#1382](https://github.com/sveltejs/kit/pull/1382)
- Renamed `$layout` to `__layout` and `$error` to `__error`
- Removed `getContext` in favor of `request.locals`
- Renamed `.svelte` output directory to `.svelte-kit`. Update your `.gitignore` accordingly
- `trailingSlash: 'never' | 'always' | 'ignore'` is now available in the config. This should make it easier to build sites that work with static hosting providers that expect a trailing slash for `index.html` pages, and provides an escape hatch for anyone that needs more complex behaviour.
## Notable bug fixes in SvelteKit
- `adapter-netlify` got a fix [sveltejs/kit#1467](https://github.com/sveltejs/kit/pull/1467) and new documentation in the readme https://github.com/sveltejs/kit/tree/master/packages/adapter-netlify
- The router will no longer intercept navigation for URLs that the app does not own. This fixes a crash for apps that have `<a>` elements on the page with the same origin but don't share a base path with the app.
- Hash only changes are now handled by the router fixing the browser's "back" navigation between hash changes in some circumstances.
## New in Svelte & Language Tools
- Svelte 3.38.1 and 3.38.2 fixed an issue with hydration that was causing duplicate elements. If you're seeing this in your project, be sure to update the latest version!
- A new TypeScript plugin provides deeper integration with Svelte files within JavaScript or TypeScript files. This includes diagnostics, references and renaming of variables. It comes packaged with the VS Code extension but is turned off by default for now. You can enable it through [this setting](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-vscode#svelteenable-ts-plugin). We encourage you to test it out and [provide feedback](https://github.com/sveltejs/language-tools/issues/580)
- In the latest version of `svelte-check` you can now provide the path to your `tsconfig.json` or `jsconfig.json`. Example: `svelte-check --tsconfig "./tsconfig.json"`. This ensures the diagnostics are only run on files that are referenced in that config. It also runs diagnostics on JavaScript and/or TypeScript files which removes the need to run another check (like `tsc --noEmit`) for non-Svelte files (`svelte-check` version [**1.6.0**](https://github.com/sveltejs/language-tools/releases/tag/svelte-check-1.6.0))
- The VS Code extension and `svelte-check` got a new major release. Previously, properties that had no initializer (`export let foo;`) were only required if the user was using both TypeScript and activated `strict` mode. This is changed now: People using TypeScript, and those using `checkJs` also in JavaScript files, will now always have these properties marked as required (`svelte-check` version [**2.0.0**](https://github.com/sveltejs/language-tools/releases/tag/svelte-check-2.0.0), extension version [**105.0.0**](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.0.0))
---
## Community Showcase
**Apps & Sites**
- [vidu](https://github.com/pa-nic/vidu) is a minimal web analytics collector and dashboard
- [River Runner](https://river-runner.samlearner.com/) is a virtual way to follow rivers downstream - built with Mapbox and Svelte.
- [JSDoc Type Generator](https://rafistrauss.github.io/jsdoc-generator/) generates JSDoc types for valid JSON.
- [pagereview.io](https://pagereview.io/) is a website feedback tool that lets you leave comments directly on the site being reviewed.
- [gamesroom.io](https://gamesroom.io/) is an online board game platform with video chat built-in.
- [Greedy Goblin](https://greedygoblin-fe11c.web.app/) is a recipe app for old-school Runescape players.
- [hashbrown.geopjr.dev](https://hashbrown.geopjr.dev/) is a GNOME-shell inspired webpage to learn about, explore the source code and download the Hashbrown GTK app ([link to source](https://github.com/GeopJr/Hashbrown/tree/website)).
**Libraries, Tools & Components**
- [svelte-image-crop](https://novacbn.github.io/svelte-image-crop/) is a simple click'n'drag image cropping library using Web APIs.
- [svelte-datepicker](https://github.com/andrew-secret/svelte-datepicker) is a lightweight and inclusive date picker build with Svelte.
- [svelte-regex-router](https://www.npmjs.com/package/svelte-regex-router) is a simple, lightweight library for you to easily handle routes in your Svelte application.
- [Svelte Micro](https://www.npmjs.com/package/svelte-micro) is a light & reactive one-component router for Svelte.
- [svelte-entity-store](https://www.npmjs.com/package/svelte-entity-store) is to provide a simple, generic solution for storing collections of entity objects.
- [svelte-animation-store](https://github.com/joshnuss/svelte-animation-store) is a store that is based on Svelte's tweened store, that lets you pause, continue, reset, replay, reverse or adjust speed of a tween.
**Want to contribute a component?** Submit a [Component](https://sveltesociety.dev/components) to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
## See you next month!
Did we miss something? Join us on [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs)!

@ -0,0 +1,65 @@
---
title: What's new in Svelte: July 2021
description: Keeping cool with fixes, TypeScript tooling and tonnes of new features
author: Daniel Sandoval
authorURL: https://desandoval.net
---
As the northern hemisphere heats up, Svelte has stayed cool with lots of performance and bug fixes, better TypeScript support, and lots of new components & tools from around the ecosystem. Let's take a peek 👀
## New in SvelteKit
- `adapter-node` now precompresses assets using gzip & brotli ([#1693](https://github.com/sveltejs/kit/pull/1693))
- Support for TypeScript transpilation has been added to the `svelte-kit package` tooling ([#1633](https://github.com/sveltejs/kit/pull/1633))
- Improved caching defaults in `adapter-node` ([#1416](https://github.com/sveltejs/kit/pull/1416))
- Allow configuring Rollup output options ([#1572](https://github.com/sveltejs/kit/pull/1572))
- Fixed usage of SSL with HMR ([#1517](https://github.com/sveltejs/kit/pull/1517))
## Features & bug fixes from around svelte/*
- [Svelte 3.38.3](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3383) (released June 22) includes a bunch of performance and bug fixes - including hydration optimizations, `this` preservation in bubbled events, and more!
- The latest language tools releases added support for prop renaming from outside of a component, PostCSS syntax grammar, and a `.d.ts` output target in `svelte2tsx` which can be used to create type definitions from Svelte files.
- Also in language tools, some long-awaited experimental features for enhanced TypeScript support were added - including explicitly typing all possible component events or slots, and using generics. Have a look at [the RFC](https://github.com/sveltejs/rfcs/pull/38) for more details and leave feedback in [this issue](https://github.com/sveltejs/language-tools/issues/442) if you are using it.
- `svelte-scroller` got some quality-of-life fixes in 2.0.7 - fixing an initial width bug and updating its `index` more conservatively
## Coming soon to Svelte
- Constants in markup ([RFC](https://github.com/sveltejs/rfcs/blob/master/text/0000-markup-constants.md)): Adds a new `{@const ...}` tag that defines a local constant ([PR](https://github.com/sveltejs/svelte/pull/6413))
---
## Community Showcase
**Apps & Sites**
- [SvelteThemes](https://sveltethemes.dev/) is a curated list of Svelte themes and templates built using svelte, sveltekit, elderjs, routify etc.
- [Beatbump](https://github.com/snuffyDev/Beatbump) is an alternative frontend for YouTube Music created using Svelte/SvelteKit.
- [Sveltuir](https://github.com/webspaceadam/sveltuir) is an app help you memorize the guitar fretboard
**Educational Content**
- [Svelte Radio: A Jolly Good Svelte Summer](https://share.transistor.fm/s/60880542) is a conversation about what's new in Svelte and a celebration of Svelte Radio's 1-year anniversary
- [Class properties in Svelte](https://navillus.dev/blog/svelte-class-props) is a refresher on the power of `class` for developers switching over to Svelte from React
- [Sveltekit Tutorial for Beginners](https://www.youtube.com/playlist?list=PLm_Qt4aKpfKjf77S8UD79Ockhwp_699Ms) is a video playlist for learning SvelteKit by WebJeda
- [How To Cache Dynamic Pages On Demand With A Service Worker In SvelteKit](https://jochemvogel.medium.com/how-to-cache-dynamic-pages-on-demand-with-a-service-worker-in-sveltekit-4b4a7652583d) walks through the power of service workers when used within SvelteKit for on-demand caching
- [Vue vs Svelte: Comparing Framework Internals](https://www.vuemastery.com/blog/vue-vs-svelte-comparing-framework-internals/) dives deep into the differences between Vue and Svelte from the inside out
- [Setting up a development environment for SvelteKit with Docker and Docker Compose](https://jenyus.web.app/blog/2021-05-30-setting-up-a-development-environment-for-sveltekit-with-docker-and-compose) walks through how to use Docker to create reusable development environments, no matter what kind of device you run your code on
- Scalable Scripts released three videos this month documenting how to deploy dockerized Svelte Apps to [AWS](https://youtu.be/VOs2Od5jYOc), [Azure](https://youtu.be/gdg4ne_uDm8) and [Google Cloud](https://youtu.be/_-uBb61Tikw)
- [Render Katex with Svelte from zero to hero](https://www.youtube.com/watch?v=euowJs9CblA) demonstrates how to implement Katex in a Svelte project
- [Using Custom Elements in Svelte](https://css-tricks.com/using-custom-elements-in-svelte/) shows some of the quirks to look out for when using custom elements in a Svelte site
**Libraries, Tools & Components**
- [svelte-pipeline](https://github.com/novacbn/svelte-pipeline) provides custom Javascript contexts and the Svelte Compiler as Svelte Stores, for REPLs, Editors, etc.
- [Sveltotron](https://github.com/Salemmous/sveltotron) is an Electron-based app made to inspect your Svelte app
- [svelte-qr-reader-writer](https://github.com/pleasemarkdarkly/svelte-qr-reader-writer) is a Svelte component that helps read and write data from QR codes
- [svelte-stack-router](https://www.npmjs.com/package/svelte-stack-router) Aims to make Svelte apps feel more native by routing with Stacks
- [svelte-typed-context](https://www.npmjs.com/package/svelte-typed-context) provides an interface which, when provided to `getContext` or `setContext`, allows for stricter types
- [svelte-modals](https://svelte-modals.mattjennings.io/) is a simple, flexible, zero-dependency modal manager for Svelte
**Want to contribute a component? Interested in helping make Svelte's presence on the web better?** Submit a Component to the Svelte Society site by making [a PR to this file](https://github.com/svelte-society/sveltesociety-2021/blob/main/src/routes/components/components.json) or check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
## See you next month!
Want more updates? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!

@ -0,0 +1,71 @@
---
title: What's new in Svelte: August 2021
description: Shadow DOM, export and await - oh my!
author: Daniel Sandoval
authorURL: https://desandoval.net
---
From The Changelog ([JS Party Ep. 182](https://changelog.com/jsparty/182)) to Svelte Radio (Episodes [29](https://share.transistor.fm/s/adc23e84) and [30](https://share.transistor.fm/s/6316622d)), it seems that folks couldn't help but talk about Svelte, this month! Also, shadow DOM support and new export and await functionality are new in Svelte.
## New in Svelte
July was the most active month for the Svelte core repo since late 2019 as we really worked to reduce the number of outstanding PRs and saw the release of Svelte 3.39.0, 3.40.0, and 3.41.0. Tons of bug fixes were added as well as the following new features:
- The `|trusted` event modifier allows you to check if an event is trusted before it's called ([#6137](https://github.com/sveltejs/svelte/issues/6137))
- The new `svelte/ssr` package to support work on improving SvelteKit SSR ([#6416](https://github.com/sveltejs/svelte/pull/6416))
- A new `errorMode` compiler option to support improved preprocessing of TypeScript files ([#6194](https://github.com/sveltejs/svelte/pull/6194))
- You can now specify a `ShadowRoot` as the `target` when creating a component - making it possible to render Svelte components inside the shadow DOM ([#5869](https://github.com/sveltejs/svelte/issues/5869))
- The `export { ... } from` ([#2214](https://github.com/sveltejs/svelte/issues/2214)), `export let { ... } =` ([#5612](https://github.com/sveltejs/svelte/issues/5612)) and `{#await ... then/catch}` ([#6270](https://github.com/sveltejs/svelte/issues/6270)) syntaxes are all now supported in Svelte components
For a full list of features and bug fixes, check out the [Svelte changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md).
## SvelteKit Updates
- `prerender.force` is now `prerender.onError` which lets you fine-tune which errors fail the build and which do not ([#2007](https://github.com/sveltejs/kit/pull/2007))
- esbuild's configuration is now exposed for use with SvelteKit adapters ([#1914](https://github.com/sveltejs/kit/pull/1914))
- Error messages are friendlier now for common config errors ([#1910](https://github.com/sveltejs/kit/pull/1910)) and compiler errors ([#1827](https://github.com/sveltejs/kit/pull/1827))
- Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it ([#1847](https://github.com/sveltejs/kit/pull/1847))
- index.js exports will now be changed to directory exports when packaging - making for nicer imports ([#1905](https://github.com/sveltejs/kit/pull/1905))
- Vite.js's `mode` is now exposed from `$app/env` ([#1789](https://github.com/sveltejs/kit/pull/1789))
- Better types across the board ([#1778](https://github.com/sveltejs/kit/pull/1778), [#1791](https://github.com/sveltejs/kit/pull/1791), [#1646](https://github.com/sveltejs/kit/pull/1646))
To see all updates to SvelteKit, check out the [SvelteKit changelog](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
## Features & bug fixes from around svelte/*
- Language Tools now better support the "Workplace Trust" functionality (used in VS Code)
- In svelte2tsx, ambient type declarations are now renamed to avoid conflicting declarations in the future. Users are now expected to provide the ambient type definitions themselves - fixing JS output
- Sapper released v0.29.2 which fixes regex routes, status codes when requesting a directory, and exports when a user has not provided a `base` tag ([changelog](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md))
---
## Community Showcase
**Apps & Sites**
- [Parsnip](https://www.parsnip.ai/) is a mobile-first, progressive-web-app that helps you to learn to cook at home. Check out the [conversation on Reddit](https://www.reddit.com/r/sveltejs/comments/oearb9/learning_to_cook_at_home_with_parsnip_built/) for all the geeky details.
- [Central Bank Digital Currency (CBDC) tracker](https://www.atlanticcouncil.org/cbdctracker/) is a site that keeps track of how countries around the world are adopting digital currencies.
- [Svelte Commerce](https://github.com/itswadesh/svelte-commerce) is an advanced frontend platform for eCommerce based on Sveltekit.
- [neovimcraft](https://neovimcraft.com/) is a SvelteKit site dedicated to neovim plugins
**Looking for a Svelte project to work on? Interested in helping make Svelte's presence on the web better?** Check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
**Educational Content**
- [How I Built a Cross-Platform Desktop Application with Svelte, Redis, and Rust](https://css-tricks.com/how-i-built-a-cross-platform-desktop-application-with-svelte-redis-and-rust/) is a blog post by Luke Edwards, Svelte maintainer and Developer Advocate from Cloudflare.
- [How to Create a Blog with SvelteKit and Strapi](https://strapi.io/blog/how-to-create-a-blog-with-svelte-kit-strapi) is a step-by-step tutorial by Aarnav Pai from Strapi
- [Sveltekit Markdown Blog](https://www.youtube.com/watch?v=sKKgT0SEioI&list=PLm_Qt4aKpfKgonq1zwaCS6kOD-nbOKx7V) is a YouTube tutorial series by WebJeda.
- [Using Custom Elements in Svelte](https://css-tricks.com/using-custom-elements-in-svelte/) is a deep dive into custom elements by Geoff Rich.
- [learn / graphql / svelte](https://hasura.io/learn/graphql/svelte-apollo/introduction/) is a free 2-hour GraphQL course course from Hasura.
- [How to add Magic Link to a SvelteKit application](https://magic.link/posts/magic-svelte) is a guide to the popular password-less login pattern.
**Libraries, Tools & Components**
- [Svelte-Capacitor](https://github.com/drannex42/svelte-capacitor/) just released v2.0.0 - making it even easier to build hybrid mobile apps for iOS and Android using Svelte and Capacitor with near native performance.
- [svelte-remixicon](https://github.com/ABarnob/svelte-remixicon) is an icon library for Svelte based on Remix Icon, consisting of more than 2000 icons.
- [SveltePress](https://github.com/GeopJr/SveltePress) is a documentation tool built on top of SvelteKit.
- [Svelte Starter Kit](https://github.com/one-aalam/svelte-starter-kit/tree/auth-supabase) is a boilerplate to quckly get up and running with Svelte, with Auth and User Profiles powered by Supabase.
- [Kahi UI](https://github.com/novacbn/kahi-ui) is a Svelte-first UI kit with Dark Mode built-in.
- [typesafe-i18n](https://github.com/ivanhofer/typesafe-i18n) is an opinionated, fully type-safe, lightweight localization library for TypeScript and JavaScript projects with no external dependencies.
Check out the community site [sveltesociety.dev](https://sveltesociety.dev/templates/) for more templates, adders and adapters from across the Svelte ecosystem.
## See you next month!
Want more updates? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!

@ -0,0 +1,83 @@
---
title: What's new in Svelte: September 2021
description: StackOverflow's most loved web framework
author: Daniel Sandoval
authorURL: https://desandoval.net
---
This month, Svelte was [voted StackOverflow's most loved web framework](https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-web-frameworks), Tan Li Hau [talked to Svelte Radio](https://share.transistor.fm/s/84c7521b) about his [Svelte-filled YouTube channel](https://www.youtube.com/channel/UCbmC3HP3FaAFdcZkui8YoMQ), and SvelteKit made even more progress towards its 1.0 release!
## New in Svelte
- `use:actions` can now be used on `<svelte:body>` (**3.42.0**)
- `HTMLElement`, `SVGElement` (**3.42.2**) and `BigInt` (**3.42.3**) are now known globals
- There is less code in Svelte's output thanks to the following improvements in **3.42.2**:
- Whitespace is now collapsed in class and style attributes
- Hydrated components have been updated to only rely upon helpers for creating the types of elements present in the component
- Scaling is now accounted for in `flip` animations (**3.42.2**)
- All `<option>`s in a `<select>` are now deselected when the bound value doesn't match any of them (**3.42.2**)
For a full list of features and bug fixes, check out the [Svelte changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md).
## SvelteKit Updates
Svelte maintainers are [looking for help getting SvelteKit to 1.0](https://github.com/sveltejs/kit/issues/2100). We've knocked out over 100 issues that were on the 1.0 milestone. There's only a couple dozen left and we'd love a hand making that list a bit shorter!
If you'd like to help, please consider working on any of the [1.0 milestone issues](https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0).
The focus this past month was on continuing to iron out any kinks, with well over 100 PRs merged. A few new features went in as well...
- SvelteKit will now detect if a prerendered app is trying to access a query parameter and return an error instead of failing silently ([#2104](https://github.com/sveltejs/kit/pull/2104))
- `adapter-node` now lets you [add the Kit middleware to your own server](https://kit.svelte.dev/faq#integrations) for use with other middleware. You can also [add middleware in dev mode](https://kit.svelte.dev/faq#how-do-i-use-x-with-sveltekit-how-do-i-use-middleware) with more improvements to come in this area
- The new [`sequence` helper lets you chain together multiple `handle` calls](https://kit.svelte.dev/docs#modules-sveltejs-kit-hooks)
- A new [`handleError` hook](https://kit.svelte.dev/docs#hooks-handleerror) gives you the option to send data to an error tracking service, or to customise the formatting before printing the error to the console.
- `adapter-node` can now listen on socket path ([#2048](https://github.com/sveltejs/kit/pull/2048))
To see all updates to SvelteKit, check out the [SvelteKit changelog](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
---
## Community Showcase
**Apps & Sites**
- [macos-web](https://github.com/PuruVJ/macos-web) by @puruvjdev has been rebuilt with Svelte from the ground up. Check out all the details in this [Twitter thread](https://twitter.com/puruvjdev/status/1426267327687847939)
- [Brave Search](https://search.brave.com/) is using Svelte
- [exatorrent](https://github.com/varbhat/exatorrent) is a self-hostable, easy-to-use, lightweight and feature-rich torrent client written in Go and Svelte
- [json2TsTypes](https://github.com/jatinhemnani01/json2TsTypes) is a simple tool which will convert your JSON to Typescript Types/Interfaces
- [Histogram.dev](https://histogram.dev/) generates histograms for each feature in a CSV
- [cybernetic.dev](https://cybernetic.dev/) is a collection of data-centric UI experiments made while learning Svelte
- [LunaNotes](https://chrome.google.com/webstore/detail/lunanotes-youtube-video-n/oehoffnnkgcdacmbkhmlbjedinpampak?hl=en) is a Chrome extension to help with taking YouTube video notes
- [theia.games](https://theia.games/#dev)'s built-in 3D environment editor lets you create a VR world with a menu built in Svelte
- [Ferrum](https://github.com/probablykasper/ferrum) is a music library and player available for Mac, Windows or Linux
- [Fluid Earth](https://github.com/byrd-polar/fluid-earth) is an interactive WebGL application for visualizing Earth's atmosphere and oceans
**Looking for a Svelte project to work on? Interested in helping make Svelte's presence on the web better?** Check out [the list of open issues](https://github.com/svelte-society/sveltesociety-2021/issues) if you'd like to contribute to the Svelte Society rewrite in SvelteKit.
**Educational Content**
- [Tauri with Standard Svelte or SvelteKit](https://medium.com/@cazanator/tauri-with-standard-svelte-or-sveltekit-ad7f103c37e7) walks through how to setup Svelte with Tauri, a new light-weight framework for developing cross-platform hybrid desktop applications
- [Svelte - Web App Development Reimagined [An Intro to Svelte]](https://www.youtube.com/watch?v=4CGzFwHoD0A&list=PLEx5khR4g7PKSASVAXXiAhkyx02_OeruP) is a great intro talk from the goto; conference
- [LevelUpTuts - Even More 5 Things I Like More In Svelte Than React](https://www.youtube.com/watch?v=ISmnG2sIOeM) highlights Svelte's approach to refs (don't need them), meta tags and more
- [State Management in Svelte Applications](https://auth0.com/blog/state-management-in-svelte-applications/) is a tutorial on how to use the Svelte state management store to manage state in Svelte applications
- [Migrating from Sapper to SvelteKit](https://shipbit.de/blog/migrating-from-sapper-to-svelte-kit/) is a review and retrospective of ShipBit's migration from Sapper
**Libraries, Tools & Components**
- [svelte-stripe-js](https://github.com/joshnuss/svelte-stripe-js) is everything you need to add Stripe to your Svelte project. 100% SvelteKit compatible
- [svelte-steps](https://github.com/shaozi/svelte-steps) is a customizable step component written in Svelte
- [simple-optics-module](https://gitlab.com/Samzelot/simple-optics-module) is an online open source optics tool for experimenting and teaching geometrical optics
- [inlang](https://github.com/samuelstroschein/inlang) is an internationalization (i18n) tool for SvelteKit apps
- [Sveno](https://github.com/pocinnovation/sveno) is a component transpiler that transforms React components to Svelte components
- [svelte-useactions](https://github.com/paolotiu/svelte-useactions) is a fully typed library for passing actions to components
- [Svelte-Element-Query](https://github.com/leveluptuts/Svelte-Element-Query) is a 322b library/action for element queries
- [svelte-meta-tags](https://github.com/oekazuma/svelte-meta-tags) is a plug-in that makes managing SEO easier in Svelte projects
- [svelte-domtree](https://github.com/alex-knyaz/svelte-domtree) lets you visualize the DOM - similar to DOM tree in Chrome DevTools
- [Diffx](https://github.com/jbjorge/diffx/tree/master/svelte), a cross-framework state management library, just added Svelte support
- [svelte-ionic-starter](https://github.com/Zettexe/svelte-ionic-starter) a project template for Svelte + Ionic + CapacitorJS apps with live reload and iOS/Android build targets
- [demo-sveltekit-sanity](https://github.com/stephane-vanraes/demo-sveltekit-sanity/) is a starter kit for SvelteKit and Sanity, an open source React CMS
Check out the community site [sveltesociety.dev](https://sveltesociety.dev/templates/) for more templates, adders and adapters from across the Svelte ecosystem.
## See you next month!
Want more updates? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs)!

@ -13,18 +13,18 @@ All three sections — script, styles and markup — are optional.
// logic goes here // logic goes here
</script> </script>
<!-- markup (zero or more items) goes here -->
<style> <style>
/* styles go here */ /* styles go here */
</style> </style>
<!-- markup (zero or more items) goes here -->
``` ```
### &lt;script&gt; ### &lt;script&gt;
A `<script>` block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup. There are four additional rules: A `<script>` block contains JavaScript that runs when a component instance is created. Variables declared (or imported) at the top level are 'visible' from the component's markup. There are four additional rules:
##### 1. `export` creates a component prop #### 1. `export` creates a component prop
--- ---
@ -57,6 +57,8 @@ 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. If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however.
Readonly props can be accessed as properties on the element, tied to the component using [`bind:this` syntax](docs#bind_element).
```sv ```sv
<script> <script>
// these are readonly // these are readonly
@ -85,7 +87,7 @@ You can use reserved words as prop names.
</script> </script>
``` ```
##### 2. Assignments are 'reactive' #### 2. Assignments are 'reactive'
--- ---
@ -93,8 +95,6 @@ To change component state and trigger a re-render, just assign to a locally decl
Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect. Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect.
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).
```sv ```sv
<script> <script>
let count = 0; let count = 0;
@ -107,7 +107,25 @@ Because Svelte's reactivity is based on assignments, using array methods like `.
</script> </script>
``` ```
##### 3. `$:` marks a statement as reactive ---
Because Svelte's reactivity is based on assignments, using array methods like `.push()` and `.splice()` won't automatically trigger updates. A subsequent assignment is required to trigger the update. This and more details can also be found in the [tutorial](tutorial/updating-arrays-and-objects).
```sv
<script>
let arr = [0, 1];
function handleClick () {
// this method call does not trigger an update
arr.push(2);
// this assignment will trigger an update
// if the markup references `arr`
arr = arr
}
</script>
```
#### 3. `$:` marks a statement as reactive
--- ---
@ -169,13 +187,13 @@ If a statement consists entirely of an assignment to an undeclared variable, Sve
</script> </script>
``` ```
##### 4. Prefix stores with `$` to access their values #### 4. Prefix stores with `$` to access their values
--- ---
A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract. A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract.
Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, and set up a store subscription that will be unsubscribed when appropriate. Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, subscribe to the store at component initialization and unsubscribe when appropriate.
Assignments to `$`-prefixed variables require that the variable be a writable store, and will result in a call to the store's `.set` method. Assignments to `$`-prefixed variables require that the variable be a writable store, and will result in a call to the store's `.set` method.
@ -277,6 +295,15 @@ To apply styles to a selector globally, use the `:global(...)` modifier.
to this component */ to this component */
color: goldenrod; color: goldenrod;
} }
p:global(.red) {
/* this will apply to all <p> elements belonging to this
component with a class of red, even if class="red" does
not initially appear in the markup, and is instead
added at runtime. This is useful when the class
of the element is dynamically applied, for instance
when updating the element's classList property directly. */
}
</style> </style>
``` ```
@ -291,3 +318,23 @@ The `-global-` part will be removed when compiled, and the keyframe then be refe
@keyframes -global-my-animation-name {...} @keyframes -global-my-animation-name {...}
</style> </style>
``` ```
---
There should only be 1 top-level `<style>` tag per component.
However, it is possible to have `<style>` tag nested inside other elements or logic blocks.
In that case, the `<style>` tag will be inserted as-is into the DOM, no scoping or processing will be done on the `<style>` tag.
```html
<div>
<style>
/* this style tag will be inserted as-is */
div {
/* this will apply to all `<div>` elements in the DOM */
color: red;
}
</style>
</div>
```

@ -136,11 +136,14 @@ An element or component can have multiple spread attributes, interspersed with r
Text can also contain JavaScript expressions: Text can also contain JavaScript expressions:
> If you're using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you'll need to wrap it in parentheses.
```sv ```sv
<h1>Hello {name}!</h1> <h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p> <p>{a} + {b} = {a + b}.</p>
```
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
```
### Comments ### Comments
@ -347,7 +350,7 @@ If you don't care about the pending state, you can also omit the initial block.
--- ---
If conversely you only want to show the error state, you can omit the `then` block. Similarly, if you only want to show the error state, you can omit the `then` block.
```sv ```sv
{#await promise catch error} {#await promise catch error}
@ -393,7 +396,7 @@ When used around components, this will cause them to be reinstantiated and reini
In a text expression, characters like `<` and `>` are escaped; however, with HTML expressions, they're not. In a text expression, characters like `<` and `>` are escaped; however, with HTML expressions, they're not.
The expression should be valid standalone HTML — `{@html "<div>"}content{@html "</div>"}` will *not* work, because `</div>` is not valid HTML. The expression should be valid standalone HTML — `{@html "<div>"}content{@html "</div>"}` will *not* work, because `</div>` is not valid HTML. It also will *not* compile Svelte code.
> 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. > 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.
@ -512,7 +515,8 @@ The following modifiers are available:
* `nonpassive` — explicitly set `passive: false` * `nonpassive` — explicitly set `passive: false`
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase * `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase
* `once` — remove the handler after the first time it runs * `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself * `self` — only trigger handler if `event.target` is the element itself
* `trusted` — only trigger handler if `event.isTrusted` is `true`. I.e. if the event is triggered by a user action.
Modifiers can be chained together, e.g. `on:click|once|capture={...}`. Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
@ -585,7 +589,7 @@ Numeric input values are coerced; even though `input.value` is a string as far a
--- ---
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). 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). It is readonly.
```sv ```sv
<label for="avatar">Upload a picture:</label> <label for="avatar">Upload a picture:</label>
@ -647,6 +651,19 @@ Elements with the `contenteditable` attribute support `innerHTML` and `textConte
<div contenteditable="true" bind:innerHTML={html}></div> <div contenteditable="true" bind:innerHTML={html}></div>
``` ```
---
`<details>` elements support binding to the `open` property.
```sv
<details bind:open={isOpen}>
<summary>Details</summary>
<p>
Something small enough to escape casual notice.
</p>
</details>
```
##### Media element bindings ##### Media element bindings
--- ---
@ -666,7 +683,7 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — six
* `playbackRate` — how fast or slow to play the video, where 1 is 'normal' * `playbackRate` — how fast or slow to play the video, where 1 is 'normal'
* `paused` — this one should be self-explanatory * `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1 * `volume` — a value between 0 and 1
* `muted` — a boolean value where `true` is muted * `muted` — a boolean value indicating whether the player is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings. Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
@ -959,20 +976,22 @@ A custom transition function can also return a `tick` function, which is called
<script> <script>
export let visible = false; export let visible = false;
function typewriter(node, { speed = 50 }) { function typewriter(node, { speed = 1 }) {
const valid = ( const valid = (
node.childNodes.length === 1 && node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE node.childNodes[0].nodeType === Node.TEXT_NODE
); );
if (!valid) return {}; if (!valid) {
throw new Error(`This transition only works on elements with a single text node child`);
}
const text = node.textContent; const text = node.textContent;
const duration = text.length * speed; const duration = text.length / (speed * 0.01);
return { return {
duration, duration,
tick: (t, u) => { tick: t => {
const i = ~~(text.length * t); const i = ~~(text.length * t);
node.textContent = text.slice(0, i); node.textContent = text.slice(0, i);
} }
@ -981,7 +1000,7 @@ A custom transition function can also return a `tick` function, which is called
</script> </script>
{#if visible} {#if visible}
<p in:typewriter="{{ speed: 20 }}"> <p in:typewriter="{{ speed: 1 }}">
The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog
</p> </p>
{/if} {/if}
@ -1236,6 +1255,74 @@ As with DOM events, if the `on:` directive is used without a value, the componen
<SomeComponent on:whatever/> <SomeComponent on:whatever/>
``` ```
#### [--style-props](style_props)
```sv
--style-props="anycssvalue"
```
---
You can also pass styles as props to components for the purposes of theming, using CSS custom properties.
Svelte's implementation is essentially syntactic sugar for adding a wrapper element. This example:
```sv
<Slider
bind:value
min={0}
--rail-color="black"
--track-color="rgb(0, 0, 255)"
/>
```
---
Desugars to this:
```sv
<div style="display: contents; --rail-color: black; --track-color: rgb(0, 0, 255)">
<Slider
bind:value
min={0}
max={100}
/>
</div>
```
**Note**: Since this is an extra `<div>`, beware that your CSS structure might accidentally target this. Be mindful of this added wrapper element when using this feature.
---
Svelte's CSS Variables support allows for easily themable components:
```sv
<!-- Slider.svelte -->
<style>
.potato-slider-rail {
background-color: var(--rail-color, var(--theme-color, 'purple'));
}
</style>
```
---
So you can set a high level theme color:
```css
/* global.css */
html {
--theme-color: black;
}
```
---
Or override it at the consumer level:
```sv
<Slider --rail-color="goldenrod"/>
```
#### [bind:*property*](bind_component_property) #### [bind:*property*](bind_component_property)
@ -1354,7 +1441,7 @@ In order to place content in a slot without using a wrapper element, you can use
--- ---
`$$slots` is an object whose keys are the names of the slots passed into the component by the parent. If the parent does not pass in a slot with a particular name, that name will not be a present in `$$slots`. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it. `$$slots` is an object whose keys are the names of the slots passed into the component by the parent. If the parent does not pass in a slot with a particular name, that name will not be present in `$$slots`. This allows components to render a slot (and other elements, like wrappers for styling) only if the parent provides it.
Note that explicitly passing in an empty named slot will add that slot's name to `$$slots`. For example, if a parent passes `<div slot="title" />` to a child component, `$$slots.title` will be truthy within the child. Note that explicitly passing in an empty named slot will add that slot's name to `$$slots`. For example, if a parent passes `<div slot="title" />` to a child component, `$$slots.title` will be truthy within the child.
@ -1376,7 +1463,7 @@ Note that explicitly passing in an empty named slot will add that slot's name to
</Card> </Card>
``` ```
#### [`<slot let:`*name*`={`*value*`}>`](slot_let) #### [`<slot key={`*value*`}>`](slot_let)
--- ---
@ -1430,7 +1517,7 @@ Named slots can also expose values. The `let:` directive goes on the element wit
The `<svelte:self>` element allows a component to include itself, recursively. 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. It cannot appear at the top level of your markup; it must be inside an if or each block or passed to a component's slot to prevent an infinite loop.
```sv ```sv
<script> <script>
@ -1497,6 +1584,8 @@ If `tag` has a nullish value, a warning will be logged in development mode.
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. 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.
Unlike `<svelte:self>`, this element may only appear the top level of your component and must never be inside a block or element.
```sv ```sv
<script> <script>
function handleKeydown(event) { function handleKeydown(event) {
@ -1534,12 +1623,15 @@ 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`. Similarly to `<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`. It also lets you use [actions](docs#use_action) on the `<body>` element.
`<svelte:body>` also has to appear at the top level of your component.
```sv ```sv
<svelte:body <svelte:body
on:mouseenter={handleMouseenter} on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave} on:mouseleave={handleMouseleave}
use:someAction
/> />
``` ```
@ -1554,6 +1646,8 @@ 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. 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.
As with `<svelte:window>` and `<svelte:body>`, this element has to appear at the top level of your component and cannot be inside a block or other element.
```sv ```sv
<svelte:head> <svelte:head>
<link rel="stylesheet" href="tutorial/dark-theme.css"> <link rel="stylesheet" href="tutorial/dark-theme.css">

@ -84,6 +84,8 @@ afterUpdate(callback: () => void)
Schedules a callback to run immediately after the component has been updated. Schedules a callback to run immediately after the component has been updated.
> The first time the callback runs will be after the initial `onMount`
```sv ```sv
<script> <script>
import { afterUpdate } from 'svelte'; import { afterUpdate } from 'svelte';
@ -198,6 +200,24 @@ Checks whether a given `key` has been set in the context of a parent component.
</script> </script>
``` ```
#### `getAllContexts`
```js
contexts: Map<any, any> = getAllContexts()
```
---
Retrieves the whole context map that belongs to the closest parent component. Must be called during component initialisation. Useful, for example, if you programmatically create a component and want to pass the existing context to it.
```sv
<script>
import { getAllContexts } from 'svelte';
const contexts = getAllContexts();
</script>
```
#### `createEventDispatcher` #### `createEventDispatcher`
```js ```js
@ -245,10 +265,10 @@ This makes it possible to wrap almost any other reactive state handling library
#### `writable` #### `writable`
```js ```js
store = writable(value: any) store = writable(value?: any)
``` ```
```js ```js
store = writable(value: any, (set: (value: any) => void) => () => void) store = writable(value?: any, start?: (set: (value: any) => void) => () => void)
``` ```
--- ---
@ -294,17 +314,17 @@ const unsubscribe = count.subscribe(value => {
unsubscribe(); // logs 'no more subscribers' unsubscribe(); // logs 'no more subscribers'
``` ```
Note that the value of a `writable` is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the `localStorage`.
#### `readable` #### `readable`
```js ```js
store = readable(value: any, (set: (value: any) => void) => () => void) store = readable(value?: any, start?: (set: (value: any) => void) => () => void)
``` ```
--- ---
Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value. Creates a store whose value cannot be set from 'outside', the first argument is the store's initial value, and the second argument to `readable` is the same as the second argument to `writable`.
The second argument to `readable` is the same as the second argument to `writable`, except that it is required with `readable` (since otherwise there would be no way to update the store value).
```js ```js
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
@ -337,7 +357,7 @@ store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) =
--- ---
Derives a store from one or more other stores. Whenever those dependencies change, the callback runs. Derives a store from one or more other stores. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change.
In the simplest version, `derived` takes a single store, and the callback returns a derived value. In the simplest version, `derived` takes a single store, and the callback returns a derived value.
@ -754,7 +774,7 @@ Animates the stroke of an SVG element, like a snake in a tube. `in` transitions
* `duration` (`number` | `function`, default 800) — milliseconds the transition lasts * `duration` (`number` | `function`, default 800) — milliseconds the transition lasts
* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing) * `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is modifier that is applied to the length of the path: `duration = length / speed`. A path that is 1000 pixels with a speed of 1 will have a duration of `1000ms`, setting the speed to `0.5` will double that duration and setting it to `2` will halve it. The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is a 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.
```sv ```sv
<script> <script>
@ -777,8 +797,36 @@ The `speed` parameter is a means of setting the duration of the transition relat
``` ```
<!-- Crossfade is coming soon... --> #### `crossfade`
The `crossfade` function creates a pair of [transitions](docs#transition_fn) called `send` and `receive`. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the `fallback` transition is used.
---
`crossfade` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number` | `function`, default 800) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `fallback` (`function`) — A fallback [transition](docs#transition_fn) to use for send when there is no matching element being received, and for receive when there is no element being sent.
```sv
<script>
import { crossfade } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
const [send, receive] = crossfade({
duration:1500,
easing: quintOut
});
</script>
{#if condition}
<h1 in:send={{key}} out:receive={{key}}>BIG ELEM</h1>
{:else}
<small in:send={{key}} out:receive={{key}}>small elem</small>
{/if}
```
### `svelte/animate` ### `svelte/animate`
@ -901,7 +949,7 @@ The following initialisation options can be provided:
| option | default | description | | option | default | description |
| --- | --- | --- | | --- | --- | --- |
| `target` | **none** | An `HTMLElement` to render to. This option is required | `target` | **none** | An `HTMLElement` or `ShadowRoot` to render to. This option is required
| `anchor` | `null` | A child of `target` to render the component immediately before | `anchor` | `null` | A child of `target` to render the component immediately before
| `props` | `{}` | An object of properties to supply to the component | `props` | `{}` | An object of properties to supply to the component
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component | `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component

@ -6,7 +6,7 @@ Typically, you won't interact with the Svelte compiler directly, but will instea
* [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) for users of [Rollup](https://rollupjs.org) * [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) for users of [Rollup](https://rollupjs.org)
* [svelte-loader](https://github.com/sveltejs/svelte-loader) for users of [webpack](https://webpack.js.org) * [svelte-loader](https://github.com/sveltejs/svelte-loader) for users of [webpack](https://webpack.js.org)
* or one of the [community-maintained plugins](https://github.com/sveltejs/integrations#bundler-plugins) * or one of the [community-maintained plugins](https://sveltesociety.dev/tooling)
Nonetheless, it's useful to understand how to use the compiler, since bundler plugins generally expose compiler options to you. Nonetheless, it's useful to understand how to use the compiler, since bundler plugins generally expose compiler options to you.
@ -44,7 +44,9 @@ The following options can be passed to the compiler. None are required:
| `filename` | string | `null` | `filename` | string | `null`
| `name` | string | `"Component"` | `name` | string | `"Component"`
| `format` | `"esm"` or `"cjs"` | `"esm"` | `format` | `"esm"` or `"cjs"` | `"esm"`
| `generate` | `"dom"` or `"ssr"` | `"dom"` | `generate` | `"dom"` or `"ssr"` or `false` | `"dom"`
| `errorMode` | `"throw"` or `"warn"` | `"throw"`
| `varsReport` | `"strict"` or `"full"` or `false` | `"strict"`
| `dev` | boolean | `false` | `dev` | boolean | `false`
| `immutable` | boolean | `false` | `immutable` | boolean | `false`
| `hydratable` | boolean | `false` | `hydratable` | boolean | `false`
@ -66,6 +68,8 @@ The following options can be passed to the compiler. None are required:
| `name` | `"Component"` | `string` that sets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope). It will normally be inferred from `filename`. | `name` | `"Component"` | `string` that sets the name of the resulting JavaScript class (though the compiler will rename it if it would otherwise conflict with other variables in scope). It will normally be inferred from `filename`.
| `format` | `"esm"` | If `"esm"`, creates a JavaScript module (with `import` and `export`). If `"cjs"`, creates a CommonJS module (with `require` and `module.exports`), which is useful in some server-side rendering situations or for testing. | `format` | `"esm"` | If `"esm"`, creates a JavaScript module (with `import` and `export`). If `"cjs"`, creates a CommonJS module (with `require` and `module.exports`), which is useful in some server-side rendering situations or for testing.
| `generate` | `"dom"` | If `"dom"`, Svelte emits a JavaScript class for mounting to the DOM. If `"ssr"`, Svelte emits an object with a `render` method suitable for server-side rendering. If `false`, no JavaScript or CSS is returned; just metadata. | `generate` | `"dom"` | If `"dom"`, Svelte emits a JavaScript class for mounting to the DOM. If `"ssr"`, Svelte emits an object with a `render` method suitable for server-side rendering. If `false`, no JavaScript or CSS is returned; just metadata.
| `errorMode` | `"throw"` | If `"throw"`, Svelte throws when a compilation error occurred. If `"warn"`, Svelte will treat errors as warnings and add them to the warning report.
| `varsReport` | `"strict"` | If `"strict"`, Svelte returns a variables report with only variables that are not globals nor internals. If `"full"`, Svelte returns a variables report with all detected variables. If `false`, no variables report is returned.
| `dev` | `false` | If `true`, causes extra code to be added to components that will perform runtime checks and provide debugging information during development. | `dev` | `false` | If `true`, causes extra code to be added to components that will perform runtime checks and provide debugging information during development.
| `immutable` | `false` | If `true`, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed. | `immutable` | `false` | If `true`, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed.
| `hydratable` | `false` | If `true` when generating DOM code, enables the `hydrate: true` runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch. When generating SSR code, this adds markers to `<head>` elements so that hydration knows which to replace. | `hydratable` | `false` | If `true` when generating DOM code, enables the `hydrate: true` runtime option, which allows a component to upgrade existing DOM rather than creating new DOM from scratch. When generating SSR code, this adds markers to `<head>` elements so that hydration knows which to replace.
@ -199,11 +203,11 @@ result: {
code: string, code: string,
dependencies?: Array<string> dependencies?: Array<string>
}>, }>,
script?: (input: { content: string, attributes: Record<string, string>, filename: string }) => Promise<{ script?: (input: { content: string, markup: string, attributes: Record<string, string>, filename: string }) => Promise<{
code: string, code: string,
dependencies?: Array<string> dependencies?: Array<string>
}>, }>,
style?: (input: { content: string, attributes: Record<string, string>, filename: string }) => Promise<{ style?: (input: { content: string, markup: string, attributes: Record<string, string>, filename: string }) => Promise<{
code: string, code: string,
dependencies?: Array<string> dependencies?: Array<string>
}> }>
@ -224,16 +228,24 @@ Each `markup`, `script` or `style` function must return an object (or a Promise
The `markup` function receives the entire component source text, along with the component's `filename` if it was specified in the third argument. The `markup` function receives the entire component source text, along with the component's `filename` if it was specified in the third argument.
> Preprocessor functions may additionally return a `map` object alongside `code` and `dependencies`, where `map` is a sourcemap representing the transformation. In current versions of Svelte it will be ignored, but future versions of Svelte may take account of preprocessor sourcemaps. > Preprocessor functions should additionally return a `map` object alongside `code` and `dependencies`, where `map` is a sourcemap representing the transformation.
```js ```js
const svelte = require('svelte/compiler'); const svelte = require('svelte/compiler');
const MagicString = require('magic-string');
const { code } = await svelte.preprocess(source, { const { code } = await svelte.preprocess(source, {
markup: ({ content, filename }) => { markup: ({ content, filename }) => {
const pos = content.indexOf('foo');
if(pos < 0) {
return { code: content }
}
const s = new MagicString(content, { filename })
s.overwrite(pos, pos + 3, 'bar', { storeName: true })
return { return {
code: content.replace(/foo/g, 'bar') code: s.toString(),
}; map: s.generateMap()
}
} }
}, { }, {
filename: 'App.svelte' filename: 'App.svelte'
@ -242,7 +254,7 @@ const { code } = await svelte.preprocess(source, {
--- ---
The `script` and `style` functions receive the contents of `<script>` and `<style>` elements respectively. In addition to `filename`, they get an object of the element's attributes. The `script` and `style` functions receive the contents of `<script>` and `<style>` elements respectively (`content`) as well as the entire component source text (`markup`). In addition to `filename`, they get an object of the element's attributes.
If a `dependencies` array is returned, it will be included in the result object. This is used by packages like [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) to watch additional files for changes, in the case where your `<style>` tag has an `@import` (for example). If a `dependencies` array is returned, it will be included in the result object. This is used by packages like [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) to watch additional files for changes, in the case where your `<style>` tag has an `@import` (for example).

@ -0,0 +1,258 @@
---
title: Accessibility warnings
---
Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you at compile time if you write inaccessible markup. However, keep in mind that many accessibility issues can only be identified at runtime using other automated tools and by manually testing your application.
Here is a list of accessibility checks Svelte will do for you.
---
### `a11y-accesskey`
Enforce no `accesskey` on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen reader and keyboard-only users create accessibility complications. To avoid complications, access keys should not be used.
```sv
<!-- A11y: Avoid using accesskey -->
<div accessKey='z'></div>
```
---
### `a11y-aria-attributes`
Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `aria-*` props.
```sv
<!-- A11y: <meta> should not have aria-* attributes -->
<meta aria-hidden="false">
```
---
### `a11y-autofocus`
Enforce that `autofocus` is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.
```sv
<!-- A11y: Avoid using autofocus -->
<input autofocus>
```
---
### `a11y-distracting-elements`
Enforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided.
The following elements are visually distracting: `<marquee>` and `<blink>`.
```sv
<!-- A11y: Avoid <marquee> elements -->
<marquee />
```
---
### `a11y-hidden`
Certain DOM elements are useful for screen reader navigation and should not be hidden.
```sv
<!-- A11y: <h2> element should not be hidden -->
<h2 aria-hidden="true">invisible header</h2>
```
---
### `a11y-img-redundant-alt`
Enforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce `img` elements as an image. There is no need to use words such as _image_, _photo_, and/or _picture_.
```sv
<img src="foo" alt="Foo eating a sandwich." />
<!-- aria-hidden, won't be announced by screen reader -->
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Photo of foo being weird." />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="bar" alt="Image of me at a bar!" />
<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Picture of baz fixing a bug." />
```
---
### `a11y-invalid-attribute`
Enforce that attributes important for accessibility have a valid value. For example, `href` should not be empty, `'#'`, or `javascript:`.
```sv
<!-- A11y: '' is not a valid href attribute -->
<a href=''>invalid</a>
```
---
### `a11y-label-has-associated-control`
Enforce that a label tag has a text label and an associated control.
There are two supported ways to associate a label with a control:
- Wrapping a control in a label tag.
- Adding `for` to a label and assigning it the ID of an input on the page.
```sv
<label for="id">B</label>
<label>C <input type="text" /></label>
<!-- A11y: A form label must be associated with a control. -->
<label>A</label>
```
---
### `a11y-media-has-caption`
Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to `alt` text on an image when an image is unable to load).
The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are not necessary for video components with the `muted` attribute.
```sv
<video><track kind="captions"/></video>
<audio muted></audio>
<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video></video>
<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video><track /></video>
```
---
### `a11y-misplaced-role`
Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` props.
```sv
<!-- A11y: <meta> should not have role attribute -->
<meta role="tooltip">
```
---
### `a11y-misplaced-scope`
The scope attribute should only be used on `<th>` elements.
```sv
<!-- A11y: The scope attribute should only be used with <th> elements -->
<div scope="row" />
```
---
### `a11y-missing-attribute`
Enforce that attributes required for accessibility are present on an element. This includes the following checks:
- `<a>` should have an href (unless it's a [fragment-defining tag](https://github.com/sveltejs/svelte/issues/4697))
- `<area>` should have alt, aria-label, or aria-labelledby
- `<html>` should have lang
- `<iframe>` should have title
- `<img>` should have alt
- `<object>` should have title, aria-label, or aria-labelledby
- `<input type="image">` should have alt, aria-label, or aria-labelledby
```sv
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-labelledby attribute -->
<input type="image">
<!-- A11y: <html> element should have a lang attribute -->
<html></html>
<!-- A11y: <a> element should have an href attribute -->
<a>text</a>
```
---
### `a11y-missing-content`
Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and that the content is accessible to screen readers
```sv
<!-- A11y: <a> element should have child content -->
<a href='/foo'></a>
<!-- A11y: <h1> element should have child content -->
<h1></h1>
```
---
### `a11y-mouse-events-have-key-events`
Enforce that `on:mouseover` and `on:mouseout` are accompanied by `on:focus` and `on:blur`, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.
```sv
<!-- A11y: on:mouseover must be accompanied by on:focus -->
<div on:mouseover={handleMouseover} />
<!-- A11y: on:mouseout must be accompanied by on:blur -->
<div on:mouseout={handleMouseout} />
```
---
### `a11y-positive-tabindex`
Avoid positive `tabindex` property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.
```sv
<!-- A11y: avoid tabindex values above zero -->
<div tabindex='1'/>
```
---
### `a11y-structure`
Enforce that certain DOM elements have the correct structure.
```sv
<!-- A11y: <figcaption> must be an immediate child of <figure> -->
<div>
<figcaption>Image caption</figcaption>
</div>
```
---
### `a11y-unknown-aria-attribute`
Enforce that only known ARIA attributes are used. This is based on the [WAI-ARIA States and Properties spec](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties).
```sv
<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
<input type="image" aria-labeledby="foo">
```
---
### `a11y-unknown-role`
Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.
```sv
<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->
<div role="toooltip"></div>
```

@ -1,3 +1,5 @@
<p>Styled!</p>
<style> <style>
p { p {
color: purple; color: purple;
@ -5,5 +7,3 @@
font-size: 2em; font-size: 2em;
} }
</style> </style>
<p>Styled!</p>

@ -2,6 +2,9 @@
import Nested from './Nested.svelte'; import Nested from './Nested.svelte';
</script> </script>
<p>These styles...</p>
<Nested/>
<style> <style>
p { p {
color: purple; color: purple;
@ -9,6 +12,3 @@
font-size: 2em; font-size: 2em;
} }
</style> </style>
<p>These styles...</p>
<Nested/>

@ -7,10 +7,10 @@
} }
</script> </script>
<style>
div { width: 100%; height: 100%; }
</style>
<div on:mousemove={handleMousemove}> <div on:mousemove={handleMousemove}>
The mouse position is {m.x} x {m.y} The mouse position is {m.x} x {m.y}
</div> </div>
<style>
div { width: 100%; height: 100%; }
</style>

@ -2,10 +2,10 @@
let m = { x: 0, y: 0 }; let m = { x: 0, y: 0 };
</script> </script>
<style>
div { width: 100%; height: 100%; }
</style>
<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}"> <div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}">
The mouse position is {m.x} x {m.y} The mouse position is {m.x} x {m.y}
</div> </div>
<style>
div { width: 100%; height: 100%; }
</style>

@ -1,3 +1,7 @@
<button on:click>
Click me
</button>
<style> <style>
button { button {
height: 4rem; height: 4rem;
@ -16,7 +20,3 @@
color: #aaa; color: #aaa;
} }
</style> </style>
<button on:click>
Click me
</button>

@ -3,10 +3,10 @@
let text = `Some words are *italic*, some are **bold**`; let text = `Some words are *italic*, some are **bold**`;
</script> </script>
<style>
textarea { width: 100%; height: 200px; }
</style>
<textarea bind:value={text}></textarea> <textarea bind:value={text}></textarea>
{@html marked(text)} {@html marked(text)}
<style>
textarea { width: 100%; height: 200px; }
</style>

@ -14,10 +14,6 @@
} }
</script> </script>
<style>
input { display: block; width: 500px; max-width: 100%; }
</style>
<h2>Insecurity questions</h2> <h2>Insecurity questions</h2>
<form on:submit|preventDefault={handleSubmit}> <form on:submit|preventDefault={handleSubmit}>
@ -37,3 +33,7 @@
</form> </form>
<p>selected question {selected ? selected.id : '[waiting...]'}</p> <p>selected question {selected ? selected.id : '[waiting...]'}</p>
<style>
input { display: block; width: 500px; max-width: 100%; }
</style>

@ -7,37 +7,35 @@
let showControls = true; let showControls = true;
let showControlsTimeout; let showControlsTimeout;
function handleMousemove(e) { // Used to track time of last mouse down event
let lastMouseDown;
function handleMove(e) {
// Make the controls visible, but fade out after // Make the controls visible, but fade out after
// 2.5 seconds of inactivity // 2.5 seconds of inactivity
clearTimeout(showControlsTimeout); clearTimeout(showControlsTimeout);
showControlsTimeout = setTimeout(() => showControls = false, 2500); showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true; showControls = true;
if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet if (!duration) return; // video not loaded yet
if (e.type !== 'touchmove' && !(e.buttons & 1)) return; // mouse not down
const clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
const { left, right } = this.getBoundingClientRect(); const { left, right } = this.getBoundingClientRect();
time = duration * (e.clientX - left) / (right - left); time = duration * (clientX - left) / (right - left);
} }
// we can't rely on the built-in click event, because it fires
// after a drag — we have to listen for clicks ourselves
function handleMousedown(e) { function handleMousedown(e) {
// we can't rely on the built-in click event, because it fires lastMouseDown = new Date();
// after a drag — we have to listen for clicks ourselves }
function handleMouseup() { function handleMouseup(e) {
if (new Date() - lastMouseDown < 300) {
if (paused) e.target.play(); if (paused) e.target.play();
else e.target.pause(); else e.target.pause();
cancel();
}
function cancel() {
e.target.removeEventListener('mouseup', handleMouseup);
} }
e.target.addEventListener('mouseup', handleMouseup);
setTimeout(cancel, 200);
} }
function format(seconds) { function format(seconds) {
@ -51,6 +49,34 @@
} }
</script> </script>
<h1>Caminandes: Llamigos</h1>
<p>From <a href="https://cloud.blender.org/open-projects">Blender Open Projects</a>. CC-BY</p>
<div>
<video
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMove}
on:touchmove|preventDefault={handleMove}
on:mousedown={handleMousedown}
on:mouseup={handleMouseup}
bind:currentTime={time}
bind:duration
bind:paused>
<track kind="captions"/>
</video>
<div class="controls" style="opacity: {duration && showControls ? 1 : 0}">
<progress value="{(time / duration) || 0}"/>
<div class="info">
<span class="time">{format(time)}</span>
<span>click anywhere to {paused ? 'play' : 'pause'} / drag to seek</span>
<span class="time">{format(duration)}</span>
</div>
</div>
</div>
<style> <style>
div { div {
position: relative; position: relative;
@ -103,29 +129,3 @@
width: 100%; width: 100%;
} }
</style> </style>
<h1>Caminandes: Llamigos</h1>
<p>From <a href="https://cloud.blender.org/open-projects">Blender Open Projects</a>. CC-BY</p>
<div>
<video
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}
bind:duration
bind:paused>
<track kind="captions"/>
</video>
<div class="controls" style="opacity: {duration && showControls ? 1 : 0}">
<progress value="{(time / duration) || 0}"/>
<div class="info">
<span class="time">{format(time)}</span>
<span>click anywhere to {paused ? 'play' : 'pause'} / drag to seek</span>
<span class="time">{format(duration)}</span>
</div>
</div>
</div>

@ -5,11 +5,6 @@
let text = 'edit me'; let text = 'edit me';
</script> </script>
<style>
input { display: block; }
div { display: inline-block; }
</style>
<input type=range bind:value={size}> <input type=range bind:value={size}>
<input bind:value={text}> <input bind:value={text}>
@ -18,3 +13,8 @@
<div bind:clientWidth={w} bind:clientHeight={h}> <div bind:clientWidth={w} bind:clientHeight={h}>
<span style="font-size: {size}px">{text}</span> <span style="font-size: {size}px">{text}</span>
</div> </div>
<style>
input { display: block; }
div { display: inline-block; }
</style>

@ -38,6 +38,12 @@
}); });
</script> </script>
<canvas
bind:this={canvas}
width={32}
height={32}
></canvas>
<style> <style>
canvas { canvas {
width: 100%; width: 100%;
@ -47,9 +53,3 @@
mask: url(svelte-logo-mask.svg) 50% 50% no-repeat; mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
} }
</style> </style>
<canvas
bind:this={canvas}
width={32}
height={32}
></canvas>

@ -10,19 +10,6 @@
const submit = () => dispatch('submit'); const submit = () => dispatch('submit');
</script> </script>
<style>
.keypad {
display: grid;
grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em
}
button {
margin: 0
}
</style>
<div class="keypad"> <div class="keypad">
<button on:click={select(1)}>1</button> <button on:click={select(1)}>1</button>
<button on:click={select(2)}>2</button> <button on:click={select(2)}>2</button>
@ -38,3 +25,16 @@
<button on:click={select(0)}>0</button> <button on:click={select(0)}>0</button>
<button disabled={!value} on:click={submit}>submit</button> <button disabled={!value} on:click={submit}>submit</button>
</div> </div>
<style>
.keypad {
display: grid;
grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em
}
button {
margin: 0
}
</style>

@ -9,20 +9,6 @@
}); });
</script> </script>
<style>
.photos {
width: 100%;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 8px;
}
figure, img {
width: 100%;
margin: 0;
}
</style>
<h1>Photo album</h1> <h1>Photo album</h1>
<div class="photos"> <div class="photos">
@ -36,3 +22,17 @@
<p>loading...</p> <p>loading...</p>
{/each} {/each}
</div> </div>
<style>
.photos {
width: 100%;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 8px;
}
figure, img {
width: 100%;
margin: 0;
}
</style>

@ -51,6 +51,20 @@
} }
</script> </script>
<div class="chat">
<h1>Eliza</h1>
<div class="scrollable" bind:this={div}>
{#each comments as comment}
<article class={comment.author}>
<span>{comment.text}</span>
</article>
{/each}
</div>
<input on:keydown={handleKeydown}>
</div>
<style> <style>
.chat { .chat {
display: flex; display: flex;
@ -90,17 +104,3 @@
border-radius: 1em 1em 0 1em; border-radius: 1em 1em 0 1em;
} }
</style> </style>
<div class="chat">
<h1>Eliza</h1>
<div class="scrollable" bind:this={div}>
{#each comments as comment}
<article class={comment.author}>
<span>{comment.text}</span>
</article>
{/each}
</div>
<input on:keydown={handleKeydown}>
</div>

@ -27,11 +27,11 @@
} }
</script> </script>
<textarea value={text} on:keydown={handleKeydown}></textarea>
<style> <style>
textarea { textarea {
width: 100%; width: 100%;
height: 200px; height: 200px;
} }
</style> </style>
<textarea value={text} on:keydown={handleKeydown}></textarea>

@ -8,13 +8,6 @@
}); });
</script> </script>
<style>
progress {
display: block;
width: 100%;
}
</style>
<progress value={$progress}></progress> <progress value={$progress}></progress>
<button on:click="{() => progress.set(0)}"> <button on:click="{() => progress.set(0)}">
@ -36,3 +29,10 @@
<button on:click="{() => progress.set(1)}"> <button on:click="{() => progress.set(1)}">
100% 100%
</button> </button>
<style>
progress {
display: block;
width: 100%;
}
</style>

@ -9,11 +9,6 @@
let size = spring(10); let size = spring(10);
</script> </script>
<style>
svg { width: 100%; height: 100%; margin: -8px }
circle { fill: #ff3e00 }
</style>
<div style="position: absolute; right: 1em;"> <div style="position: absolute; right: 1em;">
<label> <label>
<h3>stiffness ({coords.stiffness})</h3> <h3>stiffness ({coords.stiffness})</h3>
@ -33,3 +28,8 @@
> >
<circle cx={$coords.x} cy={$coords.y} r={$size}/> <circle cx={$coords.x} cy={$coords.y} r={$size}/>
</svg> </svg>
<style>
svg { width: 100%; height: 100%; margin: -8px }
circle { fill: #ff3e00 }
</style>

@ -22,6 +22,17 @@
} }
</script> </script>
<label>
<input type="checkbox" bind:checked={visible}>
visible
</label>
{#if visible}
<div class="centered" in:spin="{{duration: 8000}}" out:fade>
<span>transitions!</span>
</div>
{/if}
<style> <style>
.centered { .centered {
position: absolute; position: absolute;
@ -36,14 +47,3 @@
font-size: 4em; font-size: 4em;
} }
</style> </style>
<label>
<input type="checkbox" bind:checked={visible}>
visible
</label>
{#if visible}
<div class="centered" in:spin="{{duration: 8000}}" out:fade>
<span>transitions!</span>
</div>
{/if}

@ -1,7 +1,7 @@
<script> <script>
let visible = false; let visible = false;
function typewriter(node, { speed = 50 }) { function typewriter(node, { speed = 1 }) {
const valid = ( const valid = (
node.childNodes.length === 1 && node.childNodes.length === 1 &&
node.childNodes[0].nodeType === Node.TEXT_NODE node.childNodes[0].nodeType === Node.TEXT_NODE
@ -12,7 +12,7 @@
} }
const text = node.textContent; const text = node.textContent;
const duration = text.length * speed; const duration = text.length / (speed * 0.01);
return { return {
duration, duration,
@ -30,7 +30,7 @@
</label> </label>
{#if visible} {#if visible}
<p in:typewriter> <p in:typewriter out:typewriter>
The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog
</p> </p>
{/if} {/if}

@ -46,6 +46,44 @@
} }
</script> </script>
<div class='board'>
<input
class="new-todo"
placeholder="what needs to be done?"
on:keydown="{event => event.key === 'Enter' && add(event.target)}"
>
<div class='left'>
<h2>todo</h2>
{#each todos.filter(t => !t.done) as todo (todo.id)}
<label
in:receive="{{key: todo.id}}"
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description}
<button on:click="{() => remove(todo)}">x</button>
</label>
{/each}
</div>
<div class='right'>
<h2>done</h2>
{#each todos.filter(t => t.done) as todo (todo.id)}
<label
in:receive="{{key: todo.id}}"
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description}
<button on:click="{() => remove(todo)}">x</button>
</label>
{/each}
</div>
</div>
<style> <style>
.new-todo { .new-todo {
font-size: 1.4em; font-size: 1.4em;
@ -107,41 +145,3 @@
opacity: 1; opacity: 1;
} }
</style> </style>
<div class='board'>
<input
class="new-todo"
placeholder="what needs to be done?"
on:keydown="{event => event.key === 'Enter' && add(event.target)}"
>
<div class='left'>
<h2>todo</h2>
{#each todos.filter(t => !t.done) as todo (todo.id)}
<label
in:receive="{{key: todo.id}}"
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description}
<button on:click="{() => remove(todo)}">x</button>
</label>
{/each}
</div>
<div class='right'>
<h2>done</h2>
{#each todos.filter(t => t.done) as todo (todo.id)}
<label
in:receive="{{key: todo.id}}"
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description}
<button on:click="{() => remove(todo)}">x</button>
</label>
{/each}
</div>
</div>

@ -37,35 +37,6 @@
$: current && runAnimations(); $: current && runAnimations();
</script> </script>
<style>
.easing-vis {
display: flex;
max-height: 95%;
max-width: 800px;
margin: auto;
padding: 10px;
border: 1px solid #333;
border-radius: 2px;
padding: 20px;
}
svg {
width: 100%;
margin: 0 20px 0 0;
}
.graph {
transform: translate(200px,400px)
}
@media (max-width:600px) {
.easing-vis {
flex-direction: column;
max-height: calc(100% - 3rem);
}
}
</style>
<div bind:offsetWidth={width} class="easing-vis"> <div bind:offsetWidth={width} class="easing-vis">
<svg viewBox="0 0 1400 1802"> <svg viewBox="0 0 1400 1802">
<g class="canvas"> <g class="canvas">
@ -104,3 +75,31 @@
on:play={runAnimations} on:play={runAnimations}
/> />
</div> </div>
<style>
.easing-vis {
display: flex;
max-height: 95%;
max-width: 800px;
margin: auto;
border: 1px solid #333;
border-radius: 2px;
padding: 20px;
}
svg {
width: 100%;
margin: 0 20px 0 0;
}
.graph {
transform: translate(200px,400px)
}
@media (max-width:600px) {
.easing-vis {
flex-direction: column;
max-height: calc(100% - 3rem);
}
}
</style>

@ -14,6 +14,72 @@
$: mobile = width && width < 600; $: mobile = width && width < 600;
</script> </script>
<div class="easing-sidebar">
<div class="easing-types">
<h3>Ease</h3>
{#if mobile}
<select bind:value={current_ease}>
{#each [...eases] as [name]}
<option
value={name}
class:selected={name === current_ease}
>
{name}
</option>
{/each}
</select>
{:else}
<ul>
{#each [...eases] as [name]}
<li
class:selected={name === current_ease}
on:click={() => current_ease = name}
>
{name}
</li>
{/each}
</ul>
{/if}
<h3>Type</h3>
{#if mobile }
<select bind:value={current_type}>
{#each types as [name, type]}
<option
value={type}
>
{name}
</option>
{/each}
</select>
{:else}
<ul>
{#each types as [name, type]}
<li
class:selected={type === current_type}
on:click={() => current_type = type}
>
{name}
</li>
{/each}
</ul>
{/if}
</div>
<h4>
Duration
</h4>
<div class="duration">
<span>
<input type="number" bind:value={duration} min="0" step="100"/>
<button class="number" on:click={() => duration -= 100}>-</button>
<button class="number" on:click={() => duration += 100}>+</button>
</span>
<button class="play" on:click={() => dispatch('play')}>
{playing ? 'Restart' : 'Play'}
</button>
</div>
</div>
<style> <style>
.easing-sidebar { .easing-sidebar {
width: 11em; width: 11em;
@ -119,68 +185,3 @@
} }
} }
</style> </style>
<div class="easing-sidebar">
<div class="easing-types">
<h3>Ease</h3>
{#if mobile}
<select bind:value={current_ease}>
{#each [...eases] as [name]}
<option
value={name}
class:selected={name === current_ease}
>
{name}
</option>
{/each}
</select>
{:else}
<ul>
{#each [...eases] as [name]}
<li
class:selected={name === current_ease}
on:click={() => current_ease = name}
>
{name}
</li>
{/each}
</ul>
{/if}
<h3>Type</h3>
{#if mobile }
<select bind:value={current_type}>
{#each types as [name, type]}
<option
value={type}
>
{name}
</option>
{/each}
</select>
{:else}
<ul>
{#each types as [name, type]}
<li
class:selected={type === current_type}
on:click={() => current_type = type}
>
{name}
</li>
{/each}
</ul>
{/if}
</div>
<h4>
Duration
</h4>
<div class="duration">
<span>
<input type="number" bind:value={duration} min="0" step="100"/>
<button class="number" on:click={() => duration -= 100}>-</button>
<button class="number" on:click={() => duration += 100}>+</button>
</span>
<button class="play" on:click={() => dispatch('play')}>
{playing ? 'Restart' : 'Play'}
</button>
</div>
</div>

@ -2,19 +2,6 @@
export let x, y; export let x, y;
</script> </script>
<style>
.grid-line {
stroke:#ccc;
opacity: 0.5;
stroke-width: 2;
}
.grid-line-xy {
stroke: tomato;
stroke-width: 2;
}
</style>
<svelte:options namespace="svg" /> <svelte:options namespace="svg" />
<rect <rect
@ -60,3 +47,16 @@
fill=none fill=none
stroke-width=2 stroke-width=2
/> />
<style>
.grid-line {
stroke:#ccc;
opacity: 0.5;
stroke-width: 2;
}
.grid-line-xy {
stroke: tomato;
stroke-width: 2;
}
</style>

@ -20,44 +20,6 @@
}); });
</script> </script>
<style>
svg {
width: 100%;
height: 100%;
}
.clock-face {
stroke: #333;
fill: white;
}
.minor {
stroke: #999;
stroke-width: 0.5;
}
.major {
stroke: #333;
stroke-width: 1;
}
.hour {
stroke: #333;
}
.minute {
stroke: #666;
}
.second, .second-counterweight {
stroke: rgb(180,0,0);
}
.second-counterweight {
stroke-width: 3;
}
</style>
<svg viewBox='-50 -50 100 100'> <svg viewBox='-50 -50 100 100'>
<circle class='clock-face' r='48'/> <circle class='clock-face' r='48'/>
@ -102,3 +64,41 @@
<line class='second-counterweight' y1='10' y2='2'/> <line class='second-counterweight' y1='10' y2='2'/>
</g> </g>
</svg> </svg>
<style>
svg {
width: 100%;
height: 100%;
}
.clock-face {
stroke: #333;
fill: white;
}
.minor {
stroke: #999;
stroke-width: 0.5;
}
.major {
stroke: #333;
stroke-width: 1;
}
.hour {
stroke: #333;
}
.minute {
stroke: #666;
}
.second, .second-counterweight {
stroke: rgb(180,0,0);
}
.second-counterweight {
stroke-width: 3;
}
</style>

@ -33,6 +33,42 @@
$: barWidth = innerWidth / xTicks.length; $: barWidth = innerWidth / xTicks.length;
</script> </script>
<h2>US birthrate by year</h2>
<div class="chart" bind:clientWidth={width} bind:clientHeight={height}>
<svg>
<!-- y axis -->
<g class="axis y-axis">
{#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick)})">
<line x2="100%"></line>
<text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
</g>
{/each}
</g>
<!-- x axis -->
<g class="axis x-axis">
{#each points as point, i}
<g class="tick" transform="translate({xScale(i)},{height})">
<text x="{barWidth/2}" y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text>
</g>
{/each}
</g>
<g class='bars'>
{#each points as point, i}
<rect
x="{xScale(i) + 2}"
y="{yScale(point.birthrate)}"
width="{barWidth - 4}"
height="{yScale(0) - yScale(point.birthrate)}"
></rect>
{/each}
</g>
</svg>
</div>
<style> <style>
h2 { h2 {
text-align: center; text-align: center;
@ -80,39 +116,3 @@
opacity: 0.65; opacity: 0.65;
} }
</style> </style>
<h2>US birthrate by year</h2>
<div class="chart" bind:clientWidth={width} bind:clientHeight={height}>
<svg>
<!-- y axis -->
<g class="axis y-axis" transform="translate(0,{padding.top})">
{#each yTicks as tick}
<g class="tick tick-{tick}" transform="translate(0, {yScale(tick) - padding.bottom})">
<line x2="100%"></line>
<text y="-4">{tick} {tick === 20 ? ' per 1,000 population' : ''}</text>
</g>
{/each}
</g>
<!-- x axis -->
<g class="axis x-axis">
{#each points as point, i}
<g class="tick" transform="translate({xScale(i)},{height})">
<text x="{barWidth/2}" y="-4">{width > 380 ? point.year : formatMobile(point.year)}</text>
</g>
{/each}
</g>
<g class='bars'>
{#each points as point, i}
<rect
x="{xScale(i) + 2}"
y="{yScale(point.birthrate)}"
width="{barWidth - 4}"
height="{height - padding.bottom - yScale(point.birthrate)}"
></rect>
{/each}
</g>
</svg>
</div>

@ -3,6 +3,15 @@
import data from './data.js'; import data from './data.js';
</script> </script>
<div class="chart">
<h2>Anscombe's quartet</h2>
<Scatterplot points={data.a}/>
<Scatterplot points={data.b}/>
<Scatterplot points={data.c}/>
<Scatterplot points={data.d}/>
</div>
<style> <style>
.chart { .chart {
width: 100%; width: 100%;
@ -13,12 +22,3 @@
margin: 0 auto; margin: 0 auto;
} }
</style> </style>
<div class="chart">
<h2>Anscombe's quartet</h2>
<Scatterplot points={data.a}/>
<Scatterplot points={data.b}/>
<Scatterplot points={data.c}/>
<Scatterplot points={data.d}/>
</div>

@ -7,6 +7,38 @@
let visible = true; let visible = true;
</script> </script>
{#if visible}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124">
<g out:fade="{{duration: 200}}" opacity=0.2>
<path
in:expand="{{duration: 400, delay: 1000, easing: quintOut}}"
style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;"
d={outer}
/>
<path
in:draw="{{duration: 1000}}"
style="stroke:#ff3e00; stroke-width: 1.5"
d={inner}
/>
</g>
</svg>
<div class="centered" out:fly="{{y: -20, duration: 800}}">
{#each 'SVELTE' as char, i}
<span
in:fade="{{delay: 1000 + i * 150, duration: 800}}"
>{char}</span>
{/each}
</div>
{/if}
<label>
<input type="checkbox" bind:checked={visible}>
toggle me
</label>
<link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet">
<style> <style>
svg { svg {
width: 100%; width: 100%;
@ -40,35 +72,3 @@
will-change: filter; will-change: filter;
} }
</style> </style>
{#if visible}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124">
<g out:fade="{{duration: 200}}" opacity=0.2>
<path
in:expand="{{duration: 400, delay: 1000, easing: quintOut}}"
style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;"
d={outer}
/>
<path
in:draw="{{duration: 1000}}"
style="stroke:#ff3e00; stroke-width: 1.5"
d={inner}
/>
</g>
</svg>
<div class="centered" out:fly="{{y: -20, duration: 800}}">
{#each 'SVELTE' as char, i}
<span
in:fade="{{delay: 1000 + i * 150, duration: 800}}"
>{char}</span>
{/each}
</div>
{/if}
<label>
<input type="checkbox" bind:checked={visible}>
toggle me
</label>
<link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet">

@ -25,6 +25,16 @@
} }
</script> </script>
<div class="box"
use:pannable
on:panstart={handlePanStart}
on:panmove={handlePanMove}
on:panend={handlePanEnd}
style="transform:
translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)"
></div>
<style> <style>
.box { .box {
--width: 100px; --width: 100px;
@ -39,13 +49,3 @@
cursor: move; cursor: move;
} }
</style> </style>
<div class="box"
use:pannable
on:panstart={handlePanStart}
on:panmove={handlePanMove}
on:panend={handlePanEnd}
style="transform:
translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)"
></div>

@ -2,17 +2,6 @@
let current = 'foo'; let current = 'foo';
</script> </script>
<style>
button {
display: block;
}
.active {
background-color: #ff3e00;
color: white;
}
</style>
<button <button
class:active="{current === 'foo'}" class:active="{current === 'foo'}"
on:click="{() => current = 'foo'}" on:click="{() => current = 'foo'}"
@ -27,3 +16,14 @@
class:active="{current === 'baz'}" class:active="{current === 'baz'}"
on:click="{() => current = 'baz'}" on:click="{() => current = 'baz'}"
>baz</button> >baz</button>
<style>
button {
display: block;
}
.active {
background-color: #ff3e00;
color: white;
}
</style>

@ -2,12 +2,6 @@
let big = false; let big = false;
</script> </script>
<style>
.big {
font-size: 4em;
}
</style>
<label> <label>
<input type=checkbox bind:checked={big}> <input type=checkbox bind:checked={big}>
big big
@ -16,3 +10,9 @@
<div class:big> <div class:big>
some {big ? 'big' : 'small'} text some {big ? 'big' : 'small'} text
</div> </div>
<style>
.big {
font-size: 4em;
}
</style>

@ -1,3 +1,7 @@
<div class="box">
<slot></slot>
</div>
<style> <style>
.box { .box {
width: 300px; width: 300px;
@ -8,7 +12,3 @@
margin: 0 0 1em 0; margin: 0 0 1em 0;
} }
</style> </style>
<div class="box">
<slot></slot>
</div>

@ -1,3 +1,9 @@
<div class="box">
<slot>
<em>no content was provided</em>
</slot>
</div>
<style> <style>
.box { .box {
width: 300px; width: 300px;
@ -8,9 +14,3 @@
margin: 0 0 1em 0; margin: 0 0 1em 0;
} }
</style> </style>
<div class="box">
<slot>
<em>no content was provided</em>
</slot>
</div>

@ -1,3 +1,23 @@
<article class="contact-card">
<h2>
<slot name="name">
<span class="missing">Unknown name</span>
</slot>
</h2>
<div class="address">
<slot name="address">
<span class="missing">Unknown address</span>
</slot>
</div>
<div class="email">
<slot name="email">
<span class="missing">Unknown email</span>
</slot>
</div>
</article>
<style> <style>
.contact-card { .contact-card {
width: 300px; width: 300px;
@ -25,23 +45,3 @@
.email { background-image: url(tutorial/icons/email.svg) } .email { background-image: url(tutorial/icons/email.svg) }
.missing { color: #999 } .missing { color: #999 }
</style> </style>
<article class="contact-card">
<h2>
<slot name="name">
<span class="missing">Unknown name</span>
</slot>
</h2>
<div class="address">
<slot name="address">
<span class="missing">Unknown address</span>
</slot>
</div>
<div class="email">
<slot name="email">
<span class="missing">Unknown email</span>
</slot>
</div>
</article>

@ -2,19 +2,6 @@
import Hoverable from './Hoverable.svelte'; import Hoverable from './Hoverable.svelte';
</script> </script>
<style>
div {
padding: 1em;
margin: 0 0 1em 0;
background-color: #eee;
}
.active {
background-color: #ff3e00;
color: white;
}
</style>
<Hoverable let:hovering={active}> <Hoverable let:hovering={active}>
<div class:active> <div class:active>
{#if active} {#if active}
@ -44,3 +31,16 @@
{/if} {/if}
</div> </div>
</Hoverable> </Hoverable>
<style>
div {
padding: 1em;
margin: 0 0 1em 0;
background-color: #eee;
}
.active {
background-color: #ff3e00;
color: white;
}
</style>

@ -1,15 +1,3 @@
<style>
section {
width: 200px;
display: grid;
grid-template-columns: 1fr 1fr;
padding: 16px;
box-shadow: 2px 2px 4px #dedede;
border: 1px solid #888;
margin-bottom: 16px;
}
</style>
<section> <section>
<div>Name</div> <div>Name</div>
<slot name="name" /> <slot name="name" />
@ -22,3 +10,15 @@
<slot name="phone" /> <slot name="phone" />
{/if} {/if}
</section> </section>
<style>
section {
width: 200px;
display: grid;
grid-template-columns: 1fr 1fr;
padding: 16px;
box-shadow: 2px 2px 4px #dedede;
border: 1px solid #888;
margin-bottom: 16px;
}
</style>

@ -36,15 +36,15 @@
}); });
</script> </script>
<div bind:this={container}>
{#if map}
<slot></slot>
{/if}
</div>
<style> <style>
div { div {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
</style> </style>
<div bind:this={container}>
{#if map}
<slot></slot>
{/if}
</div>

@ -3,6 +3,8 @@
$: type = name.slice(name.lastIndexOf('.') + 1); $: type = name.slice(name.lastIndexOf('.') + 1);
</script> </script>
<span style="background-image: url(tutorial/icons/{type}.svg)">{name}</span>
<style> <style>
span { span {
padding: 0 0 0 1.5em; padding: 0 0 0 1.5em;
@ -10,5 +12,3 @@
background-size: 1em 1em; background-size: 1em 1em;
} }
</style> </style>
<span style="background-image: url(tutorial/icons/{type}.svg)">{name}</span>

@ -1,5 +1,6 @@
<script> <script>
import File from './File.svelte'; import File from './File.svelte';
import {slide} from 'svelte/transition'
export let expanded = false; export let expanded = false;
export let name; export let name;
@ -10,6 +11,22 @@
} }
</script> </script>
<span class:expanded on:click={toggle}>{name}</span>
{#if expanded}
<ul transition:slide={{duration:300}}>
{#each files as file}
<li>
{#if file.type === 'folder'}
<svelte:self {...file}/>
{:else}
<File {...file}/>
{/if}
</li>
{/each}
</ul>
{/if}
<style> <style>
span { span {
padding: 0 0 0 1.5em; padding: 0 0 0 1.5em;
@ -34,19 +51,3 @@
padding: 0.2em 0; padding: 0.2em 0;
} }
</style> </style>
<span class:expanded on:click={toggle}>{name}</span>
{#if expanded}
<ul>
{#each files as file}
<li>
{#if file.type === 'folder'}
<svelte:self {...file}/>
{:else}
<File {...file}/>
{/if}
</li>
{/each}
</ul>
{/if}

@ -1,5 +1,7 @@
<strong>Blue thing</strong>
<style> <style>
strong { color: blue; } strong {
color: blue;
}
</style> </style>
<strong>blue thing</strong>

@ -1,5 +1,7 @@
<strong>Green thing</strong>
<style> <style>
strong { color: green; } strong {
color: green;
}
</style> </style>
<strong>green thing</strong>

@ -1,5 +1,7 @@
<strong>Red thing</strong>
<style> <style>
strong { color: red; } strong {
color: red;
}
</style> </style>
<strong>red thing</strong>

@ -8,6 +8,17 @@
} }
</script> </script>
<svelte:window on:keydown={handleKeydown}/>
<div style="text-align: center">
{#if key}
<kbd>{key === ' ' ? 'Space' : key}</kbd>
<p>{keyCode}</p>
{:else}
<p>Focus this window and press any key</p>
{/if}
</div>
<style> <style>
div { div {
display: flex; display: flex;
@ -29,14 +40,3 @@
color: #555; color: #555;
} }
</style> </style>
<svelte:window on:keydown={handleKeydown}/>
<div style="text-align: center">
{#if key}
<kbd>{key === ' ' ? 'Space' : key}</kbd>
<p>{keyCode}</p>
{:else}
<p>Focus this window and press any key</p>
{/if}
</div>

@ -5,6 +5,18 @@
const handleMouseleave = () => hereKitty = false; const handleMouseleave = () => hereKitty = false;
</script> </script>
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
/>
<!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 -->
<img
class:curious={hereKitty}
alt="Kitten wants to know what's going on"
src="tutorial/kitten.png"
>
<style> <style>
img { img {
position: absolute; position: absolute;
@ -23,15 +35,3 @@
overflow: hidden; overflow: hidden;
} }
</style> </style>
<svelte:body
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
/>
<!-- creative commons BY-NC http://www.pngall.com/kitten-png/download/7247 -->
<img
class:curious={hereKitty}
alt="Kitten wants to know what's going on"
src="tutorial/kitten.png"
>

@ -31,13 +31,6 @@
} }
</script> </script>
<style>
article { margin: 0 0 1em 0; max-width: 800px }
h2, p { margin: 0 0 0.3em 0; }
audio { width: 100%; margin: 0.5em 0 1em 0; }
.playing { color: #ff3e00; }
</style>
<article class:playing={!paused}> <article class:playing={!paused}>
<h2>{title}</h2> <h2>{title}</h2>
<p><strong>{composer}</strong> / performed by {performer}</p> <p><strong>{composer}</strong> / performed by {performer}</p>
@ -50,3 +43,10 @@
{src} {src}
></audio> ></audio>
</article> </article>
<style>
article { margin: 0 0 1em 0; max-width: 800px }
h2, p { margin: 0 0 0.3em 0; }
audio { width: 100%; margin: 0.5em 0 1em 0; }
.playing { color: #ff3e00; }
</style>

@ -1,13 +1,3 @@
<!-- https://eugenkiss.github.io/7guis/tasks/#temp -->
<input value={c} on:input="{e => setBothFromC(e.target.value)}" type=number> °c =
<input value={f} on:input="{e => setBothFromF(e.target.value)}" type=number> °f
<style>
input {
width: 5em;
}
</style>
<script> <script>
let c = 0; let c = 0;
let f = 32; let f = 32;
@ -22,3 +12,13 @@
c =+(5 / 9 * (f - 32)).toFixed(1); c =+(5 / 9 * (f - 32)).toFixed(1);
} }
</script> </script>
<!-- https://eugenkiss.github.io/7guis/tasks/#temp -->
<input value={c} on:input="{e => setBothFromC(e.target.value)}" type=number> °c =
<input value={f} on:input="{e => setBothFromF(e.target.value)}" type=number> °f
<style>
input {
width: 5em;
}
</style>

@ -37,14 +37,6 @@
} }
</script> </script>
<style>
select, input, button {
display: block;
margin: 0.5em 0;
font-size: inherit;
}
</style>
<select bind:value={isReturn}> <select bind:value={isReturn}>
<option value={false}>one-way flight</option> <option value={false}>one-way flight</option>
<option value={true}>return flight</option> <option value={true}>return flight</option>
@ -57,3 +49,11 @@
on:click={bookFlight} on:click={bookFlight}
disabled="{isReturn && (startDate >= endDate)}" disabled="{isReturn && (startDate >= endDate)}"
>book</button> >book</button>
<style>
select, input, button {
display: block;
margin: 0.5em 0;
font-size: inherit;
}
</style>

@ -50,6 +50,23 @@
} }
</script> </script>
<input placeholder="filter prefix" bind:value={prefix}>
<select bind:value={i} size={5}>
{#each filteredPeople as person, i}
<option value={i}>{person.last}, {person.first}</option>
{/each}
</select>
<label><input bind:value={first} placeholder="first"></label>
<label><input bind:value={last} placeholder="last"></label>
<div class='buttons'>
<button on:click={create} disabled="{!first || !last}">create</button>
<button on:click={update} disabled="{!first || !last || !selected}">update</button>
<button on:click={remove} disabled="{!selected}">delete</button>
</div>
<style> <style>
* { * {
font-family: inherit; font-family: inherit;
@ -71,20 +88,3 @@
clear: both; clear: both;
} }
</style> </style>
<input placeholder="filter prefix" bind:value={prefix}>
<select bind:value={i} size={5}>
{#each filteredPeople as person, i}
<option value={i}>{person.last}, {person.first}</option>
{/each}
</select>
<label><input bind:value={first} placeholder="first"></label>
<label><input bind:value={last} placeholder="last"></label>
<div class='buttons'>
<button on:click={create} disabled="{!first || !last}">create</button>
<button on:click={update} disabled="{!first || !last || !selected}">update</button>
<button on:click={remove} disabled="{!selected}">delete</button>
</div>

@ -65,6 +65,31 @@ radius of the selected circle.
} }
</script> </script>
<div class="controls">
<button on:click="{() => travel(-1)}" disabled="{i === 0}">undo</button>
<button on:click="{() => travel(+1)}" disabled="{i === undoStack.length -1}">redo</button>
</div>
<svg on:click={handleClick} >
{#each circles as circle}
<circle cx={circle.cx} cy={circle.cy} r={circle.r}
on:click="{event => select(circle, event)}"
on:contextmenu|stopPropagation|preventDefault="{() => {
adjusting = !adjusting;
if (adjusting) selected = circle;
}}"
fill="{circle === selected ? '#ccc': 'white'}"
/>
{/each}
</svg>
{#if adjusting}
<div class="adjuster">
<p>adjust diameter of circle at {selected.cx}, {selected.cy}</p>
<input type="range" value={selected.r} on:input={adjust}>
</div>
{/if}
<style> <style>
.controls { .controls {
position: absolute; position: absolute;
@ -98,28 +123,3 @@ radius of the selected circle.
width: 100%; width: 100%;
} }
</style> </style>
<div class="controls">
<button on:click="{() => travel(-1)}" disabled="{i === 0}">undo</button>
<button on:click="{() => travel(+1)}" disabled="{i === undoStack.length -1}">redo</button>
</div>
<svg on:click={handleClick} >
{#each circles as circle}
<circle cx={circle.cx} cy={circle.cy} r={circle.r}
on:click="{event => select(circle, event)}"
on:contextmenu|stopPropagation|preventDefault="{() => {
adjusting = !adjusting;
if (adjusting) selected = circle;
}}"
fill="{circle === selected ? '#ccc': 'white'}"
/>
{/each}
</svg>
{#if adjusting}
<div class="adjuster">
<p>adjust diameter of circle at {selected.cx}, {selected.cy}</p>
<input type="range" value={selected.r} on:input={adjust}>
</div>
{/if}

@ -26,6 +26,16 @@
onMount(hashchange); onMount(hashchange);
</script> </script>
<svelte:window on:hashchange={hashchange}/>
<main>
{#if item}
<Item {item} returnTo="#/top/{page}"/>
{:else if page}
<List {page}/>
{/if}
</main>
<style> <style>
main { main {
position: relative; position: relative;
@ -45,13 +55,3 @@
color: rgb(0,0,150); color: rgb(0,0,150);
} }
</style> </style>
<svelte:window on:hashchange={hashchange}/>
<main>
{#if item}
<Item {item} returnTo="#/top/{page}"/>
{:else if page}
<List {page}/>
{/if}
</main>

@ -2,6 +2,18 @@
export let comment; export let comment;
</script> </script>
<article>
<p class="meta">{comment.user} {comment.time_ago}</p>
{@html comment.content}
<div class="replies">
{#each comment.comments as child}
<svelte:self comment={child}/>
{/each}
</div>
</article>
<style> <style>
article { article {
border-top: 1px solid #eee; border-top: 1px solid #eee;
@ -18,15 +30,3 @@
padding: 0 0 0 1em; padding: 0 0 0 1em;
} }
</style> </style>
<article>
<p class="meta">{comment.user} {comment.time_ago}</p>
{@html comment.content}
<div class="replies">
{#each comment.comments as child}
<svelte:self comment={child}/>
{/each}
</div>
</article>

@ -7,22 +7,6 @@
$: url = !item.domain ? `https://news.ycombinator.com/${item.url}` : item.url; $: url = !item.domain ? `https://news.ycombinator.com/${item.url}` : item.url;
</script> </script>
<style>
article {
margin: 0 0 1em 0;
}
a {
display: block;
margin: 0 0 1em 0;
}
h1 {
font-size: 1.4em;
margin: 0;
}
</style>
<a href={returnTo}>&laquo; back</a> <a href={returnTo}>&laquo; back</a>
<article> <article>
@ -41,3 +25,19 @@
<Comment {comment}/> <Comment {comment}/>
{/each} {/each}
</div> </div>
<style>
article {
margin: 0 0 1em 0;
}
a {
display: block;
margin: 0 0 1em 0;
}
h1 {
font-size: 1.4em;
margin: 0;
}
</style>

@ -18,6 +18,16 @@
}); });
</script> </script>
{#if items}
{#each items as item, i}
<Summary {item} {i} {offset}/>
{/each}
<a href="#/top/{page + 1}">page {page + 1}</a>
{:else}
<p class="loading">loading...</p>
{/if}
<style> <style>
a { a {
padding: 2em; padding: 2em;
@ -34,13 +44,3 @@
to { opacity: 1; } to { opacity: 1; }
} }
</style> </style>
{#if items}
{#each items as item, i}
<Summary {item} {i} {offset}/>
{/each}
<a href="#/top/{page + 1}">page {page + 1}</a>
{:else}
<p class="loading">loading...</p>
{/if}

@ -11,6 +11,12 @@
$: url = item.type === "ask" ? `https://news.ycombinator.com/${item.url}` : item.url; $: url = item.type === "ask" ? `https://news.ycombinator.com/${item.url}` : item.url;
</script> </script>
<article>
<span>{i + offset + 1}</span>
<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>
<style> <style>
article { article {
position: relative; position: relative;
@ -32,9 +38,3 @@
color: #333; color: #333;
} }
</style> </style>
<article>
<span>{i + offset + 1}</span>
<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>

@ -1,5 +1,3 @@
<svelte:options immutable/>
<script> <script>
import ImmutableTodo from './ImmutableTodo.svelte'; import ImmutableTodo from './ImmutableTodo.svelte';
import MutableTodo from './MutableTodo.svelte'; import MutableTodo from './MutableTodo.svelte';

@ -5,7 +5,6 @@
import flash from './flash.js'; import flash from './flash.js';
export let todo; export let todo;
export let toggle;
let div; let div;
@ -14,15 +13,15 @@
}); });
</script> </script>
<!-- the text will flash red whenever
the `todo` object changes -->
<div bind:this={div} on:click>
{todo.done ? '👍': ''} {todo.text}
</div>
<style> <style>
div { div {
cursor: pointer; cursor: pointer;
line-height: 1.5; line-height: 1.5;
} }
</style> </style>
<!-- the text will flash red whenever
the `todo` object changes -->
<div bind:this={div} on:click>
{todo.done ? '👍': ''} {todo.text}
</div>

@ -3,7 +3,6 @@
import flash from './flash.js'; import flash from './flash.js';
export let todo; export let todo;
export let toggle;
let div; let div;
@ -12,15 +11,15 @@
}); });
</script> </script>
<!-- the text will flash red whenever
the `todo` object changes -->
<div bind:this={div} on:click>
{todo.done ? '👍': ''} {todo.text}
</div>
<style> <style>
div { div {
cursor: pointer; cursor: pointer;
line-height: 1.5; line-height: 1.5;
} }
</style> </style>
<!-- the text will flash red whenever
the `todo` object changes -->
<div bind:this={div} on:click>
{todo.done ? '👍': ''} {todo.text}
</div>

@ -1,4 +1,4 @@
import emotion from 'emotion/dist/emotion.umd.min.js'; import emotion from '@emotion/css@11.1.3/dist/emotion-css.umd.min.js';
const { css } = emotion; const { css } = emotion;

@ -0,0 +1,5 @@
---
question: Is there a tool to automatically format my .svelte files?
---
You can use prettier with the [prettier-plugin-svelte](https://www.npmjs.com/package/prettier-plugin-svelte) plugin.

@ -1,5 +1,5 @@
<p>This is a paragraph.</p>
<style> <style>
/* styles go here */ /* Write your CSS here */
</style> </style>
<p>This is a paragraph.</p>

@ -1,3 +1,5 @@
<p>This is a paragraph.</p>
<style> <style>
p { p {
color: purple; color: purple;
@ -5,5 +7,3 @@
font-size: 2em; font-size: 2em;
} }
</style> </style>
<p>This is a paragraph.</p>

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

Loading…
Cancel
Save