@@ -288,15 +288,17 @@ import {
288288 getFirstDay ,
289289} from ' @nextcloud/l10n'
290290import VueDatePicker from ' @vuepic/vue-datepicker'
291+ import { parse } from ' date-fns/parse'
291292import { computed , toRef , useTemplateRef } from ' vue'
292293import NcIconSvgWrapper from ' ../NcIconSvgWrapper/NcIconSvgWrapper.vue'
293294import NcTimezonePicker from ' ../NcTimezonePicker/NcTimezonePicker.vue'
294295import { t } from ' ../../l10n.ts'
295296import NcButton from ' ../NcButton/index.ts'
296- import { getDateFormat , getDateRangeFormat , getDateTimeFormat , getDateTimeRangeFormat , getMonthFormat , getTimeFormat , getTimeRangeFormat , getYearFormat } from ' ./format.ts'
297+ import { getDateFormat , getDateTimeFormat , getMonthFormat , getTimeFormat , getWeekFormat , getYearFormat } from ' ./format.ts'
297298import useDateFnsLocale from ' ./useDateFnsLocale.ts'
298299
299300type LibraryFormatOptions = VueDatePickerProps [' format' ]
301+ type LibraryTextInputOptions = VueDatePickerProps [' textInput' ]
300302
301303/**
302304 * The preselected IANA time zone ID for the time zone picker,
@@ -344,11 +346,13 @@ const props = withDefaults(defineProps<{
344346 confirm? : boolean
345347
346348 /**
347- * Preview format for the picker input field.
349+ * Format for the picker input field.
348350 * Can either be a string of Unicode tokens or a function that takes a Date object
349351 * or for range picker an array of two dates, and returns the formatted date as string.
350352 *
351- * @default Intl.DateTimeFormat is used to format dates and times
353+ * If no format is provided, localized date and time formats are used.
354+ * If a function is provided users cannot use text input.
355+ *
352356 * @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
353357 */
354358 format? : string | ((date : Date ) => string ) | ((dates : [Date , Date ]) => string )
@@ -533,47 +537,74 @@ const placeholderFallback = computed(() => {
533537})
534538
535539const dateFnsLocale = useDateFnsLocale (toRef (() => props .locale ))
536- const dateFnsLocaleCode = computed (() => dateFnsLocale .value ? .code || ' default ' )
540+ const dateFnsLocaleCode = computed (() => dateFnsLocale .value .code )
537541
538542/**
539543 * The date (time) formatting to be used by the library.
540- * We use the provided format if possible, otherwise we provide a formatting function
541- * which uses the browsers Intl API to format the date / time in the current users locale .
544+ * We use the provided format if possible, otherwise we provide a localized formatting
545+ * using ` date-fns/locale' which is mostly similiar to Intl.DateTime formating .
542546 */
543547const realFormat = computed <LibraryFormatOptions >(() => {
544548 if (props .format ) {
545549 // we can cast the type here as in this case its either string
546550 // function `(Date) => string` or `([Date, Date]) => string` where we cast to `(Date[]) => string` here.
547551 return props .format as LibraryFormatOptions
548- } else if (props .type === ' week' ) {
549- // cannot format weeks with Intl.
550- return ' RR-II'
551552 }
552553
553- const locale = getCanonicalLocale ()
554554 switch (props .type ) {
555555 case ' date' :
556- return getDateFormat (locale )
557556 case ' date-range' :
558- return getDateRangeFormat ( locale )
557+ return getDateFormat ( dateFnsLocale . value )
559558 case ' time' :
560- return getTimeFormat (locale )
561559 case ' time-range' :
562- return getTimeRangeFormat ( locale )
560+ return getTimeFormat ( )
563561 case ' datetime' :
564- return getDateTimeFormat (locale )
565562 case ' datetime-range' :
566- return getDateTimeRangeFormat ( locale )
563+ return getDateTimeFormat ( dateFnsLocale . value )
567564 case ' month' :
568- return getMonthFormat (locale )
565+ return getMonthFormat (dateFnsLocale . value )
569566 case ' year' :
570- return getYearFormat (locale )
567+ return getYearFormat (dateFnsLocale .value )
568+ case ' week' :
569+ return getWeekFormat ()
571570 }
572571
573572 // fallback to default formatting
574573 return undefined
575574})
576575
576+ const textInput = computed <LibraryTextInputOptions >(() => {
577+ const realFormatVal = realFormat .value
578+ if (typeof realFormatVal === ' function' ) {
579+ // NOTE We could provide a format string through `textInput.format`.
580+ // Then Vuepic uses it when the user focuses the input.
581+ // But this feature has a bug.
582+ // It does not respect the provided locale when formatting.
583+ // See https://github.com/Vuepic/vue-datepicker/issues/1286
584+ //
585+ // Possible workarounds that seem not to be worth implementing for now:
586+ // - replace input value when user focuses the input by ourselves
587+
588+ // Disable text input if user provided a format function.
589+ // We do not know how to parse such values.
590+ return false
591+ }
592+
593+ if (typeof realFormatVal === ' string' ) {
594+ return {
595+ // This should not be required in Vuepic because `format` is automatically used for parsing.
596+ // But v11 has a bug because the format string ist cut off wrongly.
597+ // This is fixed in v12.1.0 and can then be simplified.
598+ // See https://github.com/Vuepic/vue-datepicker/issues/1208
599+ format : (value : string ) => {
600+ return parse (value , realFormatVal , new Date (), { locale: (dateFnsLocale .value ) })
601+ },
602+ }
603+ }
604+
605+ return true
606+ })
607+
577608const pickerType = computed (() => ({
578609 timePicker: props .type === ' time' || props .type === ' time-range' ,
579610 yearPicker: props .type === ' year' ,
@@ -788,7 +819,6 @@ function sameDay(a: Date, b: Date): boolean {
788819 :placeholder =" placeholder ?? placeholderFallback "
789820 :format =" realFormat "
790821 :formatLocale =" dateFnsLocale "
791- :locale
792822 :minDate =" calcMinMaxTime .minDate "
793823 :maxDate =" calcMinMaxTime .maxDate "
794824 :minTime =" calcMinMaxTime .minTime "
@@ -800,7 +830,7 @@ function sameDay(a: Date, b: Date): boolean {
800830 sixWeeks="fair"
801831 :inline
802832 :teleport =" appendToBody ? (targetElement || undefined ) : false "
803- textInput
833+ : textInput
804834 :weekNumName
805835 :weekNumbers =" showWeekNumber ? { type: ' iso' } : undefined "
806836 :weekStart
0 commit comments