This commit is contained in:
Liam DeBeasi
2024-04-19 09:46:44 -04:00
parent 6b13e1323f
commit 674bfeb0c8
2 changed files with 41 additions and 173 deletions

View File

@ -847,6 +847,23 @@ export class Datetime implements ComponentInterface {
this.maxParts = parseMaxParts(max, defaultParts);
};
private centerCalendarGrid = (workingMonth: HTMLElement) => {
const { el, calendarBodyRef } = this;
if (!calendarBodyRef) return;
const monthRight = workingMonth.offsetLeft + workingMonth.offsetWidth;
const elRight = el.offsetLeft + el.offsetWidth;
if (monthRight > elRight) {
calendarBodyRef.scrollLeft = workingMonth.clientWidth;
console.log('LTR', workingMonth)
} else {
calendarBodyRef.scrollLeft = -workingMonth.clientWidth;
console.log('RTL', workingMonth)
}
}
private initializeCalendarListener = () => {
const calendarBodyRef = this.calendarBodyRef;
if (!calendarBodyRef) {
@ -868,11 +885,11 @@ export class Datetime implements ComponentInterface {
* the months in a row allows us to mostly sidestep
* that issue.
*/
const months = calendarBodyRef.querySelectorAll('.calendar-month');
const months = calendarBodyRef.querySelectorAll<HTMLElement>('.calendar-month');
const startMonth = months[0] as HTMLElement;
const workingMonth = months[1] as HTMLElement;
const endMonth = months[2] as HTMLElement;
const startMonth = months[0];
const workingMonth = months[1];
const endMonth = months[2];
const mode = getIonMode(this);
const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
@ -883,7 +900,7 @@ export class Datetime implements ComponentInterface {
* if element is not in viewport. Use scrollLeft instead.
*/
writeTask(() => {
calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
this.centerCalendarGrid(workingMonth);
const getChangedMonth = (parts: DatetimeParts): DatetimeParts | undefined => {
const box = calendarBodyRef.getBoundingClientRect();
@ -953,6 +970,7 @@ export class Datetime implements ComponentInterface {
* then we can return early.
*/
const newDate = getChangedMonth(this.workingParts);
console.log(newDate,this.workingParts)
if (!newDate) return;
const { month, day, year } = newDate;
@ -993,7 +1011,7 @@ export class Datetime implements ComponentInterface {
year,
});
calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
this.centerCalendarGrid(workingMonth);
calendarBodyRef.style.removeProperty('overflow');
if (this.resolveForceDateScrolling) {
@ -1185,7 +1203,7 @@ export class Datetime implements ComponentInterface {
*/
const hasCalendarGrid = !preferWheel && ['date-time', 'time-date', 'date'].includes(presentation);
if (minParts !== undefined && hasCalendarGrid && calendarBodyRef) {
const workingMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(1)');
const workingMonth = calendarBodyRef.querySelector<HTMLElement>('.calendar-month:nth-of-type(1)');
/**
* We need to make sure the datetime is not in the process
* of scrolling to a new datetime value if the value
@ -1200,7 +1218,7 @@ export class Datetime implements ComponentInterface {
* and the resolveForceDateScrolling promise never resolves.
*/
if (workingMonth && forceRenderDate === undefined) {
calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL(this.el) ? -1 : 1);
this.centerCalendarGrid(workingMonth);
}
}
@ -1464,16 +1482,24 @@ export class Datetime implements ComponentInterface {
return;
}
const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
const nextMonth = calendarBodyRef.querySelector<HTMLElement>('.calendar-month:last-of-type');
if (!nextMonth) {
return;
}
const left = (nextMonth as HTMLElement).offsetWidth * 2;
const left = nextMonth.offsetWidth * 2;
if (!calendarBodyRef) return;
console.log('yay',left)
const monthRight = nextMonth.offsetLeft + nextMonth.offsetWidth;
const elRight = this.el.offsetLeft + this.el.offsetWidth;
const direction = monthRight > elRight ? 1 : -1;
calendarBodyRef.scrollTo({
top: 0,
left: left * (isRTL(this.el) ? -1 : 1),
left: left * direction,
behavior: 'smooth',
});
};

View File

@ -99,170 +99,12 @@
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div class="grid">
<div class="grid-item">
<h2>Inline</h2>
<ion-datetime value="2020-03-14T14:23:00.000Z" id="inline-datetime"></ion-datetime>
</div>
<div class="grid-item">
<h2>Inline - No Default Value</h2>
<ion-datetime id="inline-datetime-no-value"></ion-datetime>
</div>
<div class="grid-item">
<h2>Popover</h2>
<ion-button onclick="presentPopover(defaultPopover, event)">Present Popover</ion-button>
<ion-popover class="datetime-popover" id="default-popover">
<ion-datetime></ion-datetime>
</ion-popover>
</div>
<div class="grid-item">
<h2>Modal</h2>
<ion-button onclick="presentModal()">Present Modal</ion-button>
</div>
<div class="grid-item">
<h2>Inline - Custom</h2>
<ion-datetime show-default-buttons="true" color="danger" id="custom-datetime" show-clear-button="true">
<span slot="title">Select Date</span>
</ion-datetime>
</div>
<div class="grid-item">
<h2>Popover - Custom</h2>
<ion-button id="open-popover">Present Popover</ion-button>
<ion-popover class="datetime-popover" trigger="open-popover" id="custom-popover">
<ion-datetime>
<span slot="title">My Custom Title</span>
<ion-buttons slot="buttons">
<ion-button color="danger">Destroy</ion-button>
<ion-button color="primary">Confirm</ion-button>
</ion-buttons>
</ion-datetime>
</ion-popover>
</div>
<div class="grid-item">
<h2>Modal - Custom</h2>
<ion-button id="open-modal">Present Modal</ion-button>
<ion-modal trigger="open-modal" id="modal">
<ion-datetime>
<span slot="title">My Custom Title</span>
<ion-buttons slot="buttons">
<ion-button color="danger">Destroy</ion-button>
<ion-button color="primary">Confirm</ion-button>
</ion-buttons>
</ion-datetime>
</ion-modal>
</div>
<div class="grid-item">
<h2>formatOptions</h2>
<ion-datetime value="2020-03-14T14:23:00.000Z" id="format-options-datetime">
<span slot="title">Select Date</span>
</ion-datetime>
</div>
<ion-datetime dir="rtl"></ion-datetime>
<div dir="rtl">
<ion-datetime></ion-datetime>
</div>
</ion-content>
<script>
const datetimes = document.querySelectorAll('ion-datetime');
const color = document.querySelector('#color');
const locale = document.querySelector('#locale');
const datetime = document.querySelector('ion-datetime');
const buttons = document.querySelectorAll('ion-button');
const titleToggle = document.querySelector('#titleToggle');
const buttonsToggle = document.querySelector('#buttonsToggle');
locale.addEventListener('ionBlur', (ev) => {
const value = ev.target.value;
datetimes.forEach((datetime) => {
datetime.locale = !!value ? value : 'default';
});
});
const darkModeCheckbox = document.querySelector('ion-checkbox');
darkModeCheckbox.addEventListener('ionChange', (ev) => {
document.documentElement.classList.toggle('ion-palette-dark');
});
color.addEventListener('ionChange', (ev) => {
datetime.color = ev.target.value;
buttons.forEach((button) => {
button.color = ev.target.value;
});
});
titleToggle.addEventListener('ionChange', (ev) => {
datetimes.forEach((datetime) => {
datetime.showDefaultTitle = ev.detail.checked;
});
});
buttonsToggle.addEventListener('ionChange', (ev) => {
datetimes.forEach((datetime) => {
datetime.showDefaultButtons = ev.detail.checked;
});
});
datetimes.forEach((datetime) => {
datetime.addEventListener('ionFocus', () => {
console.log('Listen ionFocus: fired');
});
datetime.addEventListener('ionBlur', () => {
console.log('Listen ionBlur: fired');
});
});
const defaultPopover = document.querySelector('ion-popover#default-popover');
const customPopover = document.querySelector('ion-popover#custom-popover');
const presentPopover = (popover, ev) => {
popover.event = ev;
popover.showBackdrop = false;
popover.isOpen = true;
const dismiss = () => {
popover.isOpen = false;
popover.event = undefined;
popover.removeEventListener('didDismiss', dismiss);
};
popover.addEventListener('didDismiss', dismiss);
};
const presentModal = async () => {
const modal = await createModal();
await modal.present();
};
const createModal = () => {
// create component to open
const element = document.createElement('div');
element.innerHTML = `
<ion-datetime show-default-buttons="true" color="danger">
<span slot="title">Select Date</span>
</ion-datetime>
`;
// present the modal
const modalElement = Object.assign(document.createElement('ion-modal'), {
component: element,
});
const app = document.querySelector('ion-app');
app.appendChild(modalElement);
return modalElement;
};
const formatOptions = document.querySelector('#format-options-datetime');
formatOptions.formatOptions = {
time: { hour: '2-digit', minute: '2-digit' },
date: { day: '2-digit', month: 'long', era: 'short' },
};
</script>
</ion-app>
</body>
</html>