Merge branch 'master' into pr/5836

pull/5836/head
Conduitry 5 years ago
commit 6a21f2af92

@ -1,5 +1,10 @@
# Svelte changelog
## Unreleased
* Fix checkbox `bind:group` in nested `{#each}` contexts ([#5811](https://github.com/sveltejs/svelte/issues/5811))
* Add graphics roles as known ARIA roles ([#5822](https://github.com/sveltejs/svelte/pull/5822))
## 3.31.0
* Use a separate `SvelteComponentTyped` interface for typed components ([#5738](https://github.com/sveltejs/svelte/pull/5738))

@ -1,4 +1,4 @@
Copyright (c) 2016-20 [these people](https://github.com/sveltejs/svelte/graphs/contributors)
Copyright (c) 2016-21 [these people](https://github.com/sveltejs/svelte/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

@ -14,5 +14,4 @@ environment:
install:
- ps: Install-Product node $env:nodejs_version
- npm install cypress
- npm install

@ -0,0 +1,86 @@
---
title: What's new in Svelte: January 2021
description: A Svelte-packed showcase to kick-off the new year!
author: Daniel Sandoval
authorURL: https://desandoval.net
---
Happy new year from Svelte! In the last month we made progress on Sapper's upcoming release, fine-tuned our `SvelteComponent` typings, and have seen some amazing apps, sites, and libraries coming out in the showcase.
## What's changed in Svelte?
A new minor release replaces the `SvelteComponent` class with a `SvelteComponentTyped` class. This renaming should help with backwards compatibility. We've updated [last month's blog post](https://svelte.dev/blog/whats-new-in-svelte-december-2020) to avoid any confusion with the name change.
If you're using `SvelteComponent` or the new `SvelteComponentTyped` in your project or library, let us know what you're using it for and we'll add it to the showcase!
## What's going on in Sapper?
More quality of life features are landing in the upcoming release every day. `0.29.0` will include new TypeScript definitions, fixes to scroll tracking and prefetching behavior, and improvements to the runtime router to support encoded query parameters.
If you're upgrading from 0.28.x, check out [the migration guide](https://sapper.svelte.dev/migrating/#0_28_to_0_29) for steps on updating to Sapper 0.29.
## Is SvelteKit ready yet?
To avoid too much churn during development, SvelteKit is still being worked on in a private repo. There will be an announcement on the Discord, blog and Twitter when it's ready for a larger group of users and contributors.
In the meantime, you can explore the current build by running `npm init svelte@next` from your command line.
As cautioned in _[What's the deal with SvelteKit?](https://svelte.dev/blog/whats-the-deal-with-sveltekit)_, there are no docs or support available yet... So use at your own risk / for your own enjoyment!
---
## Community Showcase
**Apps & Sites**
- [manitu.me](https://manitu.me/) is a background sound / pomodoro timer for focus and relaxation
- [Answer Socrates](https://answersocrates.com/) helps you find trending questions on the internet so that you can write the most relevant blog post, tweet, or billboard
- [multris](https://multris.s1h.org/) is a multiplayer Tetris game. You can read about its development [here](https://blog.s1h.org/svelte-multiplayer-game/)
- [weather-ab](https://github.com/ganochenkodg/weather-ab) compares the archive of weather in different cities of the world. Indispensable for people thinking about migration
- [Game Nibs](https://gamenibs.com/) is a platform for gamers to find and share concise bite-sized bits of gaming advice, tips, tricks, screenshots, builds, and much more
- [Ora](https://github.com/cupcakearmy/ora) is an open source website tracking and limiting tool for Chrome and Firefox
- [vscode-dms](https://github.com/techsyndicate/vscode-dms) is a group direct messaging chat app for VSCode
- [Zero.2](https://zero.oleksandrdemian.tech/) is a math-based challenge game where you try to get to zero as quickly as possible
- [Octave Compass](https://octavecompass.com/2741) is a chord table and scale explorer for many popular musical scales
- [Infinite Walking Bass Generator 2](https://github.com/elialbert/infinitewalkingbass2) is an online music player that generates a unique walking bass line
- [ListenAddict](https://www.listenaddict.com/) is a site that notifies you whenever a person has a new talk/interview on podcast
**Demos, Libraries & Components**
- [svelte-tiny-virtual-list](https://github.com/Skayo/svelte-tiny-virtual-list) speeds up long lists by only rendering visible items
- [svelte-query](https://github.com/TanStack/svelte-query) is a collection of helpful hooks for managing, caching and syncing asynchronous and remote data
- [svelte-previous](https://github.com/bryanmylee/svelte-previous) is a svelte store to remember previous values - helpful for transitions or a quick undo stack
- [Let's Build a Confetti Cannon](https://varun.ca/confetti/) explains how to build a particle system and integrate a Canvas based animation into a larger application
- [svelte-micro](https://github.com/ayndqy/svelte-micro) is a one-component router
- [svelte-standalone-router](https://github.com/hjalmar/svelte-standalone-router) is a standalone router with an API based on [standalone-router](https://github.com/hjalmar/standalone-router)
- [svelte-datepicker](https://github.com/beyonk-adventures/svelte-datepicker) is a datepicker component with variations for time selection, date ranges and responsive themes
- [svelte-slimscroll](https://github.com/MelihAltintas/svelte-slimscroll) is a action for Svelte.js, which can transforms any div into a scrollable area with a nice scrollbar.
- [Svelte Zoomable](https://svelte.dev/repl/58dfe87756ee4db897c281b52fdef7b7?version=3.31.0) is a custom transition with a nice zoom effect
**Have a component you'd like to share?** Check out the [Components](https://sveltesociety.dev/components) page on the Svelte Society site. You can contribute by making [a PR to this file](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/pages/components/components.json).
**Learning Resources**
- [Using Svelte to create a scroll video effect](https://blog.koenvangilst.nl/tutorial-svelte-scroll-video/) showcases how the `bind` command can be used to create a cool scroll video effect with very little code
- [How to make a flappybird game in svelte and typescript](https://www.youtube.com/watch?v=nhrYBoVI8pQ) is a video tutorial including docs and code for reference
- [Accessible Svelte Transition](https://www.youtube.com/watch?v=QK_QuRL7nSo&feature=youtu.be) walks through `prefers-reduced-motion` to make svelte transitions more accessible
- [Svelte's module scripts explained](https://codechips.me/svelte-module-scripts-explained/) is a great introduction to the module context, a common Sapper pattern
- [Awesome Svelte](https://github.com/TheComputerM/awesome-svelte#readme) is a curated list of Svelte resources
- [.NET Core and Svelte](https://dev.to/cainux/net-core-and-svelte-f8o) explains how to get Svelte up and running with .NET Core
- [A la découverte de Svelte JS](https://www.youtube.com/watch?v=SLpx1Y8e1ek&list=PLff5I1miao9ZEUhpqkrOx7k8RGAZt-nm9) is a svelte tutorial series in French!
- [Svelte for React Developers](https://soshace.com/svelte-for-react-developers/) explains Svelte's core concepts to folks who are used to React
- [Building a Svelte Static Website with Smooth Page Transitions](https://www.youtube.com/watch?v=dvPfmcGtmrI&feature=emb_title) shows how to build a static website with Svelte and add smooth page transitions using Three.js and GSAP.
- [Using Apollo Client in Sapper](https://bjornlu.com/blog/using-apollo-client-in-sapper/) explains the "simplest" solutions to integrate the Apollo query client into Sapper
- [Reactive web apps with Crystal + Svelte](https://www.youtube.com/watch?v=i1xjLd6z7BU) explores how to build full-stack, server-rendered Svelte apps with a [Crystal](https://crystal-lang.org) backend
**Related Projects**
- [Snowpack's v3 release candidate](https://www.snowpack.dev/posts/2020-12-03-snowpack-3-release-candidate) is out now in preparation for a January 6 release date. Check out the [Getting Started with Svelte](https://www.snowpack.dev/tutorials/svelte) for more info on how to use Snowpack.
- [Uppy](https://uppy.io/blog/2020/12/1.24/), the open source file uploader, announced Svelte support in its new version 1.24
## See you next month!
Want to add your work to the Showcase? Want to contribute to Svelte? Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!

@ -1,4 +0,0 @@
{
"baseUrl": "http://localhost:3000",
"video": false
}

3138
site/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -36,9 +36,9 @@
"@babel/preset-env": "^7.6.0",
"@babel/runtime": "^7.6.0",
"@rollup/plugin-babel": "^5.0.0",
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-node-resolve": "^11.0.0",
"@rollup/plugin-replace": "^2.2.0",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.2.5",
@ -51,10 +51,10 @@
"node-fetch": "^2.6.1",
"node-pg-migrate": "^3.22.0",
"npm-run-all": "^4.1.5",
"rollup": "^2.26.10",
"rollup-plugin-svelte": "^6.0.0",
"rollup": "^2.30.0",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"sapper": "^0.27.16",
"sapper": "^0.28.10",
"shelljs": "^0.8.3",
"svelte": "^3.12.0"
},

@ -31,9 +31,10 @@ export default {
'process.env.MAPBOX_ACCESS_TOKEN': JSON.stringify(process.env.MAPBOX_ACCESS_TOKEN)
}),
svelte({
dev,
hydratable: true,
emitCss: true
compilerOptions: {
dev,
hydratable: true
}
}),
resolve({
browser: true,
@ -77,8 +78,12 @@ export default {
'process.env.NODE_ENV': JSON.stringify(mode)
}),
svelte({
generate: 'ssr',
dev
compilerOptions: {
dev,
generate: 'ssr',
hydratable: true
},
emitCss: false
}),
resolve({
dedupe

@ -23,7 +23,7 @@ const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateM
const aria_attributes = 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext'.split(' ');
const aria_attribute_set = new Set(aria_attributes);
const aria_roles = 'alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form generic grid gridcell group heading img link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem'.split(' ');
const aria_roles = 'alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form generic graphics-document graphics-object graphics-symbol grid gridcell group heading img link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem'.split(' ');
const aria_role_set = new Set(aria_roles);
const a11y_required_attributes = {

@ -39,6 +39,7 @@ export default class Block {
dependencies: Set<string> = new Set();
bindings: Map<string, Bindings>;
binding_group_initialised: Set<string> = new Set();
chunks: {
declarations: Array<Node | Node[]>;

@ -32,7 +32,7 @@ export default class Renderer {
blocks: Array<Block | Node | Node[]> = [];
readonly: Set<string> = new Set();
meta_bindings: Array<Node | Node[]> = []; // initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag
binding_groups: Map<string, { binding_group: (to_reference?: boolean) => Node; is_context: boolean; contexts: string[]; index: number }> = new Map();
binding_groups: Map<string, { binding_group: (to_reference?: boolean) => Node; is_context: boolean; contexts: string[]; index: number; keypath: string }> = new Map();
block: Block;
fragment: FragmentWrapper;

@ -116,11 +116,11 @@ export default class BindingWrapper {
switch (this.node.name) {
case 'group':
{
const { binding_group, is_context, contexts, index } = get_binding_group(parent.renderer, this.node, block);
const { binding_group, is_context, contexts, index, keypath } = get_binding_group(parent.renderer, this.node, block);
block.renderer.add_to_context('$$binding_groups');
if (is_context) {
if (is_context && !block.binding_group_initialised.has(keypath)) {
if (contexts.length > 1) {
let binding_group = x`${block.renderer.reference('$$binding_groups')}[${index}]`;
for (const name of contexts.slice(0, -1)) {
@ -133,6 +133,7 @@ export default class BindingWrapper {
block.chunks.init.push(
b`${binding_group(true)} = [];`
);
block.binding_group_initialised.add(keypath);
}
block.chunks.hydrate.push(
@ -257,8 +258,22 @@ function get_binding_group(renderer: Renderer, value: Binding, block: Block) {
let keypath = parts.join('.');
const contexts = [];
const contextual_dependencies = new Set<string>();
const { template_scope } = value.expression;
const add_contextual_dependency = (dep: string) => {
contextual_dependencies.add(dep);
const owner = template_scope.get_owner(dep);
if (owner.type === 'EachBlock') {
for (const dep of owner.expression.contextual_dependencies) {
add_contextual_dependency(dep);
}
}
};
for (const dep of value.expression.contextual_dependencies) {
add_contextual_dependency(dep);
}
for (const dep of contextual_dependencies) {
const context = block.bindings.get(dep);
let key;
let name;
@ -302,7 +317,8 @@ function get_binding_group(renderer: Renderer, value: Binding, block: Block) {
},
is_context: contexts.length > 0,
contexts,
index
index,
keypath
});
}

@ -17,10 +17,18 @@ export default function mark_each_block_bindings(
});
if (binding.name === 'group') {
const add_index_binding = (name: string) => {
const each_block = parent.node.scope.get_owner(name);
if (each_block.type === 'EachBlock') {
each_block.has_index_binding = true;
for (const dep of each_block.expression.contextual_dependencies) {
add_index_binding(dep);
}
}
};
// for `<input bind:group={} >`, we make sure that all the each blocks creates context with `index`
for (const name of binding.expression.contextual_dependencies) {
const each_block = parent.node.scope.get_owner(name);
(each_block as EachBlock).has_index_binding = true;
add_index_binding(name);
}
}
}

@ -0,0 +1,53 @@
export default {
html: `
<input type="checkbox" value="a" data-index="x-1">
<input type="checkbox" value="b" data-index="x-1">
<input type="checkbox" value="c" data-index="x-1">
<input type="checkbox" value="a" data-index="x-2">
<input type="checkbox" value="b" data-index="x-2">
<input type="checkbox" value="c" data-index="x-2">
<input type="checkbox" value="a" data-index="y-1">
<input type="checkbox" value="b" data-index="y-1">
<input type="checkbox" value="c" data-index="y-1">
<input type="checkbox" value="a" data-index="y-2">
<input type="checkbox" value="b" data-index="y-2">
<input type="checkbox" value="c" data-index="y-2">
<input type="checkbox" value="a" data-index="z-1">
<input type="checkbox" value="b" data-index="z-1">
<input type="checkbox" value="c" data-index="z-1">
<input type="checkbox" value="a" data-index="z-2">
<input type="checkbox" value="b" data-index="z-2">
<input type="checkbox" value="c" data-index="z-2">
`,
async test({ assert, component, target, window }) {
const inputs = target.querySelectorAll('input');
const checked = new Set();
const checkInbox = async (i) => {
checked.add(i);
inputs[i].checked = true;
await inputs[i].dispatchEvent(event);
};
for (let i = 0; i < 18; i++) {
assert.equal(inputs[i].checked, checked.has(i));
}
const event = new window.Event('change');
await checkInbox(2);
for (let i = 0; i < 18; i++) {
assert.equal(inputs[i].checked, checked.has(i));
}
await checkInbox(12);
for (let i = 0; i < 18; i++) {
assert.equal(inputs[i].checked, checked.has(i));
}
await checkInbox(8);
for (let i = 0; i < 18; i++) {
assert.equal(inputs[i].checked, checked.has(i));
}
}
};

@ -0,0 +1,15 @@
<script>
const list = [
{ id: 'x', data: [{ id: 1, data: [] }, { id: 2, data: [] }] },
{ id: 'y', data: [{ id: 1, data: [] }, { id: 2, data: [] }] },
{ id: 'z', data: [{ id: 1, data: [] }, { id: 2, data: [] }] }
];
</script>
{#each list as { id, data }}
{#each data as item}
<input type="checkbox" bind:group={item.data} value="a" data-index="{id}-{item.id}" />
<input type="checkbox" bind:group={item.data} value="b" data-index="{id}-{item.id}" />
<input type="checkbox" bind:group={item.data} value="c" data-index="{id}-{item.id}" />
{/each}
{/each}
Loading…
Cancel
Save