mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-09 08:09:32 +08:00
feat(picker): WIP initial check in of picker component
This commit is contained in:
@ -0,0 +1,73 @@
|
||||
import { Component, Listen, Method } from '@stencil/core';
|
||||
import { Picker, PickerEvent, PickerOptions } from '../../index';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-picker-controller'
|
||||
})
|
||||
export class PickerController {
|
||||
private ids = 0;
|
||||
private pickerResolves: {[pickerId: string]: Function} = {};
|
||||
private pickers: Picker[] = [];
|
||||
|
||||
@Method()
|
||||
create(opts?: PickerOptions): Promise<Picker> {
|
||||
// create ionic's wrapping ion-picker component
|
||||
const picker = document.createElement('ion-picker');
|
||||
|
||||
const id = this.ids++;
|
||||
|
||||
// give this picker a unique id
|
||||
picker.id = `picker-${id}`;
|
||||
picker.style.zIndex = (20000 + id).toString();
|
||||
|
||||
// convert the passed in picker options into props
|
||||
// that get passed down into the new picker
|
||||
Object.assign(picker, opts);
|
||||
|
||||
// append the picker element to the document body
|
||||
const appRoot = document.querySelector('ion-app') || document.body;
|
||||
appRoot.appendChild(picker as any);
|
||||
|
||||
// store the resolve function to be called later up when the picker loads
|
||||
return new Promise<Picker>(resolve => {
|
||||
this.pickerResolves[picker.id] = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Listen('body:ionPickerDidLoad')
|
||||
protected viewDidLoad(ev: PickerEvent) {
|
||||
const picker = ev.detail.picker;
|
||||
const pickerResolve = this.pickerResolves[picker.id];
|
||||
if (pickerResolve) {
|
||||
pickerResolve(picker);
|
||||
delete this.pickerResolves[picker.id];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Listen('body:ionPickerWillPresent')
|
||||
protected willPresent(ev: PickerEvent) {
|
||||
this.pickers.push(ev.detail.picker);
|
||||
}
|
||||
|
||||
|
||||
@Listen('body:ionPickerWillDismiss, body:ionPickerDidUnload')
|
||||
protected willDismiss(ev: PickerEvent) {
|
||||
const index = this.pickers.indexOf(ev.detail.picker);
|
||||
if (index > -1) {
|
||||
this.pickers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Listen('body:keyup.escape')
|
||||
protected escapeKeyUp() {
|
||||
const lastPicker = this.pickers[this.pickers.length - 1];
|
||||
if (lastPicker) {
|
||||
lastPicker.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
packages/core/src/components/picker/animations/ios.enter.ts
Normal file
26
packages/core/src/components/picker/animations/ios.enter.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Animation } from '../../../index';
|
||||
|
||||
|
||||
/**
|
||||
* iOS Loading Enter Animation
|
||||
*/
|
||||
export default function iOSEnterAnimation(Animation: Animation, baseElm: HTMLElement): Animation {
|
||||
const baseAnimation = new Animation();
|
||||
|
||||
const backdropAnimation = new Animation();
|
||||
backdropAnimation.addElement(baseElm.querySelector('.picker-backdrop'));
|
||||
|
||||
const wrapperAnimation = new Animation();
|
||||
wrapperAnimation.addElement(baseElm.querySelector('.picker-wrapper'));
|
||||
|
||||
backdropAnimation.fromTo('opacity', 0.01, 0.26);
|
||||
|
||||
wrapperAnimation.fromTo('translateY', '100%', '0%');
|
||||
|
||||
return baseAnimation
|
||||
.addElement(baseElm)
|
||||
.easing('ease-in-out')
|
||||
.duration(200)
|
||||
.add(backdropAnimation)
|
||||
.add(wrapperAnimation);
|
||||
}
|
||||
26
packages/core/src/components/picker/animations/ios.leave.ts
Normal file
26
packages/core/src/components/picker/animations/ios.leave.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Animation } from '../../../index';
|
||||
|
||||
|
||||
/**
|
||||
* iOS Loading Leave Animation
|
||||
*/
|
||||
export default function iOSLeaveAnimation(Animation: Animation, baseElm: HTMLElement): Animation {
|
||||
const baseAnimation = new Animation();
|
||||
|
||||
const backdropAnimation = new Animation();
|
||||
backdropAnimation.addElement(baseElm.querySelector('.picker-backdrop'));
|
||||
|
||||
const wrapperAnimation = new Animation();
|
||||
wrapperAnimation.addElement(baseElm.querySelector('.picker-wrapper'));
|
||||
|
||||
backdropAnimation.fromTo('opacity', 0.26, 0.01);
|
||||
|
||||
wrapperAnimation.fromTo('translateY', '0%', '100%');
|
||||
|
||||
return baseAnimation
|
||||
.addElement(baseElm)
|
||||
.easing('ease-in-out')
|
||||
.duration(200)
|
||||
.add(backdropAnimation)
|
||||
.add(wrapperAnimation);
|
||||
}
|
||||
477
packages/core/src/components/picker/picker-column.tsx
Normal file
477
packages/core/src/components/picker/picker-column.tsx
Normal file
@ -0,0 +1,477 @@
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
|
||||
import { PickerColumn } from '../../index';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-picker-column',
|
||||
host: {
|
||||
theme: 'picker-col'
|
||||
}
|
||||
})
|
||||
export class PickerColumnCmp {
|
||||
velocity: number;
|
||||
optHeight: number;
|
||||
|
||||
@Element() el: HTMLElement;
|
||||
|
||||
@Prop() col: PickerColumn;
|
||||
|
||||
optClick(ev: Event, index: number) {
|
||||
if (!this.velocity) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
this.setSelected(index, 150);
|
||||
}
|
||||
}
|
||||
|
||||
setSelected(selectedIndex: number, duration: number) {
|
||||
// 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
|
||||
let y = (selectedIndex > -1) ? ((selectedIndex * this.optHeight) * -1) : 0;
|
||||
|
||||
// this._plt.cancelRaf(this.rafId);
|
||||
this.velocity = 0;
|
||||
|
||||
// so what y position we're at
|
||||
this.update(y, duration, true, true);
|
||||
}
|
||||
|
||||
update(y: number, duration: number, saveY: boolean, emitChange: boolean) {
|
||||
// ensure we've got a good round number :)
|
||||
y = Math.round(y);
|
||||
|
||||
// let i: number;
|
||||
// let button: any;
|
||||
// let opt: any;
|
||||
// let optOffset: number;
|
||||
// let visible: boolean;
|
||||
// let translateX: number;
|
||||
// let translateY: number;
|
||||
// let translateZ: number;
|
||||
// let rotateX: number;
|
||||
// let transform: string;
|
||||
// let selected: boolean;
|
||||
|
||||
const parent = this.el.querySelector('.picker-opts');
|
||||
// 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 scaleStr = `scale(${this.scaleFactor})`;
|
||||
|
||||
// for (i = 0; i < length; i++) {
|
||||
// button = children[i];
|
||||
// opt = <any>this.col.options[i];
|
||||
// optOffset = (i * this.optHeight) + y;
|
||||
// visible = true;
|
||||
// transform = '';
|
||||
|
||||
// if (this.rotateFactor !== 0) {
|
||||
// rotateX = optOffset * this.rotateFactor;
|
||||
// if (Math.abs(rotateX) > 90) {
|
||||
// visible = false;
|
||||
// } else {
|
||||
// translateX = 0;
|
||||
// translateY = 0;
|
||||
// translateZ = 90;
|
||||
// transform = `rotateX(${rotateX}deg) `;
|
||||
// }
|
||||
// } else {
|
||||
// translateX = 0;
|
||||
// translateZ = 0;
|
||||
// translateY = optOffset;
|
||||
// if (Math.abs(translateY) > 170) {
|
||||
// visible = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// selected = selectedIndex === i;
|
||||
// if (visible) {
|
||||
// transform += `translate3d(0px,${translateY}px,${translateZ}px) `;
|
||||
// if (this.scaleFactor !== 1 && !selected) {
|
||||
// transform += scaleStr;
|
||||
// }
|
||||
// } else {
|
||||
// transform = 'translate3d(-9999px,0px,0px)';
|
||||
// }
|
||||
// // Update transition duration
|
||||
// if (duration !== opt._dur) {
|
||||
// opt._dur = duration;
|
||||
// button.style[this._plt.Css.transitionDuration] = durationStr;
|
||||
// }
|
||||
// // Update transform
|
||||
// if (transform !== opt._trans) {
|
||||
// opt._trans = transform;
|
||||
// button.style[this._plt.Css.transform] = transform;
|
||||
// }
|
||||
// // Update selected item
|
||||
// if (selected !== opt._selected) {
|
||||
// opt._selected = selected;
|
||||
// if (selected) {
|
||||
// button.classList.add(PICKER_OPT_SELECTED);
|
||||
// } else {
|
||||
// button.classList.remove(PICKER_OPT_SELECTED);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// this.col.prevSelected = selectedIndex;
|
||||
|
||||
// if (saveY) {
|
||||
// this.y = y;
|
||||
// }
|
||||
|
||||
// if (emitChange) {
|
||||
// if (this.lastIndex === undefined) {
|
||||
// // have not set a last index yet
|
||||
// this.lastIndex = this.col.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;
|
||||
// var ionChange = this.ionChange;
|
||||
// if (ionChange.observers.length > 0) {
|
||||
// this._zone.run(ionChange.emit.bind(ionChange, this.col.options[this.col.selectedIndex]));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log('picker column, render col', this.col);
|
||||
let col = this.col;
|
||||
|
||||
const pickerPrefix: any[] = [];
|
||||
|
||||
if (col.prefix) {
|
||||
pickerPrefix.push(
|
||||
<div class="picker-prefix" style={{width: col.prefixWidth}}>
|
||||
{col.prefix}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// if (this.content) {
|
||||
// pickerPrefix.push(
|
||||
// <div class='loading-content'>
|
||||
// {this.content}
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
return [
|
||||
{ pickerPrefix },
|
||||
<div class="picker-opts" style={{maxWidth: col.optionsWidth}}>
|
||||
{col.options.map((o, index) =>
|
||||
<button
|
||||
class={{'picker-opt': true, 'picker-opt-disabled': o.disabled}}
|
||||
disable-activated
|
||||
onClick={() => this.optClick(event, index)}>
|
||||
{o.text}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// @Component({
|
||||
// selector: '.picker-col',
|
||||
// template:
|
||||
// '<div *ngIf="col.prefix" class="picker-prefix" [style.width]="col.prefixWidth">{{col.prefix}}</div>' +
|
||||
// '<div class="picker-opts" #colEle [style.max-width]="col.optionsWidth">' +
|
||||
// '<button *ngFor="let o of col.options; let i=index"' +
|
||||
// '[class.picker-opt-disabled]="o.disabled" ' +
|
||||
// 'class="picker-opt" disable-activated (click)="optClick($event, i)">' +
|
||||
// '{{o.text}}' +
|
||||
// '</button>' +
|
||||
// '</div>' +
|
||||
// '<div *ngIf="col.suffix" class="picker-suffix" [style.width]="col.suffixWidth">{{col.suffix}}</div>',
|
||||
// host: {
|
||||
// '[style.max-width]': 'col.columnWidth',
|
||||
// '[class.picker-opts-left]': 'col.align=="left"',
|
||||
// '[class.picker-opts-right]': 'col.align=="right"',
|
||||
// }
|
||||
// })
|
||||
// export class PickerColumnCmp {
|
||||
// @ViewChild('colEle') colEle: ElementRef;
|
||||
// @Input() col: PickerColumn;
|
||||
// y: number = 0;
|
||||
// colHeight: number;
|
||||
// velocity: number;
|
||||
// pos: number[] = [];
|
||||
// startY: number = null;
|
||||
// rafId: number;
|
||||
// bounceFrom: number;
|
||||
// minY: number;
|
||||
// maxY: number;
|
||||
// rotateFactor: number;
|
||||
// scaleFactor: number;
|
||||
// lastIndex: number;
|
||||
// lastTempIndex: number;
|
||||
// decelerateFunc: Function;
|
||||
// debouncer: DomDebouncer;
|
||||
// events: UIEventManager;
|
||||
|
||||
// @Output() ionChange: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
// constructor(
|
||||
// config: Config,
|
||||
// private _plt: Platform,
|
||||
// private elementRef: ElementRef,
|
||||
// private _zone: NgZone,
|
||||
// private _haptic: Haptic,
|
||||
// plt: Platform,
|
||||
// domCtrl: DomController,
|
||||
// ) {
|
||||
// this.events = new UIEventManager(plt);
|
||||
// this.rotateFactor = config.getNumber('pickerRotateFactor', 0);
|
||||
// this.scaleFactor = config.getNumber('pickerScaleFactor', 1);
|
||||
// this.decelerateFunc = this.decelerate.bind(this);
|
||||
// this.debouncer = domCtrl.debouncer();
|
||||
// }
|
||||
|
||||
// ngAfterViewInit() {
|
||||
// // get the scrollable element within the column
|
||||
// let colEle: HTMLElement = this.colEle.nativeElement;
|
||||
|
||||
// this.colHeight = colEle.clientHeight;
|
||||
|
||||
// // get the height of one option
|
||||
// this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
|
||||
|
||||
// // Listening for pointer events
|
||||
// this.events.pointerEvents({
|
||||
// element: this.elementRef.nativeElement,
|
||||
// pointerDown: this.pointerStart.bind(this),
|
||||
// pointerMove: this.pointerMove.bind(this),
|
||||
// pointerUp: this.pointerEnd.bind(this),
|
||||
// capture: true,
|
||||
// zone: false
|
||||
// });
|
||||
// }
|
||||
|
||||
// ngOnDestroy() {
|
||||
// this._plt.cancelRaf(this.rafId);
|
||||
// this.events.destroy();
|
||||
// }
|
||||
|
||||
// pointerStart(ev: UIEvent): boolean {
|
||||
// console.debug('picker, pointerStart', ev.type, this.startY);
|
||||
// this._haptic.gestureSelectionStart();
|
||||
|
||||
// // We have to prevent default in order to block scrolling under the picker
|
||||
// // but we DO NOT have to stop propagation, since we still want
|
||||
// // some "click" events to capture
|
||||
// ev.preventDefault();
|
||||
|
||||
// // cancel any previous raf's that haven't fired yet
|
||||
// this._plt.cancelRaf(this.rafId);
|
||||
|
||||
// // remember where the pointer started from`
|
||||
// this.startY = pointerCoord(ev).y;
|
||||
|
||||
// // reset everything
|
||||
// this.velocity = 0;
|
||||
// this.pos.length = 0;
|
||||
// this.pos.push(this.startY, Date.now());
|
||||
|
||||
// let options = this.col.options;
|
||||
// let minY = (options.length - 1);
|
||||
// let maxY = 0;
|
||||
// for (var i = 0; i < options.length; i++) {
|
||||
// if (!options[i].disabled) {
|
||||
// minY = Math.min(minY, i);
|
||||
// maxY = Math.max(maxY, i);
|
||||
// }
|
||||
// }
|
||||
|
||||
// this.minY = (minY * this.optHeight * -1);
|
||||
// this.maxY = (maxY * this.optHeight * -1);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// pointerMove(ev: UIEvent) {
|
||||
// ev.preventDefault();
|
||||
// ev.stopPropagation();
|
||||
|
||||
// let currentY = pointerCoord(ev).y;
|
||||
// this.pos.push(currentY, Date.now());
|
||||
|
||||
// this.debouncer.write(() => {
|
||||
// if (this.startY === null) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // update the scroll position relative to pointer start position
|
||||
// let y = this.y + (currentY - this.startY);
|
||||
|
||||
// if (y > this.minY) {
|
||||
// // scrolling up higher than scroll area
|
||||
// y = Math.pow(y, 0.8);
|
||||
// this.bounceFrom = y;
|
||||
|
||||
// } else if (y < this.maxY) {
|
||||
// // scrolling down below scroll area
|
||||
// y += Math.pow(this.maxY - y, 0.9);
|
||||
// this.bounceFrom = y;
|
||||
|
||||
// } else {
|
||||
// this.bounceFrom = 0;
|
||||
// }
|
||||
|
||||
// this.update(y, 0, false, false);
|
||||
|
||||
// let 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
|
||||
// this._haptic.gestureSelectionChanged();
|
||||
// this.lastTempIndex = currentIndex;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// pointerEnd(ev: UIEvent) {
|
||||
// ev.preventDefault();
|
||||
// this.debouncer.cancel();
|
||||
|
||||
// if (this.startY === null) {
|
||||
// return;
|
||||
// }
|
||||
// console.debug('picker, pointerEnd', ev.type);
|
||||
|
||||
// this.velocity = 0;
|
||||
|
||||
// if (this.bounceFrom > 0) {
|
||||
// // bounce back up
|
||||
// this.update(this.minY, 100, true, true);
|
||||
// return;
|
||||
// } else if (this.bounceFrom < 0) {
|
||||
// // bounce back down
|
||||
// this.update(this.maxY, 100, true, true);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// let endY = pointerCoord(ev).y;
|
||||
|
||||
// this.pos.push(endY, Date.now());
|
||||
|
||||
// let endPos = (this.pos.length - 1);
|
||||
// let startPos = endPos;
|
||||
// let timeRange = (Date.now() - 100);
|
||||
|
||||
// // move pointer to position measured 100ms ago
|
||||
// for (var i = endPos; i > 0 && this.pos[i] > timeRange; i -= 2) {
|
||||
// startPos = i;
|
||||
// }
|
||||
|
||||
// if (startPos !== endPos) {
|
||||
// // compute relative movement between these two points
|
||||
// var timeOffset = (this.pos[endPos] - this.pos[startPos]);
|
||||
// var movedTop = (this.pos[startPos - 1] - this.pos[endPos - 1]);
|
||||
|
||||
// // based on XXms compute the movement to apply for each render step
|
||||
// var velocity = ((movedTop / timeOffset) * FRAME_MS);
|
||||
// this.velocity = clamp(-MAX_PICKER_SPEED, velocity, MAX_PICKER_SPEED);
|
||||
// }
|
||||
|
||||
// if (Math.abs(endY - this.startY) > 3) {
|
||||
// var y = this.y + (endY - this.startY);
|
||||
// this.update(y, 0, true, true);
|
||||
// }
|
||||
|
||||
// this.startY = null;
|
||||
// this.decelerate();
|
||||
// }
|
||||
|
||||
// decelerate() {
|
||||
// let y = 0;
|
||||
|
||||
// if (isNaN(this.y) || !this.optHeight) {
|
||||
// // fallback in case numbers get outta wack
|
||||
// this.update(y, 0, true, true);
|
||||
// this._haptic.gestureSelectionEnd();
|
||||
|
||||
// } else if (Math.abs(this.velocity) > 0) {
|
||||
// // still decelerating
|
||||
// this.velocity *= DECELERATION_FRICTION;
|
||||
|
||||
// // do not let it go slower than a velocity of 1
|
||||
// this.velocity = (this.velocity > 0)
|
||||
// ? Math.max(this.velocity, 1)
|
||||
// : Math.min(this.velocity, -1);
|
||||
|
||||
// y = Math.round(this.y - this.velocity);
|
||||
|
||||
// if (y > this.minY) {
|
||||
// // whoops, it's trying to scroll up farther than the options we have!
|
||||
// y = this.minY;
|
||||
// this.velocity = 0;
|
||||
|
||||
// } else if (y < this.maxY) {
|
||||
// // gahh, it's trying to scroll down farther than we can!
|
||||
// y = this.maxY;
|
||||
// this.velocity = 0;
|
||||
// }
|
||||
|
||||
// var notLockedIn = (y % this.optHeight !== 0 || Math.abs(this.velocity) > 1);
|
||||
|
||||
// this.update(y, 0, true, !notLockedIn);
|
||||
|
||||
|
||||
// if (notLockedIn) {
|
||||
// // isn't locked in yet, keep decelerating until it is
|
||||
// this.rafId = this._plt.raf(this.decelerateFunc);
|
||||
// }
|
||||
|
||||
// } else if (this.y % this.optHeight !== 0) {
|
||||
// // needs to still get locked into a position so options line up
|
||||
// var currentPos = Math.abs(this.y % this.optHeight);
|
||||
|
||||
// // create a velocity in the direction it needs to scroll
|
||||
// this.velocity = (currentPos > (this.optHeight / 2) ? 1 : -1);
|
||||
// this._haptic.gestureSelectionEnd();
|
||||
|
||||
// this.decelerate();
|
||||
// }
|
||||
|
||||
// let 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
|
||||
// this._haptic.gestureSelectionChanged();
|
||||
// }
|
||||
// this.lastTempIndex = currentIndex;
|
||||
// }
|
||||
|
||||
|
||||
// refresh() {
|
||||
// let min = this.col.options.length - 1;
|
||||
// let max = 0;
|
||||
// const options = this.col.options;
|
||||
// for (var i = 0; i < options.length; i++) {
|
||||
// if (!options[i].disabled) {
|
||||
// min = Math.min(min, i);
|
||||
// max = Math.max(max, i);
|
||||
// }
|
||||
// }
|
||||
|
||||
// const selectedIndex = clamp(min, this.col.selectedIndex, max);
|
||||
// if (this.col.prevSelected !== selectedIndex) {
|
||||
// var y = (selectedIndex * this.optHeight) * -1;
|
||||
// this._plt.cancelRaf(this.rafId);
|
||||
// this.velocity = 0;
|
||||
// this.update(y, 150, true, false);
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
219
packages/core/src/components/picker/picker.ios.scss
Normal file
219
packages/core/src/components/picker/picker.ios.scss
Normal file
@ -0,0 +1,219 @@
|
||||
@import "../../themes/ionic.globals.ios";
|
||||
@import "./picker";
|
||||
|
||||
|
||||
// iOS Picker
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Height of the picker wrapper
|
||||
$picker-ios-height: 260px !default;
|
||||
|
||||
/// @prop - Border color of the picker wrapper
|
||||
$picker-ios-border-color: $list-ios-border-color !default;
|
||||
|
||||
/// @prop - Background of the picker wrapper
|
||||
$picker-ios-background-color: $list-ios-background-color !default;
|
||||
|
||||
/// @prop - Height of the picker toolbar
|
||||
$picker-ios-toolbar-height: 44px !default;
|
||||
|
||||
/// @prop - Background color of the picker toolbar
|
||||
$picker-ios-toolbar-background-color: $picker-ios-background-color !default;
|
||||
|
||||
/// @prop - Height of the picker button
|
||||
$picker-ios-button-height: $picker-ios-toolbar-height !default;
|
||||
|
||||
/// @prop - Text color of the picker button
|
||||
$picker-ios-button-text-color: color($colors-ios, primary) !default;
|
||||
|
||||
/// @prop - Background of the picker button
|
||||
$picker-ios-button-background-color: transparent !default;
|
||||
|
||||
/// @prop - Font size of the picker button
|
||||
$picker-ios-button-font-size: 1.6rem !default;
|
||||
|
||||
/// @prop - Padding top of the picker button
|
||||
$picker-ios-button-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker button
|
||||
$picker-ios-button-padding-end: 1em !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker button
|
||||
$picker-ios-button-padding-bottom: $picker-ios-button-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker button
|
||||
$picker-ios-button-padding-start: $picker-ios-button-padding-end !default;
|
||||
|
||||
/// @prop - Font weight of the strong picker button
|
||||
$picker-ios-button-strong-font-weight: 600 !default;
|
||||
|
||||
/// @prop - Padding top of the picker column
|
||||
$picker-ios-column-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker column
|
||||
$picker-ios-column-padding-end: 4px !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker column
|
||||
$picker-ios-column-padding-bottom: $picker-ios-column-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker column
|
||||
$picker-ios-column-padding-start: $picker-ios-column-padding-end !default;
|
||||
|
||||
/// @prop - Perspective of the picker column
|
||||
$picker-ios-column-perspective: 1000px !default;
|
||||
|
||||
/// @prop - Padding top of the picker option
|
||||
$picker-ios-option-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker option
|
||||
$picker-ios-option-padding-end: $picker-ios-option-padding-top !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker option
|
||||
$picker-ios-option-padding-bottom: $picker-ios-option-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker option
|
||||
$picker-ios-option-padding-start: $picker-ios-option-padding-end !default;
|
||||
|
||||
/// @prop - Text color of the picker option
|
||||
$picker-ios-option-text-color: $list-ios-text-color !default;
|
||||
|
||||
/// @prop - Font size of the picker option
|
||||
$picker-ios-option-font-size: 20px !default;
|
||||
|
||||
/// @prop - Height of the picker option
|
||||
$picker-ios-option-height: 42px !default;
|
||||
|
||||
/// @prop - Offset y of the picker option
|
||||
$picker-ios-option-offset-y: (($picker-ios-height - $picker-ios-toolbar-height) / 2) - ($picker-ios-option-height / 2) - 10 !default;
|
||||
|
||||
|
||||
.picker-ios .picker-wrapper {
|
||||
height: $picker-ios-height;
|
||||
|
||||
border-top: 1px solid $picker-ios-border-color;
|
||||
|
||||
background: $picker-ios-background-color;
|
||||
}
|
||||
|
||||
.picker-ios .picker-toolbar {
|
||||
display: flex;
|
||||
|
||||
height: $picker-ios-toolbar-height;
|
||||
|
||||
border-bottom: $hairlines-width solid $picker-ios-border-color;
|
||||
|
||||
background: $picker-ios-toolbar-background-color;
|
||||
}
|
||||
|
||||
.picker-ios .picker-toolbar-button {
|
||||
@include text-align(end);
|
||||
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.picker-ios .picker-toolbar-button:last-child .picker-button {
|
||||
font-weight: $picker-ios-button-strong-font-weight;
|
||||
}
|
||||
|
||||
.picker-ios .picker-toolbar-cancel {
|
||||
@include text-align(start);
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.picker-ios .picker-button,
|
||||
.picker-ios .picker-button.activated {
|
||||
@include margin(0);
|
||||
@include padding($picker-ios-button-padding-top, $picker-ios-button-padding-end, $picker-ios-button-padding-bottom, $picker-ios-button-padding-start);
|
||||
|
||||
height: $picker-ios-button-height;
|
||||
|
||||
color: $picker-ios-button-text-color;
|
||||
background: $picker-ios-button-background-color;
|
||||
|
||||
font-size: $picker-ios-button-font-size;
|
||||
}
|
||||
|
||||
.picker-columns {
|
||||
height: $picker-ios-height - $picker-ios-toolbar-height - 1;
|
||||
|
||||
perspective: $picker-ios-column-perspective;
|
||||
}
|
||||
|
||||
.picker-ios .picker-col {
|
||||
@include padding($picker-ios-column-padding-top, $picker-ios-column-padding-end, $picker-ios-column-padding-bottom, $picker-ios-column-padding-start);
|
||||
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.picker-ios .picker-prefix,
|
||||
.picker-ios .picker-suffix,
|
||||
.picker-ios .picker-opts {
|
||||
top: $picker-ios-option-offset-y;
|
||||
|
||||
font-size: $picker-ios-option-font-size;
|
||||
line-height: $picker-ios-option-height;
|
||||
color: $picker-ios-option-text-color;
|
||||
|
||||
transform-style: preserve-3d;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.picker-ios .picker-opt {
|
||||
@include margin(0);
|
||||
@include transform-origin(center, center);
|
||||
|
||||
height: 4.6rem;
|
||||
|
||||
font-size: $picker-ios-option-font-size;
|
||||
line-height: $picker-ios-option-height;
|
||||
color: $picker-ios-option-text-color;
|
||||
|
||||
background: transparent;
|
||||
transform-style: preserve-3d;
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
backface-visibility: hidden;
|
||||
|
||||
pointer-events: auto;
|
||||
|
||||
@include padding($picker-ios-option-padding-top, $picker-ios-option-padding-end, $picker-ios-option-padding-bottom, $picker-ios-option-padding-start);
|
||||
}
|
||||
|
||||
.picker-ios .picker-above-highlight {
|
||||
@include position(0, null, null, 0);
|
||||
@include transform(translate3d(0, 0, 90px));
|
||||
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: $picker-ios-option-offset-y + 4px;
|
||||
|
||||
border-bottom: 1px solid $picker-ios-border-color;
|
||||
|
||||
background: linear-gradient(to bottom,
|
||||
rgba($picker-ios-background-color, 1) 20%,
|
||||
rgba($picker-ios-background-color, .7) 100%);
|
||||
}
|
||||
|
||||
.picker-ios .picker-below-highlight {
|
||||
@include position($picker-ios-option-offset-y + $picker-ios-option-height - 4, null, null, 0);
|
||||
@include transform(translate3d(0, 0, 90px));
|
||||
|
||||
position: absolute;
|
||||
|
||||
z-index: 11;
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: $picker-ios-option-offset-y + $picker-ios-option-height;
|
||||
|
||||
border-top: 1px solid $picker-ios-border-color;
|
||||
|
||||
background: linear-gradient(to top,
|
||||
rgba($picker-ios-background-color, 1) 30%,
|
||||
rgba($picker-ios-background-color, .7) 100%);
|
||||
}
|
||||
195
packages/core/src/components/picker/picker.md.scss
Normal file
195
packages/core/src/components/picker/picker.md.scss
Normal file
@ -0,0 +1,195 @@
|
||||
@import "../../themes/ionic.globals.md";
|
||||
@import "./picker";
|
||||
|
||||
|
||||
// Material Design Picker
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Height of the picker wrapper
|
||||
$picker-md-height: 260px !default;
|
||||
|
||||
/// @prop - Border color of the picker wrapper
|
||||
$picker-md-border-color: $list-md-border-color !default;
|
||||
|
||||
/// @prop - Background of the picker wrapper
|
||||
$picker-md-background-color: $list-md-background-color !default;
|
||||
|
||||
/// @prop - Height of the picker toolbar
|
||||
$picker-md-toolbar-height: 44px !default;
|
||||
|
||||
/// @prop - Background of the picker toolbar
|
||||
$picker-md-toolbar-background-color: $picker-md-background-color !default;
|
||||
|
||||
/// @prop - Height of the picker button
|
||||
$picker-md-button-height: $picker-md-toolbar-height !default;
|
||||
|
||||
/// @prop - Text color of the picker button
|
||||
$picker-md-button-text-color: color($colors-md, primary) !default;
|
||||
|
||||
/// @prop - Background of the picker button
|
||||
$picker-md-button-background-color: transparent !default;
|
||||
|
||||
/// @prop - Font size of the picker button
|
||||
$picker-md-button-font-size: 1.4rem !default;
|
||||
|
||||
/// @prop - Padding top of the picker column
|
||||
$picker-md-column-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker column
|
||||
$picker-md-column-padding-end: 8px !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker column
|
||||
$picker-md-column-padding-bottom: $picker-md-column-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker column
|
||||
$picker-md-column-padding-start: $picker-md-column-padding-end !default;
|
||||
|
||||
/// @prop - Padding top of the picker option
|
||||
$picker-md-option-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker option
|
||||
$picker-md-option-padding-end: $picker-md-option-padding-top !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker option
|
||||
$picker-md-option-padding-bottom: $picker-md-option-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker option
|
||||
$picker-md-option-padding-start: $picker-md-option-padding-end !default;
|
||||
|
||||
/// @prop - Text color of the picker option
|
||||
$picker-md-option-text-color: $list-md-text-color !default;
|
||||
|
||||
/// @prop - Font size of the picker option
|
||||
$picker-md-option-font-size: 22px !default;
|
||||
|
||||
/// @prop - Height of the picker option
|
||||
$picker-md-option-height: 42px !default;
|
||||
|
||||
/// @prop - Offset y of the picker option
|
||||
$picker-md-option-offset-y: (($picker-md-height - $picker-md-toolbar-height) / 2) - ($picker-md-option-height / 2) - 10 !default;
|
||||
|
||||
/// @prop - Text color of the selected picker option
|
||||
$picker-md-option-selected-color: color($colors-md, primary) !default;
|
||||
|
||||
|
||||
.picker-md .picker-wrapper {
|
||||
height: $picker-md-height;
|
||||
|
||||
border-top: $hairlines-width solid $picker-md-border-color;
|
||||
|
||||
background: $picker-md-background-color;
|
||||
}
|
||||
|
||||
.picker-md .picker-toolbar {
|
||||
display: flex;
|
||||
|
||||
justify-content: flex-end;
|
||||
|
||||
height: $picker-md-toolbar-height;
|
||||
|
||||
background: $picker-md-toolbar-background-color;
|
||||
}
|
||||
|
||||
.picker-md .picker-button,
|
||||
.picker-md .picker-button.activated {
|
||||
@include margin(0);
|
||||
|
||||
height: $picker-md-button-height;
|
||||
|
||||
color: $picker-md-button-text-color;
|
||||
background: $picker-md-button-background-color;
|
||||
|
||||
font-size: $picker-md-button-font-size;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
padding: 0 1.1em;
|
||||
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.picker-md .picker-columns {
|
||||
height: $picker-md-height - $picker-md-toolbar-height;
|
||||
|
||||
perspective: 1800px;
|
||||
}
|
||||
|
||||
.picker-md .picker-col {
|
||||
@include padding($picker-md-column-padding-top, $picker-md-column-padding-end, $picker-md-column-padding-bottom, $picker-md-column-padding-start);
|
||||
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.picker-md .picker-prefix,
|
||||
.picker-md .picker-suffix,
|
||||
.picker-md .picker-opts {
|
||||
top: $picker-md-option-offset-y;
|
||||
|
||||
font-size: $picker-md-option-font-size;
|
||||
line-height: $picker-md-option-height;
|
||||
color: $picker-md-option-text-color;
|
||||
|
||||
transform-style: preserve-3d;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.picker-md .picker-opt {
|
||||
@include margin(0);
|
||||
@include padding($picker-md-option-padding-top, $picker-md-option-padding-end, $picker-md-option-padding-bottom, $picker-md-option-padding-start);
|
||||
|
||||
height: 4.3rem;
|
||||
|
||||
font-size: $picker-md-option-font-size;
|
||||
line-height: $picker-md-option-height;
|
||||
color: $picker-md-option-text-color;
|
||||
|
||||
background: transparent;
|
||||
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
backface-visibility: hidden;
|
||||
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.picker-md .picker-prefix,
|
||||
.picker-md .picker-suffix,
|
||||
.picker-md .picker-opt.picker-opt-selected {
|
||||
|
||||
color: $picker-md-option-selected-color;
|
||||
}
|
||||
|
||||
.picker-md .picker-above-highlight {
|
||||
@include position(0, null, null, 0);
|
||||
@include transform(translate3d(0, 0, 90px));
|
||||
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
|
||||
width: 100%;
|
||||
height: $picker-md-option-offset-y + 4px;
|
||||
|
||||
border-bottom: 1px solid $picker-md-border-color;
|
||||
|
||||
background: linear-gradient(to bottom,
|
||||
rgba($picker-md-background-color, 1) 20%,
|
||||
rgba($picker-md-background-color, .7) 100%);
|
||||
}
|
||||
|
||||
.picker-md .picker-below-highlight {
|
||||
@include position($picker-md-option-offset-y + $picker-md-option-height - 4, null, null, 0);
|
||||
@include transform(translate3d(0, 0, 90px));
|
||||
|
||||
position: absolute;
|
||||
z-index: 11;
|
||||
|
||||
width: 100%;
|
||||
height: $picker-md-option-offset-y + $picker-md-option-height;
|
||||
|
||||
border-top: 1px solid $picker-md-border-color;
|
||||
|
||||
background: linear-gradient(to top,
|
||||
rgba($picker-md-background-color, 1) 30%,
|
||||
rgba($picker-md-background-color, .7) 100%);
|
||||
}
|
||||
169
packages/core/src/components/picker/picker.scss
Normal file
169
packages/core/src/components/picker/picker.scss
Normal file
@ -0,0 +1,169 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
// Picker
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Width of the picker
|
||||
$picker-width: 100% !default;
|
||||
|
||||
/// @prop - Max width of the picker
|
||||
$picker-max-width: 500px !default;
|
||||
|
||||
|
||||
ion-picker {
|
||||
@include position(0, null, null, 0);
|
||||
|
||||
position: absolute;
|
||||
z-index: $z-index-overlay;
|
||||
display: block;
|
||||
|
||||
width: $picker-width;
|
||||
height: $picker-width;
|
||||
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.picker-toolbar {
|
||||
z-index: 1;
|
||||
|
||||
width: 100%;
|
||||
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.picker-wrapper {
|
||||
@include position(null, 0, 0, 0);
|
||||
@include margin(auto);
|
||||
@include transform(translate3d(0, 100%, 0));
|
||||
|
||||
position: absolute;
|
||||
z-index: $z-index-overlay-wrapper;
|
||||
display: flex;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
flex-direction: column;
|
||||
|
||||
width: $picker-width;
|
||||
max-width: $picker-max-width;
|
||||
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.picker-columns {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
justify-content: center;
|
||||
|
||||
contain: strict;
|
||||
|
||||
@include rtl() {
|
||||
// Date is the same format in both directions
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
|
||||
.picker-col {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
|
||||
height: 100%;
|
||||
|
||||
box-sizing: content-box;
|
||||
|
||||
contain: content;
|
||||
}
|
||||
|
||||
.picker-opts {
|
||||
position: relative;
|
||||
|
||||
flex: 1;
|
||||
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.picker-prefix {
|
||||
@include text-align(end);
|
||||
|
||||
position: relative;
|
||||
|
||||
flex: 2;
|
||||
|
||||
min-width: 45%;
|
||||
max-width: 50%;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.picker-suffix {
|
||||
@include text-align(start);
|
||||
|
||||
position: relative;
|
||||
|
||||
flex: 2;
|
||||
|
||||
min-width: 45%;
|
||||
max-width: 50%;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// contain property is supported by Chrome
|
||||
.picker-opt {
|
||||
@include position(0, null, null, 0);
|
||||
@include text-align(center);
|
||||
|
||||
position: absolute;
|
||||
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
||||
width: 100%;
|
||||
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
will-change: transform;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.picker-opt.picker-opt-disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.picker-opt-disabled {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.picker-opts-left {
|
||||
@include ltr() {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@include rtl() {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.picker-opts-right {
|
||||
@include ltr() {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@include rtl() {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.picker-above-highlight,
|
||||
.picker-below-highlight {
|
||||
display: none;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
603
packages/core/src/components/picker/picker.tsx
Normal file
603
packages/core/src/components/picker/picker.tsx
Normal file
@ -0,0 +1,603 @@
|
||||
import { Animation, AnimationBuilder, AnimationController, Config } from '../../index';
|
||||
import { Component, CssClassMap, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
|
||||
|
||||
import iOSEnterAnimation from './animations/ios.enter';
|
||||
import iOSLeaveAnimation from './animations/ios.leave';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-picker',
|
||||
styleUrls: {
|
||||
ios: 'picker.ios.scss',
|
||||
md: 'picker.md.scss',
|
||||
wp: 'picker.wp.scss'
|
||||
},
|
||||
host: {
|
||||
theme: 'picker'
|
||||
}
|
||||
})
|
||||
export class Picker {
|
||||
private animation: Animation;
|
||||
private durationTimeout: any;
|
||||
private mode: string;
|
||||
|
||||
@Element() private el: HTMLElement;
|
||||
|
||||
@Event() private ionPickerDidLoad: EventEmitter;
|
||||
@Event() private ionPickerDidPresent: EventEmitter;
|
||||
@Event() private ionPickerWillPresent: EventEmitter;
|
||||
@Event() private ionPickerWillDismiss: EventEmitter;
|
||||
@Event() private ionPickerDidDismiss: EventEmitter;
|
||||
@Event() private ionPickerDidUnload: EventEmitter;
|
||||
|
||||
@State() private showSpinner: boolean = null;
|
||||
@State() private spinner: string;
|
||||
|
||||
@Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController;
|
||||
@Prop({ context: 'config' }) config: Config;
|
||||
@Prop() cssClass: string;
|
||||
@Prop() content: string;
|
||||
@Prop() dismissOnPageChange: boolean = false;
|
||||
@Prop() duration: number;
|
||||
@Prop() enterAnimation: AnimationBuilder;
|
||||
@Prop() exitAnimation: AnimationBuilder;
|
||||
@Prop() id: string;
|
||||
@Prop() showBackdrop: boolean = true;
|
||||
@Prop() enableBackdropDismiss: boolean = true;
|
||||
|
||||
@Prop() buttons: PickerButton[] = [];
|
||||
@Prop() columns: PickerColumn[] = [];
|
||||
|
||||
present() {
|
||||
return new Promise<void>(resolve => {
|
||||
this._present(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
private _present(resolve: Function) {
|
||||
if (this.animation) {
|
||||
this.animation.destroy();
|
||||
this.animation = null;
|
||||
}
|
||||
|
||||
this.ionPickerWillPresent.emit({ picker: this });
|
||||
|
||||
// get the user's animation fn if one was provided
|
||||
let animationBuilder = this.enterAnimation;
|
||||
|
||||
if (!animationBuilder) {
|
||||
// user did not provide a custom animation fn
|
||||
// decide from the config which animation to use
|
||||
animationBuilder = iOSEnterAnimation;
|
||||
}
|
||||
|
||||
// build the animation and kick it off
|
||||
this.animationCtrl.create(animationBuilder, this.el).then(animation => {
|
||||
this.animation = animation;
|
||||
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionViewDidEnter();
|
||||
resolve();
|
||||
|
||||
}).play();
|
||||
});
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
clearTimeout(this.durationTimeout);
|
||||
|
||||
if (this.animation) {
|
||||
this.animation.destroy();
|
||||
this.animation = null;
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
this.ionPickerWillDismiss.emit({ picker: this });
|
||||
|
||||
// get the user's animation fn if one was provided
|
||||
let animationBuilder = this.exitAnimation;
|
||||
|
||||
if (!animationBuilder) {
|
||||
// user did not provide a custom animation fn
|
||||
// decide from the config which animation to use
|
||||
animationBuilder = iOSLeaveAnimation;
|
||||
}
|
||||
|
||||
// build the animation and kick it off
|
||||
this.animationCtrl.create(animationBuilder, this.el).then(animation => {
|
||||
this.animation = animation;
|
||||
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionPickerDidDismiss.emit({ picker: this });
|
||||
|
||||
Context.dom.write(() => {
|
||||
this.el.parentNode.removeChild(this.el);
|
||||
});
|
||||
|
||||
resolve();
|
||||
|
||||
}).play();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected ionViewDidUnload() {
|
||||
this.ionPickerDidUnload.emit({ picker: this });
|
||||
}
|
||||
|
||||
@Listen('ionDismiss')
|
||||
protected onDismiss(ev: UIEvent) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
protected ionViewDidLoad() {
|
||||
if (!this.spinner) {
|
||||
let defaultSpinner = 'lines';
|
||||
|
||||
if (this.mode === 'md') {
|
||||
defaultSpinner = 'crescent';
|
||||
} else if (this.mode === 'wp') {
|
||||
defaultSpinner = 'circles';
|
||||
}
|
||||
|
||||
this.spinner = this.config.get('pickerSpinner') || defaultSpinner;
|
||||
}
|
||||
|
||||
if (this.showSpinner === null || this.showSpinner === undefined) {
|
||||
this.showSpinner = !!(this.spinner && this.spinner !== 'hide');
|
||||
}
|
||||
this.ionPickerDidLoad.emit({ picker: this });
|
||||
}
|
||||
|
||||
protected ionViewDidEnter() {
|
||||
// blur the currently active element
|
||||
const activeElement: any = document.activeElement;
|
||||
activeElement && activeElement.blur && activeElement.blur();
|
||||
|
||||
// If there is a duration, dismiss after that amount of time
|
||||
if (typeof this.duration === 'number' && this.duration > 10) {
|
||||
this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
|
||||
}
|
||||
|
||||
this.ionPickerDidPresent.emit({ picker: this });
|
||||
}
|
||||
|
||||
btnClick(button: PickerButton) {
|
||||
// if (!this.enabled) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // keep the time of the most recent button click
|
||||
// this.lastClick = Date.now();
|
||||
|
||||
let shouldDismiss = true;
|
||||
|
||||
// if (button.handler) {
|
||||
// // a handler has been provided, execute it
|
||||
// // pass the handler the values from the inputs
|
||||
// if (button.handler(this.getSelected()) === false) {
|
||||
// // if the return value of the handler is false then do not dismiss
|
||||
// shouldDismiss = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (shouldDismiss) {
|
||||
this.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {PickerColumn} column Picker toolbar button
|
||||
*/
|
||||
@Method()
|
||||
addColumn(column: PickerColumn) {
|
||||
this.columns.push(column);
|
||||
}
|
||||
|
||||
@Method()
|
||||
getColumn(name: string): PickerColumn {
|
||||
return this.getColumns().find(column => column.name === name);
|
||||
}
|
||||
|
||||
@Method()
|
||||
getColumns(): PickerColumn[] {
|
||||
return this.columns;
|
||||
}
|
||||
|
||||
protected backdropClick() {
|
||||
// TODO this.enabled
|
||||
if (this.enableBackdropDismiss) {
|
||||
let cancelBtn = this.buttons.find(b => b.role === 'cancel');
|
||||
if (cancelBtn) {
|
||||
this.btnClick(cancelBtn);
|
||||
} else {
|
||||
this.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
let userCssClass = 'picker-content';
|
||||
if (this.cssClass) {
|
||||
userCssClass += ' ' + this.cssClass;
|
||||
}
|
||||
|
||||
let buttons = this.buttons
|
||||
.map(b => {
|
||||
if (typeof b === 'string') {
|
||||
b = { text: b };
|
||||
}
|
||||
if (!b.cssClass) {
|
||||
b.cssClass = '';
|
||||
}
|
||||
return b;
|
||||
})
|
||||
.filter(b => b !== null);
|
||||
|
||||
console.log('picker render, columns', this.columns);
|
||||
let columns = this.columns;
|
||||
|
||||
return [
|
||||
<ion-backdrop
|
||||
onClick={this.backdropClick.bind(this)}
|
||||
class={{
|
||||
'picker-backdrop': true,
|
||||
'hide-backdrop': !this.showBackdrop
|
||||
}}
|
||||
/>,
|
||||
<div class='picker-wrapper' role='dialog'>
|
||||
<div class='picker-toolbar'>
|
||||
{buttons.map(b =>
|
||||
<div class={this.buttonWrapperClass(b)}>
|
||||
<button onClick={() => this.btnClick(b)} class={this.buttonClass(b)}>
|
||||
{b.text}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div class="picker-columns">
|
||||
<div class="picker-above-highlight"></div>
|
||||
{columns.map(c =>
|
||||
<ion-picker-column col={c}></ion-picker-column>
|
||||
)}
|
||||
<div class="picker-below-highlight"></div>
|
||||
</div>
|
||||
</div>
|
||||
];
|
||||
}
|
||||
|
||||
buttonWrapperClass(button: PickerButton): CssClassMap {
|
||||
console.log('buttonWrapperClass', button);
|
||||
let buttonClass: string[] = !button.role
|
||||
? ['picker-toolbar-button']
|
||||
: [`picker-toolbar-button`, `picker-toolbar-${button.role}`];
|
||||
return buttonClass.reduce((prevValue: any, cssClass: any) => {
|
||||
prevValue[cssClass] = true;
|
||||
return prevValue;
|
||||
}, {});
|
||||
}
|
||||
|
||||
buttonClass(button: PickerButton): CssClassMap {
|
||||
let buttonClass: string[] = !button.cssClass
|
||||
? ['picker-button']
|
||||
: [`picker-button`, `${button.cssClass}`];
|
||||
return buttonClass.reduce((prevValue: any, cssClass: any) => {
|
||||
prevValue[cssClass] = true;
|
||||
return prevValue;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface PickerButton {
|
||||
text?: string;
|
||||
role?: string;
|
||||
cssClass?: string;
|
||||
handler?: (value: any) => boolean|void;
|
||||
}
|
||||
|
||||
export interface PickerOptions {
|
||||
buttons?: PickerButton[];
|
||||
columns?: PickerColumn[];
|
||||
cssClass?: string;
|
||||
enableBackdropDismiss?: boolean;
|
||||
}
|
||||
|
||||
export interface PickerColumn {
|
||||
name?: string;
|
||||
align?: string;
|
||||
selectedIndex?: number;
|
||||
prevSelected?: number;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
options?: PickerColumnOption[];
|
||||
cssClass?: string;
|
||||
columnWidth?: string;
|
||||
prefixWidth?: string;
|
||||
suffixWidth?: string;
|
||||
optionsWidth?: string;
|
||||
}
|
||||
|
||||
export interface PickerColumnOption {
|
||||
text?: string;
|
||||
value?: any;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export interface PickerEvent extends Event {
|
||||
detail: {
|
||||
picker: Picker;
|
||||
};
|
||||
}
|
||||
|
||||
export const PICKER_OPT_SELECTED = 'picker-opt-selected';
|
||||
export const DECELERATION_FRICTION = 0.97;
|
||||
export const FRAME_MS = (1000 / 60);
|
||||
export const MAX_PICKER_SPEED = 60;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// @Component({
|
||||
// selector: 'ion-picker-cmp',
|
||||
// template: `
|
||||
// <ion-backdrop (click)="bdClick()"></ion-backdrop>
|
||||
// <div class="picker-wrapper">
|
||||
// <div class="picker-toolbar">
|
||||
// <div *ngFor="let b of d.buttons" class="picker-toolbar-button" [ngClass]="b.cssRole">
|
||||
// <ion-button (click)="btnClick(b)" [ngClass]="b.cssClass" class="picker-button" clear>
|
||||
// {{b.text}}
|
||||
// </ion-button>
|
||||
// </div>
|
||||
// </div>
|
||||
// <div class="picker-columns">
|
||||
// <div class="picker-above-highlight"></div>
|
||||
// <div *ngFor="let c of d.columns" [col]="c" class="picker-col" (ionChange)="_colChange($event)"></div>
|
||||
// <div class="picker-below-highlight"></div>
|
||||
// </div>
|
||||
// </div>
|
||||
// `,
|
||||
// host: {
|
||||
// 'role': 'dialog'
|
||||
// },
|
||||
// encapsulation: ViewEncapsulation.None,
|
||||
// })
|
||||
// export class PickerCmp {
|
||||
|
||||
// @ViewChildren(PickerColumnCmp) _cols: QueryList<PickerColumnCmp>;
|
||||
// d: PickerOptions;
|
||||
// enabled: boolean;
|
||||
// lastClick: number;
|
||||
// id: number;
|
||||
// mode: string;
|
||||
// _gestureBlocker: BlockerDelegate;
|
||||
|
||||
// constructor(
|
||||
// private _viewCtrl: ViewController,
|
||||
// private _elementRef: ElementRef,
|
||||
// config: Config,
|
||||
// private _plt: Platform,
|
||||
// gestureCtrl: GestureController,
|
||||
// params: NavParams,
|
||||
// renderer: Renderer
|
||||
// ) {
|
||||
// this._gestureBlocker = gestureCtrl.createBlocker(BLOCK_ALL);
|
||||
// this.d = params.data;
|
||||
// this.mode = config.get('mode');
|
||||
// renderer.setElementClass(_elementRef.nativeElement, `picker-${this.mode}`, true);
|
||||
|
||||
// if (this.d.cssClass) {
|
||||
// this.d.cssClass.split(' ').forEach(cssClass => {
|
||||
// renderer.setElementClass(_elementRef.nativeElement, cssClass, true);
|
||||
// });
|
||||
// }
|
||||
|
||||
// this.id = (++pickerIds);
|
||||
// this.lastClick = 0;
|
||||
// }
|
||||
|
||||
// ionViewWillLoad() {
|
||||
// // normalize the data
|
||||
// let data = this.d;
|
||||
|
||||
// data.buttons = data.buttons.map(button => {
|
||||
// if (isString(button)) {
|
||||
// return { text: button };
|
||||
// }
|
||||
// });
|
||||
|
||||
// // 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;
|
||||
// });
|
||||
// }
|
||||
|
||||
// ionViewDidLoad() {
|
||||
// this.refresh();
|
||||
// }
|
||||
|
||||
// ionViewWillEnter() {
|
||||
// this._gestureBlocker.block();
|
||||
// }
|
||||
|
||||
// ionViewDidLeave() {
|
||||
// this._gestureBlocker.unblock();
|
||||
// }
|
||||
|
||||
// refresh() {
|
||||
// this._cols.forEach(column => column.refresh());
|
||||
// }
|
||||
|
||||
// _colChange(selectedOption: PickerColumnOption) {
|
||||
// // one of the columns has changed its selected index
|
||||
// var picker = <Picker>this._viewCtrl;
|
||||
// picker.ionChange.emit(this.getSelected());
|
||||
// }
|
||||
|
||||
// @HostListener('body:keyup', ['$event'])
|
||||
// _keyUp(ev: KeyboardEvent) {
|
||||
// if (this.enabled && this._viewCtrl.isLast()) {
|
||||
// if (ev.keyCode === KEY_ENTER) {
|
||||
// if (this.lastClick + 1000 < Date.now()) {
|
||||
// // do not fire this click if there recently was already a click
|
||||
// // this can happen when the button has focus and used the enter
|
||||
// // key to click the button. However, both the click handler and
|
||||
// // this keyup event will fire, so only allow one of them to go.
|
||||
// console.debug('picker, enter button');
|
||||
// let button = this.d.buttons[this.d.buttons.length - 1];
|
||||
// this.btnClick(button);
|
||||
// }
|
||||
|
||||
// } else if (ev.keyCode === KEY_ESCAPE) {
|
||||
// console.debug('picker, escape button');
|
||||
// this.bdClick();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// ionViewDidEnter() {
|
||||
// this._plt.focusOutActiveElement();
|
||||
|
||||
// let focusableEle = this._elementRef.nativeElement.querySelector('button');
|
||||
// if (focusableEle) {
|
||||
// focusableEle.focus();
|
||||
// }
|
||||
// this.enabled = true;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// dismiss(role: string): Promise<any> {
|
||||
// return this._viewCtrl.dismiss(this.getSelected(), role);
|
||||
// }
|
||||
|
||||
// getSelected(): any {
|
||||
// let selected: {[k: string]: any} = {};
|
||||
// this.d.columns.forEach((col, index) => {
|
||||
// let selectedColumn = col.options[col.selectedIndex];
|
||||
// selected[col.name] = {
|
||||
// text: selectedColumn ? selectedColumn.text : null,
|
||||
// value: selectedColumn ? selectedColumn.value : null,
|
||||
// columnIndex: index,
|
||||
// };
|
||||
// });
|
||||
// return selected;
|
||||
// }
|
||||
|
||||
// ngOnDestroy() {
|
||||
// assert(this._gestureBlocker.blocked === false, 'gesture blocker must be already unblocked');
|
||||
// this._gestureBlocker.destroy();
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
// let pickerIds = -1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// export class Picker extends ViewController {
|
||||
// private _app: App;
|
||||
|
||||
// @Output() ionChange: EventEmitter<any>;
|
||||
|
||||
// constructor(app: App, opts: PickerOptions = {}, config: Config) {
|
||||
// if (!opts) {
|
||||
// opts = {};
|
||||
// }
|
||||
// opts.columns = opts.columns || [];
|
||||
// opts.buttons = opts.buttons || [];
|
||||
// opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? Boolean(opts.enableBackdropDismiss) : true;
|
||||
|
||||
// super(PickerCmp, opts, null);
|
||||
// this._app = app;
|
||||
// this.isOverlay = true;
|
||||
|
||||
// this.ionChange = new EventEmitter<any>();
|
||||
|
||||
// config.setTransition('picker-slide-in', PickerSlideIn);
|
||||
// config.setTransition('picker-slide-out', PickerSlideOut);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// getTransitionName(direction: string) {
|
||||
// let key = (direction === 'back' ? 'pickerLeave' : 'pickerEnter');
|
||||
// return this._nav && this._nav.config.get(key);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @param {any} button Picker toolbar button
|
||||
// */
|
||||
// addButton(button: any) {
|
||||
// this.data.buttons.push(button);
|
||||
// }
|
||||
|
||||
|
||||
// refresh() {
|
||||
// assert(this._cmp, 'componentRef must be valid');
|
||||
// assert(this._cmp.instance.refresh, 'instance must implement refresh()');
|
||||
|
||||
// this._cmp && this._cmp.instance.refresh && this._cmp.instance.refresh();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @param {string} cssClass CSS class name to add to the picker's outer wrapper.
|
||||
// */
|
||||
// setCssClass(cssClass: string) {
|
||||
// this.data.cssClass = cssClass;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Present the picker instance.
|
||||
// *
|
||||
// * @param {NavOptions} [navOptions={}] Nav options to go with this transition.
|
||||
// * @returns {Promise} Returns a promise which is resolved when the transition has completed.
|
||||
// */
|
||||
// present(navOptions: NavOptions = {}) {
|
||||
// return this._app.present(this, navOptions);
|
||||
// }
|
||||
|
||||
// }
|
||||
201
packages/core/src/components/picker/picker.wp.scss
Normal file
201
packages/core/src/components/picker/picker.wp.scss
Normal file
@ -0,0 +1,201 @@
|
||||
@import "../../themes/ionic.globals.wp";
|
||||
@import "./picker";
|
||||
|
||||
|
||||
// Windows Picker
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Height of the picker wrapper
|
||||
$picker-wp-height: 260px !default;
|
||||
|
||||
/// @prop - Border color of the picker wrapper
|
||||
$picker-wp-border-color: $list-wp-border-color !default;
|
||||
|
||||
/// @prop - Background of the picker wrapper
|
||||
$picker-wp-background-color: $list-wp-background-color !default;
|
||||
|
||||
/// @prop - Height of the picker toolbar
|
||||
$picker-wp-toolbar-height: 44px !default;
|
||||
|
||||
/// @prop - Background of the picker toolbar
|
||||
$picker-wp-toolbar-background-color: $picker-wp-background-color !default;
|
||||
|
||||
/// @prop - Height of the picker button
|
||||
$picker-wp-button-height: $picker-wp-toolbar-height !default;
|
||||
|
||||
/// @prop - Text color of the picker button
|
||||
$picker-wp-button-text-color: color($colors-wp, primary) !default;
|
||||
|
||||
/// @prop - Background of the picker button
|
||||
$picker-wp-button-background-color: transparent !default;
|
||||
|
||||
/// @prop - Padding top of the picker column
|
||||
$picker-wp-column-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker column
|
||||
$picker-wp-column-padding-end: 4px !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker column
|
||||
$picker-wp-column-padding-bottom: $picker-wp-column-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker column
|
||||
$picker-wp-column-padding-start: $picker-wp-column-padding-end !default;
|
||||
|
||||
/// @prop - Padding top of the picker option
|
||||
$picker-wp-option-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the picker option
|
||||
$picker-wp-option-padding-end: $picker-wp-option-padding-top !default;
|
||||
|
||||
/// @prop - Padding bottom of the picker option
|
||||
$picker-wp-option-padding-bottom: $picker-wp-option-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the picker option
|
||||
$picker-wp-option-padding-start: $picker-wp-option-padding-end !default;
|
||||
|
||||
/// @prop - Text color of the picker option
|
||||
$picker-wp-option-text-color: $list-wp-text-color !default;
|
||||
|
||||
/// @prop - Font size of the picker option
|
||||
$picker-wp-option-font-size: 22px !default;
|
||||
|
||||
/// @prop - Height of the picker option
|
||||
$picker-wp-option-height: 42px !default;
|
||||
|
||||
/// @prop - Offset y of the picker option
|
||||
$picker-wp-option-offset-y: (($picker-wp-height - $picker-wp-toolbar-height) / 2) - ($picker-wp-option-height / 2) - 10 !default;
|
||||
|
||||
/// @prop - Text color of the selected picker option
|
||||
$picker-wp-option-selected-color: color($colors-wp, primary) !default;
|
||||
|
||||
|
||||
.picker-wp .picker-wrapper {
|
||||
height: $picker-wp-height;
|
||||
|
||||
border-top: $hairlines-width solid $picker-wp-border-color;
|
||||
|
||||
background: $picker-wp-background-color;
|
||||
}
|
||||
|
||||
.picker-wp .picker-toolbar {
|
||||
display: flex;
|
||||
|
||||
justify-content: flex-end;
|
||||
|
||||
height: $picker-wp-toolbar-height;
|
||||
|
||||
border-width: $hairlines-width;
|
||||
|
||||
background: $picker-wp-toolbar-background-color;
|
||||
}
|
||||
|
||||
.picker-wp .picker-toolbar-button {
|
||||
@include text-align(end);
|
||||
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.picker-wp .picker-toolbar-cancel {
|
||||
@include text-align(start);
|
||||
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.picker-wp .picker-button,
|
||||
.picker-wp .picker-button.activated {
|
||||
@include margin(0);
|
||||
|
||||
height: $picker-wp-button-height;
|
||||
|
||||
color: $picker-wp-button-text-color;
|
||||
background: $picker-wp-button-background-color;
|
||||
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.picker-wp .picker-columns {
|
||||
height: $picker-wp-height - $picker-wp-toolbar-height;
|
||||
|
||||
perspective: 1800px;
|
||||
}
|
||||
|
||||
.picker-wp .picker-col {
|
||||
@include padding($picker-wp-column-padding-top, $picker-wp-column-padding-end, $picker-wp-column-padding-bottom, $picker-wp-column-padding-start);
|
||||
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.picker-wp .picker-prefix,
|
||||
.picker-wp .picker-suffix,
|
||||
.picker-wp .picker-opts {
|
||||
top: $picker-wp-option-offset-y;
|
||||
|
||||
font-size: $picker-wp-option-font-size;
|
||||
line-height: $picker-wp-option-height;
|
||||
color: $picker-wp-option-text-color;
|
||||
|
||||
transform-style: preserve-3d;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.picker-wp .picker-opt {
|
||||
@include margin(0);
|
||||
@include padding($picker-wp-option-padding-top, $picker-wp-option-padding-end, $picker-wp-option-padding-bottom, $picker-wp-option-padding-start);
|
||||
|
||||
height: 4.2rem;
|
||||
|
||||
font-size: $picker-wp-option-font-size;
|
||||
line-height: $picker-wp-option-height;
|
||||
color: $picker-wp-option-text-color;
|
||||
|
||||
background: transparent;
|
||||
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
backface-visibility: hidden;
|
||||
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.picker-wp .picker-prefix,
|
||||
.picker-wp .picker-suffix,
|
||||
.picker-wp .picker-opt-selected {
|
||||
color: $picker-wp-option-selected-color;
|
||||
}
|
||||
|
||||
.picker-wp .picker-above-highlight {
|
||||
@include position(0, null, null, 0);
|
||||
@include transform(translate3d(0, 0, 90px));
|
||||
|
||||
position: absolute;
|
||||
|
||||
z-index: 10;
|
||||
|
||||
width: 100%;
|
||||
height: $picker-wp-option-offset-y + 4px;
|
||||
|
||||
border-bottom: 1px solid $picker-wp-border-color;
|
||||
|
||||
background: linear-gradient(to bottom,
|
||||
rgba($picker-wp-background-color, 1) 20%,
|
||||
rgba($picker-wp-background-color, .7) 100%);
|
||||
}
|
||||
|
||||
.picker-wp .picker-below-highlight {
|
||||
@include position($picker-wp-option-offset-y + $picker-wp-option-height - 4, null, null, 0);
|
||||
@include transform(translate3d(0, 0, 90px));
|
||||
|
||||
position: absolute;
|
||||
|
||||
z-index: 11;
|
||||
|
||||
width: 100%;
|
||||
height: $picker-wp-option-offset-y + $picker-wp-option-height;
|
||||
|
||||
border-top: 1px solid $picker-wp-border-color;
|
||||
|
||||
background: linear-gradient(to top,
|
||||
rgba($picker-wp-background-color, 1) 30%,
|
||||
rgba($picker-wp-background-color, .7) 100%);
|
||||
}
|
||||
9
packages/core/src/index.d.ts
vendored
9
packages/core/src/index.d.ts
vendored
@ -14,6 +14,9 @@ import { MenuController } from './components/menu/menu-controller';
|
||||
import { Modal, ModalOptions, ModalEvent } from './components/modal/modal';
|
||||
import { ModalController } from './components/modal-controller/modal-controller';
|
||||
|
||||
import { Picker, PickerButton, PickerColumn, PickerEvent, PickerOptions } from './components/picker/picker'
|
||||
import { PickerController } from './components/picker-controller/picker-controller'
|
||||
|
||||
import { Popover, PopoverEvent, PopoverOptions } from './components/popover/popover'
|
||||
import { PopoverController } from './components/popover-controller/popover-controller'
|
||||
|
||||
@ -82,6 +85,12 @@ export {
|
||||
ModalController,
|
||||
ModalOptions,
|
||||
ModalEvent,
|
||||
Picker,
|
||||
PickerButton,
|
||||
PickerColumn,
|
||||
PickerController,
|
||||
PickerEvent,
|
||||
PickerOptions,
|
||||
Popover,
|
||||
PopoverController,
|
||||
PopoverEvent,
|
||||
|
||||
Reference in New Issue
Block a user