mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
fix(datetime): update active calendar display when value changes (#24244)
This commit is contained in:
@ -93,6 +93,12 @@ export class Datetime implements ComponentInterface {
|
||||
private minParts?: any;
|
||||
private maxParts?: any;
|
||||
|
||||
/**
|
||||
* Duplicate reference to `activeParts` that does not trigger a re-render of the component.
|
||||
* Allows caching an instance of the `activeParts` in between render cycles.
|
||||
*/
|
||||
private activePartsClone!: DatetimeParts;
|
||||
|
||||
@State() showMonthAndYear = false;
|
||||
|
||||
@State() activeParts: DatetimeParts = {
|
||||
@ -291,6 +297,25 @@ export class Datetime implements ComponentInterface {
|
||||
*/
|
||||
@Watch('value')
|
||||
protected valueChanged() {
|
||||
if (this.hasValue()) {
|
||||
/**
|
||||
* Clones the value of the `activeParts` to the private clone, to update
|
||||
* the date display on the current render cycle without causing another render.
|
||||
*
|
||||
* This allows us to update the current value's date/time display without
|
||||
* refocusing or shifting the user's display (leaves the user in place).
|
||||
*/
|
||||
const { month, day, year, hour, minute } = parseDate(this.value);
|
||||
this.activePartsClone = {
|
||||
...this.activeParts,
|
||||
month,
|
||||
day,
|
||||
year,
|
||||
hour,
|
||||
minute
|
||||
}
|
||||
}
|
||||
|
||||
this.emitStyle();
|
||||
this.ionChange.emit({
|
||||
value: this.value
|
||||
@ -911,7 +936,8 @@ export class Datetime implements ComponentInterface {
|
||||
tzOffset,
|
||||
ampm: hour >= 12 ? 'pm' : 'am'
|
||||
}
|
||||
this.activeParts = {
|
||||
|
||||
this.activePartsClone = this.activeParts = {
|
||||
month,
|
||||
day,
|
||||
year,
|
||||
@ -951,6 +977,10 @@ export class Datetime implements ComponentInterface {
|
||||
this.ionBlur.emit();
|
||||
}
|
||||
|
||||
private hasValue = () => {
|
||||
return this.value != null && this.value !== '';
|
||||
}
|
||||
|
||||
private nextMonth = () => {
|
||||
const { calendarBodyRef } = this;
|
||||
if (!calendarBodyRef) { return; }
|
||||
@ -1135,7 +1165,7 @@ export class Datetime implements ComponentInterface {
|
||||
{getDaysOfMonth(month, year, this.firstDayOfWeek % 7).map((dateObject, index) => {
|
||||
const { day, dayOfWeek } = dateObject;
|
||||
const referenceParts = { month, day, year };
|
||||
const { isActive, isToday, ariaLabel, ariaSelected, disabled } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
|
||||
const { isActive, isToday, ariaLabel, ariaSelected, disabled } = getCalendarDayState(this.locale, referenceParts, this.activePartsClone, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
|
||||
|
||||
return (
|
||||
<button
|
||||
@ -1213,21 +1243,22 @@ export class Datetime implements ComponentInterface {
|
||||
ampmItems: PickerColumnItem[],
|
||||
use24Hour: boolean
|
||||
) {
|
||||
const { color, workingParts } = this;
|
||||
const { color, activePartsClone, workingParts } = this;
|
||||
|
||||
return (
|
||||
<ion-picker-internal>
|
||||
<ion-picker-column-internal
|
||||
color={color}
|
||||
value={workingParts.hour}
|
||||
value={activePartsClone.hour}
|
||||
items={hoursItems}
|
||||
numericInput
|
||||
onIonChange={(ev: CustomEvent) => {
|
||||
this.setWorkingParts({
|
||||
...this.workingParts,
|
||||
...workingParts,
|
||||
hour: ev.detail.value
|
||||
});
|
||||
this.setActiveParts({
|
||||
...this.activeParts,
|
||||
...activePartsClone,
|
||||
hour: ev.detail.value
|
||||
});
|
||||
|
||||
@ -1236,16 +1267,16 @@ export class Datetime implements ComponentInterface {
|
||||
></ion-picker-column-internal>
|
||||
<ion-picker-column-internal
|
||||
color={color}
|
||||
value={workingParts.minute}
|
||||
value={activePartsClone.minute}
|
||||
items={minutesItems}
|
||||
numericInput
|
||||
onIonChange={(ev: CustomEvent) => {
|
||||
this.setWorkingParts({
|
||||
...this.workingParts,
|
||||
...workingParts,
|
||||
minute: ev.detail.value
|
||||
});
|
||||
this.setActiveParts({
|
||||
...this.activeParts,
|
||||
...activePartsClone,
|
||||
minute: ev.detail.value
|
||||
});
|
||||
|
||||
@ -1254,19 +1285,19 @@ export class Datetime implements ComponentInterface {
|
||||
></ion-picker-column-internal>
|
||||
{ !use24Hour && <ion-picker-column-internal
|
||||
color={color}
|
||||
value={workingParts.ampm}
|
||||
value={activePartsClone.ampm}
|
||||
items={ampmItems}
|
||||
onIonChange={(ev: CustomEvent) => {
|
||||
const hour = calculateHourFromAMPM(this.workingParts, ev.detail.value);
|
||||
const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
|
||||
|
||||
this.setWorkingParts({
|
||||
...this.workingParts,
|
||||
...workingParts,
|
||||
ampm: ev.detail.value,
|
||||
hour
|
||||
});
|
||||
|
||||
this.setActiveParts({
|
||||
...this.workingParts,
|
||||
...activePartsClone,
|
||||
ampm: ev.detail.value,
|
||||
hour
|
||||
});
|
||||
@ -1309,7 +1340,7 @@ export class Datetime implements ComponentInterface {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{getFormattedTime(this.workingParts, use24Hour)}
|
||||
{getFormattedTime(this.activePartsClone, use24Hour)}
|
||||
</button>,
|
||||
<ion-popover
|
||||
alignment="center"
|
||||
|
||||
Reference in New Issue
Block a user