feat(datepicker): ability to show time via showTime property (#9570)

This commit is contained in:
Nathan Walker
2022-03-04 19:32:47 -08:00
committed by GitHub
parent c68d002c9a
commit ab4e47a1c1
11 changed files with 189 additions and 24 deletions

View File

@ -1,5 +1,6 @@
import { DatePicker as DatePickerDefinition } from '.';
import { View, CSSType } from '../core/view';
import { booleanConverter } from '../core/view-base';
import { Property } from '../core/properties';
const defaultDate = new Date();
@ -10,10 +11,14 @@ export class DatePickerBase extends View implements DatePickerDefinition {
public year: number;
public month: number;
public day: number;
public hour: number;
public minute: number;
public second: number;
public maxDate: Date;
public minDate: Date;
public date: Date;
public iosPreferredDatePickerStyle: number;
public showTime: boolean;
}
DatePickerBase.prototype.recycleNativeView = 'auto';
@ -39,6 +44,27 @@ export const dayProperty = new Property<DatePickerBase, number>({
});
dayProperty.register(DatePickerBase);
export const hourProperty = new Property<DatePickerBase, number>({
name: 'hour',
defaultValue: defaultDate.getHours(),
valueConverter: (v) => parseInt(v),
});
hourProperty.register(DatePickerBase);
export const minuteProperty = new Property<DatePickerBase, number>({
name: 'minute',
defaultValue: defaultDate.getMinutes(),
valueConverter: (v) => parseInt(v),
});
minuteProperty.register(DatePickerBase);
export const secondProperty = new Property<DatePickerBase, number>({
name: 'second',
defaultValue: defaultDate.getSeconds(),
valueConverter: (v) => parseInt(v),
});
secondProperty.register(DatePickerBase);
// TODO: Make CoercibleProperties
export const maxDateProperty = new Property<DatePickerBase, Date>({
name: 'maxDate',
@ -62,6 +88,13 @@ export const dateProperty = new Property<DatePickerBase, Date>({
});
dateProperty.register(DatePickerBase);
export const showTimeProperty = new Property<DatePickerBase, boolean>({
name: 'showTime',
defaultValue: false,
valueConverter: (v) => booleanConverter(v),
});
showTimeProperty.register(DatePickerBase);
export const iosPreferredDatePickerStyleProperty = new Property<DatePickerBase, number>({
name: 'iosPreferredDatePickerStyle',
defaultValue: 0,

View File

@ -1,4 +1,6 @@
import { DatePickerBase, yearProperty, monthProperty, dayProperty, dateProperty, maxDateProperty, minDateProperty } from './date-picker-common';
import { TimePicker } from '../time-picker';
import { StackLayout } from '../layouts/stack-layout';
export * from './date-picker-common';
@ -40,8 +42,15 @@ function initializeDateChangedListener(): void {
dateChanged = true;
}
if (dateChanged) {
dateProperty.nativeValueChange(owner, new Date(year, month, day));
if (dateChanged || (owner.showTime && owner.timePicker)) {
let newDate: Date;
if (owner.showTime && owner.timePicker) {
const dateTime = owner.timePicker.time;
newDate = new Date(year, month, day, dateTime.getHours(), dateTime.getMinutes(), dateTime.getSeconds(), dateTime.getMilliseconds());
} else {
newDate = new Date(year, month, day);
}
dateProperty.nativeValueChange(owner, newDate);
}
}
}
@ -51,6 +60,7 @@ function initializeDateChangedListener(): void {
export class DatePicker extends DatePickerBase {
nativeViewProtected: android.widget.DatePicker;
timePicker: TimePicker;
public createNativeView() {
const picker = new android.widget.DatePicker(this._context);
@ -66,9 +76,21 @@ export class DatePicker extends DatePickerBase {
const listener = new DateChangedListener(this);
nativeView.init(this.year, this.month - 1, this.day, listener);
(<any>nativeView).listener = listener;
if (this.showTime) {
this.timePicker = new TimePicker();
this.timePicker.width = this.width;
this.timePicker.height = this.height;
this.timePicker.on('timeChange', (args) => {
this.updateNativeDate();
});
(<StackLayout>this.parent).addChild(this.timePicker);
}
}
public disposeNativeView() {
if (this.timePicker) {
this.timePicker.disposeNativeView();
}
(<any>this.nativeViewProtected).listener.owner = null;
super.disposeNativeView();
}
@ -78,7 +100,12 @@ export class DatePicker extends DatePickerBase {
const year = typeof this.year === 'number' ? this.year : nativeView.getYear();
const month = typeof this.month === 'number' ? this.month - 1 : nativeView.getMonth();
const day = typeof this.day === 'number' ? this.day : nativeView.getDayOfMonth();
this.date = new Date(year, month, day);
if (this.showTime && this.timePicker) {
const time = this.timePicker.time || new Date();
this.date = new Date(year, month, day, time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds());
} else {
this.date = new Date(year, month, day);
}
}
[yearProperty.setNative](value: number) {

View File

@ -1,4 +1,4 @@
import { DatePickerBase, yearProperty, monthProperty, dayProperty, dateProperty, maxDateProperty, minDateProperty } from './date-picker-common';
import { DatePickerBase, yearProperty, monthProperty, dayProperty, dateProperty, maxDateProperty, minDateProperty, hourProperty, minuteProperty, secondProperty, showTimeProperty, iosPreferredDatePickerStyleProperty } from './date-picker-common';
import { colorProperty } from '../styling/style-properties';
import { Color } from '../../color';
import { Device } from '../../platform';
@ -14,7 +14,7 @@ export class DatePicker extends DatePickerBase {
public createNativeView() {
const picker = UIDatePicker.new();
picker.datePickerMode = UIDatePickerMode.Date;
picker.datePickerMode = this.showTime ? UIDatePickerMode.DateAndTime : UIDatePickerMode.Date;
if (SUPPORT_DATE_PICKER_STYLE) {
picker.preferredDatePickerStyle = this.iosPreferredDatePickerStyle;
}
@ -38,27 +38,61 @@ export class DatePicker extends DatePickerBase {
return this.nativeViewProtected;
}
[showTimeProperty.setNative](value: boolean) {
this.showTime = value;
if (this.nativeViewProtected) {
this.nativeViewProtected.datePickerMode = this.showTime ? UIDatePickerMode.DateAndTime : UIDatePickerMode.Date;
}
}
[iosPreferredDatePickerStyleProperty.setNative](value: number) {
this.iosPreferredDatePickerStyle = value;
if (this.nativeViewProtected) {
if (SUPPORT_DATE_PICKER_STYLE) {
this.nativeViewProtected.preferredDatePickerStyle = this.iosPreferredDatePickerStyle;
}
}
}
[yearProperty.setNative](value: number) {
this.date = new Date(value, this.month - 1, this.day);
this.date = new Date(value, this.month - 1, this.day, this.hour || 0, this.minute || 0, this.second || 0);
}
[monthProperty.setNative](value: number) {
this.date = new Date(this.year, value - 1, this.day);
this.date = new Date(this.year, value - 1, this.day, this.hour || 0, this.minute || 0, this.second || 0);
}
[dayProperty.setNative](value: number) {
this.date = new Date(this.year, this.month - 1, value);
this.date = new Date(this.year, this.month - 1, value, this.hour || 0, this.minute || 0, this.second || 0);
}
[hourProperty.setNative](value: number) {
this.date = new Date(this.year, this.month - 1, this.day, value, this.minute || 0, this.second || 0);
}
[minuteProperty.setNative](value: number) {
this.date = new Date(this.year, this.month - 1, this.day, this.hour || 0, value, this.second || 0);
}
[secondProperty.setNative](value: number) {
this.date = new Date(this.year, this.month - 1, this.day, this.hour || 0, this.minute || 0, value);
}
[dateProperty.setNative](value: Date) {
const picker = this.nativeViewProtected;
const comps = NSCalendar.currentCalendar.componentsFromDate(NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay, picker.date);
const comps = NSCalendar.currentCalendar.componentsFromDate(NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.HourCalendarUnit | NSCalendarUnit.MinuteCalendarUnit | NSCalendarUnit.SecondCalendarUnit, picker.date);
comps.year = value.getFullYear();
comps.month = value.getMonth() + 1;
comps.day = value.getDate();
comps.hour = value.getHours();
comps.minute = value.getMinutes();
comps.second = value.getSeconds();
this.year = comps.year;
this.month = comps.month;
this.day = comps.day;
this.hour = comps.hour;
this.minute = comps.minute;
this.second = comps.second;
picker.setDateAnimated(NSCalendar.currentCalendar.dateFromComponents(comps), false);
}
@ -103,13 +137,13 @@ class UIDatePickerChangeHandlerImpl extends NSObject {
}
public valueChanged(sender: UIDatePicker) {
const comps = NSCalendar.currentCalendar.componentsFromDate(NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay, sender.date);
const owner = this._owner.get();
if (!owner) {
return;
}
const comps = NSCalendar.currentCalendar.componentsFromDate(NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.HourCalendarUnit | NSCalendarUnit.MinuteCalendarUnit | NSCalendarUnit.SecondCalendarUnit, sender.date);
let dateChanged = false;
if (comps.year !== owner.year) {
yearProperty.nativeValueChange(owner, comps.year);
@ -126,8 +160,23 @@ class UIDatePickerChangeHandlerImpl extends NSObject {
dateChanged = true;
}
if (comps.hour !== owner.hour) {
hourProperty.nativeValueChange(owner, comps.hour);
dateChanged = true;
}
if (comps.minute !== owner.minute) {
minuteProperty.nativeValueChange(owner, comps.minute);
dateChanged = true;
}
if (comps.second !== owner.second) {
secondProperty.nativeValueChange(owner, comps.second);
dateChanged = true;
}
if (dateChanged) {
dateProperty.nativeValueChange(owner, new Date(comps.year, comps.month - 1, comps.day));
dateProperty.nativeValueChange(owner, new Date(comps.year, comps.month - 1, comps.day, comps.hour, comps.minute, comps.second));
}
}