Advertisement
hendridm

PrimeVue Custom Calendar Component

Aug 8th, 2023 (edited)
1,741
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 115.17 KB | Source Code | 1 0
  1. <template>
  2.     <span ref="container" :id="id" :class="containerClass">
  3.         <input
  4.            v-if="!inline"
  5.            :ref="inputRef"
  6.            :id="inputId"
  7.            type="text"
  8.            role="combobox"
  9.            :class="['p-inputtext p-component', inputClass]"
  10.            :style="inputStyle"
  11.            :placeholder="placeholder"
  12.            aria-autocomplete="none"
  13.            aria-haspopup="dialog"
  14.            :aria-expanded="overlayVisible"
  15.            :aria-controls="panelId"
  16.            :aria-labelledby="ariaLabelledby"
  17.            :aria-label="ariaLabel"
  18.            inputmode="none"
  19.            :disabled="disabled"
  20.            :readonly="!manualInput || readonly"
  21.            :tabindex="0"
  22.            @input="onInput"
  23.            @click="onInputClick"
  24.            @focus="onFocus"
  25.            @blur="onBlur"
  26.            @keydown="onKeyDown"
  27.            v-bind="inputProps"
  28.        />
  29.         <CalendarButton
  30.            v-if="showIcon"
  31.            :icon="icon"
  32.            class="p-datepicker-trigger"
  33.            :disabled="disabled"
  34.            @click="onButtonClick"
  35.            type="button"
  36.            :aria-label="$primevue.config.locale.chooseDate"
  37.            aria-haspopup="dialog"
  38.            :aria-expanded="overlayVisible"
  39.            :aria-controls="panelId"
  40.        />
  41.         <Portal :appendTo="appendTo" :disabled="inline">
  42.             <transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @after-leave="onOverlayAfterLeave" @leave="onOverlayLeave">
  43.                 <div
  44.                    v-if="inline || overlayVisible"
  45.                    :ref="overlayRef"
  46.                    :id="panelId"
  47.                    :class="panelStyleClass"
  48.                    :style="panelStyle"
  49.                    :role="inline ? null : 'dialog'"
  50.                    :aria-modal="inline ? null : 'true'"
  51.                    :aria-label="$primevue.config.locale.chooseDate"
  52.                    @click="onOverlayClick"
  53.                    @keydown="onOverlayKeyDown"
  54.                    @mouseup="onOverlayMouseUp"
  55.                    v-bind="panelProps"
  56.                >
  57.                     <template v-if="!timeOnly">
  58.                         <div class="p-datepicker-group-container">
  59.                             <div v-for="(month, groupIndex) of months" :key="month.month + month.year" class="p-datepicker-group">
  60.                                 <div class="p-datepicker-header">
  61.                                     <slot name="header"></slot>
  62.                                     <button
  63.                                        v-show="showOtherMonths ? groupIndex === 0 : false"
  64.                                        v-ripple
  65.                                        class="p-datepicker-prev p-link"
  66.                                        @click="onPrevButtonClick"
  67.                                        type="button"
  68.                                        @keydown="onContainerButtonKeydown"
  69.                                        :disabled="disabled"
  70.                                        :aria-label="currentView === 'year' ? $primevue.config.locale.prevDecade : currentView === 'month' ? $primevue.config.locale.prevYear : $primevue.config.locale.prevMonth"
  71.                                    >
  72.                                         <span :class="['p-datepicker-prev-icon', previousIcon]" />
  73.                                     </button>
  74.                                     <div class="p-datepicker-title">
  75.                                         <button
  76.                                            v-if="currentView === 'date'"
  77.                                            type="button"
  78.                                            @click="switchToMonthView"
  79.                                            @keydown="onContainerButtonKeydown"
  80.                                            class="p-datepicker-month p-link"
  81.                                            :disabled="switchViewButtonDisabled"
  82.                                            :aria-label="$primevue.config.locale.chooseMonth"
  83.                                        >
  84.                                             {{ getMonthName(month.month) }}
  85.                                         </button>
  86.                                         <button
  87.                                            v-if="currentView !== 'year'"
  88.                                            type="button"
  89.                                            @click="switchToYearView"
  90.                                            @keydown="onContainerButtonKeydown"
  91.                                            class="p-datepicker-year p-link"
  92.                                            :disabled="switchViewButtonDisabled"
  93.                                            :aria-label="$primevue.config.locale.chooseYear"
  94.                                        >
  95.                                             {{ getYear(month) }}
  96.                                         </button>
  97.                                         <span v-if="currentView === 'year'" class="p-datepicker-decade">
  98.                                             <slot name="decade" :years="yearPickerValues"> {{ yearPickerValues[0] }} - {{ yearPickerValues[yearPickerValues.length - 1] }} </slot>
  99.                                         </span>
  100.                                     </div>
  101.                                     <button
  102.                                        v-show="showOtherMonths ? (numberOfMonths === 1 ? true : groupIndex === numberOfMonths - 1) : false"
  103.                                        v-ripple
  104.                                        class="p-datepicker-next p-link"
  105.                                        @click="onNextButtonClick"
  106.                                        type="button"
  107.                                        @keydown="onContainerButtonKeydown"
  108.                                        :disabled="disabled"
  109.                                        :aria-label="currentView === 'year' ? $primevue.config.locale.nextDecade : currentView === 'month' ? $primevue.config.locale.nextYear : $primevue.config.locale.nextMonth"
  110.                                    >
  111.                                         <span :class="['p-datepicker-next-icon', nextIcon]" />
  112.                                     </button>
  113.                                 </div>
  114.                                 <div v-if="currentView === 'date'" class="p-datepicker-calendar-container">
  115.                                     <table class="p-datepicker-calendar" role="grid">
  116.                                         <thead>
  117.                                             <tr>
  118.                                                 <th v-if="showWeek" scope="col" class="p-datepicker-weekheader p-disabled">
  119.                                                     <span>{{ weekHeaderLabel }}</span>
  120.                                                 </th>
  121.                                                 <th v-for="weekDay of weekDays" :key="weekDay" scope="col" :abbr="weekDay">
  122.                                                     <span>{{ weekDay }}</span>
  123.                                                 </th>
  124.                                             </tr>
  125.                                         </thead>
  126.                                         <tbody>
  127.                                             <tr v-for="(week, i) of month.dates" :key="week[0].day + '' + week[0].month">
  128.                                                 <td v-if="showWeek" class="p-datepicker-weeknumber">
  129.                                                     <span class="p-disabled">
  130.                                                         <span v-if="month.weekNumbers[i] < 10" style="visibility: hidden">0</span>
  131.                                                         {{ month.weekNumbers[i] }}
  132.                                                     </span>
  133.                                                 </td>
  134.                                                 <td v-for="date of week" :key="date.day + '' + date.month" :aria-label="date.day" :class="{ 'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today }">
  135.                                                     <span
  136.                                                        v-ripple
  137.                                                        :class="{ 'p-highlight': isSelected(date), 'p-disabled': !date.selectable }"
  138.                                                        @click="onDateSelect($event, date)"
  139.                                                        draggable="false"
  140.                                                        @keydown="onDateCellKeydown($event, date, groupIndex)"
  141.                                                        :aria-selected="isSelected(date)"
  142.                                                    >
  143.                                                         <slot name="date" :date="date">{{ date.day }}</slot>
  144.                                                     </span>
  145.                                                     <div v-if="isSelected(date)" class="p-hidden-accessible" aria-live="polite">
  146.                                                         {{ date.day }}
  147.                                                     </div>
  148.                                                 </td>
  149.                                             </tr>
  150.                                         </tbody>
  151.                                     </table>
  152.                                 </div>
  153.                             </div>
  154.                         </div>
  155.                         <div v-if="currentView === 'month'" class="p-monthpicker">
  156.                             <span v-for="(m, i) of monthPickerValues" :key="m" v-ripple @click="onMonthSelect($event, i)" @keydown="onMonthCellKeydown($event, i)" class="p-monthpicker-month" :class="{ 'p-highlight': isMonthSelected(i) }">
  157.                                 {{ m }}
  158.                                 <div v-if="isMonthSelected(i)" class="p-hidden-accessible" aria-live="polite">
  159.                                     {{ m }}
  160.                                 </div>
  161.                             </span>
  162.                         </div>
  163.                         <div v-if="currentView === 'year'" class="p-yearpicker">
  164.                             <span v-for="y of yearPickerValues" :key="y" v-ripple @click="onYearSelect($event, y)" @keydown="onYearCellKeydown($event, y)" class="p-yearpicker-year" :class="{ 'p-highlight': isYearSelected(y) }">
  165.                                 {{ y }}
  166.                                 <div v-if="isYearSelected(y)" class="p-hidden-accessible" aria-live="polite">
  167.                                     {{ y }}
  168.                                 </div>
  169.                             </span>
  170.                         </div>
  171.                     </template>
  172.                     <div v-if="(showTime || timeOnly) && currentView === 'date'" class="p-timepicker">
  173.                         <div class="p-hour-picker">
  174.                             <button
  175.                                v-ripple
  176.                                class="p-link"
  177.                                :aria-label="$primevue.config.locale.nextHour"
  178.                                @mousedown="onTimePickerElementMouseDown($event, 0, 1)"
  179.                                @mouseup="onTimePickerElementMouseUp($event)"
  180.                                @keydown="onContainerButtonKeydown"
  181.                                @mouseleave="onTimePickerElementMouseLeave()"
  182.                                @keydown.enter="onTimePickerElementMouseDown($event, 0, 1)"
  183.                                @keydown.space="onTimePickerElementMouseDown($event, 0, 1)"
  184.                                @keyup.enter="onTimePickerElementMouseUp($event)"
  185.                                @keyup.space="onTimePickerElementMouseUp($event)"
  186.                                type="button"
  187.                            >
  188.                                 <span :class="incrementIcon" />
  189.                             </button>
  190.                             <span>{{ formattedCurrentHour }}</span>
  191.                             <button
  192.                                v-ripple
  193.                                class="p-link"
  194.                                :aria-label="$primevue.config.locale.prevHour"
  195.                                @mousedown="onTimePickerElementMouseDown($event, 0, -1)"
  196.                                @mouseup="onTimePickerElementMouseUp($event)"
  197.                                @keydown="onContainerButtonKeydown"
  198.                                @mouseleave="onTimePickerElementMouseLeave()"
  199.                                @keydown.enter="onTimePickerElementMouseDown($event, 0, -1)"
  200.                                @keydown.space="onTimePickerElementMouseDown($event, 0, -1)"
  201.                                @keyup.enter="onTimePickerElementMouseUp($event)"
  202.                                @keyup.space="onTimePickerElementMouseUp($event)"
  203.                                type="button"
  204.                            >
  205.                                 <span :class="decrementIcon" />
  206.                             </button>
  207.                         </div>
  208.                         <div class="p-separator">
  209.                             <span>{{ timeSeparator }}</span>
  210.                         </div>
  211.                         <div class="p-minute-picker">
  212.                             <button
  213.                                v-ripple
  214.                                class="p-link"
  215.                                :aria-label="$primevue.config.locale.nextMinute"
  216.                                @mousedown="onTimePickerElementMouseDown($event, 1, 1)"
  217.                                @mouseup="onTimePickerElementMouseUp($event)"
  218.                                @keydown="onContainerButtonKeydown"
  219.                                :disabled="disabled"
  220.                                @mouseleave="onTimePickerElementMouseLeave()"
  221.                                @keydown.enter="onTimePickerElementMouseDown($event, 1, 1)"
  222.                                @keydown.space="onTimePickerElementMouseDown($event, 1, 1)"
  223.                                @keyup.enter="onTimePickerElementMouseUp($event)"
  224.                                @keyup.space="onTimePickerElementMouseUp($event)"
  225.                                type="button"
  226.                            >
  227.                                 <span :class="incrementIcon" />
  228.                             </button>
  229.                             <span>{{ formattedCurrentMinute }}</span>
  230.                             <button
  231.                                v-ripple
  232.                                class="p-link"
  233.                                :aria-label="$primevue.config.locale.prevMinute"
  234.                                @mousedown="onTimePickerElementMouseDown($event, 1, -1)"
  235.                                @mouseup="onTimePickerElementMouseUp($event)"
  236.                                @keydown="onContainerButtonKeydown"
  237.                                :disabled="disabled"
  238.                                @mouseleave="onTimePickerElementMouseLeave()"
  239.                                @keydown.enter="onTimePickerElementMouseDown($event, 1, -1)"
  240.                                @keydown.space="onTimePickerElementMouseDown($event, 1, -1)"
  241.                                @keyup.enter="onTimePickerElementMouseUp($event)"
  242.                                @keyup.space="onTimePickerElementMouseUp($event)"
  243.                                type="button"
  244.                            >
  245.                                 <span :class="decrementIcon" />
  246.                             </button>
  247.                         </div>
  248.                         <div v-if="showSeconds" class="p-separator">
  249.                             <span>{{ timeSeparator }}</span>
  250.                         </div>
  251.                         <div v-if="showSeconds" class="p-second-picker">
  252.                             <button
  253.                                v-ripple
  254.                                class="p-link"
  255.                                :aria-label="$primevue.config.locale.nextSecond"
  256.                                @mousedown="onTimePickerElementMouseDown($event, 2, 1)"
  257.                                @mouseup="onTimePickerElementMouseUp($event)"
  258.                                @keydown="onContainerButtonKeydown"
  259.                                :disabled="disabled"
  260.                                @mouseleave="onTimePickerElementMouseLeave()"
  261.                                @keydown.enter="onTimePickerElementMouseDown($event, 2, 1)"
  262.                                @keydown.space="onTimePickerElementMouseDown($event, 2, 1)"
  263.                                @keyup.enter="onTimePickerElementMouseUp($event)"
  264.                                @keyup.space="onTimePickerElementMouseUp($event)"
  265.                                type="button"
  266.                            >
  267.                                 <span :class="incrementIcon" />
  268.                             </button>
  269.                             <span>{{ formattedCurrentSecond }}</span>
  270.                             <button
  271.                                v-ripple
  272.                                class="p-link"
  273.                                :aria-label="$primevue.config.locale.prevSecond"
  274.                                @mousedown="onTimePickerElementMouseDown($event, 2, -1)"
  275.                                @mouseup="onTimePickerElementMouseUp($event)"
  276.                                @keydown="onContainerButtonKeydown"
  277.                                :disabled="disabled"
  278.                                @mouseleave="onTimePickerElementMouseLeave()"
  279.                                @keydown.enter="onTimePickerElementMouseDown($event, 2, -1)"
  280.                                @keydown.space="onTimePickerElementMouseDown($event, 2, -1)"
  281.                                @keyup.enter="onTimePickerElementMouseUp($event)"
  282.                                @keyup.space="onTimePickerElementMouseUp($event)"
  283.                                type="button"
  284.                            >
  285.                                 <span :class="decrementIcon" />
  286.                             </button>
  287.                         </div>
  288.                         <div v-if="hourFormat == '12'" class="p-separator">
  289.                             <span>{{ timeSeparator }}</span>
  290.                         </div>
  291.                         <div v-if="hourFormat == '12'" class="p-ampm-picker">
  292.                             <button v-ripple class="p-link" :aria-label="$primevue.config.locale.am" @click="toggleAMPM($event)" type="button" :disabled="disabled">
  293.                                 <span :class="incrementIcon" />
  294.                             </button>
  295.                             <span>{{ pm ? $primevue.config.locale.pm : $primevue.config.locale.am }}</span>
  296.                             <button v-ripple class="p-link" :aria-label="$primevue.config.locale.pm" @click="toggleAMPM($event)" type="button" :disabled="disabled">
  297.                                 <span :class="decrementIcon" />
  298.                             </button>
  299.                         </div>
  300.                     </div>
  301.                     <div v-if="showButtonBar" class="p-datepicker-buttonbar">
  302.                         <CalendarButton type="button" :label="todayLabel" @click="onTodayButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown" />
  303.                         <CalendarButton type="button" :label="clearLabel" @click="onClearButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown" />
  304.                     </div>
  305.                     <slot name="footer"></slot>
  306.                 </div>
  307.             </transition>
  308.         </Portal>
  309.     </span>
  310. </template>
  311.  
  312. <script>
  313. import Button from 'primevue/button';
  314. import OverlayEventBus from 'primevue/overlayeventbus';
  315. import Portal from 'primevue/portal';
  316. import Ripple from 'primevue/ripple';
  317. import { ConnectedOverlayScrollHandler, DomHandler, UniqueComponentId, ZIndexUtils } from 'primevue/utils';
  318.  
  319. export default {
  320.     name: 'Calendar',
  321.     emits: ['show', 'hide', 'input', 'month-change', 'year-change', 'date-select', 'update:modelValue', 'today-click', 'clear-click', 'focus', 'blur', 'keydown'],
  322.     props: {
  323.         modelValue: null,
  324.         selectionMode: {
  325.             type: String,
  326.             default: 'single'
  327.         },
  328.         dateFormat: {
  329.             type: String,
  330.             default: null
  331.         },
  332.         inline: {
  333.             type: Boolean,
  334.             default: false
  335.         },
  336.         showOtherMonths: {
  337.             type: Boolean,
  338.             default: true
  339.         },
  340.         selectOtherMonths: {
  341.             type: Boolean,
  342.             default: false
  343.         },
  344.         showIcon: {
  345.             type: Boolean,
  346.             default: false
  347.         },
  348.         icon: {
  349.             type: String,
  350.             default: 'pi pi-calendar'
  351.         },
  352.         previousIcon: {
  353.             type: String,
  354.             default: 'pi pi-chevron-left'
  355.         },
  356.         nextIcon: {
  357.             type: String,
  358.             default: 'pi pi-chevron-right'
  359.         },
  360.         incrementIcon: {
  361.             type: String,
  362.             default: 'pi pi-chevron-up'
  363.         },
  364.         decrementIcon: {
  365.             type: String,
  366.             default: 'pi pi-chevron-down'
  367.         },
  368.         numberOfMonths: {
  369.             type: Number,
  370.             default: 1
  371.         },
  372.         responsiveOptions: Array,
  373.         view: {
  374.             type: String,
  375.             default: 'date'
  376.         },
  377.         touchUI: {
  378.             type: Boolean,
  379.             default: false
  380.         },
  381.         monthNavigator: {
  382.             type: Boolean,
  383.             default: false
  384.         },
  385.         yearNavigator: {
  386.             type: Boolean,
  387.             default: false
  388.         },
  389.         yearRange: {
  390.             type: String,
  391.             default: null
  392.         },
  393.         minDate: {
  394.             type: Date,
  395.             value: null
  396.         },
  397.         maxDate: {
  398.             type: Date,
  399.             value: null
  400.         },
  401.         disabledDates: {
  402.             type: Array,
  403.             value: null
  404.         },
  405.         disabledDays: {
  406.             type: Array,
  407.             value: null
  408.         },
  409.         maxDateCount: {
  410.             type: Number,
  411.             value: null
  412.         },
  413.         showOnFocus: {
  414.             type: Boolean,
  415.             default: true
  416.         },
  417.         autoZIndex: {
  418.             type: Boolean,
  419.             default: true
  420.         },
  421.         baseZIndex: {
  422.             type: Number,
  423.             default: 0
  424.         },
  425.         showButtonBar: {
  426.             type: Boolean,
  427.             default: false
  428.         },
  429.         shortYearCutoff: {
  430.             type: String,
  431.             default: '+10'
  432.         },
  433.         showTime: {
  434.             type: Boolean,
  435.             default: false
  436.         },
  437.         timeOnly: {
  438.             type: Boolean,
  439.             default: false
  440.         },
  441.         hourFormat: {
  442.             type: String,
  443.             default: '24'
  444.         },
  445.         stepHour: {
  446.             type: Number,
  447.             default: 1
  448.         },
  449.         stepMinute: {
  450.             type: Number,
  451.             default: 1
  452.         },
  453.         stepSecond: {
  454.             type: Number,
  455.             default: 1
  456.         },
  457.         showSeconds: {
  458.             type: Boolean,
  459.             default: false
  460.         },
  461.         hideOnDateTimeSelect: {
  462.             type: Boolean,
  463.             default: false
  464.         },
  465.         hideOnRangeSelection: {
  466.             type: Boolean,
  467.             default: false
  468.         },
  469.         timeSeparator: {
  470.             type: String,
  471.             default: ':'
  472.         },
  473.         showWeek: {
  474.             type: Boolean,
  475.             default: false
  476.         },
  477.         manualInput: {
  478.             type: Boolean,
  479.             default: true
  480.         },
  481.         appendTo: {
  482.             type: String,
  483.             default: 'body'
  484.         },
  485.         disabled: {
  486.             type: Boolean,
  487.             default: false
  488.         },
  489.         readonly: {
  490.             type: Boolean,
  491.             default: false
  492.         },
  493.         placeholder: {
  494.             type: String,
  495.             default: null
  496.         },
  497.         id: {
  498.             type: String,
  499.             default: null
  500.         },
  501.         inputId: {
  502.             type: String,
  503.             default: null
  504.         },
  505.         inputClass: {
  506.             type: String,
  507.             default: null
  508.         },
  509.         inputStyle: {
  510.             type: null,
  511.             default: null
  512.         },
  513.         inputProps: {
  514.             type: null,
  515.             default: null
  516.         },
  517.         panelClass: {
  518.             type: String,
  519.             default: null
  520.         },
  521.         panelStyle: {
  522.             type: null,
  523.             default: null
  524.         },
  525.         panelProps: {
  526.             type: null,
  527.             default: null
  528.         },
  529.         'aria-labelledby': {
  530.             type: String,
  531.             default: null
  532.         },
  533.         'aria-label': {
  534.             type: String,
  535.             default: null
  536.         }
  537.     },
  538.     navigationState: null,
  539.     timePickerChange: false,
  540.     scrollHandler: null,
  541.     outsideClickListener: null,
  542.     maskClickListener: null,
  543.     resizeListener: null,
  544.     overlay: null,
  545.     input: null,
  546.     mask: null,
  547.     timePickerTimer: null,
  548.     preventFocus: false,
  549.     typeUpdate: false,
  550.     data() {
  551.         return {
  552.             currentMonth: null,
  553.             currentYear: null,
  554.             currentHour: null,
  555.             currentMinute: null,
  556.             currentSecond: null,
  557.             pm: null,
  558.             focused: false,
  559.             overlayVisible: false,
  560.             currentView: this.view
  561.         };
  562.     },
  563.     watch: {
  564.         modelValue(newValue) {
  565.             this.updateCurrentMetaData();
  566.  
  567.             if (!this.typeUpdate && !this.inline && this.input) {
  568.                this.input.value = this.formatValue(newValue);
  569.             }
  570.  
  571.             this.typeUpdate = false;
  572.         },
  573.         showTime() {
  574.             this.updateCurrentMetaData();
  575.         },
  576.         months() {
  577.             if (this.overlay) {
  578.                 if (!this.focused) {
  579.                     if (this.inline) {
  580.                         this.preventFocus = true;
  581.                     }
  582.  
  583.                     setTimeout(this.updateFocus, 0);
  584.                 }
  585.             }
  586.         },
  587.         numberOfMonths() {
  588.             this.destroyResponsiveStyleElement();
  589.             this.createResponsiveStyle();
  590.         },
  591.         responsiveOptions() {
  592.             this.destroyResponsiveStyleElement();
  593.             this.createResponsiveStyle();
  594.         },
  595.         currentView() {
  596.             Promise.resolve(null).then(() => this.alignOverlay());
  597.         }
  598.     },
  599.     created() {
  600.         this.updateCurrentMetaData();
  601.     },
  602.     mounted() {
  603.         this.createResponsiveStyle();
  604.  
  605.         if (this.inline) {
  606.             this.overlay && this.overlay.setAttribute(this.attributeSelector, '');
  607.  
  608.             if (!this.disabled) {
  609.                 this.preventFocus = true;
  610.                 this.initFocusableCell();
  611.  
  612.                 if (this.numberOfMonths === 1) {
  613.                     this.overlay.style.width = DomHandler.getOuterWidth(this.$el) + 'px';
  614.                 }
  615.             }
  616.         } else {
  617.             this.input.value = this.formatValue(this.modelValue);
  618.         }
  619.     },
  620.     updated() {
  621.         if (this.overlay) {
  622.             this.preventFocus = true;
  623.             this.updateFocus();
  624.         }
  625.  
  626.         if (this.input && this.selectionStart != null && this.selectionEnd != null) {
  627.            this.input.selectionStart = this.selectionStart;
  628.             this.input.selectionEnd = this.selectionEnd;
  629.             this.selectionStart = null;
  630.             this.selectionEnd = null;
  631.         }
  632.     },
  633.     beforeUnmount() {
  634.         if (this.timePickerTimer) {
  635.             clearTimeout(this.timePickerTimer);
  636.         }
  637.  
  638.         if (this.mask) {
  639.             this.destroyMask();
  640.         }
  641.  
  642.         this.destroyResponsiveStyleElement();
  643.  
  644.         this.unbindOutsideClickListener();
  645.         this.unbindResizeListener();
  646.  
  647.         if (this.scrollHandler) {
  648.             this.scrollHandler.destroy();
  649.             this.scrollHandler = null;
  650.         }
  651.  
  652.         if (this.overlay && this.autoZIndex) {
  653.            ZIndexUtils.clear(this.overlay);
  654.         }
  655.  
  656.         this.overlay = null;
  657.     },
  658.     methods: {
  659.         isComparable() {
  660.             return this.modelValue != null && typeof this.modelValue !== 'string';
  661.         },
  662.         isSelected(dateMeta) {
  663.             if (!this.isComparable()) {
  664.                 return false;
  665.             }
  666.  
  667.             if (this.modelValue) {
  668.                 if (this.isSingleSelection()) {
  669.                     return this.isDateEquals(this.modelValue, dateMeta);
  670.                 } else if (this.isMultipleSelection()) {
  671.                     let selected = false;
  672.  
  673.                     for (let date of this.modelValue) {
  674.                         selected = this.isDateEquals(date, dateMeta);
  675.  
  676.                         if (selected) {
  677.                             break;
  678.                         }
  679.                     }
  680.  
  681.                     return selected;
  682.                 } else if (this.isRangeSelection()) {
  683.                     if (this.modelValue[1]) return this.isDateEquals(this.modelValue[0], dateMeta) || this.isDateEquals(this.modelValue[1], dateMeta) || this.isDateBetween(this.modelValue[0], this.modelValue[1], dateMeta);
  684.                     else {
  685.                         return this.isDateEquals(this.modelValue[0], dateMeta);
  686.                     }
  687.                 }
  688.             }
  689.  
  690.             return false;
  691.         },
  692.         isMonthSelected(month) {
  693.             if (this.isComparable()) {
  694.                 let value = this.isRangeSelection() ? this.modelValue[0] : this.modelValue;
  695.  
  696.                 return !this.isMultipleSelection() ? value.getMonth() === month && value.getFullYear() === this.currentYear : false;
  697.             }
  698.  
  699.             return false;
  700.         },
  701.         isYearSelected(year) {
  702.             if (this.isComparable()) {
  703.                 let value = this.isRangeSelection() ? this.modelValue[0] : this.modelValue;
  704.  
  705.                 return !this.isMultipleSelection() && this.isComparable() ? value.getFullYear() === year : false;
  706.             }
  707.  
  708.             return false;
  709.         },
  710.         isDateEquals(value, dateMeta) {
  711.             if (value) return value.getDate() === dateMeta.day && value.getMonth() === dateMeta.month && value.getFullYear() === dateMeta.year;
  712.             else return false;
  713.         },
  714.         isDateBetween(start, end, dateMeta) {
  715.             let between = false;
  716.  
  717.             if (start && end) {
  718.                let date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
  719.  
  720.                 return start.getTime() <= date.getTime() && end.getTime() >= date.getTime();
  721.             }
  722.  
  723.             return between;
  724.         },
  725.         getFirstDayOfMonthIndex(month, year) {
  726.             let day = new Date();
  727.  
  728.             day.setDate(1);
  729.             day.setMonth(month);
  730.             day.setFullYear(year);
  731.  
  732.             let dayIndex = day.getDay() + this.sundayIndex;
  733.  
  734.             return dayIndex >= 7 ? dayIndex - 7 : dayIndex;
  735.         },
  736.         getDaysCountInMonth(month, year) {
  737.             return 32 - this.daylightSavingAdjust(new Date(year, month, 32)).getDate();
  738.         },
  739.         getDaysCountInPrevMonth(month, year) {
  740.             let prev = this.getPreviousMonthAndYear(month, year);
  741.  
  742.             return this.getDaysCountInMonth(prev.month, prev.year);
  743.         },
  744.         getPreviousMonthAndYear(month, year) {
  745.             let m, y;
  746.  
  747.             if (month === 0) {
  748.                 m = 11;
  749.                 y = year - 1;
  750.             } else {
  751.                 m = month - 1;
  752.                 y = year;
  753.             }
  754.  
  755.             return { month: m, year: y };
  756.         },
  757.         getNextMonthAndYear(month, year) {
  758.             let m, y;
  759.  
  760.             if (month === 11) {
  761.                 m = 0;
  762.                 y = year + 1;
  763.             } else {
  764.                 m = month + 1;
  765.                 y = year;
  766.             }
  767.  
  768.             return { month: m, year: y };
  769.         },
  770.         daylightSavingAdjust(date) {
  771.             if (!date) {
  772.                 return null;
  773.             }
  774.  
  775.             date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
  776.  
  777.             return date;
  778.         },
  779.         isToday(today, day, month, year) {
  780.             return today.getDate() === day && today.getMonth() === month && today.getFullYear() === year;
  781.         },
  782.         isSelectable(day, month, year, otherMonth) {
  783.             let validMin = true;
  784.             let validMax = true;
  785.             let validDate = true;
  786.             let validDay = true;
  787.  
  788.             if (otherMonth && !this.selectOtherMonths) {
  789.                return false;
  790.             }
  791.  
  792.             if (this.minDate) {
  793.                 if (this.minDate.getFullYear() > year) {
  794.                     validMin = false;
  795.                 } else if (this.minDate.getFullYear() === year) {
  796.                     if (this.minDate.getMonth() > month) {
  797.                         validMin = false;
  798.                     } else if (this.minDate.getMonth() === month) {
  799.                         if (this.minDate.getDate() > day) {
  800.                             validMin = false;
  801.                         }
  802.                     }
  803.                 }
  804.             }
  805.  
  806.             if (this.maxDate) {
  807.                 if (this.maxDate.getFullYear() < year) {
  808.                    validMax = false;
  809.                } else if (this.maxDate.getFullYear() === year) {
  810.                    if (this.maxDate.getMonth() < month) {
  811.                        validMax = false;
  812.                    } else if (this.maxDate.getMonth() === month) {
  813.                        if (this.maxDate.getDate() < day) {
  814.                            validMax = false;
  815.                        }
  816.                    }
  817.                }
  818.            }
  819.  
  820.            if (this.disabledDates) {
  821.                validDate = !this.isDateDisabled(day, month, year);
  822.            }
  823.  
  824.            if (this.disabledDays) {
  825.                validDay = !this.isDayDisabled(day, month, year);
  826.            }
  827.  
  828.            return validMin && validMax && validDate && validDay;
  829.        },
  830.        onOverlayEnter(el) {
  831.            el.setAttribute(this.attributeSelector, '');
  832.  
  833.            if (this.autoZIndex) {
  834.                if (this.touchUI) ZIndexUtils.set('modal', el, this.baseZIndex || this.$primevue.config.zIndex.modal);
  835.                else ZIndexUtils.set('overlay', el, this.baseZIndex || this.$primevue.config.zIndex.overlay);
  836.            }
  837.  
  838.            this.alignOverlay();
  839.            this.$emit('show');
  840.        },
  841.        onOverlayEnterComplete() {
  842.            this.bindOutsideClickListener();
  843.            this.bindScrollListener();
  844.            this.bindResizeListener();
  845.        },
  846.        onOverlayAfterLeave(el) {
  847.            if (this.autoZIndex) {
  848.                ZIndexUtils.clear(el);
  849.            }
  850.        },
  851.        onOverlayLeave() {
  852.            this.currentView = this.view;
  853.            this.unbindOutsideClickListener();
  854.            this.unbindScrollListener();
  855.            this.unbindResizeListener();
  856.            this.$emit('hide');
  857.  
  858.            if (this.mask) {
  859.                this.disableModality();
  860.            }
  861.  
  862.            this.overlay = null;
  863.        },
  864.        onPrevButtonClick(event) {
  865.            if (this.showOtherMonths) {
  866.                this.navigationState = { backward: true, button: true };
  867.                this.navBackward(event);
  868.            }
  869.        },
  870.        onNextButtonClick(event) {
  871.            if (this.showOtherMonths) {
  872.                this.navigationState = { backward: false, button: true };
  873.                this.navForward(event);
  874.            }
  875.        },
  876.        navBackward(event) {
  877.            event.preventDefault();
  878.  
  879.            if (!this.isEnabled()) {
  880.                return;
  881.            }
  882.  
  883.            if (this.currentView === 'month') {
  884.                this.decrementYear();
  885.            } else if (this.currentView === 'year') {
  886.                this.decrementDecade();
  887.            } else {
  888.                if (event.shiftKey) {
  889.                    this.decrementYear();
  890.                } else {
  891.                    if (this.currentMonth === 0) {
  892.                        this.currentMonth = 11;
  893.                        this.decrementYear();
  894.                    } else {
  895.                        this.currentMonth--;
  896.                    }
  897.  
  898.                    this.$emit('month-change', { month: this.currentMonth + 1, year: this.currentYear });
  899.                }
  900.            }
  901.        },
  902.        navForward(event) {
  903.            event.preventDefault();
  904.  
  905.            if (!this.isEnabled()) {
  906.                return;
  907.            }
  908.  
  909.            if (this.currentView === 'month') {
  910.                this.incrementYear();
  911.            } else if (this.currentView === 'year') {
  912.                this.incrementDecade();
  913.            } else {
  914.                if (event.shiftKey) {
  915.                    this.incrementYear();
  916.                } else {
  917.                    if (this.currentMonth === 11) {
  918.                        this.currentMonth = 0;
  919.                        this.incrementYear();
  920.                    } else {
  921.                        this.currentMonth++;
  922.                    }
  923.  
  924.                    this.$emit('month-change', { month: this.currentMonth + 1, year: this.currentYear });
  925.                }
  926.            }
  927.        },
  928.        decrementYear() {
  929.            this.currentYear--;
  930.        },
  931.        decrementDecade() {
  932.            this.currentYear = this.currentYear - 10;
  933.        },
  934.        incrementYear() {
  935.            this.currentYear++;
  936.        },
  937.        incrementDecade() {
  938.            this.currentYear = this.currentYear + 10;
  939.        },
  940.        switchToMonthView(event) {
  941.            this.currentView = 'month';
  942.            setTimeout(this.updateFocus, 0);
  943.            event.preventDefault();
  944.        },
  945.        switchToYearView(event) {
  946.            this.currentView = 'year';
  947.            setTimeout(this.updateFocus, 0);
  948.            event.preventDefault();
  949.        },
  950.        isEnabled() {
  951.            return !this.disabled && !this.readonly;
  952.        },
  953.        updateCurrentTimeMeta(date) {
  954.            let currentHour = date.getHours();
  955.  
  956.            if (this.hourFormat === '12') {
  957.                this.pm = currentHour > 11;
  958.  
  959.                 if (currentHour >= 12) currentHour = currentHour == 12 ? 12 : currentHour - 12;
  960.                 else currentHour = currentHour == 0 ? 12 : currentHour;
  961.             }
  962.  
  963.             this.currentHour = Math.floor(currentHour / this.stepHour) * this.stepHour;
  964.             this.currentMinute = Math.floor(date.getMinutes() / this.stepMinute) * this.stepMinute;
  965.             this.currentSecond = Math.floor(date.getSeconds() / this.stepSecond) * this.stepSecond;
  966.         },
  967.         bindOutsideClickListener() {
  968.             if (!this.outsideClickListener) {
  969.                 this.outsideClickListener = (event) => {
  970.                     if (this.overlayVisible && this.isOutsideClicked(event)) {
  971.                        this.overlayVisible = false;
  972.                     }
  973.                 };
  974.  
  975.                 document.addEventListener('mousedown', this.outsideClickListener);
  976.             }
  977.         },
  978.         unbindOutsideClickListener() {
  979.             if (this.outsideClickListener) {
  980.                 document.removeEventListener('mousedown', this.outsideClickListener);
  981.                 this.outsideClickListener = null;
  982.             }
  983.         },
  984.         bindScrollListener() {
  985.             if (!this.scrollHandler) {
  986.                 this.scrollHandler = new ConnectedOverlayScrollHandler(this.$refs.container, () => {
  987.                     if (this.overlayVisible) {
  988.                         this.overlayVisible = false;
  989.                     }
  990.                 });
  991.             }
  992.  
  993.             this.scrollHandler.bindScrollListener();
  994.         },
  995.         unbindScrollListener() {
  996.             if (this.scrollHandler) {
  997.                 this.scrollHandler.unbindScrollListener();
  998.             }
  999.         },
  1000.         bindResizeListener() {
  1001.             if (!this.resizeListener) {
  1002.                 this.resizeListener = () => {
  1003.                     if (this.overlayVisible && !DomHandler.isTouchDevice()) {
  1004.                        this.overlayVisible = false;
  1005.                     }
  1006.                 };
  1007.  
  1008.                 window.addEventListener('resize', this.resizeListener);
  1009.             }
  1010.         },
  1011.         unbindResizeListener() {
  1012.             if (this.resizeListener) {
  1013.                 window.removeEventListener('resize', this.resizeListener);
  1014.                 this.resizeListener = null;
  1015.             }
  1016.         },
  1017.         isOutsideClicked(event) {
  1018.             return !(this.$el.isSameNode(event.target) || this.isNavIconClicked(event) || this.$el.contains(event.target) || (this.overlay && this.overlay.contains(event.target)));
  1019.         },
  1020.         isNavIconClicked(event) {
  1021.             return (
  1022.                 DomHandler.hasClass(event.target, 'p-datepicker-prev') ||
  1023.                 DomHandler.hasClass(event.target, 'p-datepicker-prev-icon') ||
  1024.                 DomHandler.hasClass(event.target, 'p-datepicker-next') ||
  1025.                 DomHandler.hasClass(event.target, 'p-datepicker-next-icon')
  1026.             );
  1027.         },
  1028.         alignOverlay() {
  1029.             if (this.touchUI) {
  1030.                 this.enableModality();
  1031.             } else if (this.overlay) {
  1032.                 if (this.appendTo === 'self' || this.inline) {
  1033.                     DomHandler.relativePosition(this.overlay, this.$el);
  1034.                 } else {
  1035.                     if (this.view === 'date') {
  1036.                         this.overlay.style.width = DomHandler.getOuterWidth(this.overlay) + 'px';
  1037.                         this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
  1038.                     } else {
  1039.                         this.overlay.style.width = DomHandler.getOuterWidth(this.$el) + 'px';
  1040.                     }
  1041.  
  1042.                     DomHandler.absolutePosition(this.overlay, this.$el);
  1043.                 }
  1044.             }
  1045.         },
  1046.         onButtonClick() {
  1047.             if (this.isEnabled()) {
  1048.                 if (!this.overlayVisible) {
  1049.                     this.input.focus();
  1050.                     this.overlayVisible = true;
  1051.                 } else {
  1052.                     this.overlayVisible = false;
  1053.                 }
  1054.             }
  1055.         },
  1056.         isDateDisabled(day, month, year) {
  1057.             if (this.disabledDates) {
  1058.                 for (let disabledDate of this.disabledDates) {
  1059.                     if (disabledDate.getFullYear() === year && disabledDate.getMonth() === month && disabledDate.getDate() === day) {
  1060.                        return true;
  1061.                     }
  1062.                 }
  1063.             }
  1064.  
  1065.             return false;
  1066.         },
  1067.         isDayDisabled(day, month, year) {
  1068.             if (this.disabledDays) {
  1069.                 let weekday = new Date(year, month, day);
  1070.                 let weekdayNumber = weekday.getDay();
  1071.  
  1072.                 return this.disabledDays.indexOf(weekdayNumber) !== -1;
  1073.             }
  1074.  
  1075.             return false;
  1076.         },
  1077.         onMonthDropdownChange(value) {
  1078.             this.currentMonth = parseInt(value);
  1079.             this.$emit('month-change', { month: this.currentMonth + 1, year: this.currentYear });
  1080.         },
  1081.         onYearDropdownChange(value) {
  1082.             this.currentYear = parseInt(value);
  1083.             this.$emit('year-change', { month: this.currentMonth + 1, year: this.currentYear });
  1084.         },
  1085.         onDateSelect(event, dateMeta) {
  1086.             if (this.disabled || !dateMeta.selectable) {
  1087.                 return;
  1088.             }
  1089.  
  1090.             DomHandler.find(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled)').forEach((cell) => (cell.tabIndex = -1));
  1091.  
  1092.             if (event) {
  1093.                 event.currentTarget.focus();
  1094.             }
  1095.  
  1096.             if (this.isMultipleSelection() && this.isSelected(dateMeta)) {
  1097.                let newValue = this.modelValue.filter((date) => !this.isDateEquals(date, dateMeta));
  1098.  
  1099.                 this.updateModel(newValue);
  1100.             } else {
  1101.                 if (this.shouldSelectDate(dateMeta)) {
  1102.                     if (dateMeta.otherMonth) {
  1103.                         this.currentMonth = dateMeta.month;
  1104.                         this.currentYear = dateMeta.year;
  1105.                         this.selectDate(dateMeta);
  1106.                     } else {
  1107.                         this.selectDate(dateMeta);
  1108.                     }
  1109.                 }
  1110.             }
  1111.  
  1112.             if (this.isSingleSelection() && (!this.showTime || this.hideOnDateTimeSelect)) {
  1113.                setTimeout(() => {
  1114.                    if (this.input) {
  1115.                        this.input.focus();
  1116.                     }
  1117.  
  1118.                     this.overlayVisible = false;
  1119.                 }, 150);
  1120.             }
  1121.         },
  1122.         selectDate(dateMeta) {
  1123.             let date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
  1124.  
  1125.             if (this.showTime) {
  1126.                 if (this.hourFormat === '12' && this.pm && this.currentHour != 12) date.setHours(this.currentHour + 12);
  1127.                 else date.setHours(this.currentHour);
  1128.  
  1129.                 date.setMinutes(this.currentMinute);
  1130.                 date.setSeconds(this.currentSecond);
  1131.             }
  1132.  
  1133.             if (this.minDate && this.minDate > date) {
  1134.                date = this.minDate;
  1135.                 this.currentHour = date.getHours();
  1136.                 this.currentMinute = date.getMinutes();
  1137.                 this.currentSecond = date.getSeconds();
  1138.             }
  1139.  
  1140.             if (this.maxDate && this.maxDate < date) {
  1141.                date = this.maxDate;
  1142.                 this.currentHour = date.getHours();
  1143.                 this.currentMinute = date.getMinutes();
  1144.                 this.currentSecond = date.getSeconds();
  1145.             }
  1146.  
  1147.             let modelVal = null;
  1148.  
  1149.             if (this.isSingleSelection()) {
  1150.                 modelVal = date;
  1151.             } else if (this.isMultipleSelection()) {
  1152.                 modelVal = this.modelValue ? [...this.modelValue, date] : [date];
  1153.             } else if (this.isRangeSelection()) {
  1154.                 if (this.modelValue && this.modelValue.length) {
  1155.                    let startDate = this.modelValue[0];
  1156.                     let endDate = this.modelValue[1];
  1157.  
  1158.                     if (!endDate && date.getTime() >= startDate.getTime()) {
  1159.                        endDate = date;
  1160.                     } else {
  1161.                         startDate = date;
  1162.                         endDate = null;
  1163.                     }
  1164.  
  1165.                     modelVal = [startDate, endDate];
  1166.                 } else {
  1167.                     modelVal = [date, null];
  1168.                 }
  1169.             }
  1170.  
  1171.             if (modelVal !== null) {
  1172.                 this.updateModel(modelVal);
  1173.             }
  1174.  
  1175.             if (this.isRangeSelection() && this.hideOnRangeSelection && modelVal[1] !== null) {
  1176.                setTimeout(() => {
  1177.                    this.overlayVisible = false;
  1178.                 }, 150);
  1179.             }
  1180.  
  1181.             this.$emit('date-select', date);
  1182.         },
  1183.         updateModel(value) {
  1184.             this.$emit('update:modelValue', value);
  1185.         },
  1186.         shouldSelectDate() {
  1187.             if (this.isMultipleSelection()) return this.maxDateCount != null ? this.maxDateCount > (this.modelValue ? this.modelValue.length : 0) : true;
  1188.             else return true;
  1189.         },
  1190.         isSingleSelection() {
  1191.             return this.selectionMode === 'single';
  1192.         },
  1193.         isRangeSelection() {
  1194.             return this.selectionMode === 'range';
  1195.         },
  1196.         isMultipleSelection() {
  1197.             return this.selectionMode === 'multiple';
  1198.         },
  1199.         formatValue(value) {
  1200.             if (typeof value === 'string') {
  1201.                 return value;
  1202.             }
  1203.  
  1204.             let formattedValue = '';
  1205.  
  1206.             if (value) {
  1207.                 try {
  1208.                     if (this.isSingleSelection()) {
  1209.                         formattedValue = this.formatDateTime(value);
  1210.                     } else if (this.isMultipleSelection()) {
  1211.                         for (let i = 0; i < value.length; i++) {
  1212.                            let dateAsString = this.formatDateTime(value[i]);
  1213.  
  1214.                            formattedValue += dateAsString;
  1215.  
  1216.                            if (i !== value.length - 1) {
  1217.                                formattedValue += ', ';
  1218.                            }
  1219.                        }
  1220.                    } else if (this.isRangeSelection()) {
  1221.                        if (value && value.length) {
  1222.                            let startDate = value[0];
  1223.                            let endDate = value[1];
  1224.  
  1225.                            formattedValue = this.formatDateTime(startDate);
  1226.  
  1227.                            if (endDate) {
  1228.                                formattedValue += ' - ' + this.formatDateTime(endDate);
  1229.                            }
  1230.                        }
  1231.                    }
  1232.                } catch (err) {
  1233.                    formattedValue = value;
  1234.                }
  1235.            }
  1236.  
  1237.            return formattedValue;
  1238.        },
  1239.        formatDateTime(date) {
  1240.            let formattedValue = null;
  1241.  
  1242.            if (date) {
  1243.                if (this.timeOnly) {
  1244.                    formattedValue = this.formatTime(date);
  1245.                } else {
  1246.                    formattedValue = this.formatDate(date, this.datePattern);
  1247.  
  1248.                    if (this.showTime) {
  1249.                        formattedValue += ' ' + this.formatTime(date);
  1250.                    }
  1251.                }
  1252.            }
  1253.  
  1254.            return formattedValue;
  1255.        },
  1256.        formatDate(date, format) {
  1257.            if (!date) {
  1258.                return '';
  1259.            }
  1260.  
  1261.            let iFormat;
  1262.  
  1263.            const lookAhead = (match) => {
  1264.                     const matches = iFormat + 1 < format.length && format.charAt(iFormat + 1) === match;
  1265.  
  1266.                    if (matches) {
  1267.                        iFormat++;
  1268.                    }
  1269.  
  1270.                    return matches;
  1271.                },
  1272.                formatNumber = (match, value, len) => {
  1273.                     let num = '' + value;
  1274.  
  1275.                     if (lookAhead(match)) {
  1276.                         while (num.length < len) {
  1277.                            num = '0' + num;
  1278.                        }
  1279.                    }
  1280.  
  1281.                    return num;
  1282.                },
  1283.                formatName = (match, value, shortNames, longNames) => {
  1284.                     return lookAhead(match) ? longNames[value] : shortNames[value];
  1285.                 };
  1286.  
  1287.             let output = '';
  1288.             let literal = false;
  1289.  
  1290.             if (date) {
  1291.                 for (iFormat = 0; iFormat < format.length; iFormat++) {
  1292.                    if (literal) {
  1293.                        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
  1294.                            literal = false;
  1295.                        } else {
  1296.                            output += format.charAt(iFormat);
  1297.                        }
  1298.                    } else {
  1299.                        switch (format.charAt(iFormat)) {
  1300.                            case 'd':
  1301.                                output += formatNumber('d', date.getDate(), 2);
  1302.                                break;
  1303.                            case 'D':
  1304.                                output += formatName('D', date.getDay(), this.$primevue.config.locale.dayNamesShort, this.$primevue.config.locale.dayNames);
  1305.                                break;
  1306.                            case 'o':
  1307.                                output += formatNumber('o', Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
  1308.                                break;
  1309.                            case 'm':
  1310.                                output += formatNumber('m', date.getMonth() + 1, 2);
  1311.                                break;
  1312.                            case 'M':
  1313.                                output += formatName('M', date.getMonth(), this.$primevue.config.locale.monthNamesShort, this.$primevue.config.locale.monthNames);
  1314.                                break;
  1315.                            case 'y':
  1316.                                output += lookAhead('y') ? date.getFullYear() : (date.getFullYear() % 100 < 10 ? '0' : '') + (date.getFullYear() % 100);
  1317.                                break;
  1318.                            case '@':
  1319.                                output += date.getTime();
  1320.                                break;
  1321.                            case '!':
  1322.                                output += date.getTime() * 10000 + this.ticksTo1970;
  1323.                                break;
  1324.                            case "'":
  1325.                                if (lookAhead("'")) {
  1326.                                    output += "'";
  1327.                                } else {
  1328.                                    literal = true;
  1329.                                }
  1330.  
  1331.                                break;
  1332.                            default:
  1333.                                output += format.charAt(iFormat);
  1334.                        }
  1335.                    }
  1336.                }
  1337.            }
  1338.  
  1339.            return output;
  1340.        },
  1341.        formatTime(date) {
  1342.            if (!date) {
  1343.                return '';
  1344.            }
  1345.  
  1346.            let output = '';
  1347.            let hours = date.getHours();
  1348.            let minutes = date.getMinutes();
  1349.            let seconds = date.getSeconds();
  1350.  
  1351.            if (this.hourFormat === '12' && hours > 11 && hours !== 12) {
  1352.                hours -= 12;
  1353.             }
  1354.  
  1355.             if (this.hourFormat === '12') {
  1356.                 output += hours === 0 ? 12 : hours < 10 ? '0' + hours : hours;
  1357.            } else {
  1358.                output += hours < 10 ? '0' + hours : hours;
  1359.            }
  1360.  
  1361.            output += ':';
  1362.            output += minutes < 10 ? '0' + minutes : minutes;
  1363.  
  1364.            if (this.showSeconds) {
  1365.                output += ':';
  1366.                output += seconds < 10 ? '0' + seconds : seconds;
  1367.            }
  1368.  
  1369.            if (this.hourFormat === '12') {
  1370.                output += date.getHours() > 11 ? ` ${this.$primevue.config.locale.pm}` : ` ${this.$primevue.config.locale.am}`;
  1371.             }
  1372.  
  1373.             return output;
  1374.         },
  1375.         onTodayButtonClick(event) {
  1376.             let date = new Date();
  1377.             let dateMeta = {
  1378.                 day: date.getDate(),
  1379.                 month: date.getMonth(),
  1380.                 year: date.getFullYear(),
  1381.                 otherMonth: date.getMonth() !== this.currentMonth || date.getFullYear() !== this.currentYear,
  1382.                 today: true,
  1383.                 selectable: true
  1384.             };
  1385.  
  1386.             this.onDateSelect(null, dateMeta);
  1387.             this.$emit('today-click', date);
  1388.             event.preventDefault();
  1389.         },
  1390.         onClearButtonClick(event) {
  1391.             this.updateModel(null);
  1392.             this.overlayVisible = false;
  1393.             this.$emit('clear-click', event);
  1394.             event.preventDefault();
  1395.         },
  1396.         onTimePickerElementMouseDown(event, type, direction) {
  1397.             if (this.isEnabled()) {
  1398.                 this.repeat(event, null, type, direction);
  1399.                 event.preventDefault();
  1400.             }
  1401.         },
  1402.         onTimePickerElementMouseUp(event) {
  1403.             if (this.isEnabled()) {
  1404.                 this.clearTimePickerTimer();
  1405.                 this.updateModelTime();
  1406.                 event.preventDefault();
  1407.             }
  1408.         },
  1409.         onTimePickerElementMouseLeave() {
  1410.             this.clearTimePickerTimer();
  1411.         },
  1412.         repeat(event, interval, type, direction) {
  1413.             let i = interval || 500;
  1414.  
  1415.             this.clearTimePickerTimer();
  1416.             this.timePickerTimer = setTimeout(() => {
  1417.                 this.repeat(event, 100, type, direction);
  1418.             }, i);
  1419.  
  1420.             switch (type) {
  1421.                 case 0:
  1422.                     if (direction === 1) this.incrementHour(event);
  1423.                     else this.decrementHour(event);
  1424.                     break;
  1425.  
  1426.                 case 1:
  1427.                     if (direction === 1) this.incrementMinute(event);
  1428.                     else this.decrementMinute(event);
  1429.                     break;
  1430.  
  1431.                 case 2:
  1432.                     if (direction === 1) this.incrementSecond(event);
  1433.                     else this.decrementSecond(event);
  1434.                     break;
  1435.             }
  1436.         },
  1437.         convertTo24Hour(hours, pm) {
  1438.             if (this.hourFormat == '12') {
  1439.                 if (hours === 12) {
  1440.                     return pm ? 12 : 0;
  1441.                 } else {
  1442.                     return pm ? hours + 12 : hours;
  1443.                 }
  1444.             }
  1445.  
  1446.             return hours;
  1447.         },
  1448.         validateTime(hour, minute, second, pm) {
  1449.             let value = this.isComparable() ? this.modelValue : this.viewDate;
  1450.             const convertedHour = this.convertTo24Hour(hour, pm);
  1451.  
  1452.             if (this.isRangeSelection()) {
  1453.                 value = this.modelValue[1] || this.modelValue[0];
  1454.             }
  1455.  
  1456.             if (this.isMultipleSelection()) {
  1457.                 value = this.modelValue[this.modelValue.length - 1];
  1458.             }
  1459.  
  1460.             const valueDateString = value ? value.toDateString() : null;
  1461.  
  1462.             if (this.minDate && valueDateString && this.minDate.toDateString() === valueDateString) {
  1463.                if (this.minDate.getHours() > convertedHour) {
  1464.                    return false;
  1465.                 }
  1466.  
  1467.                 if (this.minDate.getHours() === convertedHour) {
  1468.                     if (this.minDate.getMinutes() > minute) {
  1469.                         return false;
  1470.                     }
  1471.  
  1472.                     if (this.minDate.getMinutes() === minute) {
  1473.                         if (this.minDate.getSeconds() > second) {
  1474.                             return false;
  1475.                         }
  1476.                     }
  1477.                 }
  1478.             }
  1479.  
  1480.             if (this.maxDate && valueDateString && this.maxDate.toDateString() === valueDateString) {
  1481.                if (this.maxDate.getHours() < convertedHour) {
  1482.                    return false;
  1483.                 }
  1484.  
  1485.                 if (this.maxDate.getHours() === convertedHour) {
  1486.                     if (this.maxDate.getMinutes() < minute) {
  1487.                        return false;
  1488.                    }
  1489.  
  1490.                    if (this.maxDate.getMinutes() === minute) {
  1491.                        if (this.maxDate.getSeconds() < second) {
  1492.                            return false;
  1493.                        }
  1494.                    }
  1495.                }
  1496.            }
  1497.  
  1498.            return true;
  1499.        },
  1500.        incrementHour(event) {
  1501.            let prevHour = this.currentHour;
  1502.            let newHour = this.currentHour + this.stepHour;
  1503.            let newPM = this.pm;
  1504.  
  1505.            if (this.hourFormat == '24') newHour = newHour >= 24 ? newHour - 24 : newHour;
  1506.             else if (this.hourFormat == '12') {
  1507.                 // Before the AM/PM break, now after
  1508.                 if (prevHour < 12 && newHour > 11) {
  1509.                     newPM = !this.pm;
  1510.                 }
  1511.  
  1512.                 newHour = newHour >= 13 ? newHour - 12 : newHour;
  1513.             }
  1514.  
  1515.             if (this.validateTime(newHour, this.currentMinute, this.currentSecond, newPM)) {
  1516.                 this.currentHour = newHour;
  1517.                 this.pm = newPM;
  1518.             }
  1519.  
  1520.             event.preventDefault();
  1521.         },
  1522.         decrementHour(event) {
  1523.             let newHour = this.currentHour - this.stepHour;
  1524.             let newPM = this.pm;
  1525.  
  1526.             if (this.hourFormat == '24') newHour = newHour < 0 ? 24 + newHour : newHour;
  1527.            else if (this.hourFormat == '12') {
  1528.                // If we were at noon/midnight, then switch
  1529.                if (this.currentHour === 12) {
  1530.                    newPM = !this.pm;
  1531.                }
  1532.  
  1533.                newHour = newHour <= 0 ? 12 + newHour : newHour;
  1534.            }
  1535.  
  1536.            if (this.validateTime(newHour, this.currentMinute, this.currentSecond, newPM)) {
  1537.                this.currentHour = newHour;
  1538.                this.pm = newPM;
  1539.            }
  1540.  
  1541.            event.preventDefault();
  1542.        },
  1543.        incrementMinute(event) {
  1544.            let newMinute = this.currentMinute + this.stepMinute;
  1545.  
  1546.            if (this.validateTime(this.currentHour, newMinute, this.currentSecond, true)) {
  1547.                this.currentMinute = newMinute > 59 ? newMinute - 60 : newMinute;
  1548.             }
  1549.  
  1550.             event.preventDefault();
  1551.         },
  1552.         decrementMinute(event) {
  1553.             let newMinute = this.currentMinute - this.stepMinute;
  1554.  
  1555.             newMinute = newMinute < 0 ? 60 + newMinute : newMinute;
  1556.  
  1557.            if (this.validateTime(this.currentHour, newMinute, this.currentSecond, true)) {
  1558.                this.currentMinute = newMinute;
  1559.            }
  1560.  
  1561.            event.preventDefault();
  1562.        },
  1563.        incrementSecond(event) {
  1564.            let newSecond = this.currentSecond + this.stepSecond;
  1565.  
  1566.            if (this.validateTime(this.currentHour, this.currentMinute, newSecond, true)) {
  1567.                this.currentSecond = newSecond > 59 ? newSecond - 60 : newSecond;
  1568.             }
  1569.  
  1570.             event.preventDefault();
  1571.         },
  1572.         decrementSecond(event) {
  1573.             let newSecond = this.currentSecond - this.stepSecond;
  1574.  
  1575.             newSecond = newSecond < 0 ? 60 + newSecond : newSecond;
  1576.  
  1577.            if (this.validateTime(this.currentHour, this.currentMinute, newSecond, true)) {
  1578.                this.currentSecond = newSecond;
  1579.            }
  1580.  
  1581.            event.preventDefault();
  1582.        },
  1583.        updateModelTime() {
  1584.            this.timePickerChange = true;
  1585.            let value = this.isComparable() ? this.modelValue : this.viewDate;
  1586.  
  1587.            if (this.isRangeSelection()) {
  1588.                value = this.modelValue[1] || this.modelValue[0];
  1589.            }
  1590.  
  1591.            if (this.isMultipleSelection()) {
  1592.                value = this.modelValue[this.modelValue.length - 1];
  1593.            }
  1594.  
  1595.            value = value ? new Date(value.getTime()) : new Date();
  1596.  
  1597.            if (this.hourFormat == '12') {
  1598.                if (this.currentHour === 12) value.setHours(this.pm ? 12 : 0);
  1599.                else value.setHours(this.pm ? this.currentHour + 12 : this.currentHour);
  1600.            } else {
  1601.                value.setHours(this.currentHour);
  1602.            }
  1603.  
  1604.            value.setMinutes(this.currentMinute);
  1605.            value.setSeconds(this.currentSecond);
  1606.  
  1607.            if (this.isRangeSelection()) {
  1608.                if (this.modelValue[1]) value = [this.modelValue[0], value];
  1609.                else value = [value, null];
  1610.            }
  1611.  
  1612.            if (this.isMultipleSelection()) {
  1613.                value = [...this.modelValue.slice(0, -1), value];
  1614.            }
  1615.  
  1616.            this.updateModel(value);
  1617.            this.$emit('date-select', value);
  1618.            setTimeout(() => (this.timePickerChange = false), 0);
  1619.         },
  1620.         toggleAMPM(event) {
  1621.             const validHour = this.validateTime(this.currentHour, this.currentMinute, this.currentSecond, !this.pm);
  1622.  
  1623.             if (!validHour && (this.maxDate || this.minDate)) return;
  1624.  
  1625.             this.pm = !this.pm;
  1626.             this.updateModelTime();
  1627.             event.preventDefault();
  1628.         },
  1629.         clearTimePickerTimer() {
  1630.             if (this.timePickerTimer) {
  1631.                 clearInterval(this.timePickerTimer);
  1632.             }
  1633.         },
  1634.         onMonthSelect(event, index) {
  1635.             if (this.view === 'month') {
  1636.                 this.onDateSelect(event, { year: this.currentYear, month: index, day: 1, selectable: true });
  1637.             } else {
  1638.                 this.currentMonth = index;
  1639.                 this.currentView = 'date';
  1640.                 this.$emit('month-change', { month: this.currentMonth + 1, year: this.currentYear });
  1641.             }
  1642.  
  1643.             setTimeout(this.updateFocus, 0);
  1644.         },
  1645.         onYearSelect(event, year) {
  1646.             if (this.view === 'year') {
  1647.                 this.onDateSelect(event, { year: year, month: 0, day: 1, selectable: true });
  1648.             } else {
  1649.                 this.currentYear = year;
  1650.                 this.currentView = 'month';
  1651.                 this.$emit('year-change', { month: this.currentMonth + 1, year: this.currentYear });
  1652.             }
  1653.  
  1654.             setTimeout(this.updateFocus, 0);
  1655.         },
  1656.         enableModality() {
  1657.             if (!this.mask) {
  1658.                 this.mask = document.createElement('div');
  1659.                 this.mask.style.zIndex = String(parseInt(this.overlay.style.zIndex, 10) - 1);
  1660.                 DomHandler.addMultipleClasses(this.mask, 'p-datepicker-mask p-datepicker-mask-scrollblocker p-component-overlay p-component-overlay-enter');
  1661.  
  1662.                 this.maskClickListener = () => {
  1663.                     this.overlayVisible = false;
  1664.                 };
  1665.  
  1666.                 this.mask.addEventListener('click', this.maskClickListener);
  1667.  
  1668.                 document.body.appendChild(this.mask);
  1669.                 DomHandler.addClass(document.body, 'p-overflow-hidden');
  1670.             }
  1671.         },
  1672.         disableModality() {
  1673.             if (this.mask) {
  1674.                 DomHandler.addClass(this.mask, 'p-component-overlay-leave');
  1675.                 this.mask.addEventListener('animationend', () => {
  1676.                     this.destroyMask();
  1677.                 });
  1678.             }
  1679.         },
  1680.         destroyMask() {
  1681.             this.mask.removeEventListener('click', this.maskClickListener);
  1682.             this.maskClickListener = null;
  1683.             document.body.removeChild(this.mask);
  1684.             this.mask = null;
  1685.  
  1686.             let bodyChildren = document.body.children;
  1687.             let hasBlockerMasks;
  1688.  
  1689.             for (let i = 0; i < bodyChildren.length; i++) {
  1690.                let bodyChild = bodyChildren[i];
  1691.  
  1692.                if (DomHandler.hasClass(bodyChild, 'p-datepicker-mask-scrollblocker')) {
  1693.                    hasBlockerMasks = true;
  1694.                    break;
  1695.                }
  1696.            }
  1697.  
  1698.            if (!hasBlockerMasks) {
  1699.                DomHandler.removeClass(document.body, 'p-overflow-hidden');
  1700.            }
  1701.        },
  1702.        updateCurrentMetaData() {
  1703.            const viewDate = this.viewDate;
  1704.  
  1705.            this.currentMonth = viewDate.getMonth();
  1706.            this.currentYear = viewDate.getFullYear();
  1707.  
  1708.            if (this.showTime || this.timeOnly) {
  1709.                this.updateCurrentTimeMeta(viewDate);
  1710.            }
  1711.        },
  1712.        isValidSelection(value) {
  1713.            if (value == null) {
  1714.                return true;
  1715.            }
  1716.  
  1717.            let isValid = true;
  1718.  
  1719.            if (this.isSingleSelection()) {
  1720.                if (!this.isSelectable(value.getDate(), value.getMonth(), value.getFullYear(), false)) {
  1721.                    isValid = false;
  1722.                }
  1723.            } else if (value.every((v) => this.isSelectable(v.getDate(), v.getMonth(), v.getFullYear(), false))) {
  1724.                 if (this.isRangeSelection()) {
  1725.                     isValid = value.length > 1 && value[1] > value[0] ? true : false;
  1726.                 }
  1727.             }
  1728.  
  1729.             return isValid;
  1730.         },
  1731.         parseValue(text) {
  1732.             if (!text || text.trim().length === 0) {
  1733.                 return null;
  1734.             }
  1735.  
  1736.             let value;
  1737.  
  1738.             if (this.isSingleSelection()) {
  1739.                 value = this.parseDateTime(text);
  1740.             } else if (this.isMultipleSelection()) {
  1741.                 let tokens = text.split(',');
  1742.  
  1743.                 value = [];
  1744.  
  1745.                 for (let token of tokens) {
  1746.                     value.push(this.parseDateTime(token.trim()));
  1747.                 }
  1748.             } else if (this.isRangeSelection()) {
  1749.                 let tokens = text.split(' - ');
  1750.  
  1751.                 value = [];
  1752.  
  1753.                 for (let i = 0; i < tokens.length; i++) {
  1754.                    value[i] = this.parseDateTime(tokens[i].trim());
  1755.                }
  1756.            }
  1757.  
  1758.            return value;
  1759.        },
  1760.        parseDateTime(text) {
  1761.            let date;
  1762.            let parts = text.split(' ');
  1763.  
  1764.            if (this.timeOnly) {
  1765.                date = new Date();
  1766.                this.populateTime(date, parts[0], parts[1]);
  1767.            } else {
  1768.                const dateFormat = this.datePattern;
  1769.  
  1770.                if (this.showTime) {
  1771.                    date = this.parseDate(parts[0], dateFormat);
  1772.                    this.populateTime(date, parts[1], parts[2]);
  1773.                } else {
  1774.                    date = this.parseDate(text, dateFormat);
  1775.                }
  1776.            }
  1777.  
  1778.            return date;
  1779.        },
  1780.        populateTime(value, timeString, ampm) {
  1781.            if (this.hourFormat == '12' && !ampm) {
  1782.                throw 'Invalid Time';
  1783.            }
  1784.  
  1785.            //this.pm = ampm === this.$primevue.config.locale.am || ampm === this.$primevue.config.locale.am.toLowerCase();
  1786.            // Fix: https://github.com/primefaces/primevue/pull/3420/commits/404a238e9e4b8b69f2bb5cdf627d42dd773e1c44
  1787.            this.pm = ampm === this.$primevue.config.locale.pm || ampm === this.$primevue.config.locale.pm.toLowerCase();
  1788.            let time = this.parseTime(timeString);
  1789.  
  1790.            value.setHours(time.hour);
  1791.            value.setMinutes(time.minute);
  1792.            value.setSeconds(time.second);
  1793.        },
  1794.        parseTime(value) {
  1795.            let tokens = value.split(':');
  1796.            let validTokenLength = this.showSeconds ? 3 : 2;
  1797.            let regex = /^[0-9][0-9]$/;
  1798.  
  1799.            if (tokens.length !== validTokenLength || !tokens[0].match(regex) || !tokens[1].match(regex) || (this.showSeconds && !tokens[2].match(regex))) {
  1800.                throw 'Invalid time';
  1801.            }
  1802.  
  1803.            let h = parseInt(tokens[0]);
  1804.            let m = parseInt(tokens[1]);
  1805.            let s = this.showSeconds ? parseInt(tokens[2]) : null;
  1806.  
  1807.            if (isNaN(h) || isNaN(m) || h > 23 || m > 59 || (this.hourFormat == '12' && h > 12) || (this.showSeconds && (isNaN(s) || s > 59))) {
  1808.                throw 'Invalid time';
  1809.             } else {
  1810.                 if (this.hourFormat == '12' && h !== 12 && this.pm) {
  1811.                    h += 12;
  1812.                 } else if (this.hourFormat == '12' && h === 12 && !this.pm) {
  1813.                    h = 0;
  1814.                 }
  1815.  
  1816.                 return { hour: h, minute: m, second: s };
  1817.             }
  1818.         },
  1819.         parseDate(value, format) {
  1820.             if (format == null || value == null) {
  1821.                 throw 'Invalid arguments';
  1822.             }
  1823.  
  1824.             value = typeof value === 'object' ? value.toString() : value + '';
  1825.  
  1826.             if (value === '') {
  1827.                 return null;
  1828.             }
  1829.  
  1830.             let iFormat,
  1831.                 dim,
  1832.                 extra,
  1833.                 iValue = 0,
  1834.                 shortYearCutoff = typeof this.shortYearCutoff !== 'string' ? this.shortYearCutoff : (new Date().getFullYear() % 100) + parseInt(this.shortYearCutoff, 10),
  1835.                 year = -1,
  1836.                 month = -1,
  1837.                 day = -1,
  1838.                 doy = -1,
  1839.                 literal = false,
  1840.                 date,
  1841.                 lookAhead = (match) => {
  1842.                     let matches = iFormat + 1 < format.length && format.charAt(iFormat + 1) === match;
  1843.  
  1844.                    if (matches) {
  1845.                        iFormat++;
  1846.                    }
  1847.  
  1848.                    return matches;
  1849.                },
  1850.                getNumber = (match) => {
  1851.                     let isDoubled = lookAhead(match),
  1852.                         size = match === '@' ? 14 : match === '!' ? 20 : match === 'y' && isDoubled ? 4 : match === 'o' ? 3 : 2,
  1853.                        minSize = match === 'y' ? size : 1,
  1854.                        digits = new RegExp('^\\d{' + minSize + ',' + size + '}'),
  1855.                        num = value.substring(iValue).match(digits);
  1856.  
  1857.                     if (!num) {
  1858.                         throw 'Missing number at position ' + iValue;
  1859.                     }
  1860.  
  1861.                     iValue += num[0].length;
  1862.  
  1863.                     return parseInt(num[0], 10);
  1864.                 },
  1865.                 getName = (match, shortNames, longNames) => {
  1866.                     let index = -1;
  1867.                     let arr = lookAhead(match) ? longNames : shortNames;
  1868.                     let names = [];
  1869.  
  1870.                     for (let i = 0; i < arr.length; i++) {
  1871.                        names.push([i, arr[i]]);
  1872.                    }
  1873.  
  1874.                    names.sort((a, b) => {
  1875.                         return -(a[1].length - b[1].length);
  1876.                     });
  1877.  
  1878.                     for (let i = 0; i < names.length; i++) {
  1879.                        let name = names[i][1];
  1880.  
  1881.                        if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
  1882.                            index = names[i][0];
  1883.                            iValue += name.length;
  1884.                            break;
  1885.                        }
  1886.                    }
  1887.  
  1888.                    if (index !== -1) {
  1889.                        return index + 1;
  1890.                    } else {
  1891.                        throw 'Unknown name at position ' + iValue;
  1892.                    }
  1893.                },
  1894.                checkLiteral = () => {
  1895.                     if (value.charAt(iValue) !== format.charAt(iFormat)) {
  1896.                         throw 'Unexpected literal at position ' + iValue;
  1897.                     }
  1898.  
  1899.                     iValue++;
  1900.                 };
  1901.  
  1902.             if (this.currentView === 'month') {
  1903.                 day = 1;
  1904.             }
  1905.  
  1906.             for (iFormat = 0; iFormat < format.length; iFormat++) {
  1907.                if (literal) {
  1908.                    if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
  1909.                        literal = false;
  1910.                    } else {
  1911.                        checkLiteral();
  1912.                    }
  1913.                } else {
  1914.                    switch (format.charAt(iFormat)) {
  1915.                        case 'd':
  1916.                            day = getNumber('d');
  1917.                            break;
  1918.                        case 'D':
  1919.                            getName('D', this.$primevue.config.locale.dayNamesShort, this.$primevue.config.locale.dayNames);
  1920.                            break;
  1921.                        case 'o':
  1922.                            doy = getNumber('o');
  1923.                            break;
  1924.                        case 'm':
  1925.                            month = getNumber('m');
  1926.                            break;
  1927.                        case 'M':
  1928.                            month = getName('M', this.$primevue.config.locale.monthNamesShort, this.$primevue.config.locale.monthNames);
  1929.                            break;
  1930.                        case 'y':
  1931.                            year = getNumber('y');
  1932.                            break;
  1933.                        case '@':
  1934.                            date = new Date(getNumber('@'));
  1935.                            year = date.getFullYear();
  1936.                            month = date.getMonth() + 1;
  1937.                            day = date.getDate();
  1938.                            break;
  1939.                        case '!':
  1940.                            date = new Date((getNumber('!') - this.ticksTo1970) / 10000);
  1941.                            year = date.getFullYear();
  1942.                            month = date.getMonth() + 1;
  1943.                            day = date.getDate();
  1944.                            break;
  1945.                        case "'":
  1946.                            if (lookAhead("'")) {
  1947.                                checkLiteral();
  1948.                            } else {
  1949.                                literal = true;
  1950.                            }
  1951.  
  1952.                            break;
  1953.                        default:
  1954.                            checkLiteral();
  1955.                    }
  1956.                }
  1957.            }
  1958.  
  1959.            if (iValue < value.length) {
  1960.                extra = value.substr(iValue);
  1961.  
  1962.                if (!/^\s+/.test(extra)) {
  1963.                    throw 'Extra/unparsed characters found in date: ' + extra;
  1964.                }
  1965.            }
  1966.  
  1967.            if (year === -1) {
  1968.                year = new Date().getFullYear();
  1969.            } else if (year < 100) {
  1970.                year += new Date().getFullYear() - (new Date().getFullYear() % 100) + (year <= shortYearCutoff ? 0 : -100);
  1971.            }
  1972.  
  1973.            if (doy > -1) {
  1974.                 month = 1;
  1975.                 day = doy;
  1976.  
  1977.                 do {
  1978.                     dim = this.getDaysCountInMonth(year, month - 1);
  1979.  
  1980.                     if (day <= dim) {
  1981.                        break;
  1982.                    }
  1983.  
  1984.                    month++;
  1985.                    day -= dim;
  1986.                    // eslint-disable-next-line
  1987.                } while (true);
  1988.            }
  1989.  
  1990.            date = this.daylightSavingAdjust(new Date(year, month - 1, day));
  1991.  
  1992.            if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
  1993.                throw 'Invalid date'; // E.g. 31/02/00
  1994.            }
  1995.  
  1996.            return date;
  1997.        },
  1998.        getWeekNumber(date) {
  1999.            let checkDate = new Date(date.getTime());
  2000.  
  2001.            checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
  2002.            let time = checkDate.getTime();
  2003.  
  2004.            checkDate.setMonth(0);
  2005.            checkDate.setDate(1);
  2006.  
  2007.            return Math.floor(Math.round((time - checkDate.getTime()) / 86400000) / 7) + 1;
  2008.        },
  2009.        onDateCellKeydown(event, date, groupIndex) {
  2010.            const cellContent = event.currentTarget;
  2011.            const cell = cellContent.parentElement;
  2012.  
  2013.            const cellIndex = DomHandler.index(cell);
  2014.  
  2015.            switch (event.code) {
  2016.                case 'ArrowDown': {
  2017.                    cellContent.tabIndex = '-1';
  2018.  
  2019.                    let nextRow = cell.parentElement.nextElementSibling;
  2020.  
  2021.                    if (nextRow) {
  2022.                        let tableRowIndex = DomHandler.index(cell.parentElement);
  2023.                        const tableRows = Array.from(cell.parentElement.parentElement.children);
  2024.                        const nextTableRows = tableRows.slice(tableRowIndex + 1);
  2025.  
  2026.                        let hasNextFocusableDate = nextTableRows.find((el) => {
  2027.                             let focusCell = el.children[cellIndex].children[0];
  2028.  
  2029.                             return !DomHandler.hasClass(focusCell, 'p-disabled');
  2030.                         });
  2031.  
  2032.                         if (hasNextFocusableDate) {
  2033.                             let focusCell = hasNextFocusableDate.children[cellIndex].children[0];
  2034.  
  2035.                             focusCell.tabIndex = '0';
  2036.                             focusCell.focus();
  2037.                         } else {
  2038.                             this.navigationState = { backward: false };
  2039.                             this.navForward(event);
  2040.                         }
  2041.                     } else {
  2042.                         this.navigationState = { backward: false };
  2043.                         this.navForward(event);
  2044.                     }
  2045.  
  2046.                     event.preventDefault();
  2047.                     break;
  2048.                 }
  2049.  
  2050.                 case 'ArrowUp': {
  2051.                     cellContent.tabIndex = '-1';
  2052.                     let prevRow = cell.parentElement.previousElementSibling;
  2053.  
  2054.                     if (prevRow) {
  2055.                         let tableRowIndex = DomHandler.index(cell.parentElement);
  2056.                         const tableRows = Array.from(cell.parentElement.parentElement.children);
  2057.                         const prevTableRows = tableRows.slice(0, tableRowIndex).reverse();
  2058.  
  2059.                         let hasNextFocusableDate = prevTableRows.find((el) => {
  2060.                             let focusCell = el.children[cellIndex].children[0];
  2061.  
  2062.                             return !DomHandler.hasClass(focusCell, 'p-disabled');
  2063.                         });
  2064.  
  2065.                         if (hasNextFocusableDate) {
  2066.                             let focusCell = hasNextFocusableDate.children[cellIndex].children[0];
  2067.  
  2068.                             focusCell.tabIndex = '0';
  2069.                             focusCell.focus();
  2070.                         } else {
  2071.                             this.navigationState = { backward: true };
  2072.                             this.navBackward(event);
  2073.                         }
  2074.                     } else {
  2075.                         this.navigationState = { backward: true };
  2076.                         this.navBackward(event);
  2077.                     }
  2078.  
  2079.                     event.preventDefault();
  2080.                     break;
  2081.                 }
  2082.  
  2083.                 case 'ArrowLeft': {
  2084.                     cellContent.tabIndex = '-1';
  2085.                     let prevCell = cell.previousElementSibling;
  2086.  
  2087.                     if (prevCell) {
  2088.                         const cells = Array.from(cell.parentElement.children);
  2089.                         const prevCells = cells.slice(0, cellIndex).reverse();
  2090.  
  2091.                         let hasNextFocusableDate = prevCells.find((el) => {
  2092.                             let focusCell = el.children[0];
  2093.  
  2094.                             return !DomHandler.hasClass(focusCell, 'p-disabled');
  2095.                         });
  2096.  
  2097.                         if (hasNextFocusableDate) {
  2098.                             let focusCell = hasNextFocusableDate.children[0];
  2099.  
  2100.                             focusCell.tabIndex = '0';
  2101.                             focusCell.focus();
  2102.                         } else {
  2103.                             this.navigateToMonth(event, true, groupIndex);
  2104.                         }
  2105.                     } else {
  2106.                         this.navigateToMonth(event, true, groupIndex);
  2107.                     }
  2108.  
  2109.                     event.preventDefault();
  2110.                     break;
  2111.                 }
  2112.  
  2113.                 case 'ArrowRight': {
  2114.                     cellContent.tabIndex = '-1';
  2115.                     let nextCell = cell.nextElementSibling;
  2116.  
  2117.                     if (nextCell) {
  2118.                         const cells = Array.from(cell.parentElement.children);
  2119.                         const nextCells = cells.slice(cellIndex + 1);
  2120.                         let hasNextFocusableDate = nextCells.find((el) => {
  2121.                             let focusCell = el.children[0];
  2122.  
  2123.                             return !DomHandler.hasClass(focusCell, 'p-disabled');
  2124.                         });
  2125.  
  2126.                         if (hasNextFocusableDate) {
  2127.                             let focusCell = hasNextFocusableDate.children[0];
  2128.  
  2129.                             focusCell.tabIndex = '0';
  2130.                             focusCell.focus();
  2131.                         } else {
  2132.                             this.navigateToMonth(event, false, groupIndex);
  2133.                         }
  2134.                     } else {
  2135.                         this.navigateToMonth(event, false, groupIndex);
  2136.                     }
  2137.  
  2138.                     event.preventDefault();
  2139.                     break;
  2140.                 }
  2141.  
  2142.                 case 'Enter':
  2143.                     /* falls through */
  2144.                 case 'Space': {
  2145.                     this.onDateSelect(event, date);
  2146.                     event.preventDefault();
  2147.                     break;
  2148.                 }
  2149.  
  2150.                 case 'Escape': {
  2151.                     this.overlayVisible = false;
  2152.                     event.preventDefault();
  2153.                     break;
  2154.                 }
  2155.  
  2156.                 case 'Tab': {
  2157.                     if (!this.inline) {
  2158.                         this.trapFocus(event);
  2159.                     }
  2160.  
  2161.                     break;
  2162.                 }
  2163.  
  2164.                 case 'Home': {
  2165.                     cellContent.tabIndex = '-1';
  2166.                     let currentRow = cell.parentElement;
  2167.                     let focusCell = currentRow.children[0].children[0];
  2168.  
  2169.                     if (DomHandler.hasClass(focusCell, 'p-disabled')) {
  2170.                         this.navigateToMonth(event, true, groupIndex);
  2171.                     } else {
  2172.                         focusCell.tabIndex = '0';
  2173.                         focusCell.focus();
  2174.                     }
  2175.  
  2176.                     event.preventDefault();
  2177.                     break;
  2178.                 }
  2179.  
  2180.                 case 'End': {
  2181.                     cellContent.tabIndex = '-1';
  2182.                     let currentRow = cell.parentElement;
  2183.                     let focusCell = currentRow.children[currentRow.children.length - 1].children[0];
  2184.  
  2185.                     if (DomHandler.hasClass(focusCell, 'p-disabled')) {
  2186.                         this.navigateToMonth(event, false, groupIndex);
  2187.                     } else {
  2188.                         focusCell.tabIndex = '0';
  2189.                         focusCell.focus();
  2190.                     }
  2191.  
  2192.                     event.preventDefault();
  2193.                     break;
  2194.                 }
  2195.  
  2196.                 case 'PageUp': {
  2197.                     cellContent.tabIndex = '-1';
  2198.                     if (event.shiftKey) {
  2199.                         this.navigationState = { backward: true };
  2200.                         this.navBackward(event);
  2201.                     } else this.navigateToMonth(event, true, groupIndex);
  2202.  
  2203.                     event.preventDefault();
  2204.                     break;
  2205.                 }
  2206.  
  2207.                 case 'PageDown': {
  2208.                     cellContent.tabIndex = '-1';
  2209.                     if (event.shiftKey) {
  2210.                         this.navigationState = { backward: false };
  2211.                         this.navForward(event);
  2212.                     } else this.navigateToMonth(event, false, groupIndex);
  2213.  
  2214.                     event.preventDefault();
  2215.                     break;
  2216.                 }
  2217.  
  2218.                 default:
  2219.                     //no op
  2220.                     break;
  2221.             }
  2222.         },
  2223.         navigateToMonth(event, prev, groupIndex) {
  2224.             if (prev) {
  2225.                 if (this.numberOfMonths === 1 || groupIndex === 0) {
  2226.                     this.navigationState = { backward: true };
  2227.                     this.navBackward(event);
  2228.                 } else {
  2229.                     let prevMonthContainer = this.overlay.children[groupIndex - 1];
  2230.                     let cells = DomHandler.find(prevMonthContainer, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
  2231.                     let focusCell = cells[cells.length - 1];
  2232.  
  2233.                     focusCell.tabIndex = '0';
  2234.                     focusCell.focus();
  2235.                 }
  2236.             } else {
  2237.                 if (this.numberOfMonths === 1 || groupIndex === this.numberOfMonths - 1) {
  2238.                     this.navigationState = { backward: false };
  2239.                     this.navForward(event);
  2240.                 } else {
  2241.                     let nextMonthContainer = this.overlay.children[groupIndex + 1];
  2242.                     let focusCell = DomHandler.findSingle(nextMonthContainer, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
  2243.  
  2244.                     focusCell.tabIndex = '0';
  2245.                     focusCell.focus();
  2246.                 }
  2247.             }
  2248.         },
  2249.         onMonthCellKeydown(event, index) {
  2250.             const cell = event.currentTarget;
  2251.  
  2252.             switch (event.code) {
  2253.                 case 'ArrowUp':
  2254.                     /* falls through */
  2255.                 case 'ArrowDown': {
  2256.                     cell.tabIndex = '-1';
  2257.                     var cells = cell.parentElement.children;
  2258.                     var cellIndex = DomHandler.index(cell);
  2259.                     let nextCell = cells[event.code === 'ArrowDown' ? cellIndex + 3 : cellIndex - 3];
  2260.  
  2261.                     if (nextCell) {
  2262.                         nextCell.tabIndex = '0';
  2263.                         nextCell.focus();
  2264.                     }
  2265.  
  2266.                     event.preventDefault();
  2267.                     break;
  2268.                 }
  2269.  
  2270.                 case 'ArrowLeft': {
  2271.                     cell.tabIndex = '-1';
  2272.                     let prevCell = cell.previousElementSibling;
  2273.  
  2274.                     if (prevCell) {
  2275.                         prevCell.tabIndex = '0';
  2276.                         prevCell.focus();
  2277.                     } else {
  2278.                         this.navigationState = { backward: true };
  2279.                         this.navBackward(event);
  2280.                     }
  2281.  
  2282.                     event.preventDefault();
  2283.                     break;
  2284.                 }
  2285.  
  2286.                 case 'ArrowRight': {
  2287.                     cell.tabIndex = '-1';
  2288.                     let nextCell = cell.nextElementSibling;
  2289.  
  2290.                     if (nextCell) {
  2291.                         nextCell.tabIndex = '0';
  2292.                         nextCell.focus();
  2293.                     } else {
  2294.                         this.navigationState = { backward: false };
  2295.                         this.navForward(event);
  2296.                     }
  2297.  
  2298.                     event.preventDefault();
  2299.                     break;
  2300.                 }
  2301.  
  2302.                 case 'PageUp': {
  2303.                     if (event.shiftKey) return;
  2304.                     this.navigationState = { backward: true };
  2305.                     this.navBackward(event);
  2306.  
  2307.                     break;
  2308.                 }
  2309.  
  2310.                 case 'PageDown': {
  2311.                     if (event.shiftKey) return;
  2312.                     this.navigationState = { backward: false };
  2313.                     this.navForward(event);
  2314.  
  2315.                     break;
  2316.                 }
  2317.  
  2318.                 case 'Enter':
  2319.                     /* falls through */
  2320.                 case 'Space': {
  2321.                     this.onMonthSelect(event, index);
  2322.                     event.preventDefault();
  2323.                     break;
  2324.                 }
  2325.  
  2326.                 case 'Escape': {
  2327.                     this.overlayVisible = false;
  2328.                     event.preventDefault();
  2329.                     break;
  2330.                 }
  2331.  
  2332.                 case 'Tab': {
  2333.                     this.trapFocus(event);
  2334.                     break;
  2335.                 }
  2336.  
  2337.                 default:
  2338.                     //no op
  2339.                     break;
  2340.             }
  2341.         },
  2342.         onYearCellKeydown(event, index) {
  2343.             const cell = event.currentTarget;
  2344.  
  2345.             switch (event.code) {
  2346.                 case 'ArrowUp':
  2347.                     /* falls through */
  2348.                 case 'ArrowDown': {
  2349.                     cell.tabIndex = '-1';
  2350.                     var cells = cell.parentElement.children;
  2351.                     var cellIndex = DomHandler.index(cell);
  2352.                     let nextCell = cells[event.code === 'ArrowDown' ? cellIndex + 2 : cellIndex - 2];
  2353.  
  2354.                     if (nextCell) {
  2355.                         nextCell.tabIndex = '0';
  2356.                         nextCell.focus();
  2357.                     }
  2358.  
  2359.                     event.preventDefault();
  2360.                     break;
  2361.                 }
  2362.  
  2363.                 case 'ArrowLeft': {
  2364.                     cell.tabIndex = '-1';
  2365.                     let prevCell = cell.previousElementSibling;
  2366.  
  2367.                     if (prevCell) {
  2368.                         prevCell.tabIndex = '0';
  2369.                         prevCell.focus();
  2370.                     } else {
  2371.                         this.navigationState = { backward: true };
  2372.                         this.navBackward(event);
  2373.                     }
  2374.  
  2375.                     event.preventDefault();
  2376.                     break;
  2377.                 }
  2378.  
  2379.                 case 'ArrowRight': {
  2380.                     cell.tabIndex = '-1';
  2381.                     let nextCell = cell.nextElementSibling;
  2382.  
  2383.                     if (nextCell) {
  2384.                         nextCell.tabIndex = '0';
  2385.                         nextCell.focus();
  2386.                     } else {
  2387.                         this.navigationState = { backward: false };
  2388.                         this.navForward(event);
  2389.                     }
  2390.  
  2391.                     event.preventDefault();
  2392.                     break;
  2393.                 }
  2394.  
  2395.                 case 'PageUp': {
  2396.                     if (event.shiftKey) return;
  2397.                     this.navigationState = { backward: true };
  2398.                     this.navBackward(event);
  2399.  
  2400.                     break;
  2401.                 }
  2402.  
  2403.                 case 'PageDown': {
  2404.                     if (event.shiftKey) return;
  2405.                     this.navigationState = { backward: false };
  2406.                     this.navForward(event);
  2407.  
  2408.                     break;
  2409.                 }
  2410.  
  2411.                 case 'Enter':
  2412.                     /* falls through */
  2413.                 case 'Space': {
  2414.                     this.onYearSelect(event, index);
  2415.                     event.preventDefault();
  2416.                     break;
  2417.                 }
  2418.  
  2419.                 case 'Escape': {
  2420.                     this.overlayVisible = false;
  2421.                     event.preventDefault();
  2422.                     break;
  2423.                 }
  2424.  
  2425.                 case 'Tab': {
  2426.                     this.trapFocus(event);
  2427.                     break;
  2428.                 }
  2429.  
  2430.                 default:
  2431.                     //no op
  2432.                     break;
  2433.             }
  2434.         },
  2435.         updateFocus() {
  2436.             let cell;
  2437.  
  2438.             if (this.navigationState) {
  2439.                 if (this.navigationState.button) {
  2440.                     this.initFocusableCell();
  2441.  
  2442.                     if (this.navigationState.backward) DomHandler.findSingle(this.overlay, '.p-datepicker-prev').focus();
  2443.                     else DomHandler.findSingle(this.overlay, '.p-datepicker-next').focus();
  2444.                 } else {
  2445.                     if (this.navigationState.backward) {
  2446.                         let cells;
  2447.  
  2448.                         if (this.currentView === 'month') {
  2449.                             cells = DomHandler.find(this.overlay, '.p-monthpicker .p-monthpicker-month:not(.p-disabled)');
  2450.                         } else if (this.currentView === 'year') {
  2451.                             cells = DomHandler.find(this.overlay, '.p-yearpicker .p-yearpicker-year:not(.p-disabled)');
  2452.                         } else {
  2453.                             cells = DomHandler.find(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
  2454.                         }
  2455.  
  2456.                         if (cells && cells.length > 0) {
  2457.                            cell = cells[cells.length - 1];
  2458.                         }
  2459.                     } else {
  2460.                         if (this.currentView === 'month') {
  2461.                             cell = DomHandler.findSingle(this.overlay, '.p-monthpicker .p-monthpicker-month:not(.p-disabled)');
  2462.                         } else if (this.currentView === 'year') {
  2463.                             cell = DomHandler.findSingle(this.overlay, '.p-yearpicker .p-yearpicker-year:not(.p-disabled)');
  2464.                         } else {
  2465.                             cell = DomHandler.findSingle(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
  2466.                         }
  2467.                     }
  2468.  
  2469.                     if (cell) {
  2470.                         cell.tabIndex = '0';
  2471.                         cell.focus();
  2472.                     }
  2473.                 }
  2474.  
  2475.                 this.navigationState = null;
  2476.             } else {
  2477.                 this.initFocusableCell();
  2478.             }
  2479.         },
  2480.         initFocusableCell() {
  2481.             let cell;
  2482.  
  2483.             if (this.currentView === 'month') {
  2484.                 let cells = DomHandler.find(this.overlay, '.p-monthpicker .p-monthpicker-month');
  2485.                 let selectedCell = DomHandler.findSingle(this.overlay, '.p-monthpicker .p-monthpicker-month.p-highlight');
  2486.  
  2487.                 cells.forEach((cell) => (cell.tabIndex = -1));
  2488.                 cell = selectedCell || cells[0];
  2489.             } else if (this.currentView === 'year') {
  2490.                 let cells = DomHandler.find(this.overlay, '.p-yearpicker .p-yearpicker-year');
  2491.                 let selectedCell = DomHandler.findSingle(this.overlay, '.p-yearpicker .p-yearpicker-year.p-highlight');
  2492.  
  2493.                 cells.forEach((cell) => (cell.tabIndex = -1));
  2494.                 cell = selectedCell || cells[0];
  2495.             } else {
  2496.                 cell = DomHandler.findSingle(this.overlay, 'span.p-highlight');
  2497.  
  2498.                 if (!cell) {
  2499.                     let todayCell = DomHandler.findSingle(this.overlay, 'td.p-datepicker-today span:not(.p-disabled):not(.p-ink');
  2500.  
  2501.                     if (todayCell) cell = todayCell;
  2502.                     else cell = DomHandler.findSingle(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink');
  2503.                 }
  2504.             }
  2505.  
  2506.             if (cell) {
  2507.                 cell.tabIndex = '0';
  2508.  
  2509.                 //if (!this.inline && (!this.navigationState || !this.navigationState.button) && !this.timePickerChange) {
  2510.                // Fix: https://github.com/primefaces/primevue/pull/3689/commits/d68ff23fa99160f13bef99aed0efa9a1e4cc9a4d
  2511.                if (!this.preventFocus && !this.inline && (!this.navigationState || !this.navigationState.button) && !this.timePickerChange) {
  2512.                    cell.focus();
  2513.                 }
  2514.  
  2515.                 this.preventFocus = false;
  2516.             }
  2517.         },
  2518.         trapFocus(event) {
  2519.             event.preventDefault();
  2520.             let focusableElements = DomHandler.getFocusableElements(this.overlay);
  2521.  
  2522.             if (focusableElements && focusableElements.length > 0) {
  2523.                if (!document.activeElement) {
  2524.                    focusableElements[0].focus();
  2525.                 } else {
  2526.                     let focusedIndex = focusableElements.indexOf(document.activeElement);
  2527.  
  2528.                     if (event.shiftKey) {
  2529.                         if (focusedIndex === -1 || focusedIndex === 0) focusableElements[focusableElements.length - 1].focus();
  2530.                         else focusableElements[focusedIndex - 1].focus();
  2531.                     } else {
  2532.                         if (focusedIndex === -1) {
  2533.                             if (this.timeOnly) {
  2534.                                 focusableElements[0].focus();
  2535.                             } else {
  2536.                                 let spanIndex = null;
  2537.  
  2538.                                 for (let i = 0; i < focusableElements.length; i++) {
  2539.                                    if (focusableElements[i].tagName === 'SPAN') spanIndex = i;
  2540.                                }
  2541.  
  2542.                                focusableElements[spanIndex].focus();
  2543.                            }
  2544.                        } else if (focusedIndex === focusableElements.length - 1) focusableElements[0].focus();
  2545.                        else focusableElements[focusedIndex + 1].focus();
  2546.                    }
  2547.                }
  2548.            }
  2549.        },
  2550.        onContainerButtonKeydown(event) {
  2551.            switch (event.code) {
  2552.                case 'Tab':
  2553.                    this.trapFocus(event);
  2554.                    break;
  2555.  
  2556.                case 'Escape':
  2557.                    this.overlayVisible = false;
  2558.                    event.preventDefault();
  2559.                    break;
  2560.  
  2561.                default:
  2562.                    //Noop
  2563.                    break;
  2564.            }
  2565.  
  2566.            this.$emit('keydown', event);
  2567.        },
  2568.        onInput(event) {
  2569.            try {
  2570.                this.selectionStart = this.input.selectionStart;
  2571.                this.selectionEnd = this.input.selectionEnd;
  2572.  
  2573.                let value = this.parseValue(event.target.value);
  2574.  
  2575.                if (this.isValidSelection(value)) {
  2576.                    this.typeUpdate = true;
  2577.                    this.updateModel(value);
  2578.                }
  2579.            } catch (err) {
  2580.                /* NoOp */
  2581.            }
  2582.  
  2583.            this.$emit('input', event);
  2584.        },
  2585.        onInputClick() {
  2586.            if (this.showOnFocus && this.isEnabled() && !this.overlayVisible) {
  2587.                this.overlayVisible = true;
  2588.            }
  2589.        },
  2590.        onFocus(event) {
  2591.            if (this.showOnFocus && this.isEnabled()) {
  2592.                this.overlayVisible = true;
  2593.            }
  2594.  
  2595.            this.focused = true;
  2596.            this.$emit('focus', event);
  2597.        },
  2598.        onBlur(event) {
  2599.            this.$emit('blur', { originalEvent: event, value: event.target.value });
  2600.  
  2601.            this.focused = false;
  2602.            event.target.value = this.formatValue(this.modelValue);
  2603.        },
  2604.        onKeyDown(event) {
  2605.            if (event.code === 'ArrowDown' && this.overlay) {
  2606.                this.trapFocus(event);
  2607.            } else if (event.code === 'ArrowDown' && !this.overlay) {
  2608.                this.overlayVisible = true;
  2609.            } else if (event.code === 'Escape') {
  2610.                if (this.overlayVisible) {
  2611.                    this.overlayVisible = false;
  2612.                    event.preventDefault();
  2613.                }
  2614.            } else if (event.code === 'Tab') {
  2615.                if (this.overlay) {
  2616.                    DomHandler.getFocusableElements(this.overlay).forEach((el) => (el.tabIndex = '-1'));
  2617.                 }
  2618.  
  2619.                 if (this.overlayVisible) {
  2620.                     this.overlayVisible = false;
  2621.                 }
  2622.             }
  2623.         },
  2624.         overlayRef(el) {
  2625.             this.overlay = el;
  2626.         },
  2627.         inputRef(el) {
  2628.             this.input = el;
  2629.         },
  2630.         getMonthName(index) {
  2631.             return this.$primevue.config.locale.monthNames[index];
  2632.         },
  2633.         getYear(month) {
  2634.             return this.currentView === 'month' ? this.currentYear : month.year;
  2635.         },
  2636.         onOverlayClick(event) {
  2637.             if (!this.inline) {
  2638.                 OverlayEventBus.emit('overlay-click', {
  2639.                     originalEvent: event,
  2640.                     target: this.$el
  2641.                 });
  2642.             }
  2643.         },
  2644.         onOverlayKeyDown(event) {
  2645.             switch (event.code) {
  2646.                 case 'Escape':
  2647.                     this.input.focus();
  2648.                     this.overlayVisible = false;
  2649.                     break;
  2650.  
  2651.                 default:
  2652.                     break;
  2653.             }
  2654.         },
  2655.         onOverlayMouseUp(event) {
  2656.             this.onOverlayClick(event);
  2657.         },
  2658.         createResponsiveStyle() {
  2659.             if (this.numberOfMonths > 1 && this.responsiveOptions) {
  2660.                if (!this.responsiveStyleElement) {
  2661.                    this.responsiveStyleElement = document.createElement('style');
  2662.                     this.responsiveStyleElement.type = 'text/css';
  2663.                     document.body.appendChild(this.responsiveStyleElement);
  2664.                 }
  2665.  
  2666.                 let innerHTML = '';
  2667.  
  2668.                 if (this.responsiveOptions) {
  2669.                     let responsiveOptions = [...this.responsiveOptions].filter((o) => !!(o.breakpoint && o.numMonths)).sort((o1, o2) => -1 * o1.breakpoint.localeCompare(o2.breakpoint, undefined, { numeric: true }));
  2670.  
  2671.                     for (let i = 0; i < responsiveOptions.length; i++) {
  2672.                        let { breakpoint, numMonths } = responsiveOptions[i];
  2673.                        let styles = `
  2674.                            .p-datepicker[${this.attributeSelector}] .p-datepicker-group:nth-child(${numMonths}) .p-datepicker-next {
  2675.                                display: inline-flex !important;
  2676.                            }
  2677.                        `;
  2678.  
  2679.                        for (let j = numMonths; j < this.numberOfMonths; j++) {
  2680.                            styles += `
  2681.                                .p-datepicker[${this.attributeSelector}] .p-datepicker-group:nth-child(${j + 1}) {
  2682.                                    display: none !important;
  2683.                                }
  2684.                            `;
  2685.                        }
  2686.  
  2687.                        innerHTML += `
  2688.                            @media screen and (max-width: ${breakpoint}) {
  2689.                                ${styles}
  2690.                            }
  2691.                        `;
  2692.                    }
  2693.                }
  2694.  
  2695.                this.responsiveStyleElement.innerHTML = innerHTML;
  2696.            }
  2697.        },
  2698.        destroyResponsiveStyleElement() {
  2699.            if (this.responsiveStyleElement) {
  2700.                this.responsiveStyleElement.remove();
  2701.                this.responsiveStyleElement = null;
  2702.            }
  2703.        }
  2704.    },
  2705.    computed: {
  2706.        viewDate() {
  2707.            let propValue = this.modelValue;
  2708.  
  2709.            if (propValue && Array.isArray(propValue)) {
  2710.                if (this.isRangeSelection()) {
  2711.                    propValue = this.inline ? propValue[0] : propValue[1] || propValue[0];
  2712.                } else if (this.isMultipleSelection()) {
  2713.                    propValue = propValue[propValue.length - 1];
  2714.                }
  2715.            }
  2716.  
  2717.            if (propValue && typeof propValue !== 'string') {
  2718.                return propValue;
  2719.            } else {
  2720.                let today = new Date();
  2721.  
  2722.                if (this.maxDate && this.maxDate < today) {
  2723.                    return this.maxDate;
  2724.                }
  2725.  
  2726.                if (this.minDate && this.minDate > today) {
  2727.                     return this.minDate;
  2728.                 }
  2729.  
  2730.                 return today;
  2731.             }
  2732.         },
  2733.         inputFieldValue() {
  2734.             return this.formatValue(this.modelValue);
  2735.         },
  2736.         containerClass() {
  2737.             return [
  2738.                 'p-calendar p-component p-inputwrapper',
  2739.                 {
  2740.                     'p-calendar-w-btn': this.showIcon,
  2741.                     'p-calendar-timeonly': this.timeOnly,
  2742.                     'p-calendar-disabled': this.disabled,
  2743.                     'p-inputwrapper-filled': this.modelValue,
  2744.                     'p-inputwrapper-focus': this.focused
  2745.                 }
  2746.             ];
  2747.         },
  2748.         panelStyleClass() {
  2749.             return [
  2750.                 'p-datepicker p-component',
  2751.                 this.panelClass,
  2752.                 {
  2753.                     'p-datepicker-inline': this.inline,
  2754.                     'p-disabled': this.disabled,
  2755.                     'p-datepicker-timeonly': this.timeOnly,
  2756.                     'p-datepicker-multiple-month': this.numberOfMonths > 1,
  2757.                     'p-datepicker-monthpicker': this.currentView === 'month',
  2758.                     'p-datepicker-yearpicker': this.currentView === 'year',
  2759.                     'p-datepicker-touch-ui': this.touchUI,
  2760.                     'p-input-filled': this.$primevue.config.inputStyle === 'filled',
  2761.                     'p-ripple-disabled': this.$primevue.config.ripple === false
  2762.                 }
  2763.             ];
  2764.         },
  2765.         months() {
  2766.             let months = [];
  2767.  
  2768.             for (let i = 0; i < this.numberOfMonths; i++) {
  2769.                let month = this.currentMonth + i;
  2770.                let year = this.currentYear;
  2771.  
  2772.                if (month > 11) {
  2773.                     month = (month % 11) - 1;
  2774.                     year = year + 1;
  2775.                 }
  2776.  
  2777.                 let dates = [];
  2778.                 let firstDay = this.getFirstDayOfMonthIndex(month, year);
  2779.                 let daysLength = this.getDaysCountInMonth(month, year);
  2780.                 let prevMonthDaysLength = this.getDaysCountInPrevMonth(month, year);
  2781.                 let dayNo = 1;
  2782.                 let today = new Date();
  2783.                 let weekNumbers = [];
  2784.                 let monthRows = Math.ceil((daysLength + firstDay) / 7);
  2785.  
  2786.                 for (let i = 0; i < monthRows; i++) {
  2787.                    let week = [];
  2788.  
  2789.                    if (i == 0) {
  2790.                        for (let j = prevMonthDaysLength - firstDay + 1; j <= prevMonthDaysLength; j++) {
  2791.                            let prev = this.getPreviousMonthAndYear(month, year);
  2792.  
  2793.                            week.push({ day: j, month: prev.month, year: prev.year, otherMonth: true, today: this.isToday(today, j, prev.month, prev.year), selectable: this.isSelectable(j, prev.month, prev.year, true) });
  2794.                        }
  2795.  
  2796.                        let remainingDaysLength = 7 - week.length;
  2797.  
  2798.                        for (let j = 0; j < remainingDaysLength; j++) {
  2799.                            week.push({ day: dayNo, month: month, year: year, today: this.isToday(today, dayNo, month, year), selectable: this.isSelectable(dayNo, month, year, false) });
  2800.                            dayNo++;
  2801.                        }
  2802.                    } else {
  2803.                        for (let j = 0; j < 7; j++) {
  2804.                            if (dayNo > daysLength) {
  2805.                                 let next = this.getNextMonthAndYear(month, year);
  2806.  
  2807.                                 week.push({
  2808.                                     day: dayNo - daysLength,
  2809.                                     month: next.month,
  2810.                                     year: next.year,
  2811.                                     otherMonth: true,
  2812.                                     today: this.isToday(today, dayNo - daysLength, next.month, next.year),
  2813.                                     selectable: this.isSelectable(dayNo - daysLength, next.month, next.year, true)
  2814.                                 });
  2815.                             } else {
  2816.                                 week.push({ day: dayNo, month: month, year: year, today: this.isToday(today, dayNo, month, year), selectable: this.isSelectable(dayNo, month, year, false) });
  2817.                             }
  2818.  
  2819.                             dayNo++;
  2820.                         }
  2821.                     }
  2822.  
  2823.                     if (this.showWeek) {
  2824.                         weekNumbers.push(this.getWeekNumber(new Date(week[0].year, week[0].month, week[0].day)));
  2825.                     }
  2826.  
  2827.                     dates.push(week);
  2828.                 }
  2829.  
  2830.                 months.push({
  2831.                     month: month,
  2832.                     year: year,
  2833.                     dates: dates,
  2834.                     weekNumbers: weekNumbers
  2835.                 });
  2836.             }
  2837.  
  2838.             return months;
  2839.         },
  2840.         weekDays() {
  2841.             let weekDays = [];
  2842.             let dayIndex = this.$primevue.config.locale.firstDayOfWeek;
  2843.  
  2844.             for (let i = 0; i < 7; i++) {
  2845.                weekDays.push(this.$primevue.config.locale.dayNamesMin[dayIndex]);
  2846.                dayIndex = dayIndex == 6 ? 0 : ++dayIndex;
  2847.            }
  2848.  
  2849.            return weekDays;
  2850.        },
  2851.        ticksTo1970() {
  2852.            return ((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000;
  2853.        },
  2854.        sundayIndex() {
  2855.            return this.$primevue.config.locale.firstDayOfWeek > 0 ? 7 - this.$primevue.config.locale.firstDayOfWeek : 0;
  2856.         },
  2857.         datePattern() {
  2858.             return this.dateFormat || this.$primevue.config.locale.dateFormat;
  2859.         },
  2860.         yearOptions() {
  2861.             if (this.yearRange) {
  2862.                 let $vm = this;
  2863.                 const years = this.yearRange.split(':');
  2864.                 let yearStart = parseInt(years[0]);
  2865.                 let yearEnd = parseInt(years[1]);
  2866.                 let yearOptions = [];
  2867.  
  2868.                 if (this.currentYear < yearStart) {
  2869.                    $vm.currentYear = yearEnd;
  2870.                } else if (this.currentYear > yearEnd) {
  2871.                     $vm.currentYear = yearStart;
  2872.                 }
  2873.  
  2874.                 for (let i = yearStart; i <= yearEnd; i++) {
  2875.                    yearOptions.push(i);
  2876.                }
  2877.  
  2878.                return yearOptions;
  2879.            } else {
  2880.                return null;
  2881.            }
  2882.        },
  2883.        monthPickerValues() {
  2884.            let monthPickerValues = [];
  2885.  
  2886.            for (let i = 0; i <= 11; i++) {
  2887.                monthPickerValues.push(this.$primevue.config.locale.monthNamesShort[i]);
  2888.            }
  2889.  
  2890.            return monthPickerValues;
  2891.        },
  2892.        yearPickerValues() {
  2893.            let yearPickerValues = [];
  2894.            let base = this.currentYear - (this.currentYear % 10);
  2895.  
  2896.            for (let i = 0; i < 10; i++) {
  2897.                yearPickerValues.push(base + i);
  2898.            }
  2899.  
  2900.            return yearPickerValues;
  2901.        },
  2902.        formattedCurrentHour() {
  2903.            return this.currentHour < 10 ? '0' + this.currentHour : this.currentHour;
  2904.        },
  2905.        formattedCurrentMinute() {
  2906.            return this.currentMinute < 10 ? '0' + this.currentMinute : this.currentMinute;
  2907.        },
  2908.        formattedCurrentSecond() {
  2909.            return this.currentSecond < 10 ? '0' + this.currentSecond : this.currentSecond;
  2910.        },
  2911.        todayLabel() {
  2912.            return this.$primevue.config.locale.today;
  2913.        },
  2914.        clearLabel() {
  2915.            return this.$primevue.config.locale.clear;
  2916.        },
  2917.        weekHeaderLabel() {
  2918.            return this.$primevue.config.locale.weekHeader;
  2919.        },
  2920.        monthNames() {
  2921.            return this.$primevue.config.locale.monthNames;
  2922.        },
  2923.        attributeSelector() {
  2924.            return UniqueComponentId();
  2925.        },
  2926.        switchViewButtonDisabled() {
  2927.            return this.numberOfMonths > 1 || this.disabled;
  2928.         },
  2929.         panelId() {
  2930.             return UniqueComponentId() + '_panel';
  2931.         }
  2932.     },
  2933.     components: {
  2934.         CalendarButton: Button,
  2935.         Portal: Portal
  2936.     },
  2937.     directives: {
  2938.         ripple: Ripple
  2939.     }
  2940. };
  2941. </script>
  2942.  
  2943. <style>
  2944. .p-calendar {
  2945.     position: relative;
  2946.     display: inline-flex;
  2947.     max-width: 100%;
  2948. }
  2949.  
  2950. .p-calendar .p-inputtext {
  2951.     flex: 1 1 auto;
  2952.     width: 1%;
  2953. }
  2954.  
  2955. .p-calendar-w-btn .p-inputtext {
  2956.     border-top-right-radius: 0;
  2957.     border-bottom-right-radius: 0;
  2958. }
  2959.  
  2960. .p-calendar-w-btn .p-datepicker-trigger {
  2961.     border-top-left-radius: 0;
  2962.     border-bottom-left-radius: 0;
  2963. }
  2964.  
  2965. /* Fluid */
  2966. .p-fluid .p-calendar {
  2967.     display: flex;
  2968. }
  2969.  
  2970. .p-fluid .p-calendar .p-inputtext {
  2971.     width: 1%;
  2972. }
  2973.  
  2974. /* Datepicker */
  2975. .p-calendar .p-datepicker {
  2976.     min-width: 100%;
  2977. }
  2978.  
  2979. .p-datepicker {
  2980.     width: auto;
  2981.     position: absolute;
  2982.     top: 0;
  2983.     left: 0;
  2984. }
  2985.  
  2986. .p-datepicker-inline {
  2987.     display: inline-block;
  2988.     position: static;
  2989.     overflow-x: auto;
  2990. }
  2991.  
  2992. /* Header */
  2993. .p-datepicker-header {
  2994.     display: flex;
  2995.     align-items: center;
  2996.     justify-content: space-between;
  2997. }
  2998.  
  2999. .p-datepicker-header .p-datepicker-title {
  3000.     margin: 0 auto;
  3001. }
  3002.  
  3003. .p-datepicker-prev,
  3004. .p-datepicker-next {
  3005.     cursor: pointer;
  3006.     display: inline-flex;
  3007.     justify-content: center;
  3008.     align-items: center;
  3009.     overflow: hidden;
  3010.     position: relative;
  3011. }
  3012.  
  3013. /* Multiple Month DatePicker */
  3014. .p-datepicker-multiple-month .p-datepicker-group-container {
  3015.     display: flex;
  3016. }
  3017.  
  3018. .p-datepicker-multiple-month .p-datepicker-group-container .p-datepicker-group {
  3019.     flex: 1 1 auto;
  3020. }
  3021.  
  3022. /* DatePicker Table */
  3023. .p-datepicker table {
  3024.     width: 100%;
  3025.     border-collapse: collapse;
  3026. }
  3027.  
  3028. .p-datepicker td > span {
  3029.     display: flex;
  3030.     justify-content: center;
  3031.     align-items: center;
  3032.     cursor: pointer;
  3033.     margin: 0 auto;
  3034.     overflow: hidden;
  3035.     position: relative;
  3036. }
  3037.  
  3038. /* Month Picker */
  3039. .p-monthpicker-month {
  3040.     width: 33.3%;
  3041.     display: inline-flex;
  3042.     align-items: center;
  3043.     justify-content: center;
  3044.     cursor: pointer;
  3045.     overflow: hidden;
  3046.     position: relative;
  3047. }
  3048.  
  3049. /* Year Picker */
  3050. .p-yearpicker-year {
  3051.     width: 50%;
  3052.     display: inline-flex;
  3053.     align-items: center;
  3054.     justify-content: center;
  3055.     cursor: pointer;
  3056.     overflow: hidden;
  3057.     position: relative;
  3058. }
  3059.  
  3060. /*  Button Bar */
  3061. .p-datepicker-buttonbar {
  3062.     display: flex;
  3063.     justify-content: space-between;
  3064.     align-items: center;
  3065. }
  3066.  
  3067. /* Time Picker */
  3068. .p-timepicker {
  3069.     display: flex;
  3070.     justify-content: center;
  3071.     align-items: center;
  3072. }
  3073.  
  3074. .p-timepicker button {
  3075.     display: flex;
  3076.     align-items: center;
  3077.     justify-content: center;
  3078.     cursor: pointer;
  3079.     overflow: hidden;
  3080.     position: relative;
  3081. }
  3082.  
  3083. .p-timepicker > div {
  3084.     display: flex;
  3085.     align-items: center;
  3086.     flex-direction: column;
  3087. }
  3088.  
  3089. /* Touch UI */
  3090. .p-datepicker-touch-ui,
  3091. .p-calendar .p-datepicker-touch-ui {
  3092.     position: fixed;
  3093.     top: 50%;
  3094.     left: 50%;
  3095.     min-width: 80vw;
  3096.     transform: translate(-50%, -50%);
  3097. }
  3098. </style>
  3099.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement