| @@ -217,8 +230,15 @@ |
-
{{ m.value }}
-
+
-
{{ y.value }}
-
+
@@ -621,25 +639,25 @@ export default {
queryMatches: false,
queryOrientation: null,
focusedDateIndex: 0,
- rawValue: null
+ rawValue: null,
+ suppressFocusOpen: false
};
},
watch: {
modelValue: {
immediate: true,
handler(newValue) {
- this.updateCurrentMetaData();
this.rawValue = typeof newValue === 'string' ? this.parseValue(newValue) : newValue;
+ this.updateCurrentMetaData();
+
if (!this.typeUpdate && !this.inline && this.input) {
this.input.value = this.formatValue(this.rawValue);
}
this.typeUpdate = false;
- if (this.$refs.clearIcon?.$el?.style) {
- this.$refs.clearIcon.$el.style.display = isEmpty(newValue) ? 'none' : 'block';
- }
+ this.updateClearIconVisibility(!isEmpty(newValue));
}
},
showTime() {
@@ -693,9 +711,7 @@ export default {
} else {
this.input.value = this.inputFieldValue;
- if (this.$refs.clearIcon?.$el?.style) {
- this.$refs.clearIcon.$el.style.display = !this.$filled ? 'none' : 'block';
- }
+ this.updateClearIconVisibility(this.$filled);
}
},
updated() {
@@ -1222,7 +1238,7 @@ export default {
return;
}
- find(this.overlay, 'table td span:not([data-p-disabled="true"])').forEach((cell) => (cell.tabIndex = -1));
+ find(this.overlay, 'table td[role="gridcell"]:not([data-p-disabled="true"])').forEach((cell) => (cell.tabIndex = -1));
if (event) {
event.currentTarget.focus();
@@ -1245,12 +1261,14 @@ export default {
}
if (this.isSingleSelection() && (!this.showTime || this.hideOnDateTimeSelect)) {
- if (this.input) {
- this.input.focus();
- }
-
setTimeout(() => {
this.overlayVisible = false;
+
+ // Return keyboard focus to the trigger input after panel closes.
+ if (this.input) {
+ this.suppressFocusOpen = true;
+ setTimeout(() => this.input?.focus(), 0);
+ }
}, 150);
}
},
@@ -2186,14 +2204,13 @@ export default {
},
onDateCellKeydown(event, date, groupIndex) {
event.preventDefault();
- const cellContent = event.currentTarget;
- const cell = cellContent.parentElement;
+ const cell = event.currentTarget;
const cellIndex = getIndex(cell);
switch (event.code) {
case 'ArrowDown': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
let nextRow = cell.parentElement.nextElementSibling;
@@ -2203,13 +2220,13 @@ export default {
const nextTableRows = tableRows.slice(tableRowIndex + 1);
let hasNextFocusableDate = nextTableRows.find((el) => {
- let focusCell = el.children[cellIndex].children[0];
+ let focusCell = el.children[cellIndex];
return !getAttribute(focusCell, 'data-p-disabled');
});
if (hasNextFocusableDate) {
- let focusCell = hasNextFocusableDate.children[cellIndex].children[0];
+ let focusCell = hasNextFocusableDate.children[cellIndex];
focusCell.tabIndex = '0';
focusCell.focus();
@@ -2227,7 +2244,7 @@ export default {
}
case 'ArrowUp': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
if (event.altKey) {
this.overlayVisible = false;
@@ -2241,13 +2258,13 @@ export default {
const prevTableRows = tableRows.slice(0, tableRowIndex).reverse();
let hasNextFocusableDate = prevTableRows.find((el) => {
- let focusCell = el.children[cellIndex].children[0];
+ let focusCell = el.children[cellIndex];
return !getAttribute(focusCell, 'data-p-disabled');
});
if (hasNextFocusableDate) {
- let focusCell = hasNextFocusableDate.children[cellIndex].children[0];
+ let focusCell = hasNextFocusableDate.children[cellIndex];
focusCell.tabIndex = '0';
focusCell.focus();
@@ -2266,7 +2283,7 @@ export default {
}
case 'ArrowLeft': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
let prevCell = cell.previousElementSibling;
if (prevCell) {
@@ -2274,13 +2291,13 @@ export default {
const prevCells = cells.slice(0, cellIndex).reverse();
let hasNextFocusableDate = prevCells.find((el) => {
- let focusCell = el.children[0];
+ let focusCell = el;
return !getAttribute(focusCell, 'data-p-disabled');
});
if (hasNextFocusableDate) {
- let focusCell = hasNextFocusableDate.children[0];
+ let focusCell = hasNextFocusableDate;
focusCell.tabIndex = '0';
focusCell.focus();
@@ -2296,20 +2313,20 @@ export default {
}
case 'ArrowRight': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
let nextCell = cell.nextElementSibling;
if (nextCell) {
const cells = Array.from(cell.parentElement.children);
const nextCells = cells.slice(cellIndex + 1);
let hasNextFocusableDate = nextCells.find((el) => {
- let focusCell = el.children[0];
+ let focusCell = el;
return !getAttribute(focusCell, 'data-p-disabled');
});
if (hasNextFocusableDate) {
- let focusCell = hasNextFocusableDate.children[0];
+ let focusCell = hasNextFocusableDate;
focusCell.tabIndex = '0';
focusCell.focus();
@@ -2348,9 +2365,9 @@ export default {
}
case 'Home': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
let currentRow = cell.parentElement;
- let focusCell = currentRow.children[0].children[0];
+ let focusCell = currentRow.children[0];
if (getAttribute(focusCell, 'data-p-disabled')) {
this.navigateToMonth(event, true, groupIndex);
@@ -2364,9 +2381,9 @@ export default {
}
case 'End': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
let currentRow = cell.parentElement;
- let focusCell = currentRow.children[currentRow.children.length - 1].children[0];
+ let focusCell = currentRow.children[currentRow.children.length - 1];
if (getAttribute(focusCell, 'data-p-disabled')) {
this.navigateToMonth(event, false, groupIndex);
@@ -2380,7 +2397,7 @@ export default {
}
case 'PageUp': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
if (event.shiftKey) {
this.navigationState = { backward: true };
this.navBackward(event);
@@ -2391,7 +2408,7 @@ export default {
}
case 'PageDown': {
- cellContent.tabIndex = '-1';
+ cell.tabIndex = '-1';
if (event.shiftKey) {
this.navigationState = { backward: false };
this.navForward(event);
@@ -2413,7 +2430,7 @@ export default {
this.navBackward(event);
} else {
let prevMonthContainer = this.overlay.children[groupIndex - 1];
- let cells = find(prevMonthContainer, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
+ let cells = find(prevMonthContainer, 'table td[role="gridcell"]:not([data-p-disabled="true"])');
let focusCell = cells[cells.length - 1];
focusCell.tabIndex = '0';
@@ -2425,7 +2442,7 @@ export default {
this.navForward(event);
} else {
let nextMonthContainer = this.overlay.children[groupIndex + 1];
- let focusCell = findSingle(nextMonthContainer, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
+ let focusCell = findSingle(nextMonthContainer, 'table td[role="gridcell"]:not([data-p-disabled="true"])');
focusCell.tabIndex = '0';
focusCell.focus();
@@ -2641,7 +2658,7 @@ export default {
} else if (this.currentView === 'year') {
cells = find(this.overlay, '[data-pc-section="yearview"] [data-pc-section="year"]:not([data-p-disabled="true"])');
} else {
- cells = find(this.overlay, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
+ cells = find(this.overlay, 'table td[role="gridcell"]:not([data-p-disabled="true"])');
}
if (cells && cells.length > 0) {
@@ -2653,7 +2670,7 @@ export default {
} else if (this.currentView === 'year') {
cell = findSingle(this.overlay, '[data-pc-section="yearview"] [data-pc-section="year"]:not([data-p-disabled="true"])');
} else {
- cell = findSingle(this.overlay, 'table td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
+ cell = findSingle(this.overlay, 'table td[role="gridcell"]:not([data-p-disabled="true"])');
}
}
@@ -2684,19 +2701,21 @@ export default {
cells.forEach((cell) => (cell.tabIndex = -1));
cell = selectedCell || cells[0];
} else {
- cell = findSingle(this.overlay, 'span[data-p-selected="true"]');
+ let cells = find(this.overlay, 'table td[role="gridcell"]');
+
+ cells.forEach((gridCell) => (gridCell.tabIndex = -1));
+ cell = findSingle(this.overlay, 'td[role="gridcell"][data-p-selected="true"]');
if (!cell) {
- let todayCell = findSingle(this.overlay, 'td[data-p-today="true"] span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
+ let todayCell = findSingle(this.overlay, 'td[role="gridcell"][data-p-today="true"]:not([data-p-disabled="true"])');
if (todayCell) cell = todayCell;
- else cell = findSingle(this.overlay, '.p-datepicker-calendar td span:not([data-p-disabled="true"]):not([data-p-ink="true"])');
+ else cell = findSingle(this.overlay, 'table td[role="gridcell"]:not([data-p-disabled="true"])');
}
}
if (cell) {
cell.tabIndex = '0';
-
this.preventFocus = false;
}
},
@@ -2718,12 +2737,16 @@ export default {
if (this.timeOnly) {
focusableElements[0].focus();
} else {
- let elementIndex = focusableElements.findIndex((el) => el.tagName === 'SPAN');
+ let elementIndex = focusableElements.findIndex((el) => el.tagName === 'TD');
if (elementIndex === -1) {
elementIndex = focusableElements.findIndex((el) => el.tagName === 'BUTTON');
}
+ if (elementIndex === -1) {
+ elementIndex = focusableElements.findIndex((el) => el.tagName === 'SPAN');
+ }
+
if (elementIndex !== -1) {
focusableElements[elementIndex].focus();
} else {
@@ -2757,14 +2780,22 @@ export default {
this.$emit('keydown', event);
},
+ getClearIconElement() {
+ return this.$refs.clearIcon?.$el || this.$refs.clearIcon;
+ },
+ updateClearIconVisibility(visible) {
+ const clearIconEl = this.getClearIconElement();
+
+ if (clearIconEl?.style) {
+ clearIconEl.style.display = visible ? 'block' : 'none';
+ }
+ },
onInput(event) {
try {
this.selectionStart = this.input.selectionStart;
this.selectionEnd = this.input.selectionEnd;
- if (this.$refs.clearIcon?.$el?.style) {
- this.$refs.clearIcon.$el.style.display = isEmpty(event.target.value) ? 'none' : 'block';
- }
+ this.updateClearIconVisibility(!isEmpty(event.target.value));
let value = this.parseValue(event.target.value);
@@ -2785,7 +2816,9 @@ export default {
}
},
onFocus(event) {
- if (this.showOnFocus && this.isEnabled()) {
+ if (this.suppressFocusOpen) {
+ this.suppressFocusOpen = false;
+ } else if (this.showOnFocus && this.isEnabled()) {
this.overlayVisible = true;
}
@@ -2799,9 +2832,7 @@ export default {
this.focused = false;
event.target.value = this.formatValue(this.rawValue);
- if (this.$refs.clearIcon?.$el?.style) {
- this.$refs.clearIcon.$el.style.display = isEmpty(event.target.value) ? 'none' : 'block';
- }
+ this.updateClearIconVisibility(!isEmpty(event.target.value));
},
onKeyDown(event) {
if (event.code === 'ArrowDown' && this.overlay) {
@@ -2823,18 +2854,25 @@ export default {
this.overlayVisible = false;
}
} else if (event.code === 'Enter') {
+ let handled = false;
+
if (this.manualInput && event.target.value !== null && event.target.value?.trim() !== '') {
try {
let value = this.parseValue(event.target.value);
if (this.isValidSelection(value)) {
this.overlayVisible = false;
+ handled = true;
}
} catch (err) {
/* NoOp */
}
}
+ if (handled) {
+ event.preventDefault();
+ }
+
this.$emit('keydown', event);
}
},
@@ -2853,12 +2891,33 @@ export default {
getMonthName(index) {
return this.$primevue.config.locale.monthNames[index];
},
+ getCalendarAriaLabel(month) {
+ return `${this.getMonthName(month.month)} ${month.year} calendar`;
+ },
+ getDateAriaLabel(dateMeta) {
+ const date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
+ const dayName = this.$primevue.config.locale.dayNames[date.getDay()];
+ const monthName = this.$primevue.config.locale.monthNames[dateMeta.month];
+
+ return `${dayName}, ${monthName} ${dateMeta.day}, ${dateMeta.year}`;
+ },
+ getMonthButtonAriaLabel(month) {
+ return `${this.$primevue.config.locale.chooseMonth}: ${this.getMonthName(month.month)} ${month.year}`;
+ },
+ getYearButtonAriaLabel(month) {
+ return `${this.$primevue.config.locale.chooseYear}: ${this.getYear(month)}`;
+ },
getYear(month) {
return this.currentView === 'month' ? this.currentYear : month.year;
},
onClearClick() {
this.updateModel(null);
this.overlayVisible = false;
+
+ if (this.input) {
+ this.suppressFocusOpen = true;
+ setTimeout(() => this.input?.focus(), 0);
+ }
},
onOverlayClick(event) {
event.stopPropagation();
@@ -2957,14 +3016,18 @@ export default {
propValue = propValue[0];
} else {
const start = this.parseValueForComparison(propValue[0]);
- let lastVisibleMonth = new Date(start.getFullYear(), start.getMonth() + this.numberOfMonths, 1);
+ const end = this.parseValueForComparison(propValue[1]);
- if (propValue[1] < lastVisibleMonth) {
- propValue = propValue[0];
+ if (this.showTime) {
+ propValue = end;
} else {
- const end = this.parseValueForComparison(propValue[1]);
+ let lastVisibleMonth = new Date(start.getFullYear(), start.getMonth() + this.numberOfMonths, 1);
- propValue = new Date(end.getFullYear(), end.getMonth() - this.numberOfMonths + 1, 1);
+ if (propValue[1] < lastVisibleMonth) {
+ propValue = propValue[0];
+ } else {
+ propValue = new Date(end.getFullYear(), end.getMonth() - this.numberOfMonths + 1, 1);
+ }
}
}
} else if (this.isMultipleSelection()) {
diff --git a/packages/primevue/src/datepicker/style/DatePickerStyle.js b/packages/primevue/src/datepicker/style/DatePickerStyle.js
index ae5249a0d8..dba076ddb8 100644
--- a/packages/primevue/src/datepicker/style/DatePickerStyle.js
+++ b/packages/primevue/src/datepicker/style/DatePickerStyle.js
@@ -5,6 +5,21 @@ const inlineStyles = {
root: ({ props }) => ({ position: props.appendTo === 'self' || props.showClear ? 'relative' : undefined })
};
+const css = () => `
+.p-datepicker-day-cell:focus,
+.p-datepicker-day-cell:focus-visible {
+ outline: none;
+}
+
+.p-datepicker-day-cell:focus-visible .p-datepicker-day {
+ outline-width: var(--p-datepicker-date-focus-ring-width);
+ outline-style: var(--p-datepicker-date-focus-ring-style);
+ outline-color: var(--p-datepicker-date-focus-ring-color);
+ outline-offset: var(--p-datepicker-date-focus-ring-offset);
+ box-shadow: var(--p-datepicker-date-focus-ring-shadow);
+}
+`;
+
const classes = {
root: ({ instance, state }) => [
'p-datepicker p-component p-inputwrapper',
@@ -101,6 +116,7 @@ const classes = {
export default BaseStyle.extend({
name: 'datepicker',
+ css,
style,
classes,
inlineStyles
|
|---|