@ionic/core 8.5.8-dev.11748374591.17686118 → 8.5.8-dev.11748388365.11ad9dfe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/button.js +23 -5
- package/components/ion-datetime.js +27 -51
- package/components/ion-input-password-toggle.js +2 -2
- package/components/ion-searchbar.js +4 -4
- package/components/modal.js +159 -68
- package/components/picker-column2.js +3 -3
- package/css/core.css +1 -1
- package/css/core.css.map +1 -1
- package/css/ionic.bundle.css +1 -1
- package/css/ionic.bundle.css.map +1 -1
- package/dist/cjs/ion-button_2.cjs.entry.js +19 -3
- package/dist/cjs/ion-datetime_3.cjs.entry.js +30 -54
- package/dist/cjs/ion-input-password-toggle.cjs.entry.js +2 -2
- package/dist/cjs/ion-modal.cjs.entry.js +159 -68
- package/dist/cjs/ion-searchbar.cjs.entry.js +4 -4
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/button/button.js +23 -3
- package/dist/collection/components/datetime/datetime.js +27 -51
- package/dist/collection/components/input-password-toggle/input-password-toggle.js +2 -2
- package/dist/collection/components/modal/animations/ios.enter.js +41 -1
- package/dist/collection/components/modal/animations/ios.leave.js +24 -2
- package/dist/collection/components/modal/animations/md.enter.js +41 -1
- package/dist/collection/components/modal/animations/md.leave.js +24 -2
- package/dist/collection/components/modal/gestures/sheet.js +29 -62
- package/dist/collection/components/picker-legacy-column/picker-column.js +3 -3
- package/dist/collection/components/searchbar/searchbar.js +5 -5
- package/dist/docs.json +2 -2
- package/dist/esm/ion-button_2.entry.js +20 -4
- package/dist/esm/ion-datetime_3.entry.js +30 -54
- package/dist/esm/ion-input-password-toggle.entry.js +2 -2
- package/dist/esm/ion-modal.entry.js +159 -68
- package/dist/esm/ion-searchbar.entry.js +4 -4
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm-es5/ion-button_2.entry.js +1 -1
- package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
- package/dist/esm-es5/ion-input-password-toggle.entry.js +1 -1
- package/dist/esm-es5/ion-modal.entry.js +1 -1
- package/dist/esm-es5/ion-searchbar.entry.js +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/html.html-data.json +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-12914457.entry.js +4 -0
- package/dist/ionic/{p-50cb2e8b.system.entry.js → p-3cee5d7c.system.entry.js} +2 -2
- package/dist/ionic/p-3d2b2787.system.entry.js +4 -0
- package/dist/ionic/{p-7611ede3.system.entry.js → p-3ec227cd.system.entry.js} +1 -1
- package/dist/ionic/p-4090ce24.entry.js +4 -0
- package/dist/ionic/p-8b8b4530.system.entry.js +4 -0
- package/dist/ionic/p-94a18d00.entry.js +4 -0
- package/dist/ionic/p-cec902a0.system.entry.js +4 -0
- package/dist/ionic/{p-891553d8.entry.js → p-e7f732ef.entry.js} +1 -1
- package/dist/ionic/p-f725bf9e.system.js +2 -2
- package/dist/ionic/{p-a835aca8.entry.js → p-ffa2125f.entry.js} +1 -1
- package/dist/types/components/button/button.d.ts +11 -0
- package/dist/types/components/searchbar/searchbar.d.ts +1 -1
- package/dist/types/components.d.ts +2 -2
- package/hydrate/index.js +213 -131
- package/hydrate/index.mjs +213 -131
- package/package.json +2 -2
- package/dist/ionic/p-57957c0f.entry.js +0 -4
- package/dist/ionic/p-6b8530f5.system.entry.js +0 -4
- package/dist/ionic/p-b5432d15.entry.js +0 -4
- package/dist/ionic/p-b7242f55.entry.js +0 -4
- package/dist/ionic/p-c1b7d311.system.entry.js +0 -4
- package/dist/ionic/p-db06d822.system.entry.js +0 -4
|
@@ -210,6 +210,20 @@ const Button = class {
|
|
|
210
210
|
this.formButtonEl.disabled = disabled;
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* This component is used within the `ion-input-password-toggle` component
|
|
215
|
+
* to toggle the visibility of the password input.
|
|
216
|
+
* These attributes need to update based on the state of the password input.
|
|
217
|
+
* Otherwise, the values will be stale.
|
|
218
|
+
*
|
|
219
|
+
* @param newValue
|
|
220
|
+
* @param _oldValue
|
|
221
|
+
* @param propName
|
|
222
|
+
*/
|
|
223
|
+
onAriaChanged(newValue, _oldValue, propName) {
|
|
224
|
+
this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [propName]: newValue });
|
|
225
|
+
index.forceUpdate(this);
|
|
226
|
+
}
|
|
213
227
|
/**
|
|
214
228
|
* This is responsible for rendering a hidden native
|
|
215
229
|
* button element inside the associated form. This allows
|
|
@@ -347,7 +361,7 @@ const Button = class {
|
|
|
347
361
|
{
|
|
348
362
|
type !== 'button' && this.renderHiddenButton();
|
|
349
363
|
}
|
|
350
|
-
return (index.h(index.Host, { key: '
|
|
364
|
+
return (index.h(index.Host, { key: 'b105ad09215adb3ca2298acdadf0dc9154bbb9b0', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: theme.createColorClasses(color, {
|
|
351
365
|
[mode]: true,
|
|
352
366
|
[buttonType]: true,
|
|
353
367
|
[`${buttonType}-${expand}`]: expand !== undefined,
|
|
@@ -362,11 +376,13 @@ const Button = class {
|
|
|
362
376
|
'button-disabled': disabled,
|
|
363
377
|
'ion-activatable': true,
|
|
364
378
|
'ion-focusable': true,
|
|
365
|
-
}) }, index.h(TagType, Object.assign({ key: '
|
|
379
|
+
}) }, index.h(TagType, Object.assign({ key: '66b4e7112bcb9e41d5a723fbbadb0a3104f9ee1d' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), index.h("span", { key: '1439fc3da280221028dcf7ce8ec9dab273c4d4bb', class: "button-inner" }, index.h("slot", { key: 'd5269ae1afc87ec7b99746032f59cbae93720a9f', name: "icon-only", onSlotchange: this.slotChanged }), index.h("slot", { key: '461c83e97aa246aa86d83e14f1e15a288d35041e', name: "start" }), index.h("slot", { key: '807170d47101f9f6a333dd4ff489c89284f306fe' }), index.h("slot", { key: 'e67f116dd0349a0d27893e4f3ff0ccef1d402f80', name: "end" })), mode === 'md' && index.h("ion-ripple-effect", { key: '273f0bd9645a36c1bfd18a5c2ab4f81e22b7b989', type: this.rippleType }))));
|
|
366
380
|
}
|
|
367
381
|
get el() { return index.getElement(this); }
|
|
368
382
|
static get watchers() { return {
|
|
369
|
-
"disabled": ["disabledChanged"]
|
|
383
|
+
"disabled": ["disabledChanged"],
|
|
384
|
+
"aria-checked": ["onAriaChanged"],
|
|
385
|
+
"aria-label": ["onAriaChanged"]
|
|
370
386
|
}; }
|
|
371
387
|
};
|
|
372
388
|
Button.style = {
|
|
@@ -687,19 +687,18 @@ const Datetime = class {
|
|
|
687
687
|
data.warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
|
|
688
688
|
}
|
|
689
689
|
/**
|
|
690
|
-
* If there are multiple values,
|
|
691
|
-
*
|
|
692
|
-
*
|
|
690
|
+
* If there are multiple values, clamp to the last one.
|
|
691
|
+
* This is because the last value is the one that the user
|
|
692
|
+
* has most recently interacted with.
|
|
693
693
|
*/
|
|
694
|
-
const singleValue = Array.isArray(valueToProcess) ? valueToProcess[
|
|
694
|
+
const singleValue = Array.isArray(valueToProcess) ? valueToProcess[valueToProcess.length - 1] : valueToProcess;
|
|
695
695
|
const targetValue = data.clampDate(singleValue, minParts, maxParts);
|
|
696
696
|
const { month, day, year, hour, minute } = targetValue;
|
|
697
697
|
const ampm = data.parseAmPm(hour);
|
|
698
698
|
/**
|
|
699
|
-
* Since `activeParts` indicates a value that
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
* if the `value` property is set.
|
|
699
|
+
* Since `activeParts` indicates a value that been explicitly selected
|
|
700
|
+
* either by the user or the app, only update `activeParts` if the
|
|
701
|
+
* `value` property is set.
|
|
703
702
|
*/
|
|
704
703
|
if (hasValue) {
|
|
705
704
|
if (Array.isArray(valueToProcess)) {
|
|
@@ -724,51 +723,28 @@ const Datetime = class {
|
|
|
724
723
|
*/
|
|
725
724
|
this.activeParts = [];
|
|
726
725
|
}
|
|
727
|
-
/**
|
|
728
|
-
* Only animate if:
|
|
729
|
-
* 1. We're using grid style (wheel style pickers should just jump to new value)
|
|
730
|
-
* 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
|
|
731
|
-
* 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
|
|
732
|
-
* 4. The month/year picker is not open (since you wouldn't see the animation anyway)
|
|
733
|
-
*/
|
|
734
726
|
const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
|
|
735
727
|
const bodyIsVisible = el.classList.contains('datetime-ready');
|
|
736
728
|
const { isGridStyle, showMonthAndYear } = this;
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
729
|
+
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
|
|
730
|
+
/**
|
|
731
|
+
* Only animate if:
|
|
732
|
+
* 1. We're using grid style (wheel style pickers should just jump to new value)
|
|
733
|
+
* 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
|
|
734
|
+
* 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
|
|
735
|
+
* 4. The month/year picker is not open (since you wouldn't see the animation anyway)
|
|
736
|
+
*/
|
|
737
|
+
this.animateToDate(targetValue);
|
|
746
738
|
}
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
this.animateToDate(targetValue);
|
|
757
|
-
}
|
|
758
|
-
else {
|
|
759
|
-
/**
|
|
760
|
-
* We only need to do this if we didn't just animate to a new month,
|
|
761
|
-
* since that calls prevMonth/nextMonth which calls setWorkingParts for us.
|
|
762
|
-
*/
|
|
763
|
-
this.setWorkingParts({
|
|
764
|
-
month,
|
|
765
|
-
day,
|
|
766
|
-
year,
|
|
767
|
-
hour,
|
|
768
|
-
minute,
|
|
769
|
-
ampm,
|
|
770
|
-
});
|
|
771
|
-
}
|
|
739
|
+
else {
|
|
740
|
+
this.setWorkingParts({
|
|
741
|
+
month,
|
|
742
|
+
day,
|
|
743
|
+
year,
|
|
744
|
+
hour,
|
|
745
|
+
minute,
|
|
746
|
+
ampm,
|
|
747
|
+
});
|
|
772
748
|
}
|
|
773
749
|
};
|
|
774
750
|
this.animateToDate = async (targetValue) => {
|
|
@@ -1763,7 +1739,7 @@ const Datetime = class {
|
|
|
1763
1739
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1764
1740
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1765
1741
|
helpers.renderHiddenInput(true, el, name, data.formatValue(value), disabled);
|
|
1766
|
-
return (index$1.h(index$1.Host, { key: '
|
|
1742
|
+
return (index$1.h(index$1.Host, { key: '20e64fb4cfe3fbd74b24038c89e00651d78b500c', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, theme.createColorClasses(color, {
|
|
1767
1743
|
[mode]: true,
|
|
1768
1744
|
['datetime-readonly']: readonly,
|
|
1769
1745
|
['datetime-disabled']: disabled,
|
|
@@ -1773,7 +1749,7 @@ const Datetime = class {
|
|
|
1773
1749
|
[`datetime-size-${size}`]: true,
|
|
1774
1750
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1775
1751
|
[`datetime-grid`]: isGridStyle,
|
|
1776
|
-
})) }, index$1.h("div", { key: '
|
|
1752
|
+
})) }, index$1.h("div", { key: '488fe7bf6b9052e208d65206a580d5d65b945a62', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1777
1753
|
}
|
|
1778
1754
|
get el() { return index$1.getElement(this); }
|
|
1779
1755
|
static get watchers() { return {
|
|
@@ -2383,7 +2359,7 @@ const PickerColumnCmp = class {
|
|
|
2383
2359
|
const colEl = this.optsEl;
|
|
2384
2360
|
if (colEl) {
|
|
2385
2361
|
// DOM READ
|
|
2386
|
-
// We perfom a DOM read over a rendered item, this needs to happen after the first render or after the
|
|
2362
|
+
// We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
|
|
2387
2363
|
this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
|
|
2388
2364
|
}
|
|
2389
2365
|
this.refresh(forceRefresh, animated);
|
|
@@ -2391,9 +2367,9 @@ const PickerColumnCmp = class {
|
|
|
2391
2367
|
render() {
|
|
2392
2368
|
const col = this.col;
|
|
2393
2369
|
const mode = ionicGlobal.getIonMode(this);
|
|
2394
|
-
return (index$1.h(index$1.Host, { key: '
|
|
2370
|
+
return (index$1.h(index$1.Host, { key: '10ef653cbae8e1ed92a23fa17f3396082e35951f', class: Object.assign({ [mode]: true, 'picker-col': true, 'picker-opts-left': this.col.align === 'left', 'picker-opts-right': this.col.align === 'right' }, theme.getClassMap(col.cssClass)), style: {
|
|
2395
2371
|
'max-width': this.col.columnWidth,
|
|
2396
|
-
} }, col.prefix && (index$1.h("div", { key: '
|
|
2372
|
+
} }, col.prefix && (index$1.h("div", { key: '253066708012034206b1d3d466ea48d0a3be3323', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), index$1.h("div", { key: '15fa07307d4d2b4994504a5bf2de8db05b51cd2c', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (index$1.h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (index$1.h("div", { key: '4db779830b1e6aa6b324e5a72541d4f610ac1ff5', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
|
|
2397
2373
|
}
|
|
2398
2374
|
get el() { return index$1.getElement(this); }
|
|
2399
2375
|
static get watchers() { return {
|
|
@@ -71,14 +71,14 @@ const InputPasswordToggle = class {
|
|
|
71
71
|
const isPasswordVisible = type === 'text';
|
|
72
72
|
return (index.h(index.Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: theme.createColorClasses(color, {
|
|
73
73
|
[mode]: true,
|
|
74
|
-
}) }, index.h("ion-button", { key: '
|
|
74
|
+
}) }, index.h("ion-button", { key: '61591d11d97f3065240e51d8887f831339fd36cf', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": isPasswordVisible ? 'Hide password' : 'Show password', role: "switch", type: "button", onPointerDown: (ev) => {
|
|
75
75
|
/**
|
|
76
76
|
* This prevents mobile browsers from
|
|
77
77
|
* blurring the input when the password toggle
|
|
78
78
|
* button is activated.
|
|
79
79
|
*/
|
|
80
80
|
ev.preventDefault();
|
|
81
|
-
}, onClick: this.togglePasswordVisibility }, index.h("ion-icon", { key: '
|
|
81
|
+
}, onClick: this.togglePasswordVisibility }, index.h("ion-icon", { key: '9d98e6675d5e2adea5c0f56ab67e98b6f57521dd', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
|
|
82
82
|
}
|
|
83
83
|
get el() { return index.getElement(this); }
|
|
84
84
|
static get watchers() { return {
|
|
@@ -588,7 +588,47 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
588
588
|
.addElement(baseEl)
|
|
589
589
|
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
590
590
|
.duration(500)
|
|
591
|
-
.addAnimation([wrapperAnimation])
|
|
591
|
+
.addAnimation([wrapperAnimation])
|
|
592
|
+
.beforeAddWrite(() => {
|
|
593
|
+
if (expandToScroll) {
|
|
594
|
+
// Scroll can only be done when the modal is fully expanded.
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* There are some browsers that causes flickering when
|
|
599
|
+
* dragging the content when scroll is enabled at every
|
|
600
|
+
* breakpoint. This is due to the wrapper element being
|
|
601
|
+
* transformed off the screen and having a snap animation.
|
|
602
|
+
*
|
|
603
|
+
* A workaround is to clone the footer element and append
|
|
604
|
+
* it outside of the wrapper element. This way, the footer
|
|
605
|
+
* is still visible and the drag can be done without
|
|
606
|
+
* flickering. The original footer is hidden until the modal
|
|
607
|
+
* is dismissed. This maintains the animation of the footer
|
|
608
|
+
* when the modal is dismissed.
|
|
609
|
+
*
|
|
610
|
+
* The workaround needs to be done before the animation starts
|
|
611
|
+
* so there are no flickering issues.
|
|
612
|
+
*/
|
|
613
|
+
const ionFooter = baseEl.querySelector('ion-footer');
|
|
614
|
+
/**
|
|
615
|
+
* This check is needed to prevent more than one footer
|
|
616
|
+
* from being appended to the shadow root.
|
|
617
|
+
* Otherwise, iOS and MD enter animations would append
|
|
618
|
+
* the footer twice.
|
|
619
|
+
*/
|
|
620
|
+
const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
|
|
621
|
+
if (ionFooter && !ionFooterAlreadyAppended) {
|
|
622
|
+
const footerHeight = ionFooter.clientHeight;
|
|
623
|
+
const clonedFooter = ionFooter.cloneNode(true);
|
|
624
|
+
baseEl.shadowRoot.appendChild(clonedFooter);
|
|
625
|
+
ionFooter.style.setProperty('display', 'none');
|
|
626
|
+
ionFooter.setAttribute('aria-hidden', 'true');
|
|
627
|
+
// Padding is added to prevent some content from being hidden.
|
|
628
|
+
const page = baseEl.querySelector('.ion-page');
|
|
629
|
+
page.style.setProperty('padding-bottom', `${footerHeight}px`);
|
|
630
|
+
}
|
|
631
|
+
});
|
|
592
632
|
if (contentAnimation) {
|
|
593
633
|
baseAnimation.addAnimation(contentAnimation);
|
|
594
634
|
}
|
|
@@ -669,7 +709,7 @@ const createLeaveAnimation$1 = () => {
|
|
|
669
709
|
* iOS Modal Leave Animation
|
|
670
710
|
*/
|
|
671
711
|
const iosLeaveAnimation = (baseEl, opts, duration = 500) => {
|
|
672
|
-
const { presentingEl, currentBreakpoint } = opts;
|
|
712
|
+
const { presentingEl, currentBreakpoint, expandToScroll } = opts;
|
|
673
713
|
const root = helpers.getElementRoot(baseEl);
|
|
674
714
|
const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation$1();
|
|
675
715
|
backdropAnimation.addElement(root.querySelector('ion-backdrop'));
|
|
@@ -678,7 +718,29 @@ const iosLeaveAnimation = (baseEl, opts, duration = 500) => {
|
|
|
678
718
|
.addElement(baseEl)
|
|
679
719
|
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
680
720
|
.duration(duration)
|
|
681
|
-
.addAnimation(wrapperAnimation)
|
|
721
|
+
.addAnimation(wrapperAnimation)
|
|
722
|
+
.beforeAddWrite(() => {
|
|
723
|
+
if (expandToScroll) {
|
|
724
|
+
// Scroll can only be done when the modal is fully expanded.
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* If expandToScroll is disabled, we need to swap
|
|
729
|
+
* the visibility to the original, so the footer
|
|
730
|
+
* dismisses with the modal and doesn't stay
|
|
731
|
+
* until the modal is removed from the DOM.
|
|
732
|
+
*/
|
|
733
|
+
const ionFooter = baseEl.querySelector('ion-footer');
|
|
734
|
+
if (ionFooter) {
|
|
735
|
+
const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
|
|
736
|
+
ionFooter.style.removeProperty('display');
|
|
737
|
+
ionFooter.removeAttribute('aria-hidden');
|
|
738
|
+
clonedFooter.style.setProperty('display', 'none');
|
|
739
|
+
clonedFooter.setAttribute('aria-hidden', 'true');
|
|
740
|
+
const page = baseEl.querySelector('.ion-page');
|
|
741
|
+
page.style.removeProperty('padding-bottom');
|
|
742
|
+
}
|
|
743
|
+
});
|
|
682
744
|
if (presentingEl) {
|
|
683
745
|
const isMobile = window.innerWidth < 768;
|
|
684
746
|
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
@@ -774,7 +836,47 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
774
836
|
.addElement(baseEl)
|
|
775
837
|
.easing('cubic-bezier(0.36,0.66,0.04,1)')
|
|
776
838
|
.duration(280)
|
|
777
|
-
.addAnimation([backdropAnimation, wrapperAnimation])
|
|
839
|
+
.addAnimation([backdropAnimation, wrapperAnimation])
|
|
840
|
+
.beforeAddWrite(() => {
|
|
841
|
+
if (expandToScroll) {
|
|
842
|
+
// Scroll can only be done when the modal is fully expanded.
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* There are some browsers that causes flickering when
|
|
847
|
+
* dragging the content when scroll is enabled at every
|
|
848
|
+
* breakpoint. This is due to the wrapper element being
|
|
849
|
+
* transformed off the screen and having a snap animation.
|
|
850
|
+
*
|
|
851
|
+
* A workaround is to clone the footer element and append
|
|
852
|
+
* it outside of the wrapper element. This way, the footer
|
|
853
|
+
* is still visible and the drag can be done without
|
|
854
|
+
* flickering. The original footer is hidden until the modal
|
|
855
|
+
* is dismissed. This maintains the animation of the footer
|
|
856
|
+
* when the modal is dismissed.
|
|
857
|
+
*
|
|
858
|
+
* The workaround needs to be done before the animation starts
|
|
859
|
+
* so there are no flickering issues.
|
|
860
|
+
*/
|
|
861
|
+
const ionFooter = baseEl.querySelector('ion-footer');
|
|
862
|
+
/**
|
|
863
|
+
* This check is needed to prevent more than one footer
|
|
864
|
+
* from being appended to the shadow root.
|
|
865
|
+
* Otherwise, iOS and MD enter animations would append
|
|
866
|
+
* the footer twice.
|
|
867
|
+
*/
|
|
868
|
+
const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
|
|
869
|
+
if (ionFooter && !ionFooterAlreadyAppended) {
|
|
870
|
+
const footerHeight = ionFooter.clientHeight;
|
|
871
|
+
const clonedFooter = ionFooter.cloneNode(true);
|
|
872
|
+
baseEl.shadowRoot.appendChild(clonedFooter);
|
|
873
|
+
ionFooter.style.setProperty('display', 'none');
|
|
874
|
+
ionFooter.setAttribute('aria-hidden', 'true');
|
|
875
|
+
// Padding is added to prevent some content from being hidden.
|
|
876
|
+
const page = baseEl.querySelector('.ion-page');
|
|
877
|
+
page.style.setProperty('padding-bottom', `${footerHeight}px`);
|
|
878
|
+
}
|
|
879
|
+
});
|
|
778
880
|
if (contentAnimation) {
|
|
779
881
|
baseAnimation.addAnimation(contentAnimation);
|
|
780
882
|
}
|
|
@@ -793,7 +895,7 @@ const createLeaveAnimation = () => {
|
|
|
793
895
|
* Md Modal Leave Animation
|
|
794
896
|
*/
|
|
795
897
|
const mdLeaveAnimation = (baseEl, opts) => {
|
|
796
|
-
const { currentBreakpoint } = opts;
|
|
898
|
+
const { currentBreakpoint, expandToScroll } = opts;
|
|
797
899
|
const root = helpers.getElementRoot(baseEl);
|
|
798
900
|
const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
|
|
799
901
|
backdropAnimation.addElement(root.querySelector('ion-backdrop'));
|
|
@@ -801,7 +903,29 @@ const mdLeaveAnimation = (baseEl, opts) => {
|
|
|
801
903
|
const baseAnimation = animation.createAnimation()
|
|
802
904
|
.easing('cubic-bezier(0.47,0,0.745,0.715)')
|
|
803
905
|
.duration(200)
|
|
804
|
-
.addAnimation([backdropAnimation, wrapperAnimation])
|
|
906
|
+
.addAnimation([backdropAnimation, wrapperAnimation])
|
|
907
|
+
.beforeAddWrite(() => {
|
|
908
|
+
if (expandToScroll) {
|
|
909
|
+
// Scroll can only be done when the modal is fully expanded.
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* If expandToScroll is disabled, we need to swap
|
|
914
|
+
* the visibility to the original, so the footer
|
|
915
|
+
* dismisses with the modal and doesn't stay
|
|
916
|
+
* until the modal is removed from the DOM.
|
|
917
|
+
*/
|
|
918
|
+
const ionFooter = baseEl.querySelector('ion-footer');
|
|
919
|
+
if (ionFooter) {
|
|
920
|
+
const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
|
|
921
|
+
ionFooter.style.removeProperty('display');
|
|
922
|
+
ionFooter.removeAttribute('aria-hidden');
|
|
923
|
+
clonedFooter.style.setProperty('display', 'none');
|
|
924
|
+
clonedFooter.setAttribute('aria-hidden', 'true');
|
|
925
|
+
const page = baseEl.querySelector('.ion-page');
|
|
926
|
+
page.style.removeProperty('padding-bottom');
|
|
927
|
+
}
|
|
928
|
+
});
|
|
805
929
|
return baseAnimation;
|
|
806
930
|
};
|
|
807
931
|
|
|
@@ -833,9 +957,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
833
957
|
let offset = 0;
|
|
834
958
|
let canDismissBlocksGesture = false;
|
|
835
959
|
let cachedScrollEl = null;
|
|
836
|
-
let cachedFooterEl = null;
|
|
837
|
-
let cachedFooterYPosition = null;
|
|
838
|
-
let currentFooterState = null;
|
|
839
960
|
const canDismissMaxStep = 0.95;
|
|
840
961
|
const maxBreakpoint = breakpoints[breakpoints.length - 1];
|
|
841
962
|
const minBreakpoint = breakpoints[0];
|
|
@@ -865,45 +986,29 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
865
986
|
baseEl.classList.add(overlays.FOCUS_TRAP_DISABLE_CLASS);
|
|
866
987
|
};
|
|
867
988
|
/**
|
|
868
|
-
* Toggles the
|
|
869
|
-
*
|
|
870
|
-
* @param footer Whether the footer is in a moving or stationary position.
|
|
989
|
+
* Toggles the visible modal footer when `expandToScroll` is disabled.
|
|
990
|
+
* @param footer The footer to show.
|
|
871
991
|
*/
|
|
872
|
-
const
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
return;
|
|
877
|
-
}
|
|
992
|
+
const swapFooterVisibility = (footer) => {
|
|
993
|
+
const originalFooter = baseEl.querySelector('ion-footer');
|
|
994
|
+
if (!originalFooter) {
|
|
995
|
+
return;
|
|
878
996
|
}
|
|
997
|
+
const clonedFooter = wrapperEl.nextElementSibling;
|
|
998
|
+
const footerToHide = footer === 'original' ? clonedFooter : originalFooter;
|
|
999
|
+
const footerToShow = footer === 'original' ? originalFooter : clonedFooter;
|
|
1000
|
+
footerToShow.style.removeProperty('display');
|
|
1001
|
+
footerToShow.removeAttribute('aria-hidden');
|
|
879
1002
|
const page = baseEl.querySelector('.ion-page');
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
// Reset positioning styles to allow normal document flow
|
|
883
|
-
cachedFooterEl.classList.remove('modal-footer-moving');
|
|
884
|
-
cachedFooterEl.style.removeProperty('position');
|
|
885
|
-
cachedFooterEl.style.removeProperty('bottom');
|
|
886
|
-
page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
|
|
887
|
-
// Move to page
|
|
888
|
-
page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
|
|
1003
|
+
if (footer === 'original') {
|
|
1004
|
+
page.style.removeProperty('padding-bottom');
|
|
889
1005
|
}
|
|
890
1006
|
else {
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
// make the footer absolutely positioned or we may accidentally cause the
|
|
894
|
-
// sheet to scroll.
|
|
895
|
-
const footerHeight = cachedFooterEl.clientHeight;
|
|
896
|
-
page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
|
|
897
|
-
// Apply positioning styles to keep footer at bottom
|
|
898
|
-
cachedFooterEl.classList.add('modal-footer-moving');
|
|
899
|
-
cachedFooterEl.style.setProperty('position', 'absolute');
|
|
900
|
-
cachedFooterEl.style.setProperty('bottom', '0');
|
|
901
|
-
// Also cache the footer Y position, which we use to determine if the
|
|
902
|
-
// sheet has been moved below the footer. When that happens, we need to swap
|
|
903
|
-
// the position back so it will collapse correctly.
|
|
904
|
-
cachedFooterYPosition = cachedFooterEl.getBoundingClientRect().top + window.scrollY;
|
|
905
|
-
document.body.appendChild(cachedFooterEl);
|
|
1007
|
+
const pagePadding = footerToShow.clientHeight;
|
|
1008
|
+
page.style.setProperty('padding-bottom', `${pagePadding}px`);
|
|
906
1009
|
}
|
|
1010
|
+
footerToHide.style.setProperty('display', 'none');
|
|
1011
|
+
footerToHide.setAttribute('aria-hidden', 'true');
|
|
907
1012
|
};
|
|
908
1013
|
/**
|
|
909
1014
|
* After the entering animation completes,
|
|
@@ -997,11 +1102,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
997
1102
|
}
|
|
998
1103
|
/**
|
|
999
1104
|
* If expandToScroll is disabled, we need to swap
|
|
1000
|
-
* the footer
|
|
1001
|
-
*
|
|
1105
|
+
* the footer visibility to the original, so if the modal
|
|
1106
|
+
* is dismissed, the footer dismisses with the modal
|
|
1107
|
+
* and doesn't stay on the screen after the modal is gone.
|
|
1002
1108
|
*/
|
|
1003
1109
|
if (!expandToScroll) {
|
|
1004
|
-
|
|
1110
|
+
swapFooterVisibility('original');
|
|
1005
1111
|
}
|
|
1006
1112
|
/**
|
|
1007
1113
|
* If we are pulling down, then it is possible we are pulling on the content.
|
|
@@ -1020,21 +1126,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1020
1126
|
animation.progressStart(true, 1 - currentBreakpoint);
|
|
1021
1127
|
};
|
|
1022
1128
|
const onMove = (detail) => {
|
|
1023
|
-
/**
|
|
1024
|
-
* If `expandToScroll` is disabled, we need to see if we're currently below
|
|
1025
|
-
* the footer element and the footer is in a stationary position. If so,
|
|
1026
|
-
* we need to make the stationary the original position so that the footer
|
|
1027
|
-
* collapses with the sheet.
|
|
1028
|
-
*/
|
|
1029
|
-
if (!expandToScroll && cachedFooterYPosition !== null && currentFooterState !== null) {
|
|
1030
|
-
// Check if we need to swap the footer position
|
|
1031
|
-
if (detail.currentY >= cachedFooterYPosition && currentFooterState === 'moving') {
|
|
1032
|
-
swapFooterPosition('stationary');
|
|
1033
|
-
}
|
|
1034
|
-
else if (detail.currentY < cachedFooterYPosition && currentFooterState === 'stationary') {
|
|
1035
|
-
swapFooterPosition('moving');
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
1129
|
/**
|
|
1039
1130
|
* If `expandToScroll` is disabled, and an upwards swipe gesture is done within
|
|
1040
1131
|
* the scrollable content, we should not allow the swipe gesture to continue.
|
|
@@ -1168,6 +1259,14 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1168
1259
|
* snapping animation completes.
|
|
1169
1260
|
*/
|
|
1170
1261
|
gesture.enable(false);
|
|
1262
|
+
/**
|
|
1263
|
+
* If expandToScroll is disabled, we need to swap
|
|
1264
|
+
* the footer visibility to the cloned one so the footer
|
|
1265
|
+
* doesn't flicker when the sheet's height is animated.
|
|
1266
|
+
*/
|
|
1267
|
+
if (!expandToScroll && shouldRemainOpen) {
|
|
1268
|
+
swapFooterVisibility('cloned');
|
|
1269
|
+
}
|
|
1171
1270
|
if (shouldPreventDismiss) {
|
|
1172
1271
|
handleCanDismiss(baseEl, animation);
|
|
1173
1272
|
}
|
|
@@ -1188,14 +1287,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1188
1287
|
animation
|
|
1189
1288
|
.onFinish(() => {
|
|
1190
1289
|
if (shouldRemainOpen) {
|
|
1191
|
-
/**
|
|
1192
|
-
* If expandToScroll is disabled, we need to swap
|
|
1193
|
-
* the footer position to stationary so that it
|
|
1194
|
-
* will act as it would by default
|
|
1195
|
-
*/
|
|
1196
|
-
if (!expandToScroll) {
|
|
1197
|
-
swapFooterPosition('stationary');
|
|
1198
|
-
}
|
|
1199
1290
|
/**
|
|
1200
1291
|
* Once the snapping animation completes,
|
|
1201
1292
|
* we need to reset the animation to go
|
|
@@ -394,8 +394,8 @@ const Searchbar = class {
|
|
|
394
394
|
const clearIcon = this.clearIcon || (mode === 'ios' ? index$2.closeCircle : index$2.closeSharp);
|
|
395
395
|
const searchIcon = this.searchIcon || (mode === 'ios' ? index$2.searchOutline : index$2.searchSharp);
|
|
396
396
|
const shouldShowCancelButton = this.shouldShowCancelButton();
|
|
397
|
-
const cancelButton = this.showCancelButton !== 'never' && (index.h("button", { key: '
|
|
398
|
-
return (index.h(index.Host, { key: '
|
|
397
|
+
const cancelButton = this.showCancelButton !== 'never' && (index.h("button", { key: '4a4bddfaf44acb9ea71d37d11c3fc11450134a5c', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: mode === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, index.h("div", { key: '24424547e34a80422f617f5597965724a3ef65f0', "aria-hidden": "true" }, mode === 'md' ? (index.h("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
|
|
398
|
+
return (index.h(index.Host, { key: '0c0e7334cb2af87081a278e5a3f6be3dc646a073', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: theme.createColorClasses(this.color, {
|
|
399
399
|
[mode]: true,
|
|
400
400
|
'searchbar-animated': animated,
|
|
401
401
|
'searchbar-disabled': this.disabled,
|
|
@@ -405,14 +405,14 @@ const Searchbar = class {
|
|
|
405
405
|
'searchbar-has-focus': this.focused,
|
|
406
406
|
'searchbar-should-show-clear': this.shouldShowClearButton(),
|
|
407
407
|
'searchbar-should-show-cancel': this.shouldShowCancelButton(),
|
|
408
|
-
}) }, index.h("div", { key: '
|
|
408
|
+
}) }, index.h("div", { key: '859da78b062b9059701eba166be3bc5417f7395b', class: "searchbar-input-container" }, index.h("input", Object.assign({ key: '840fd06a1e4b5a8d7f6d7439d02aef9fcb9720b6', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), mode === 'md' && cancelButton, index.h("ion-icon", { key: 'a5aaa6a2204d38433cac283dd47b6197499fa585', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), index.h("button", { key: 'cf62c8969c5c916ac838e122a0ad45b2ae234791', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
|
|
409
409
|
/**
|
|
410
410
|
* This prevents mobile browsers from
|
|
411
411
|
* blurring the input when the clear
|
|
412
412
|
* button is activated.
|
|
413
413
|
*/
|
|
414
414
|
ev.preventDefault();
|
|
415
|
-
}, onClick: () => this.onClearInput(true) }, index.h("ion-icon", { key: '
|
|
415
|
+
}, onClick: () => this.onClearInput(true) }, index.h("ion-icon", { key: 'b1a75f0964fc2119479e246dc27bef7cc33bd19f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
|
|
416
416
|
}
|
|
417
417
|
get el() { return index.getElement(this); }
|
|
418
418
|
static get watchers() { return {
|