mirror of https://github.com/sveltejs/svelte
commit
4f9b4d8ee6
@ -0,0 +1,87 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: March 2022"
|
||||||
|
description: "Svelte Summit Spring is coming... and page endpoints are here!"
|
||||||
|
author: Daniel Sandoval
|
||||||
|
authorURL: https://desandoval.net
|
||||||
|
---
|
||||||
|
|
||||||
|
Just announced: [Svelte Summit Spring](https://www.sveltesummit.com/) will be taking place on April 30, 2022. The 5th Virtual Svelte Conference is [looking for speakers](https://www.sveltesummit.com/#speakers) and [sponsors](https://www.sveltesummit.com/sponsors)... so it's time to dust off those proposals!
|
||||||
|
|
||||||
|
Also, some long-requested features were added to SvelteKit this month... including page endpoints! This change in how the `load` function works makes it easier to fetch data required for basic pages, redirect from POST responses and handle 404s and other errors.
|
||||||
|
|
||||||
|
More on that and other new features and fixes below!
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- The docs are now searchable and multipage with type definitions and hoverable code examples - Check them out at [kit.svelte.dev/docs](https://kit.svelte.dev/docs/)
|
||||||
|
- Page endpoints significantly decrease the boilerplate needed when loading a page ([Issue](https://github.com/sveltejs/kit/issues/3532), [PR](https://github.com/sveltejs/kit/pull/3679), [Docs](https://kit.svelte.dev/docs/routing#endpoints-page-endpoints))
|
||||||
|
- Application versioning and update detection support lets you determine what to do when a route fails to load after an app update ([Issue](https://github.com/sveltejs/kit/issues/87), [PR](https://github.com/sveltejs/kit/pull/3412), [Docs](https://kit.svelte.dev/docs/configuration#version))
|
||||||
|
- A new option in `npm init svelte@next` will now set up Playwright automatically for testing ([PR](https://github.com/sveltejs/kit/pull/4056))
|
||||||
|
|
||||||
|
|
||||||
|
**Breaking Changes**
|
||||||
|
- The `target` option is no longer available. Instead, the `init` script hydrates its `parentNode` ([#3674](https://github.com/sveltejs/kit/pull/3674))
|
||||||
|
- App-level types now live in the `App` namespace which allows you to type global types like `Stuff` or `Session` ([#3670](https://github.com/sveltejs/kit/pull/3670))
|
||||||
|
- `JSONString` is now `JSONValue` ([#3683](https://github.com/sveltejs/kit/pull/3683))
|
||||||
|
- `createIndexFiles` has been removed — it is now controlled by the `trailingSlash` option ([#3801](https://github.com/sveltejs/kit/pull/3801))
|
||||||
|
- SvelteKit will no longer exclude root-relative external links from prerendering, which will cause 404s if these URLs are intended to be served by a separate app. Use a custom [`prerender.onError`](https://kit.svelte.dev/docs/configuration#prerender) handler if you need to ignore them ([#3826](https://github.com/sveltejs/kit/pull/3826))
|
||||||
|
|
||||||
|
|
||||||
|
## New in Language Tools
|
||||||
|
- Accessing properties in markups has been improved in the Svelte language tools ([105.12.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.12.0)) - working around some known issues with autocomplete ([#538](https://github.com/sveltejs/language-tools/issues/538) / [#1302](https://github.com/sveltejs/language-tools/issues/1302))
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites**
|
||||||
|
- [SvelteStorm](https://github.com/open-source-labs/SvelteStorm) is specifically tailored to provide all of the essential tools a Svelte developer needs to build a Svelte application
|
||||||
|
- [Supachat](https://github.com/Lleweraf/supachat) is a real-time chat app using Svelte and Supabase
|
||||||
|
- [Radicle](https://radicle.xyz/) is a peer-to-peer stack for building software together
|
||||||
|
- [The Making Known](https://the-making-known.com/) is a narrated encounter with posters designed by the Nazi German government to communicate with the occupied nations of Belgium, France, and Luxembourg during the Second World War
|
||||||
|
- [Svelte Kanban](https://github.com/V-Py/svelte-kanban) is a simple Svelte Kanban made in pure CSS
|
||||||
|
- [fngrng](https://github.com/nvlgzr/fngrng) is a typing trainer focussed on accuracy over speed
|
||||||
|
- [Generative grids](https://svelte.dev/repl/873988ce33db43f097c0ca69df57b3ac?version=3.46.4) is a neat little generative SVG grid in a Svelte REPL, with randomly generated color palettes and shapes
|
||||||
|
- [LifeHash](https://github.com/BlockchainCommons/lifehash.info) is a method of hash visualization that creates beautiful, deterministic icons
|
||||||
|
- [TypedWebhook.tools](https://typedwebhook.tools/) is a webhook testing tool for checking payloads, with automatic type generation
|
||||||
|
- [Speedskating](https://github.com/spiegelgraphics/speedskating) is an animation widget to show olympic speedskating runs. Built with Svelte, D3 and regl
|
||||||
|
- [Web tail](https://github.com/mishankov/web-tail) is a web application to view lines from file on local system or on remote server
|
||||||
|
|
||||||
|
Want to work on a SvelteKit site with others? [Contribute to the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Svelte Components as Web Components](https://medium.com/@yesmeno/svelte-components-as-web-components-b400d1253504) by Matias Meno
|
||||||
|
- [Simple Svelte Routing with Reactive URLs](https://bjornlu.com/blog/simple-svelte-routing-with-reactive-urls) by Bjorn Lu
|
||||||
|
- [Leveling Up my Sveltekit / Sanity.io Blog Content with Featured Videos and Syntax Highlighting](https://ryanboddy.net/level-up-blog) by Ryan Boddy
|
||||||
|
- [How This Blog Makes the Most of GitHub](https://paullj.github.io/posts/how-this-blog-makes-the-most-of-github/) by paullj
|
||||||
|
- [FullStack JWT Auth: Introducing SvelteKit](https://dev.to/sirneij/fullstack-jwt-introducing-sveltekit-3jcn) by John Idogun
|
||||||
|
- [Svelte-Cubed: Adding Motion to 3D Scenes](https://dev.to/alexwarnes/svelte-cubed-adding-motion-to-3d-scenes-51lo) by Alex Warnes
|
||||||
|
- [Creating a RSS feed with Sanity and Svelte Kit](https://ghostdev.xyz/posts/creating-a-rss-feed-with-sanity-and-svelte-kit) by GHOST
|
||||||
|
- [How to use Svelte's style directive](https://geoffrich.net/posts/style-directives/) by Geoff Rich
|
||||||
|
- [SvelteKit and the "Client pattern"](https://retro.cloud/sveltekit-and-the-client-pattern/) by Julian Laubstein
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [~~Shadow~~ Page Endpoints In Svelte Kit - Weekly Svelte](https://www.youtube.com/watch?v=PoYPZT7ruqI) by LevelUpTuts
|
||||||
|
- [Testing For Beginners (Playlist)](https://www.youtube.com/watch?v=y53wwdBr5AI&list=PLA9WiRZ-IS_z7KpqhPELfEMbhAGRwZrzn) by Joy of Code
|
||||||
|
- [KitQL - The native SvelteKit library for GraphQL](https://www.youtube.com/watch?v=6pH4fnFN70w) by Jean-Yves COUËT
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [gosvelte](https://github.com/sachinbhutani/gosvelte) is a proof of concept to serve Svelte-generated pages on GoLang HTTP server with server data being sent as props to svelte components
|
||||||
|
- [svelte-ethers-store](https://www.npmjs.com/package/svelte-ethers-store) uses the ethers.js library as a collection of readable Svelte stores for Svelte, Sapper or SvelteKit
|
||||||
|
- [Fluid Grid](https://fluid-grid.com/) is a CSS grid system for future web
|
||||||
|
- [stirstack](https://github.com/seeReadCode/stirstack) is an opinionated framework that combines Svelte.js, TailwindCSS, InertiaJS and Ruby on Rails
|
||||||
|
- [OATHqr](https://codeberg.org/vhs/oathqr) helps users create security credentials for use with 2FA/MFA and other OATH-enabled apps. Use it to generate scannable QR codes for one-time password authenticator apps such as Aegis or YubiKey
|
||||||
|
- [svelte-GridTiles](https://github.com/honeybeeSunshine/svelte-GridTiles) is a drag and drop resizable tiles library built on a responsive grid
|
||||||
|
- [Miscellaneous Svelte Components](https://github.com/alex-knyaz/Miscellaneous-svelte-components/) is a collection of miscellaneous svelte components alex-knyaz often use in my projects
|
||||||
|
- [walk-and-graph-svelte-components](https://github.com/j2l/walk-and-graph-svelte-components) is a CLI node script to walk svelte and js files, to draw a beautiful JPG of your dependencies aka "imports"
|
||||||
|
- [Felte](https://www.npmjs.com/package/felte) is a simple to use form library for Svelte
|
||||||
|
- [svelte-use-tooltip](https://github.com/untemps/svelte-use-tooltip) is a Svelte action to display a tooltip
|
||||||
|
- [persistent-svelte-store](https://github.com/omer-g/persistent-svelte-store) is a generic persistent writable store, built from scratch in TypeScript according to the Svelte store contract
|
||||||
|
|
||||||
|
What'd we miss? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to continue the conversation.
|
||||||
|
|
||||||
|
See y'all next month!
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
title: "What's new in Svelte: April 2022"
|
||||||
|
description: "Goodbye fallthrough routes, hello param validators!"
|
||||||
|
author: Daniel Sandoval
|
||||||
|
authorURL: https://desandoval.net
|
||||||
|
---
|
||||||
|
|
||||||
|
This month, we felt a shift in the way SvelteKit handles page properties. The last holdout of the use-cases that required fallthrough routes, validating parameter properties, has been replaced by a more specific solution.
|
||||||
|
|
||||||
|
More on that, and what else is new in Svelte, as we dive in...
|
||||||
|
|
||||||
|
## What's new in SvelteKit
|
||||||
|
- Param matchers allow you to check if a url parameter matches before rendering a page - replacing the need for fallthrough routes for this purpose ([Docs](https://kit.svelte.dev/docs/routing#advanced-routing-matching), [#4334](https://github.com/sveltejs/kit/pull/4334))
|
||||||
|
- Explicit redirects can now be handled directly from endpoints ([#4260](https://github.com/sveltejs/kit/pull/4260))
|
||||||
|
- `svelte-kit sync` ([#4182](https://github.com/sveltejs/kit/pull/4182)), TypeScript 4.6 ([#4190](https://github.com/sveltejs/kit/pull/4190)) and Vite 2.9 were released - adding non-blocking dependency optimization and experimental CSS source maps in dev mode as well as a number of bug fixes contributed by the SvelteKit team ([#4468](https://github.com/sveltejs/kit/pull/4468))
|
||||||
|
|
||||||
|
|
||||||
|
**New Config Options**
|
||||||
|
- `outDir` fixes path issues in monorepos and other situations where the desired output directory is outside the project directory ([Docs](https://kit.svelte.dev/docs/configuration#outdir), [#4176](https://github.com/sveltejs/kit/pull/4176))
|
||||||
|
- `endpointExtensions` prevents files other than .js and .ts files from being treated as endpoints, unless you specify endpointExtensions ([Docs](https://kit.svelte.dev/docs/configuration#endpointextensions), [#4197](https://github.com/sveltejs/kit/pull/4197))
|
||||||
|
- `prerender.default` lets you prerender every page without having to write `export const prerender = true` in every page file ([Docs](https://kit.svelte.dev/docs/configuration#prerender), [#4192](https://github.com/sveltejs/kit/pull/4192))
|
||||||
|
|
||||||
|
|
||||||
|
**Breaking Changes**
|
||||||
|
- Fallthrough routes have been removed. For migration tips, check out the PR ([#4330](https://github.com/sveltejs/kit/pull/4330))
|
||||||
|
- `tabindex="-1"` is only added to `<body>` during navigation ([#4140](https://github.com/sveltejs/kit/pull/4140) and [#4184](https://github.com/sveltejs/kit/pull/4184))
|
||||||
|
- Adapters are now required to supply a `getClientAddress` function ([#4289](https://github.com/sveltejs/kit/pull/4289))
|
||||||
|
- `InputProps` and `OutputProps` can now be typed separately in generated `Load` ([#4305](https://github.com/sveltejs/kit/pull/4305))
|
||||||
|
- The `\$` character is no longer allowed in dynamic parameters ([#4334](https://github.com/sveltejs/kit/pull/4334))
|
||||||
|
- `svelte-kit package` has been marked as experimental so changes to it after Kit 1.0 will not be considered breaking ([#4164](https://github.com/sveltejs/kit/pull/4164))
|
||||||
|
|
||||||
|
|
||||||
|
## New across the Svelte ecosystem
|
||||||
|
- Svelte: Lots of new types for TypeScript and Svelte plugin users - including `style:` directives and Svelte Actions (**3.46.4** and **3.46.5**)
|
||||||
|
- Language Tools: Svelte project files are now importable/findable through references without having them imported in a TS file ([105.13.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.13.0))
|
||||||
|
- Language Tools: Region folding is now supported in html with `<!--#region-->`/`<!--#endregion-->` ([105.13.0](https://github.com/sveltejs/language-tools/releases/tag/extensions-105.13.0))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community Showcase
|
||||||
|
|
||||||
|
**Apps & Sites built with Svelte**
|
||||||
|
- [Launcher](https://launcher.team/) is an open-source app launcher powered by SvelteKit, Prisma, and Tailwind
|
||||||
|
- [Paaster](https://paaster.io/) is a secure by default end to end encrypted pastebin built with Svelte, Vite, Typescript, Python, Starlette, rclone & Docker.
|
||||||
|
- [Simple AF Video Converter](https://github.com/berlyozzy/Simple-AF-Video-Converter) is an Electron wrapper around ffmpeg.wasm to make converting videos between formats easier
|
||||||
|
- [Streamchaser](https://github.com/streamchaser/streamchaser) seeks to simplify movie, series and documentary search through a centralized entertainment technology platform
|
||||||
|
- [Svelte Color Picker](https://github.com/V-Py/svelte-material-color-picker) is a simple color picker made with Svelte
|
||||||
|
- [ConcertMash](https://github.com/mcmxcdev/ConcertMash) is a small website that interacts with the Spotify API and generates new playlists based on the upcoming concerts you're attending
|
||||||
|
- [Modulus](https://modulus.vision/) is a Design+Code Think Tank conceived with the main mission to evolve design and technology
|
||||||
|
- [Multiply](https://www.multiply.us/) is an integrated PR and Social agency moving at the speed of culture
|
||||||
|
- [yia!](https://www.yia.co.nz/) is a Young Innovator Award competition in New Zealand
|
||||||
|
- [Write to Russia](https://www.writetorussia.org/index) is a community email writing platform to communicate with public `.ru` email addresses
|
||||||
|
- [Markdown Playground](https://github.com/Petros-K/markdown-playground) is an online playground dedicated for your markdown experiments.
|
||||||
|
- [RatherMisty](https://rathermisty.com/) is a no frills weather app with weather data from Open-Meteo
|
||||||
|
- [Minecraft Profile Pic (MCPFP)](https://github.com/MauritsWilke/mcpfp) is a site to generate Minecraft profile pictures with ease
|
||||||
|
- [WebGL Fluid Simulation](https://github.com/jpaquim/svelte-webgl-fluid-simulation) is a configurable fluid simulation built with Svelte and WebGL
|
||||||
|
- [This @NobelPeaceOslo exhibition](https://twitter.com/perbyhring/status/1504754949791621120) was built using printed graphics, projected motion graphics, particle animations and generative sound design
|
||||||
|
|
||||||
|
Itching to contribute to a modern SvelteKit website? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||||
|
|
||||||
|
|
||||||
|
**Learning Resources**
|
||||||
|
|
||||||
|
_To Attend_
|
||||||
|
- [Svelte Summit: Spring](https://www.sveltesummit.com/) will take place on April 30, 2022! Join us for the 5th virtual Svelte conference on [YouTube](https://www.sveltesummit.com/) and Discord 🍾
|
||||||
|
|
||||||
|
_To Read_
|
||||||
|
- [Svelte(Kit) TypeScript Showcase + general TypeScript tips](https://github.com/ivanhofer/sveltekit-typescript-showcase) by Hofer Ivan
|
||||||
|
- [Local constants in Svelte with the @const tag](https://geoffrich.net/posts/local-constants/) by Geoff Rich
|
||||||
|
- [Design Patterns for Building Reusable Svelte Components](https://render.com/blog/svelte-design-patterns) by Eric Liu
|
||||||
|
- [Svelte is better than React](https://labs.hamy.xyz/posts/svelte-is-better-than-react/) by Hamilton Greene
|
||||||
|
- [Making Visualizations Literally with Svelte and D3](https://www.connorrothschild.com/post/svelte-and-d3) by Connor Rothschild
|
||||||
|
- [Coordinating Multiple Elements with Svelte Deferred Transitions](https://imfeld.dev/writing/svelte_deferred_transitions) by Daniel Imfeld
|
||||||
|
- [Animate on scroll with Svelte Inview - Little Bits](https://dev.to/maciekgrzybek/animate-on-scroll-with-svelte-inview-266f) by Maciek Grzybek
|
||||||
|
- [Lazy-Loading Firebase with SvelteKit](https://www.captaincodeman.com/lazy-loading-firebase-with-sveltekit) and [HeadlessUI Components with Svelte](https://www.captaincodeman.com/headlessui-components-with-svelte) by Captain Codeman
|
||||||
|
- [SvelteKit Accessibility Testing: Automated CI A11y Tests](https://rodneylab.com/sveltekit-accessibility-testing/) by Rodney Lab
|
||||||
|
- [Getting Started with KitQL and GraphCMS](https://scottspence.com/posts/getting-started-with-kitql-and-graphcms) by Scott Spence
|
||||||
|
- [React ⇆ Svelte Cheatsheet](https://dev.to/joshnuss/react-to-svelte-cheatsheet-1a2a) lists the similarities and differences between the two libraries - by Joshua Nussbaum
|
||||||
|
|
||||||
|
_To Watch_
|
||||||
|
- [Svelte Extravaganza | Async](https://www.youtube.com/watch?v=mT4CLVHgtSg) by pngwn
|
||||||
|
- [6 Svelte Packages You Should Know](https://www.youtube.com/watch?v=y5SrUKcX_Co) and [Basic React To Svelte Conversion](https://www.youtube.com/watch?v=DiSuwLlhOxs) by LevelUpTuts
|
||||||
|
- [Page/Shadow Endpoint in SvelteKit](https://www.youtube.com/watch?v=j-9D5UDyVOM) by WebJeda
|
||||||
|
- [Custom Svelte Store: Higher Order Store](https://www.youtube.com/watch?v=p1aPfVyZ1IY) by lihautan
|
||||||
|
- [SvelteKit For Beginners (Playlist)](https://www.youtube.com/watch?v=bLBHecY4-ak&list=PLA9WiRZ-IS_zXZZyW4qfj0akvOAtk6MFS) by Joy of Code - follow along with the [blog guide](https://joyofcode.xyz/sveltekit-for-beginners)
|
||||||
|
- [Fullstack SvelteKit Auth 🔐 with Firebase & Magic Links! 🪄](https://www.youtube.com/watch?v=MAHE4iQgh5Q) by Johnny Magrippis
|
||||||
|
- [Firebase Authentication in SvelteKit! Full Stack App](https://www.youtube.com/watch?v=N6Y3hqhZvNI) by Ryan Boddy
|
||||||
|
|
||||||
|
|
||||||
|
**Libraries, Tools & Components**
|
||||||
|
- [SvelTable](https://sveltable.io/) is a feature rich, data table component built with Svelte
|
||||||
|
- [svelte-cyberComp](https://github.com/Cybersteam00/svelte-cyberComp) is a powerful, lightweight component library written in Svelte and Typescript
|
||||||
|
- [Flowbite Svelte](https://github.com/shinokada/flowbite-svelte) is an unofficial Flowbite component library for Svelte
|
||||||
|
- [Svelte-Tide-Project](https://github.com/jbertovic/svelte-tide-project) is a starter template for Svelte frontend apps with Rust Tide backend server
|
||||||
|
- [Fetch Inject](https://github.com/vhscom/fetch-inject#sveltekit) implements a performance optimization technique for managing asynchronous JavaScript dependencies - now with Svelte support
|
||||||
|
- [svelte-utterances](https://github.com/shinokada/svelte-utterances) is a lightweight comments widget built on GitHub issues
|
||||||
|
- [Liquivelte](https://github.com/malipetek/liquivelte-vscode) allows you to create your Shopify theme with Svelte-like components
|
||||||
|
- [@storyblok/svelte](https://github.com/storyblok/storyblok-svelte) is the Svelte SDK you need to interact with Storyblok API and enable the Real-time Visual Editing Experience
|
||||||
|
- [@svelte-on-solana/wallet-adapter](https://github.com/svelte-on-solana/wallet-adapter) is a modular TypeScript wallet adapter and UI components for Solana/Anchor applications using SvelteJS as framework
|
||||||
|
- [svelte-lookat](https://www.npmjs.com/package/svelte-lookat) creates a div which makes all its children follow the mouse cursor or the user's face when using a mobile phone
|
||||||
|
|
||||||
|
Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to continue the conversation.
|
||||||
|
|
||||||
|
See y'all next month!
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
const options = ['h1', 'h3', 'p'];
|
||||||
|
let selected = options[0];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value={selected}>
|
||||||
|
{#each options as option}
|
||||||
|
<option value={option}>{option}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"title": "<svelte:element>"
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<script>
|
||||||
|
const options = ['h1', 'h3', 'p'];
|
||||||
|
let selected = options[0];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value={selected}>
|
||||||
|
{#each options as option}
|
||||||
|
<option value={option}>{option}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
{#if selected === 'h1'}
|
||||||
|
<h1>I'm a h1 tag</h1>
|
||||||
|
{:else if selected === 'h3'}
|
||||||
|
<h3>I'm a h3 tag</h3>
|
||||||
|
{:else if selected === 'p'}
|
||||||
|
<p>I'm a p tag</p>
|
||||||
|
{/if}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<script>
|
||||||
|
const options = ['h1', 'h3', 'p'];
|
||||||
|
let selected = options[0];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value={selected}>
|
||||||
|
{#each options as option}
|
||||||
|
<option value={option}>{option}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
title: <svelte:element>
|
||||||
|
---
|
||||||
|
|
||||||
|
Sometimes we don't know in advance what kind of DOM element to render. `<svelte:element>` comes in handy here. Instead of a sequence of `if` blocks...
|
||||||
|
|
||||||
|
```html
|
||||||
|
{#if selected === 'h1'}
|
||||||
|
<h1>I'm a h1 tag</h1>
|
||||||
|
{:else if selected === 'h3'}
|
||||||
|
<h3>I'm a h3 tag</h3>
|
||||||
|
{:else if selected === 'p'}
|
||||||
|
<p>I'm a p tag</p>
|
||||||
|
{/if}
|
||||||
|
```
|
||||||
|
|
||||||
|
...we can have a single dynamic component:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<svelte:element this={selected}>I'm a {selected} tag</svelte:element>
|
||||||
|
```
|
||||||
|
|
||||||
|
The `this` value can be any string, or a falsy value — if it's falsy, no element is rendered.
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Actions can return an object containing the two properties defined in this interface. Both are optional.
|
||||||
|
* - update: An action can have a parameter. This method will be called whenever that parameter changes,
|
||||||
|
* immediately after Svelte has applied updates to the markup.
|
||||||
|
* - destroy: Method that is called after the element is unmounted
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* export function myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter> {
|
||||||
|
* // ...
|
||||||
|
* return {
|
||||||
|
* update: (updatedParameter) => {...},
|
||||||
|
* destroy: () => {...}
|
||||||
|
* };
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Docs: https://svelte.dev/docs#template-syntax-element-directives-use-action
|
||||||
|
*/
|
||||||
|
export interface ActionReturn<Parameter = any> {
|
||||||
|
update?: (parameter: Parameter) => void;
|
||||||
|
destroy?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions are functions that are called when an element is created.
|
||||||
|
* You can use this interface to type such actions.
|
||||||
|
* The following example defines an action that only works on `<div>` elements
|
||||||
|
* and optionally accepts a parameter which it has a default value for:
|
||||||
|
* ```ts
|
||||||
|
* export const myAction: Action<HTMLDivElement, { someProperty: boolean }> = (node, param = { someProperty: true }) => {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* You can return an object with methods `update` and `destroy` from the function.
|
||||||
|
* See interface `ActionReturn` for more details.
|
||||||
|
*
|
||||||
|
* Docs: https://svelte.dev/docs#template-syntax-element-directives-use-action
|
||||||
|
*/
|
||||||
|
export interface Action<Element = HTMLElement, Parameter = any> {
|
||||||
|
<Node extends Element>(node: Node, parameter?: Parameter): void | ActionReturn<Parameter>;
|
||||||
|
}
|
||||||
@ -1 +1 @@
|
|||||||
:root{--root-test:20}div.svelte-xyz{--test:10}
|
:root{--root-test:20}div.svelte-xyz{--test:10}div.svelte-xyz{--foo: ;--bar: !important}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
export default {
|
||||||
|
warnings: [
|
||||||
|
{
|
||||||
|
code: 'css-unused-selector',
|
||||||
|
end: {
|
||||||
|
character: 86,
|
||||||
|
column: 8,
|
||||||
|
line: 7
|
||||||
|
},
|
||||||
|
frame:
|
||||||
|
' 5: color: red;\n 6: }\n 7: .unused {\n ^\n 8: font-style: italic;\n 9: }',
|
||||||
|
message: 'Unused CSS selector ".unused"',
|
||||||
|
pos: 79,
|
||||||
|
start: {
|
||||||
|
character: 79,
|
||||||
|
column: 1,
|
||||||
|
line: 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@ -0,0 +1 @@
|
|||||||
|
.used.svelte-xyz{color:red}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<div class="used svelte-xyz"></div>
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<svelte:element this="div" class="used" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.used {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
.unused {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
<svelte:element this="div"></svelte:element>
|
||||||
|
<svelte:element this="div" class="foo"></svelte:element>
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"html": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 101,
|
||||||
|
"type": "Fragment",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"end": 44,
|
||||||
|
"type": "Element",
|
||||||
|
"name": "svelte:element",
|
||||||
|
"attributes": [],
|
||||||
|
"children": [],
|
||||||
|
"tag": "div"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"start": 44,
|
||||||
|
"end": 45,
|
||||||
|
"data": "\n",
|
||||||
|
"raw": "\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"start": 45,
|
||||||
|
"end": 101,
|
||||||
|
"type": "Element",
|
||||||
|
"name": "svelte:element",
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"type": "Attribute",
|
||||||
|
"start": 72,
|
||||||
|
"end": 83,
|
||||||
|
"name": "class",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"start": 79,
|
||||||
|
"end": 82,
|
||||||
|
"data": "foo",
|
||||||
|
"raw": "foo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [],
|
||||||
|
"tag": "div"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
<svelte:element this={tag}></svelte:element>
|
||||||
|
<svelte:element this={tag} class="foo"></svelte:element>
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"html": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 101,
|
||||||
|
"type": "Fragment",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"end": 44,
|
||||||
|
"type": "Element",
|
||||||
|
"name": "svelte:element",
|
||||||
|
"attributes": [],
|
||||||
|
"children": [],
|
||||||
|
"tag": {
|
||||||
|
"start": 22,
|
||||||
|
"end": 25,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 22
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "tag",
|
||||||
|
"type": "Identifier"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"start": 44,
|
||||||
|
"end": 45,
|
||||||
|
"data": "\n",
|
||||||
|
"raw": "\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"start": 45,
|
||||||
|
"end": 101,
|
||||||
|
"type": "Element",
|
||||||
|
"name": "svelte:element",
|
||||||
|
"children": [],
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"type": "Attribute",
|
||||||
|
"start": 72,
|
||||||
|
"end": 83,
|
||||||
|
"name": "class",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"start": 79,
|
||||||
|
"end": 82,
|
||||||
|
"data": "foo",
|
||||||
|
"raw": "foo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tag": {
|
||||||
|
"start": 67,
|
||||||
|
"end": 70,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 2,
|
||||||
|
"column": 22
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 2,
|
||||||
|
"column": 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "tag",
|
||||||
|
"type": "Identifier"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
<slot name="box1" />
|
||||||
|
<slot />
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
export default {
|
||||||
|
html: `
|
||||||
|
<div>static dynamic</div>
|
||||||
|
<div>static dynamic</div>
|
||||||
|
<div>static dynamic</div>
|
||||||
|
`,
|
||||||
|
async test({ component, target, assert }) {
|
||||||
|
component.props = 'xxx';
|
||||||
|
assert.htmlEqual(target.innerHTML, `
|
||||||
|
<div>static xxx</div>
|
||||||
|
<div>static xxx</div>
|
||||||
|
<div>static xxx</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
<script>
|
||||||
|
import Component from './Component.svelte';
|
||||||
|
export let props = "dynamic";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Component>
|
||||||
|
<svelte:fragment slot="box1">
|
||||||
|
{@const foo = "static"}
|
||||||
|
{@const bar = props}
|
||||||
|
<div>{foo} {bar}</div>
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
<svelte:fragment>
|
||||||
|
{@const foo = "static"}
|
||||||
|
{@const bar = props}
|
||||||
|
<div>{foo} {bar}</div>
|
||||||
|
</svelte:fragment>
|
||||||
|
</Component>
|
||||||
|
|
||||||
|
<Component>
|
||||||
|
{@const foo = "static"}
|
||||||
|
{@const bar = props}
|
||||||
|
<div>{foo} {bar}</div>
|
||||||
|
</Component>
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
export default {
|
||||||
|
html: `
|
||||||
|
<p>0</p>
|
||||||
|
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||||
|
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||||
|
`,
|
||||||
|
async test({ component, target, assert }) {
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>0</p>
|
||||||
|
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
|
||||||
|
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
component.nums = [1, 2, 3];
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>0</p>
|
||||||
|
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
|
||||||
|
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
|
||||||
|
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
<script>
|
||||||
|
export let nums = [1, 2];
|
||||||
|
let foos = [
|
||||||
|
{
|
||||||
|
nums: [1, 2, 3],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nums: [0, 2, 4],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nums: [-100, 0, 100],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
let foo = 0;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{foo}</p>
|
||||||
|
{#each nums as num, index}
|
||||||
|
{@const bar = nums.map((num) => {
|
||||||
|
const func = (foos, num) => {
|
||||||
|
return [...foos.map((foo) => foo), num];
|
||||||
|
}
|
||||||
|
return func(foos[index].nums, num);
|
||||||
|
})}
|
||||||
|
<p>bar: {bar}, num: {num}</p>
|
||||||
|
{/each}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
export default {
|
||||||
|
html: `
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
|
||||||
|
`,
|
||||||
|
async test({ component, target, assert }) {
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
component.nums = [1, 2, 3, 4];
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
|
||||||
|
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 4</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
<script>
|
||||||
|
export let nums = [1, 2, 3];
|
||||||
|
let foos = [
|
||||||
|
{
|
||||||
|
nums: [1, 2, 3],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nums: [0, 2, 4],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nums: [-100, 0, 100],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each nums as num}
|
||||||
|
{@const bar = foos.map((foos) => foos.nums)}
|
||||||
|
<p>bar: {bar}, num: {num}</p>
|
||||||
|
{/each}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue