mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 12:14:41 +01:00
feat(module): define neutral utilities (#3629)
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
@import "tailwindcss" theme(static) source("../../../..");
|
||||
@import "@nuxt/ui-pro";
|
||||
|
||||
@source "../../../content";
|
||||
@source "../../../content/**/*";
|
||||
@source "../../../node_modules/.c12";
|
||||
|
||||
@theme static {
|
||||
|
||||
@@ -23,7 +23,7 @@ onMounted(() => {
|
||||
@reference "../assets/css/main.css";
|
||||
|
||||
.carbon :deep(#carbonads) {
|
||||
@apply relative border border-(--ui-border) rounded-md hover:bg-(--ui-bg-elevated)/50 w-full transition-colors min-h-[220px] p-2;
|
||||
@apply relative border border-default rounded-md hover:bg-elevated/50 w-full transition-colors min-h-[220px] p-2;
|
||||
|
||||
.carbon-img {
|
||||
@apply flex justify-center w-full;
|
||||
@@ -34,16 +34,16 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.carbon-text {
|
||||
@apply text-sm text-(--ui-text-muted) transition-colors text-center text-pretty flex pt-2;
|
||||
@apply text-sm text-muted transition-colors text-center text-pretty flex pt-2;
|
||||
}
|
||||
|
||||
.carbon-poweredby {
|
||||
@apply block text-xs text-center text-(--ui-text-muted) pt-2;
|
||||
@apply block text-xs text-center text-muted pt-2;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.carbon-text {
|
||||
@apply text-(--ui-text);
|
||||
@apply text-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ const links = [{
|
||||
|
||||
<UFooter>
|
||||
<template #left>
|
||||
<NuxtLink to="https://github.com/nuxt/ui" target="_blank" class="text-sm text-(--ui-text-muted)">
|
||||
Published under <span class="text-(--ui-text-highlighted)">MIT License</span>
|
||||
<NuxtLink to="https://github.com/nuxt/ui" target="_blank" class="text-sm text-muted">
|
||||
Published under <span class="text-highlighted">MIT License</span>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ watch(framework, () => {
|
||||
:content="false"
|
||||
color="neutral"
|
||||
:ui="{
|
||||
indicator: 'bg-(--ui-bg)',
|
||||
trigger: 'px-1 data-[state=active]:text-(--ui-text-highlighted)'
|
||||
indicator: 'bg-default',
|
||||
trigger: 'px-1 data-[state=active]:text-highlighted'
|
||||
}"
|
||||
size="xs"
|
||||
@update:model-value="(framework = $event as string)"
|
||||
|
||||
@@ -41,7 +41,7 @@ const mobileLinks = computed(() => [
|
||||
<template>
|
||||
<UHeader :ui="{ left: 'min-w-0' }" :menu="{ shouldScaleBackground: true }">
|
||||
<template #left>
|
||||
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-(--ui-text-highlighted) min-w-0 focus-visible:outline-(--ui-primary) shrink-0" aria-label="Nuxt UI">
|
||||
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-highlighted min-w-0 focus-visible:outline-primary shrink-0" aria-label="Nuxt UI">
|
||||
<Logo v-if="route.path === '/'" class="w-auto h-6 shrink-0" />
|
||||
<LogoPro v-else-if="route.path.startsWith('/pro')" class="w-auto h-6 shrink-0" />
|
||||
<template v-else>
|
||||
@@ -63,7 +63,7 @@ const mobileLinks = computed(() => [
|
||||
trailing-icon="i-lucide-chevron-down"
|
||||
size="xs"
|
||||
class="-mb-[6px] font-semibold rounded-full truncate"
|
||||
:class="[open && 'bg-(--ui-primary)/15 ']"
|
||||
:class="[open && 'bg-primary/15 ']"
|
||||
:ui="{
|
||||
trailingIcon: ['transition-transform duration-200', open ? 'rotate-180' : undefined].filter(Boolean).join(' ')
|
||||
}"
|
||||
@@ -108,7 +108,7 @@ const mobileLinks = computed(() => [
|
||||
<span class="inline-flex items-center gap-0.5">
|
||||
{{ link.title }}
|
||||
|
||||
<sup v-if="link.module === 'ui-pro'" class="text-[8px] font-medium text-(--ui-primary)">PRO</sup>
|
||||
<sup v-if="link.module === 'ui-pro'" class="text-[8px] font-medium text-primary">PRO</sup>
|
||||
</span>
|
||||
</template>
|
||||
</UContentNavigation>
|
||||
|
||||
@@ -19,8 +19,8 @@ watch(module, () => {
|
||||
:content="false"
|
||||
color="neutral"
|
||||
:ui="{
|
||||
indicator: 'bg-(--ui-bg)',
|
||||
trigger: 'px-1 data-[state=active]:text-(--ui-text-highlighted)'
|
||||
indicator: 'bg-default',
|
||||
trigger: 'px-1 data-[state=active]:text-highlighted'
|
||||
}"
|
||||
size="xs"
|
||||
@update:model-value="(module = $event as string)"
|
||||
|
||||
@@ -329,15 +329,15 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div class="relative">
|
||||
<div v-if="options.length" class="flex flex-wrap items-center gap-2.5 border border-(--ui-border-muted) border-b-0 relative rounded-t-md px-4 py-2.5 overflow-x-auto">
|
||||
<div v-if="options.length" class="flex flex-wrap items-center gap-2.5 border border-muted border-b-0 relative rounded-t-md px-4 py-2.5 overflow-x-auto">
|
||||
<template v-for="option in options" :key="option.name">
|
||||
<UFormField
|
||||
:label="option.label"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-sm flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
@@ -377,7 +377,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="component" class="flex justify-center border border-b-0 border-(--ui-border-muted) relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class, { 'overflow-hidden': props.overflowHidden }]">
|
||||
<div v-if="component" class="flex justify-center border border-b-0 border-muted relative p-4 z-[1]" :class="[!options.length && 'rounded-t-md', props.class, { 'overflow-hidden': props.overflowHidden }]">
|
||||
<component :is="component" v-bind="{ ...componentProps, ...componentEvents }">
|
||||
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
|
||||
<slot :name="slot" mdc-unwrap="p">
|
||||
|
||||
@@ -150,8 +150,8 @@ const urlSearchParams = computed(() => {
|
||||
<template>
|
||||
<div ref="el" class="my-5">
|
||||
<template v-if="preview">
|
||||
<div class="border border-(--ui-border-muted) relative z-[1]" :class="[{ 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source, 'overflow-hidden': props.overflowHidden }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-(--ui-border-muted)">
|
||||
<div class="border border-muted relative z-[1]" :class="[{ 'border-b-0 rounded-t-md': props.source, 'rounded-md': !props.source, 'overflow-hidden': props.overflowHidden }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-muted">
|
||||
<slot name="options" />
|
||||
|
||||
<UFormField
|
||||
@@ -160,10 +160,10 @@ const urlSearchParams = computed(() => {
|
||||
:label="option.label"
|
||||
:name="option.name"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-sm flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
|
||||
@@ -112,7 +112,7 @@ const metaProps: ComputedRef<ComponentMeta['props']> = computed(() => {
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="prop.type" :type="prop.type" />
|
||||
|
||||
<MDC v-if="prop.description" :value="prop.description" class="text-(--ui-text-toned) mt-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-description`" />
|
||||
<MDC v-if="prop.description" :value="prop.description" class="text-toned mt-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-description`" />
|
||||
|
||||
<ComponentPropsLinks v-if="prop.tags?.length" :prop="prop" />
|
||||
<ComponentPropsSchema v-if="prop.schema" :prop="prop" :ignore="ignore" />
|
||||
|
||||
@@ -43,7 +43,7 @@ const schemaProps = computed(() => {
|
||||
<ProseLi v-for="schemaProp in schemaProps" :key="schemaProp.name">
|
||||
<HighlightInlineType :type="`${schemaProp.name}${schemaProp.required === false ? '?' : ''}: ${schemaProp.type}`" />
|
||||
|
||||
<MDC v-if="schemaProp.description" :value="schemaProp.description" class="text-(--ui-text-muted) my-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-${schemaProp.name}-description`" />
|
||||
<MDC v-if="schemaProp.description" :value="schemaProp.description" class="text-muted my-1" :cache-key="`${kebabCase(route.path)}-${prop.name}-${schemaProp.name}-description`" />
|
||||
</ProseLi>
|
||||
</ProseUl>
|
||||
</ProseCollapsible>
|
||||
|
||||
@@ -36,7 +36,7 @@ const meta = await fetchComponentMeta(name as any)
|
||||
<ProseTd>
|
||||
<HighlightInlineType v-if="slot.type" :type="slot.type" />
|
||||
|
||||
<MDC v-if="slot.description" :value="slot.description" class="text-(--ui-text-toned) mt-1" :cache-key="`${kebabCase(route.path)}-${slot.name}-description`" />
|
||||
<MDC v-if="slot.description" :value="slot.description" class="text-toned mt-1" :cache-key="`${kebabCase(route.path)}-${slot.name}-description`" />
|
||||
</ProseTd>
|
||||
</ProseTr>
|
||||
</ProseTbody>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden rounded-sm 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">
|
||||
<div class="relative overflow-hidden rounded-sm border border-dashed border-accented opacity-75 px-4 flex items-center justify-center">
|
||||
<svg class="absolute inset-0 h-full w-full stroke-inverted/10" fill="none">
|
||||
<defs>
|
||||
<pattern
|
||||
id="pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e"
|
||||
|
||||
@@ -20,7 +20,7 @@ const items: AccordionItem[] = [
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #content="{ item }">
|
||||
<p class="pb-3.5 text-sm text-(--ui-text-muted)">
|
||||
<p class="pb-3.5 text-sm text-muted">
|
||||
This is the {{ item.label }} panel.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -24,7 +24,7 @@ const items = [
|
||||
<template>
|
||||
<UAccordion :items="items">
|
||||
<template #colors="{ item }">
|
||||
<p class="text-sm pb-3.5 text-(--ui-primary)">
|
||||
<p class="text-sm pb-3.5 text-primary">
|
||||
{{ item.content }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<ULink
|
||||
to="https://github.com/benjamincanac"
|
||||
target="_blank"
|
||||
class="hover:ring-(--ui-primary) transition"
|
||||
class="hover:ring-primary transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
@@ -15,7 +15,7 @@
|
||||
<ULink
|
||||
to="https://github.com/romhml"
|
||||
target="_blank"
|
||||
class="hover:ring-(--ui-primary) transition"
|
||||
class="hover:ring-primary transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
@@ -27,7 +27,7 @@
|
||||
<ULink
|
||||
to="https://github.com/noook"
|
||||
target="_blank"
|
||||
class="hover:ring-(--ui-primary) transition"
|
||||
class="hover:ring-primary transition"
|
||||
raw
|
||||
>
|
||||
<UAvatar
|
||||
|
||||
@@ -20,7 +20,7 @@ const items: BreadcrumbItem[] = [
|
||||
<template>
|
||||
<UBreadcrumb :items="items">
|
||||
<template #separator>
|
||||
<span class="mx-2 text-(--ui-text-muted)">/</span>
|
||||
<span class="mx-2 text-muted">/</span>
|
||||
</template>
|
||||
</UBreadcrumb>
|
||||
</template>
|
||||
|
||||
@@ -35,7 +35,7 @@ const items = computed<ContextMenuItem[]>(() => [{
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
</UContextMenu>
|
||||
|
||||
@@ -28,7 +28,7 @@ const items: ContextMenuItem[][] = [
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
</UContextMenu>
|
||||
|
||||
@@ -19,7 +19,7 @@ const items = [
|
||||
|
||||
<template>
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@ const items = [
|
||||
</template>
|
||||
|
||||
<template #refresh-trailing>
|
||||
<UIcon v-if="loading" name="i-lucide-refresh-cw" class="shrink-0 size-5 text-(--ui-primary) animate-spin" />
|
||||
<UIcon v-if="loading" name="i-lucide-refresh-cw" class="shrink-0 size-5 text-primary animate-spin" />
|
||||
</template>
|
||||
</UContextMenu>
|
||||
</template>
|
||||
|
||||
@@ -7,7 +7,7 @@ const open = ref(false)
|
||||
<UButton label="Open" color="neutral" variant="subtle" trailing-icon="i-lucide-chevron-up" />
|
||||
|
||||
<template #header>
|
||||
<h2 class="text-(--ui-text-highlighted) font-semibold">
|
||||
<h2 class="text-highlighted font-semibold">
|
||||
Drawer non-dismissible
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ const items = [
|
||||
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
|
||||
|
||||
<template #profile-trailing>
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-(--ui-primary)" />
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-primary" />
|
||||
</template>
|
||||
</UDropdownMenu>
|
||||
</template>
|
||||
|
||||
@@ -36,7 +36,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-(--ui-text-muted)">
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -15,7 +15,7 @@ const domain = ref(domains[0])
|
||||
}"
|
||||
>
|
||||
<template #leading>
|
||||
<p class="text-sm text-(--ui-text-muted)">
|
||||
<p class="text-sm text-muted">
|
||||
https://
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -13,7 +13,7 @@ const maxLength = 15
|
||||
<template #trailing>
|
||||
<div
|
||||
id="character-count"
|
||||
class="text-xs text-(--ui-text-muted) tabular-nums"
|
||||
class="text-xs text-muted tabular-nums"
|
||||
aria-live="polite"
|
||||
role="status"
|
||||
>
|
||||
|
||||
@@ -4,8 +4,8 @@ const value = ref('')
|
||||
|
||||
<template>
|
||||
<UInput v-model="value" placeholder="" :ui="{ base: 'peer' }">
|
||||
<label class="pointer-events-none absolute left-0 -top-2.5 text-(--ui-text-highlighted) text-xs font-medium px-1.5 transition-all peer-focus:-top-2.5 peer-focus:text-(--ui-text-highlighted) peer-focus:text-xs peer-focus:font-medium peer-placeholder-shown:text-sm peer-placeholder-shown:text-(--ui-text-dimmed) peer-placeholder-shown:top-1.5 peer-placeholder-shown:font-normal">
|
||||
<span class="inline-flex bg-(--ui-bg) px-1">Email address</span>
|
||||
<label class="pointer-events-none absolute left-0 -top-2.5 text-highlighted text-xs font-medium px-1.5 transition-all peer-focus:-top-2.5 peer-focus:text-highlighted peer-focus:text-xs peer-focus:font-medium peer-placeholder-shown:text-sm peer-placeholder-shown:text-dimmed peer-placeholder-shown:top-1.5 peer-placeholder-shown:font-normal">
|
||||
<span class="inline-flex bg-default px-1">Email address</span>
|
||||
</label>
|
||||
</UInput>
|
||||
</template>
|
||||
|
||||
@@ -77,7 +77,7 @@ const text = computed(() => {
|
||||
v-for="(req, index) in strength"
|
||||
:key="index"
|
||||
class="flex items-center gap-0.5"
|
||||
:class="req.met ? 'text-(--ui-success)' : 'text-(--ui-text-muted)'"
|
||||
:class="req.met ? 'text-success' : 'text-muted'"
|
||||
>
|
||||
<UIcon :name="req.met ? 'i-lucide-circle-check' : 'i-lucide-circle-x'" class="size-4 shrink-0" />
|
||||
|
||||
|
||||
@@ -76,11 +76,11 @@ const items = [
|
||||
</li>
|
||||
|
||||
<li v-for="child in item.children" :key="child.label">
|
||||
<ULink class="text-sm text-left rounded-md p-3 transition-colors hover:bg-(--ui-bg-elevated)/50">
|
||||
<p class="font-medium text-(--ui-text-highlighted)">
|
||||
<ULink class="text-sm text-left rounded-md p-3 transition-colors hover:bg-elevated/50">
|
||||
<p class="font-medium text-highlighted">
|
||||
{{ child.label }}
|
||||
</p>
|
||||
<p class="text-(--ui-text-muted) line-clamp-2">
|
||||
<p class="text-muted line-clamp-2">
|
||||
{{ child.description }}
|
||||
</p>
|
||||
</ULink>
|
||||
|
||||
@@ -8,7 +8,7 @@ const open = ref(false)
|
||||
|
||||
<template #content>
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<h2 class="text-(--ui-text-highlighted) font-semibold">
|
||||
<h2 class="text-highlighted font-semibold">
|
||||
Popover non-dismissible
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
|
||||
<template #item-label="{ item }">
|
||||
{{ item.label }}
|
||||
|
||||
<span class="text-(--ui-text-muted)">
|
||||
<span class="text-muted">
|
||||
{{ item.email }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -100,7 +100,7 @@ const columnFilters = ref([{
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col flex-1 w-full">
|
||||
<div class="flex px-4 py-3.5 border-b border-(--ui-border-accented)">
|
||||
<div class="flex px-4 py-3.5 border-b border-accented">
|
||||
<UInput
|
||||
:model-value="(table?.tableApi?.getColumn('email')?.getFilterValue() as string)"
|
||||
class="max-w-sm"
|
||||
|
||||
@@ -131,7 +131,7 @@ function getHeader(column: Column<Payment>, label: string) {
|
||||
'variant': 'ghost',
|
||||
label,
|
||||
'icon': isSorted ? (isSorted === 'asc' ? 'i-lucide-arrow-up-narrow-wide' : 'i-lucide-arrow-down-wide-narrow') : 'i-lucide-arrow-up-down',
|
||||
'class': '-mx-2.5 data-[state=open]:bg-(--ui-bg-elevated)',
|
||||
'class': '-mx-2.5 data-[state=open]:bg-elevated',
|
||||
'aria-label': `Sort by ${isSorted === 'asc' ? 'descending' : 'ascending'}`
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ const columnVisibility = ref({
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col flex-1 w-full">
|
||||
<div class="flex justify-end px-4 py-3.5 border-b border-(--ui-border-accented)">
|
||||
<div class="flex justify-end px-4 py-3.5 border-b border-accented">
|
||||
<UDropdownMenu
|
||||
:items="table?.tableApi?.getAllColumns().filter(column => column.getCanHide()).map(column => ({
|
||||
label: upperFirst(column.id),
|
||||
|
||||
@@ -265,7 +265,7 @@ function randomize() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-1 divide-y divide-(--ui-border-accented) w-full">
|
||||
<div class="flex-1 divide-y divide-accented w-full">
|
||||
<div class="flex items-center gap-2 px-4 py-3.5 overflow-x-auto">
|
||||
<UInput
|
||||
:model-value="(table?.tableApi?.getColumn('email')?.getFilterValue() as string)"
|
||||
@@ -313,7 +313,7 @@ function randomize() {
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
<div class="px-4 py-3.5 text-sm text-(--ui-text-muted)">
|
||||
<div class="px-4 py-3.5 text-sm text-muted">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@ const columns: TableColumn<User>[] = [{
|
||||
size: 'lg'
|
||||
}),
|
||||
h('div', undefined, [
|
||||
h('p', { class: 'font-medium text-(--ui-text-highlighted)' }, row.original.name),
|
||||
h('p', { class: 'font-medium text-highlighted' }, row.original.name),
|
||||
h('p', { class: '' }, `@${row.original.username}`)
|
||||
])
|
||||
])
|
||||
|
||||
@@ -95,7 +95,7 @@ const globalFilter = ref('45')
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col flex-1 w-full">
|
||||
<div class="flex px-4 py-3.5 border-b border-(--ui-border-accented)">
|
||||
<div class="flex px-4 py-3.5 border-b border-accented">
|
||||
<UInput
|
||||
v-model="globalFilter"
|
||||
class="max-w-sm"
|
||||
|
||||
@@ -162,7 +162,7 @@ const pagination = ref({
|
||||
class="flex-1"
|
||||
/>
|
||||
|
||||
<div class="flex justify-center border-t border-(--ui-border) pt-4">
|
||||
<div class="flex justify-center border-t border-default pt-4">
|
||||
<UPagination
|
||||
:default-page="(table?.tableApi?.getState().pagination.pageIndex || 0) + 1"
|
||||
:items-per-page="table?.tableApi?.getState().pagination.pageSize"
|
||||
|
||||
@@ -112,7 +112,7 @@ const expanded = ref({ 1: true })
|
||||
v-model:expanded="expanded"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:ui="{ tr: 'data-[expanded=true]:bg-(--ui-bg-elevated)/50' }"
|
||||
:ui="{ tr: 'data-[expanded=true]:bg-elevated/50' }"
|
||||
class="flex-1"
|
||||
>
|
||||
<template #expanded="{ row }">
|
||||
|
||||
@@ -122,7 +122,7 @@ function onSelect(row: TableRow<Payment>, e?: Event) {
|
||||
@select="onSelect"
|
||||
/>
|
||||
|
||||
<div class="px-4 py-3.5 border-t border-[var(--ui-border-accented)] text-sm text-[var(--ui-text-muted)]">
|
||||
<div class="px-4 py-3.5 border-t border-accented text-sm text-muted">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
|
||||
@@ -113,7 +113,7 @@ const rowSelection = ref({ 1: true })
|
||||
:columns="columns"
|
||||
/>
|
||||
|
||||
<div class="px-4 py-3.5 border-t border-(--ui-border-accented) text-sm text-(--ui-text-muted)">
|
||||
<div class="px-4 py-3.5 border-t border-accented text-sm text-muted">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,7 @@ function getDropdownActions(user: User): DropdownMenuItem[][] {
|
||||
<div class="flex items-center gap-3">
|
||||
<UAvatar :src="`https://i.pravatar.cc/120?img=${row.original.id}`" size="lg" :alt="`${row.original.name} avatar`" />
|
||||
<div>
|
||||
<p class="font-medium text-(--ui-text-highlighted)">
|
||||
<p class="font-medium text-highlighted">
|
||||
{{ row.original.name }}
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -28,7 +28,7 @@ const state = reactive({
|
||||
<template>
|
||||
<UTabs :items="items" variant="link" class="gap-4 w-full" :ui="{ trigger: 'flex-1' }">
|
||||
<template #account="{ item }">
|
||||
<p class="text-(--ui-text-muted) mb-4">
|
||||
<p class="text-muted mb-4">
|
||||
{{ item.description }}
|
||||
</p>
|
||||
|
||||
@@ -45,7 +45,7 @@ const state = reactive({
|
||||
</template>
|
||||
|
||||
<template #password="{ item }">
|
||||
<p class="text-(--ui-text-muted) mb-4">
|
||||
<p class="text-muted mb-4">
|
||||
{{ item.description }}
|
||||
</p>
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ const appConfig = useAppConfig()
|
||||
<UFormField
|
||||
label="toaster.duration"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-sm flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
|
||||
@@ -7,10 +7,10 @@ const appConfig = useAppConfig()
|
||||
<UFormField
|
||||
label="toaster.expand"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-sm flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
|
||||
@@ -10,10 +10,10 @@ const appConfig = useAppConfig()
|
||||
<UFormField
|
||||
label="toaster.position"
|
||||
size="sm"
|
||||
class="inline-flex ring ring-(--ui-border-accented) rounded-sm"
|
||||
class="inline-flex ring ring-accented rounded-sm"
|
||||
:ui="{
|
||||
wrapper: 'bg-(--ui-bg-elevated)/50 rounded-l-sm flex border-r border-(--ui-border-accented)',
|
||||
label: 'text-(--ui-text-muted) px-2 py-1.5',
|
||||
wrapper: 'bg-elevated/50 rounded-l-sm flex border-r border-accented',
|
||||
label: 'text-muted px-2 py-1.5',
|
||||
container: 'mt-0'
|
||||
}"
|
||||
>
|
||||
|
||||
@@ -20,7 +20,7 @@ const { width } = useElementSize(el)
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="isolate rounded-full relative circle w-full aspect-[1/1] p-8 sm:p-12 md:p-14 lg:p-10 xl:p-16 before:absolute before:inset-px before:bg-(--ui-bg) before:rounded-full z-(--level)"
|
||||
class="isolate rounded-full relative circle w-full aspect-[1/1] p-8 sm:p-12 md:p-14 lg:p-10 xl:p-16 before:absolute before:inset-px before:bg-default before:rounded-full z-(--level)"
|
||||
:class="{ 'animation-paused': paused }"
|
||||
:style="{
|
||||
'--duration': `${((level + 1) * 8)}s`,
|
||||
@@ -65,7 +65,7 @@ const { width } = useElementSize(el)
|
||||
:src="`https://ipx.nuxt.com/s_56x56/gh_avatar/${contributor.username}`"
|
||||
:srcset="`https://ipx.nuxt.com/s_112x112/gh_avatar/${contributor.username} 2x`"
|
||||
:alt="contributor.username"
|
||||
class="ring-2 ring-(--ui-border) lg:hover:ring-(--ui-border-inverted) transition rounded-full size-7"
|
||||
class="ring-2 ring-default lg:hover:ring-inverted transition rounded-full size-7"
|
||||
loading="lazy"
|
||||
>
|
||||
</NuxtLink>
|
||||
|
||||
@@ -69,7 +69,7 @@ function setBlackAsPrimary(value: boolean) {
|
||||
:variant="open ? 'soft' : 'ghost'"
|
||||
square
|
||||
aria-label="Color picker"
|
||||
:ui="{ leadingIcon: 'text-(--ui-primary)' }"
|
||||
:ui="{ leadingIcon: 'text-primary' }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ const slots = defineSlots<{
|
||||
variant="outline"
|
||||
:icon="icon"
|
||||
:label="label"
|
||||
class="capitalize ring-(--ui-border) rounded-sm text-[11px]"
|
||||
:class="[selected ? 'bg-(--ui-bg-elevated)' : 'hover:bg-(--ui-bg-elevated)/50']"
|
||||
class="capitalize ring-default rounded-sm text-[11px]"
|
||||
:class="[selected ? 'bg-elevated' : 'hover:bg-elevated/50']"
|
||||
>
|
||||
<template v-if="chip || !!slots.leading" #leading>
|
||||
<slot name="leading">
|
||||
|
||||
@@ -22,7 +22,7 @@ const navigation = inject<Ref<ContentNavigationItem[]>>('navigation')
|
||||
<span class="inline-flex items-center gap-0.5">
|
||||
{{ link.title }}
|
||||
|
||||
<sup v-if="link.module === 'ui-pro'" class="text-[8px] font-medium text-(--ui-primary)">PRO</sup>
|
||||
<sup v-if="link.module === 'ui-pro'" class="text-[8px] font-medium text-primary">PRO</sup>
|
||||
</span>
|
||||
</template>
|
||||
</UContentNavigation>
|
||||
|
||||
@@ -130,7 +130,7 @@ const communityLinks = computed(() => [{
|
||||
</template>
|
||||
|
||||
<template #title>
|
||||
{{ page.title }}<sup v-if="page.module === 'ui-pro'" class="ml-1 text-xs align-super font-medium text-(--ui-primary)">PRO</sup>
|
||||
{{ page.title }}<sup v-if="page.module === 'ui-pro'" class="ml-1 text-xs align-super font-medium text-primary">PRO</sup>
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
|
||||
@@ -82,7 +82,7 @@ onMounted(() => {
|
||||
:ui="{ title: 'text-balance', container: 'relative' }"
|
||||
>
|
||||
<template #top>
|
||||
<div class="absolute z-[-1] rounded-full bg-(--ui-primary) blur-[300px] size-60 sm:size-80 transform -translate-x-1/2 left-1/2 -translate-y-80" />
|
||||
<div class="absolute z-[-1] rounded-full bg-primary blur-[300px] size-60 sm:size-80 transform -translate-x-1/2 left-1/2 -translate-y-80" />
|
||||
</template>
|
||||
|
||||
<template #headline>
|
||||
@@ -97,7 +97,7 @@ onMounted(() => {
|
||||
/>
|
||||
</template>
|
||||
<template #title>
|
||||
Build beautiful UI with <span class="text-(--ui-primary)">{{ components!.length }}+</span> powerful components
|
||||
Build beautiful UI with <span class="text-primary">{{ components!.length }}+</span> powerful components
|
||||
</template>
|
||||
|
||||
<template #links>
|
||||
@@ -121,22 +121,22 @@ onMounted(() => {
|
||||
|
||||
<LazyStarsBg />
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
</UPageHero>
|
||||
|
||||
<div v-for="category in categories" :key="category.id">
|
||||
<div data-track-sticky class="group mb-4 sm:mb-6 lg:mb-8 sticky top-[calc(var(--ui-header-height)-1px)] bg-(--ui-bg)/75 backdrop-blur z-[1]">
|
||||
<div class="relative border-y border-(--ui-border) py-4 sm:not-group-[[data-stuck]]:py-6 lg:not-group-[[data-stuck]]:py-8 transition-all duration-300">
|
||||
<div data-track-sticky class="group mb-4 sm:mb-6 lg:mb-8 sticky top-[calc(var(--ui-header-height)-1px)] bg-default/75 backdrop-blur z-[1]">
|
||||
<div class="relative border-y border-default py-4 sm:not-group-[[data-stuck]]:py-6 lg:not-group-[[data-stuck]]:py-8 transition-all duration-300">
|
||||
<UContainer>
|
||||
<h2 class="relative text-pretty font-bold text-(--ui-text-highlighted) text-base sm:not-group-[[data-stuck]]:text-xl lg:not-group-[[data-stuck]]:text-2xl transition-all duration-300 ">
|
||||
<h2 class="relative text-pretty font-bold text-highlighted text-base sm:not-group-[[data-stuck]]:text-xl lg:not-group-[[data-stuck]]:text-2xl transition-all duration-300 ">
|
||||
<a :href="`#${category.id}`" class="group lg:not-group-[[data-stuck]]:ps-2 lg:not-group-[[data-stuck]]:-ms-2">
|
||||
<span class="absolute -ms-8 top-1 opacity-0 group-hover:opacity-100 group-focus:opacity-100 p-1 bg-(--ui-bg-elevated) hover:text-(--ui-primary) rounded-md hidden lg:not-group-[[data-stuck]]:flex text-(--ui-text-muted) transition">
|
||||
<span class="absolute -ms-8 top-1 opacity-0 group-hover:opacity-100 group-focus:opacity-100 p-1 bg-elevated hover:text-primary rounded-md hidden lg:not-group-[[data-stuck]]:flex text-muted transition">
|
||||
<UIcon name="i-lucide-hash" class="size-4 shrink-0" />
|
||||
</span>
|
||||
{{ category.title }}
|
||||
</a>
|
||||
</h2>
|
||||
<p class="text-pretty text-(--ui-text-muted) text-sm sm:not-group-[[data-stuck]]:text-base lg:not-group-[[data-stuck]]:text-lg mt-1 sm:not-group-[[data-stuck]]:mt-2 line-clamp-1 transition-all duration-300">
|
||||
<p class="text-pretty text-muted text-sm sm:not-group-[[data-stuck]]:text-base lg:not-group-[[data-stuck]]:text-lg mt-1 sm:not-group-[[data-stuck]]:mt-2 line-clamp-1 transition-all duration-300">
|
||||
{{ category.description }}
|
||||
</p>
|
||||
</UContainer>
|
||||
@@ -157,11 +157,11 @@ onMounted(() => {
|
||||
<template #title>
|
||||
<div class="flex items-center gap-0.5">
|
||||
<span>{{ component.title }}</span>
|
||||
<sup v-if="component.module === 'ui-pro'" class="text-[8px] font-medium text-(--ui-primary)">PRO</sup>
|
||||
<sup v-if="component.module === 'ui-pro'" class="text-[8px] font-medium text-primary">PRO</sup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="rounded-md border border-(--ui-border-muted) overflow-hidden aspect-[16/9]">
|
||||
<div class="rounded-md border border-muted overflow-hidden aspect-[16/9]">
|
||||
<UColorModeImage
|
||||
:light="`${component.path.replace('/components/', '/components/light/')}.png`"
|
||||
:dark="`${component.path.replace('/components/', '/components/dark/')}.png`"
|
||||
|
||||
@@ -27,7 +27,7 @@ features1:
|
||||
description: Start with essential components, or unlock Pro for complete blocks and templates.
|
||||
icon: i-lucide-files
|
||||
cta1:
|
||||
title: Everything you need in a [single file]{class="text-(--ui-primary)"}.
|
||||
title: Everything you need in a [single file]{class="text-primary"}.
|
||||
description: Design and development in perfect sync with our [Free](https://www.figma.com/community/file/1288455405058138934/nuxt-ui-v3-official-design-kit-free) and Pro files. Developers can implement designs faster, while designers work with production-ready components.
|
||||
section1:
|
||||
title: Customize in a few clicks to fit your needs
|
||||
@@ -181,7 +181,7 @@ pricing:
|
||||
# discount: $119
|
||||
billing_period: one-time payment
|
||||
billing_cycle: plus local taxes
|
||||
class: bg-(--ui-bg-elevated)/50
|
||||
class: bg-elevated/50
|
||||
features:
|
||||
- '**1 Designer**'
|
||||
- Nuxt UI & Nuxt UI Pro Components
|
||||
@@ -203,7 +203,7 @@ pricing:
|
||||
# discount: $279
|
||||
billing_period: one-time payment
|
||||
billing_cycle: plus local taxes
|
||||
class: bg-(--ui-bg-elevated)/50
|
||||
class: bg-elevated/50
|
||||
features:
|
||||
- '**Up to 20 Designers**'
|
||||
- Nuxt UI & Nuxt UI Pro Components
|
||||
|
||||
@@ -57,7 +57,7 @@ onMounted(async () => {
|
||||
<template>
|
||||
<div class="relative">
|
||||
<div id="cursor1" class="absolute z-10 pointer-events-none" :style="{ opacity: 0 }">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" class="absolute top-0 left-0 drop-shadow-[0_1px_2px_rgb(0,0,0,0.25)] text-white dark:text-(--ui-bg)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" class="absolute top-0 left-0 drop-shadow-[0_1px_2px_rgb(0,0,0,0.25)] text-inverted">
|
||||
<path
|
||||
fill="var(--ui-info)"
|
||||
stroke="currentColor"
|
||||
@@ -72,7 +72,7 @@ onMounted(async () => {
|
||||
</UBadge>
|
||||
</div>
|
||||
<div id="cursor2" class="absolute z-10 pointer-events-none" :style="{ opacity: 0 }">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" class="absolute top-0 left-0 drop-shadow-[0_1px_2px_rgb(0,0,0,0.25)] text-white dark:text-(--ui-bg)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" class="absolute top-0 left-0 drop-shadow-[0_1px_2px_rgb(0,0,0,0.25)] text-inverted">
|
||||
<path
|
||||
fill="var(--ui-success)"
|
||||
stroke="currentColor"
|
||||
@@ -99,7 +99,7 @@ onMounted(async () => {
|
||||
<template #description>
|
||||
<MDC :value="page.hero.description" unwrap="p" cache-key="figma-hero-description" />
|
||||
</template>
|
||||
<!-- <img src="/pro/figma/nuxt-ui-figma.png" alt="Screnshot of the Nuxt UI Figma design kit" class="w-full h-auto border border-(--ui-border) border-b-0"> -->
|
||||
<!-- <img src="/pro/figma/nuxt-ui-figma.png" alt="Screnshot of the Nuxt UI Figma design kit" class="w-full h-auto border border-default border-b-0"> -->
|
||||
<div class="relative">
|
||||
<video
|
||||
ref="video"
|
||||
@@ -126,10 +126,10 @@ onMounted(async () => {
|
||||
</div>
|
||||
</div>
|
||||
<Motion as-child :initial="{ height: 0 }" :animate="{ height: 'auto' }" :transition="{ delay: 0.2, duration: 1 }">
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
</Motion>
|
||||
</UPageHero>
|
||||
<UPageSection v-bind="page.features1" :ui="{ container: 'py-16 sm:py-16 lg:py-16', features: 'mt-0' }" class="border-y border-(--ui-border)" />
|
||||
<UPageSection v-bind="page.features1" :ui="{ container: 'py-16 sm:py-16 lg:py-16', features: 'mt-0' }" class="border-y border-default" />
|
||||
<UPageCTA
|
||||
v-if="page.cta1"
|
||||
variant="naked"
|
||||
@@ -138,7 +138,7 @@ onMounted(async () => {
|
||||
wrapper: 'grid grid-cols-1 lg:grid-cols-2',
|
||||
description: 'lg:mt-0' }"
|
||||
orientation="horizontal"
|
||||
class="rounded-none bg-gradient-to-b from-(--ui-bg-muted) to-(--ui-bg)"
|
||||
class="rounded-none bg-gradient-to-b from-elevated/50 to-default"
|
||||
>
|
||||
<template #title>
|
||||
<MDC :value="page.cta1.title" unwrap="p" cache-key="figma-cta-1-title" />
|
||||
@@ -192,8 +192,8 @@ onMounted(async () => {
|
||||
<template #description>
|
||||
<MDC :value="page.section4.description" unwrap="p" cache-key="figma-section-4-description" />
|
||||
</template>
|
||||
<div aria-hidden="true" class="absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 items-start justify-center border border-(--ui-border) border-b-0 sm:divide-x divide-y lg:divide-y-0 divide-(--ui-border)">
|
||||
<div aria-hidden="true" class="absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 items-start justify-center border border-default border-b-0 sm:divide-x divide-y lg:divide-y-0 divide-default">
|
||||
<li v-for="(step, index) in page?.section4.steps" :key="step.title" class="flex flex-col gap-y-4 justify-start group h-full p-4">
|
||||
<NuxtImg
|
||||
v-if="step.image"
|
||||
@@ -205,14 +205,14 @@ onMounted(async () => {
|
||||
<h2 class="font-semibold inline-flex items-center gap-x-1">
|
||||
<UBadge :label="index + 1" size="sm" color="neutral" variant="subtle" class="rounded-full tabular-nums" /> {{ step.title }}
|
||||
</h2>
|
||||
<p class="text-(--ui-text-muted) text-sm">
|
||||
<p class="text-muted text-sm">
|
||||
{{ step.description }}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</UPageSection>
|
||||
<UPageSection v-bind="page.features2" :ui="{ container: 'py-16 sm:py-16 lg:py-16', features: 'mt-0' }" class="border-y border-(--ui-border)" />
|
||||
<UPageSection v-bind="page.features2" :ui="{ container: 'py-16 sm:py-16 lg:py-16', features: 'mt-0' }" class="border-y border-default" />
|
||||
<UPageSection
|
||||
v-if="page.pricing"
|
||||
:title="page.pricing.title"
|
||||
@@ -226,7 +226,7 @@ onMounted(async () => {
|
||||
wrapper: 'sm:pl-8'
|
||||
}"
|
||||
>
|
||||
<div aria-hidden="true" class="absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<UPricingPlans compact class="-space-x-px">
|
||||
<UPricingPlan
|
||||
v-for="(plan, index) in page.pricing.plans"
|
||||
@@ -246,8 +246,8 @@ onMounted(async () => {
|
||||
>
|
||||
<template #features>
|
||||
<li v-for="(feature, i) in plan.features" :key="i" class="flex items-center gap-2 min-w-0">
|
||||
<UIcon name="i-lucide-circle-check" class="size-5 shrink-0 text-(--ui-primary)" />
|
||||
<MDC :value="feature" unwrap="p" tag="span" class="text-sm truncate text-(--ui-text-accented)" :cache-key="`figma-pricing-plan-${index}-feature-${i}`" />
|
||||
<UIcon name="i-lucide-circle-check" class="size-5 shrink-0 text-primary" />
|
||||
<MDC :value="feature" unwrap="p" tag="span" class="text-sm truncate text-accented" :cache-key="`figma-pricing-plan-${index}-feature-${i}`" />
|
||||
</li>
|
||||
</template>
|
||||
<template #button>
|
||||
@@ -278,7 +278,7 @@ onMounted(async () => {
|
||||
</UPageMarquee>
|
||||
</UPageCTA>
|
||||
<UPageSection v-bind="page.faq" :ui="{ container: 'relative' }">
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<UPageAccordion
|
||||
multiple
|
||||
:items="(page.faq.items as any[])"
|
||||
|
||||
@@ -48,7 +48,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
}"
|
||||
>
|
||||
<template #title>
|
||||
The Intuitive <br> <span class="text-(--ui-primary)">Vue UI Library</span>
|
||||
The Intuitive <br> <span class="text-primary">Vue UI Library</span>
|
||||
</template>
|
||||
<template #description>
|
||||
{{ page.hero.description }}
|
||||
@@ -81,14 +81,14 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
pause-on-hover
|
||||
:overlay="false"
|
||||
:ui="{
|
||||
root: '[--gap:--spacing(4)] [--duration:40s] border-(--ui-border) absolute w-full left-0 border-y lg:border-x lg:border-y-0 lg:w-[calc(50%-6px)] 2xl:w-[320px] lg:flex-col',
|
||||
root: '[--gap:--spacing(4)] [--duration:40s] border-default absolute w-full left-0 border-y lg:border-x lg:border-y-0 lg:w-[calc(50%-6px)] 2xl:w-[320px] lg:flex-col',
|
||||
content: 'lg:w-auto lg:flex-col lg:animate-[marquee-vertical_var(--duration)_linear_infinite] lg:rtl:animate-[marquee-vertical-rtl_var(--duration)_linear_infinite] lg:h-[fit-content]'
|
||||
}"
|
||||
>
|
||||
<ULink
|
||||
v-for="component of components?.slice(0, 10)"
|
||||
:key="component.path"
|
||||
class="relative group/link aspect-video border-(--ui-border) w-[290px] xl:w-[330px] 2xl:w-[320px] 2xl:p-2 2xl:border-y"
|
||||
class="relative group/link aspect-video border-default w-[290px] xl:w-[330px] 2xl:w-[320px] 2xl:p-2 2xl:border-y"
|
||||
:to="component.path"
|
||||
>
|
||||
<UColorModeImage
|
||||
@@ -98,7 +98,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
width="290"
|
||||
height="163"
|
||||
format="webp"
|
||||
class="hover:scale-105 lg:hover:scale-110 transition-transform aspect-video w-full border-x lg:border-x-0 lg:border-y border-(--ui-border) 2xl:border-y-0"
|
||||
class="hover:scale-105 lg:hover:scale-110 transition-transform aspect-video w-full border-x lg:border-x-0 lg:border-y border-default 2xl:border-y-0"
|
||||
loading="lazy"
|
||||
/>
|
||||
<UBadge color="neutral" variant="outline" size="md" :label="component.title" class="hidden lg:block absolute mx-auto top-4 left-6 xl:left-4 group-hover/link:opacity-100 opacity-0 transition-all duration-300 pointer-events-none -translate-y-2 group-hover/link:translate-y-0" />
|
||||
@@ -110,14 +110,14 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
reverse
|
||||
:overlay="false"
|
||||
:ui="{
|
||||
root: '[--gap:--spacing(4)] [--duration:40s] border-(--ui-border) absolute w-full mt-[180px] left-0 border-y lg:mt-auto lg:left-auto lg:border-y-0 lg:border-x lg:w-[calc(50%-6px)] 2xl:w-[320px] lg:right-0 lg:flex-col',
|
||||
root: '[--gap:--spacing(4)] [--duration:40s] border-default absolute w-full mt-[180px] left-0 border-y lg:mt-auto lg:left-auto lg:border-y-0 lg:border-x lg:w-[calc(50%-6px)] 2xl:w-[320px] lg:right-0 lg:flex-col',
|
||||
content: 'lg:w-auto lg:flex-col lg:animate-[marquee-vertical_var(--duration)_linear_infinite] lg:rtl:animate-[marquee-vertical-rtl_var(--duration)_linear_infinite] lg:h-[fit-content] lg:[animation-direction:reverse]'
|
||||
}"
|
||||
>
|
||||
<ULink
|
||||
v-for="component of components?.slice(10, 20)"
|
||||
:key="component.path"
|
||||
class="relative group/link aspect-video border-(--ui-border) w-[290px] xl:w-[330px] 2xl:w-[320px] 2xl:p-2 2xl:border-y"
|
||||
class="relative group/link aspect-video border-default w-[290px] xl:w-[330px] 2xl:w-[320px] 2xl:p-2 2xl:border-y"
|
||||
:to="component.path"
|
||||
>
|
||||
<UColorModeImage
|
||||
@@ -127,7 +127,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
width="290"
|
||||
height="163"
|
||||
format="webp"
|
||||
class="hover:scale-105 lg:hover:scale-110 transition-transform aspect-video w-full border-x lg:border-x-0 lg:border-y border-(--ui-border) 2xl:border-y-0"
|
||||
class="hover:scale-105 lg:hover:scale-110 transition-transform aspect-video w-full border-x lg:border-x-0 lg:border-y border-default 2xl:border-y-0"
|
||||
loading="lazy"
|
||||
/>
|
||||
<UBadge color="neutral" variant="outline" size="md" :label="component.title" class="hidden lg:block absolute mx-auto top-4 left-6 xl:left-4 group-hover/link:opacity-100 opacity-0 transition-all duration-300 pointer-events-none -translate-y-2 group-hover/link:translate-y-0" />
|
||||
@@ -168,11 +168,11 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
<UIcon :name="feature.icon" class="size-5 shrink-0" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h2 class="font-medium text-(--ui-text-highlighted) inline-flex items-center gap-x-1">
|
||||
<h2 class="font-medium text-highlighted inline-flex items-center gap-x-1">
|
||||
{{ feature.title }}
|
||||
<UIcon v-if="feature.to" name="i-lucide-arrow-right" class="size-4 shrink-0 opacity-0 group-hover:opacity-100 transition-all duration-200 -translate-x-1 group-hover:translate-x-0" />
|
||||
</h2>
|
||||
<p class="text-sm text-(--ui-text-muted)">
|
||||
<p class="text-sm text-muted">
|
||||
{{ feature.description }}
|
||||
</p>
|
||||
</div>
|
||||
@@ -215,33 +215,33 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
:links="page.community.links"
|
||||
orientation="horizontal"
|
||||
:ui="{ features: 'flex items-center gap-4 lg:gap-8' }"
|
||||
class="border-b border-(--ui-border)"
|
||||
class="border-b border-default"
|
||||
>
|
||||
<template #features>
|
||||
<li>
|
||||
<NuxtLink to="https://npm.chart.dev/@nuxt/ui" target="_blank" class="min-w-0">
|
||||
<p class="text-4xl font-semibold text-(--ui-text-highlighted) truncate">
|
||||
<p class="text-4xl font-semibold text-highlighted truncate">
|
||||
{{ format(module?.stats?.downloads ?? 0) }}+
|
||||
</p>
|
||||
<p class="text-(--ui-text-muted) text-sm truncate">monthly downloads</p>
|
||||
<p class="text-muted text-sm truncate">monthly downloads</p>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<NuxtLink to="https://github.com/nuxt/ui" target="_blank" class="min-w-0">
|
||||
<p class="text-4xl font-semibold text-(--ui-text-highlighted) truncate">
|
||||
<p class="text-4xl font-semibold text-highlighted truncate">
|
||||
{{ format(module?.stats?.stars ?? 0) }}+
|
||||
</p>
|
||||
<p class="text-(--ui-text-muted) text-sm truncate">GitHub stars</p>
|
||||
<p class="text-muted text-sm truncate">GitHub stars</p>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<NuxtLink to="https://github.com/nuxt/ui/graphs/contributors" target="_blank" class="min-w-0">
|
||||
<p class="text-4xl font-semibold text-(--ui-text-highlighted) truncate">
|
||||
<p class="text-4xl font-semibold text-highlighted truncate">
|
||||
175+
|
||||
</p>
|
||||
<p class="text-(--ui-text-muted) text-sm truncate">Contributors</p>
|
||||
<p class="text-muted text-sm truncate">Contributors</p>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</template>
|
||||
@@ -253,10 +253,10 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
|
||||
<UPageSection :ui="{ container: 'relative !pb-0 overflow-hidden' }">
|
||||
<template #title>
|
||||
Build faster with Nuxt UI <span class="text-(--ui-primary)">Pro</span>.
|
||||
Build faster with Nuxt UI <span class="text-primary">Pro</span>.
|
||||
</template>
|
||||
<template #description>
|
||||
A collection of premium Vue components, composables and utils built on top of Nuxt UI. <br> Focused on structure and layout, these <span class="text-(--ui-text)">responsive components</span> are designed to be the perfect <span class="text-(--ui-text)">building blocks for your next idea</span>.
|
||||
A collection of premium Vue components, composables and utils built on top of Nuxt UI. <br> Focused on structure and layout, these <span class="text-default">responsive components</span> are designed to be the perfect <span class="text-default">building blocks for your next idea</span>.
|
||||
</template>
|
||||
<template #links>
|
||||
<UButton to="/pro" size="lg">
|
||||
@@ -269,8 +269,8 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
|
||||
<LazyStarsBg />
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div class="relative h-[400px] border border-(--ui-border) bg-(--ui-bg-muted) overflow-hidden border-x-0 -mx-4 sm:-mx-6 lg:mx-0 lg:border-x w-screen lg:w-full">
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div class="relative h-[400px] border border-default bg-muted overflow-hidden border-x-0 -mx-4 sm:-mx-6 lg:mx-0 lg:border-x w-screen lg:w-full">
|
||||
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -left-[100px] -top-[300px] h-[940px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
|
||||
<img
|
||||
v-for="i in 4"
|
||||
@@ -280,7 +280,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
height="258"
|
||||
loading="lazy"
|
||||
:alt="`Nuxt UI Pro Screenshot ${i}`"
|
||||
class="aspect-video border border-(--ui-border) rounded-lg bg-white"
|
||||
class="aspect-video border border-default rounded-lg bg-white"
|
||||
>
|
||||
</UPageMarquee>
|
||||
<UPageMarquee orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -top-[400px] left-[480px] h-[1160px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
|
||||
@@ -292,7 +292,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
height="258"
|
||||
loading="lazy"
|
||||
:alt="`Nuxt UI Pro Screenshot ${i}`"
|
||||
class="aspect-video border border-(--ui-border) rounded-lg bg-white"
|
||||
class="aspect-video border border-default rounded-lg bg-white"
|
||||
>
|
||||
</UPageMarquee>
|
||||
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: 'hidden md:flex [--duration:40s] absolute w-[460px] -top-[300px] left-[1020px] h-[1060px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
|
||||
@@ -304,7 +304,7 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
height="258"
|
||||
loading="lazy"
|
||||
:alt="`Nuxt UI Pro Screenshot ${i}`"
|
||||
class="aspect-video border border-(--ui-border) rounded-lg bg-white"
|
||||
class="aspect-video border border-default rounded-lg bg-white"
|
||||
>
|
||||
</UPageMarquee>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ title: Nuxt UI Pro Pricing
|
||||
description: Start for free in development mode, then upgrade to a paid plan to unlock the full features of Nuxt UI Pro when you are ready to launch.
|
||||
pricing:
|
||||
headline: Pricing
|
||||
title: Upgrade to Nuxt UI [Pro]{class="text-(--ui-primary)"}.
|
||||
title: Upgrade to Nuxt UI [Pro]{class="text-primary"}.
|
||||
description: On top of 40+ open source components from Nuxt UI, Pro gives you access to 50+ premium Vue components to create beautiful & responsive Nuxt applications in minutes. It includes all primitives to build landing pages, documentations, blogs, dashboards or entire SaaS products.
|
||||
freePlan:
|
||||
title: Free in development
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
title: Build faster with Nuxt UI Pro.
|
||||
description: A collection of premium Vue components, composables and utils built on top of Nuxt UI, oriented on structure and layout and designed to be used as building blocks for your application.
|
||||
hero:
|
||||
title: Build faster with Nuxt UI [Pro]{class="text-(--ui-primary)"}.
|
||||
description: A collection of premium Vue components, composables and utils built on top of Nuxt UI. :br Focused on structure and layout, these [responsive components]{class="text-(--ui-text)"} are designed to be the perfect [building blocks for your next idea]{class="text-(--ui-text)"}.
|
||||
title: Build faster with Nuxt UI [Pro]{class="text-primary"}.
|
||||
description: A collection of premium Vue components, composables and utils built on top of Nuxt UI. :br Focused on structure and layout, these [responsive components]{class="text-default"} are designed to be the perfect [building blocks for your next idea]{class="text-default"}.
|
||||
links:
|
||||
- label: Buy a license
|
||||
size: xl
|
||||
@@ -62,7 +62,7 @@ testimonial:
|
||||
# avatar:
|
||||
# src: https://github.com/benjamincanac.png
|
||||
mainSection:
|
||||
title: Meet the [Pro Components]{class="text-(--ui-primary)"}.
|
||||
title: Meet the [Pro Components]{class="text-primary"}.
|
||||
description: Code with 50+ components and sections of Nuxt UI Pro to build your next application by reducing the amount of code you need to write.
|
||||
sections:
|
||||
- title: The freedom to build anything
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
title: Official Nuxt UI Pro Templates
|
||||
description: 'Ready to use templates powered by our premium Vue components and Nuxt Content. The templates are responsive, accessible and easy to customize so you can get started in no time.'
|
||||
hero:
|
||||
title: Ship [in minutes]{.text-(--ui-primary)} with :br Nuxt UI Pro Templates
|
||||
title: Ship [in minutes]{.text-primary} with :br Nuxt UI Pro Templates
|
||||
description: 'Ready to use templates powered by our premium Vue components and Nuxt Content.<br class="hidden lg:block"> The templates are responsive, accessible and easy to customize so you can get started in no time.'
|
||||
navigation: false
|
||||
links:
|
||||
|
||||
@@ -73,9 +73,9 @@ onMounted(() => {
|
||||
<UPageHero headline="License Activation" :title="title" :description="description" :ui="{ container: 'relative overflow-hidden', wrapper: 'lg:px-12', description: 'text-pretty' }">
|
||||
<LazyStarsBg />
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
|
||||
<div class="px-4 py-10 lg:border border-(--ui-border) bg-(--ui-bg)">
|
||||
<div class="px-4 py-10 lg:border border-default bg-default">
|
||||
<div class="max-w-xl mx-auto">
|
||||
<UForm
|
||||
:schema="schema"
|
||||
|
||||
@@ -35,9 +35,9 @@ useSeoMeta({
|
||||
<LazyStarsBg />
|
||||
|
||||
<Motion as-child :initial="{ height: 0 }" :animate="{ height: 'auto' }" :transition="{ delay: 0.2, duration: 1 }">
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
</Motion>
|
||||
<div class="relative h-[400px] border border-(--ui-border) bg-(--ui-bg-muted) overflow-hidden border-x-0 -mx-4 sm:-mx-6 lg:mx-0 lg:border-x w-screen lg:w-full">
|
||||
<div class="relative h-[400px] border border-default bg-muted overflow-hidden border-x-0 -mx-4 sm:-mx-6 lg:mx-0 lg:border-x w-screen lg:w-full">
|
||||
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -left-[100px] -top-[300px] h-[940px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
|
||||
<img
|
||||
v-for="i in 4"
|
||||
@@ -46,7 +46,7 @@ useSeoMeta({
|
||||
width="460"
|
||||
height="258"
|
||||
:alt="`Nuxt UI Pro Screenshot ${i}`"
|
||||
class="aspect-video border border-(--ui-border) rounded-lg bg-white"
|
||||
class="aspect-video border border-default rounded-lg bg-white"
|
||||
>
|
||||
</UPageMarquee>
|
||||
<UPageMarquee orientation="vertical" :overlay="false" :ui="{ root: '[--duration:40s] absolute w-[460px] -top-[400px] left-[480px] h-[1160px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
|
||||
@@ -57,7 +57,7 @@ useSeoMeta({
|
||||
width="460"
|
||||
height="258"
|
||||
:alt="`Nuxt UI Pro Screenshot ${i}`"
|
||||
class="aspect-video border border-(--ui-border) rounded-lg bg-white"
|
||||
class="aspect-video border border-default rounded-lg bg-white"
|
||||
>
|
||||
</UPageMarquee>
|
||||
<UPageMarquee reverse orientation="vertical" :overlay="false" :ui="{ root: 'hidden md:flex [--duration:40s] absolute w-[460px] -top-[300px] left-[1020px] h-[1060px] transform-3d rotate-x-55 rotate-y-0 rotate-z-30' }">
|
||||
@@ -68,7 +68,7 @@ useSeoMeta({
|
||||
width="460"
|
||||
height="258"
|
||||
:alt="`Nuxt UI Pro Screenshot ${i}`"
|
||||
class="aspect-video border border-(--ui-border) rounded-lg bg-white"
|
||||
class="aspect-video border border-default rounded-lg bg-white"
|
||||
>
|
||||
</UPageMarquee>
|
||||
</div>
|
||||
@@ -101,10 +101,10 @@ useSeoMeta({
|
||||
container: 'relative',
|
||||
wrapper: 'sm:px-8'
|
||||
}"
|
||||
class="border-t border-(--ui-border)"
|
||||
class="border-t border-default"
|
||||
>
|
||||
<Motion as-child :initial="{ height: 0 }" :while-in-view="{ height: 'auto' }" :transition="{ delay: 0.4, duration: 1 }">
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
</Motion>
|
||||
</UPageSection>
|
||||
|
||||
@@ -116,7 +116,7 @@ useSeoMeta({
|
||||
wrapper: 'grid grid-cols-1 lg:grid-cols-2',
|
||||
description: 'lg:mt-0' }"
|
||||
orientation="horizontal"
|
||||
class="rounded-none border-t border-(--ui-border) bg-gradient-to-b from-(--ui-bg-elevated)/50 to-(--ui-bg)"
|
||||
class="rounded-none border-t border-default bg-gradient-to-b from-elevated/50 to-default"
|
||||
>
|
||||
<template #title>
|
||||
<MDC :value="page.mainSection.title" tag="span" unwrap="p" cache-key="pro-main-section-title" />
|
||||
@@ -134,7 +134,7 @@ useSeoMeta({
|
||||
:reverse="section.reverse"
|
||||
:features="section.features"
|
||||
orientation="horizontal"
|
||||
:class="{ 'border-b border-(--ui-border)': index === page.sections.length - 1 }"
|
||||
:class="{ 'border-b border-default': index === page.sections.length - 1 }"
|
||||
:ui="{
|
||||
container: index === 0 ? 'pb-0 sm:pb-0 lg:pb-0 py-16 sm:py-16 lg:py-16' : ''
|
||||
}"
|
||||
@@ -145,10 +145,10 @@ useSeoMeta({
|
||||
<UPageSection
|
||||
id="templates"
|
||||
v-bind="page.templates"
|
||||
class="overflow-hidden border-x border-(--ui-border)"
|
||||
class="overflow-hidden border-x border-default"
|
||||
:ui="{ container: 'relative' }"
|
||||
>
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<UCarousel
|
||||
v-slot="{ item }"
|
||||
loop
|
||||
@@ -160,7 +160,7 @@ useSeoMeta({
|
||||
:ui="{
|
||||
item: 'basis-1/2',
|
||||
container: 'py-2',
|
||||
viewport: 'border-x border-(--ui-border)',
|
||||
viewport: 'border-x border-default',
|
||||
arrows: 'hidden 2xl:block'
|
||||
}"
|
||||
>
|
||||
@@ -181,7 +181,7 @@ useSeoMeta({
|
||||
:light="item.thumbnail.light"
|
||||
:dark="item.thumbnail.dark"
|
||||
:alt="item.title"
|
||||
class="rounded-lg w-full border border-(--ui-border) aspect-video"
|
||||
class="rounded-lg w-full border border-default aspect-video"
|
||||
loading="lazy"
|
||||
/>
|
||||
</UPageCard>
|
||||
|
||||
@@ -29,13 +29,13 @@ useSeoMeta({
|
||||
|
||||
<LazyStarsBg />
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
|
||||
<div class="flex flex-col bg-(--ui-bg) gap-8 lg:gap-0">
|
||||
<div class="flex flex-col bg-default gap-8 lg:gap-0">
|
||||
<UPricingPlan
|
||||
v-bind="page.pricing.freePlan"
|
||||
variant="naked"
|
||||
class="lg:rounded-none border-x border-(--ui-border) border-t border-b lg:border-b-0"
|
||||
class="lg:rounded-none border-x border-default border-t border-b lg:border-b-0"
|
||||
/>
|
||||
<UPricingPlans compact>
|
||||
<UPricingPlan
|
||||
@@ -48,7 +48,7 @@ useSeoMeta({
|
||||
:billing-period="plan.billing_period"
|
||||
:billing-cycle="plan.billing_cycle"
|
||||
:variant="plan.highlight ? 'soft' : 'outline'"
|
||||
:class="['lg:rounded-none', { 'border-2 lg:border lg:border-x-0 border-(--ui-primary) lg:border-(--ui-border)': plan.highlight }]"
|
||||
:class="['lg:rounded-none', { 'border-2 lg:border lg:border-x-0 border-primary lg:border-default': plan.highlight }]"
|
||||
:features="plan.features"
|
||||
:button="plan.button"
|
||||
/>
|
||||
@@ -58,12 +58,12 @@ useSeoMeta({
|
||||
variant="naked"
|
||||
:billing-period="page.pricing.figma.billing_period"
|
||||
:billing-cycle="page.pricing.figma.billing_cycle"
|
||||
class="lg:rounded-none border lg:border-y-0 border-(--ui-border)"
|
||||
class="lg:rounded-none border lg:border-y-0 border-default"
|
||||
>
|
||||
<template #features>
|
||||
<li v-for="(feature, index) in page.pricing.figma.features" :key="index" class="flex items-center gap-2 min-w-0">
|
||||
<UIcon name="i-lucide-circle-check" class="size-5 text-(--ui-primary) shrink-0" />
|
||||
<MDC :value="feature" unwrap="p" class="text-sm truncate text-(--ui-text-toned)" :cache-key="`pro-pricing-figma-feature-${index}`" />
|
||||
<UIcon name="i-lucide-circle-check" class="size-5 text-primary shrink-0" />
|
||||
<MDC :value="feature" unwrap="p" class="text-sm truncate text-toned" :cache-key="`pro-pricing-figma-feature-${index}`" />
|
||||
</li>
|
||||
</template>
|
||||
</UPricingPlan>
|
||||
@@ -73,7 +73,7 @@ useSeoMeta({
|
||||
<UPageSection
|
||||
id="testimonials"
|
||||
v-bind="page.testimonials"
|
||||
class="border-y border-(--ui-border)"
|
||||
class="border-y border-default"
|
||||
>
|
||||
<UPageMarquee pause-on-hover :ui="{ root: '[--duration:40s]' }">
|
||||
<img
|
||||
@@ -110,7 +110,7 @@ useSeoMeta({
|
||||
class="scroll-mt-(--ui-header-height)"
|
||||
:ui="{ container: 'relative' }"
|
||||
>
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<UPageAccordion
|
||||
multiple
|
||||
:items="(page.faq.items as any[])"
|
||||
|
||||
@@ -20,7 +20,7 @@ useSeoMeta({
|
||||
<UPageHero :links="page.links" :ui="{ container: 'relative' }">
|
||||
<LazyStarsBg />
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
|
||||
<template #title>
|
||||
<MDC :value="page.hero.title" unwrap="p" cache-key="pro-templates-hero-title" />
|
||||
@@ -38,10 +38,10 @@ useSeoMeta({
|
||||
:links="template.links"
|
||||
:features="template.features"
|
||||
orientation="horizontal"
|
||||
class="lg:border-t border-(--ui-border)"
|
||||
class="lg:border-t border-default"
|
||||
:ui="{
|
||||
title: 'lg:text-4xl',
|
||||
wrapper: 'lg:py-16 lg:border-r border-(--ui-border) order-last lg:pr-16',
|
||||
wrapper: 'lg:py-16 lg:border-r border-default order-last lg:pr-16',
|
||||
container: 'lg:py-0',
|
||||
links: 'gap-x-3'
|
||||
}"
|
||||
@@ -50,12 +50,12 @@ useSeoMeta({
|
||||
<MDC :value="template.description" unwrap="p" :cache-key="`pro-templates-${index}-description`" />
|
||||
</template>
|
||||
|
||||
<div class="lg:border-x border-(--ui-border) h-full flex items-center lg:bg-(--ui-bg-muted)/20">
|
||||
<div class="lg:border-x border-default h-full flex items-center lg:bg-muted/20">
|
||||
<Motion class="flex-1" :initial="{ opacity: 0, transform: 'translateY(10px)' }" :while-in-view="{ opacity: 1, transform: 'translateY(0px)' }" :in-view-options="{ once: true }" :transition="{ duration: 0.5, delay: 0.2 }">
|
||||
<UColorModeImage
|
||||
v-if="template.thumbnail"
|
||||
v-bind="template.thumbnail"
|
||||
class="w-full h-auto border lg:border-y lg:border-x-0 border-(--ui-border) rounded-sm lg:rounded-none"
|
||||
class="w-full h-auto border lg:border-y lg:border-x-0 border-default rounded-sm lg:rounded-none"
|
||||
:alt="`Template ${index} thumbnail`"
|
||||
width="656"
|
||||
height="369"
|
||||
|
||||
@@ -29,19 +29,19 @@ defineOgImageComponent('Docs', {
|
||||
}"
|
||||
>
|
||||
<template #top>
|
||||
<div class="absolute z-[-1] rounded-full bg-(--ui-primary) blur-[300px] size-60 sm:size-80 transform -translate-x-1/2 left-1/2 -translate-y-80" />
|
||||
<div class="absolute z-[-1] rounded-full bg-primary blur-[300px] size-60 sm:size-80 transform -translate-x-1/2 left-1/2 -translate-y-80" />
|
||||
</template>
|
||||
|
||||
<LazyStarsBg />
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-default inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
|
||||
<div class="border-l border-t border-(--ui-border)">
|
||||
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 items-start justify-center divide-y divide-x divide-(--ui-border)">
|
||||
<div class="border-l border-t border-default">
|
||||
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 items-start justify-center divide-y divide-x divide-default">
|
||||
<li
|
||||
v-for="item in page.items"
|
||||
:key="item.name"
|
||||
class="group relative flex items-center justify-center flex-1 size-full p-2 last:border-r last:border-b border-(--ui-border) overflow-hidden"
|
||||
class="group relative flex items-center justify-center flex-1 size-full p-2 last:border-r last:border-b border-default overflow-hidden"
|
||||
>
|
||||
<NuxtLink class="inset-0 absolute" :to="item.url" target="_blank">
|
||||
<span class="sr-only">Go to {{ item.name }}</span>
|
||||
|
||||
@@ -41,7 +41,7 @@ const icons = {
|
||||
:ui="{ title: 'text-balance', container: 'relative' }"
|
||||
>
|
||||
<template #top>
|
||||
<div class="absolute z-[-1] rounded-full bg-(--ui-primary) blur-[300px] size-60 sm:size-80 transform -translate-x-1/2 left-1/2 -translate-y-80" />
|
||||
<div class="absolute z-[-1] rounded-full bg-primary blur-[300px] size-60 sm:size-80 transform -translate-x-1/2 left-1/2 -translate-y-80" />
|
||||
</template>
|
||||
|
||||
<LazyStarsBg />
|
||||
@@ -58,7 +58,7 @@ const icons = {
|
||||
container: 'gap-y-4 lg:p-8',
|
||||
leading: 'flex justify-center',
|
||||
title: 'text-center',
|
||||
description: 'text-center text-(--ui-text-muted)'
|
||||
description: 'text-center text-muted'
|
||||
}"
|
||||
variant="subtle"
|
||||
>
|
||||
@@ -126,7 +126,7 @@ const icons = {
|
||||
container: 'gap-y-2',
|
||||
leading: 'flex justify-center',
|
||||
title: 'text-center',
|
||||
description: 'text-center text-(--ui-text-muted)'
|
||||
description: 'text-center text-muted'
|
||||
}"
|
||||
>
|
||||
<template #leading>
|
||||
|
||||
@@ -195,10 +195,10 @@ You can also use the new [design tokens](/getting-started/theme#neutral-palette)
|
||||
```diff
|
||||
<template>
|
||||
- <p class="text-gray-500 dark:text-gray-400" />
|
||||
+ <p class="text-(--ui-text-muted)" />
|
||||
+ <p class="text-muted" />
|
||||
|
||||
- <p class="text-gray-900 dark:text-white" />
|
||||
+ <p class="text-(--ui-text-highlighted)" />
|
||||
+ <p class="text-highlighted" />
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
@@ -118,17 +118,7 @@ Learn more about automatic content detection in the detecting classes in source
|
||||
|
||||
## Design system
|
||||
|
||||
Nuxt UI extends Tailwind CSS's theming capabilities, providing a flexible design system with pre-configured color aliases and CSS variables. This allows for easy customization and quick adaptation of the UI to your brand's aesthetic.
|
||||
|
||||
### Colors
|
||||
|
||||
::framework-only
|
||||
#nuxt
|
||||
Nuxt UI leverages Nuxt [App Config](https://nuxt.com/docs/guide/directory-structure/app-config#app-config-file) to provide customizable color aliases based on [Tailwind CSS colors](https://tailwindcss.com/docs/customizing-colors#color-palette-reference):
|
||||
|
||||
#vue
|
||||
Nuxt UI leverages Vite config to provide customizable color aliases based on [Tailwind CSS colors](https://tailwindcss.com/docs/customizing-colors#color-palette-reference):
|
||||
::
|
||||
Nuxt UI extends Tailwind CSS's theming capabilities, providing a flexible design system with pre-configured color aliases based on [Tailwind CSS colors](https://tailwindcss.com/docs/customizing-colors#color-palette-reference). This allows for easy customization and quick adaptation of the UI to your brand's aesthetic.
|
||||
|
||||
| Color | Default | Description |
|
||||
| --- | --- | --- |
|
||||
@@ -140,10 +130,27 @@ Nuxt UI leverages Vite config to provide customizable color aliases based on [Ta
|
||||
| `error`{color="error"} | `red` | Used for form error validation states. |
|
||||
| `neutral` | `slate` | Neutral color for backgrounds, text, etc. |
|
||||
|
||||
These colors are used to style the components but also to generate the `color` props:
|
||||
|
||||
::component-code{slug="button"}
|
||||
---
|
||||
props:
|
||||
color: primary
|
||||
slots:
|
||||
default: Button
|
||||
---
|
||||
::
|
||||
|
||||
::note
|
||||
Try the :prose-icon{name="i-lucide-swatch-book" class="text-primary"} theme picker in the header above to change `primary` and `neutral` colors.
|
||||
::
|
||||
|
||||
### Configuration
|
||||
|
||||
::framework-only
|
||||
#nuxt
|
||||
:::div
|
||||
You can configure these color aliases at runtime in your `app.config.ts` file under the `ui.colors` key, allowing for dynamic theme customization without requiring an application rebuild:
|
||||
You can configure these color aliases at runtime in your [`app.config.ts`](https://nuxt.com/docs/guide/directory-structure/app-config#app-config-file) file under the `ui.colors` key, allowing for dynamic theme customization without requiring an application rebuild:
|
||||
|
||||
```ts [app.config.ts]
|
||||
export default defineAppConfig({
|
||||
@@ -222,27 +229,14 @@ export default defineConfig({
|
||||
|
||||
::
|
||||
|
||||
::note
|
||||
Try the :prose-icon{name="i-lucide-swatch-book" 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:
|
||||
|
||||
::component-code{slug="button"}
|
||||
---
|
||||
props:
|
||||
color: primary
|
||||
slots:
|
||||
default: Button
|
||||
---
|
||||
::
|
||||
### Extend colors
|
||||
|
||||
::framework-only
|
||||
#nuxt
|
||||
:::tip
|
||||
You can add you own dynamic color aliases in your `app.config.ts`, you just have to make sure to define them in the [`ui.theme.colors`](/getting-started/installation/nuxt#themecolors) option in your `nuxt.config.ts` file.
|
||||
:::div
|
||||
You can add you own dynamic color aliases in your `app.config.ts`, you just have to make sure to define them in the [`ui.theme.colors`](/getting-started/installation/nuxt#themecolors) option in your `nuxt.config.ts` file:
|
||||
|
||||
```ts [app.config.ts]
|
||||
```ts [app.config.ts]{4}
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
colors: {
|
||||
@@ -252,11 +246,19 @@ export default defineAppConfig({
|
||||
})
|
||||
```
|
||||
|
||||
```ts [nuxt.config.ts]
|
||||
```ts [nuxt.config.ts]{7}
|
||||
export default defineNuxtConfig({
|
||||
ui: {
|
||||
theme: {
|
||||
colors: ['primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error']
|
||||
colors: [
|
||||
'primary',
|
||||
'secondary',
|
||||
'tertiary',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error'
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -266,9 +268,9 @@ export default defineNuxtConfig({
|
||||
|
||||
#vue
|
||||
|
||||
:::tip
|
||||
:::div
|
||||
|
||||
You can add you own dynamic color aliases in your `vite.config.ts`, you just have to make sure to also define them in the [`theme.colors`](/getting-started/installation/vue#themecolors) option of the `ui` plugin.
|
||||
You can add you own dynamic color aliases in your `vite.config.ts`, you just have to make sure to also define them in the [`theme.colors`](/getting-started/installation/vue#themecolors) option of the `ui` plugin:
|
||||
|
||||
::::module-only
|
||||
|
||||
@@ -276,7 +278,7 @@ You can add you own dynamic color aliases in your `vite.config.ts`, you just hav
|
||||
|
||||
:::::div
|
||||
|
||||
```ts [vite.config.ts]
|
||||
```ts [vite.config.ts]{11,18}
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import ui from '@nuxt/ui/vite'
|
||||
@@ -291,7 +293,15 @@ export default defineConfig({
|
||||
}
|
||||
},
|
||||
theme: {
|
||||
colors: ['primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error']
|
||||
colors: [
|
||||
'primary',
|
||||
'secondary',
|
||||
'tertiary',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error'
|
||||
]
|
||||
}
|
||||
})
|
||||
]
|
||||
@@ -304,7 +314,7 @@ export default defineConfig({
|
||||
|
||||
:::::div
|
||||
|
||||
```ts [vite.config.ts]
|
||||
```ts [vite.config.ts]{11,18}
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import uiPro from '@nuxt/ui-pro/vite'
|
||||
@@ -316,10 +326,18 @@ export default defineConfig({
|
||||
ui: {
|
||||
colors: {
|
||||
tertiary: 'indigo'
|
||||
},
|
||||
}
|
||||
},
|
||||
theme: {
|
||||
colors: ['primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error']
|
||||
colors: [
|
||||
'primary',
|
||||
'secondary',
|
||||
'tertiary',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error'
|
||||
]
|
||||
}
|
||||
})
|
||||
]
|
||||
@@ -334,13 +352,13 @@ export default defineConfig({
|
||||
|
||||
::
|
||||
|
||||
### Tokens
|
||||
## CSS Variables
|
||||
|
||||
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
|
||||
### Colors
|
||||
|
||||
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:
|
||||
Nuxt UI provides a CSS variable for each color alias you define which represent the default shade used in both light and dark modes:
|
||||
|
||||
::code-group
|
||||
|
||||
@@ -368,16 +386,125 @@ Nuxt UI automatically creates a CSS variable for each color alias you define whi
|
||||
|
||||
::
|
||||
|
||||
::note
|
||||
You can use these variables in your Tailwind CSS classes in two ways:
|
||||
- Using CSS variable syntax: `text-(--ui-primary)` or `bg-(--ui-primary)`
|
||||
- Using color alias: `text-primary` or `bg-primary`
|
||||
These CSS variables are defined in Tailwind CSS's `@theme` so you can use them as classes:
|
||||
|
||||
Both approaches will automatically adapt to the current color scheme, ensuring consistent styling across light and dark modes.
|
||||
::code-preview
|
||||
[Primary]{class="text-primary text-sm px-4"}
|
||||
[Secondary]{class="text-secondary text-sm px-4"}
|
||||
[Success]{class="text-success text-sm px-4"}
|
||||
[Info]{class="text-info text-sm px-4"}
|
||||
[Warning]{class="text-warning text-sm px-4"}
|
||||
[Error]{class="text-error text-sm px-4"}
|
||||
|
||||
#code
|
||||
```vue
|
||||
<template>
|
||||
<span class="text-primary">Primary</span>
|
||||
<span class="text-secondary">Secondary</span>
|
||||
<span class="text-success">Success</span>
|
||||
<span class="text-info">Info</span>
|
||||
<span class="text-warning">Warning</span>
|
||||
<span class="text-error">Error</span>
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
::tip
|
||||
You can change which shade is used for each color on light and dark mode:
|
||||
::note
|
||||
This is how the `@theme` is generated for each color alias:
|
||||
|
||||
:::code-collapse{class="[&>div]:!my-0"}
|
||||
```scss
|
||||
@theme default {
|
||||
--color-primary: var(--ui-primary);
|
||||
--color-primary-50: var(--ui-color-primary-50);
|
||||
--color-primary-100: var(--ui-color-primary-100);
|
||||
--color-primary-200: var(--ui-color-primary-200);
|
||||
--color-primary-300: var(--ui-color-primary-300);
|
||||
--color-primary-400: var(--ui-color-primary-400);
|
||||
--color-primary-500: var(--ui-color-primary-500);
|
||||
--color-primary-600: var(--ui-color-primary-600);
|
||||
--color-primary-700: var(--ui-color-primary-700);
|
||||
--color-primary-800: var(--ui-color-primary-800);
|
||||
--color-primary-900: var(--ui-color-primary-900);
|
||||
--color-primary-950: var(--ui-color-primary-950);
|
||||
--color-secondary: var(--ui-secondary);
|
||||
--color-secondary-50: var(--ui-color-secondary-50);
|
||||
--color-secondary-100: var(--ui-color-secondary-100);
|
||||
--color-secondary-200: var(--ui-color-secondary-200);
|
||||
--color-secondary-300: var(--ui-color-secondary-300);
|
||||
--color-secondary-400: var(--ui-color-secondary-400);
|
||||
--color-secondary-500: var(--ui-color-secondary-500);
|
||||
--color-secondary-600: var(--ui-color-secondary-600);
|
||||
--color-secondary-700: var(--ui-color-secondary-700);
|
||||
--color-secondary-800: var(--ui-color-secondary-800);
|
||||
--color-secondary-900: var(--ui-color-secondary-900);
|
||||
--color-secondary-950: var(--ui-color-secondary-950);
|
||||
--color-success: var(--ui-success);
|
||||
--color-success-50: var(--ui-color-success-50);
|
||||
--color-success-100: var(--ui-color-success-100);
|
||||
--color-success-200: var(--ui-color-success-200);
|
||||
--color-success-300: var(--ui-color-success-300);
|
||||
--color-success-400: var(--ui-color-success-400);
|
||||
--color-success-500: var(--ui-color-success-500);
|
||||
--color-success-600: var(--ui-color-success-600);
|
||||
--color-success-700: var(--ui-color-success-700);
|
||||
--color-success-800: var(--ui-color-success-800);
|
||||
--color-success-900: var(--ui-color-success-900);
|
||||
--color-success-950: var(--ui-color-success-950);
|
||||
--color-info: var(--ui-info);
|
||||
--color-info-50: var(--ui-color-info-50);
|
||||
--color-info-100: var(--ui-color-info-100);
|
||||
--color-info-200: var(--ui-color-info-200);
|
||||
--color-info-300: var(--ui-color-info-300);
|
||||
--color-info-400: var(--ui-color-info-400);
|
||||
--color-info-500: var(--ui-color-info-500);
|
||||
--color-info-600: var(--ui-color-info-600);
|
||||
--color-info-700: var(--ui-color-info-700);
|
||||
--color-info-800: var(--ui-color-info-800);
|
||||
--color-info-900: var(--ui-color-info-900);
|
||||
--color-info-950: var(--ui-color-info-950);
|
||||
--color-warning: var(--ui-warning);
|
||||
--color-warning-50: var(--ui-color-warning-50);
|
||||
--color-warning-100: var(--ui-color-warning-100);
|
||||
--color-warning-200: var(--ui-color-warning-200);
|
||||
--color-warning-300: var(--ui-color-warning-300);
|
||||
--color-warning-400: var(--ui-color-warning-400);
|
||||
--color-warning-500: var(--ui-color-warning-500);
|
||||
--color-warning-600: var(--ui-color-warning-600);
|
||||
--color-warning-700: var(--ui-color-warning-700);
|
||||
--color-warning-800: var(--ui-color-warning-800);
|
||||
--color-warning-900: var(--ui-color-warning-900);
|
||||
--color-warning-950: var(--ui-color-warning-950);
|
||||
--color-error: var(--ui-error);
|
||||
--color-error-50: var(--ui-color-error-50);
|
||||
--color-error-100: var(--ui-color-error-100);
|
||||
--color-error-200: var(--ui-color-error-200);
|
||||
--color-error-300: var(--ui-color-error-300);
|
||||
--color-error-400: var(--ui-color-error-400);
|
||||
--color-error-500: var(--ui-color-error-500);
|
||||
--color-error-600: var(--ui-color-error-600);
|
||||
--color-error-700: var(--ui-color-error-700);
|
||||
--color-error-800: var(--ui-color-error-800);
|
||||
--color-error-900: var(--ui-color-error-900);
|
||||
--color-error-950: var(--ui-color-error-950);
|
||||
--color-neutral-50: var(--ui-color-neutral-50);
|
||||
--color-neutral-100: var(--ui-color-neutral-100);
|
||||
--color-neutral-200: var(--ui-color-neutral-200);
|
||||
--color-neutral-300: var(--ui-color-neutral-300);
|
||||
--color-neutral-400: var(--ui-color-neutral-400);
|
||||
--color-neutral-500: var(--ui-color-neutral-500);
|
||||
--color-neutral-600: var(--ui-color-neutral-600);
|
||||
--color-neutral-700: var(--ui-color-neutral-700);
|
||||
--color-neutral-800: var(--ui-color-neutral-800);
|
||||
--color-neutral-900: var(--ui-color-neutral-900);
|
||||
--color-neutral-950: var(--ui-color-neutral-950);
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::
|
||||
|
||||
You can change which shade is used for each color on light and dark mode in your `main.css` file:
|
||||
|
||||
::module-only
|
||||
#ui
|
||||
@@ -417,10 +544,6 @@ You can change which shade is used for each color on light and dark mode:
|
||||
:::
|
||||
::
|
||||
|
||||
::
|
||||
|
||||
#### Black as Primary Color
|
||||
|
||||
::framework-only
|
||||
#nuxt
|
||||
:::p
|
||||
@@ -471,7 +594,7 @@ You cannot set `primary: 'black'`{lang="ts-type"} in your [`vite.config.ts`](#co
|
||||
:::
|
||||
::
|
||||
|
||||
#### Neutral Palette
|
||||
### Neutral
|
||||
|
||||
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:
|
||||
|
||||
@@ -479,89 +602,153 @@ Nuxt UI provides a comprehensive set of design tokens for the `neutral` color pa
|
||||
|
||||
```css [Light]
|
||||
:root {
|
||||
/* Least prominent text */
|
||||
--ui-text-dimmed: var(--ui-color-neutral-400);
|
||||
/* Slightly muted text */
|
||||
--ui-text-muted: var(--ui-color-neutral-500);
|
||||
/* Moderately prominent text */
|
||||
--ui-text-toned: var(--ui-color-neutral-600);
|
||||
/* Default text color */
|
||||
--ui-text: var(--ui-color-neutral-700);
|
||||
/* Most prominent text */
|
||||
--ui-text-highlighted: var(--ui-color-neutral-900);
|
||||
--ui-text-inverted: var(--color-white);
|
||||
|
||||
/* Main background color */
|
||||
--ui-bg: var(--color-white);
|
||||
/* Subtle background */
|
||||
--ui-bg-muted: var(--ui-color-neutral-50);
|
||||
/* Slightly elevated background */
|
||||
--ui-bg-elevated: var(--ui-color-neutral-100);
|
||||
/* More prominent background */
|
||||
--ui-bg-accented: var(--ui-color-neutral-200);
|
||||
/* Inverted background color */
|
||||
--ui-bg-inverted: var(--ui-color-neutral-900);
|
||||
|
||||
/* Default border color */
|
||||
--ui-border: var(--ui-color-neutral-200);
|
||||
/* Subtle border */
|
||||
--ui-border-muted: var(--ui-color-neutral-200);
|
||||
/* More prominent border */
|
||||
--ui-border-accented: var(--ui-color-neutral-300);
|
||||
/* Inverted border color */
|
||||
--ui-border-inverted: var(--ui-color-neutral-900);
|
||||
}
|
||||
```
|
||||
|
||||
```css [Dark]
|
||||
.dark {
|
||||
/* Least prominent text */
|
||||
--ui-text-dimmed: var(--ui-color-neutral-500);
|
||||
/* Slightly muted text */
|
||||
--ui-text-muted: var(--ui-color-neutral-400);
|
||||
/* Moderately prominent text */
|
||||
--ui-text-toned: var(--ui-color-neutral-300);
|
||||
/* Default text color */
|
||||
--ui-text: var(--ui-color-neutral-200);
|
||||
/* Most prominent text */
|
||||
--ui-text-highlighted: var(--color-white);
|
||||
--ui-text-inverted: var(--ui-color-neutral-900);
|
||||
|
||||
/* Main background color */
|
||||
--ui-bg: var(--ui-color-neutral-900);
|
||||
/* Subtle background */
|
||||
--ui-bg-muted: var(--ui-color-neutral-800);
|
||||
/* Slightly elevated background */
|
||||
--ui-bg-elevated: var(--ui-color-neutral-800);
|
||||
/* More prominent background */
|
||||
--ui-bg-accented: var(--ui-color-neutral-700);
|
||||
/* Inverted background color */
|
||||
--ui-bg-inverted: var(--color-white);
|
||||
|
||||
/* Default border color */
|
||||
--ui-border: var(--ui-color-neutral-800);
|
||||
/* Subtle border */
|
||||
--ui-border-muted: var(--ui-color-neutral-700);
|
||||
/* More prominent border */
|
||||
--ui-border-accented: var(--ui-color-neutral-700);
|
||||
/* Inverted border color */
|
||||
--ui-border-inverted: var(--color-white);
|
||||
}
|
||||
```
|
||||
|
||||
::
|
||||
|
||||
::note
|
||||
Nuxt UI automatically applies a text and background color on the `<body>` element of your app:
|
||||
These CSS variables are defined in Tailwind CSS's `@theme` so you can use them as classes:
|
||||
|
||||
```css
|
||||
body {
|
||||
@apply antialiased text-(--ui-text) bg-(--ui-bg);
|
||||
::code-preview
|
||||
[Dimmed]{class="text-dimmed text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
[Muted]{class="text-muted text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
[Toned]{class="text-toned text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
[Text]{class="text-default text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
[Highlighted]{class="text-highlighted text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
[Inverted]{class="text-inverted bg-inverted text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
|
||||
#code
|
||||
```vue
|
||||
<template>
|
||||
<span class="text-dimmed">Dimmed</span>
|
||||
<span class="text-muted">Muted</span>
|
||||
<span class="text-toned">Toned</span>
|
||||
<span class="text-default">Text</span>
|
||||
<span class="text-highlighted">Highlighted</span>
|
||||
<span class="text-inverted bg-inverted">Inverted</span>
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
::code-preview
|
||||
[Default]{class="bg-default text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Muted]{class="bg-muted text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Elevated]{class="bg-elevated text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Accented]{class="bg-accented text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Inverted]{class="bg-inverted text-inverted text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
|
||||
#code
|
||||
```vue
|
||||
<template>
|
||||
<div class="bg-default">Default</div>
|
||||
<div class="bg-muted">Muted</div>
|
||||
<div class="bg-elevated">Elevated</div>
|
||||
<div class="bg-accented">Accented</div>
|
||||
<div class="bg-inverted text-inverted">Inverted</div>
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
::code-preview
|
||||
[Default]{class="border-2 border-default text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Muted]{class="border-2 border-muted text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Accented]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[Inverted]{class="border-2 border-inverted text-sm px-4 py-1.5 inline-block rounded-md"}
|
||||
|
||||
#code
|
||||
```vue
|
||||
<template>
|
||||
<div class="border border-default">Default</div>
|
||||
<div class="border border-muted">Muted</div>
|
||||
<div class="border border-accented">Accented</div>
|
||||
<div class="border border-inverted">Inverted</div>
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
::note
|
||||
This is how the `@theme` is generated for each design token:
|
||||
|
||||
:::code-collapse{class="[&>div]:!my-0"}
|
||||
```scss
|
||||
@theme default {
|
||||
--text-color-dimmed: var(--ui-text-dimmed);
|
||||
--text-color-muted: var(--ui-text-muted);
|
||||
--text-color-toned: var(--ui-text-toned);
|
||||
--text-color-default: var(--ui-text);
|
||||
--text-color-highlighted: var(--ui-text-highlighted);
|
||||
--text-color-inverted: var(--ui-text-inverted);
|
||||
--background-color-default: var(--ui-bg);
|
||||
--background-color-muted: var(--ui-bg-muted);
|
||||
--background-color-elevated: var(--ui-bg-elevated);
|
||||
--background-color-accented: var(--ui-bg-accented);
|
||||
--background-color-inverted: var(--ui-bg-inverted);
|
||||
--background-color-border: var(--ui-border);
|
||||
--border-color-default: var(--ui-border);
|
||||
--border-color-muted: var(--ui-border-muted);
|
||||
--border-color-accented: var(--ui-border-accented);
|
||||
--border-color-inverted: var(--ui-border-inverted);
|
||||
--ring-color-default: var(--ui-border);
|
||||
--ring-color-muted: var(--ui-border-muted);
|
||||
--ring-color-accented: var(--ui-border-accented);
|
||||
--ring-color-inverted: var(--ui-border-inverted);
|
||||
--ring-color-bg: var(--ui-bg);
|
||||
--divide-color-default: var(--ui-border);
|
||||
--divide-color-muted: var(--ui-border-muted);
|
||||
--divide-color-accented: var(--ui-border-accented);
|
||||
--divide-color-inverted: var(--ui-border-inverted);
|
||||
--outline-color-default: var(--ui-border);
|
||||
--outline-color-inverted: var(--ui-border-inverted);
|
||||
--stroke-color-default: var(--ui-border);
|
||||
--stroke-color-inverted: var(--ui-border-inverted);
|
||||
--fill-color-default: var(--ui-border);
|
||||
--fill-color-inverted: var(--ui-border-inverted);
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::
|
||||
|
||||
::tip
|
||||
You can customize these CSS variables to tailor the appearance of your application:
|
||||
You can customize these CSS variables to tailor the appearance of your application in your `main.css` file:
|
||||
|
||||
::module-only
|
||||
#ui
|
||||
@@ -605,13 +792,57 @@ You can customize these CSS variables to tailor the appearance of your applicati
|
||||
:::
|
||||
::
|
||||
|
||||
::
|
||||
|
||||
#### Border Radius
|
||||
|
||||
Nuxt UI provides a centralized border radius system through the `--ui-radius` CSS variable, which defaults to `0.25rem`. This system replaces Tailwind CSS's default `rounded-*` utilities while maintaining the familiar class names. The border radius system is built on a scale that multiplies the base radius value:
|
||||
::note
|
||||
Nuxt UI applies a text and background color on the `<body>` element of your app:
|
||||
|
||||
```css
|
||||
body {
|
||||
@apply antialiased text-default bg-default scheme-light dark:scheme-dark;
|
||||
}
|
||||
```
|
||||
|
||||
::
|
||||
|
||||
### Radius
|
||||
|
||||
Nuxt UI provides a centralized border radius system through the `--ui-radius` CSS variable.
|
||||
|
||||
```css
|
||||
:root {
|
||||
--ui-radius: 0.25rem;
|
||||
}
|
||||
```
|
||||
|
||||
This CSS variable replaces Tailwind CSS's default `rounded-*` utilities so you can use the same class names:
|
||||
|
||||
::code-preview
|
||||
[xs]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-xs mr-2"}
|
||||
[sm]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-sm mr-2"}
|
||||
[md]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-md mr-2"}
|
||||
[lg]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-lg mr-2"}
|
||||
[xl]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-xl mr-2"}
|
||||
[2xl]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-2xl mr-2"}
|
||||
[3xl]{class="border-2 border-accented text-sm px-4 py-1.5 inline-block rounded-3xl mr-2"}
|
||||
|
||||
#code
|
||||
```vue
|
||||
<template>
|
||||
<div class="rounded-xs">xs</div>
|
||||
<div class="rounded-sm">sm</div>
|
||||
<div class="rounded-md">md</div>
|
||||
<div class="rounded-lg">lg</div>
|
||||
<div class="rounded-xl">xl</div>
|
||||
<div class="rounded-2xl">2xl</div>
|
||||
<div class="rounded-3xl">3xl</div>
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
::note
|
||||
This is how the `@theme` is generated for each radius value:
|
||||
|
||||
:::code-collapse{class="[&>div]:!my-0"}
|
||||
```scss
|
||||
@theme default {
|
||||
--radius-xs: calc(var(--ui-radius) * 0.5); /* 0.125rem */
|
||||
--radius-sm: var(--ui-radius); /* 0.25rem */
|
||||
@@ -622,6 +853,9 @@ Nuxt UI provides a centralized border radius system through the `--ui-radius` CS
|
||||
--radius-3xl: calc(var(--ui-radius) * 6); /* 1.5rem */
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::
|
||||
|
||||
You can customize the base radius value in your `main.css` file:
|
||||
|
||||
@@ -656,12 +890,18 @@ You can customize the base radius value in your `main.css` file:
|
||||
::
|
||||
|
||||
::note
|
||||
Try the :prose-icon{name="i-lucide-swatch-book" class="text-(--ui-primary)"} theme picker in the header above to change the base radius value.
|
||||
Try the :prose-icon{name="i-lucide-swatch-book" class="text-primary"} theme picker in the header above to change the base radius value.
|
||||
::
|
||||
|
||||
#### Container
|
||||
### Container
|
||||
|
||||
Nuxt UI provides a global `--ui-container` CSS variable that controls the maximum width of the [Container](/components/container) component, which defaults to `var(--container-7xl)`.
|
||||
Nuxt UI provides a `--ui-container` CSS variable that controls the maximum width of the [Container](/components/container) component.
|
||||
|
||||
```css
|
||||
:root {
|
||||
--ui-container: var(--container-7xl);
|
||||
}
|
||||
```
|
||||
|
||||
You can customize this value in your `main.css` file to adjust container widths consistently throughout your application:
|
||||
|
||||
@@ -716,7 +956,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',
|
||||
root: 'bg-default ring ring-default divide-y divide-default rounded-lg',
|
||||
header: 'p-4 sm:px-6',
|
||||
body: 'p-4 sm:p-6',
|
||||
footer: 'p-4 sm:px-6'
|
||||
@@ -775,7 +1015,7 @@ Nuxt UI components use `variants` to change the `slots` styles based on props. H
|
||||
```ts [src/theme/avatar.ts]
|
||||
export default {
|
||||
slots: {
|
||||
root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-(--ui-bg-elevated)',
|
||||
root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-elevated',
|
||||
image: 'h-full w-full rounded-[inherit] object-cover'
|
||||
},
|
||||
variants: {
|
||||
|
||||
@@ -330,7 +330,7 @@ props:
|
||||
color: neutral
|
||||
variant: outline
|
||||
ui:
|
||||
leadingIcon: 'text-(--ui-primary)'
|
||||
leadingIcon: 'text-primary'
|
||||
slots:
|
||||
default: |
|
||||
|
||||
|
||||
@@ -99,12 +99,12 @@ props:
|
||||
slots:
|
||||
default: |
|
||||
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
---
|
||||
|
||||
:div{class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72"}[Right click here]
|
||||
:div{class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"}[Right click here]
|
||||
::
|
||||
|
||||
::note
|
||||
@@ -143,12 +143,12 @@ props:
|
||||
slots:
|
||||
default: |
|
||||
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
---
|
||||
|
||||
:div{class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72"}[Right click here]
|
||||
:div{class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"}[Right click here]
|
||||
::
|
||||
|
||||
### Disabled
|
||||
@@ -179,12 +179,12 @@ props:
|
||||
slots:
|
||||
default: |
|
||||
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
---
|
||||
|
||||
:div{class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72"}[Right click here]
|
||||
:div{class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72"}[Right click here]
|
||||
::
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -248,7 +248,7 @@ Make sure to add the `data-vaul-drawer-wrapper` directive to a parent element of
|
||||
```vue [app.vue]
|
||||
<template>
|
||||
<UApp>
|
||||
<div class="bg-(--ui-bg)" data-vaul-drawer-wrapper>
|
||||
<div class="bg-default" data-vaul-drawer-wrapper>
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
@@ -262,7 +262,7 @@ export default defineNuxtConfig({
|
||||
app: {
|
||||
rootAttrs: {
|
||||
'data-vaul-drawer-wrapper': '',
|
||||
'class': 'bg-(--ui-bg)'
|
||||
'class': 'bg-default'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -195,12 +195,12 @@ This will give you access to the following:
|
||||
|
||||
| Name | Type |
|
||||
| ---- | ---- |
|
||||
| `submit()`{lang="ts-type"} | `Promise<void>`{lang="ts-type"} <br> <div class="text-(--ui-text-toned) mt-1"><p>Triggers form submission.</p> |
|
||||
| `validate(opts: { name?: keyof T \| (keyof T)[], silent?: boolean, nested?: boolean, transform?: boolean })`{lang="ts-type"} | `Promise<T>`{lang="ts-type"} <br> <div class="text-(--ui-text-toned) mt-1"><p>Triggers form validation. Will raise any errors unless `opts.silent` is set to true.</p> |
|
||||
| `clear(path?: keyof T)`{lang="ts-type"} | `void` <br> <div class="text-(--ui-text-toned) mt-1"><p>Clears form errors associated with a specific path. If no path is provided, clears all form errors.</p> |
|
||||
| `getErrors(path?: keyof T)`{lang="ts-type"} | `FormError[]`{lang="ts-type"} <br> <div class="text-(--ui-text-toned) mt-1"><p>Retrieves form errors associated with a specific path. If no path is provided, returns all form errors.</p></div> |
|
||||
| `setErrors(errors: FormError[], name?: keyof T)`{lang="ts-type"} | `void` <br> <div class="text-(--ui-text-toned) mt-1"><p>Sets form errors for a given path. If no path is provided, overrides all errors.</p> |
|
||||
| `errors`{lang="ts-type"} | `Ref<FormError[]>`{lang="ts-type"} <br> <div class="text-(--ui-text-toned) mt-1"><p>A reference to the array containing validation errors. Use this to access or manipulate the error information.</p> |
|
||||
| `submit()`{lang="ts-type"} | `Promise<void>`{lang="ts-type"} <br> <div class="text-toned mt-1"><p>Triggers form submission.</p> |
|
||||
| `validate(opts: { name?: keyof T \| (keyof T)[], silent?: boolean, nested?: boolean, transform?: boolean })`{lang="ts-type"} | `Promise<T>`{lang="ts-type"} <br> <div class="text-toned mt-1"><p>Triggers form validation. Will raise any errors unless `opts.silent` is set to true.</p> |
|
||||
| `clear(path?: keyof T)`{lang="ts-type"} | `void` <br> <div class="text-toned mt-1"><p>Clears form errors associated with a specific path. If no path is provided, clears all form errors.</p> |
|
||||
| `getErrors(path?: keyof T)`{lang="ts-type"} | `FormError[]`{lang="ts-type"} <br> <div class="text-toned mt-1"><p>Retrieves form errors associated with a specific path. If no path is provided, returns all form errors.</p></div> |
|
||||
| `setErrors(errors: FormError[], name?: keyof T)`{lang="ts-type"} | `void` <br> <div class="text-toned mt-1"><p>Sets form errors for a given path. If no path is provided, overrides all errors.</p> |
|
||||
| `errors`{lang="ts-type"} | `Ref<FormError[]>`{lang="ts-type"} <br> <div class="text-toned mt-1"><p>A reference to the array containing validation errors. Use this to access or manipulate the error information.</p> |
|
||||
| `disabled`{lang="ts-type"} | `Ref<boolean>`{lang="ts-type"} |
|
||||
| `dirty`{lang="ts-type"} | `Ref<boolean>`{lang="ts-type"} `true` if at least one form field has been updated by the user.|
|
||||
| `dirtyFields`{lang="ts-type"} | `DeepReadonly<Set<keyof T>>`{lang="ts-type"} Tracks fields that have been modified by the user. |
|
||||
|
||||
@@ -67,7 +67,7 @@ props:
|
||||
raw: true
|
||||
to: /components/link
|
||||
activeClass: 'font-bold'
|
||||
inactiveClass: 'text-(--ui-text-muted)'
|
||||
inactiveClass: 'text-muted'
|
||||
slots:
|
||||
default: Link
|
||||
---
|
||||
|
||||
@@ -330,7 +330,7 @@ props:
|
||||
- label: Help
|
||||
icon: i-lucide-circle-help
|
||||
disabled: true
|
||||
class: 'data-[orientation=horizontal]:border-b border-(--ui-border) data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-48'
|
||||
class: 'data-[orientation=horizontal]:border-b border-default data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-48'
|
||||
---
|
||||
::
|
||||
|
||||
|
||||
@@ -75,13 +75,13 @@ props:
|
||||
|
||||
Use the `columns` prop as an array of [ColumnDef](https://tanstack.com/table/latest/docs/api/core/column-def) objects with properties like:
|
||||
|
||||
- `accessorKey`: [The key of the row object to use when extracting the value for the column.]{class="text-(--ui-text-muted)"}
|
||||
- `header`: [The header to display for the column. If a string is passed, it can be used as a default for the column ID. If a function is passed, it will be passed a props object for the header and should return the rendered header value (the exact type depends on the adapter being used).]{class="text-(--ui-text-muted)"}
|
||||
- `cell`: [The cell to display each row for the column. If a function is passed, it will be passed a props object for the cell and should return the rendered cell value (the exact type depends on the adapter being used).]{class="text-(--ui-text-muted)"}
|
||||
- `meta`: [Extra properties for the column.]{class="text-(--ui-text-muted)"}
|
||||
- `accessorKey`: [The key of the row object to use when extracting the value for the column.]{class="text-muted"}
|
||||
- `header`: [The header to display for the column. If a string is passed, it can be used as a default for the column ID. If a function is passed, it will be passed a props object for the header and should return the rendered header value (the exact type depends on the adapter being used).]{class="text-muted"}
|
||||
- `cell`: [The cell to display each row for the column. If a function is passed, it will be passed a props object for the cell and should return the rendered cell value (the exact type depends on the adapter being used).]{class="text-muted"}
|
||||
- `meta`: [Extra properties for the column.]{class="text-muted"}
|
||||
- `class`:
|
||||
- `td`: [The classes to apply to the `td` element.]{class="text-(--ui-text-muted)"}
|
||||
- `th`: [The classes to apply to the `th` element.]{class="text-(--ui-text-muted)"}
|
||||
- `td`: [The classes to apply to the `td` element.]{class="text-muted"}
|
||||
- `th`: [The classes to apply to the `th` element.]{class="text-muted"}
|
||||
|
||||
In order to render components or other HTML elements, you will need to use the Vue [`h` function](https://vuejs.org/api/render-function.html#h) inside the `header` and `cell` props. This is different from other components that use slots but allows for more flexibility.
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ export default defineNuxtConfig({
|
||||
},
|
||||
rootAttrs: {
|
||||
'data-vaul-drawer-wrapper': '',
|
||||
'class': 'bg-(--ui-bg)'
|
||||
'class': 'bg-default'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"@nuxt/content": "https://pkg.pr.new/@nuxt/content@754e480",
|
||||
"@nuxt/image": "^1.10.0",
|
||||
"@nuxt/ui": "latest",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@3cc20d8",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@9c280b4",
|
||||
"@nuxthub/core": "^0.8.24",
|
||||
"@nuxtjs/plausible": "^1.2.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
|
||||
@@ -84,9 +84,9 @@ defineShortcuts({
|
||||
|
||||
<template>
|
||||
<UApp :toaster="(appConfig.toaster as any)">
|
||||
<div class="h-screen w-screen overflow-hidden flex min-h-0 bg-(--ui-bg)" data-vaul-drawer-wrapper>
|
||||
<UNavigationMenu :items="items" orientation="vertical" class="hidden lg:flex border-e border-(--ui-border) overflow-y-auto w-48 p-4" />
|
||||
<UNavigationMenu :items="items" orientation="horizontal" class="lg:hidden border-b border-(--ui-border) [&>div]:min-w-min overflow-x-auto" />
|
||||
<div class="h-screen w-screen overflow-hidden flex min-h-0 bg-default" data-vaul-drawer-wrapper>
|
||||
<UNavigationMenu :items="items" orientation="vertical" class="hidden lg:flex border-e border-default overflow-y-auto w-48 p-4" />
|
||||
<UNavigationMenu :items="items" orientation="horizontal" class="lg:hidden border-b border-default [&>div]:min-w-min overflow-x-auto" />
|
||||
|
||||
<div class="fixed top-15 lg:top-3 end-4 flex items-center gap-2">
|
||||
<UButton
|
||||
|
||||
@@ -89,9 +89,9 @@ useHead({
|
||||
<template>
|
||||
<template v-if="!$route.path.startsWith('/__nuxt_ui__')">
|
||||
<UApp :toaster="appConfig.toaster">
|
||||
<div class="h-screen w-screen overflow-hidden flex flex-col lg:flex-row min-h-0 bg-(--ui-bg)" data-vaul-drawer-wrapper>
|
||||
<UNavigationMenu :items="items" orientation="vertical" class="hidden lg:flex border-e border-(--ui-border) overflow-y-auto w-48 p-4" />
|
||||
<UNavigationMenu :items="items" orientation="horizontal" class="lg:hidden border-b border-(--ui-border) [&>div]:min-w-min overflow-x-auto" />
|
||||
<div class="h-screen w-screen overflow-hidden flex flex-col lg:flex-row min-h-0 bg-default" data-vaul-drawer-wrapper>
|
||||
<UNavigationMenu :items="items" orientation="vertical" class="hidden lg:flex border-e border-default overflow-y-auto w-48 p-4" />
|
||||
<UNavigationMenu :items="items" orientation="horizontal" class="lg:hidden border-b border-default [&>div]:min-w-min overflow-x-auto" />
|
||||
|
||||
<div class="fixed top-15 lg:top-3 end-4 flex items-center gap-2">
|
||||
<ClientOnly v-if="!colorMode?.forced">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="relative overflow-hidden rounded-sm 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">
|
||||
<div class="relative overflow-hidden rounded-sm border border-dashed border-accented opacity-75 px-4 flex items-center justify-center">
|
||||
<svg class="absolute inset-0 h-full w-full stroke-inverted/10" fill="none">
|
||||
<defs>
|
||||
<pattern
|
||||
id="pattern-5c1e4f0e-62d5-498b-8ff0-cf77bb448c8e"
|
||||
|
||||
@@ -33,18 +33,18 @@ const items = [{
|
||||
<UCard :ui="{ body: 'p-0 sm:p-0' }">
|
||||
<UAccordion :items="items" class="w-96" :ui="{ trigger: 'px-3.5', body: 'px-3.5' }">
|
||||
<template #body="{ item }">
|
||||
<p class="text-(--ui-text-muted)">
|
||||
<p class="text-muted">
|
||||
{{ item.content }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #custom="{ item }">
|
||||
<p class="text-(--ui-text-muted)">
|
||||
<p class="text-muted">
|
||||
Custom: {{ item.content }}
|
||||
</p>
|
||||
</template>
|
||||
<template #custom-body="{ item }">
|
||||
<p class="text-(--ui-text-muted)">
|
||||
<p class="text-muted">
|
||||
Custom: {{ item.content }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -18,7 +18,7 @@ const items = [{
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<UChip v-for="position in positions" :key="position" :position="position">
|
||||
<UChip v-for="position in positions" :key="position" :position="position" color="neutral">
|
||||
<UButton icon="i-lucide-inbox" color="neutral" variant="subtle" />
|
||||
</UChip>
|
||||
</div>
|
||||
|
||||
@@ -138,7 +138,7 @@ defineShortcuts({
|
||||
<UButton label="Open drawer" color="neutral" variant="outline" />
|
||||
|
||||
<template #content>
|
||||
<ReuseTemplate class="border-t border-(--ui-border) mt-4" />
|
||||
<ReuseTemplate class="border-t border-default mt-4" />
|
||||
</template>
|
||||
</UDrawer>
|
||||
|
||||
|
||||
@@ -106,13 +106,13 @@ defineShortcuts(extractShortcuts(items.value))
|
||||
</div>
|
||||
|
||||
<UContextMenu :items="items" :ui="{ content: 'w-48' }" :size="size">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Right click here
|
||||
</div>
|
||||
</UContextMenu>
|
||||
|
||||
<UContextMenu :items="itemsWithColor" :ui="{ content: 'w-48' }" :size="size">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-(--ui-border-accented) text-sm aspect-video w-72">
|
||||
<div class="flex items-center justify-center rounded-md border border-dashed border-accented text-sm aspect-video w-72">
|
||||
Color right click here
|
||||
</div>
|
||||
</UContextMenu>
|
||||
|
||||
@@ -144,7 +144,7 @@ defineShortcuts(extractShortcuts(items.value))
|
||||
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />
|
||||
|
||||
<template #custom-trailing>
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-(--ui-primary)" />
|
||||
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-primary" />
|
||||
</template>
|
||||
</UDropdownMenu>
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ const disabled = ref(false)
|
||||
<FormExampleNestedList />
|
||||
</div>
|
||||
|
||||
<div class="border border-(--ui-border) rounded-lg">
|
||||
<div class="border border-default rounded-lg">
|
||||
<div class="py-2 px-4 flex gap-4 items-center">
|
||||
<UFormField label="Validate on" class="flex items-center gap-2">
|
||||
<USelectMenu v-model="validateOn" :items="['input', 'change', 'blur']" multiple class="w-48" />
|
||||
@@ -62,7 +62,7 @@ const disabled = ref(false)
|
||||
<UCheckbox v-model="disabled" label="Disabled" />
|
||||
</div>
|
||||
|
||||
<FormExampleElements :validate-on="validateOn" :disabled="disabled" class="border-t border-(--ui-border) p-4" />
|
||||
<FormExampleElements :validate-on="validateOn" :disabled="disabled" class="border-t border-default p-4" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<ULink active>
|
||||
Button active
|
||||
</ULink>
|
||||
<ULink active class="font-medium" active-class="text-(--ui-text-highlighted)">
|
||||
<ULink active class="font-medium" active-class="text-highlighted">
|
||||
Button active with class
|
||||
</ULink>
|
||||
<ULink active disabled>
|
||||
@@ -18,7 +18,7 @@
|
||||
<ULink>
|
||||
Button inactive
|
||||
</ULink>
|
||||
<ULink class="font-medium" inactive-class="hover:text-(--ui-primary)">
|
||||
<ULink class="font-medium" inactive-class="hover:text-primary">
|
||||
Button inactive with class
|
||||
</ULink>
|
||||
<ULink disabled>
|
||||
@@ -34,7 +34,7 @@
|
||||
<ULink to="/components/link">
|
||||
Link active
|
||||
</ULink>
|
||||
<ULink to="/components/link" class="font-medium" active-class="text-(--ui-text-highlighted)">
|
||||
<ULink to="/components/link" class="font-medium" active-class="text-highlighted">
|
||||
Link active with class
|
||||
</ULink>
|
||||
<ULink to="/components/link" disabled>
|
||||
@@ -44,7 +44,7 @@
|
||||
<ULink to="/components/button">
|
||||
Link inactive
|
||||
</ULink>
|
||||
<ULink to="/components/button" class="font-medium" inactive-class="hover:text-(--ui-primary)">
|
||||
<ULink to="/components/button" class="font-medium" inactive-class="hover:text-primary">
|
||||
Link inactive with class
|
||||
</ULink>
|
||||
<ULink to="/components/button" disabled>
|
||||
|
||||
@@ -112,7 +112,7 @@ const items = [
|
||||
:content-orientation="contentOrientation"
|
||||
:highlight="highlight"
|
||||
:highlight-color="highlightColor"
|
||||
:class="highlight && 'data-[orientation=horizontal]:border-b border-(--ui-border)'"
|
||||
:class="highlight && 'data-[orientation=horizontal]:border-b border-default'"
|
||||
class="data-[orientation=vertical]:data-[collapsed=false]:w-48"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<p class="font-semibold text-(--ui-text-highlighted)">
|
||||
<p class="font-semibold text-highlighted">
|
||||
Nuxt UI
|
||||
</p>
|
||||
<p>An open-source UI component library.</p>
|
||||
|
||||
@@ -339,10 +339,10 @@ onMounted(() => {
|
||||
getPaginationRowModel: getPaginationRowModel()
|
||||
}"
|
||||
:ui="{
|
||||
tr: 'divide-x divide-(--ui-border)'
|
||||
tr: 'divide-x divide-default'
|
||||
}"
|
||||
sticky
|
||||
class="border border-(--ui-border-accented) rounded-sm"
|
||||
class="border border-accented rounded-sm"
|
||||
@select="onSelect"
|
||||
>
|
||||
<template #expanded="{ row }">
|
||||
@@ -351,7 +351,7 @@ onMounted(() => {
|
||||
</UTable>
|
||||
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div class="text-sm text-(--ui-text-muted)">
|
||||
<div class="text-sm text-muted">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
|
||||
@@ -57,7 +57,7 @@ const items = [{
|
||||
class="w-96"
|
||||
>
|
||||
<template #custom="{ item }">
|
||||
<span class="text-(--ui-text-muted)">Custom: {{ item.content }}</span>
|
||||
<span class="text-muted">Custom: {{ item.content }}</span>
|
||||
</template>
|
||||
|
||||
<template #list-trailing>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="text-center">
|
||||
<h1 class="font-semibold mb-1">
|
||||
<h1 class="font-semibold text-primary mb-1">
|
||||
Playground
|
||||
</h1>
|
||||
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -246,8 +246,8 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:..
|
||||
'@nuxt/ui-pro':
|
||||
specifier: https://pkg.pr.new/@nuxt/ui-pro@3cc20d8
|
||||
version: https://pkg.pr.new/@nuxt/ui-pro@3cc20d8(@babel/parser@7.27.0)(joi@17.13.3)(magicast@0.3.5)(superstruct@2.0.2)(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))(yup@1.6.1)(zod@3.24.3)
|
||||
specifier: https://pkg.pr.new/@nuxt/ui-pro@9c280b4
|
||||
version: https://pkg.pr.new/@nuxt/ui-pro@9c280b4(@babel/parser@7.27.0)(joi@17.13.3)(magicast@0.3.5)(superstruct@2.0.2)(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))(yup@1.6.1)(zod@3.24.3)
|
||||
'@nuxthub/core':
|
||||
specifier: ^0.8.24
|
||||
version: 0.8.24(db0@0.3.1(better-sqlite3@11.9.1))(ioredis@5.6.0)(magicast@0.3.5)(vite@6.3.2(@types/node@22.13.14)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(yaml@2.7.1))
|
||||
@@ -1348,8 +1348,8 @@ packages:
|
||||
vitest:
|
||||
optional: true
|
||||
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@3cc20d8':
|
||||
resolution: {tarball: https://pkg.pr.new/@nuxt/ui-pro@3cc20d8}
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@9c280b4':
|
||||
resolution: {tarball: https://pkg.pr.new/@nuxt/ui-pro@9c280b4}
|
||||
version: 3.0.2
|
||||
peerDependencies:
|
||||
joi: ^17.13.0
|
||||
@@ -8250,7 +8250,7 @@ snapshots:
|
||||
- typescript
|
||||
- yaml
|
||||
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@3cc20d8(@babel/parser@7.27.0)(joi@17.13.3)(magicast@0.3.5)(superstruct@2.0.2)(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))(yup@1.6.1)(zod@3.24.3)':
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@9c280b4(@babel/parser@7.27.0)(joi@17.13.3)(magicast@0.3.5)(superstruct@2.0.2)(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(vue@3.5.13(typescript@5.8.3))(yup@1.6.1)(zod@3.24.3)':
|
||||
dependencies:
|
||||
'@ai-sdk/vue': 1.2.8(vue@3.5.13(typescript@5.8.3))(zod@3.24.3)
|
||||
'@nuxt/kit': 3.16.2(magicast@0.3.5)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply antialiased text-(--ui-text) bg-(--ui-bg) scheme-light dark:scheme-dark;
|
||||
@apply antialiased text-default bg-default scheme-light dark:scheme-dark;
|
||||
}
|
||||
|
||||
:root, .light {
|
||||
@@ -15,6 +15,7 @@
|
||||
--ui-text-toned: var(--ui-color-neutral-600);
|
||||
--ui-text: var(--ui-color-neutral-700);
|
||||
--ui-text-highlighted: var(--ui-color-neutral-900);
|
||||
--ui-text-inverted: var(--color-white);
|
||||
|
||||
--ui-bg: var(--color-white);
|
||||
--ui-bg-muted: var(--ui-color-neutral-50);
|
||||
@@ -37,6 +38,7 @@
|
||||
--ui-text-toned: var(--ui-color-neutral-300);
|
||||
--ui-text: var(--ui-color-neutral-200);
|
||||
--ui-text-highlighted: var(--color-white);
|
||||
--ui-text-inverted: var(--ui-color-neutral-900);
|
||||
|
||||
--ui-bg: var(--ui-color-neutral-900);
|
||||
--ui-bg-muted: var(--ui-color-neutral-800);
|
||||
|
||||
@@ -99,6 +99,37 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
|
||||
--radius-xl: calc(var(--ui-radius) * 3);
|
||||
--radius-2xl: calc(var(--ui-radius) * 4);
|
||||
--radius-3xl: calc(var(--ui-radius) * 6);
|
||||
--text-color-dimmed: var(--ui-text-dimmed);
|
||||
--text-color-muted: var(--ui-text-muted);
|
||||
--text-color-toned: var(--ui-text-toned);
|
||||
--text-color-default: var(--ui-text);
|
||||
--text-color-highlighted: var(--ui-text-highlighted);
|
||||
--text-color-inverted: var(--ui-text-inverted);
|
||||
--background-color-default: var(--ui-bg);
|
||||
--background-color-muted: var(--ui-bg-muted);
|
||||
--background-color-elevated: var(--ui-bg-elevated);
|
||||
--background-color-accented: var(--ui-bg-accented);
|
||||
--background-color-inverted: var(--ui-bg-inverted);
|
||||
--background-color-border: var(--ui-border);
|
||||
--border-color-default: var(--ui-border);
|
||||
--border-color-muted: var(--ui-border-muted);
|
||||
--border-color-accented: var(--ui-border-accented);
|
||||
--border-color-inverted: var(--ui-border-inverted);
|
||||
--ring-color-default: var(--ui-border);
|
||||
--ring-color-muted: var(--ui-border-muted);
|
||||
--ring-color-accented: var(--ui-border-accented);
|
||||
--ring-color-inverted: var(--ui-border-inverted);
|
||||
--ring-color-bg: var(--ui-bg);
|
||||
--divide-color-default: var(--ui-border);
|
||||
--divide-color-muted: var(--ui-border-muted);
|
||||
--divide-color-accented: var(--ui-border-accented);
|
||||
--divide-color-inverted: var(--ui-border-inverted);
|
||||
--outline-color-default: var(--ui-border);
|
||||
--outline-color-inverted: var(--ui-border-inverted);
|
||||
--stroke-color-default: var(--ui-border);
|
||||
--stroke-color-inverted: var(--ui-border-inverted);
|
||||
--fill-color-default: var(--ui-border);
|
||||
--fill-color-inverted: var(--ui-border-inverted);
|
||||
}
|
||||
`
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export default {
|
||||
slots: {
|
||||
root: 'w-full',
|
||||
item: 'border-b border-(--ui-border) last:border-b-0',
|
||||
item: 'border-b border-default last:border-b-0',
|
||||
header: 'flex',
|
||||
trigger: 'group flex-1 flex items-center gap-1.5 font-medium text-sm py-3.5 focus-visible:outline-(--ui-primary) min-w-0',
|
||||
trigger: 'group flex-1 flex items-center gap-1.5 font-medium text-sm py-3.5 focus-visible:outline-primary min-w-0',
|
||||
content: 'data-[state=open]:animate-[accordion-down_200ms_ease-out] data-[state=closed]:animate-[accordion-up_200ms_ease-out] overflow-hidden focus:outline-none',
|
||||
body: 'text-sm pb-3.5',
|
||||
leadingIcon: 'shrink-0 size-5',
|
||||
|
||||
@@ -43,49 +43,49 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
color,
|
||||
variant: 'solid',
|
||||
class: {
|
||||
root: `bg-(--ui-${color}) text-(--ui-bg)`
|
||||
root: `bg-${color} text-inverted`
|
||||
}
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'outline',
|
||||
class: {
|
||||
root: `text-(--ui-${color}) ring ring-inset ring-(--ui-${color})/25`
|
||||
root: `text-${color} ring ring-inset ring-${color}/25`
|
||||
}
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'soft',
|
||||
class: {
|
||||
root: `bg-(--ui-${color})/10 text-(--ui-${color})`
|
||||
root: `bg-${color}/10 text-${color}`
|
||||
}
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'subtle',
|
||||
class: {
|
||||
root: `bg-(--ui-${color})/10 text-(--ui-${color}) ring ring-inset ring-(--ui-${color})/25`
|
||||
root: `bg-${color}/10 text-${color} ring ring-inset ring-${color}/25`
|
||||
}
|
||||
})), {
|
||||
color: 'neutral',
|
||||
variant: 'solid',
|
||||
class: {
|
||||
root: 'text-(--ui-bg) bg-(--ui-bg-inverted)'
|
||||
root: 'text-inverted bg-inverted'
|
||||
}
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'outline',
|
||||
class: {
|
||||
root: 'text-(--ui-text-highlighted) bg-(--ui-bg) ring ring-inset ring-(--ui-border)'
|
||||
root: 'text-highlighted bg-default ring ring-inset ring-default'
|
||||
}
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'soft',
|
||||
class: {
|
||||
root: 'text-(--ui-text-highlighted) bg-(--ui-bg-elevated)/50'
|
||||
root: 'text-highlighted bg-elevated/50'
|
||||
}
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'subtle',
|
||||
class: {
|
||||
root: 'text-(--ui-text-highlighted) bg-(--ui-bg-elevated)/50 ring ring-inset ring-(--ui-border-accented)'
|
||||
root: 'text-highlighted bg-elevated/50 ring ring-inset ring-accented'
|
||||
}
|
||||
}],
|
||||
defaultVariants: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
slots: {
|
||||
root: 'inline-flex flex-row-reverse justify-end',
|
||||
base: 'relative rounded-full ring-(--ui-bg) first:me-0'
|
||||
base: 'relative rounded-full ring-bg first:me-0'
|
||||
},
|
||||
variants: {
|
||||
size: {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export default {
|
||||
slots: {
|
||||
root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-(--ui-bg-elevated)',
|
||||
root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-elevated',
|
||||
image: 'h-full w-full rounded-[inherit] object-cover',
|
||||
fallback: 'font-medium leading-none text-(--ui-text-muted) truncate',
|
||||
icon: 'text-(--ui-text-muted) shrink-0'
|
||||
fallback: 'font-medium leading-none text-muted truncate',
|
||||
icon: 'text-muted shrink-0'
|
||||
},
|
||||
variants: {
|
||||
size: {
|
||||
|
||||
@@ -58,35 +58,35 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
compoundVariants: [...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'solid',
|
||||
class: `bg-(--ui-${color}) text-(--ui-bg)`
|
||||
class: `bg-${color} text-inverted`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'outline',
|
||||
class: `text-(--ui-${color}) ring ring-inset ring-(--ui-${color})/50`
|
||||
class: `text-${color} ring ring-inset ring-${color}/50`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'soft',
|
||||
class: `bg-(--ui-${color})/10 text-(--ui-${color})`
|
||||
class: `bg-${color}/10 text-${color}`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'subtle',
|
||||
class: `bg-(--ui-${color})/10 text-(--ui-${color}) ring ring-inset ring-(--ui-${color})/25`
|
||||
class: `bg-${color}/10 text-${color} ring ring-inset ring-${color}/25`
|
||||
})), {
|
||||
color: 'neutral',
|
||||
variant: 'solid',
|
||||
class: 'text-(--ui-bg) bg-(--ui-bg-inverted)'
|
||||
class: 'text-inverted bg-inverted'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'outline',
|
||||
class: 'ring ring-inset ring-(--ui-border-accented) text-(--ui-text) bg-(--ui-bg)'
|
||||
class: 'ring ring-inset ring-accented text-default bg-default'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'soft',
|
||||
class: 'text-(--ui-text) bg-(--ui-bg-elevated)'
|
||||
class: 'text-default bg-elevated'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'subtle',
|
||||
class: 'ring ring-inset ring-(--ui-border-accented) text-(--ui-text) bg-(--ui-bg-elevated)'
|
||||
class: 'ring ring-inset ring-accented text-default bg-elevated'
|
||||
}],
|
||||
defaultVariants: {
|
||||
color: 'primary',
|
||||
|
||||
@@ -5,21 +5,21 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
root: 'relative min-w-0',
|
||||
list: 'flex items-center gap-1.5',
|
||||
item: 'flex min-w-0',
|
||||
link: 'group relative flex items-center gap-1.5 text-sm min-w-0 focus-visible:outline-(--ui-primary)',
|
||||
link: 'group relative flex items-center gap-1.5 text-sm min-w-0 focus-visible:outline-primary',
|
||||
linkLeadingIcon: 'shrink-0 size-5',
|
||||
linkLeadingAvatar: 'shrink-0',
|
||||
linkLeadingAvatarSize: '2xs',
|
||||
linkLabel: 'truncate',
|
||||
separator: 'flex',
|
||||
separatorIcon: 'shrink-0 size-5 text-(--ui-text-muted)'
|
||||
separatorIcon: 'shrink-0 size-5 text-muted'
|
||||
},
|
||||
variants: {
|
||||
active: {
|
||||
true: {
|
||||
link: 'text-(--ui-primary) font-semibold'
|
||||
link: 'text-primary font-semibold'
|
||||
},
|
||||
false: {
|
||||
link: 'text-(--ui-text-muted) font-medium'
|
||||
link: 'text-muted font-medium'
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
@@ -36,7 +36,7 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
active: false,
|
||||
to: true,
|
||||
class: {
|
||||
link: ['hover:text-(--ui-text)', options.theme.transitions && 'transition-colors']
|
||||
link: ['hover:text-default', options.theme.transitions && 'transition-colors']
|
||||
}
|
||||
}]
|
||||
})
|
||||
|
||||
@@ -86,51 +86,51 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
compoundVariants: [...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'solid',
|
||||
class: `text-(--ui-bg) bg-(--ui-${color}) hover:bg-(--ui-${color})/75 disabled:bg-(--ui-${color}) aria-disabled:bg-(--ui-${color}) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ui-${color})`
|
||||
class: `text-inverted bg-${color} hover:bg-${color}/75 disabled:bg-${color} aria-disabled:bg-${color} focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-${color}`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'outline',
|
||||
class: `ring ring-inset ring-(--ui-${color})/50 text-(--ui-${color}) hover:bg-(--ui-${color})/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-(--ui-${color})`
|
||||
class: `ring ring-inset ring-${color}/50 text-${color} hover:bg-${color}/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-${color}`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'soft',
|
||||
class: `text-(--ui-${color}) bg-(--ui-${color})/10 hover:bg-(--ui-${color})/15 focus:outline-none focus-visible:bg-(--ui-${color})/15 disabled:bg-(--ui-${color})/10 aria-disabled:bg-(--ui-${color})/10`
|
||||
class: `text-${color} bg-${color}/10 hover:bg-${color}/15 focus:outline-none focus-visible:bg-${color}/15 disabled:bg-${color}/10 aria-disabled:bg-${color}/10`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'subtle',
|
||||
class: `text-(--ui-${color}) ring ring-inset ring-(--ui-${color})/25 bg-(--ui-${color})/10 hover:bg-(--ui-${color})/15 disabled:bg-(--ui-${color})/10 aria-disabled:bg-(--ui-${color})/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-(--ui-${color})`
|
||||
class: `text-${color} ring ring-inset ring-${color}/25 bg-${color}/10 hover:bg-${color}/15 disabled:bg-${color}/10 aria-disabled:bg-${color}/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-${color}`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'ghost',
|
||||
class: `text-(--ui-${color}) hover:bg-(--ui-${color})/10 focus:outline-none focus-visible:bg-(--ui-${color})/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent`
|
||||
class: `text-${color} hover:bg-${color}/10 focus:outline-none focus-visible:bg-${color}/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent`
|
||||
})), ...(options.theme.colors || []).map((color: string) => ({
|
||||
color,
|
||||
variant: 'link',
|
||||
class: `text-(--ui-${color}) hover:text-(--ui-${color})/75 disabled:text-(--ui-${color}) aria-disabled:text-(--ui-${color}) focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-(--ui-${color})`
|
||||
class: `text-${color} hover:text-${color}/75 disabled:text-${color} aria-disabled:text-${color} focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-${color}`
|
||||
})), {
|
||||
color: 'neutral',
|
||||
variant: 'solid',
|
||||
class: 'text-(--ui-bg) bg-(--ui-bg-inverted) hover:bg-(--ui-bg-inverted)/90 disabled:bg-(--ui-bg-inverted) aria-disabled:bg-(--ui-bg-inverted) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ui-border-inverted)'
|
||||
class: 'text-inverted bg-inverted hover:bg-inverted/90 disabled:bg-inverted aria-disabled:bg-inverted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-inverted'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'outline',
|
||||
class: 'ring ring-inset ring-(--ui-border-accented) text-(--ui-text) bg-(--ui-bg) hover:bg-(--ui-bg-elevated) disabled:bg-(--ui-bg) aria-disabled:bg-(--ui-bg) focus:outline-none focus-visible:ring-2 focus-visible:ring-(--ui-border-inverted)'
|
||||
class: 'ring ring-inset ring-accented text-default bg-default hover:bg-elevated disabled:bg-default aria-disabled:bg-default focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'soft',
|
||||
class: 'text-(--ui-text) bg-(--ui-bg-elevated) hover:bg-(--ui-bg-accented)/75 focus:outline-none focus-visible:bg-(--ui-bg-accented)/75 disabled:bg-(--ui-bg-elevated) aria-disabled:bg-(--ui-bg-elevated)'
|
||||
class: 'text-default bg-elevated hover:bg-accented/75 focus:outline-none focus-visible:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'subtle',
|
||||
class: 'ring ring-inset ring-(--ui-border-accented) text-(--ui-text) bg-(--ui-bg-elevated) hover:bg-(--ui-bg-accented)/75 disabled:bg-(--ui-bg-elevated) aria-disabled:bg-(--ui-bg-elevated) focus:outline-none focus-visible:ring-2 focus-visible:ring-(--ui-border-inverted)'
|
||||
class: 'ring ring-inset ring-accented text-default bg-elevated hover:bg-accented/75 disabled:bg-elevated aria-disabled:bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
class: 'text-(--ui-text) hover:bg-(--ui-bg-elevated) focus:outline-none focus-visible:bg-(--ui-bg-elevated) hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent'
|
||||
class: 'text-default hover:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent'
|
||||
}, {
|
||||
color: 'neutral',
|
||||
variant: 'link',
|
||||
class: 'text-(--ui-text-muted) hover:text-(--ui-text) disabled:text-(--ui-text-muted) aria-disabled:text-(--ui-text-muted) focus:outline-none focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-(--ui-border-inverted)'
|
||||
class: 'text-muted hover:text-default disabled:text-muted aria-disabled:text-muted focus:outline-none focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-inverted'
|
||||
}, {
|
||||
size: 'xs',
|
||||
square: true,
|
||||
|
||||
@@ -12,17 +12,17 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
gridBody: 'grid',
|
||||
headCell: 'rounded-md',
|
||||
cell: 'relative text-center',
|
||||
cellTrigger: ['m-0.5 relative flex items-center justify-center rounded-full whitespace-nowrap focus-visible:ring-2 focus:outline-none data-disabled:text-(--ui-text-muted) data-unavailable:line-through data-unavailable:text-(--ui-text-muted) data-unavailable:pointer-events-none data-[selected]:text-(--ui-bg) data-today:font-semibold data-[outside-view]:text-(--ui-text-muted)', options.theme.transitions && 'transition']
|
||||
cellTrigger: ['m-0.5 relative flex items-center justify-center rounded-full whitespace-nowrap focus-visible:ring-2 focus:outline-none data-disabled:text-muted data-unavailable:line-through data-unavailable:text-muted data-unavailable:pointer-events-none data-[selected]:text-inverted data-today:font-semibold data-[outside-view]:text-muted', options.theme.transitions && 'transition']
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
...Object.fromEntries((options.theme.colors || []).map((color: string) => [color, {
|
||||
headCell: `text-(--ui-${color})`,
|
||||
cellTrigger: `focus-visible:ring-(--ui-${color}) data-[selected]:bg-(--ui-${color}) data-today:not-data-[selected]:text-(--ui-${color}) data-[highlighted]:bg-(--ui-${color})/20 hover:not-data-[selected]:bg-(--ui-${color})/20`
|
||||
headCell: `text-${color}`,
|
||||
cellTrigger: `focus-visible:ring-${color} data-[selected]:bg-${color} data-today:not-data-[selected]:text-${color} data-[highlighted]:bg-${color}/20 hover:not-data-[selected]:bg-${color}/20`
|
||||
}])),
|
||||
neutral: {
|
||||
headCell: 'text-(--ui-bg-inverted)',
|
||||
cellTrigger: 'focus-visible:ring-(--ui-border-inverted) data-[selected]:bg-(--ui-bg-inverted) data-today:not-data-[selected]:text-(--ui-bg-inverted) data-[highlighted]:bg-(--ui-bg-inverted)/20 hover:not-data-[selected]:bg-(--ui-bg-inverted)/10'
|
||||
headCell: 'text-highlighted',
|
||||
cellTrigger: 'focus-visible:ring-inverted data-[selected]:bg-inverted data-today:not-data-[selected]:text-inverted data-[highlighted]:bg-inverted/20 hover:not-data-[selected]:bg-inverted/10'
|
||||
}
|
||||
},
|
||||
size: {
|
||||
|
||||
@@ -8,16 +8,16 @@ export default {
|
||||
variants: {
|
||||
variant: {
|
||||
solid: {
|
||||
root: 'bg-(--ui-bg-inverted) text-(--ui-bg)'
|
||||
root: 'bg-inverted text-inverted'
|
||||
},
|
||||
outline: {
|
||||
root: 'bg-(--ui-bg) ring ring-(--ui-border) divide-y divide-(--ui-border)'
|
||||
root: 'bg-default ring ring-default divide-y divide-default'
|
||||
},
|
||||
soft: {
|
||||
root: 'bg-(--ui-bg-elevated)/50 divide-y divide-(--ui-border)'
|
||||
root: 'bg-elevated/50 divide-y divide-default'
|
||||
},
|
||||
subtle: {
|
||||
root: 'bg-(--ui-bg-elevated)/50 ring ring-(--ui-border) divide-y divide-(--ui-border)'
|
||||
root: 'bg-elevated/50 ring ring-default divide-y divide-default'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user