Community
Changelog
Release notes for Vue Functional Calendar.
All notable changes to this project are documented here.
Unreleased
Changed
- Range presets render as a quiet list on a divided rail instead of outlined buttons. The selected preset takes the range tint and the primary color.
- The clear range button is a text button that only darkens on hover.
- Default labels use sentence case:
Clear range,Clear ranges,Start dateandEnd date. Passlabelsto keep the old text.
3.1.1 - 2026-10-18
The package code is the same as 3.1.0. This release updates what npm shows.
Changed
- The README lists Relaticle as a sponsor, with light and dark logos.
repository.urluses thegit+httpsform npm expects.
Fixed
- The GetCopy sponsor logo in the README, whose old URL returned 404.
3.1.0 - 2026-10-18
The 3.0.0 release on npm was a Vue 2 build. 3.1.0 is the first Vue 3 release. Vue 2 apps stay on ^2.10.0. See MIGRATION.md.
Added
- A Vue 3 build with ESM, CJS and UMD bundles, an
exportsmap and type declarations. vue-functional-calendar/style.css, the stylesheet as a separate import.- Theming with
--vfc-*custom properties, and a dark mode throughisDark. - Keyboard navigation and an ARIA date grid, with focus management for modal calendars.
- The
localeprop, which derives day names, month names and the first day of the week fromIntl. - The
labelsprop, which translates every UI string. - The
presetsprop, with six built-in quick ranges and custom ranges. - A documentation site with live examples and a playground.
Changed
valueandinputbecamemodelValueandupdate:modelValue. Templates that usev-modelneed no change.- The plugin installs with
app.use(FunctionalCalendar, options). vueis a peer dependency,^3.3.0. The package has no runtime dependencies.- The SCSS
!defaultvariables are replaced by--vfc-*tokens. - The default look is redesigned. The
vfc-*class names are unchanged. - Deep imports from
src/no longer resolve. Import fromvue-functional-calendar. - The slide transition classes follow Vue 3:
.vfc-calendar-slide-*-enteris now-enter-from. See MIGRATION.md.
Fixed
- The badges of multiple date ranges count from 1, as the day labels do. The first range showed 0 at its start and -1 at its end.
- Week numbers with
sundayStartfollow ISO numbering of each row's Thursday. They were one lower. - Typed dates are validated.
31/02/2026is rejected, padded dates such as05/03/2026are accepted, and a value commits only when the date is complete. - A pasted or autofilled ISO date is reordered to
dateFormat, and pasted text that is not a date stays as pasted. - Typing with an input method editor no longer breaks the composition, and full-width digits are converted when it ends.
- Text typed after the date in a
displayTimeInputfield is kept, and the input is long enough to hold the time. - ArrowDown no longer opens the calendar while an IME composes, or when the input already handled the key.
- A navigation arrow slot that renders a focusable component is no longer wrapped in a second button.
- A model that is
null,{}, readonly, frozen or missing keys such asdateRangeno longer breaks the calendar. A plain object keeps being your object and gets the missing keys filled in. Assigning a new{}object clears the selection (#75, #117, #132). - A parent that binds a model holding only
multipleDateRangecan pick ranges without anInvalid Data Rangeerror. That model is read, never written to. - A preloaded
v-modelsurvivesnewCurrentDate, and a server render shows the bound selection. disabledDates,enabledDatesandmarkedDatesaccept dates with a leading zero, such as05/10/2026or2026-10-05. They were ignored (#153, #40).- A
dateRangein the model and amarkedDateRangewritten with leading zeros, such as08/10/2026, mark their start, end and days. They were ignored. - A
multipleDateRangewritten with leading zeros, such as06/10/2026, marks its start, end and days and shows its end button. A parent that setsdateRange.startordateRange.endtonullno longer makes the calendar throw. - Delete removes a multiple date range whose open start is written with a leading zero, and a preset shows as pressed when the selected date or range is written with leading zeros.
- A
selectedDateorselectedDatesentry in the model written with leading zeros, such as08/10/2026, marks its day, reports it as selected, keeps the keyboard tab stop on it, and is removed by a click on its day. - In a
isMultipleDateRangecalendar the range band no longer covers the numbers of the days inside a range. - The
minSelDaysandmaxSelDayshover preview counts whole calendar days, so it no longer shows one day too many or too few when the range crosses a daylight saving change. - An empty
{}v-model receives typed dates, time picker changes and cleared values. - The calendar no longer adds
inRangetoString.prototypeorgetWeekNumbertoDate.prototype, and two multi-range calendars with differentdateFormatvalues on one page each draw their ranges with their own format. - Side-by-side calendars could get the same internal key and reuse the wrong grid after navigation. Each grid now gets a unique key.
- A
localeon an engine withoutIntl.Localeno longer throws while mounting. The first day of the week falls back to the default. minSelDaysandmaxSelDayskeep the times of a range withwithTimePicker, and the time picker no longer throws on a range edge without a time.- The
minSelDaysextension of a range stops atlimitsand before disabled days instead of running past them. disabledDatesandenabledDatesapply to range clicks withwithTimePicker. A disabled date was selectable and an enabled one was rejected.- A rejected click on a
withTimePickerrange no longer rewrites the day, so a disabled date stays disabled and a second click cannot select it. - A modal with
isAutoCloseableandwithTimePickerstays open for the time picker and closes when the time picker is closed (#103, #49). - A modal that loses focus with the time picker open reopens on the day grid instead of the time picker.
- With
isMultipleDateRangeandminSelDays, starting the next range no longer rewrites the range that was just finished. withTimePickerwithisMultipleDateRangeno longer opens a time picker that edited the emptydateRange. The combination is unsupported and the ranges hold plain dates.- An invalid initial
multipleDateRangemodel raisesInvalid Data Rangethrough the app error handler, which Vue rethrows in development when none is set. With a handler, or in production, the calendar still renders and follows later valid models. - Picking a month or year with several calendars keeps them consecutive, updates
currentDate, emits the model and re-checkslimits. It emitschangedMonthwhen the month of the first visible calendar changes andchangedYearwhen its year changes, each with the first visible month as its date, so a view thatlimitsclamp reports what is on screen and an unchanged view reports nothing. - Every navigation move stays inside
limits: the year arrows,changeMonthStep,changeYearStep, the month and year pickers andChooseDateno longer overshoot, and the right arrow of a multi-calendar picker disables before a month pastmaxshows.ChooseDatereturnsfalsewhen the month is outsidelimits. - A multi-calendar picker no longer shows a month after
limits.max. The view starts early enough that the last calendar is themaxmonth, and keeps allcalendarsCountcalendars unless the limits span fewer months (#114). - With
isSeparately, each calendar disables its own arrows atlimitsby its own month. They followed the first calendar before. - The previous and next month arrows emit
changedYearwhen the visible year changes, as the year arrows do. A keyboard move across a year boundary emitschangedYeartoo. markedDates,markedDateRange,disabledDates,enabledDates,disabledDayNames,limits,calendarsCountandisDarkfollow later changes, as props and insideconfigs. A list that arrives after mount, a replaced list and an edited reactive list all update the calendar, and an equal object created again changes nothing. WithisSeparately, alimitsorcalendarsCountchange keeps the month of each grid (#2, #65, #78, #97, #101, #109, #142).- The tags input of
isMultipleDatePickerremoves a date with a labelled<button>(labels.removeDate) instead of an unnamed link, shows the date as text instead of HTML, names its input withlabels.addDate, and returns focus to the input after a removal. - The inputs of a modal calendar are
role="combobox"witharia-controlspointing at the dialog and anaria-labelfromlabels. A plain textbox witharia-expandedand a name fromtitlealone failed axe. - A screen reader announces the visible months when they change, through a visually hidden
aria-live="polite"region. The calendar's root no longer takes focus with a namelesstabindex="0". - Today has
aria-current="date"and "Today" in its label. The first and last day of a range end their label with "range start" or "range end", and the number badge of a multiple date range is drawn from adata-numberattribute so the label of a range day contains its visible text. New labels:today,rangeStart,rangeEnd. - Week numbers are named "Week 42" for a screen reader (
labels.week), the start and end toggles of the time picker reportaria-pressed, and the time line no longer carries a fixedid="time-line"that duplicated across calendars. - The month and year picker is a named
role="group"(labels.chooseMonth,labels.chooseYear), its year is a<button class="vfc-top-date">instead of an<h2>, and it closes when focus moves out of it, so Tab no longer walks into the grid hidden beneath it. - In a right to left page ArrowLeft and ArrowRight move to the day on that side, the navigation chevrons mirror under
dir="rtl", and the range bands, their rounded ends, the week number divider and the range badges sit on the correct side. Left to right rendering is unchanged. - The type declarations compile on Vue 3.3 and 3.4. They imported
EmitsToPropsandPublicProps, which exist from Vue 3.5. PreMonth,NextMonth,PreYear,NextYearandChooseDateare typed as returningboolean, andconfigsand the plugin options reject the options that are always props, such asdisplayTimeInputandnewCurrentDate, which were ignored there.package.jsonis importable through theexportsmap, and jsDelivr serves the UMD build.placeholder: trueno longer throws while rendering the inputs. A placeholder that is not a string falls back to thedateFormat.- In forced colors modes (Windows high contrast) the selected days, range ends, days inside a range, today, the selected preset, month, year and time, and the range badges stay visible. They were drawn with a background colour only and disappeared.
- With
isSeparately, a calendar added whencalendarsCountgrows stays insidelimitsinstead of showing a month afterlimits.max. - In forced colors modes the close and remove crosses stay visible, and a disabled today keeps its line-through next to the underline.
2.10.0 - 2026-10-17
The last Vue 2 line. It ships a built bundle and types.
Added
- TypeScript declarations in
index.d.ts. unpkgandjsdelivrentries that point at the UMD build.
Changed
vuemoved topeerDependencies, andcore-jsmoved todevDependencies, because the polyfills are inlined at build time.- The build uses Dart Sass instead of
node-sass, which no longer installs on current Node. - The package builds before it is published.
Fixed
mainpointed atindex.js, which imports the raw.vuesources, so every consumer had to compile the SCSS. It now points at the built bundle, so Vite projects without Sass work (#169).- TypeScript reported TS7016 for the missing declarations (#169).