UNPKG

19.4 kBJavaScriptView Raw
1/*!
2 * (C) Ionic http://ionicframework.com - MIT License
3 */
4import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
5import { b as getIonMode } from './ionic-global.js';
6import { B as BACKDROP, i as isCancel, e as prepareOverlay, d as present, f as dismiss, g as eventMethod, s as safeCall } from './overlays.js';
7import { g as getClassMap } from './theme.js';
8import { c as createAnimation } from './animation.js';
9import { d as defineCustomElement$3 } from './backdrop.js';
10import { d as defineCustomElement$2 } from './picker-column.js';
11
12/**
13 * iOS Picker Enter Animation
14 */
15const iosEnterAnimation = (baseEl) => {
16 const baseAnimation = createAnimation();
17 const backdropAnimation = createAnimation();
18 const wrapperAnimation = createAnimation();
19 backdropAnimation
20 .addElement(baseEl.querySelector('ion-backdrop'))
21 .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
22 .beforeStyles({
23 'pointer-events': 'none'
24 })
25 .afterClearStyles(['pointer-events']);
26 wrapperAnimation
27 .addElement(baseEl.querySelector('.picker-wrapper'))
28 .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
29 return baseAnimation
30 .addElement(baseEl)
31 .easing('cubic-bezier(.36,.66,.04,1)')
32 .duration(400)
33 .addAnimation([backdropAnimation, wrapperAnimation]);
34};
35
36/**
37 * iOS Picker Leave Animation
38 */
39const iosLeaveAnimation = (baseEl) => {
40 const baseAnimation = createAnimation();
41 const backdropAnimation = createAnimation();
42 const wrapperAnimation = createAnimation();
43 backdropAnimation
44 .addElement(baseEl.querySelector('ion-backdrop'))
45 .fromTo('opacity', 'var(--backdrop-opacity)', 0.01);
46 wrapperAnimation
47 .addElement(baseEl.querySelector('.picker-wrapper'))
48 .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
49 return baseAnimation
50 .addElement(baseEl)
51 .easing('cubic-bezier(.36,.66,.04,1)')
52 .duration(400)
53 .addAnimation([backdropAnimation, wrapperAnimation]);
54};
55
56const pickerIosCss = ".sc-ion-picker-ios-h{--border-radius:0;--border-style:solid;--min-width:auto;--width:100%;--max-width:500px;--min-height:auto;--max-height:auto;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}[dir=rtl].sc-ion-picker-ios-h,[dir=rtl] .sc-ion-picker-ios-h{left:unset;right:unset;right:0}.overlay-hidden.sc-ion-picker-ios-h{display:none}.picker-wrapper.sc-ion-picker-ios{border-radius:var(--border-radius);left:0;right:0;bottom:0;margin-left:auto;margin-right:auto;margin-top:auto;margin-bottom:auto;-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);contain:strict;overflow:hidden;z-index:10}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){.picker-wrapper.sc-ion-picker-ios{margin-left:unset;margin-right:unset;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto}}.picker-toolbar.sc-ion-picker-ios{width:100%;background:transparent;contain:strict;z-index:1}.picker-button.sc-ion-picker-ios{border:0;font-family:inherit}.picker-button.sc-ion-picker-ios:active,.picker-button.sc-ion-picker-ios:focus{outline:none}.picker-columns.sc-ion-picker-ios{display:-ms-flexbox;display:flex;position:relative;-ms-flex-pack:center;justify-content:center;margin-bottom:var(--ion-safe-area-bottom, 0);contain:strict;direction:ltr;overflow:hidden}.picker-above-highlight.sc-ion-picker-ios,.picker-below-highlight.sc-ion-picker-ios{display:none;pointer-events:none}.sc-ion-picker-ios-h{--background:var(--ion-background-color, #fff);--border-width:1px 0 0;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, #c8c7cc)));--height:260px;--backdrop-opacity:var(--ion-backdrop-opacity, 0.26);color:var(--ion-item-color, var(--ion-text-color, #000))}.picker-toolbar.sc-ion-picker-ios{display:-ms-flexbox;display:flex;height:44px;border-bottom:0.55px solid var(--border-color)}.picker-toolbar-button.sc-ion-picker-ios{-ms-flex:1;flex:1;text-align:end}.picker-toolbar-button.sc-ion-picker-ios:last-child .picker-button.sc-ion-picker-ios{font-weight:600}.picker-toolbar-button.sc-ion-picker-ios:first-child{font-weight:normal;text-align:start}.picker-button.sc-ion-picker-ios,.picker-button.ion-activated.sc-ion-picker-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:1em;padding-right:1em;padding-top:0;padding-bottom:0;height:44px;background:transparent;color:var(--ion-color-primary, #3880ff);font-size:16px}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){.picker-button.sc-ion-picker-ios,.picker-button.ion-activated.sc-ion-picker-ios{padding-left:unset;padding-right:unset;-webkit-padding-start:1em;padding-inline-start:1em;-webkit-padding-end:1em;padding-inline-end:1em}}.picker-columns.sc-ion-picker-ios{height:215px;-webkit-perspective:1000px;perspective:1000px}.picker-above-highlight.sc-ion-picker-ios{left:0;top:0;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);display:block;position:absolute;width:100%;height:81px;border-bottom:1px solid var(--border-color);background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, var(--background, var(--ion-background-color, #fff))), to(rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8)));background:linear-gradient(to bottom, var(--background, var(--ion-background-color, #fff)) 20%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8) 100%);z-index:10}[dir=rtl].sc-ion-picker-ios .picker-above-highlight.sc-ion-picker-ios,[dir=rtl].sc-ion-picker-ios-h .picker-above-highlight.sc-ion-picker-ios,[dir=rtl] .sc-ion-picker-ios-h .picker-above-highlight.sc-ion-picker-ios{left:unset;right:unset;right:0}.picker-below-highlight.sc-ion-picker-ios{left:0;top:115px;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);display:block;position:absolute;width:100%;height:119px;border-top:1px solid var(--border-color);background:-webkit-gradient(linear, left bottom, left top, color-stop(30%, var(--background, var(--ion-background-color, #fff))), to(rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8)));background:linear-gradient(to top, var(--background, var(--ion-background-color, #fff)) 30%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8) 100%);z-index:11}[dir=rtl].sc-ion-picker-ios .picker-below-highlight.sc-ion-picker-ios,[dir=rtl].sc-ion-picker-ios-h .picker-below-highlight.sc-ion-picker-ios,[dir=rtl] .sc-ion-picker-ios-h .picker-below-highlight.sc-ion-picker-ios{left:unset;right:unset;right:0}";
57
58const pickerMdCss = ".sc-ion-picker-md-h{--border-radius:0;--border-style:solid;--min-width:auto;--width:100%;--max-width:500px;--min-height:auto;--max-height:auto;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}[dir=rtl].sc-ion-picker-md-h,[dir=rtl] .sc-ion-picker-md-h{left:unset;right:unset;right:0}.overlay-hidden.sc-ion-picker-md-h{display:none}.picker-wrapper.sc-ion-picker-md{border-radius:var(--border-radius);left:0;right:0;bottom:0;margin-left:auto;margin-right:auto;margin-top:auto;margin-bottom:auto;-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);contain:strict;overflow:hidden;z-index:10}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){.picker-wrapper.sc-ion-picker-md{margin-left:unset;margin-right:unset;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto}}.picker-toolbar.sc-ion-picker-md{width:100%;background:transparent;contain:strict;z-index:1}.picker-button.sc-ion-picker-md{border:0;font-family:inherit}.picker-button.sc-ion-picker-md:active,.picker-button.sc-ion-picker-md:focus{outline:none}.picker-columns.sc-ion-picker-md{display:-ms-flexbox;display:flex;position:relative;-ms-flex-pack:center;justify-content:center;margin-bottom:var(--ion-safe-area-bottom, 0);contain:strict;direction:ltr;overflow:hidden}.picker-above-highlight.sc-ion-picker-md,.picker-below-highlight.sc-ion-picker-md{display:none;pointer-events:none}.sc-ion-picker-md-h{--background:var(--ion-background-color, #fff);--border-width:0.55px 0 0;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, 0.13))));--height:260px;--backdrop-opacity:var(--ion-backdrop-opacity, 0.26);color:var(--ion-item-color, var(--ion-text-color, #000))}.picker-toolbar.sc-ion-picker-md{display:-ms-flexbox;display:flex;-ms-flex-pack:end;justify-content:flex-end;height:44px}.picker-button.sc-ion-picker-md,.picker-button.ion-activated.sc-ion-picker-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:1.1em;padding-right:1.1em;padding-top:0;padding-bottom:0;height:44px;background:transparent;color:var(--ion-color-primary, #3880ff);font-size:14px;font-weight:500;text-transform:uppercase;-webkit-box-shadow:none;box-shadow:none}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){.picker-button.sc-ion-picker-md,.picker-button.ion-activated.sc-ion-picker-md{padding-left:unset;padding-right:unset;-webkit-padding-start:1.1em;padding-inline-start:1.1em;-webkit-padding-end:1.1em;padding-inline-end:1.1em}}.picker-columns.sc-ion-picker-md{height:216px;-webkit-perspective:1800px;perspective:1800px}.picker-above-highlight.sc-ion-picker-md{left:0;top:0;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);position:absolute;width:100%;height:81px;border-bottom:1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, 0.13))));background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, var(--ion-background-color, #fff)), to(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8)));background:linear-gradient(to bottom, var(--ion-background-color, #fff) 20%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8) 100%);z-index:10}[dir=rtl].sc-ion-picker-md .picker-above-highlight.sc-ion-picker-md,[dir=rtl].sc-ion-picker-md-h .picker-above-highlight.sc-ion-picker-md,[dir=rtl] .sc-ion-picker-md-h .picker-above-highlight.sc-ion-picker-md{left:unset;right:unset;right:0}.picker-below-highlight.sc-ion-picker-md{left:0;top:115px;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);position:absolute;width:100%;height:119px;border-top:1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, 0.13))));background:-webkit-gradient(linear, left bottom, left top, color-stop(30%, var(--ion-background-color, #fff)), to(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8)));background:linear-gradient(to top, var(--ion-background-color, #fff) 30%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8) 100%);z-index:11}[dir=rtl].sc-ion-picker-md .picker-below-highlight.sc-ion-picker-md,[dir=rtl].sc-ion-picker-md-h .picker-below-highlight.sc-ion-picker-md,[dir=rtl] .sc-ion-picker-md-h .picker-below-highlight.sc-ion-picker-md{left:unset;right:unset;right:0}";
59
60const Picker = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
61 constructor() {
62 super();
63 this.__registerHost();
64 this.didPresent = createEvent(this, "ionPickerDidPresent", 7);
65 this.willPresent = createEvent(this, "ionPickerWillPresent", 7);
66 this.willDismiss = createEvent(this, "ionPickerWillDismiss", 7);
67 this.didDismiss = createEvent(this, "ionPickerDidDismiss", 7);
68 this.presented = false;
69 /**
70 * If `true`, the keyboard will be automatically dismissed when the overlay is presented.
71 */
72 this.keyboardClose = true;
73 /**
74 * Array of buttons to be displayed at the top of the picker.
75 */
76 this.buttons = [];
77 /**
78 * Array of columns to be displayed in the picker.
79 */
80 this.columns = [];
81 /**
82 * Number of milliseconds to wait before dismissing the picker.
83 */
84 this.duration = 0;
85 /**
86 * If `true`, a backdrop will be displayed behind the picker.
87 */
88 this.showBackdrop = true;
89 /**
90 * If `true`, the picker will be dismissed when the backdrop is clicked.
91 */
92 this.backdropDismiss = true;
93 /**
94 * If `true`, the picker will animate.
95 */
96 this.animated = true;
97 this.onBackdropTap = () => {
98 this.dismiss(undefined, BACKDROP);
99 };
100 this.dispatchCancelHandler = (ev) => {
101 const role = ev.detail.role;
102 if (isCancel(role)) {
103 const cancelButton = this.buttons.find(b => b.role === 'cancel');
104 this.callButtonHandler(cancelButton);
105 }
106 };
107 }
108 connectedCallback() {
109 prepareOverlay(this.el);
110 }
111 /**
112 * Present the picker overlay after it has been created.
113 */
114 async present() {
115 await present(this, 'pickerEnter', iosEnterAnimation, iosEnterAnimation, undefined);
116 if (this.duration > 0) {
117 this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
118 }
119 }
120 /**
121 * Dismiss the picker overlay after it has been presented.
122 *
123 * @param data Any data to emit in the dismiss events.
124 * @param role The role of the element that is dismissing the picker.
125 * This can be useful in a button handler for determining which button was
126 * clicked to dismiss the picker.
127 * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
128 */
129 dismiss(data, role) {
130 if (this.durationTimeout) {
131 clearTimeout(this.durationTimeout);
132 }
133 return dismiss(this, data, role, 'pickerLeave', iosLeaveAnimation, iosLeaveAnimation);
134 }
135 /**
136 * Returns a promise that resolves when the picker did dismiss.
137 */
138 onDidDismiss() {
139 return eventMethod(this.el, 'ionPickerDidDismiss');
140 }
141 /**
142 * Returns a promise that resolves when the picker will dismiss.
143 */
144 onWillDismiss() {
145 return eventMethod(this.el, 'ionPickerWillDismiss');
146 }
147 /**
148 * Get the column that matches the specified name.
149 *
150 * @param name The name of the column.
151 */
152 getColumn(name) {
153 return Promise.resolve(this.columns.find(column => column.name === name));
154 }
155 async buttonClick(button) {
156 const role = button.role;
157 if (isCancel(role)) {
158 return this.dismiss(undefined, role);
159 }
160 const shouldDismiss = await this.callButtonHandler(button);
161 if (shouldDismiss) {
162 return this.dismiss(this.getSelected(), button.role);
163 }
164 return Promise.resolve();
165 }
166 async callButtonHandler(button) {
167 if (button) {
168 // a handler has been provided, execute it
169 // pass the handler the values from the inputs
170 const rtn = await safeCall(button.handler, this.getSelected());
171 if (rtn === false) {
172 // if the return value of the handler is false then do not dismiss
173 return false;
174 }
175 }
176 return true;
177 }
178 getSelected() {
179 const selected = {};
180 this.columns.forEach((col, index) => {
181 const selectedColumn = col.selectedIndex !== undefined
182 ? col.options[col.selectedIndex]
183 : undefined;
184 selected[col.name] = {
185 text: selectedColumn ? selectedColumn.text : undefined,
186 value: selectedColumn ? selectedColumn.value : undefined,
187 columnIndex: index
188 };
189 });
190 return selected;
191 }
192 render() {
193 const { htmlAttributes } = this;
194 const mode = getIonMode(this);
195 return (h(Host, Object.assign({ "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
196 zIndex: `${20000 + this.overlayIndex}`
197 }, class: Object.assign({ [mode]: true,
198 // Used internally for styling
199 [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { tabindex: "0" }), h("div", { class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, h("div", { class: "picker-toolbar" }, this.buttons.map(b => (h("div", { class: buttonWrapperClass(b) }, h("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass(b) }, b.text))))), h("div", { class: "picker-columns" }, h("div", { class: "picker-above-highlight" }), this.presented && this.columns.map(c => h("ion-picker-column", { col: c })), h("div", { class: "picker-below-highlight" }))), h("div", { tabindex: "0" })));
200 }
201 get el() { return this; }
202 static get style() { return {
203 ios: pickerIosCss,
204 md: pickerMdCss
205 }; }
206}, [34, "ion-picker", {
207 "overlayIndex": [2, "overlay-index"],
208 "keyboardClose": [4, "keyboard-close"],
209 "enterAnimation": [16],
210 "leaveAnimation": [16],
211 "buttons": [16],
212 "columns": [16],
213 "cssClass": [1, "css-class"],
214 "duration": [2],
215 "showBackdrop": [4, "show-backdrop"],
216 "backdropDismiss": [4, "backdrop-dismiss"],
217 "animated": [4],
218 "htmlAttributes": [16],
219 "presented": [32],
220 "present": [64],
221 "dismiss": [64],
222 "onDidDismiss": [64],
223 "onWillDismiss": [64],
224 "getColumn": [64]
225 }]);
226const buttonWrapperClass = (button) => {
227 return {
228 [`picker-toolbar-${button.role}`]: button.role !== undefined,
229 'picker-toolbar-button': true
230 };
231};
232const buttonClass = (button) => {
233 return Object.assign({ 'picker-button': true, 'ion-activatable': true }, getClassMap(button.cssClass));
234};
235function defineCustomElement$1() {
236 if (typeof customElements === "undefined") {
237 return;
238 }
239 const components = ["ion-picker", "ion-backdrop", "ion-picker-column"];
240 components.forEach(tagName => { switch (tagName) {
241 case "ion-picker":
242 if (!customElements.get(tagName)) {
243 customElements.define(tagName, Picker);
244 }
245 break;
246 case "ion-backdrop":
247 if (!customElements.get(tagName)) {
248 defineCustomElement$3();
249 }
250 break;
251 case "ion-picker-column":
252 if (!customElements.get(tagName)) {
253 defineCustomElement$2();
254 }
255 break;
256 } });
257}
258
259const IonPicker = Picker;
260const defineCustomElement = defineCustomElement$1;
261
262export { IonPicker, defineCustomElement };