Refactor #3965 - For Calendar
parent
9e1f1b5194
commit
b13d188e4f
|
@ -2,6 +2,19 @@
|
|||
import { ObjectUtils } from 'primevue/utils';
|
||||
import { mergeProps } from 'vue';
|
||||
|
||||
const inlineStyles = {
|
||||
hiddenAccessible: {
|
||||
border: '0',
|
||||
clip: 'rect(0 0 0 0)',
|
||||
height: '1px',
|
||||
margin: '-1px',
|
||||
overflow: 'hidden',
|
||||
padding: '0',
|
||||
position: 'absolute',
|
||||
width: '1px'
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'BaseComponent',
|
||||
props: {
|
||||
|
@ -37,6 +50,19 @@ export default {
|
|||
},
|
||||
ptmo(obj = {}, key = '', params = {}) {
|
||||
return this.getPTValue(obj, key, params);
|
||||
},
|
||||
css(key = '', params = {}) {
|
||||
return !this.isUnstyled ? ObjectUtils.getItemValue(this.getOption(this.$options.style && this.$options.style.classes, key), { instance: this, props: this.$props, state: this.$data, ...params }) : undefined;
|
||||
},
|
||||
style(key = '', when = true, params = {}) {
|
||||
if (when) {
|
||||
const self = ObjectUtils.getItemValue(this.getOption(this.$options.style && this.$options.style.inlineStyles, key), { instance: this, props: this.$props, state: this.$data, ...params });
|
||||
const base = ObjectUtils.getItemValue(this.getOption(inlineStyles, key), { instance: this, props: this.$props, state: this.$data, ...params });
|
||||
|
||||
return [base, self];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -44,7 +70,7 @@ export default {
|
|||
return ObjectUtils.getItemValue(this.getOption(this.$primevue.config.pt, this.$.type.name), this.defaultsParams);
|
||||
},
|
||||
defaultsParams() {
|
||||
return { instance: this.$ };
|
||||
return { instance: this };
|
||||
},
|
||||
isUnstyled() {
|
||||
return this.unstyled !== undefined ? this.unstyled : this.$primevue.config.unstyled;
|
||||
|
|
|
@ -0,0 +1,459 @@
|
|||
<script>
|
||||
import BaseComponent from 'primevue/basecomponent';
|
||||
import { useStyle } from 'primevue/usestyle';
|
||||
|
||||
const styles = `
|
||||
.p-calendar {
|
||||
display: inline-flex;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.p-calendar .p-inputtext {
|
||||
flex: 1 1 auto;
|
||||
width: 1%;
|
||||
}
|
||||
|
||||
.p-calendar-w-btn .p-inputtext {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.p-calendar-w-btn .p-datepicker-trigger {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
/* Fluid */
|
||||
.p-fluid .p-calendar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.p-fluid .p-calendar .p-inputtext {
|
||||
width: 1%;
|
||||
}
|
||||
|
||||
/* Datepicker */
|
||||
.p-calendar .p-datepicker {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.p-datepicker {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.p-datepicker-inline {
|
||||
display: inline-block;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.p-datepicker-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.p-datepicker-header .p-datepicker-title {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.p-datepicker-prev,
|
||||
.p-datepicker-next {
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Multiple Month DatePicker */
|
||||
.p-datepicker-multiple-month .p-datepicker-group-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.p-datepicker-multiple-month .p-datepicker-group-container .p-datepicker-group {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* DatePicker Table */
|
||||
.p-datepicker table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.p-datepicker td > span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Month Picker */
|
||||
.p-monthpicker-month {
|
||||
width: 33.3%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Year Picker */
|
||||
.p-yearpicker-year {
|
||||
width: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Button Bar */
|
||||
.p-datepicker-buttonbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Time Picker */
|
||||
.p-timepicker {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.p-timepicker button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.p-timepicker > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Touch UI */
|
||||
.p-datepicker-touch-ui,
|
||||
.p-calendar .p-datepicker-touch-ui {
|
||||
min-width: 80vw;
|
||||
}
|
||||
`;
|
||||
|
||||
const inlineStyles = {
|
||||
root: ({ props }) => ({ position: props.appendTo === 'self' ? 'relative' : undefined })
|
||||
};
|
||||
|
||||
const classes = {
|
||||
root: ({ props, state }) => [
|
||||
'p-calendar p-component p-inputwrapper',
|
||||
{
|
||||
'p-calendar-w-btn': props.showIcon,
|
||||
'p-calendar-timeonly': props.timeOnly,
|
||||
'p-calendar-disabled': props.disabled,
|
||||
'p-inputwrapper-filled': props.modelValue,
|
||||
'p-inputwrapper-focus': state.focused
|
||||
}
|
||||
],
|
||||
input: 'p-inputtext p-component',
|
||||
dropdownButton: 'p-datepicker-trigger',
|
||||
panel: ({ instance, props, state }) => [
|
||||
'p-datepicker p-component',
|
||||
props.panelClass,
|
||||
{
|
||||
'p-datepicker-inline': props.inline,
|
||||
'p-disabled': props.disabled,
|
||||
'p-datepicker-timeonly': props.timeOnly,
|
||||
'p-datepicker-multiple-month': props.numberOfMonths > 1,
|
||||
'p-datepicker-monthpicker': state.currentView === 'month',
|
||||
'p-datepicker-yearpicker': state.currentView === 'year',
|
||||
'p-datepicker-touch-ui': props.touchUI,
|
||||
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
|
||||
'p-ripple-disabled': instance.$primevue.config.ripple === false
|
||||
}
|
||||
],
|
||||
groupContainer: 'p-datepicker-group-container',
|
||||
group: 'p-datepicker-group',
|
||||
header: 'p-datepicker-header',
|
||||
previousButton: 'p-datepicker-prev p-link',
|
||||
previousIcon: 'p-datepicker-prev-icon',
|
||||
title: 'p-datepicker-title',
|
||||
monthTitle: 'p-datepicker-month p-link',
|
||||
yearTitle: 'p-datepicker-year p-link',
|
||||
decadeTitle: 'p-datepicker-decade',
|
||||
nextButton: 'p-datepicker-next p-link',
|
||||
nextIcon: 'p-datepicker-next-icon',
|
||||
container: 'p-datepicker-calendar-container',
|
||||
table: 'p-datepicker-calendar',
|
||||
weekHeader: 'p-datepicker-weekheader p-disabled',
|
||||
weekNumber: 'p-datepicker-weeknumber',
|
||||
weekLabelContainer: 'p-disabled',
|
||||
day: ({ date }) => [{ 'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today }],
|
||||
dayLabel: ({ instance, date }) => [{ 'p-highlight': instance.isSelected(date), 'p-disabled': !date.selectable }],
|
||||
ariaSelectedDay: 'p-hidden-accessible',
|
||||
monthPicker: 'p-monthpicker',
|
||||
month: ({ instance, month, index }) => ['p-monthpicker-month', { 'p-highlight': instance.isMonthSelected(index), 'p-disabled': !month.selectable }],
|
||||
ariaMonth: 'p-hidden-accessible',
|
||||
yearPicker: 'p-yearpicker',
|
||||
year: ({ instance, year }) => ['p-yearpicker-year', { 'p-highlight': instance.isYearSelected(year.value), 'p-disabled': !year.selectable }],
|
||||
ariaYear: 'p-hidden-accessible',
|
||||
timePicker: 'p-timepicker',
|
||||
hourPicker: 'p-hour-picker',
|
||||
incrementButton: 'p-link',
|
||||
decrementButton: 'p-link',
|
||||
separatorContainer: 'p-separator',
|
||||
minutePicker: 'p-minute-picker',
|
||||
incrementButton: 'p-link',
|
||||
decrementButton: 'p-link',
|
||||
secondPicker: 'p-second-picker',
|
||||
ampmPicker: 'p-ampm-picker',
|
||||
buttonbar: 'p-datepicker-buttonbar',
|
||||
todayButton: 'p-button-text',
|
||||
clearButton: 'p-button-text'
|
||||
};
|
||||
|
||||
const { load: loadStyle, unload: unloadStyle } = useStyle(styles, { id: 'primevue_calendar_style', manual: true });
|
||||
|
||||
export default {
|
||||
name: 'BaseCalendar',
|
||||
extends: BaseComponent,
|
||||
props: {
|
||||
modelValue: null,
|
||||
selectionMode: {
|
||||
type: String,
|
||||
default: 'single'
|
||||
},
|
||||
dateFormat: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showOtherMonths: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
selectOtherMonths: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
previousIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
nextIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
incrementIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
decrementIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
numberOfMonths: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
responsiveOptions: Array,
|
||||
view: {
|
||||
type: String,
|
||||
default: 'date'
|
||||
},
|
||||
touchUI: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
monthNavigator: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
yearNavigator: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
yearRange: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
minDate: {
|
||||
type: Date,
|
||||
value: null
|
||||
},
|
||||
maxDate: {
|
||||
type: Date,
|
||||
value: null
|
||||
},
|
||||
disabledDates: {
|
||||
type: Array,
|
||||
value: null
|
||||
},
|
||||
disabledDays: {
|
||||
type: Array,
|
||||
value: null
|
||||
},
|
||||
maxDateCount: {
|
||||
type: Number,
|
||||
value: null
|
||||
},
|
||||
showOnFocus: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoZIndex: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
baseZIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
showButtonBar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
shortYearCutoff: {
|
||||
type: String,
|
||||
default: '+10'
|
||||
},
|
||||
showTime: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
timeOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hourFormat: {
|
||||
type: String,
|
||||
default: '24'
|
||||
},
|
||||
stepHour: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
stepMinute: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
stepSecond: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
showSeconds: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hideOnDateTimeSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hideOnRangeSelection: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
timeSeparator: {
|
||||
type: String,
|
||||
default: ':'
|
||||
},
|
||||
showWeek: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
manualInput: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
appendTo: {
|
||||
type: String,
|
||||
default: 'body'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
inputId: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
inputClass: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
inputStyle: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
inputProps: {
|
||||
type: null,
|
||||
default: null
|
||||
},
|
||||
panelClass: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
panelStyle: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
panelProps: {
|
||||
type: null,
|
||||
default: null
|
||||
},
|
||||
'aria-labelledby': {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
'aria-label': {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
style: {
|
||||
inlineStyles,
|
||||
classes
|
||||
},
|
||||
watch: {
|
||||
isUnstyled: {
|
||||
immediate: true,
|
||||
handler(newValue) {
|
||||
!newValue && loadStyle();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<span ref="container" :id="id" :class="containerClass" v-bind="ptm('root')">
|
||||
<span ref="container" :id="id" :class="css('root')" :style="style('root')" data-pc-name="calendar" data-pc-section="root" v-bind="ptm('root')">
|
||||
<input
|
||||
v-if="!inline"
|
||||
:ref="inputRef"
|
||||
:id="inputId"
|
||||
type="text"
|
||||
role="combobox"
|
||||
:class="['p-inputtext p-component', inputClass]"
|
||||
:class="[css('input'), inputClass]"
|
||||
:style="inputStyle"
|
||||
:placeholder="placeholder"
|
||||
autocomplete="off"
|
||||
|
@ -29,7 +29,7 @@
|
|||
/>
|
||||
<CalendarButton
|
||||
v-if="showIcon"
|
||||
class="p-datepicker-trigger"
|
||||
:class="css('dropdownButton')"
|
||||
:disabled="disabled"
|
||||
@click="onButtonClick"
|
||||
type="button"
|
||||
|
@ -51,7 +51,7 @@
|
|||
v-if="inline || overlayVisible"
|
||||
:ref="overlayRef"
|
||||
:id="panelId"
|
||||
:class="panelStyleClass"
|
||||
:class="css('panel')"
|
||||
:style="panelStyle"
|
||||
:role="inline ? null : 'dialog'"
|
||||
:aria-modal="inline ? null : 'true'"
|
||||
|
@ -62,14 +62,15 @@
|
|||
v-bind="{ ...panelProps, ...ptm('panel') }"
|
||||
>
|
||||
<template v-if="!timeOnly">
|
||||
<div class="p-datepicker-group-container" v-bind="ptm('groupContainer')">
|
||||
<div v-for="(month, groupIndex) of months" :key="month.month + month.year" class="p-datepicker-group" v-bind="ptm('group')">
|
||||
<div class="p-datepicker-header" v-bind="ptm('header')">
|
||||
<div :class="css('groupContainer')" v-bind="ptm('groupContainer')">
|
||||
<div v-for="(month, groupIndex) of months" :key="month.month + month.year" :class="css('group')" v-bind="ptm('group')">
|
||||
<div :class="css('header')" v-bind="ptm('header')">
|
||||
<slot name="header"></slot>
|
||||
<button
|
||||
v-show="showOtherMonths ? groupIndex === 0 : false"
|
||||
:ref="previousButtonRef"
|
||||
v-ripple
|
||||
class="p-datepicker-prev p-link"
|
||||
:class="css('previousButton')"
|
||||
@click="onPrevButtonClick"
|
||||
type="button"
|
||||
@keydown="onContainerButtonKeydown"
|
||||
|
@ -78,16 +79,16 @@
|
|||
v-bind="ptm('previousButton')"
|
||||
>
|
||||
<slot name="previousicon">
|
||||
<component :is="previousIcon ? 'span' : 'ChevronLeftIcon'" :class="['p-datepicker-prev-icon', previousIcon]" v-bind="ptm('previousIcon')" />
|
||||
<component :is="previousIcon ? 'span' : 'ChevronLeftIcon'" :class="[css('previousIcon'), previousIcon]" v-bind="ptm('previousIcon')" />
|
||||
</slot>
|
||||
</button>
|
||||
<div class="p-datepicker-title" v-bind="ptm('title')">
|
||||
<div :class="css('title')" v-bind="ptm('title')">
|
||||
<button
|
||||
v-if="currentView === 'date'"
|
||||
type="button"
|
||||
@click="switchToMonthView"
|
||||
@keydown="onContainerButtonKeydown"
|
||||
class="p-datepicker-month p-link"
|
||||
:class="css('monthTitle')"
|
||||
:disabled="switchViewButtonDisabled"
|
||||
:aria-label="$primevue.config.locale.chooseMonth"
|
||||
v-bind="ptm('monthTitle')"
|
||||
|
@ -99,21 +100,22 @@
|
|||
type="button"
|
||||
@click="switchToYearView"
|
||||
@keydown="onContainerButtonKeydown"
|
||||
class="p-datepicker-year p-link"
|
||||
:class="css('yearTitle')"
|
||||
:disabled="switchViewButtonDisabled"
|
||||
:aria-label="$primevue.config.locale.chooseYear"
|
||||
v-bind="ptm('yearTitle')"
|
||||
>
|
||||
{{ getYear(month) }}
|
||||
</button>
|
||||
<span v-if="currentView === 'year'" class="p-datepicker-decade" v-bind="ptm('decadeTitle')">
|
||||
<span v-if="currentView === 'year'" :class="css('decadeTitle')" v-bind="ptm('decadeTitle')">
|
||||
<slot name="decade" :years="yearPickerValues"> {{ yearPickerValues[0].value }} - {{ yearPickerValues[yearPickerValues.length - 1].value }} </slot>
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
v-show="showOtherMonths ? (numberOfMonths === 1 ? true : groupIndex === numberOfMonths - 1) : false"
|
||||
:ref="nextButtonRef"
|
||||
v-ripple
|
||||
class="p-datepicker-next p-link"
|
||||
:class="css('nextButton')"
|
||||
@click="onNextButtonClick"
|
||||
type="button"
|
||||
@keydown="onContainerButtonKeydown"
|
||||
|
@ -122,15 +124,15 @@
|
|||
v-bind="ptm('nextButton')"
|
||||
>
|
||||
<slot name="nexticon">
|
||||
<component :is="nextIcon ? 'span' : 'ChevronRightIcon'" :class="['p-datepicker-next-icon', nextIcon]" v-bind="ptm('nextIcon')" />
|
||||
<component :is="nextIcon ? 'span' : 'ChevronRightIcon'" :class="[css('nextIcon'), nextIcon]" v-bind="ptm('nextIcon')" />
|
||||
</slot>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="currentView === 'date'" class="p-datepicker-calendar-container" v-bind="ptm('container')">
|
||||
<table class="p-datepicker-calendar" role="grid" v-bind="ptm('table')">
|
||||
<div v-if="currentView === 'date'" :class="css('container')" v-bind="ptm('container')">
|
||||
<table :class="css('table')" role="grid" v-bind="ptm('table')">
|
||||
<thead v-bind="ptm('tableHeader')">
|
||||
<tr v-bind="ptm('tableHeaderRow')">
|
||||
<th v-if="showWeek" scope="col" class="p-datepicker-weekheader p-disabled" v-bind="ptm('weekHeader')">
|
||||
<th v-if="showWeek" scope="col" :class="css('weekHeader')" :data-p-disabled="true" v-bind="ptm('weekHeader')">
|
||||
<span v-bind="ptm('weekLabel')">{{ weekHeaderLabel }}</span>
|
||||
</th>
|
||||
<th v-for="weekDay of weekDays" :key="weekDay" scope="col" :abbr="weekDay" v-bind="ptm('tableHeaderCell')">
|
||||
|
@ -140,25 +142,28 @@
|
|||
</thead>
|
||||
<tbody v-bind="ptm('tableBody')">
|
||||
<tr v-for="(week, i) of month.dates" :key="week[0].day + '' + week[0].month" v-bind="ptm('tableBodyRow')">
|
||||
<td v-if="showWeek" class="p-datepicker-weeknumber" v-bind="ptm('weekNumber')">
|
||||
<span class="p-disabled" v-bind="ptm('weekLabelContainer')">
|
||||
<td v-if="showWeek" :class="css('weekNumber')" v-bind="ptm('weekNumber')">
|
||||
<span :class="css('weekLabelContainer')" :data-p-disabled="true" v-bind="ptm('weekLabelContainer')">
|
||||
<span v-if="month.weekNumbers[i] < 10" style="visibility: hidden" v-bind="ptm('weekLabel')">0</span>
|
||||
{{ month.weekNumbers[i] }}
|
||||
</span>
|
||||
</td>
|
||||
<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 }" v-bind="ptm('day')">
|
||||
<td v-for="date of week" :key="date.day + '' + date.month" :aria-label="date.day" :class="css('day', { date })" :data-p-today="date.today" :data-p-other-month="date.otherMonth" v-bind="ptm('day')">
|
||||
<span
|
||||
v-ripple
|
||||
:class="{ 'p-highlight': isSelected(date), 'p-disabled': !date.selectable }"
|
||||
:class="css('dayLabel', { date })"
|
||||
@click="onDateSelect($event, date)"
|
||||
draggable="false"
|
||||
@keydown="onDateCellKeydown($event, date, groupIndex)"
|
||||
:aria-selected="isSelected(date)"
|
||||
:aria-disabled="!date.selectable"
|
||||
:data-p-disabled="!date.selectable"
|
||||
:data-p-highlight="isSelected(date)"
|
||||
v-bind="ptm('dayLabel')"
|
||||
>
|
||||
<slot name="date" :date="date">{{ date.day }}</slot>
|
||||
</span>
|
||||
<div v-if="isSelected(date)" class="p-hidden-accessible" aria-live="polite" v-bind="ptm('ariaSelectedDay')">
|
||||
<div v-if="isSelected(date)" :class="css('ariaSelectedDay')" :style="style('hiddenAccessible', isUnstyled)" aria-live="polite" :data-p-hidden-accessible="true" v-bind="ptm('ariaSelectedDay')">
|
||||
{{ date.day }}
|
||||
</div>
|
||||
</td>
|
||||
|
@ -168,46 +173,50 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="currentView === 'month'" class="p-monthpicker" v-bind="ptm('monthPicker')">
|
||||
<div v-if="currentView === 'month'" :class="css('monthPicker')" data-pc-section="monthpicker" v-bind="ptm('monthPicker')">
|
||||
<span
|
||||
v-for="(m, i) of monthPickerValues"
|
||||
:key="m"
|
||||
v-ripple
|
||||
@click="onMonthSelect($event, { month: m, index: i })"
|
||||
@keydown="onMonthCellKeydown($event, { month: m, index: i })"
|
||||
class="p-monthpicker-month"
|
||||
:class="{ 'p-highlight': isMonthSelected(i), 'p-disabled': !m.selectable }"
|
||||
:class="css('month', { month: m, index: i })"
|
||||
data-pc-section="month"
|
||||
:data-p-disabled="!m.selectable"
|
||||
:data-p-highlight="isMonthSelected(i)"
|
||||
v-bind="ptm('month')"
|
||||
>
|
||||
{{ m.value }}
|
||||
<div v-if="isMonthSelected(i)" class="p-hidden-accessible" aria-live="polite" v-bind="ptm('ariaMonth')">
|
||||
<div v-if="isMonthSelected(i)" :class="css('ariaMonth')" :style="style('hiddenAccessible', isUnstyled)" aria-live="polite" :data-p-hidden-accessible="true" v-bind="ptm('ariaMonth')">
|
||||
{{ m.value }}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="currentView === 'year'" class="p-yearpicker" v-bind="ptm('yearPicker')">
|
||||
<div v-if="currentView === 'year'" :class="css('yearPicker')" data-pc-section="yearpicker" v-bind="ptm('yearPicker')">
|
||||
<span
|
||||
v-for="y of yearPickerValues"
|
||||
:key="y.value"
|
||||
v-ripple
|
||||
@click="onYearSelect($event, y)"
|
||||
@keydown="onYearCellKeydown($event, y)"
|
||||
class="p-yearpicker-year"
|
||||
:class="{ 'p-highlight': isYearSelected(y.value), 'p-disabled': !y.selectable }"
|
||||
:class="css('year', { year: y })"
|
||||
data-pc-section="year"
|
||||
:data-p-disabled="!y.selectable"
|
||||
:data-p-highlight="isYearSelected(y.value)"
|
||||
v-bind="ptm('year')"
|
||||
>
|
||||
{{ y.value }}
|
||||
<div v-if="isYearSelected(y.value)" class="p-hidden-accessible" aria-live="polite" v-bind="ptm('ariaYear')">
|
||||
<div v-if="isYearSelected(y.value)" :class="css('ariaYear')" :style="style('hiddenAccessible', isUnstyled)" aria-live="polite" :data-p-hidden-accessible="true" v-bind="ptm('ariaYear')">
|
||||
{{ y.value }}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="(showTime || timeOnly) && currentView === 'date'" class="p-timepicker" v-bind="ptm('timePicker')">
|
||||
<div class="p-hour-picker" v-bind="ptm('hourPicker')">
|
||||
<div v-if="(showTime || timeOnly) && currentView === 'date'" :class="css('timePicker')" v-bind="ptm('timePicker')">
|
||||
<div :class="css('hourPicker')" v-bind="ptm('hourPicker')">
|
||||
<button
|
||||
v-ripple
|
||||
class="p-link"
|
||||
:class="css('incrementButton')"
|
||||
:aria-label="$primevue.config.locale.nextHour"
|
||||
@mousedown="onTimePickerElementMouseDown($event, 0, 1)"
|
||||
@mouseup="onTimePickerElementMouseUp($event)"
|
||||
|
@ -227,7 +236,7 @@
|
|||
<span v-bind="ptm('hour')">{{ formattedCurrentHour }}</span>
|
||||
<button
|
||||
v-ripple
|
||||
class="p-link"
|
||||
:class="css('decrementButton')"
|
||||
:aria-label="$primevue.config.locale.prevHour"
|
||||
@mousedown="onTimePickerElementMouseDown($event, 0, -1)"
|
||||
@mouseup="onTimePickerElementMouseUp($event)"
|
||||
|
@ -245,13 +254,13 @@
|
|||
</slot>
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-separator" v-bind="ptm('separatorContainer')">
|
||||
<div :class="css('separatorContainer')" v-bind="ptm('separatorContainer')">
|
||||
<span v-bind="ptm('separator')">{{ timeSeparator }}</span>
|
||||
</div>
|
||||
<div class="p-minute-picker" v-bind="ptm('minutePicker')">
|
||||
<div :class="css('minutePicker')" v-bind="ptm('minutePicker')">
|
||||
<button
|
||||
v-ripple
|
||||
class="p-link"
|
||||
:class="css('incrementButton')"
|
||||
:aria-label="$primevue.config.locale.nextMinute"
|
||||
@mousedown="onTimePickerElementMouseDown($event, 1, 1)"
|
||||
@mouseup="onTimePickerElementMouseUp($event)"
|
||||
|
@ -272,7 +281,7 @@
|
|||
<span v-bind="ptm('minute')">{{ formattedCurrentMinute }}</span>
|
||||
<button
|
||||
v-ripple
|
||||
class="p-link"
|
||||
:class="css('decrementButton')"
|
||||
:aria-label="$primevue.config.locale.prevMinute"
|
||||
@mousedown="onTimePickerElementMouseDown($event, 1, -1)"
|
||||
@mouseup="onTimePickerElementMouseUp($event)"
|
||||
|
@ -291,13 +300,13 @@
|
|||
</slot>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="showSeconds" class="p-separator" v-bind="ptm('separatorContainer')">
|
||||
<div v-if="showSeconds" :class="css('separatorContainer')" v-bind="ptm('separatorContainer')">
|
||||
<span v-bind="ptm('separator')">{{ timeSeparator }}</span>
|
||||
</div>
|
||||
<div v-if="showSeconds" class="p-second-picker" v-bind="ptm('secondPicker')">
|
||||
<div v-if="showSeconds" :class="css('secondPicker')" v-bind="ptm('secondPicker')">
|
||||
<button
|
||||
v-ripple
|
||||
class="p-link"
|
||||
:class="css('incrementButton')"
|
||||
:aria-label="$primevue.config.locale.nextSecond"
|
||||
@mousedown="onTimePickerElementMouseDown($event, 2, 1)"
|
||||
@mouseup="onTimePickerElementMouseUp($event)"
|
||||
|
@ -318,7 +327,7 @@
|
|||
<span v-bind="ptm('second')">{{ formattedCurrentSecond }}</span>
|
||||
<button
|
||||
v-ripple
|
||||
class="p-link"
|
||||
:class="css('decrementButton')"
|
||||
:aria-label="$primevue.config.locale.prevSecond"
|
||||
@mousedown="onTimePickerElementMouseDown($event, 2, -1)"
|
||||
@mouseup="onTimePickerElementMouseUp($event)"
|
||||
|
@ -337,26 +346,26 @@
|
|||
</slot>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="hourFormat == '12'" class="p-separator" v-bind="ptm('separatorContainer')">
|
||||
<div v-if="hourFormat == '12'" :class="css('separatorContainer')" v-bind="ptm('separatorContainer')">
|
||||
<span v-bind="ptm('separator')">{{ timeSeparator }}</span>
|
||||
</div>
|
||||
<div v-if="hourFormat == '12'" class="p-ampm-picker" v-bind="ptm('ampmPicker')">
|
||||
<button v-ripple class="p-link" :aria-label="$primevue.config.locale.am" @click="toggleAMPM($event)" type="button" :disabled="disabled" v-bind="ptm('incrementButton')">
|
||||
<div v-if="hourFormat == '12'" :class="css('ampmPicker')" v-bind="ptm('ampmPicker')">
|
||||
<button v-ripple :class="css('incrementButton')" :aria-label="$primevue.config.locale.am" @click="toggleAMPM($event)" type="button" :disabled="disabled" v-bind="ptm('incrementButton')">
|
||||
<slot name="incrementicon">
|
||||
<component :is="incrementIcon ? 'span' : 'ChevronUpIcon'" :class="incrementIcon" v-bind="ptm('incrementIcon')" />
|
||||
<component :is="incrementIcon ? 'span' : 'ChevronUpIcon'" :class="css('incrementIcon')" v-bind="ptm('incrementIcon')" />
|
||||
</slot>
|
||||
</button>
|
||||
<span v-bind="ptm('ampm')">{{ pm ? $primevue.config.locale.pm : $primevue.config.locale.am }}</span>
|
||||
<button v-ripple class="p-link" :aria-label="$primevue.config.locale.pm" @click="toggleAMPM($event)" type="button" :disabled="disabled" v-bind="ptm('decrementButton')">
|
||||
<button v-ripple :class="css('decrementButton')" :aria-label="$primevue.config.locale.pm" @click="toggleAMPM($event)" type="button" :disabled="disabled" v-bind="ptm('decrementButton')">
|
||||
<slot name="decrementicon">
|
||||
<component :is="decrementIcon ? 'span' : 'ChevronDownIcon'" :class="decrementIcon" v-bind="ptm('decrementIcon')" />
|
||||
<component :is="decrementIcon ? 'span' : 'ChevronDownIcon'" :class="css('decrementIcon')" v-bind="ptm('decrementIcon')" />
|
||||
</slot>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showButtonBar" class="p-datepicker-buttonbar" v-bind="ptm('buttonbar')">
|
||||
<CalendarButton type="button" :label="todayLabel" @click="onTodayButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown" :pt="ptm('todayButton')" />
|
||||
<CalendarButton type="button" :label="clearLabel" @click="onClearButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown" :pt="ptm('clearButton')" />
|
||||
<div v-if="showButtonBar" :class="css('buttonbar')" v-bind="ptm('buttonbar')">
|
||||
<CalendarButton type="button" :label="todayLabel" @click="onTodayButtonClick($event)" :class="css('todayButton')" @keydown="onContainerButtonKeydown" :pt="ptm('todayButton')" />
|
||||
<CalendarButton type="button" :label="clearLabel" @click="onClearButtonClick($event)" :class="css('clearButton')" @keydown="onContainerButtonKeydown" :pt="ptm('clearButton')" />
|
||||
</div>
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
|
@ -366,7 +375,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import BaseComponent from 'primevue/basecomponent';
|
||||
import Button from 'primevue/button';
|
||||
import CalendarIcon from 'primevue/icons/calendar';
|
||||
import ChevronDownIcon from 'primevue/icons/chevrondown';
|
||||
|
@ -377,227 +385,12 @@ import OverlayEventBus from 'primevue/overlayeventbus';
|
|||
import Portal from 'primevue/portal';
|
||||
import Ripple from 'primevue/ripple';
|
||||
import { ConnectedOverlayScrollHandler, DomHandler, UniqueComponentId, ZIndexUtils } from 'primevue/utils';
|
||||
import BaseCalendar from './BaseCalendar';
|
||||
|
||||
export default {
|
||||
name: 'Calendar',
|
||||
extends: BaseComponent,
|
||||
extends: BaseCalendar,
|
||||
emits: ['show', 'hide', 'input', 'month-change', 'year-change', 'date-select', 'update:modelValue', 'today-click', 'clear-click', 'focus', 'blur', 'keydown'],
|
||||
props: {
|
||||
modelValue: null,
|
||||
selectionMode: {
|
||||
type: String,
|
||||
default: 'single'
|
||||
},
|
||||
dateFormat: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showOtherMonths: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
selectOtherMonths: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
previousIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
nextIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
incrementIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
decrementIcon: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
numberOfMonths: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
responsiveOptions: Array,
|
||||
view: {
|
||||
type: String,
|
||||
default: 'date'
|
||||
},
|
||||
touchUI: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
monthNavigator: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
yearNavigator: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
yearRange: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
minDate: {
|
||||
type: Date,
|
||||
value: null
|
||||
},
|
||||
maxDate: {
|
||||
type: Date,
|
||||
value: null
|
||||
},
|
||||
disabledDates: {
|
||||
type: Array,
|
||||
value: null
|
||||
},
|
||||
disabledDays: {
|
||||
type: Array,
|
||||
value: null
|
||||
},
|
||||
maxDateCount: {
|
||||
type: Number,
|
||||
value: null
|
||||
},
|
||||
showOnFocus: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoZIndex: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
baseZIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
showButtonBar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
shortYearCutoff: {
|
||||
type: String,
|
||||
default: '+10'
|
||||
},
|
||||
showTime: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
timeOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hourFormat: {
|
||||
type: String,
|
||||
default: '24'
|
||||
},
|
||||
stepHour: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
stepMinute: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
stepSecond: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
showSeconds: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hideOnDateTimeSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hideOnRangeSelection: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
timeSeparator: {
|
||||
type: String,
|
||||
default: ':'
|
||||
},
|
||||
showWeek: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
manualInput: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
appendTo: {
|
||||
type: String,
|
||||
default: 'body'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
inputId: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
inputClass: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
inputStyle: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
inputProps: {
|
||||
type: null,
|
||||
default: null
|
||||
},
|
||||
panelClass: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
panelStyle: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
panelProps: {
|
||||
type: null,
|
||||
default: null
|
||||
},
|
||||
'aria-labelledby': {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
'aria-label': {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
navigationState: null,
|
||||
timePickerChange: false,
|
||||
scrollHandler: null,
|
||||
|
@ -607,6 +400,8 @@ export default {
|
|||
overlay: null,
|
||||
input: null,
|
||||
mask: null,
|
||||
previousButton: null,
|
||||
nextButton: null,
|
||||
timePickerTimer: null,
|
||||
preventFocus: false,
|
||||
typeUpdate: false,
|
||||
|
@ -892,6 +687,9 @@ export default {
|
|||
},
|
||||
onOverlayEnter(el) {
|
||||
el.setAttribute(this.attributeSelector, '');
|
||||
const styles = this.touchUI ? { position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' } : !this.inline ? { position: 'absolute', top: '0', left: '0' } : undefined;
|
||||
|
||||
DomHandler.addStyles(el, styles);
|
||||
|
||||
if (this.autoZIndex) {
|
||||
if (this.touchUI) ZIndexUtils.set('modal', el, this.baseZIndex || this.$primevue.config.zIndex.modal);
|
||||
|
@ -1083,12 +881,7 @@ export default {
|
|||
return !(this.$el.isSameNode(event.target) || this.isNavIconClicked(event) || this.$el.contains(event.target) || (this.overlay && this.overlay.contains(event.target)));
|
||||
},
|
||||
isNavIconClicked(event) {
|
||||
return (
|
||||
DomHandler.hasClass(event.target, 'p-datepicker-prev') ||
|
||||
DomHandler.hasClass(event.target, 'p-datepicker-prev-icon') ||
|
||||
DomHandler.hasClass(event.target, 'p-datepicker-next') ||
|
||||
DomHandler.hasClass(event.target, 'p-datepicker-next-icon')
|
||||
);
|
||||
return (this.previousButton && (this.previousButton.isSameNode(event.target) || this.previousButton.contains(event.target))) || (this.nextButton && (this.nextButton.isSameNode(event.target) || this.nextButton.contains(event.target)));
|
||||
},
|
||||
alignOverlay() {
|
||||
if (this.touchUI) {
|
||||
|
@ -1152,7 +945,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
DomHandler.find(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled)').forEach((cell) => (cell.tabIndex = -1));
|
||||
DomHandler.find(this.overlay, 'table td span:not([data-p-disabled="true"])').forEach((cell) => (cell.tabIndex = -1));
|
||||
|
||||
if (event) {
|
||||
event.currentTarget.focus();
|
||||
|
@ -1722,7 +1515,8 @@ export default {
|
|||
if (!this.mask) {
|
||||
this.mask = document.createElement('div');
|
||||
this.mask.style.zIndex = String(parseInt(this.overlay.style.zIndex, 10) - 1);
|
||||
DomHandler.addMultipleClasses(this.mask, 'p-datepicker-mask p-datepicker-mask-scrollblocker p-component-overlay p-component-overlay-enter');
|
||||
this.mask.setAttribute('data-pc-section', 'datepicker-mask');
|
||||
!this.isUnstyled && DomHandler.addMultipleClasses(this.mask, 'p-datepicker-mask p-datepicker-mask-scrollblocker p-component-overlay p-component-overlay-enter');
|
||||
|
||||
this.maskClickListener = () => {
|
||||
this.overlayVisible = false;
|
||||
|
@ -1731,15 +1525,20 @@ export default {
|
|||
this.mask.addEventListener('click', this.maskClickListener);
|
||||
|
||||
document.body.appendChild(this.mask);
|
||||
DomHandler.addClass(document.body, 'p-overflow-hidden');
|
||||
document.body.setAttribute('data-p-overflow-hidden', 'true');
|
||||
!this.isUnstyled && DomHandler.addClass(document.body, 'p-overflow-hidden');
|
||||
}
|
||||
},
|
||||
disableModality() {
|
||||
if (this.mask) {
|
||||
DomHandler.addClass(this.mask, 'p-component-overlay-leave');
|
||||
this.mask.addEventListener('animationend', () => {
|
||||
if (this.isUnstyled) {
|
||||
this.destroyMask();
|
||||
});
|
||||
} else {
|
||||
DomHandler.addClass(this.mask, 'p-component-overlay-leave');
|
||||
this.mask.addEventListener('animationend', () => {
|
||||
this.destroyMask();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
destroyMask() {
|
||||
|
@ -1754,14 +1553,15 @@ export default {
|
|||
for (let i = 0; i < bodyChildren.length; i++) {
|
||||
let bodyChild = bodyChildren[i];
|
||||
|
||||
if (DomHandler.hasClass(bodyChild, 'p-datepicker-mask-scrollblocker')) {
|
||||
if (DomHandler.isAttributeEquals(bodyChild, 'data-pc-section', 'datepicker-mask')) {
|
||||
hasBlockerMasks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasBlockerMasks) {
|
||||
DomHandler.removeClass(document.body, 'p-overflow-hidden');
|
||||
document.body.removeAttribute('data-p-overflow-hidden');
|
||||
!this.isUnstyled && DomHandler.removeClass(document.body, 'p-overflow-hidden');
|
||||
}
|
||||
},
|
||||
updateCurrentMetaData() {
|
||||
|
@ -2087,7 +1887,7 @@ export default {
|
|||
let hasNextFocusableDate = nextTableRows.find((el) => {
|
||||
let focusCell = el.children[cellIndex].children[0];
|
||||
|
||||
return !DomHandler.hasClass(focusCell, 'p-disabled');
|
||||
return !DomHandler.getAttribute(focusCell, 'data-p-disabled');
|
||||
});
|
||||
|
||||
if (hasNextFocusableDate) {
|
||||
|
@ -2120,7 +1920,7 @@ export default {
|
|||
let hasNextFocusableDate = prevTableRows.find((el) => {
|
||||
let focusCell = el.children[cellIndex].children[0];
|
||||
|
||||
return !DomHandler.hasClass(focusCell, 'p-disabled');
|
||||
return !DomHandler.getAttribute(focusCell, 'data-p-disabled');
|
||||
});
|
||||
|
||||
if (hasNextFocusableDate) {
|
||||
|
@ -2152,7 +1952,7 @@ export default {
|
|||
let hasNextFocusableDate = prevCells.find((el) => {
|
||||
let focusCell = el.children[0];
|
||||
|
||||
return !DomHandler.hasClass(focusCell, 'p-disabled');
|
||||
return !DomHandler.getAttribute(focusCell, 'data-p-disabled');
|
||||
});
|
||||
|
||||
if (hasNextFocusableDate) {
|
||||
|
@ -2181,7 +1981,7 @@ export default {
|
|||
let hasNextFocusableDate = nextCells.find((el) => {
|
||||
let focusCell = el.children[0];
|
||||
|
||||
return !DomHandler.hasClass(focusCell, 'p-disabled');
|
||||
return !DomHandler.getAttribute(focusCell, 'data-p-disabled');
|
||||
});
|
||||
|
||||
if (hasNextFocusableDate) {
|
||||
|
@ -2227,7 +2027,7 @@ export default {
|
|||
let currentRow = cell.parentElement;
|
||||
let focusCell = currentRow.children[0].children[0];
|
||||
|
||||
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
||||
if (DomHandler.getAttribute(focusCell, 'data-p-disabled')) {
|
||||
this.navigateToMonth(event, true, groupIndex);
|
||||
} else {
|
||||
focusCell.tabIndex = '0';
|
||||
|
@ -2243,7 +2043,7 @@ export default {
|
|||
let currentRow = cell.parentElement;
|
||||
let focusCell = currentRow.children[currentRow.children.length - 1].children[0];
|
||||
|
||||
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
||||
if (DomHandler.getAttribute(focusCell, 'data-p-disabled')) {
|
||||
this.navigateToMonth(event, false, groupIndex);
|
||||
} else {
|
||||
focusCell.tabIndex = '0';
|
||||
|
@ -2288,7 +2088,7 @@ export default {
|
|||
this.navBackward(event);
|
||||
} else {
|
||||
let prevMonthContainer = this.overlay.children[groupIndex - 1];
|
||||
let cells = DomHandler.find(prevMonthContainer, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
|
||||
let cells = DomHandler.find(prevMonthContainer, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
|
||||
let focusCell = cells[cells.length - 1];
|
||||
|
||||
focusCell.tabIndex = '0';
|
||||
|
@ -2300,7 +2100,7 @@ export default {
|
|||
this.navForward(event);
|
||||
} else {
|
||||
let nextMonthContainer = this.overlay.children[groupIndex + 1];
|
||||
let focusCell = DomHandler.findSingle(nextMonthContainer, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
|
||||
let focusCell = DomHandler.findSingle(nextMonthContainer, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
|
||||
|
||||
focusCell.tabIndex = '0';
|
||||
focusCell.focus();
|
||||
|
@ -2500,18 +2300,18 @@ export default {
|
|||
if (this.navigationState.button) {
|
||||
this.initFocusableCell();
|
||||
|
||||
if (this.navigationState.backward) DomHandler.findSingle(this.overlay, '.p-datepicker-prev').focus();
|
||||
else DomHandler.findSingle(this.overlay, '.p-datepicker-next').focus();
|
||||
if (this.navigationState.backward) this.previousButton.focus();
|
||||
else this.nextButton.focus();
|
||||
} else {
|
||||
if (this.navigationState.backward) {
|
||||
let cells;
|
||||
|
||||
if (this.currentView === 'month') {
|
||||
cells = DomHandler.find(this.overlay, '.p-monthpicker .p-monthpicker-month:not(.p-disabled)');
|
||||
cells = DomHandler.find(this.overlay, '[data-pc-section="monthpicker"] [data-pc-section="month"]:not([data-p-disabled="true"])');
|
||||
} else if (this.currentView === 'year') {
|
||||
cells = DomHandler.find(this.overlay, '.p-yearpicker .p-yearpicker-year:not(.p-disabled)');
|
||||
cells = DomHandler.find(this.overlay, '[data-pc-section="yearpicker"] [data-pc-section="year"]:not([data-p-disabled="true"])');
|
||||
} else {
|
||||
cells = DomHandler.find(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
|
||||
cells = DomHandler.find(this.overlay, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
|
||||
}
|
||||
|
||||
if (cells && cells.length > 0) {
|
||||
|
@ -2519,11 +2319,11 @@ export default {
|
|||
}
|
||||
} else {
|
||||
if (this.currentView === 'month') {
|
||||
cell = DomHandler.findSingle(this.overlay, '.p-monthpicker .p-monthpicker-month:not(.p-disabled)');
|
||||
cell = DomHandler.findSingle(this.overlay, '[data-pc-section="monthpicker"] [data-pc-section="month"]:not([data-p-disabled="true"])');
|
||||
} else if (this.currentView === 'year') {
|
||||
cell = DomHandler.findSingle(this.overlay, '.p-yearpicker .p-yearpicker-year:not(.p-disabled)');
|
||||
cell = DomHandler.findSingle(this.overlay, '[data-pc-section="yearpicker"] [data-pc-section="year"]:not([data-p-disabled="true"])');
|
||||
} else {
|
||||
cell = DomHandler.findSingle(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink)');
|
||||
cell = DomHandler.findSingle(this.overlay, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2542,25 +2342,25 @@ export default {
|
|||
let cell;
|
||||
|
||||
if (this.currentView === 'month') {
|
||||
let cells = DomHandler.find(this.overlay, '.p-monthpicker .p-monthpicker-month');
|
||||
let selectedCell = DomHandler.findSingle(this.overlay, '.p-monthpicker .p-monthpicker-month.p-highlight');
|
||||
let cells = DomHandler.find(this.overlay, '[data-pc-section="monthpicker"] [data-pc-section="month"]');
|
||||
let selectedCell = DomHandler.findSingle(this.overlay, '[data-pc-section="monthpicker"] [data-pc-section="month"][data-p-highlight="true"]');
|
||||
|
||||
cells.forEach((cell) => (cell.tabIndex = -1));
|
||||
cell = selectedCell || cells[0];
|
||||
} else if (this.currentView === 'year') {
|
||||
let cells = DomHandler.find(this.overlay, '.p-yearpicker .p-yearpicker-year');
|
||||
let selectedCell = DomHandler.findSingle(this.overlay, '.p-yearpicker .p-yearpicker-year.p-highlight');
|
||||
let cells = DomHandler.find(this.overlay, '[data-pc-section="yearpicker"] [data-pc-section="year"]');
|
||||
let selectedCell = DomHandler.findSingle(this.overlay, '[data-pc-section="yearpicker"] [data-pc-section="year"][data-p-highlight="true"]');
|
||||
|
||||
cells.forEach((cell) => (cell.tabIndex = -1));
|
||||
cell = selectedCell || cells[0];
|
||||
} else {
|
||||
cell = DomHandler.findSingle(this.overlay, 'span.p-highlight');
|
||||
cell = DomHandler.findSingle(this.overlay, 'span[data-p-highlight="true"]');
|
||||
|
||||
if (!cell) {
|
||||
let todayCell = DomHandler.findSingle(this.overlay, 'td.p-datepicker-today span:not(.p-disabled):not(.p-ink');
|
||||
let todayCell = DomHandler.findSingle(this.overlay, 'td[data-p-today="true"] span:not([data-p-disabled="true"]):not([data-p-ink="true"]');
|
||||
|
||||
if (todayCell) cell = todayCell;
|
||||
else cell = DomHandler.findSingle(this.overlay, '.p-datepicker-calendar td span:not(.p-disabled):not(.p-ink');
|
||||
else cell = DomHandler.findSingle(this.overlay, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"]');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2686,6 +2486,12 @@ export default {
|
|||
inputRef(el) {
|
||||
this.input = el;
|
||||
},
|
||||
previousButtonRef(el) {
|
||||
this.previousButton = el;
|
||||
},
|
||||
nextButtonRef(el) {
|
||||
this.nextButton = el;
|
||||
},
|
||||
getMonthName(index) {
|
||||
return this.$primevue.config.locale.monthNames[index];
|
||||
},
|
||||
|
@ -2715,7 +2521,7 @@ export default {
|
|||
this.onOverlayClick(event);
|
||||
},
|
||||
createResponsiveStyle() {
|
||||
if (this.numberOfMonths > 1 && this.responsiveOptions) {
|
||||
if (this.numberOfMonths > 1 && this.responsiveOptions && !this.isUnstyled) {
|
||||
if (!this.responsiveStyleElement) {
|
||||
this.responsiveStyleElement = document.createElement('style');
|
||||
this.responsiveStyleElement.type = 'text/css';
|
||||
|
@ -2792,35 +2598,6 @@ export default {
|
|||
inputFieldValue() {
|
||||
return this.formatValue(this.modelValue);
|
||||
},
|
||||
containerClass() {
|
||||
return [
|
||||
'p-calendar p-component p-inputwrapper',
|
||||
{
|
||||
'p-calendar-w-btn': this.showIcon,
|
||||
'p-calendar-timeonly': this.timeOnly,
|
||||
'p-calendar-disabled': this.disabled,
|
||||
'p-inputwrapper-filled': this.modelValue,
|
||||
'p-inputwrapper-focus': this.focused
|
||||
}
|
||||
];
|
||||
},
|
||||
panelStyleClass() {
|
||||
return [
|
||||
'p-datepicker p-component',
|
||||
this.panelClass,
|
||||
{
|
||||
'p-datepicker-inline': this.inline,
|
||||
'p-disabled': this.disabled,
|
||||
'p-datepicker-timeonly': this.timeOnly,
|
||||
'p-datepicker-multiple-month': this.numberOfMonths > 1,
|
||||
'p-datepicker-monthpicker': this.currentView === 'month',
|
||||
'p-datepicker-yearpicker': this.currentView === 'year',
|
||||
'p-datepicker-touch-ui': this.touchUI,
|
||||
'p-input-filled': this.$primevue.config.inputStyle === 'filled',
|
||||
'p-ripple-disabled': this.$primevue.config.ripple === false
|
||||
}
|
||||
];
|
||||
},
|
||||
months() {
|
||||
let months = [];
|
||||
|
||||
|
@ -3037,160 +2814,3 @@ export default {
|
|||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.p-calendar {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.p-calendar .p-inputtext {
|
||||
flex: 1 1 auto;
|
||||
width: 1%;
|
||||
}
|
||||
|
||||
.p-calendar-w-btn .p-inputtext {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.p-calendar-w-btn .p-datepicker-trigger {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
/* Fluid */
|
||||
.p-fluid .p-calendar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.p-fluid .p-calendar .p-inputtext {
|
||||
width: 1%;
|
||||
}
|
||||
|
||||
/* Datepicker */
|
||||
.p-calendar .p-datepicker {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.p-datepicker {
|
||||
width: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.p-datepicker-inline {
|
||||
display: inline-block;
|
||||
position: static;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.p-datepicker-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.p-datepicker-header .p-datepicker-title {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.p-datepicker-prev,
|
||||
.p-datepicker-next {
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Multiple Month DatePicker */
|
||||
.p-datepicker-multiple-month .p-datepicker-group-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.p-datepicker-multiple-month .p-datepicker-group-container .p-datepicker-group {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* DatePicker Table */
|
||||
.p-datepicker table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.p-datepicker td > span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Month Picker */
|
||||
.p-monthpicker-month {
|
||||
width: 33.3%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Year Picker */
|
||||
.p-yearpicker-year {
|
||||
width: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Button Bar */
|
||||
.p-datepicker-buttonbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Time Picker */
|
||||
.p-timepicker {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.p-timepicker button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.p-timepicker > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Touch UI */
|
||||
.p-datepicker-touch-ui,
|
||||
.p-calendar .p-datepicker-touch-ui {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
min-width: 80vw;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -16,6 +16,7 @@ function create(el) {
|
|||
ink.className = 'p-ink';
|
||||
ink.setAttribute('role', 'presentation');
|
||||
ink.setAttribute('aria-hidden', 'true');
|
||||
ink.setAttribute('data-p-ink', 'true');
|
||||
el.appendChild(ink);
|
||||
|
||||
ink.addEventListener('animationend', onAnimationEnd);
|
||||
|
|
|
@ -167,6 +167,12 @@ export default {
|
|||
return false;
|
||||
},
|
||||
|
||||
addStyles(element, styles = {}) {
|
||||
if (element) {
|
||||
Object.entries(styles).forEach(([key, value]) => (element.style[key] = value));
|
||||
}
|
||||
},
|
||||
|
||||
find(element, selector) {
|
||||
return this.isElement(element) ? element.querySelectorAll(selector) : [];
|
||||
},
|
||||
|
@ -175,6 +181,32 @@ export default {
|
|||
return this.isElement(element) ? element.querySelector(selector) : null;
|
||||
},
|
||||
|
||||
getAttribute(element, name) {
|
||||
if (element) {
|
||||
const value = element.getAttribute(name);
|
||||
|
||||
if (!isNaN(value)) {
|
||||
return +value;
|
||||
}
|
||||
|
||||
if (value === 'true' || value === 'false') {
|
||||
return value === 'true';
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
isAttributeEquals(element, name, value) {
|
||||
return element ? this.getAttribute(element, name) === value : false;
|
||||
},
|
||||
|
||||
isAttributeNotEquals(element, name, value) {
|
||||
return !this.isAttributeEquals(element, name, value);
|
||||
},
|
||||
|
||||
getHeight(el) {
|
||||
if (el) {
|
||||
let height = el.offsetHeight;
|
||||
|
@ -203,15 +235,15 @@ export default {
|
|||
|
||||
absolutePosition(element, target) {
|
||||
if (element) {
|
||||
let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
|
||||
let elementOuterHeight = elementDimensions.height;
|
||||
let elementOuterWidth = elementDimensions.width;
|
||||
let targetOuterHeight = target.offsetHeight;
|
||||
let targetOuterWidth = target.offsetWidth;
|
||||
let targetOffset = target.getBoundingClientRect();
|
||||
let windowScrollTop = this.getWindowScrollTop();
|
||||
let windowScrollLeft = this.getWindowScrollLeft();
|
||||
let viewport = this.getViewport();
|
||||
const elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
|
||||
const elementOuterHeight = elementDimensions.height;
|
||||
const elementOuterWidth = elementDimensions.width;
|
||||
const targetOuterHeight = target.offsetHeight;
|
||||
const targetOuterWidth = target.offsetWidth;
|
||||
const targetOffset = target.getBoundingClientRect();
|
||||
const windowScrollTop = this.getWindowScrollTop();
|
||||
const windowScrollLeft = this.getWindowScrollLeft();
|
||||
const viewport = this.getViewport();
|
||||
let top, left;
|
||||
|
||||
if (targetOffset.top + targetOuterHeight + elementOuterHeight > viewport.height) {
|
||||
|
@ -236,7 +268,7 @@ export default {
|
|||
|
||||
relativePosition(element, target) {
|
||||
if (element) {
|
||||
let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
|
||||
const elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
|
||||
const targetHeight = target.offsetHeight;
|
||||
const targetOffset = target.getBoundingClientRect();
|
||||
const viewport = this.getViewport();
|
||||
|
|
Loading…
Reference in New Issue