useThemeLayer
- Layered themes
With Artivue, creating theme nuances is straightforward thanks to the useThemeLayer
composable, allowing you to create theme layers. For example, a Card component can utilize this:
<script setup lang="ts">
const {
// Use this on the element where you want to start overriding
className,
// A computed which tells if the current theme is dark or not
isDark,
// The current theme configuration
theme,
// The current generated full theme configuration
generatedTheme
} = useThemeLayer()
</script>
<template>
<div
:class="className"
class="card"
>
<slot />
</div>
</template>
<style>
.card {
background-color: rgba(var(--artivue-surface-bg), 1);
border: 1px solid rgba(var(--artivue-surface-border), 1);
border-radius: 0.5em;
padding: 1em;
color: rgba(var(--artivue-surface-text), 1);
}
</style>
Output:
How does it work?
useThemeLayer
dynamically adds a new CSS class which can be used to override the base CSS variables. The variables is a tint of its "ancestor" theme. The composable returns the generated CSS class name in className
. Add this to the element where you want the theme to start overriding.
It is possible to nest the composable, the generated variables will be based on the previous theme layer:
<template>
<Card>
<Card>
<Card>
<p>Hello world</p>
</Card>
</Card>
</Card>
</template>
Example:
First layer (notice that this is the same layer as the card above? They share the same style tag in head even though they are two different instances!)
Second layer
Hello world
Is dark: true
Advanced
You can pass a multiplier for the tint / shade of the parent theme (default is 1). To create darker shades you can pass negative values.
Usage:
<script setup>
const {
className,
isDark,
theme,
} = useThemeLayer(2)
</script>
Example:
I have a slightly brighter layer than default
And I'm still nestable
You can also override the base theme completely and pass a custom theme.
Usage:
<script setup>
const {
className,
isDark,
theme,
} = useThemeLayer({
surface: {
background: '#589edf',
text: '#000000',
},
accent: {
background: '#5c72ff',
text: '#ffffff',
}
})
</script>
Example:
I have a custom theme
And I'm still nestable
Type reference
interface UseThemeLayerReturn {
className: ComputedRef<string>
theme: ComputedRef<Theme>
generatedTheme: ComputedRef<GeneratedTheme>
isDark: ComputedRef<boolean>
id: ComputedRef<string>
}
function useThemeLayer(multiplier?: MaybeRef<number>): UseThemeLayerReturn
function useThemeLayer(fn: (parent: Theme, isParentDark: boolean) => PartialTheme, multiplier?: MaybeRef<number>): UseThemeLayerReturn
function useThemeLayer(theme: MaybeRef<PartialTheme>, multiplier?: MaybeRef<number>): UseThemeLayerReturn
function useThemeLayer(arg?: MaybeRef<PartialTheme | number | undefined | ((parent: Theme, isParentDark: boolean) => PartialTheme)>, multiplier?: MaybeRef<number | undefined>): UseThemeLayerReturn