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 | boolean
as 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: boolean
works same as a regular Vue propdefault
will be typed according to the varianttype: any
works same as a regular Vue prop (you should not overwrite this)mediaPrefix: boolean
toggles 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>