[UInputDate] Zod validation not triggering when value is updated via UCalendar (DatePicker mode)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.9k
- Forks
- 1.1k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 57
Description
Environment
| Operating system | Linux 6.6.87.2-microsoft-standard-WSL2 |
| CPU | AMD Ryzen 5 3600 6-Core Processor (8 cores) |
| Node.js version | v24.13.0 |
| nuxt/cli version | 3.31.3 |
| Package manager | pnpm@10.26.1 |
| Nuxt version | 4.2.2 |
| Nitro version | 2.12.9 |
| Builder | vite@7.3.0 |
| Config | compatibilityDate, css, devtools, eslint, modules, routeRules |
| Modules | @nuxt/eslint@1.12.1, @nuxt/ui@4.4.0, @nuxt/a11y@1.0.0-alpha.1, @nuxt/test-utils@3.23.0 |
Is this bug related to Nuxt or Vue?
Nuxt
Package
v4.x
Version
v4.4.0
Reproduction
Can't reproduce on codesandbox (troubleshooting to install latest Nuxt/Nuxt UI versions)
<script setup lang="ts">
import { z } from 'zod'
import { CalendarDate } from '@internationalized/date'
import type { FormSubmitEvent } from '#ui/types'
const schema = z.object({
date: z.custom<CalendarDate>(
(val) => val && typeof val === 'object' && 'toDate' in val,
{ message: 'Invalid date' }
)
.transform((calendarDate) => calendarDate.toDate('UTC'))
.pipe(
z.date().max(new Date(), { message: "Too young!" })
)
})
type Schema = z.output<typeof schema>
const state = reactive({
date: undefined,
range: undefined
})
const submittedData = ref<Schema | null>(null)
const inputDate = useTemplateRef('inputDate')
async function onSubmit(event: FormSubmitEvent<Schema>) {
submittedData.value = event.data
}
const { emitFormInput } = useFormField({ name: "date" })
function onUpdate(open: boolean) {
if (!open) {
emitFormInput()
console.log('Calendar closed ' + open);
}
}
</script>
<template>
<UPage>
<UPageHeader
title="InputDate Test"
description="Testing Nuxt UI InputDate component with Zod validation."
:links="[{ label: 'Back to Home', to: '/', icon: 'i-lucide-arrow-left', color: 'neutral', variant: 'ghost' }]"
/>
<UPageBody>
<UForm
:schema="schema"
:state="state"
class="max-w-xl space-y-8"
@submit="onSubmit"
>
<UFormField
label="Single Date Selection"
name="date"
description="Select a single date using UInputDate"
required
>
<UInputDate ref="inputDate" v-model="state.date">
<template #trailing>
<UPopover :reference="inputDate?.inputsRef[3]?.$el" @update:open="onUpdate">
<UButton
color="neutral"
variant="link"
size="sm"
icon="i-lucide-calendar"
aria-label="Select a date"
class="px-0"
/>
<template #content>
<UCalendar v-model="state.date" class="p-2" />
</template>
</UPopover>
</template>
</UInputDate>
</UFormField>
<div class="flex items-center gap-3">
<UButton type="submit">
Submit Form
</UButton>
<UButton
color="neutral"
variant="outline"
@click="state.date = undefined; state.range = undefined; submittedData = null"
>
Reset
</UButton>
</div>
</UForm>
<div v-if="submittedData" class="mt-12 p-6 rounded-lg border border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50">
<h4 class="text-sm font-bold uppercase tracking-wider text-gray-500 mb-4">Submitted Data</h4>
<pre class="text-sm overflow-auto">{{ JSON.stringify(submittedData, null, 2) }}</pre>
</div>
</UPageBody>
</UPage>
</template>
Description
I am encountering an issue with form validation when using the UInputDate component configured as a DatePicker (with UPopover and UCalendar inside the #trailing slot), as seen in the official documentation examples.
When the date is typed manually into the input field, the Zod schema validation triggers correctly. However, when the date is selected via the UCalendar inside the popover, the v-model updates visually, but the UForm validation does not seem to catch the change event, leaving the field in an invalid state or not clearing existing errors.
It seems the UInputDate does not emit the necessary change or blur events to the parent UForm when the value is mutated programmatically via the internal UCalendar.
Additional context
I try to use emitFormInput because of this issue: https://github.com/nuxt/ui/issues/4803
Logs
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided UInputDate, UCalendar, UForm, and useFormField reproduction, then inspect how the calendar update reaches form validation. Compare manual input events with the UCalendar v-model update and check whether the field receives the needed validation event. Done means selecting a date through the popover updates or clears the Zod validation state without the workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100