N
Nuxt3mo ago
S'h

UCalendar theming in Nuxt UI 4.1: custom palette + day-cell hover/variants

Hi! 👋 I’m using Nuxt 4.1 with Nuxt UI 4.1 and the UCalendar component. I’d like to fully customize its colors and states. Goals: Use a custom color (not just the built-in ones), and define lighter/darker variants. Change the hover color on day cells specifically (different from the base color). Generally understand the best way to theme the whole calendar (header, selected day, today, range, disabled days, hover, focus, etc.). Example of my current usage:
<UCalendar v-model="selectedDate" locale="fr-FR" color="info" class="w-full" />
Docs I’m referencing: https://ui.nuxt.com/components/calendar#fixed-weeks Questions: What’s the recommended way to register a custom palette and use it via the color prop (e.g., color="brand")? How can I override hover/focus/selected/today styles for individual day cells? Is there a :ui prop or class API that targets day cells and header elements? Should this be done via global theme config (e.g., app.config.ts), Tailwind tokens, or per-component overrides? If possible, could you share a small snippet showing the correct structure? Thanks in advance! 🙏
Nuxt UI
Vue Calendar Component - Nuxt UI
A calendar component for selecting single dates, multiple dates or date ranges.
6 Replies
kapa.ai
kapa.ai3mo ago
Hi @S'h. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Here’s a practical way to theme UCalendar in Nuxt UI 4.1, covering a custom palette, and precise control of day-cell states. 1) Register a custom color alias (e.g., brand) so you can use color="brand" - Define the color tokens in Tailwind (so utilities like bg-brand-500 exist), then alias it in Nuxt UI, and finally allow Nuxt UI to generate the variants. app/assets/css/main.css (Tailwind v4 tokens)
@import "tailwindcss";
@import "@nuxt/ui";

@theme static {
/* Example brand palette */
--color-brand-50: #F5F3FF;
--color-brand-100: #EDE9FE;
--color-brand-200: #DDD6FE;
--color-brand-300: #C4B5FD;
--color-brand-400: #A78BFA;
--color-brand-500: #8B5CF6;
--color-brand-600: #7C3AED;
--color-brand-700: #6D28D9;
--color-brand-800: #5B21B6;
--color-brand-900: #4C1D95;
--color-brand-950: #2E1065;
}
@import "tailwindcss";
@import "@nuxt/ui";

@theme static {
/* Example brand palette */
--color-brand-50: #F5F3FF;
--color-brand-100: #EDE9FE;
--color-brand-200: #DDD6FE;
--color-brand-300: #C4B5FD;
--color-brand-400: #A78BFA;
--color-brand-500: #8B5CF6;
--color-brand-600: #7C3AED;
--color-brand-700: #6D28D9;
--color-brand-800: #5B21B6;
--color-brand-900: #4C1D95;
--color-brand-950: #2E1065;
}
nuxt.config.ts (tell Nuxt UI that brand is a dynamic color)
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
theme: {
colors: ['primary', 'secondary', 'success', 'info', 'warning', 'error', 'brand']
}
}
})
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
theme: {
colors: ['primary', 'secondary', 'success', 'info', 'warning', 'error', 'brand']
}
}
})
app.config.ts (map the alias)
export default defineAppConfig({
ui: {
colors: {
brand: 'brand' // may also map to a Tailwind color name like 'indigo'
}
}
})
export default defineAppConfig({
ui: {
colors: {
brand: 'brand' // may also map to a Tailwind color name like 'indigo'
}
}
})
Now you can do: <UCalendar color="brand" />. When defining theme colors, you must use a Tailwind default color name or a custom one you defined in your CSS, as above. [Theme; Install (Nuxt) options] 2) Override hover/focus/selected/today on day cells The calendar exposes granular slots and variants. The “day cell button” is the cellTrigger slot. You can globally override (recommended) in app.config.ts, adding a color.brand variant that mirrors the built-ins, changing hover, focus, selected, today, etc. [Calendar theme; Theme config] app.config.ts (per-component global theme)
export default defineAppConfig({
ui: {
calendar: {
// You can also tweak slots like header, heading, headCell, etc.
variants: {
color: {
brand: {
headCell: 'text-brand',
// Customize states on the day cell button:
// - focus ring
// - selected day background
// - today (when not selected)
// - keyboard highlight range
// - hover (when not selected)
cellTrigger:
'focus-visible:ring-brand ' +
'data-[selected]:bg-brand ' +
'data-today:not-data-[selected]:text-brand ' +
'data-[highlighted]:bg-brand/20 ' +
'hover:not-data-[selected]:bg-brand/10'
}
}
}
}
}
})
export default defineAppConfig({
ui: {
calendar: {
// You can also tweak slots like header, heading, headCell, etc.
variants: {
color: {
brand: {
headCell: 'text-brand',
// Customize states on the day cell button:
// - focus ring
// - selected day background
// - today (when not selected)
// - keyboard highlight range
// - hover (when not selected)
cellTrigger:
'focus-visible:ring-brand ' +
'data-[selected]:bg-brand ' +
'data-today:not-data-[selected]:text-brand ' +
'data-[highlighted]:bg-brand/20 ' +
'hover:not-data-[selected]:bg-brand/10'
}
}
}
}
}
})
The structure and state data-attributes match the default calendar theme, so you can selectively change just what you need. [Calendar theme] 3) Per-instance overrides (fine-tuning) For a one-off change, use the ui prop to override specific slots (e.g., only hover on a single calendar). [Theme config (ui prop); Components theme (slots)]
<UCalendar
color="brand"
:ui="{
// tweak only this instance
header: 'flex items-center justify-between',
cellTrigger: 'hover:not-data-[selected]:bg-brand/15 focus-visible:ring-brand'
}"
/>
<UCalendar
color="brand"
:ui="{
// tweak only this instance
header: 'flex items-center justify-between',
cellTrigger: 'hover:not-data-[selected]:bg-brand/15 focus-visible:ring-brand'
}"
/>
4) What to customize where? - Tailwind tokens (@theme in CSS): define new palettes and design tokens (e.g., brand). [Theme] - Global Nuxt UI config (app.config.ts): set color aliases and component theme (slots/variants/defaults) app-wide. [Theme config; Install (Nuxt) options] - Per-component instance: use :ui for slot-level overrides; class for root element. [Theme config] Useful slots and states to target - Slots: header, heading, headCell (weekdays), cell, cellTrigger (day button), grid, gridRow, gridWeekDaysRow, body. [Calendar theme] - States via data-attributes on cellTrigger: - data-[selected] - data-today - data-[highlighted] (range/keyboard) - data-unavailable, data-disabled - data-[outside-view] These are already used in the default theme; you can override their styles as shown. [Calendar theme] That’s it: define brand in Tailwind tokens, register it as a dynamic color alias, and either globally customize the calendar’s variants (especially cellTrigger) or adjust per instance with :ui. [Theme; Calendar theme] ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@343478391942414339> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
S'h
S'hOP3mo ago
@kapa.ai
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: Sorry @S'h, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
S'h
S'hOP3mo ago
I’m using Nuxt (not plain Vue), so I only have a nuxt.config.ts. I put the ui section inside it, but the theme still doesn’t apply to the UCalendar. I added the following to nuxt.config.ts, but it’s not working: ui: { theme: { colors: [ "primary", "secondary", "success", "info", "warning", "brand", // added by me ], }, }, appConfig: { ui: { colors: { brand: "brand", // alias pointing to my Tailwind "brand" palette }, calendar: { variants: { color: { brand: { headCell: "text-brand-600", cellTrigger: [ "focus-visible:ring-brand-500", "data-[selected]:bg-brand-500", "data-[selected]:text-white", "data-today:not-data-[selected]:text-brand-600", "data-[highlighted]:bg-brand-100", "hover:not-data-[selected]:bg-brand-50", ].join(" "), }, }, }, }, }, }, @kapa.ai
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: Sorry @S'h, I am experiencing especially high traffic right now, please try again. :technologist:

Did you find this page helpful?