feat(datetime-button): add button for displaying datetime in overlays (#25655)

resolves #24316
This commit is contained in:
Liam DeBeasi
2022-07-27 09:47:02 -04:00
committed by GitHub
parent 52f0b22778
commit 499733105e
59 changed files with 1514 additions and 9 deletions

View File

@@ -21,3 +21,5 @@ export interface DatetimeParts {
ampm?: 'am' | 'pm';
tzOffset?: number;
}
export type DatetimePresentation = 'date-time' | 'time-date' | 'date' | 'time' | 'month' | 'year' | 'month-year';

View File

@@ -3,7 +3,14 @@ import { Component, Element, Event, Host, Method, Prop, State, Watch, h, writeTa
import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward } from 'ionicons/icons';
import { getIonMode } from '../../global/ionic-global';
import type { Color, DatetimeChangeEventDetail, DatetimeParts, Mode, StyleEventDetail } from '../../interface';
import type {
Color,
DatetimePresentation,
DatetimeChangeEventDetail,
DatetimeParts,
Mode,
StyleEventDetail,
} from '../../interface';
import { startFocusVisible } from '../../utils/focus-visible';
import { getElementRoot, raf, renderHiddenInput } from '../../utils/helpers';
import { printIonError, printIonWarning } from '../../utils/logging';
@@ -204,7 +211,7 @@ export class Datetime implements ComponentInterface {
* AM/PM. `'date-time'` will show the date picker first and time picker second.
* `'time-date'` will show the time picker first and date picker second.
*/
@Prop() presentation: 'date-time' | 'time-date' | 'date' | 'time' | 'month' | 'year' | 'month-year' = 'date-time';
@Prop() presentation: DatetimePresentation = 'date-time';
/**
* The text to display on the picker's cancel button.
@@ -469,6 +476,12 @@ export class Datetime implements ComponentInterface {
*/
@Event() ionStyle!: EventEmitter<StyleEventDetail>;
/**
* Emitted when componentDidRender is fired.
* @internal
*/
@Event() ionRender!: EventEmitter<void>;
/**
* Confirms the selected datetime value, updates the
* `value` property, and optionally closes the popover
@@ -1114,6 +1127,10 @@ export class Datetime implements ComponentInterface {
this.destroyInteractionListeners();
this.initializeListeners();
raf(() => {
this.ionRender.emit();
});
}
private processValue = (value?: string | string[] | null) => {
@@ -2130,8 +2147,9 @@ export class Datetime implements ComponentInterface {
presentation === 'year' || presentation === 'month' || presentation === 'month-year';
const shouldShowMonthAndYear = showMonthAndYear || isMonthAndYearPresentation;
const monthYearPickerOpen = showMonthAndYear && !isMonthAndYearPresentation;
const hasWheelVariant =
(presentation === 'date' || presentation === 'date-time' || presentation === 'time-date') && preferWheel;
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
const hasWheelVariant = hasDatePresentation && preferWheel;
const hasGrid = hasDatePresentation && !preferWheel;
renderHiddenInput(true, el, name, formatValue(value), disabled);
@@ -2151,6 +2169,7 @@ export class Datetime implements ComponentInterface {
[`datetime-presentation-${presentation}`]: true,
[`datetime-size-${size}`]: true,
[`datetime-prefer-wheel`]: hasWheelVariant,
[`datetime-grid`]: hasGrid,
}),
}}
>

View File

@@ -100,6 +100,32 @@ export const getMonthAndYear = (locale: string, refParts: DatetimeParts) => {
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
};
/**
* Given a locale and a date object,
* return a formatted string that includes
* the short month, numeric day, and full year.
* Example: Apr 22, 2021
*/
export const getMonthDayAndYear = (locale: string, refParts: DatetimeParts) => {
return getLocalizedDateTime(locale, refParts, { month: 'short', day: 'numeric', year: 'numeric' });
};
/**
* Wrapper function for Intl.DateTimeFormat.
* Allows developers to apply an allowed format to DatetimeParts.
* This function also has built in safeguards for older browser bugs
* with Intl.DateTimeFormat.
*/
export const getLocalizedDateTime = (
locale: string,
refParts: DatetimeParts,
options: Intl.DateTimeFormatOptions
): string => {
const timeString = !!refParts.hour && !!refParts.minute ? ` ${refParts.hour}:${refParts.minute}` : '';
const date = new Date(`${refParts.month}/${refParts.day}/${refParts.year}${timeString} GMT+0000`);
return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(date);
};
/**
* Gets a localized version of "Today"
* Falls back to "Today" in English for