-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow objects/arrays for class attribute (#14714)
* WIP * missed * fix * fix * rename, smooth over incompatibilities * spread support + test * docs * types * implement CSS pruning for array/object expressions * beefier static analysis * lint * rename doc * move class after all directive docs * tweak docs - clarify top-level falsy values, stagger examples, demonstrate composition, discourage class: more strongly * changeset * fix * Update documentation/docs/03-template-syntax/18-class.md Co-authored-by: Conduitry <[email protected]> * Apply suggestions from code review --------- Co-authored-by: Rich Harris <[email protected]> Co-authored-by: Conduitry <[email protected]>
- Loading branch information
1 parent
38a3ae3
commit 015210a
Showing
35 changed files
with
433 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'svelte': minor | ||
--- | ||
|
||
feat: allow `class` attribute to be an object or array, using `clsx` |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
--- | ||
title: class | ||
--- | ||
|
||
There are two ways to set classes on elements: the `class` attribute, and the `class:` directive. | ||
|
||
## Attributes | ||
|
||
Primitive values are treated like any other attribute: | ||
|
||
```svelte | ||
<div class={large ? 'large' : 'small'}>...</div> | ||
``` | ||
|
||
> [!NOTE] | ||
> For historical reasons, falsy values (like `false` and `NaN`) are stringified (`class="false"`), though `class={undefined}` (or `null`) cause the attribute to be omitted altogether. In a future version of Svelte, all falsy values will cause `class` to be omitted. | ||
### Objects and arrays | ||
|
||
Since Svelte 5.16, `class` can be an object or array, and is converted to a string using [clsx](https://github.com/lukeed/clsx). | ||
|
||
If the value is an object, the truthy keys are added: | ||
|
||
```svelte | ||
<script> | ||
let { cool } = $props(); | ||
</script> | ||
<!-- results in `class="cool"` if `cool` is truthy, | ||
`class="lame"` otherwise --> | ||
<div class={{ cool, lame: !cool }}>...</div> | ||
``` | ||
|
||
If the value is an array, the truthy values are combined: | ||
|
||
```svelte | ||
<!-- if `faded` and `large` are both truthy, results in | ||
`class="saturate-0 opacity-50 scale-200"` --> | ||
<div class={[faded && 'saturate-0 opacity-50', large && 'scale-200']}>...</div> | ||
``` | ||
|
||
Note that whether we're using the array or object form, we can set multiple classes simultaneously with a single condition, which is particularly useful if you're using things like Tailwind. | ||
|
||
Arrays can contain arrays and objects, and clsx will flatten them. This is useful for combining local classes with props, for example: | ||
|
||
```svelte | ||
<!--- file: Button.svelte ---> | ||
<script> | ||
let props = $props(); | ||
</script> | ||
<button {...props} class={['cool-button', props.class]}> | ||
{@render props.children?.()} | ||
</button> | ||
``` | ||
|
||
The user of this component has the same flexibility to use a mixture of objects, arrays and strings: | ||
|
||
```svelte | ||
<!--- file: App.svelte ---> | ||
<script> | ||
import Button from './Button.svelte'; | ||
let useTailwind = $state(false); | ||
</script> | ||
<Button | ||
onclick={() => useTailwind = true} | ||
class={{ 'bg-blue-700 sm:w-1/2': useTailwind }} | ||
> | ||
Accept the inevitability of Tailwind | ||
</Button> | ||
``` | ||
|
||
## The `class:` directive | ||
|
||
Prior to Svelte 5.16, the `class:` directive was the most convenient way to set classes on elements conditionally. | ||
|
||
```svelte | ||
<!-- These are equivalent --> | ||
<div class={{ cool, lame: !cool }}>...</div> | ||
<div class:cool={cool} class:lame={!cool}>...</div> | ||
``` | ||
|
||
As with other directives, we can use a shorthand when the name of the class coincides with the value: | ||
|
||
```svelte | ||
<div class:cool class:lame={!cool}>...</div> | ||
``` | ||
|
||
> [!NOTE] Unless you're using an older version of Svelte, consider avoiding `class:`, since the attribute is more powerful and composable. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.