Variants
Variants let you declare different appearances that can respond to media queries using props.
They can be defined in the variants key, at the root of your css() function.
<script setup lang="ts">
defineProps({
...variants
})
</script>
<template>
<div>
<slot />
</div>
</template>
<style lang="ts">
css({
variants: {
size: {
sm: {
padding: '{space.3} {space.6}',
},
md: {
padding: '{space.6} {space.8}'
},
lg: {
padding: '{space.8} {space.12}'
},
xl: {
padding: '{space.12} {space.24}'
},
options: {
default: 'sm',
},
},
},
})
</style>
Context
Variants generates components props and runtime style bindings.
Every key at the root of the variants object relates to a prop of your component.
In the example above, you can see the variants object gets spread into defineProps().
This props object gets generated from your variants declaration and supports:
-
string | booleanas the key of your variants values'sm' | 'md' | 'lg' | 'xl'<MyButton size="sm" />
-
{ initial: string | boolean, [key: PinceauMediaQueries]: string | boolean }{ initial: 'sm' | 'md' | 'lg' | 'xl', dark: 'sm' | 'md' | 'lg' | 'xl', ... }<MyButton :size="{ initial: 'sm', lg: 'xl' }" />
Boolean variants
Boolean variants supports true and false as key and will generated a Boolean prop.
css({
variants: {
transparent: {
true: {
backgroundColor: 'transparent'
}
},
rounded: {
true: {
borderRadius: '{space.4}',
},
false: {
borderRadius: '{space.0}'
},
options: {
default: true
}
}
}
})
<MyButton transparent :rounded="{ initial: false, xl: true }" />
Enum variants
Boolean variants any string as key and will generated a string prop with union type of all the keys.
You can add as many keys you want in enum variants.
<style lang="ts">
css({
variants: {
size: {
sm: {
padding: '{space.3} {space.6}',
},
md: {
padding: '{space.6} {space.8}'
},
lg: {
padding: '{space.8} {space.12}'
},
xl: {
padding: '{space.12} {space.24}'
},
options: {
default: 'sm',
},
},
},
})
</style>
<MyButton size="sm" />
<MyButton :size="{ initial: 'sm', lg: 'xl' }" />
Class variants
Class variants are useful when you are using Pinceau in combination with a utility-first CSS framework.
They are supported both with Boolean and Enum variants.
<style lang="ts">
css({
variants: {
size: {
sm: 'px-3 py-6',
md: 'px-6 py-8',
lg: 'px-8 py-12',
xl: 'px-12 py-24',
options: {
default: 'sm',
mediaPrefix: true
},
},
},
})
</style>
These classes will be added to the component root element, the same as other variants.
mediaPrefix variant option allows to enabled/disable support for responsive feature for classes.
That will add the ${mediaQuery}: prefix in front of the classes, based on the media queries used in props.
Variants options
The options key is reserved in variants declaration and allows you to configure the output prop.
required: booleanworks same as a regular Vue propdefaultwill be typed according to the varianttype: anyworks same as a regular Vue prop (you should not overwrite this)-
mediaPrefix: booleantoggles the support for media prefix for Class variants
Class binding
A class gets generated and added to the root element of your <template>, here on <div>.
In some cases, you might want to place that class somewhere else:
- Your root component does not support
class - You want your styling to be bound to a nested element of your template
In these cases, you can bind $pinceau to another element, and that will disable the automatic binding.
<template>
<Transition>
<div :class="$pinceau" />
</Transition>
</template>
Edit this page on GitHub
Table of Contents