mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-19 14:31:47 +01:00
feat(module): implement --ui-radius CSS variable (#2341)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -4,6 +4,9 @@ export default defineAppConfig({
|
||||
expand: true,
|
||||
duration: 5000
|
||||
},
|
||||
theme: {
|
||||
radius: 0.25
|
||||
},
|
||||
ui: {
|
||||
colors: {
|
||||
primary: 'green',
|
||||
|
||||
@@ -52,6 +52,7 @@ const links = computed(() => {
|
||||
})
|
||||
|
||||
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
|
||||
const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
|
||||
|
||||
useHead({
|
||||
meta: [
|
||||
@@ -62,6 +63,9 @@ useHead({
|
||||
{ rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' },
|
||||
{ rel: 'canonical', href: `https://ui.nuxt.com${withoutTrailingSlash(route.path)}` }
|
||||
],
|
||||
style: [
|
||||
{ innerHTML: radius, id: 'nuxt-ui-radius', tagPriority: -2 }
|
||||
],
|
||||
htmlAttrs: {
|
||||
lang: 'en'
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@ const config = useRuntimeConfig().public
|
||||
const navigation = inject<Ref<NavItem[]>>('navigation')
|
||||
|
||||
// const items = computed(() => props.links.map(({ icon, ...link }) => link))
|
||||
|
||||
defineShortcuts({
|
||||
meta_g: () => {
|
||||
window.open('https://github.com/nuxt/ui/tree/v3', '_blank')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -26,22 +32,22 @@ const navigation = inject<Ref<NavItem[]>>('navigation')
|
||||
<!-- <UNavigationMenu :items="items" variant="link" /> -->
|
||||
|
||||
<template #right>
|
||||
<ColorPicker />
|
||||
<ThemePicker />
|
||||
|
||||
<UTooltip text="Search" :kbds="['meta', 'K']">
|
||||
<UContentSearchButton />
|
||||
</UTooltip>
|
||||
|
||||
<ColorModeButton />
|
||||
|
||||
<UButton
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
to="https://github.com/nuxt/ui/tree/v3"
|
||||
target="_blank"
|
||||
icon="i-simple-icons-github"
|
||||
aria-label="GitHub"
|
||||
/>
|
||||
<UTooltip text="Open on GitHub" :kbds="['meta', 'G']">
|
||||
<UButton
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
to="https://github.com/nuxt/ui/tree/v3"
|
||||
target="_blank"
|
||||
icon="i-simple-icons-github"
|
||||
aria-label="GitHub"
|
||||
/>
|
||||
</UTooltip>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<ClientOnly v-if="!colorMode?.forced">
|
||||
<UButton
|
||||
:icon="isDark ? appConfig.ui.icons.dark : appConfig.ui.icons.light"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
v-bind="{
|
||||
...$attrs
|
||||
}"
|
||||
:aria-label="`Switch to ${isDark ? 'light' : 'dark'} mode`"
|
||||
@click="isDark = !isDark"
|
||||
/>
|
||||
|
||||
<template #fallback>
|
||||
<div class="w-8 h-8" />
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
inheritAttrs: false
|
||||
})
|
||||
|
||||
const colorMode = useColorMode()
|
||||
const appConfig = useAppConfig()
|
||||
|
||||
// Computed
|
||||
|
||||
const isDark = computed({
|
||||
get() {
|
||||
return colorMode.value === 'dark'
|
||||
},
|
||||
set() {
|
||||
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<UPopover mode="hover" :ui="{ content: 'p-2' }">
|
||||
<template #default="{ open }">
|
||||
<UButton
|
||||
icon="i-heroicons-swatch-20-solid"
|
||||
color="neutral"
|
||||
:variant="open ? 'soft' : 'ghost'"
|
||||
square
|
||||
aria-label="Color picker"
|
||||
:ui="{ leadingIcon: 'text-[--ui-primary]' }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<fieldset class="grid grid-cols-5 gap-px">
|
||||
<legend class="text-[11px] font-bold mb-1">
|
||||
Primary
|
||||
</legend>
|
||||
|
||||
<ColorPickerPill v-for="color in primaryColors" :key="color" :color="color" :selected="primary" @select="primary = color" />
|
||||
</fieldset>
|
||||
|
||||
<USeparator class="my-2" type="dashed" />
|
||||
|
||||
<fieldset class="grid grid-cols-5 gap-px">
|
||||
<legend class="text-[11px] font-bold mb-1">
|
||||
Neutral
|
||||
</legend>
|
||||
|
||||
<ColorPickerPill v-for="color in neutralColors" :key="color" :color="color" :selected="neutral" @select="neutral = color" />
|
||||
</fieldset>
|
||||
</template>
|
||||
</UPopover>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import colors from 'tailwindcss/colors'
|
||||
import { omit } from '#ui/utils'
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
|
||||
// Computed
|
||||
|
||||
const neutralColors = ['slate', 'gray', 'zinc', 'neutral', 'stone']
|
||||
const neutral = computed({
|
||||
get() {
|
||||
return appConfig.ui.colors.neutral
|
||||
},
|
||||
set(option) {
|
||||
appConfig.ui.colors.neutral = option
|
||||
window.localStorage.setItem('nuxt-ui-neutral', appConfig.ui.colors.neutral)
|
||||
}
|
||||
})
|
||||
|
||||
const colorsToOmit = ['inherit', 'current', 'transparent', 'black', 'white', ...neutralColors]
|
||||
const primaryColors = Object.keys(omit(colors, colorsToOmit as any))
|
||||
const primary = computed({
|
||||
get() {
|
||||
return appConfig.ui.colors.primary
|
||||
},
|
||||
set(option) {
|
||||
appConfig.ui.colors.primary = option
|
||||
window.localStorage.setItem('nuxt-ui-primary', appConfig.ui.colors.primary)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<UTooltip :text="color" class="capitalize" :portal="false">
|
||||
<UButton
|
||||
color="neutral"
|
||||
square
|
||||
:variant="color === selected ? 'soft' : 'ghost'"
|
||||
@click.stop.prevent="$emit('select')"
|
||||
>
|
||||
<span
|
||||
class="inline-block w-3 h-3 rounded-full"
|
||||
:class="`bg-[--color-light] dark:bg-[--color-dark]`"
|
||||
:style="{
|
||||
'--color-light': `var(--color-${color}-500)`,
|
||||
'--color-dark': `var(--color-${color}-400)`
|
||||
}"
|
||||
/>
|
||||
</UButton>
|
||||
</UTooltip>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ color: string, selected: string }>()
|
||||
defineEmits(['select'])
|
||||
</script>
|
||||
@@ -214,7 +214,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div>
|
||||
<div v-if="options.length" class="flex items-center gap-2.5 border border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700] border-b-0 relative rounded-t-md px-4 py-2.5 overflow-x-auto">
|
||||
<div v-if="options.length" class="flex items-center gap-2.5 border border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700] border-b-0 relative rounded-t-[calc(var(--ui-radius)*1.5)] px-4 py-2.5 overflow-x-auto">
|
||||
<template v-for="option in options" :key="option.name">
|
||||
<UFormField
|
||||
:label="option.label"
|
||||
@@ -263,7 +263,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center border border-b-0 border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700] relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class]">
|
||||
<div class="flex justify-center border border-b-0 border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700] relative p-4 z-[1]" :class="[!options.length && 'rounded-t-[calc(var(--ui-radius)*1.5)]', props.class]">
|
||||
<component :is="name" v-bind="{ ...componentProps, ...componentEvents }">
|
||||
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
|
||||
<ContentSlot :name="slot" unwrap="p">
|
||||
|
||||
@@ -114,7 +114,7 @@ const optionsValues = ref(props.options?.reduce((acc, option) => {
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div v-if="preview">
|
||||
<div class="border border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700] relative z-[1]" :class="[{ 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source }]">
|
||||
<div class="border border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700] relative z-[1]" :class="[{ 'border-b-0 rounded-t-[calc(var(--ui-radius)*1.5)]': props.source, 'rounded-[calc(var(--ui-radius)*1.5)]': !props.source }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-[--ui-color-neutral-200] dark:border-[--ui-color-neutral-700]">
|
||||
<slot name="options" />
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden rounded border border-dashed border-[--ui-border-accented] opacity-75 px-4 flex items-center justify-center">
|
||||
<div class="relative overflow-hidden rounded-[--ui-radius] border border-dashed border-[--ui-border-accented] opacity-75 px-4 flex items-center justify-center">
|
||||
<svg class="absolute inset-0 h-full w-full stroke-[--ui-border-inverted]/10" fill="none">
|
||||
<defs>
|
||||
<pattern
|
||||
|
||||
140
docs/app/components/theme-picker/ThemePicker.vue
Normal file
140
docs/app/components/theme-picker/ThemePicker.vue
Normal file
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<UPopover :ui="{ content: 'w-72 px-6 py-4 flex flex-col gap-4' }">
|
||||
<template #default="{ open }">
|
||||
<UButton
|
||||
icon="i-heroicons-swatch"
|
||||
color="neutral"
|
||||
:variant="open ? 'soft' : 'ghost'"
|
||||
square
|
||||
aria-label="Color picker"
|
||||
:ui="{ leadingIcon: 'text-[--ui-primary]' }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<fieldset>
|
||||
<legend class="text-[11px] leading-none font-semibold mb-2">
|
||||
Primary
|
||||
</legend>
|
||||
|
||||
<div class="grid grid-cols-3 gap-1 -mx-2">
|
||||
<ThemePickerButton
|
||||
v-for="color in primaryColors"
|
||||
:key="color"
|
||||
:label="color"
|
||||
:chip="color"
|
||||
:selected="primary === color"
|
||||
@select="primary = color"
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend class="text-[11px] leading-none font-semibold mb-2">
|
||||
Neutral
|
||||
</legend>
|
||||
|
||||
<div class="grid grid-cols-3 gap-1 -mx-2">
|
||||
<ThemePickerButton
|
||||
v-for="color in neutralColors"
|
||||
:key="color"
|
||||
:label="color"
|
||||
:chip="color"
|
||||
:selected="neutral === color"
|
||||
@select="neutral = color"
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend class="text-[11px] leading-none font-semibold mb-2">
|
||||
Radius
|
||||
</legend>
|
||||
|
||||
<div class="grid grid-cols-5 gap-1 -mx-2">
|
||||
<ThemePickerButton
|
||||
v-for="r in radiuses"
|
||||
:key="r"
|
||||
:label="String(r)"
|
||||
class="justify-center px-0"
|
||||
:selected="radius === r"
|
||||
@select="radius = r"
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend class="text-[11px] leading-none font-semibold mb-2">
|
||||
Theme
|
||||
</legend>
|
||||
|
||||
<div class="flex gap-1 -mx-2">
|
||||
<ThemePickerButton
|
||||
v-for="m in modes"
|
||||
:key="m.label"
|
||||
v-bind="m"
|
||||
:selected="mode === m.label"
|
||||
@select="mode = m.label"
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
</template>
|
||||
</UPopover>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import colors from 'tailwindcss/colors'
|
||||
import { omit } from '#ui/utils'
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const colorMode = useColorMode()
|
||||
|
||||
// Computed
|
||||
|
||||
const neutralColors = ['slate', 'gray', 'zinc', 'neutral', 'stone']
|
||||
const neutral = computed({
|
||||
get() {
|
||||
return appConfig.ui.colors.neutral
|
||||
},
|
||||
set(option) {
|
||||
appConfig.ui.colors.neutral = option
|
||||
window.localStorage.setItem('nuxt-ui-neutral', appConfig.ui.colors.neutral)
|
||||
}
|
||||
})
|
||||
|
||||
const colorsToOmit = ['inherit', 'current', 'transparent', 'black', 'white', ...neutralColors]
|
||||
const primaryColors = Object.keys(omit(colors, colorsToOmit as any))
|
||||
const primary = computed({
|
||||
get() {
|
||||
return appConfig.ui.colors.primary
|
||||
},
|
||||
set(option) {
|
||||
appConfig.ui.colors.primary = option
|
||||
window.localStorage.setItem('nuxt-ui-primary', appConfig.ui.colors.primary)
|
||||
}
|
||||
})
|
||||
|
||||
const radiuses = [0, 0.125, 0.25, 0.375, 0.5]
|
||||
const radius = computed({
|
||||
get() {
|
||||
return appConfig.theme.radius
|
||||
},
|
||||
set(option) {
|
||||
appConfig.theme.radius = option
|
||||
window.localStorage.setItem('nuxt-ui-radius', String(appConfig.theme.radius))
|
||||
}
|
||||
})
|
||||
|
||||
const modes = [
|
||||
{ label: 'light', icon: appConfig.ui.icons.light },
|
||||
{ label: 'dark', icon: appConfig.ui.icons.dark }
|
||||
]
|
||||
const mode = computed({
|
||||
get() {
|
||||
return colorMode.value
|
||||
},
|
||||
set(option) {
|
||||
colorMode.preference = option
|
||||
}
|
||||
})
|
||||
</script>
|
||||
32
docs/app/components/theme-picker/ThemePickerButton.vue
Normal file
32
docs/app/components/theme-picker/ThemePickerButton.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<UButton
|
||||
size="sm"
|
||||
color="neutral"
|
||||
:icon="icon"
|
||||
:label="label"
|
||||
:variant="selected ? 'soft' : 'outline'"
|
||||
class="capitalize ring-[--ui-border] rounded-[--ui-radius] text-[11px]"
|
||||
@click.stop.prevent="$emit('select')"
|
||||
>
|
||||
<template v-if="chip" #leading>
|
||||
<span
|
||||
class="inline-block w-2 h-2 rounded-full"
|
||||
:class="`bg-[--color-light] dark:bg-[--color-dark]`"
|
||||
:style="{
|
||||
'--color-light': `var(--color-${chip}-500)`,
|
||||
'--color-dark': `var(--color-${chip}-400)`
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
label: string
|
||||
icon?: string
|
||||
chip?: string
|
||||
selected?: boolean
|
||||
}>()
|
||||
defineEmits(['select'])
|
||||
</script>
|
||||
@@ -11,15 +11,22 @@ export default defineNuxtPlugin({
|
||||
}
|
||||
}
|
||||
|
||||
function updateRadius() {
|
||||
const radius = localStorage.getItem('nuxt-ui-radius')
|
||||
if (radius) {
|
||||
appConfig.theme.radius = Number.parseFloat(radius)
|
||||
}
|
||||
}
|
||||
|
||||
updateColor('primary')
|
||||
updateColor('neutral')
|
||||
updateRadius()
|
||||
}
|
||||
|
||||
if (import.meta.server) {
|
||||
useHead({
|
||||
script: [
|
||||
{
|
||||
innerHTML: `
|
||||
script: [{
|
||||
innerHTML: `
|
||||
let html = document.querySelector('style#nuxt-ui-colors').innerHTML;
|
||||
|
||||
if (localStorage.getItem('nuxt-ui-primary')) {
|
||||
@@ -39,10 +46,17 @@ export default defineNuxtPlugin({
|
||||
|
||||
document.querySelector('style#nuxt-ui-colors').innerHTML = html;
|
||||
`.replace(/\s+/g, ' '),
|
||||
type: 'text/javascript',
|
||||
tagPriority: -1
|
||||
}
|
||||
]
|
||||
type: 'text/javascript',
|
||||
tagPriority: -1
|
||||
}, {
|
||||
innerHTML: `
|
||||
if (localStorage.getItem('nuxt-ui-radius')) {
|
||||
document.querySelector('style#nuxt-ui-radius').innerHTML = ':root { --ui-radius: ' + localStorage.getItem('nuxt-ui-radius') + 'rem; }';
|
||||
}
|
||||
`.replace(/\s+/g, ' '),
|
||||
type: 'text/javascript',
|
||||
tagPriority: -1
|
||||
}]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ export default defineAppConfig({
|
||||
```
|
||||
|
||||
::note
|
||||
Try the :prose-icon{name="i-heroicons-swatch-20-solid" class="text-[--ui-primary]"} picker in the header above to change `primary` and `neutral` colors.
|
||||
Try the :prose-icon{name="i-heroicons-swatch" class="text-[--ui-primary]"} theme picker in the header above to change `primary` and `neutral` colors.
|
||||
::
|
||||
|
||||
These colors are used to style the components but also to generate the `color` variants:
|
||||
@@ -149,7 +149,7 @@ export default defineNuxtConfig({
|
||||
|
||||
::
|
||||
|
||||
::note
|
||||
::warning
|
||||
These color aliases are not automatically defined as Tailwind CSS colors, so classes like `text-primary-500 dark:text-primary-400` won't be available by default as in Nuxt UI v2. This approach provides more flexibility and prevents overwriting of user-defined Tailwind CSS colors.<br><br>
|
||||
|
||||
However, you can generate these classes using Tailwind's `@theme` directive, allowing you to use custom color utility classes while maintaining dynamic color aliases:
|
||||
@@ -178,7 +178,11 @@ However, you can generate these classes using Tailwind's `@theme` directive, all
|
||||
|
||||
### Tokens
|
||||
|
||||
Nuxt UI generates CSS variables as design tokens for component styling. These tokens enable consistent theming and support both light and dark modes. You can use them in Tailwind classes like `text-[--ui-primary]`, which automatically adapts to the current color scheme.
|
||||
Nuxt UI leverages a robust system of CSS variables as design tokens to ensure consistent and flexible component styling. These tokens form the foundation of the theming system, offering smooth support for both light and dark modes.
|
||||
|
||||
#### Color Shades
|
||||
|
||||
Nuxt UI automatically creates a CSS variable for each color alias you define which represent the default shade used in both light and dark modes:
|
||||
|
||||
::code-group
|
||||
|
||||
@@ -206,6 +210,10 @@ Nuxt UI generates CSS variables as design tokens for component styling. These to
|
||||
|
||||
::
|
||||
|
||||
::note
|
||||
You can use these variables in classes like `text-[--ui-primary]`, it will automatically adapt to the current color scheme.
|
||||
::
|
||||
|
||||
::tip
|
||||
You can change which shade is used for each color on light and dark mode:
|
||||
|
||||
@@ -225,6 +233,8 @@ You can change which shade is used for each color on light and dark mode:
|
||||
```
|
||||
::
|
||||
|
||||
#### Neutral Palette
|
||||
|
||||
Nuxt UI provides a comprehensive set of design tokens for the `neutral` color palette, ensuring consistent and accessible UI styling across both light and dark modes. These tokens offer fine-grained control over text, background, and border colors:
|
||||
|
||||
::code-group
|
||||
@@ -293,7 +303,18 @@ Nuxt UI provides a comprehensive set of design tokens for the `neutral` color pa
|
||||
|
||||
::
|
||||
|
||||
You can easily customize these CSS variables in your `app.vue`{lang="ts-type"} or [CSS](https://nuxt.com/docs/getting-started/styling#the-css-property) to tailor the appearance of your application:
|
||||
::note
|
||||
Nuxt UI automatically applies a text and background color on the `<body>` element of your app:
|
||||
|
||||
```css
|
||||
body {
|
||||
@apply antialiased font-sans text-[--ui-text] bg-[--ui-bg];
|
||||
}
|
||||
```
|
||||
::
|
||||
|
||||
::tip
|
||||
You can customize these CSS variables to tailor the appearance of your application:
|
||||
|
||||
```vue [app.vue]
|
||||
<style>
|
||||
@@ -311,15 +332,35 @@ You can easily customize these CSS variables in your `app.vue`{lang="ts-type"} o
|
||||
}
|
||||
</style>
|
||||
```
|
||||
::
|
||||
|
||||
::note
|
||||
Nuxt UI automatically applies a text and background color on the `<body>` element of your app:
|
||||
#### Border Radius
|
||||
|
||||
Nuxt UI uses a global `--ui-radius` CSS variable for consistent border rounding. Components use variations of this base value, like `rounded-[calc(var(--ui-radius)*2)]`, to create different levels of roundness throughout the UI:
|
||||
|
||||
```css
|
||||
body {
|
||||
@apply antialiased font-sans text-[--ui-text] bg-[--ui-bg];
|
||||
:root {
|
||||
--ui-radius: var(--radius-sm);
|
||||
}
|
||||
```
|
||||
|
||||
::note
|
||||
Try the :prose-icon{name="i-heroicons-swatch" class="text-[--ui-primary]"} theme picker in the header above to change the base radius value.
|
||||
::
|
||||
|
||||
::tip
|
||||
You can customize the default radius value using the default Tailwind CSS variables or a value of your choice:
|
||||
|
||||
```vue [app.vue]
|
||||
<style>
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui";
|
||||
|
||||
:root {
|
||||
--ui-radius: var(--radius-sm);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
::
|
||||
|
||||
## Components theme
|
||||
@@ -335,7 +376,7 @@ Components in Nuxt UI can have multiple `slots`, each representing a distinct HT
|
||||
```ts [src/theme/card.ts]
|
||||
export default {
|
||||
slots: {
|
||||
root: 'bg-[--ui-bg] ring ring-[--ui-border] divide-y divide-[--ui-border] rounded-lg shadow',
|
||||
root: 'bg-[--ui-bg] ring ring-[--ui-border] divide-y divide-[--ui-border] rounded-[calc(var(--ui-radius)*2)] shadow',
|
||||
header: 'p-4 sm:px-6',
|
||||
body: 'p-4 sm:p-6',
|
||||
footer: 'p-4 sm:px-6'
|
||||
|
||||
Reference in New Issue
Block a user