mirror of https://github.com/sveltejs/svelte
More docs stuff (#13769)
* fix * link * more docs stuff * more * more * fix * more * more * fix * fix * more * ffs * FMLtransition-out-effect-tracking
parent
4c7cfff434
commit
4f6bb41030
@ -1,103 +0,0 @@
|
||||
---
|
||||
title: use:
|
||||
---
|
||||
|
||||
- template syntax
|
||||
- how to write
|
||||
- typings
|
||||
- adjust so that `$effect` is used instead of update/destroy?
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
use:action
|
||||
```
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
use:action={parameters}
|
||||
```
|
||||
|
||||
```ts
|
||||
/// copy: false
|
||||
// @noErrors
|
||||
action = (node: HTMLElement, parameters: any) => {
|
||||
update?: (parameters: any) => void,
|
||||
destroy?: () => void
|
||||
}
|
||||
```
|
||||
|
||||
Actions are functions that are called when an element is created. They can return an object with a `destroy` method that is called after the element is unmounted:
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
/** @type {import('svelte/action').Action} */
|
||||
function foo(node) {
|
||||
// the node has been mounted in the DOM
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
// the node has been removed from the DOM
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:foo />
|
||||
```
|
||||
|
||||
An action can have a parameter. If the returned value has an `update` method, it will be called immediately after Svelte has applied updates to the markup whenever that parameter changes.
|
||||
|
||||
> [!NOTE] Don't worry that we're redeclaring the `foo` function for every component instance — Svelte will hoist any functions that don't depend on local state out of the component definition.
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
/** @type {string} */
|
||||
export let bar;
|
||||
|
||||
/** @type {import('svelte/action').Action<HTMLElement, string>} */
|
||||
function foo(node, bar) {
|
||||
// the node has been mounted in the DOM
|
||||
|
||||
return {
|
||||
update(bar) {
|
||||
// the value of `bar` has changed
|
||||
},
|
||||
|
||||
destroy() {
|
||||
// the node has been removed from the DOM
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:foo={bar} />
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
Sometimes actions emit custom events and apply custom attributes to the element they are applied to. To support this, actions typed with `Action` or `ActionReturn` type can have a last parameter, `Attributes`:
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
/**
|
||||
* @type {import('svelte/action').Action<HTMLDivElement, { prop: any }, { 'on:emit': (e: CustomEvent<string>) => void }>}
|
||||
*/
|
||||
function foo(node, { prop }) {
|
||||
// the node has been mounted in the DOM
|
||||
|
||||
//...LOGIC
|
||||
node.dispatchEvent(new CustomEvent('emit', { detail: 'hello' }));
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
// the node has been removed from the DOM
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:foo={{ prop: 'someValue' }} onemit={handleEmit} />
|
||||
```
|
@ -0,0 +1,81 @@
|
||||
---
|
||||
title: use:
|
||||
---
|
||||
|
||||
Actions are functions that are called when an element is mounted. They are added with the `use:` directive, and will typically use an `$effect` so that they can reset any state when the element is unmounted:
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
/** @type {import('svelte/action').Action} */
|
||||
function myaction(node) {
|
||||
// the node has been mounted in the DOM
|
||||
|
||||
$effect(() => {
|
||||
// setup goes here
|
||||
|
||||
return () => {
|
||||
// teardown goes here
|
||||
};
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:myaction>...</div>
|
||||
```
|
||||
|
||||
An action can be called with an argument:
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
/** @type {import('svelte/action').Action} */
|
||||
function myaction(node, +++data+++) {
|
||||
// ...
|
||||
}
|
||||
</script>
|
||||
|
||||
<div use:myaction={+++data+++}>...</div>
|
||||
```
|
||||
|
||||
The action is only called once (but not during server-side rendering) — it will _not_ run again if the argument changes.
|
||||
|
||||
> [!LEGACY]
|
||||
> Prior to the `$effect` rune, actions could return an object with `update` and `destroy` methods, where `update` would be called with the latest value of the argument if it changed. Using effects is preferred.
|
||||
|
||||
## Typing
|
||||
|
||||
The `Action` interface receives three optional type arguments — a node type (which can be `Element`, if the action applies to everything), a parameter, and any custom event handlers created by the action.:
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
import { on } from 'svelte/events';
|
||||
|
||||
/**
|
||||
* @type {import('svelte/action').Action<
|
||||
* HTMLDivElement,
|
||||
* null,
|
||||
* {
|
||||
* onswiperight: (e: CustomEvent) => void;
|
||||
* onswipeleft: (e: CustomEvent) => void;
|
||||
* // ...
|
||||
* }>}
|
||||
*/
|
||||
function gestures(node) {
|
||||
$effect(() => {
|
||||
// ...
|
||||
node.dispatchEvent(new CustomEvent('swipeleft'));
|
||||
|
||||
// ...
|
||||
node.dispatchEvent(new CustomEvent('swiperight'));
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
use:gestures
|
||||
onswipeleft={next}
|
||||
onswiperight={prev}
|
||||
>...</div>
|
||||
```
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
title: in: and out:
|
||||
---
|
||||
|
||||
Coming soon!
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
title: animate:
|
||||
---
|
||||
|
||||
Coming soon!
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
title: in: and out:
|
||||
---
|
||||
|
||||
The `in:` and `out:` directives are identical to [`transition:`](transition), except that the resulting transitions are not bidirectional — an `in` transition will continue to 'play' alongside the `out` transition, rather than reversing, if the block is outroed while the transition is in progress. If an out transition is aborted, transitions will restart from scratch.
|
||||
|
||||
```svelte
|
||||
{#if visible}
|
||||
<div in:fly out:fade>flies in, fades out</div>
|
||||
{/if}
|
||||
```
|
@ -0,0 +1,118 @@
|
||||
---
|
||||
title: animate:
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
An animation is triggered when the contents of a [keyed each block](each#Keyed-each-blocks) are re-ordered. Animations do not run when an element is added or removed, only when the index of an existing data item within the each block changes. Animate directives must be on an element that is an _immediate_ child of a keyed each block.
|
||||
|
||||
Animations can be used with Svelte's [built-in animation functions](svelte-animate) or [custom animation functions](#Custom-animation-functions).
|
||||
|
||||
```svelte
|
||||
<!-- When `list` is reordered the animation will run-->
|
||||
{#each list as item, index (item)}
|
||||
<li animate:flip>{item}</li>
|
||||
{/each}
|
||||
```
|
||||
|
||||
## Animation Parameters
|
||||
|
||||
As with actions and transitions, animations can have parameters.
|
||||
|
||||
(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)
|
||||
|
||||
```svelte
|
||||
{#each list as item, index (item)}
|
||||
<li animate:flip={{ delay: 500 }}>{item}</li>
|
||||
{/each}
|
||||
```
|
||||
|
||||
## Custom animation functions
|
||||
|
||||
```js
|
||||
/// copy: false
|
||||
// @noErrors
|
||||
animation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => {
|
||||
delay?: number,
|
||||
duration?: number,
|
||||
easing?: (t: number) => number,
|
||||
css?: (t: number, u: number) => string,
|
||||
tick?: (t: number, u: number) => void
|
||||
}
|
||||
```
|
||||
|
||||
Animations can use custom functions that provide the `node`, an `animation` object and any `parameters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, and the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.
|
||||
|
||||
If the returned object has a `css` method, Svelte will create a [web animation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API) that plays on the element.
|
||||
|
||||
The `t` argument passed to `css` is a value that goes from `0` and `1` after the `easing` function has been applied. The `u` argument is equal to `1 - t`.
|
||||
|
||||
The function is called repeatedly _before_ the animation begins, with different `t` and `u` arguments.
|
||||
|
||||
<!-- TODO: Types -->
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
import { cubicOut } from 'svelte/easing';
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} node
|
||||
* @param {{ from: DOMRect; to: DOMRect }} states
|
||||
* @param {any} params
|
||||
*/
|
||||
function whizz(node, { from, to }, params) {
|
||||
const dx = from.left - to.left;
|
||||
const dy = from.top - to.top;
|
||||
|
||||
const d = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
return {
|
||||
delay: 0,
|
||||
duration: Math.sqrt(d) * 120,
|
||||
easing: cubicOut,
|
||||
css: (t, u) => `transform: translate(${u * dx}px, ${u * dy}px) rotate(${t * 360}deg);`
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each list as item, index (item)}
|
||||
<div animate:whizz>{item}</div>
|
||||
{/each}
|
||||
```
|
||||
|
||||
A custom animation function can also return a `tick` function, which is called _during_ the animation with the same `t` and `u` arguments.
|
||||
|
||||
> [!NOTE] If it's possible to use `css` instead of `tick`, do so — web animations can run off the main thread, preventing jank on slower devices.
|
||||
|
||||
```svelte
|
||||
<!--- file: App.svelte --->
|
||||
<script>
|
||||
import { cubicOut } from 'svelte/easing';
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} node
|
||||
* @param {{ from: DOMRect; to: DOMRect }} states
|
||||
* @param {any} params
|
||||
*/
|
||||
function whizz(node, { from, to }, params) {
|
||||
const dx = from.left - to.left;
|
||||
const dy = from.top - to.top;
|
||||
|
||||
const d = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
return {
|
||||
delay: 0,
|
||||
duration: Math.sqrt(d) * 120,
|
||||
easing: cubicOut,
|
||||
tick: (t, u) => Object.assign(node.style, { color: t > 0.5 ? 'Pink' : 'Blue' })
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each list as item, index (item)}
|
||||
<div animate:whizz>{item}</div>
|
||||
{/each}
|
||||
```
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
title: class: and style:
|
||||
---
|
||||
|
||||
Coming soon!
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: class:
|
||||
---
|
||||
|
||||
The `class:` directive is a convenient way to conditionally set classes on elements, as an alternative to using conditional expressions inside `class` attributes:
|
||||
|
||||
```svelte
|
||||
<!-- These are equivalent -->
|
||||
<div class={isCool ? 'cool' : ''}>...</div>
|
||||
<div class:cool={isCool}>...</div>
|
||||
```
|
||||
|
||||
As with other directives, we can use a shorthand when the name of the class coincides with the value:
|
||||
|
||||
```svelte
|
||||
<div class:cool>...</div>
|
||||
```
|
||||
|
||||
Multiple `class:` directives can be added to a single element:
|
||||
|
||||
```svelte
|
||||
<div class:cool class:lame={!cool} class:potato>...</div>
|
||||
```
|
@ -0,0 +1,41 @@
|
||||
---
|
||||
title: style:
|
||||
---
|
||||
|
||||
The `style:` directive provides a shorthand for setting multiple styles on an element.
|
||||
|
||||
```svelte
|
||||
<!-- These are equivalent -->
|
||||
<div style:color="red">...</div>
|
||||
<div style="color: red;">...</div>
|
||||
```
|
||||
|
||||
The value can contain arbitrary expressions:
|
||||
|
||||
```svelte
|
||||
<div style:color={myColor}>...</div>
|
||||
```
|
||||
|
||||
The shorthand form is allowed:
|
||||
|
||||
```svelte
|
||||
<div style:color>...</div>
|
||||
```
|
||||
|
||||
Multiple styles can be set on a single element:
|
||||
|
||||
```svelte
|
||||
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'}>...</div>
|
||||
```
|
||||
|
||||
To mark a style as important, use the `|important` modifier:
|
||||
|
||||
```svelte
|
||||
<div style:color|important="red">...</div>
|
||||
```
|
||||
|
||||
When `style:` directives are combined with `style` attributes, the directives will take precedence:
|
||||
|
||||
```svelte
|
||||
<div style="color: blue;" style:color="red">This will be red</div>
|
||||
```
|
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Scoped styles
|
||||
---
|
||||
|
||||
Svelte components can include a `<style>` element containing CSS that belongs to the component. This CSS is _scoped_ by default, meaning that styles will not apply to any elements on the page outside the component in question.
|
||||
|
||||
This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
p {
|
||||
/* this will only affect <p> elements in this component */
|
||||
color: burlywood;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Specificity
|
||||
|
||||
Each scoped selector receives a [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) increase of 0-1-0, as a result of the scoping class (e.g. `.svelte-123xyz`) being added to the selector. This means that (for example) a `p` selector defined in a component will take precedence over a `p` selector defined in a global stylesheet, even if the global stylesheet is loaded later.
|
||||
|
||||
In some cases, the scoping class must be added to a selector multiple times, but after the first occurrence it is added with `:where(.svelte-xyz123)` in order to not increase specificity further.
|
||||
|
||||
## Scoped keyframes
|
||||
|
||||
If a component defines `@keyframes`, the name is scoped to the component using the same hashing approach. Any `animation` rules in the component will be similarly adjusted:
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
.bouncy {
|
||||
animation: bounce 10s;
|
||||
}
|
||||
|
||||
/* these keyframes are only accessible inside this component */
|
||||
@keyframes bounce {
|
||||
/* ... *.
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
|
||||
|
@ -1,235 +0,0 @@
|
||||
---
|
||||
title: Styles & Classes
|
||||
---
|
||||
|
||||
- style scoping
|
||||
- `:global`
|
||||
- `style:`
|
||||
- `class:`
|
||||
- `--css` props
|
||||
|
||||
Styling is a fundamental part of UI components. Svelte helps you style your components with ease, providing useful features out of the box.
|
||||
|
||||
## Scoped by default
|
||||
|
||||
By default CSS inside a `<style>` block will be scoped to that component.
|
||||
|
||||
This works by adding a class to affected elements, which is based on a hash of the component styles (e.g. `svelte-123xyz`).
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
p {
|
||||
/* this will only affect <p> elements in this component */
|
||||
color: burlywood;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## :global(...)
|
||||
|
||||
To apply styles to a single selector globally, use the `:global(...)` modifier:
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
:global(body) {
|
||||
/* applies to <body> */
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div :global(strong) {
|
||||
/* applies to all <strong> elements, in any component,
|
||||
that are inside <div> elements belonging
|
||||
to this component */
|
||||
color: goldenrod;
|
||||
}
|
||||
|
||||
p:global(.big.red) {
|
||||
/* applies to all <p> elements belonging to this component
|
||||
with `class="big red"`, even if it is applied
|
||||
programmatically (for example by a library) */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with `-global-`.
|
||||
|
||||
The `-global-` part will be removed when compiled, and the keyframe will then be referenced using just `my-animation-name` elsewhere in your code.
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
@keyframes -global-my-animation-name {
|
||||
/* code goes here */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## :global
|
||||
|
||||
To apply styles to a group of selectors globally, create a `:global {...}` block:
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
:global {
|
||||
/* applies to every <div> in your application */
|
||||
div { ... }
|
||||
|
||||
/* applies to every <p> in your application */
|
||||
p { ... }
|
||||
}
|
||||
|
||||
.a :global {
|
||||
/* applies to every `.b .c .d` element, in any component,
|
||||
that is inside an `.a` element in this component */
|
||||
.b .c .d {...}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
> [!NOTE] The second example above could also be written as an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped, though the nested form is preferred.
|
||||
|
||||
## Nested style tags
|
||||
|
||||
There should only be 1 top-level `<style>` tag per component.
|
||||
|
||||
However, it is possible to have a `<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.
|
||||
|
||||
```svelte
|
||||
<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>
|
||||
```
|
||||
|
||||
## class:_name_
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
class:name={value}
|
||||
```
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
class:name
|
||||
```
|
||||
|
||||
A `class:` directive provides a shorter way of toggling a class on an element.
|
||||
|
||||
```svelte
|
||||
<!-- These are equivalent -->
|
||||
<div class={isActive ? 'active' : ''}>...</div>
|
||||
<div class:active={isActive}>...</div>
|
||||
|
||||
<!-- Shorthand, for when name and value match -->
|
||||
<div class:active>...</div>
|
||||
|
||||
<!-- Multiple class toggles can be included -->
|
||||
<div class:active class:inactive={!active} class:isAdmin>...</div>
|
||||
```
|
||||
|
||||
## style:_property_
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
style:property={value}
|
||||
```
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
style:property="value"
|
||||
```
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
style:property
|
||||
```
|
||||
|
||||
The `style:` directive provides a shorthand for setting multiple styles on an element.
|
||||
|
||||
```svelte
|
||||
<!-- These are equivalent -->
|
||||
<div style:color="red">...</div>
|
||||
<div style="color: red;">...</div>
|
||||
|
||||
<!-- Variables can be used -->
|
||||
<div style:color={myColor}>...</div>
|
||||
|
||||
<!-- Shorthand, for when property and variable name match -->
|
||||
<div style:color>...</div>
|
||||
|
||||
<!-- Multiple styles can be included -->
|
||||
<div style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'}>...</div>
|
||||
|
||||
<!-- Styles can be marked as important -->
|
||||
<div style:color|important="red">...</div>
|
||||
```
|
||||
|
||||
When `style:` directives are combined with `style` attributes, the directives will take precedence:
|
||||
|
||||
```svelte
|
||||
<div style="color: blue;" style:color="red">This will be red</div>
|
||||
```
|
||||
|
||||
## --style-props
|
||||
|
||||
```svelte
|
||||
<!--- copy: false --->
|
||||
--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:
|
||||
|
||||
```svelte
|
||||
<Slider bind:value min={0} --rail-color="black" --track-color="rgb(0, 0, 255)" />
|
||||
```
|
||||
|
||||
Desugars to this:
|
||||
|
||||
```svelte
|
||||
<svelte-css-wrapper style="display: contents; --rail-color: black; --track-color: rgb(0, 0, 255)">
|
||||
<Slider bind:value min={0} max={100} />
|
||||
</svelte-css-wrapper>
|
||||
```
|
||||
|
||||
For SVG namespace, the example above desugars into using `<g>` instead:
|
||||
|
||||
```svelte
|
||||
<g style="--rail-color: black; --track-color: rgb(0, 0, 255)">
|
||||
<Slider bind:value min={0} max={100} />
|
||||
</g>
|
||||
```
|
||||
|
||||
> [!NOTE] Since this is an extra `<svelte-css-wrapper>` (or `<g>`), 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 themeable components:
|
||||
|
||||
```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:
|
||||
|
||||
```svelte
|
||||
<Slider --rail-color="goldenrod" />
|
||||
```
|
@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Global styles
|
||||
---
|
||||
|
||||
## :global(...)
|
||||
|
||||
To apply styles to a single selector globally, use the `:global(...)` modifier:
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
:global(body) {
|
||||
/* applies to <body> */
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div :global(strong) {
|
||||
/* applies to all <strong> elements, in any component,
|
||||
that are inside <div> elements belonging
|
||||
to this component */
|
||||
color: goldenrod;
|
||||
}
|
||||
|
||||
p:global(.big.red) {
|
||||
/* applies to all <p> elements belonging to this component
|
||||
with `class="big red"`, even if it is applied
|
||||
programmatically (for example by a library) */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
If you want to make @keyframes that are accessible globally, you need to prepend your keyframe names with `-global-`.
|
||||
|
||||
The `-global-` part will be removed when compiled, and the keyframe will then be referenced using just `my-animation-name` elsewhere in your code.
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
@keyframes -global-my-animation-name {
|
||||
/* code goes here */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## :global
|
||||
|
||||
To apply styles to a group of selectors globally, create a `:global {...}` block:
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
:global {
|
||||
/* applies to every <div> in your application */
|
||||
div { ... }
|
||||
|
||||
/* applies to every <p> in your application */
|
||||
p { ... }
|
||||
}
|
||||
|
||||
.a :global {
|
||||
/* applies to every `.b .c .d` element, in any component,
|
||||
that is inside an `.a` element in this component */
|
||||
.b .c .d {...}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
> [!NOTE] The second example above could also be written as an equivalent `.a :global .b .c .d` selector, where everything after the `:global` is unscoped, though the nested form is preferred.
|
@ -0,0 +1,57 @@
|
||||
---
|
||||
title: Custom properties
|
||||
---
|
||||
|
||||
You can pass CSS custom properties — both static and dynamic — to components:
|
||||
|
||||
```svelte
|
||||
<Slider
|
||||
bind:value
|
||||
min={0}
|
||||
max={100}
|
||||
--track-color="black"
|
||||
--thumb-color="rgb({r} {g} {b})"
|
||||
/>
|
||||
```
|
||||
|
||||
The above code essentially desugars to this:
|
||||
|
||||
```svelte
|
||||
<svelte-css-wrapper style="display: contents; --track-color: black; --thumb-color: rgb({r} {g} {b})">
|
||||
<Slider
|
||||
bind:value
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</svelte-css-wrapper>
|
||||
```
|
||||
|
||||
For an SVG element, it would use `<g>` instead:
|
||||
|
||||
```svelte
|
||||
<g style="--track-color: black; --thumb-color: rgb({r} {g} {b})">
|
||||
<Slider
|
||||
bind:value
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</g>
|
||||
```
|
||||
|
||||
Inside the component, we can read these custom properties (and provide fallback values) using [`var(...)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties):
|
||||
|
||||
```svelte
|
||||
<style>
|
||||
.track {
|
||||
background: var(--track-color, #aaa);
|
||||
}
|
||||
|
||||
.thumb {
|
||||
background: var(--thumb-color, blue);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
You don't _have_ to specify the values directly on the component; as long as the custom properties are defined on a parent element, the component can use them. It's common to define custom properties on the `:root` element in a global stylesheet so that they apply to your entire application.
|
||||
|
||||
> [!NOTE] While the extra element will not affect layout, it _will_ affect any CSS selectors that (for example) use the `>` combinator to target an element directly inside the component's container.
|
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Nested <style> elements
|
||||
---
|
||||
|
||||
There should only be 1 top-level `<style>` tag per component.
|
||||
|
||||
However, it is possible to have a `<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.
|
||||
|
||||
```svelte
|
||||
<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>
|
||||
```
|
@ -0,0 +1,44 @@
|
||||
---
|
||||
title: <svelte:window>
|
||||
---
|
||||
|
||||
```svelte
|
||||
<svelte:window onevent={handler} />
|
||||
```
|
||||
|
||||
```svelte
|
||||
<svelte:window bind:prop={value} />
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
This element may only appear at the top level of your component — it cannot be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
function handleKeydown(event) {
|
||||
alert(`pressed the ${event.key} key`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={handleKeydown} />
|
||||
```
|
||||
|
||||
You can also bind to the following properties:
|
||||
|
||||
- `innerWidth`
|
||||
- `innerHeight`
|
||||
- `outerWidth`
|
||||
- `outerHeight`
|
||||
- `scrollX`
|
||||
- `scrollY`
|
||||
- `online` — an alias for `window.navigator.onLine`
|
||||
- `devicePixelRatio`
|
||||
|
||||
All except `scrollX` and `scrollY` are readonly.
|
||||
|
||||
```svelte
|
||||
<svelte:window bind:scrollY={y} />
|
||||
```
|
||||
|
||||
> [!NOTE] Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. If you have a legitimate reason to scroll when the component is rendered, call `scrollTo()` in an `$effect`.
|
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: <svelte:document>
|
||||
---
|
||||
|
||||
```svelte
|
||||
<svelte:document onevent={handler} />
|
||||
```
|
||||
|
||||
```svelte
|
||||
<svelte:document bind:prop={value} />
|
||||
```
|
||||
|
||||
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](use) on `document`.
|
||||
|
||||
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<svelte:document onvisibilitychange={handleVisibilityChange} use:someAction />
|
||||
```
|
||||
|
||||
You can also bind to the following properties:
|
||||
|
||||
- `activeElement`
|
||||
- `fullscreenElement`
|
||||
- `pointerLockElement`
|
||||
- `visibilityState`
|
||||
|
||||
All are readonly.
|
@ -0,0 +1,15 @@
|
||||
---
|
||||
title: <svelte:body>
|
||||
---
|
||||
|
||||
```svelte
|
||||
<svelte:body onevent={handler} />
|
||||
```
|
||||
|
||||
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](use) on the `<body>` element.
|
||||
|
||||
As with `<svelte:window>` and `<svelte:document>`, this element may only appear the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave} use:someAction />
|
||||
```
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: <svelte:head>
|
||||
---
|
||||
|
||||
```svelte
|
||||
<svelte:head>...</svelte:head>
|
||||
```
|
||||
|
||||
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `body` content.
|
||||
|
||||
As with `<svelte:window>`, `<svelte:document>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<svelte:head>
|
||||
<title>Hello world!</title>
|
||||
<meta name="description" content="This is where the description goes for SEO" />
|
||||
</svelte:head>
|
||||
```
|
@ -0,0 +1,31 @@
|
||||
---
|
||||
title: <svelte:element>
|
||||
---
|
||||
|
||||
```svelte
|
||||
<svelte:element this={expression} />
|
||||
```
|
||||
|
||||
The `<svelte:element>` element lets you render an element that is unknown at author time, for example because it comes from a CMS. Any properties and event listeners present will be applied to the element.
|
||||
|
||||
The only supported binding is `bind:this`, since Svelte's built-in bindings do not work with generic elements.
|
||||
|
||||
If `this` has a nullish value, the element and its children will not be rendered.
|
||||
|
||||
If `this` is the name of a [void element](https://developer.mozilla.org/en-US/docs/Glossary/Void_element) (e.g., `br`) and `<svelte:element>` has child elements, a runtime error will be thrown in development mode:
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
let tag = $state('hr');
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag}>
|
||||
This text cannot appear inside an hr element
|
||||
</svelte:element>
|
||||
```
|
||||
|
||||
Svelte tries its best to infer the correct namespace from the element's surroundings, but it's not always possible. You can make it explicit with an `xmlns` attribute:
|
||||
|
||||
```svelte
|
||||
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" />
|
||||
```
|
@ -0,0 +1,22 @@
|
||||
---
|
||||
title: <svelte:options>
|
||||
---
|
||||
|
||||
```svelte
|
||||
<svelte:options option={value} />
|
||||
```
|
||||
|
||||
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](svelte-compiler#compile). The possible options are:
|
||||
|
||||
- `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
|
||||
- `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
|
||||
- `accessors={true}` — adds getters and setters for the component's props
|
||||
- `accessors={false}` — the default
|
||||
- `runes={true}` — forces a component into _runes mode_ (see the [Legacy APIs](legacy-overview) section)
|
||||
- `runes={false}` — forces a component into _legacy mode_
|
||||
- `namespace="..."` — the namespace where this component will be used, most commonly "svg"; use the "foreign" namespace to opt out of case-insensitive attribute names and HTML-specific warnings
|
||||
- `customElement={...}` — the [options](custom-elements#Component-options) to use when compiling this component as a custom element. If a string is passed, it is used as the `tag` option
|
||||
|
||||
```svelte
|
||||
<svelte:options customElement="my-custom-element" />
|
||||
```
|
@ -1,190 +0,0 @@
|
||||
---
|
||||
title: Special elements
|
||||
---
|
||||
|
||||
- [basically what we have in the docs today](https://svelte.dev/docs/special-elements)
|
||||
|
||||
Some of Svelte's concepts need special elements. Those are prefixed with `svelte:` and listed here.
|
||||
|
||||
## `<svelte:self>`
|
||||
|
||||
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 or passed to a component's slot to prevent an infinite loop.
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
let { count } = $props();
|
||||
</script>
|
||||
|
||||
{#if count > 0}
|
||||
<p>counting down... {count}</p>
|
||||
<svelte:self count={count - 1} />
|
||||
{:else}
|
||||
<p>lift-off!</p>
|
||||
{/if}
|
||||
```
|
||||
|
||||
## `<svelte:component>`
|
||||
|
||||
```svelte
|
||||
<svelte:component this={expression} />
|
||||
```
|
||||
|
||||
The `<svelte:component>` element renders a component dynamically, using the component constructor specified as the `this` property. When the property changes, the component is destroyed and recreated.
|
||||
|
||||
If `this` is falsy, no component is rendered.
|
||||
|
||||
```svelte
|
||||
<svelte:component this={currentSelection.component} foo={bar} />
|
||||
```
|
||||
|
||||
## `<svelte:element>`
|
||||
|
||||
```svelte
|
||||
<svelte:element this={expression} />
|
||||
```
|
||||
|
||||
The `<svelte:element>` element lets you render an element of a dynamically specified type. This is useful for example when displaying rich text content from a CMS. Any properties and event listeners present will be applied to the element.
|
||||
|
||||
The only supported binding is `bind:this`, since the element type-specific bindings that Svelte does at build time (e.g. `bind:value` for input elements) do not work with a dynamic tag type.
|
||||
|
||||
If `this` has a nullish value, the element and its children will not be rendered.
|
||||
|
||||
If `this` is the name of a [void element](https://developer.mozilla.org/en-US/docs/Glossary/Void_element) (e.g., `br`) and `<svelte:element>` has child elements, a runtime error will be thrown in development mode.
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
let { handler } = $props();
|
||||
|
||||
let tag = $state('div');
|
||||
</script>
|
||||
|
||||
<svelte:element this={tag} onclick={handler}>Foo</svelte:element>
|
||||
```
|
||||
|
||||
Svelte tries its best to infer the correct namespace from the element's surroundings, but it's not always possible. You can make it explicit with an `xmlns` attribute:
|
||||
|
||||
```svelte
|
||||
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" />
|
||||
```
|
||||
|
||||
## `<svelte:window>`
|
||||
|
||||
```svelte
|
||||
<svelte:window onevent={handler} />
|
||||
```
|
||||
|
||||
```svelte
|
||||
<svelte:window bind:prop={value} />
|
||||
```
|
||||
|
||||
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 at the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
function handleKeydown(event) {
|
||||
alert(`pressed the ${event.key} key`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window onkeydown={handleKeydown} />
|
||||
```
|
||||
|
||||
You can also bind to the following properties:
|
||||
|
||||
- `innerWidth`
|
||||
- `innerHeight`
|
||||
- `outerWidth`
|
||||
- `outerHeight`
|
||||
- `scrollX`
|
||||
- `scrollY`
|
||||
- `online` — an alias for `window.navigator.onLine`
|
||||
- `devicePixelRatio`
|
||||
|
||||
All except `scrollX` and `scrollY` are readonly.
|
||||
|
||||
```svelte
|
||||
<svelte:window bind:scrollY={y} />
|
||||
```
|
||||
|
||||
> [!NOTE] Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. However, if the scrolling behaviour is desired, call `scrollTo()` in `onMount()`.
|
||||
|
||||
## `<svelte:document>`
|
||||
|
||||
```svelte
|
||||
<svelte:document onevent={handler} />
|
||||
```
|
||||
|
||||
```svelte
|
||||
<svelte:document bind:prop={value} />
|
||||
```
|
||||
|
||||
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](use) on `document`.
|
||||
|
||||
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<svelte:document onvisibilitychange={handleVisibilityChange} use:someAction />
|
||||
```
|
||||
|
||||
You can also bind to the following properties:
|
||||
|
||||
- `activeElement`
|
||||
- `fullscreenElement`
|
||||
- `pointerLockElement`
|
||||
- `visibilityState`
|
||||
|
||||
All are readonly.
|
||||
|
||||
## `<svelte:body>`
|
||||
|
||||
```svelte
|
||||
<svelte:body onevent={handler} />
|
||||
```
|
||||
|
||||
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](use) on the `<body>` element.
|
||||
|
||||
As with `<svelte:window>` and `<svelte:document>`, this element may only appear the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave} use:someAction />
|
||||
```
|
||||
|
||||
## `<svelte:head>`
|
||||
|
||||
```svelte
|
||||
<svelte:head>...</svelte:head>
|
||||
```
|
||||
|
||||
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>`, `<svelte:document>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.
|
||||
|
||||
```svelte
|
||||
<svelte:head>
|
||||
<title>Hello world!</title>
|
||||
<meta name="description" content="This is where the description goes for SEO" />
|
||||
</svelte:head>
|
||||
```
|
||||
|
||||
## `<svelte:options>`
|
||||
|
||||
```svelte
|
||||
<svelte:options option={value} />
|
||||
```
|
||||
|
||||
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](svelte-compiler#compile). The possible options are:
|
||||
|
||||
- `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
|
||||
- `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
|
||||
- `accessors={true}` — adds getters and setters for the component's props
|
||||
- `accessors={false}` — the default
|
||||
- `namespace="..."` — the namespace where this component will be used, most commonly "svg"; use the "foreign" namespace to opt out of case-insensitive attribute names and HTML-specific warnings
|
||||
- `customElement={...}` — the [options](custom-elements#Component-options) to use when compiling this component as a custom element. If a string is passed, it is used as the `tag` option
|
||||
|
||||
```svelte
|
||||
<svelte:options customElement="my-custom-element" />
|
||||
```
|
Loading…
Reference in new issue