Accessibility for Calendar
parent
e25ec06753
commit
5adb1e8d78
|
@ -1,24 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<span ref="container" :class="containerClass" :style="style">
|
<span ref="container" :id="id" :class="containerClass" :style="style">
|
||||||
<input :ref="inputRef" v-if="!inline" type="text" :class="['p-inputtext p-component', inputClass]" :style="inputStyle" @input="onInput" v-bind="$attrs"
|
<input :ref="inputRef" v-if="!inline" type="text" role="combobox" :id="inputId" :class="['p-inputtext p-component', inputClass]" :style="inputStyle"
|
||||||
@focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :readonly="!manualInput" inputmode="none">
|
aria-autocomplete="none" aria-haspopup="dialog" :aria-expanded="overlayVisible" :aria-controls="panelId" inputmode="none"
|
||||||
<CalendarButton v-if="showIcon" :icon="icon" tabindex="-1" class="p-datepicker-trigger" :disabled="$attrs.disabled" @click="onButtonClick" type="button" :aria-label="inputFieldValue"/>
|
@input="onInput" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :readonly="!manualInput" v-bind="inputProps">
|
||||||
|
<CalendarButton v-if="showIcon" :icon="icon" class="p-datepicker-trigger" :disabled="disabled" @click="onButtonClick" type="button" :aria-label="$primevue.config.locale.chooseDate" aria-haspopup="dialog" :aria-expanded="overlayVisible" :aria-controls="panelId"/>
|
||||||
<Portal :appendTo="appendTo" :disabled="inline">
|
<Portal :appendTo="appendTo" :disabled="inline">
|
||||||
<transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @after-leave="onOverlayAfterLeave" @leave="onOverlayLeave">
|
<transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @after-leave="onOverlayAfterLeave" @leave="onOverlayLeave">
|
||||||
<div :ref="overlayRef" :class="panelStyleClass" v-if="inline || overlayVisible" :role="inline ? null : 'dialog'" @click="onOverlayClick" @mouseup="onOverlayMouseUp">
|
<div :ref="overlayRef" :id="panelId" :class="panelStyleClass" v-if="inline || overlayVisible" :role="inline ? null : 'dialog'" :aria-modal="inline ? null : 'true'" :aria-label="$primevue.config.locale.chooseDate" @click="onOverlayClick" @mouseup="onOverlayMouseUp" v-bind="panelProps">
|
||||||
<template v-if="!timeOnly">
|
<template v-if="!timeOnly">
|
||||||
<div class="p-datepicker-group-container">
|
<div class="p-datepicker-group-container">
|
||||||
<div class="p-datepicker-group" v-for="(month,groupIndex) of months" :key="month.month + month.year">
|
<div class="p-datepicker-group" v-for="(month,groupIndex) of months" :key="month.month + month.year">
|
||||||
<div class="p-datepicker-header">
|
<div class="p-datepicker-header">
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
<button class="p-datepicker-prev p-link" v-show="groupIndex === 0" @click="onPrevButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled">
|
<button class="p-datepicker-prev p-link" v-show="groupIndex === 0" @click="onPrevButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="disabled" :aria-label=" currentView === 'year' ? $primevue.config.locale.prevDecade: currentView === 'month' ? $primevue.config.locale.prevYear : $primevue.config.locale.prevMonth">
|
||||||
<span class="p-datepicker-prev-icon pi pi-chevron-left"></span>
|
<span class="p-datepicker-prev-icon pi pi-chevron-left"></span>
|
||||||
</button>
|
</button>
|
||||||
<div class="p-datepicker-title">
|
<div class="p-datepicker-title">
|
||||||
<button type="button" @click="switchToMonthView" @keydown="onContainerButtonKeydown" v-if="currentView === 'date'" class="p-datepicker-month p-link" :disabled="switchViewButtonDisabled">
|
<button type="button" @click="switchToMonthView" @keydown="onContainerButtonKeydown" v-if="currentView === 'date'" class="p-datepicker-month p-link" :disabled="switchViewButtonDisabled" :aria-label="$primevue.config.locale.chooseMonth">
|
||||||
{{getMonthName(month.month)}}
|
{{getMonthName(month.month)}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" @click="switchToYearView" @keydown="onContainerButtonKeydown" v-if="currentView !== 'year'" class="p-datepicker-year p-link" :disabled="switchViewButtonDisabled">
|
<button type="button" @click="switchToYearView" @keydown="onContainerButtonKeydown" v-if="currentView !== 'year'" class="p-datepicker-year p-link" :disabled="switchViewButtonDisabled" :aria-label="$primevue.config.locale.chooseYear">
|
||||||
{{getYear(month)}}
|
{{getYear(month)}}
|
||||||
</button>
|
</button>
|
||||||
<span class="p-datepicker-decade" v-if="currentView === 'year'">
|
<span class="p-datepicker-decade" v-if="currentView === 'year'">
|
||||||
|
@ -28,18 +29,18 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="p-datepicker-next p-link" v-show="numberOfMonths === 1 ? true : (groupIndex === numberOfMonths - 1)"
|
<button class="p-datepicker-next p-link" v-show="numberOfMonths === 1 ? true : (groupIndex === numberOfMonths - 1)"
|
||||||
@click="onNextButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled">
|
@click="onNextButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="disabled" :aria-label=" currentView === 'year' ? $primevue.config.locale.nextDecade : currentView === 'month' ? $primevue.config.locale.nextYear : $primevue.config.locale.nextMonth">
|
||||||
<span class="p-datepicker-next-icon pi pi-chevron-right"></span>
|
<span class="p-datepicker-next-icon pi pi-chevron-right"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-datepicker-calendar-container" v-if="currentView ==='date'">
|
<div class="p-datepicker-calendar-container" v-if="currentView ==='date'">
|
||||||
<table class="p-datepicker-calendar">
|
<table class="p-datepicker-calendar" role="grid">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" v-if="showWeek" class="p-datepicker-weekheader p-disabled">
|
<th scope="col" v-if="showWeek" class="p-datepicker-weekheader p-disabled">
|
||||||
<span>{{weekHeaderLabel}}</span>
|
<span>{{weekHeaderLabel}}</span>
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" v-for="weekDay of weekDays" :key="weekDay">
|
<th scope="col" v-for="weekDay of weekDays" :key="weekDay" :abbr="weekDay">
|
||||||
<span>{{weekDay}}</span>
|
<span>{{weekDay}}</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -52,11 +53,14 @@
|
||||||
{{month.weekNumbers[i]}}
|
{{month.weekNumbers[i]}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td v-for="date of week" :key="date.day + '' + date.month" :class="{'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today}">
|
<td v-for="date of week" :aria-label="date.day" :key="date.day + '' + date.month" :class="{'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today}">
|
||||||
<span :class="{'p-highlight': isSelected(date), 'p-disabled': !date.selectable}" @click="onDateSelect($event, date)"
|
<span :class="{'p-highlight': isSelected(date), 'p-disabled': !date.selectable}" @click="onDateSelect($event, date)"
|
||||||
draggable="false" @keydown="onDateCellKeydown($event,date,groupIndex)" v-ripple>
|
draggable="false" @keydown="onDateCellKeydown($event,date,groupIndex)" v-ripple :aria-selected="isSelected(date)">
|
||||||
<slot name="date" :date="date">{{date.day}}</slot>
|
<slot name="date" :date="date">{{date.day}}</slot>
|
||||||
</span>
|
</span>
|
||||||
|
<div v-if="isSelected(date)" class="p-hidden-accessible" aria-live="polite">
|
||||||
|
{{date.day}}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -68,23 +72,29 @@
|
||||||
<span v-for="(m,i) of monthPickerValues" :key="m" @click="onMonthSelect($event, i)" @keydown="onMonthCellKeydown($event,i)"
|
<span v-for="(m,i) of monthPickerValues" :key="m" @click="onMonthSelect($event, i)" @keydown="onMonthCellKeydown($event,i)"
|
||||||
class="p-monthpicker-month" :class="{'p-highlight': isMonthSelected(i)}" v-ripple>
|
class="p-monthpicker-month" :class="{'p-highlight': isMonthSelected(i)}" v-ripple>
|
||||||
{{m}}
|
{{m}}
|
||||||
|
<div v-if="isMonthSelected(i)" class="p-hidden-accessible" aria-live="polite">
|
||||||
|
{{m}}
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-yearpicker" v-if="currentView === 'year'">
|
<div class="p-yearpicker" v-if="currentView === 'year'">
|
||||||
<span v-for="y of yearPickerValues" :key="y" @click="onYearSelect($event, y)" @keydown="onYearCellKeydown($event,y)"
|
<span v-for="y of yearPickerValues" :key="y" @click="onYearSelect($event, y)" @keydown="onYearCellKeydown($event,y)"
|
||||||
class="p-yearpicker-year" :class="{'p-highlight': isYearSelected(y)}" v-ripple>
|
class="p-yearpicker-year" :class="{'p-highlight': isYearSelected(y)}" v-ripple>
|
||||||
{{y}}
|
{{y}}
|
||||||
|
<div v-if="isYearSelected(y)" class="p-hidden-accessible" aria-live="polite">
|
||||||
|
{{y}}
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="p-timepicker" v-if="(showTime||timeOnly) && currentView === 'date'">
|
<div class="p-timepicker" v-if="(showTime||timeOnly) && currentView === 'date'">
|
||||||
<div class="p-hour-picker">
|
<div class="p-hour-picker">
|
||||||
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 0, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
|
<button class="p-link" :aria-label="$primevue.config.locale.nextHour" @mousedown="onTimePickerElementMouseDown($event, 0, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
|
||||||
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, 1)" @keydown.space="onTimePickerElementMouseDown($event, 0, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, 1)" @keydown.space="onTimePickerElementMouseDown($event, 0, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
||||||
<span class="pi pi-chevron-up"></span>
|
<span class="pi pi-chevron-up"></span>
|
||||||
</button>
|
</button>
|
||||||
<span>{{formattedCurrentHour}}</span>
|
<span>{{formattedCurrentHour}}</span>
|
||||||
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 0, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
|
<button class="p-link" :aria-label="$primevue.config.locale.prevHour" @mousedown="onTimePickerElementMouseDown($event, 0, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
|
||||||
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, -1)" @keydown.space="onTimePickerElementMouseDown($event, 0, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, -1)" @keydown.space="onTimePickerElementMouseDown($event, 0, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
||||||
<span class="pi pi-chevron-down"></span>
|
<span class="pi pi-chevron-down"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -93,12 +103,12 @@
|
||||||
<span>{{timeSeparator}}</span>
|
<span>{{timeSeparator}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-minute-picker">
|
<div class="p-minute-picker">
|
||||||
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 1, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
|
<button class="p-link" :aria-label="$primevue.config.locale.nextMinute" @mousedown="onTimePickerElementMouseDown($event, 1, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="disabled"
|
||||||
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, 1)" @keydown.space="onTimePickerElementMouseDown($event, 1, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, 1)" @keydown.space="onTimePickerElementMouseDown($event, 1, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
||||||
<span class="pi pi-chevron-up"></span>
|
<span class="pi pi-chevron-up"></span>
|
||||||
</button>
|
</button>
|
||||||
<span>{{formattedCurrentMinute}}</span>
|
<span>{{formattedCurrentMinute}}</span>
|
||||||
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 1, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
|
<button class="p-link" :aria-label="$primevue.config.locale.prevMinute" @mousedown="onTimePickerElementMouseDown($event, 1, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="disabled"
|
||||||
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, -1)" @keydown.space="onTimePickerElementMouseDown($event, 1, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, -1)" @keydown.space="onTimePickerElementMouseDown($event, 1, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
||||||
<span class="pi pi-chevron-down"></span>
|
<span class="pi pi-chevron-down"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -107,12 +117,12 @@
|
||||||
<span>{{timeSeparator}}</span>
|
<span>{{timeSeparator}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-second-picker" v-if="showSeconds">
|
<div class="p-second-picker" v-if="showSeconds">
|
||||||
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 2, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
|
<button class="p-link" :aria-label="$primevue.config.locale.nextSecond" @mousedown="onTimePickerElementMouseDown($event, 2, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="disabled"
|
||||||
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, 1)" @keydown.space="onTimePickerElementMouseDown($event, 2, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, 1)" @keydown.space="onTimePickerElementMouseDown($event, 2, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
||||||
<span class="pi pi-chevron-up"></span>
|
<span class="pi pi-chevron-up"></span>
|
||||||
</button>
|
</button>
|
||||||
<span>{{formattedCurrentSecond}}</span>
|
<span>{{formattedCurrentSecond}}</span>
|
||||||
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 2, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
|
<button class="p-link" :aria-label="$primevue.config.locale.prevSecond" @mousedown="onTimePickerElementMouseDown($event, 2, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="disabled"
|
||||||
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, -1)" @keydown.space="onTimePickerElementMouseDown($event, 2, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, -1)" @keydown.space="onTimePickerElementMouseDown($event, 2, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" @keyup.space="onTimePickerElementMouseUp($event)" type="button">
|
||||||
<span class="pi pi-chevron-down"></span>
|
<span class="pi pi-chevron-down"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -121,11 +131,11 @@
|
||||||
<span>{{timeSeparator}}</span>
|
<span>{{timeSeparator}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-ampm-picker" v-if="hourFormat=='12'">
|
<div class="p-ampm-picker" v-if="hourFormat=='12'">
|
||||||
<button class="p-link" @click="toggleAMPM($event)" type="button" v-ripple :disabled="$attrs.disabled">
|
<button class="p-link" :aria-label="$primevue.config.locale.am" @click="toggleAMPM($event)" type="button" v-ripple :disabled="disabled">
|
||||||
<span class="pi pi-chevron-up"></span>
|
<span class="pi pi-chevron-up"></span>
|
||||||
</button>
|
</button>
|
||||||
<span>{{pm ? 'PM' : 'AM'}}</span>
|
<span>{{pm ? 'PM' : 'AM'}}</span>
|
||||||
<button class="p-link" @click="toggleAMPM($event)" type="button" v-ripple :disabled="$attrs.disabled">
|
<button class="p-link" :aria-label="$primevue.config.locale.pm" @click="toggleAMPM($event)" type="button" v-ripple :disabled="disabled">
|
||||||
<span class="pi pi-chevron-down"></span>
|
<span class="pi pi-chevron-down"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -150,7 +160,6 @@ import Portal from 'primevue/portal';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Calendar',
|
name: 'Calendar',
|
||||||
inheritAttrs: false,
|
|
||||||
emits: ['show', 'hide', 'input', 'month-change', 'year-change', 'date-select', 'update:modelValue', 'today-click', 'clear-click', 'focus', 'blur', 'keydown'],
|
emits: ['show', 'hide', 'input', 'month-change', 'year-change', 'date-select', 'update:modelValue', 'today-click', 'clear-click', 'focus', 'blur', 'keydown'],
|
||||||
props: {
|
props: {
|
||||||
modelValue: null,
|
modelValue: null,
|
||||||
|
@ -303,10 +312,22 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'body'
|
default: 'body'
|
||||||
},
|
},
|
||||||
|
id: null,
|
||||||
|
inputId: null,
|
||||||
inputClass: null,
|
inputClass: null,
|
||||||
inputStyle: null,
|
inputStyle: null,
|
||||||
class: null,
|
class: null,
|
||||||
style: null
|
style: null,
|
||||||
|
inputProps: null,
|
||||||
|
panelProps: null,
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
navigationState: null,
|
navigationState: null,
|
||||||
timePickerChange: false,
|
timePickerChange: false,
|
||||||
|
@ -329,7 +350,7 @@ export default {
|
||||||
if (this.inline) {
|
if (this.inline) {
|
||||||
this.overlay && this.overlay.setAttribute(this.attributeSelector, '');
|
this.overlay && this.overlay.setAttribute(this.attributeSelector, '');
|
||||||
|
|
||||||
if (!this.$attrs.disabled) {
|
if (!this.disabled) {
|
||||||
this.preventFocus = true;
|
this.preventFocus = true;
|
||||||
this.initFocusableCell();
|
this.initFocusableCell();
|
||||||
|
|
||||||
|
@ -660,15 +681,20 @@ export default {
|
||||||
this.decrementDecade();
|
this.decrementDecade();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.currentMonth === 0) {
|
if (event.shiftKey) {
|
||||||
this.currentMonth = 11;
|
|
||||||
this.decrementYear();
|
this.decrementYear();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.currentMonth--;
|
if (this.currentMonth === 0) {
|
||||||
}
|
this.currentMonth = 11;
|
||||||
|
this.decrementYear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.currentMonth--;
|
||||||
|
}
|
||||||
|
|
||||||
this.$emit('month-change', {month: this.currentMonth + 1, year: this.currentYear});
|
this.$emit('month-change', {month: this.currentMonth + 1, year: this.currentYear});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
navForward(event) {
|
navForward(event) {
|
||||||
|
@ -685,15 +711,20 @@ export default {
|
||||||
this.incrementDecade();
|
this.incrementDecade();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.currentMonth === 11) {
|
if (event.shiftKey) {
|
||||||
this.currentMonth = 0;
|
|
||||||
this.incrementYear();
|
this.incrementYear();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.currentMonth++;
|
if (this.currentMonth === 11) {
|
||||||
}
|
this.currentMonth = 0;
|
||||||
|
this.incrementYear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.currentMonth++;
|
||||||
|
}
|
||||||
|
|
||||||
this.$emit('month-change', {month: this.currentMonth + 1, year: this.currentYear});
|
this.$emit('month-change', {month: this.currentMonth + 1, year: this.currentYear});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
decrementYear() {
|
decrementYear() {
|
||||||
|
@ -719,7 +750,7 @@ export default {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
return !this.$attrs.disabled && !this.$attrs.readonly;
|
return !this.disabled && !this.readonly;
|
||||||
},
|
},
|
||||||
updateCurrentTimeMeta(date) {
|
updateCurrentTimeMeta(date) {
|
||||||
let currentHour = date.getHours();
|
let currentHour = date.getHours();
|
||||||
|
@ -853,7 +884,7 @@ export default {
|
||||||
this.$emit('year-change', {month: this.currentMonth + 1, year: this.currentYear});
|
this.$emit('year-change', {month: this.currentMonth + 1, year: this.currentYear});
|
||||||
},
|
},
|
||||||
onDateSelect(event, dateMeta) {
|
onDateSelect(event, dateMeta) {
|
||||||
if (this.$attrs.disabled || !dateMeta.selectable) {
|
if (this.disabled || !dateMeta.selectable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1736,9 +1767,8 @@ export default {
|
||||||
const cellContent = event.currentTarget;
|
const cellContent = event.currentTarget;
|
||||||
const cell = cellContent.parentElement;
|
const cell = cellContent.parentElement;
|
||||||
|
|
||||||
switch (event.which) {
|
switch (event.code) {
|
||||||
//down arrow
|
case 'ArrowDown': {
|
||||||
case 40: {
|
|
||||||
cellContent.tabIndex = '-1';
|
cellContent.tabIndex = '-1';
|
||||||
let cellIndex = DomHandler.index(cell);
|
let cellIndex = DomHandler.index(cell);
|
||||||
let nextRow = cell.parentElement.nextElementSibling;
|
let nextRow = cell.parentElement.nextElementSibling;
|
||||||
|
@ -1761,8 +1791,7 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//up arrow
|
case 'ArrowUp': {
|
||||||
case 38: {
|
|
||||||
cellContent.tabIndex = '-1';
|
cellContent.tabIndex = '-1';
|
||||||
let cellIndex = DomHandler.index(cell);
|
let cellIndex = DomHandler.index(cell);
|
||||||
let prevRow = cell.parentElement.previousElementSibling;
|
let prevRow = cell.parentElement.previousElementSibling;
|
||||||
|
@ -1785,14 +1814,13 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//left arrow
|
case 'ArrowLeft': {
|
||||||
case 37: {
|
|
||||||
cellContent.tabIndex = '-1';
|
cellContent.tabIndex = '-1';
|
||||||
let prevCell = cell.previousElementSibling;
|
let prevCell = cell.previousElementSibling;
|
||||||
if (prevCell) {
|
if (prevCell) {
|
||||||
let focusCell = prevCell.children[0];
|
let focusCell = prevCell.children[0];
|
||||||
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
||||||
this.navigateToMonth(true, groupIndex);
|
this.navigateToMonth(event, true, groupIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
focusCell.tabIndex = '0';
|
focusCell.tabIndex = '0';
|
||||||
|
@ -1800,20 +1828,19 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.navigateToMonth(true, groupIndex);
|
this.navigateToMonth(event, true, groupIndex);
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//right arrow
|
case 'ArrowRight': {
|
||||||
case 39: {
|
|
||||||
cellContent.tabIndex = '-1';
|
cellContent.tabIndex = '-1';
|
||||||
let nextCell = cell.nextElementSibling;
|
let nextCell = cell.nextElementSibling;
|
||||||
if (nextCell) {
|
if (nextCell) {
|
||||||
let focusCell = nextCell.children[0];
|
let focusCell = nextCell.children[0];
|
||||||
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
||||||
this.navigateToMonth(false, groupIndex);
|
this.navigateToMonth(event, false, groupIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
focusCell.tabIndex = '0';
|
focusCell.tabIndex = '0';
|
||||||
|
@ -1821,42 +1848,94 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.navigateToMonth(false, groupIndex);
|
this.navigateToMonth(event, false, groupIndex);
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//enter
|
case 'Enter':
|
||||||
//space
|
case 'Space': {
|
||||||
case 13:
|
|
||||||
case 32: {
|
|
||||||
this.onDateSelect(event, date);
|
this.onDateSelect(event, date);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//escape
|
case 'Escape': {
|
||||||
case 27: {
|
|
||||||
this.overlayVisible = false;
|
this.overlayVisible = false;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//tab
|
case 'Tab': {
|
||||||
case 9: {
|
|
||||||
if (!this.inline) {
|
if (!this.inline) {
|
||||||
this.trapFocus(event);
|
this.trapFocus(event);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'Home': {
|
||||||
|
cellContent.tabIndex = '-1';
|
||||||
|
let currentRow = cell.parentElement;
|
||||||
|
let focusCell = currentRow.children[0].children[0];
|
||||||
|
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
||||||
|
this.navigateToMonth(event, true, groupIndex);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
focusCell.tabIndex = '0';
|
||||||
|
focusCell.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'End': {
|
||||||
|
cellContent.tabIndex = '-1';
|
||||||
|
let currentRow = cell.parentElement;
|
||||||
|
let focusCell = currentRow.children[currentRow.children.length -1].children[0];
|
||||||
|
if (DomHandler.hasClass(focusCell, 'p-disabled')) {
|
||||||
|
this.navigateToMonth(event, false, groupIndex);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
focusCell.tabIndex = '0';
|
||||||
|
focusCell.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'PageUp': {
|
||||||
|
cellContent.tabIndex = '-1';
|
||||||
|
if (event.shiftKey) {
|
||||||
|
this.navigationState = {backward: true};
|
||||||
|
this.navBackward(event);
|
||||||
|
}
|
||||||
|
else this.navigateToMonth(event, true, groupIndex);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'PageDown': {
|
||||||
|
cellContent.tabIndex = '-1';
|
||||||
|
if (event.shiftKey) {
|
||||||
|
this.navigationState = {backward: false};
|
||||||
|
this.navForward(event);
|
||||||
|
}
|
||||||
|
else this.navigateToMonth(event, false, groupIndex);
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//no op
|
//no op
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
navigateToMonth(prev, groupIndex) {
|
navigateToMonth(event, prev, groupIndex) {
|
||||||
if (prev) {
|
if (prev) {
|
||||||
if (this.numberOfMonths === 1 || (groupIndex === 0)) {
|
if (this.numberOfMonths === 1 || (groupIndex === 0)) {
|
||||||
this.navigationState = {backward: true};
|
this.navigationState = {backward: true};
|
||||||
|
@ -1886,14 +1965,13 @@ export default {
|
||||||
onMonthCellKeydown(event, index) {
|
onMonthCellKeydown(event, index) {
|
||||||
const cell = event.currentTarget;
|
const cell = event.currentTarget;
|
||||||
|
|
||||||
switch (event.which) {
|
switch (event.code) {
|
||||||
//arrows
|
case 'ArrowUp':
|
||||||
case 38:
|
case 'ArrowDown': {
|
||||||
case 40: {
|
|
||||||
cell.tabIndex = '-1';
|
cell.tabIndex = '-1';
|
||||||
var cells = cell.parentElement.children;
|
var cells = cell.parentElement.children;
|
||||||
var cellIndex = DomHandler.index(cell);
|
var cellIndex = DomHandler.index(cell);
|
||||||
let nextCell = cells[event.which === 40 ? cellIndex + 3 : cellIndex -3];
|
let nextCell = cells[event.code === 'ArrowDown' ? cellIndex + 3 : cellIndex -3];
|
||||||
if (nextCell) {
|
if (nextCell) {
|
||||||
nextCell.tabIndex = '0';
|
nextCell.tabIndex = '0';
|
||||||
nextCell.focus();
|
nextCell.focus();
|
||||||
|
@ -1902,8 +1980,7 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//left arrow
|
case 'ArrowLeft': {
|
||||||
case 37: {
|
|
||||||
cell.tabIndex = '-1';
|
cell.tabIndex = '-1';
|
||||||
let prevCell = cell.previousElementSibling;
|
let prevCell = cell.previousElementSibling;
|
||||||
if (prevCell) {
|
if (prevCell) {
|
||||||
|
@ -1918,8 +1995,7 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//right arrow
|
case 'ArrowRight': {
|
||||||
case 39: {
|
|
||||||
cell.tabIndex = '-1';
|
cell.tabIndex = '-1';
|
||||||
let nextCell = cell.nextElementSibling;
|
let nextCell = cell.nextElementSibling;
|
||||||
if (nextCell) {
|
if (nextCell) {
|
||||||
|
@ -1934,24 +2010,36 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//enter
|
case 'PageUp': {
|
||||||
//space
|
if (event.shiftKey) return;
|
||||||
case 13:
|
this.navigationState = {backward: true};
|
||||||
case 32: {
|
this.navBackward(event);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'PageDown': {
|
||||||
|
if (event.shiftKey) return;
|
||||||
|
this.navigationState = {backward: false};
|
||||||
|
this.navForward(event);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Enter':
|
||||||
|
case 'Space': {
|
||||||
this.onMonthSelect(event, index);
|
this.onMonthSelect(event, index);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//escape
|
case 'Escape': {
|
||||||
case 27: {
|
|
||||||
this.overlayVisible = false;
|
this.overlayVisible = false;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//tab
|
case 'Tab': {
|
||||||
case 9: {
|
|
||||||
this.trapFocus(event);
|
this.trapFocus(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1964,14 +2052,13 @@ export default {
|
||||||
onYearCellKeydown(event, index) {
|
onYearCellKeydown(event, index) {
|
||||||
const cell = event.currentTarget;
|
const cell = event.currentTarget;
|
||||||
|
|
||||||
switch (event.which) {
|
switch (event.code) {
|
||||||
//arrows
|
case 'ArrowUp':
|
||||||
case 38:
|
case 'ArrowDown': {
|
||||||
case 40: {
|
|
||||||
cell.tabIndex = '-1';
|
cell.tabIndex = '-1';
|
||||||
var cells = cell.parentElement.children;
|
var cells = cell.parentElement.children;
|
||||||
var cellIndex = DomHandler.index(cell);
|
var cellIndex = DomHandler.index(cell);
|
||||||
let nextCell = cells[event.which === 40 ? cellIndex + 2 : cellIndex - 2];
|
let nextCell = cells[event.code === 'ArrowDown' ? cellIndex + 2 : cellIndex - 2];
|
||||||
if (nextCell) {
|
if (nextCell) {
|
||||||
nextCell.tabIndex = '0';
|
nextCell.tabIndex = '0';
|
||||||
nextCell.focus();
|
nextCell.focus();
|
||||||
|
@ -1980,8 +2067,7 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//left arrow
|
case 'ArrowLeft': {
|
||||||
case 37: {
|
|
||||||
cell.tabIndex = '-1';
|
cell.tabIndex = '-1';
|
||||||
let prevCell = cell.previousElementSibling;
|
let prevCell = cell.previousElementSibling;
|
||||||
if (prevCell) {
|
if (prevCell) {
|
||||||
|
@ -1996,8 +2082,7 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//right arrow
|
case 'ArrowRight': {
|
||||||
case 39: {
|
|
||||||
cell.tabIndex = '-1';
|
cell.tabIndex = '-1';
|
||||||
let nextCell = cell.nextElementSibling;
|
let nextCell = cell.nextElementSibling;
|
||||||
if (nextCell) {
|
if (nextCell) {
|
||||||
|
@ -2012,24 +2097,36 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//enter
|
case 'PageUp': {
|
||||||
//space
|
if (event.shiftKey) return;
|
||||||
case 13:
|
this.navigationState = {backward: true};
|
||||||
case 32: {
|
this.navBackward(event);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'PageDown': {
|
||||||
|
if (event.shiftKey) return;
|
||||||
|
this.navigationState = {backward: false};
|
||||||
|
this.navForward(event);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'Enter':
|
||||||
|
case 'Space': {
|
||||||
this.onYearSelect(event, index);
|
this.onYearSelect(event, index);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//escape
|
case 'Escape': {
|
||||||
case 27: {
|
|
||||||
this.overlayVisible = false;
|
this.overlayVisible = false;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//tab
|
case 'Tab': {
|
||||||
case 9: {
|
|
||||||
this.trapFocus(event);
|
this.trapFocus(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2156,14 +2253,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onContainerButtonKeydown(event) {
|
onContainerButtonKeydown(event) {
|
||||||
switch (event.which) {
|
switch (event.code) {
|
||||||
//tab
|
case 'Tab':
|
||||||
case 9:
|
|
||||||
this.trapFocus(event);
|
this.trapFocus(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//escape
|
case 'Escape':
|
||||||
case 27:
|
|
||||||
this.overlayVisible = false;
|
this.overlayVisible = false;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
|
@ -2206,16 +2301,16 @@ export default {
|
||||||
event.target.value = this.formatValue(this.modelValue);
|
event.target.value = this.formatValue(this.modelValue);
|
||||||
},
|
},
|
||||||
onKeyDown(event) {
|
onKeyDown(event) {
|
||||||
if (event.keyCode === 40 && this.overlay) {
|
if (event.code === 'ArrowDown' && this.overlay) {
|
||||||
this.trapFocus(event);
|
this.trapFocus(event);
|
||||||
}
|
}
|
||||||
else if (event.keyCode === 27) {
|
else if (event.code === 'Escape') {
|
||||||
if (this.overlayVisible) {
|
if (this.overlayVisible) {
|
||||||
this.overlayVisible = false;
|
this.overlayVisible = false;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.keyCode === 9) {
|
else if (event.code === 'Tab') {
|
||||||
if (this.overlay) {
|
if (this.overlay) {
|
||||||
DomHandler.getFocusableElements(this.overlay).forEach(el => el.tabIndex = '-1');
|
DomHandler.getFocusableElements(this.overlay).forEach(el => el.tabIndex = '-1');
|
||||||
}
|
}
|
||||||
|
@ -2334,7 +2429,7 @@ export default {
|
||||||
{
|
{
|
||||||
'p-calendar-w-btn': this.showIcon,
|
'p-calendar-w-btn': this.showIcon,
|
||||||
'p-calendar-timeonly': this.timeOnly,
|
'p-calendar-timeonly': this.timeOnly,
|
||||||
'p-calendar-disabled': this.$attrs.disabled,
|
'p-calendar-disabled': this.disabled,
|
||||||
'p-inputwrapper-filled': this.modelValue,
|
'p-inputwrapper-filled': this.modelValue,
|
||||||
'p-inputwrapper-focus': this.focused
|
'p-inputwrapper-focus': this.focused
|
||||||
}
|
}
|
||||||
|
@ -2343,7 +2438,7 @@ export default {
|
||||||
panelStyleClass() {
|
panelStyleClass() {
|
||||||
return ['p-datepicker p-component', this.panelClass, {
|
return ['p-datepicker p-component', this.panelClass, {
|
||||||
'p-datepicker-inline': this.inline,
|
'p-datepicker-inline': this.inline,
|
||||||
'p-disabled': this.$attrs.disabled,
|
'p-disabled': this.disabled,
|
||||||
'p-datepicker-timeonly': this.timeOnly,
|
'p-datepicker-timeonly': this.timeOnly,
|
||||||
'p-datepicker-multiple-month': this.numberOfMonths > 1,
|
'p-datepicker-multiple-month': this.numberOfMonths > 1,
|
||||||
'p-datepicker-monthpicker': (this.currentView === 'month'),
|
'p-datepicker-monthpicker': (this.currentView === 'month'),
|
||||||
|
@ -2509,7 +2604,10 @@ export default {
|
||||||
return UniqueComponentId();
|
return UniqueComponentId();
|
||||||
},
|
},
|
||||||
switchViewButtonDisabled() {
|
switchViewButtonDisabled() {
|
||||||
return this.numberOfMonths > 1 || this.$attrs.disabled;
|
return this.numberOfMonths > 1 || this.disabled;
|
||||||
|
},
|
||||||
|
panelId() {
|
||||||
|
return UniqueComponentId() + '_panel';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -36,6 +36,23 @@ const defaultOptions = {
|
||||||
dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"],
|
dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"],
|
||||||
monthNames: ["January","February","March","April","May","June","July","August","September","October","November","December"],
|
monthNames: ["January","February","March","April","May","June","July","August","September","October","November","December"],
|
||||||
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun","Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||||
|
chooseYear: 'Choose Year',
|
||||||
|
chooseMonth: 'Choose Month',
|
||||||
|
chooseDate: 'Choose Date',
|
||||||
|
prevDecade: 'Previous Decade',
|
||||||
|
nextDecade: 'Next Decade',
|
||||||
|
prevYear: 'Previous Year',
|
||||||
|
nextYear: 'Next Year',
|
||||||
|
prevMonth: 'Previous Month',
|
||||||
|
nextMonth: 'Next Month',
|
||||||
|
prevHour: 'Previous Hour',
|
||||||
|
nextHour: 'Next Hour',
|
||||||
|
prevMinute: 'Previous Minute',
|
||||||
|
nextMinute: 'Next Minute',
|
||||||
|
prevSecond: 'Previous Second',
|
||||||
|
nextSecond: 'Next Second',
|
||||||
|
am: 'am',
|
||||||
|
pm: 'pm',
|
||||||
today: 'Today',
|
today: 'Today',
|
||||||
weekHeader: 'Wk',
|
weekHeader: 'Wk',
|
||||||
firstDayOfWeek: 0,
|
firstDayOfWeek: 0,
|
||||||
|
|
|
@ -628,6 +628,191 @@ export default {
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h5>Accessibility</h5>
|
||||||
|
<DevelopmentSection>
|
||||||
|
<h6>Screen Reader</h6>
|
||||||
|
<p>Value to describe the component can either be provided via <i>label</i> tag combined with <i>inputId</i> prop or using <i>aria-labelledby</i>, <i>aria-label</i> props. The input element has <i>combobox</i> role
|
||||||
|
in addition to <i>aria-autocomplete</i> as "none", <i>aria-haspopup</i> as "dialog" and <i>aria-expanded</i> attributes. The relation between the input and the popup is created with <i>aria-controls</i> attribute that refers to the id of the popup.</p>
|
||||||
|
<p>The optional calendar button requires includes <i>aria-haspopup</i>, <i>aria-expanded</i> for states along with <i>aria-controls</i> to define the relation between the popup and the button. The value to read is retrieved from the <i>chooseDate</i>
|
||||||
|
key of the aria property from the <router-link to="/locale">locale</router-link> API. This label is also used for the <i>aria-label</i> of the popup as well. When there is a value selected, it is formatted and appended to the label to be able to notify users
|
||||||
|
about the current value.</p>
|
||||||
|
|
||||||
|
<p>Popup has a <i>dialog</i> role along with <i>aria-modal</i> and <i>aria-label</i>. The navigation buttons at the header has an <i>aria-label</i> retrieved from the <i>prevYear</i>, <i>nextYear</i>, <i>prevMonth</i>, <i>nextMonth</i>,
|
||||||
|
<i>prevDecade</i> and <i>nextDecade</i> keys of the locale aria API. Similarly month picker button uses the <i>chooseMonth</i> and year picker button uses the <i>chooseYear</i> keys.</p>
|
||||||
|
|
||||||
|
<p>Main date table uses <i>grid</i> role that contains th elements with <i>col</i> as the scope along with <i>abbr</i> tag resolving to the full name of the month. Each date cell has an <i>aria-label</i> referring to the full date value.
|
||||||
|
Buttons at the footer utilize their readable labels as <i>aria-label</i> as well. Selected date also receives the <i>aria-selected</i> attribute.</p>
|
||||||
|
|
||||||
|
<p>Timepicker spinner buttons get their labels for <i>aria-label</i> from the aria locale API using the <i>prevHour</i>, <i>nextHour</i>, <i>prevMinute</i>, <i>nextMinute</i>, <i>prevSecond</i>, <i>nextSecond</i>, <i>am</i> and <i>pm</i> keys.</p>
|
||||||
|
|
||||||
|
<p>Calendar also includes a hidden section that is only available to screen readers with <i>aria-live</i> as "polite". This element is updated when the selected date changes to instruct the user about the current date selected.</p>
|
||||||
|
|
||||||
|
<pre v-code><code>
|
||||||
|
<label for="date1">Date</label>
|
||||||
|
<Calendar inputId="date1" />
|
||||||
|
|
||||||
|
<span id="date2">Date</span>
|
||||||
|
<Calendar aria-labelledby="date2" />
|
||||||
|
|
||||||
|
<Calendar aria-label="Date" />
|
||||||
|
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
<h6>Choose Date Button Keyboard Support</h6>
|
||||||
|
<div class="doc-tablewrapper">
|
||||||
|
<table class="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><i>space</i></td>
|
||||||
|
<td>Opens popup and moves focus to the selected date, if there is none focuses on today.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>enter</i></td>
|
||||||
|
<td>Opens popup and moves focus to the selected date, if there is none focuses on today.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h6>Popup Keyboard Support</h6>
|
||||||
|
<div class="doc-tablewrapper">
|
||||||
|
<table class="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><i>escape</i></td>
|
||||||
|
<td>Closes the popup and moves focus to the input element.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>tab</i></td>
|
||||||
|
<td>Moves focus to the next focusable element within the popup.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>shift</i> + <i>tab</i></td>
|
||||||
|
<td>Moves focus to the next focusable element within the popup.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h6>Header Buttons Keyboard Support</h6>
|
||||||
|
<div class="doc-tablewrapper">
|
||||||
|
<table class="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><i>enter</i></td>
|
||||||
|
<td>Triggers the button action.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>space</i></td>
|
||||||
|
<td>Triggers the button action.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h6>Date Grid Keyboard Support</h6>
|
||||||
|
<div class="doc-tablewrapper">
|
||||||
|
<table class="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><i>enter</i></td>
|
||||||
|
<td>Selects the date, closes the popup and moves focus to the input element.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>space</i></td>
|
||||||
|
<td>Selects the date, closes the popup and moves focus to the input element.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>up arrow</i></td>
|
||||||
|
<td>Moves focus to the same day of the previous week.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>down arrow</i></td>
|
||||||
|
<td>Moves focus to the same day of the next week.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>right arrow</i></td>
|
||||||
|
<td>Moves focus to the next day.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>left arrow</i></td>
|
||||||
|
<td>Moves focus to the previous day.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>home</i></td>
|
||||||
|
<td>Moves focus to the first day of the current week.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>end</i></td>
|
||||||
|
<td>Moves focus to the last day of the current week.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>page up</i></td>
|
||||||
|
<td>Changes the date to previous month in date picker mode. Moves to previous year in month picker mode and previous decade in year picker.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>shift</i> + <i>page up</i></td>
|
||||||
|
<td>Changes the date to previous year in date picker mode. Has no effect in month or year picker</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>page down</i></td>
|
||||||
|
<td>Changes the date to next month in date picker mode. Moves to next year in month picker mode and next decade in year picker.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>shift</i> + <i>page down</i></td>
|
||||||
|
<td>Changes the date to next year in date picker mode. Has no effect in month or year picker</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h6>Footer Buttons Keyboard Support</h6>
|
||||||
|
<div class="doc-tablewrapper">
|
||||||
|
<table class="doc-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Function</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><i>enter</i></td>
|
||||||
|
<td>Triggers the button action.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><i>space</i></td>
|
||||||
|
<td>Triggers the button action.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</DevelopmentSection>
|
||||||
|
|
||||||
<h5>Dependencies</h5>
|
<h5>Dependencies</h5>
|
||||||
<p>None.</p>
|
<p>None.</p>
|
||||||
</AppDoc>
|
</AppDoc>
|
||||||
|
|
Loading…
Reference in New Issue