1 |
|
2 |
|
3 |
|
4 | import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
|
5 | import { g as getElementRoot } from './helpers.js';
|
6 |
|
7 | const pickerInternalIosCss = ":host{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:200px;direction:ltr;z-index:0}:host .picker-before,:host .picker-after{position:absolute;width:100%;z-index:1;pointer-events:none}:host .picker-before{left:0;top:0;height:83px}:host-context([dir=rtl]){left:unset;right:unset;right:0}:host .picker-after{left:0;top:116px;height:84px}:host-context([dir=rtl]){left:unset;right:unset;right:0}:host .picker-highlight{border-radius:8px;left:0;right:0;top:50%;bottom:0;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;position:absolute;width:calc(100% - 16px);height:34px;-webkit-transform:translateY(-50%);transform:translateY(-50%);z-index:-1}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){:host .picker-highlight{margin-left:unset;margin-right:unset;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto}}:host input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host ::slotted(ion-picker-column-internal:first-of-type){text-align:start}:host ::slotted(ion-picker-column-internal:last-of-type){text-align:end}:host .picker-before{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%)}:host .picker-after{background:-webkit-gradient(linear, left bottom, left top, 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 top, var(--background, var(--ion-background-color, #fff)) 20%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8) 100%)}:host .picker-highlight{background:var(--ion-color-step-150, #eeeeef)}";
|
8 |
|
9 | const pickerInternalMdCss = ":host{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:200px;direction:ltr;z-index:0}:host .picker-before,:host .picker-after{position:absolute;width:100%;z-index:1;pointer-events:none}:host .picker-before{left:0;top:0;height:83px}:host-context([dir=rtl]){left:unset;right:unset;right:0}:host .picker-after{left:0;top:116px;height:84px}:host-context([dir=rtl]){left:unset;right:unset;right:0}:host .picker-highlight{border-radius:8px;left:0;right:0;top:50%;bottom:0;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;position:absolute;width:calc(100% - 16px);height:34px;-webkit-transform:translateY(-50%);transform:translateY(-50%);z-index:-1}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){:host .picker-highlight{margin-left:unset;margin-right:unset;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto}}:host input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host ::slotted(ion-picker-column-internal:first-of-type){text-align:start}:host ::slotted(ion-picker-column-internal:last-of-type){text-align:end}:host .picker-before{background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, var(--background, var(--ion-background-color, #fff))), color-stop(90%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0)));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) 90%)}:host .picker-after{background:-webkit-gradient(linear, left bottom, left top, color-stop(30%, var(--background, var(--ion-background-color, #fff))), color-stop(90%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0)));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) 90%)}";
|
10 |
|
11 | const PickerInternal = proxyCustomElement(class extends HTMLElement {
|
12 | constructor() {
|
13 | super();
|
14 | this.__registerHost();
|
15 | this.__attachShadow();
|
16 | this.ionInputModeChange = createEvent(this, "ionInputModeChange", 7);
|
17 | this.useInputMode = false;
|
18 | this.isInHighlightBounds = (ev) => {
|
19 | const { highlightEl } = this;
|
20 | if (!highlightEl) {
|
21 | return false;
|
22 | }
|
23 | const bbox = highlightEl.getBoundingClientRect();
|
24 | |
25 |
|
26 |
|
27 |
|
28 | const outsideX = ev.clientX < bbox.left || ev.clientX > bbox.right;
|
29 | const outsideY = ev.clientY < bbox.top || ev.clientY > bbox.bottom;
|
30 | if (outsideX || outsideY) {
|
31 | return false;
|
32 | }
|
33 | return true;
|
34 | };
|
35 | |
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | this.onFocusOut = (ev) => {
|
43 | const { relatedTarget } = ev;
|
44 | if (!relatedTarget ||
|
45 | relatedTarget.tagName !== 'ION-PICKER-COLUMN-INTERNAL' && relatedTarget !== this.inputEl) {
|
46 | this.exitInputMode();
|
47 | }
|
48 | };
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 | this.onFocusIn = (ev) => {
|
55 | const { target } = ev;
|
56 | |
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | if (target.tagName !== 'ION-PICKER-COLUMN-INTERNAL') {
|
63 | return;
|
64 | }
|
65 | |
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | if (!this.actionOnClick) {
|
79 | const columnEl = target;
|
80 | const allowInput = columnEl.numericInput;
|
81 | if (allowInput) {
|
82 | this.enterInputMode(columnEl, false);
|
83 | }
|
84 | else {
|
85 | this.exitInputMode();
|
86 | }
|
87 | }
|
88 | };
|
89 | |
90 |
|
91 |
|
92 |
|
93 |
|
94 | this.onClick = () => {
|
95 | const { actionOnClick } = this;
|
96 | if (actionOnClick) {
|
97 | actionOnClick();
|
98 | this.actionOnClick = undefined;
|
99 | }
|
100 | };
|
101 | |
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | this.onPointerDown = (ev) => {
|
111 | const { useInputMode, inputModeColumn, el } = this;
|
112 | if (this.isInHighlightBounds(ev)) {
|
113 | |
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | if (useInputMode) {
|
121 | |
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | if (ev.target.tagName === 'ION-PICKER-COLUMN-INTERNAL') {
|
130 | |
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 | if (inputModeColumn && inputModeColumn === ev.target) {
|
137 | this.actionOnClick = () => {
|
138 | this.enterInputMode();
|
139 | };
|
140 | }
|
141 | else {
|
142 | this.actionOnClick = () => {
|
143 | this.enterInputMode(ev.target);
|
144 | };
|
145 | }
|
146 | }
|
147 | else {
|
148 | this.actionOnClick = () => {
|
149 | this.exitInputMode();
|
150 | };
|
151 | }
|
152 | |
153 |
|
154 |
|
155 |
|
156 |
|
157 | }
|
158 | else {
|
159 | |
160 |
|
161 |
|
162 |
|
163 | const columns = el.querySelectorAll('ion-picker-column-internal.picker-column-numeric-input');
|
164 | const columnEl = (columns.length === 1) ? ev.target : undefined;
|
165 | this.actionOnClick = () => {
|
166 | this.enterInputMode(columnEl);
|
167 | };
|
168 | }
|
169 | return;
|
170 | }
|
171 | this.actionOnClick = () => {
|
172 | this.exitInputMode();
|
173 | };
|
174 | };
|
175 | |
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | this.enterInputMode = (columnEl, focusInput = true) => {
|
189 | const { inputEl, el } = this;
|
190 | if (!inputEl) {
|
191 | return;
|
192 | }
|
193 | |
194 |
|
195 |
|
196 |
|
197 | const hasInputColumn = el.querySelector('ion-picker-column-internal.picker-column-numeric-input');
|
198 | if (!hasInputColumn) {
|
199 | return;
|
200 | }
|
201 | |
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 | this.useInputMode = true;
|
208 | this.inputModeColumn = columnEl;
|
209 | |
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | if (focusInput) {
|
217 | if (this.destroyKeypressListener) {
|
218 | this.destroyKeypressListener();
|
219 | this.destroyKeypressListener = undefined;
|
220 | }
|
221 | inputEl.focus();
|
222 | }
|
223 | else {
|
224 | el.addEventListener('keypress', this.onKeyPress);
|
225 | this.destroyKeypressListener = () => {
|
226 | el.removeEventListener('keypress', this.onKeyPress);
|
227 | };
|
228 | }
|
229 | this.emitInputModeChange();
|
230 | };
|
231 | this.exitInputMode = () => {
|
232 | const { inputEl, useInputMode } = this;
|
233 | if (!useInputMode || !inputEl) {
|
234 | return;
|
235 | }
|
236 | this.useInputMode = false;
|
237 | this.inputModeColumn = undefined;
|
238 | inputEl.blur();
|
239 | inputEl.value = '';
|
240 | if (this.destroyKeypressListener) {
|
241 | this.destroyKeypressListener();
|
242 | this.destroyKeypressListener = undefined;
|
243 | }
|
244 | this.emitInputModeChange();
|
245 | };
|
246 | this.onKeyPress = (ev) => {
|
247 | const { inputEl } = this;
|
248 | if (!inputEl) {
|
249 | return;
|
250 | }
|
251 | const parsedValue = parseInt(ev.key, 10);
|
252 | |
253 |
|
254 |
|
255 | if (!Number.isNaN(parsedValue)) {
|
256 | inputEl.value += ev.key;
|
257 | this.onInputChange();
|
258 | }
|
259 | };
|
260 | this.selectSingleColumn = () => {
|
261 | const { inputEl, inputModeColumn, singleColumnSearchTimeout } = this;
|
262 | if (!inputEl || !inputModeColumn) {
|
263 | return;
|
264 | }
|
265 | const values = inputModeColumn.items;
|
266 | |
267 |
|
268 |
|
269 |
|
270 |
|
271 |
|
272 | if (singleColumnSearchTimeout) {
|
273 | clearTimeout(singleColumnSearchTimeout);
|
274 | }
|
275 | this.singleColumnSearchTimeout = setTimeout(() => {
|
276 | inputEl.value = '';
|
277 | this.singleColumnSearchTimeout = undefined;
|
278 | }, 1000);
|
279 | |
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 | if (inputEl.value.length >= 3) {
|
288 | const startIndex = inputEl.value.length - 2;
|
289 | const newString = inputEl.value.substring(startIndex);
|
290 | inputEl.value = newString;
|
291 | this.selectSingleColumn();
|
292 | return;
|
293 | }
|
294 | |
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 | const findItemFromCompleteValue = values.find(({ text }) => text.replace(/^0+/, '') === inputEl.value);
|
303 | if (findItemFromCompleteValue) {
|
304 | inputModeColumn.value = findItemFromCompleteValue.value;
|
305 | return;
|
306 | }
|
307 | |
308 |
|
309 |
|
310 |
|
311 | if (inputEl.value.length === 2) {
|
312 | const changedCharacter = inputEl.value.substring(inputEl.value.length - 1);
|
313 | inputEl.value = changedCharacter;
|
314 | this.selectSingleColumn();
|
315 | }
|
316 | };
|
317 | |
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 | this.searchColumn = (colEl, value, zeroBehavior = 'start') => {
|
324 | let item;
|
325 | const behavior = zeroBehavior === 'start' ? /^0+/ : /0$/;
|
326 | item = colEl.items.find(({ text }) => text.replace(behavior, '') === value);
|
327 | if (item) {
|
328 | colEl.value = item.value;
|
329 | }
|
330 | };
|
331 | this.selectMultiColumn = () => {
|
332 | const { inputEl, el } = this;
|
333 | if (!inputEl) {
|
334 | return;
|
335 | }
|
336 | const numericPickers = Array.from(el.querySelectorAll('ion-picker-column-internal')).filter(col => col.numericInput);
|
337 | const firstColumn = numericPickers[0];
|
338 | const lastColumn = numericPickers[1];
|
339 | let value = inputEl.value;
|
340 | let minuteValue;
|
341 | switch (value.length) {
|
342 | case 1:
|
343 | this.searchColumn(firstColumn, value);
|
344 | break;
|
345 | case 2:
|
346 | |
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 | const firstCharacter = inputEl.value.substring(0, 1);
|
353 | value = (firstCharacter === '0' || firstCharacter === '1') ? inputEl.value : firstCharacter;
|
354 | this.searchColumn(firstColumn, value);
|
355 | |
356 |
|
357 |
|
358 |
|
359 |
|
360 | if (value.length === 1) {
|
361 | minuteValue = inputEl.value.substring(inputEl.value.length - 1);
|
362 | this.searchColumn(lastColumn, minuteValue, 'end');
|
363 | }
|
364 | break;
|
365 | case 3:
|
366 | |
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 | const firstCharacterAgain = inputEl.value.substring(0, 1);
|
373 | value = (firstCharacterAgain === '0' || firstCharacterAgain === '1') ? inputEl.value.substring(0, 2) : firstCharacterAgain;
|
374 | this.searchColumn(firstColumn, value);
|
375 | |
376 |
|
377 |
|
378 |
|
379 |
|
380 | minuteValue = (value.length === 1) ? inputEl.value.substring(1) : inputEl.value.substring(2);
|
381 | this.searchColumn(lastColumn, minuteValue, 'end');
|
382 | break;
|
383 | case 4:
|
384 | |
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 | const firstCharacterAgainAgain = inputEl.value.substring(0, 1);
|
391 | value = (firstCharacterAgainAgain === '0' || firstCharacterAgainAgain === '1') ? inputEl.value.substring(0, 2) : firstCharacterAgainAgain;
|
392 | this.searchColumn(firstColumn, value);
|
393 | |
394 |
|
395 |
|
396 |
|
397 |
|
398 | const minuteValueAgain = (value.length === 1) ? inputEl.value.substring(1, inputEl.value.length) : inputEl.value.substring(2, inputEl.value.length);
|
399 | this.searchColumn(lastColumn, minuteValueAgain, 'end');
|
400 | break;
|
401 | default:
|
402 | const startIndex = inputEl.value.length - 4;
|
403 | const newString = inputEl.value.substring(startIndex);
|
404 | inputEl.value = newString;
|
405 | this.selectMultiColumn();
|
406 | break;
|
407 | }
|
408 | };
|
409 | |
410 |
|
411 |
|
412 |
|
413 |
|
414 | this.onInputChange = () => {
|
415 | const { useInputMode, inputEl, inputModeColumn } = this;
|
416 | if (!useInputMode || !inputEl) {
|
417 | return;
|
418 | }
|
419 | if (inputModeColumn) {
|
420 | this.selectSingleColumn();
|
421 | }
|
422 | else {
|
423 | this.selectMultiColumn();
|
424 | }
|
425 | };
|
426 | |
427 |
|
428 |
|
429 |
|
430 |
|
431 | this.emitInputModeChange = () => {
|
432 | const { useInputMode, inputModeColumn } = this;
|
433 | this.ionInputModeChange.emit({
|
434 | useInputMode,
|
435 | inputModeColumn
|
436 | });
|
437 | };
|
438 | }
|
439 | componentWillLoad() {
|
440 | getElementRoot(this.el).addEventListener('focusin', this.onFocusIn);
|
441 | getElementRoot(this.el).addEventListener('focusout', this.onFocusOut);
|
442 | }
|
443 | render() {
|
444 | return (h(Host, { onPointerDown: (ev) => this.onPointerDown(ev), onClick: () => this.onClick() }, h("input", { "aria-hidden": "true", tabindex: -1, inputmode: "numeric", type: "number", ref: el => this.inputEl = el, onInput: () => this.onInputChange(), onBlur: () => this.exitInputMode() }), h("div", { class: "picker-before" }), h("div", { class: "picker-after" }), h("div", { class: "picker-highlight", ref: el => this.highlightEl = el }), h("slot", null)));
|
445 | }
|
446 | get el() { return this; }
|
447 | static get style() { return {
|
448 | ios: pickerInternalIosCss,
|
449 | md: pickerInternalMdCss
|
450 | }; }
|
451 | }, [33, "ion-picker-internal"]);
|
452 | function defineCustomElement() {
|
453 | if (typeof customElements === "undefined") {
|
454 | return;
|
455 | }
|
456 | const components = ["ion-picker-internal"];
|
457 | components.forEach(tagName => { switch (tagName) {
|
458 | case "ion-picker-internal":
|
459 | if (!customElements.get(tagName)) {
|
460 | customElements.define(tagName, PickerInternal);
|
461 | }
|
462 | break;
|
463 | } });
|
464 | }
|
465 |
|
466 | export { PickerInternal as P, defineCustomElement as d };
|