mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
fix(datetime): ionChange event
This commit is contained in:
@ -27,7 +27,7 @@
|
|||||||
"ionicons": "4.3.0"
|
"ionicons": "4.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@stencil/core": "0.11.0",
|
"@stencil/core": "0.11.1",
|
||||||
"@stencil/dev-server": "latest",
|
"@stencil/dev-server": "latest",
|
||||||
"@stencil/sass": "0.1.0",
|
"@stencil/sass": "0.1.0",
|
||||||
"@stencil/utils": "latest",
|
"@stencil/utils": "latest",
|
||||||
|
8827
core/src/components.d.ts
vendored
8827
core/src/components.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@ -173,7 +173,7 @@ export function isLeapYear(year: number): boolean {
|
|||||||
const ISO_8601_REGEXP = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
|
const ISO_8601_REGEXP = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
|
||||||
const TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
|
const TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
|
||||||
|
|
||||||
export function parseDate(val: any): DatetimeData | null {
|
export function parseDate(val: string | undefined): DatetimeData | null {
|
||||||
// manually parse IS0 cuz Date.parse cannot be trusted
|
// manually parse IS0 cuz Date.parse cannot be trusted
|
||||||
// ISO 8601 format: 1994-12-15T13:47:20Z
|
// ISO 8601 format: 1994-12-15T13:47:20Z
|
||||||
let parse: any[] | null = null;
|
let parse: any[] | null = null;
|
||||||
@ -254,8 +254,9 @@ export function updateDate(existingData: DatetimeData, newData: any): boolean {
|
|||||||
|
|
||||||
// merge new values from the picker's selection
|
// merge new values from the picker's selection
|
||||||
// to the existing DatetimeData values
|
// to the existing DatetimeData values
|
||||||
Object.assign(existingData, newData);
|
for (const key of Object.keys(newData)) {
|
||||||
|
existingData[key] = newData[key].value;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,10 +163,7 @@ export class Datetime {
|
|||||||
* Any additional options that the picker interface can accept.
|
* Any additional options that the picker interface can accept.
|
||||||
* See the [Picker API docs](../../picker/Picker) for the picker options.
|
* See the [Picker API docs](../../picker/Picker) for the picker options.
|
||||||
*/
|
*/
|
||||||
@Prop() pickerOptions: PickerOptions = {
|
@Prop() pickerOptions?: PickerOptions;
|
||||||
buttons: [],
|
|
||||||
columns: []
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text to display when there's no date selected yet.
|
* The text to display when there's no date selected yet.
|
||||||
@ -186,6 +183,7 @@ export class Datetime {
|
|||||||
protected valueChanged() {
|
protected valueChanged() {
|
||||||
this.updateValue();
|
this.updateValue();
|
||||||
this.emitStyle();
|
this.emitStyle();
|
||||||
|
this.ionChange.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,6 +191,11 @@ export class Datetime {
|
|||||||
*/
|
*/
|
||||||
@Event() ionCancel!: EventEmitter<void>;
|
@Event() ionCancel!: EventEmitter<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the checked property has changed.
|
||||||
|
*/
|
||||||
|
@Event() ionChange!: EventEmitter<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when the styles change.
|
* Emitted when the styles change.
|
||||||
*/
|
*/
|
||||||
@ -232,7 +235,23 @@ export class Datetime {
|
|||||||
this.updateText();
|
this.updateText();
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildPicker(pickerOptions: PickerOptions) {
|
private async open() {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pickerOptions = this.generatePicketOptions();
|
||||||
|
this.picker = await this.pickerCtrl.create(pickerOptions);
|
||||||
|
this.validate();
|
||||||
|
await this.picker!.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
private generatePicketOptions(): PickerOptions {
|
||||||
|
const pickerOptions: PickerOptions = {
|
||||||
|
...this.pickerOptions,
|
||||||
|
columns: this.generateColumns()
|
||||||
|
};
|
||||||
|
|
||||||
// If the user has not passed in picker buttons,
|
// If the user has not passed in picker buttons,
|
||||||
// add a cancel and ok button to the picker
|
// add a cancel and ok button to the picker
|
||||||
const buttons = pickerOptions.buttons;
|
const buttons = pickerOptions.buttons;
|
||||||
@ -245,36 +264,20 @@ export class Datetime {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: this.doneText,
|
text: this.doneText,
|
||||||
handler: (data: any) => this.value = data,
|
handler: (data: any) => this.value = data
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
];
|
||||||
pickerOptions.columns = this.generateColumns();
|
|
||||||
|
|
||||||
const picker = this.pickerCtrl.create(pickerOptions);
|
|
||||||
|
|
||||||
return picker;
|
|
||||||
}
|
}
|
||||||
|
return pickerOptions;
|
||||||
private async open() {
|
|
||||||
// TODO check this.isFocus() || this.disabled
|
|
||||||
if (this.disabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const pickerOptions = { ...this.pickerOptions };
|
|
||||||
this.picker = await this.buildPicker(pickerOptions);
|
|
||||||
this.validate();
|
|
||||||
await this.picker!.present();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateColumns(): PickerColumn[] {
|
private generateColumns(): PickerColumn[] {
|
||||||
let columns: PickerColumn[] = [];
|
|
||||||
|
|
||||||
// if a picker format wasn't provided, then fallback
|
// if a picker format wasn't provided, then fallback
|
||||||
// to use the display format
|
// to use the display format
|
||||||
let template = this.pickerFormat || this.displayFormat || DEFAULT_FORMAT;
|
let template = this.pickerFormat || this.displayFormat || DEFAULT_FORMAT;
|
||||||
|
if (!template) {
|
||||||
if (template) {
|
return [];
|
||||||
|
}
|
||||||
// make sure we've got up to date sizing information
|
// make sure we've got up to date sizing information
|
||||||
this.calcMinMax();
|
this.calcMinMax();
|
||||||
|
|
||||||
@ -290,7 +293,7 @@ export class Datetime {
|
|||||||
template = template.replace(/{~}/g, '');
|
template = template.replace(/{~}/g, '');
|
||||||
|
|
||||||
// parse apart the given template into an array of "formats"
|
// parse apart the given template into an array of "formats"
|
||||||
parseTemplate(template).forEach((format: any) => {
|
const columns = parseTemplate(template).map((format: any) => {
|
||||||
// loop through each format in the template
|
// loop through each format in the template
|
||||||
// create a new picker column to build up with data
|
// create a new picker column to build up with data
|
||||||
const key = convertFormatToKey(format)!;
|
const key = convertFormatToKey(format)!;
|
||||||
@ -302,28 +305,23 @@ export class Datetime {
|
|||||||
? convertToArrayOfNumbers(this[key + 'Values'], key)
|
? convertToArrayOfNumbers(this[key + 'Values'], key)
|
||||||
: dateValueRange(format, this.datetimeMin, this.datetimeMax);
|
: dateValueRange(format, this.datetimeMin, this.datetimeMax);
|
||||||
|
|
||||||
const column: PickerColumn = {
|
const colOptions = values.map(val => {
|
||||||
name: key,
|
|
||||||
selectedIndex: 0,
|
|
||||||
options: values.map(val => {
|
|
||||||
return {
|
return {
|
||||||
value: val,
|
value: val,
|
||||||
text: renderTextFormat(format, val, null, this.locale),
|
text: renderTextFormat(format, val, null, this.locale),
|
||||||
};
|
};
|
||||||
})
|
});
|
||||||
};
|
|
||||||
|
|
||||||
// cool, we've loaded up the columns with options
|
// cool, we've loaded up the columns with options
|
||||||
// preselect the option for this column
|
// preselect the option for this column
|
||||||
const optValue = getValueFromFormat(this.datetimeValue, format);
|
const optValue = getValueFromFormat(this.datetimeValue, format);
|
||||||
const selectedIndex = column.options.findIndex(opt => opt.value === optValue);
|
const selectedIndex = colOptions.findIndex(opt => opt.value === optValue);
|
||||||
if (selectedIndex >= 0) {
|
|
||||||
// set the select index for this column's options
|
|
||||||
column.selectedIndex = selectedIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add our newly created column to the picker
|
return {
|
||||||
columns.push(column);
|
name: key,
|
||||||
|
selectedIndex: selectedIndex >= 0 ? selectedIndex : 0,
|
||||||
|
options: colOptions
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Normalize min/max
|
// Normalize min/max
|
||||||
@ -336,10 +334,7 @@ export class Datetime {
|
|||||||
max[name] = 0;
|
max[name] = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
columns = this.divyColumns(columns);
|
return divyColumns(columns);
|
||||||
}
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private validate() {
|
private validate() {
|
||||||
@ -484,42 +479,6 @@ export class Datetime {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private divyColumns(columns: PickerColumn[]): PickerColumn[] {
|
|
||||||
const pickerColumns = columns;
|
|
||||||
const columnsWidth: number[] = [];
|
|
||||||
let col: PickerColumn;
|
|
||||||
let width: number;
|
|
||||||
for (let i = 0; i < pickerColumns.length; i++) {
|
|
||||||
col = pickerColumns[i];
|
|
||||||
columnsWidth.push(0);
|
|
||||||
|
|
||||||
for (const option of col.options) {
|
|
||||||
width = option.text!.length;
|
|
||||||
if (width > columnsWidth[i]) {
|
|
||||||
columnsWidth[i] = width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (columnsWidth.length === 2) {
|
|
||||||
width = Math.max(columnsWidth[0], columnsWidth[1]);
|
|
||||||
pickerColumns[0].align = 'right';
|
|
||||||
pickerColumns[1].align = 'left';
|
|
||||||
pickerColumns[0].optionsWidth = pickerColumns[1].optionsWidth = `${width * 17}px`;
|
|
||||||
|
|
||||||
} else if (columnsWidth.length === 3) {
|
|
||||||
width = Math.max(columnsWidth[0], columnsWidth[2]);
|
|
||||||
pickerColumns[0].align = 'right';
|
|
||||||
pickerColumns[1].columnWidth = `${columnsWidth[1] * 17}px`;
|
|
||||||
pickerColumns[0].optionsWidth = pickerColumns[2].optionsWidth = `${width * 17}px`;
|
|
||||||
pickerColumns[2].align = 'left';
|
|
||||||
}
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
private updateText() {
|
private updateText() {
|
||||||
// create the text of the formatted data
|
// create the text of the formatted data
|
||||||
const template = this.displayFormat || this.pickerFormat || DEFAULT_FORMAT;
|
const template = this.displayFormat || this.pickerFormat || DEFAULT_FORMAT;
|
||||||
@ -527,8 +486,6 @@ export class Datetime {
|
|||||||
this.text = renderDatetime(template, this.datetimeValue, this.locale);
|
this.text = renderDatetime(template, this.datetimeValue, this.locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
hasValue(): boolean {
|
hasValue(): boolean {
|
||||||
const val = this.datetimeValue;
|
const val = this.datetimeValue;
|
||||||
return val
|
return val
|
||||||
@ -580,6 +537,38 @@ export class Datetime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function divyColumns(columns: PickerColumn[]): PickerColumn[] {
|
||||||
|
const columnsWidth: number[] = [];
|
||||||
|
let col: PickerColumn;
|
||||||
|
let width: number;
|
||||||
|
for (let i = 0; i < columns.length; i++) {
|
||||||
|
col = columns[i];
|
||||||
|
columnsWidth.push(0);
|
||||||
|
|
||||||
|
for (const option of col.options) {
|
||||||
|
width = option.text!.length;
|
||||||
|
if (width > columnsWidth[i]) {
|
||||||
|
columnsWidth[i] = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnsWidth.length === 2) {
|
||||||
|
width = Math.max(columnsWidth[0], columnsWidth[1]);
|
||||||
|
columns[0].align = 'right';
|
||||||
|
columns[1].align = 'left';
|
||||||
|
columns[0].optionsWidth = columns[1].optionsWidth = `${width * 17}px`;
|
||||||
|
|
||||||
|
} else if (columnsWidth.length === 3) {
|
||||||
|
width = Math.max(columnsWidth[0], columnsWidth[2]);
|
||||||
|
columns[0].align = 'right';
|
||||||
|
columns[1].columnWidth = `${columnsWidth[1] * 17}px`;
|
||||||
|
columns[0].optionsWidth = columns[2].optionsWidth = `${width * 17}px`;
|
||||||
|
columns[2].align = 'left';
|
||||||
|
}
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
let datetimeIds = 0;
|
let datetimeIds = 0;
|
||||||
|
|
||||||
const DEFAULT_FORMAT = 'MMM D, YYYY';
|
const DEFAULT_FORMAT = 'MMM D, YYYY';
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { Component, Element, Prop, QueueApi } from '@stencil/core';
|
import { Component, Element, Event, EventEmitter, Prop, QueueApi } from '@stencil/core';
|
||||||
|
|
||||||
import { Gesture, GestureDetail, Mode, PickerColumn } from '../../interface';
|
import { Gesture, GestureDetail, Mode, PickerColumn } from '../../interface';
|
||||||
import { hapticSelectionChanged } from '../../utils';
|
import { hapticSelectionChanged } from '../../utils';
|
||||||
import { clamp } from '../../utils/helpers';
|
import { clamp } from '../../utils/helpers';
|
||||||
import { createThemedClasses } from '../../utils/theme';
|
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@ -14,7 +13,6 @@ export class PickerColumnCmp {
|
|||||||
|
|
||||||
private bounceFrom!: number;
|
private bounceFrom!: number;
|
||||||
private lastIndex?: number;
|
private lastIndex?: number;
|
||||||
private lastTempIndex?: number;
|
|
||||||
private minY!: number;
|
private minY!: number;
|
||||||
private maxY!: number;
|
private maxY!: number;
|
||||||
private optHeight = 0;
|
private optHeight = 0;
|
||||||
@ -22,6 +20,7 @@ export class PickerColumnCmp {
|
|||||||
private scaleFactor = 1;
|
private scaleFactor = 1;
|
||||||
private velocity = 0;
|
private velocity = 0;
|
||||||
private y = 0;
|
private y = 0;
|
||||||
|
private optsEl?: HTMLElement;
|
||||||
private gesture?: Gesture;
|
private gesture?: Gesture;
|
||||||
private rafId: any;
|
private rafId: any;
|
||||||
|
|
||||||
@ -31,6 +30,8 @@ export class PickerColumnCmp {
|
|||||||
|
|
||||||
@Prop() col!: PickerColumn;
|
@Prop() col!: PickerColumn;
|
||||||
|
|
||||||
|
@Event() ionChange!: EventEmitter<void>;
|
||||||
|
|
||||||
componentWillLoad() {
|
componentWillLoad() {
|
||||||
let pickerRotateFactor = 0;
|
let pickerRotateFactor = 0;
|
||||||
let pickerScaleFactor = 0.81;
|
let pickerScaleFactor = 0.81;
|
||||||
@ -46,7 +47,7 @@ export class PickerColumnCmp {
|
|||||||
|
|
||||||
async componentDidLoad() {
|
async componentDidLoad() {
|
||||||
// get the scrollable element within the column
|
// get the scrollable element within the column
|
||||||
const colEl = this.el.querySelector('.picker-opts')!;
|
const colEl = this.optsEl!;
|
||||||
|
|
||||||
// get the height of one option
|
// get the height of one option
|
||||||
this.optHeight = (colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0);
|
this.optHeight = (colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0);
|
||||||
@ -69,39 +70,35 @@ export class PickerColumnCmp {
|
|||||||
private setSelected(selectedIndex: number, duration: number) {
|
private setSelected(selectedIndex: number, duration: number) {
|
||||||
// if there is a selected index, then figure out it's y position
|
// if there is a selected index, then figure out it's y position
|
||||||
// if there isn't a selected index, then just use the top y position
|
// if there isn't a selected index, then just use the top y position
|
||||||
const y = (selectedIndex > -1) ? ((selectedIndex * this.optHeight) * -1) : 0;
|
const y = (selectedIndex > -1) ? -(selectedIndex * this.optHeight) : 0;
|
||||||
|
|
||||||
this.velocity = 0;
|
this.velocity = 0;
|
||||||
|
|
||||||
// set what y position we're at
|
// set what y position we're at
|
||||||
cancelAnimationFrame(this.rafId);
|
cancelAnimationFrame(this.rafId);
|
||||||
this.update(y, duration, true, true);
|
this.update(y, duration, true);
|
||||||
|
this.ionChange.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private update(y: number, duration: number, saveY: boolean, emitChange: boolean) {
|
private update(y: number, duration: number, saveY: boolean) {
|
||||||
// ensure we've got a good round number :)
|
// ensure we've got a good round number :)
|
||||||
y = Math.round(y);
|
|
||||||
|
|
||||||
let translateY = 0;
|
let translateY = 0;
|
||||||
let translateZ = 0;
|
let translateZ = 0;
|
||||||
|
const { col, rotateFactor } = this;
|
||||||
const parent = this.el.querySelector('.picker-opts')!;
|
const selectedIndex = col.selectedIndex = this.indexForY(-y);
|
||||||
const children = parent.children;
|
|
||||||
const length = children.length;
|
|
||||||
const selectedIndex = this.col.selectedIndex = Math.min(Math.max(Math.round(-y / this.optHeight), 0), length - 1);
|
|
||||||
|
|
||||||
const durationStr = (duration === 0) ? null : duration + 'ms';
|
const durationStr = (duration === 0) ? null : duration + 'ms';
|
||||||
const scaleStr = `scale(${this.scaleFactor})`;
|
const scaleStr = `scale(${this.scaleFactor})`;
|
||||||
|
|
||||||
for (let i = 0; i < length; i++) {
|
const children = this.optsEl!.children;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
const button = children[i] as HTMLElement;
|
const button = children[i] as HTMLElement;
|
||||||
const opt = this.col.options[i];
|
const opt = col.options[i];
|
||||||
const optOffset = (i * this.optHeight) + y;
|
const optOffset = (i * this.optHeight) + y;
|
||||||
let visible = true;
|
let visible = true;
|
||||||
let transform = '';
|
let transform = '';
|
||||||
|
|
||||||
if (this.rotateFactor !== 0) {
|
if (rotateFactor !== 0) {
|
||||||
const rotateX = optOffset * this.rotateFactor;
|
const rotateX = optOffset * rotateFactor;
|
||||||
if (Math.abs(rotateX) > 90) {
|
if (Math.abs(rotateX) > 90) {
|
||||||
visible = false;
|
visible = false;
|
||||||
} else {
|
} else {
|
||||||
@ -152,32 +149,15 @@ export class PickerColumnCmp {
|
|||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emitChange) {
|
if (this.lastIndex !== selectedIndex) {
|
||||||
if (this.lastIndex === undefined) {
|
|
||||||
// have not set a last index yet
|
// have not set a last index yet
|
||||||
this.lastIndex = this.col.selectedIndex;
|
hapticSelectionChanged();
|
||||||
|
this.lastIndex = selectedIndex;
|
||||||
} else if (this.lastIndex !== this.col.selectedIndex) {
|
|
||||||
// new selected index has changed from the last index
|
|
||||||
// update the lastIndex and emit that it has changed
|
|
||||||
this.lastIndex = this.col.selectedIndex;
|
|
||||||
// TODO ionChange event
|
|
||||||
// var ionChange = this.ionChange;
|
|
||||||
// if (ionChange.observers.length > 0) {
|
|
||||||
// this._zone.run(ionChange.emit.bind(ionChange, this.col.options[this.col.selectedIndex]));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private decelerate() {
|
private decelerate() {
|
||||||
let y = 0;
|
if (this.velocity !== 0) {
|
||||||
|
|
||||||
if (isNaN(this.y) || !this.optHeight) {
|
|
||||||
// fallback in case numbers get outta wack
|
|
||||||
this.update(y, 0, true, true);
|
|
||||||
|
|
||||||
} else if (Math.abs(this.velocity) > 0) {
|
|
||||||
// still decelerating
|
// still decelerating
|
||||||
this.velocity *= DECELERATION_FRICTION;
|
this.velocity *= DECELERATION_FRICTION;
|
||||||
|
|
||||||
@ -186,7 +166,7 @@ export class PickerColumnCmp {
|
|||||||
? Math.max(this.velocity, 1)
|
? Math.max(this.velocity, 1)
|
||||||
: Math.min(this.velocity, -1);
|
: Math.min(this.velocity, -1);
|
||||||
|
|
||||||
y = Math.round(this.y + this.velocity);
|
let y = this.y + this.velocity;
|
||||||
|
|
||||||
if (y > this.minY) {
|
if (y > this.minY) {
|
||||||
// whoops, it's trying to scroll up farther than the options we have!
|
// whoops, it's trying to scroll up farther than the options we have!
|
||||||
@ -199,13 +179,13 @@ export class PickerColumnCmp {
|
|||||||
this.velocity = 0;
|
this.velocity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const notLockedIn = (y % this.optHeight !== 0 || Math.abs(this.velocity) > 1);
|
this.update(y, 0, true);
|
||||||
|
const notLockedIn = (Math.round(y) % this.optHeight !== 0) || (Math.abs(this.velocity) > 1);
|
||||||
this.update(y, 0, true, !notLockedIn);
|
|
||||||
|
|
||||||
if (notLockedIn) {
|
if (notLockedIn) {
|
||||||
// isn't locked in yet, keep decelerating until it is
|
// isn't locked in yet, keep decelerating until it is
|
||||||
this.rafId = requestAnimationFrame(() => this.decelerate());
|
this.rafId = requestAnimationFrame(() => this.decelerate());
|
||||||
|
} else {
|
||||||
|
this.ionChange.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (this.y % this.optHeight !== 0) {
|
} else if (this.y % this.optHeight !== 0) {
|
||||||
@ -217,14 +197,10 @@ export class PickerColumnCmp {
|
|||||||
|
|
||||||
this.decelerate();
|
this.decelerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentIndex = Math.max(Math.abs(Math.round(y / this.optHeight)), 0);
|
|
||||||
|
|
||||||
if (currentIndex !== this.lastTempIndex) {
|
|
||||||
// Trigger a haptic event for physical feedback that the index has changed
|
|
||||||
hapticSelectionChanged();
|
|
||||||
}
|
}
|
||||||
this.lastTempIndex = currentIndex;
|
|
||||||
|
private indexForY(y: number) {
|
||||||
|
return Math.min(Math.max(Math.abs(Math.round(y / this.optHeight)), 0), this.col.options.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should this check disabled?
|
// TODO should this check disabled?
|
||||||
@ -250,8 +226,8 @@ export class PickerColumnCmp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.minY = (minY * this.optHeight * -1);
|
this.minY = -(minY * this.optHeight);
|
||||||
this.maxY = (maxY * this.optHeight * -1);
|
this.maxY = -(maxY * this.optHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDragMove(detail: GestureDetail) {
|
private onDragMove(detail: GestureDetail) {
|
||||||
@ -277,22 +253,17 @@ export class PickerColumnCmp {
|
|||||||
this.bounceFrom = 0;
|
this.bounceFrom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update(y, 0, false, false);
|
this.update(y, 0, false);
|
||||||
|
|
||||||
const currentIndex = Math.max(Math.abs(Math.round(y / this.optHeight)), 0);
|
|
||||||
if (currentIndex !== this.lastTempIndex) {
|
|
||||||
this.lastTempIndex = currentIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDragEnd(detail: GestureDetail) {
|
private onDragEnd(detail: GestureDetail) {
|
||||||
if (this.bounceFrom > 0) {
|
if (this.bounceFrom > 0) {
|
||||||
// bounce back up
|
// bounce back up
|
||||||
this.update(this.minY, 100, true, true);
|
this.update(this.minY, 100, true);
|
||||||
return;
|
return;
|
||||||
} else if (this.bounceFrom < 0) {
|
} else if (this.bounceFrom < 0) {
|
||||||
// bounce back down
|
// bounce back down
|
||||||
this.update(this.maxY, 100, true, true);
|
this.update(this.maxY, 100, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,10 +275,7 @@ export class PickerColumnCmp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (Math.abs(detail.deltaY) > 3) {
|
this.y += detail.deltaY;
|
||||||
const y = this.y + detail.deltaY;
|
|
||||||
this.update(y, 0, true, true);
|
|
||||||
}
|
|
||||||
this.decelerate();
|
this.decelerate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,15 +295,14 @@ export class PickerColumnCmp {
|
|||||||
if (this.col.prevSelected !== selectedIndex) {
|
if (this.col.prevSelected !== selectedIndex) {
|
||||||
const y = (selectedIndex * this.optHeight) * -1;
|
const y = (selectedIndex * this.optHeight) * -1;
|
||||||
this.velocity = 0;
|
this.velocity = 0;
|
||||||
this.update(y, 150, true, false);
|
this.update(y, 150, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hostData() {
|
hostData() {
|
||||||
return {
|
return {
|
||||||
class: {
|
class: {
|
||||||
...createThemedClasses(this.mode, 'picker-col'),
|
'picker-col': true,
|
||||||
|
|
||||||
'picker-opts-left': this.col.align === 'left',
|
'picker-opts-left': this.col.align === 'left',
|
||||||
'picker-opts-right': this.col.align === 'right'
|
'picker-opts-right': this.col.align === 'right'
|
||||||
},
|
},
|
||||||
@ -347,14 +314,6 @@ export class PickerColumnCmp {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const col = this.col;
|
const col = this.col;
|
||||||
|
|
||||||
const options = col.options.map(o => {
|
|
||||||
return (typeof o === 'string')
|
|
||||||
? { text: o }
|
|
||||||
: o;
|
|
||||||
})
|
|
||||||
.filter(o => o !== null);
|
|
||||||
|
|
||||||
const Button = 'button' as any;
|
const Button = 'button' as any;
|
||||||
return [
|
return [
|
||||||
col.prefix && (
|
col.prefix && (
|
||||||
@ -362,8 +321,11 @@ export class PickerColumnCmp {
|
|||||||
{col.prefix}
|
{col.prefix}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
<div class="picker-opts" style={{ maxWidth: col.optionsWidth! }}>
|
<div
|
||||||
{options.map((o, index) =>
|
class="picker-opts"
|
||||||
|
style={{ maxWidth: col.optionsWidth! }}
|
||||||
|
ref={ el => this.optsEl = el }>
|
||||||
|
{ col.options.map((o, index) =>
|
||||||
<Button
|
<Button
|
||||||
class={{ 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }}
|
class={{ 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }}
|
||||||
disable-activated
|
disable-activated
|
||||||
|
@ -205,22 +205,6 @@ export class Picker implements OverlayInterface {
|
|||||||
return eventMethod(this.el, 'ionPickerWillDismiss', callback);
|
return eventMethod(this.el, 'ionPickerWillDismiss', callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new PickerButton to the picker
|
|
||||||
*/
|
|
||||||
@Method()
|
|
||||||
addButton(button: PickerButton) {
|
|
||||||
this.buttons.push(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new PickerColumn to the picker
|
|
||||||
*/
|
|
||||||
@Method()
|
|
||||||
addColumn(column: PickerColumn) {
|
|
||||||
this.columns.push(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the column the matches the specified name
|
* Returns the column the matches the specified name
|
||||||
*/
|
*/
|
||||||
@ -229,14 +213,6 @@ export class Picker implements OverlayInterface {
|
|||||||
return this.columns.find(column => column.name === name);
|
return this.columns.find(column => column.name === name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all the PickerColumns
|
|
||||||
*/
|
|
||||||
@Method()
|
|
||||||
getColumns(): PickerColumn[] {
|
|
||||||
return this.columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
private buttonClick(button: PickerButton) {
|
private buttonClick(button: PickerButton) {
|
||||||
// if (this.disabled) {
|
// if (this.disabled) {
|
||||||
// return;
|
// return;
|
||||||
@ -295,41 +271,14 @@ export class Picker implements OverlayInterface {
|
|||||||
|
|
||||||
const columns = this.columns;
|
const columns = this.columns;
|
||||||
|
|
||||||
// // clean up dat data
|
|
||||||
// data.columns = data.columns.map(column => {
|
|
||||||
// if (!isPresent(column.options)) {
|
|
||||||
// column.options = [];
|
|
||||||
// }
|
|
||||||
// column.selectedIndex = column.selectedIndex || 0;
|
|
||||||
// column.options = column.options.map(inputOpt => {
|
|
||||||
// let opt: PickerColumnOption = {
|
|
||||||
// text: '',
|
|
||||||
// value: '',
|
|
||||||
// disabled: inputOpt.disabled,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if (isPresent(inputOpt)) {
|
|
||||||
// if (isString(inputOpt) || isNumber(inputOpt)) {
|
|
||||||
// opt.text = inputOpt.toString();
|
|
||||||
// opt.value = inputOpt;
|
|
||||||
|
|
||||||
// } else {
|
|
||||||
// opt.text = isPresent(inputOpt.text) ? inputOpt.text : inputOpt.value;
|
|
||||||
// opt.value = isPresent(inputOpt.value) ? inputOpt.value : inputOpt.text;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return opt;
|
|
||||||
// });
|
|
||||||
// return column;
|
|
||||||
// });
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<ion-backdrop
|
<ion-backdrop
|
||||||
visible={this.showBackdrop}
|
visible={this.showBackdrop}
|
||||||
tappable={this.enableBackdropDismiss}
|
tappable={this.enableBackdropDismiss}
|
||||||
/>,
|
/>,
|
||||||
|
|
||||||
<div class="picker-wrapper" role="dialog">
|
<div class="picker-wrapper" role="dialog">
|
||||||
|
|
||||||
<div class="picker-toolbar">
|
<div class="picker-toolbar">
|
||||||
{buttons.map(b => (
|
{buttons.map(b => (
|
||||||
<div class={buttonWrapperClass(b)}>
|
<div class={buttonWrapperClass(b)}>
|
||||||
@ -342,11 +291,13 @@ export class Picker implements OverlayInterface {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="picker-columns">
|
<div class="picker-columns">
|
||||||
<div class="picker-above-highlight" />
|
<div class="picker-above-highlight" />
|
||||||
{columns.map(c => <ion-picker-column col={c} />)}
|
{columns.map(c => <ion-picker-column col={c} />)}
|
||||||
<div class="picker-below-highlight" />
|
<div class="picker-below-highlight" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user