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 prop
  • default will be typed according to the variant
  • type: 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>