@ionic/core 8.5.8-dev.11748388365.11ad9dfe → 8.5.8-dev.11748450896.16232653
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 +5 -23
- package/components/ion-datetime.js +51 -27
- package/components/ion-input-password-toggle.js +2 -2
- package/components/ion-searchbar.js +4 -4
- package/components/modal.js +82 -159
- 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 +3 -19
- package/dist/cjs/ion-datetime_3.cjs.entry.js +54 -30
- package/dist/cjs/ion-input-password-toggle.cjs.entry.js +2 -2
- package/dist/cjs/ion-modal.cjs.entry.js +82 -159
- 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 +3 -23
- package/dist/collection/components/datetime/datetime.js +51 -27
- package/dist/collection/components/input-password-toggle/input-password-toggle.js +2 -2
- package/dist/collection/components/modal/animations/ios.enter.js +1 -41
- package/dist/collection/components/modal/animations/ios.leave.js +2 -24
- package/dist/collection/components/modal/animations/md.enter.js +1 -41
- package/dist/collection/components/modal/animations/md.leave.js +2 -24
- package/dist/collection/components/modal/gestures/sheet.js +76 -29
- 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 +4 -20
- package/dist/esm/ion-datetime_3.entry.js +54 -30
- package/dist/esm/ion-input-password-toggle.entry.js +2 -2
- package/dist/esm/ion-modal.entry.js +82 -159
- 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-3cee5d7c.system.entry.js → p-50cb2e8b.system.entry.js} +2 -2
- package/dist/ionic/p-57957c0f.entry.js +4 -0
- package/dist/ionic/p-6b8530f5.system.entry.js +4 -0
- package/dist/ionic/{p-3ec227cd.system.entry.js → p-7611ede3.system.entry.js} +1 -1
- package/dist/ionic/{p-e7f732ef.entry.js → p-891553d8.entry.js} +1 -1
- package/dist/ionic/{p-ffa2125f.entry.js → p-a835aca8.entry.js} +1 -1
- package/dist/ionic/p-b1e199b2.entry.js +4 -0
- package/dist/ionic/p-b5432d15.entry.js +4 -0
- package/dist/ionic/p-c1b7d311.system.entry.js +4 -0
- package/dist/ionic/p-f2367bf2.system.entry.js +4 -0
- package/dist/ionic/p-f725bf9e.system.js +2 -2
- package/dist/types/components/button/button.d.ts +0 -11
- package/dist/types/components/searchbar/searchbar.d.ts +1 -1
- package/dist/types/components.d.ts +2 -2
- package/hydrate/index.js +145 -213
- package/hydrate/index.mjs +145 -213
- package/package.json +2 -2
- package/dist/ionic/p-12914457.entry.js +0 -4
- package/dist/ionic/p-3d2b2787.system.entry.js +0 -4
- package/dist/ionic/p-4090ce24.entry.js +0 -4
- package/dist/ionic/p-8b8b4530.system.entry.js +0 -4
- package/dist/ionic/p-94a18d00.entry.js +0 -4
- package/dist/ionic/p-cec902a0.system.entry.js +0 -4
package/components/button.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { proxyCustomElement, HTMLElement, createEvent,
|
|
4
|
+
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
|
|
5
5
|
import { h as hasShadowDom, i as inheritAriaAttributes } from './helpers.js';
|
|
6
6
|
import { a as printIonWarning } from './index4.js';
|
|
7
7
|
import { o as openURL, c as createColorClasses, h as hostContext } from './theme.js';
|
|
@@ -77,20 +77,6 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
|
|
|
77
77
|
this.formButtonEl.disabled = disabled;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
/**
|
|
81
|
-
* This component is used within the `ion-input-password-toggle` component
|
|
82
|
-
* to toggle the visibility of the password input.
|
|
83
|
-
* These attributes need to update based on the state of the password input.
|
|
84
|
-
* Otherwise, the values will be stale.
|
|
85
|
-
*
|
|
86
|
-
* @param newValue
|
|
87
|
-
* @param _oldValue
|
|
88
|
-
* @param propName
|
|
89
|
-
*/
|
|
90
|
-
onAriaChanged(newValue, _oldValue, propName) {
|
|
91
|
-
this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [propName]: newValue });
|
|
92
|
-
forceUpdate(this);
|
|
93
|
-
}
|
|
94
80
|
/**
|
|
95
81
|
* This is responsible for rendering a hidden native
|
|
96
82
|
* button element inside the associated form. This allows
|
|
@@ -228,7 +214,7 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
|
|
|
228
214
|
{
|
|
229
215
|
type !== 'button' && this.renderHiddenButton();
|
|
230
216
|
}
|
|
231
|
-
return (h(Host, { key: '
|
|
217
|
+
return (h(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses(color, {
|
|
232
218
|
[mode]: true,
|
|
233
219
|
[buttonType]: true,
|
|
234
220
|
[`${buttonType}-${expand}`]: expand !== undefined,
|
|
@@ -243,13 +229,11 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
|
|
|
243
229
|
'button-disabled': disabled,
|
|
244
230
|
'ion-activatable': true,
|
|
245
231
|
'ion-focusable': true,
|
|
246
|
-
}) }, h(TagType, Object.assign({ key: '
|
|
232
|
+
}) }, h(TagType, Object.assign({ key: 'b7c2a46fb994024841219316f4089335fa463d84' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), h("span", { key: '3e07a5c9f86836f9fbaefc6c617bdde6eb6f70cd', class: "button-inner" }, h("slot", { key: '41c08ae09aed16faaa57707d229ff75d97f0731c', name: "icon-only", onSlotchange: this.slotChanged }), h("slot", { key: 'ab8b749e4572884cc04970a7594466b4a24c886e', name: "start" }), h("slot", { key: '397f7ff48ea45e82029414be95d29ae86e12c3a9' }), h("slot", { key: '9a5627713002e8be3738d392b616f6e951b70e12', name: "end" })), mode === 'md' && h("ion-ripple-effect", { key: '105566543ceda102474edab7ca8a44c7e71af589', type: this.rippleType }))));
|
|
247
233
|
}
|
|
248
234
|
get el() { return this; }
|
|
249
235
|
static get watchers() { return {
|
|
250
|
-
"disabled": ["disabledChanged"]
|
|
251
|
-
"aria-checked": ["onAriaChanged"],
|
|
252
|
-
"aria-label": ["onAriaChanged"]
|
|
236
|
+
"disabled": ["disabledChanged"]
|
|
253
237
|
}; }
|
|
254
238
|
static get style() { return {
|
|
255
239
|
ios: IonButtonIosStyle0,
|
|
@@ -274,9 +258,7 @@ const Button = /*@__PURE__*/ proxyCustomElement(class Button extends HTMLElement
|
|
|
274
258
|
"form": [1],
|
|
275
259
|
"isCircle": [32]
|
|
276
260
|
}, undefined, {
|
|
277
|
-
"disabled": ["disabledChanged"]
|
|
278
|
-
"aria-checked": ["onAriaChanged"],
|
|
279
|
-
"aria-label": ["onAriaChanged"]
|
|
261
|
+
"disabled": ["disabledChanged"]
|
|
280
262
|
}]);
|
|
281
263
|
function defineCustomElement() {
|
|
282
264
|
if (typeof customElements === "undefined") {
|
|
@@ -685,18 +685,19 @@ const Datetime = /*@__PURE__*/ proxyCustomElement(class Datetime extends HTMLEle
|
|
|
685
685
|
warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
|
|
686
686
|
}
|
|
687
687
|
/**
|
|
688
|
-
* If there are multiple values, clamp to
|
|
689
|
-
*
|
|
690
|
-
*
|
|
688
|
+
* If there are multiple values, pick an arbitrary one to clamp to. This way,
|
|
689
|
+
* if the values are across months, we always show at least one of them. Note
|
|
690
|
+
* that the values don't necessarily have to be in order.
|
|
691
691
|
*/
|
|
692
|
-
const singleValue = Array.isArray(valueToProcess) ? valueToProcess[
|
|
692
|
+
const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
|
|
693
693
|
const targetValue = clampDate(singleValue, minParts, maxParts);
|
|
694
694
|
const { month, day, year, hour, minute } = targetValue;
|
|
695
695
|
const ampm = parseAmPm(hour);
|
|
696
696
|
/**
|
|
697
|
-
* Since `activeParts` indicates a value that
|
|
698
|
-
*
|
|
699
|
-
*
|
|
697
|
+
* Since `activeParts` indicates a value that
|
|
698
|
+
* been explicitly selected either by the
|
|
699
|
+
* user or the app, only update `activeParts`
|
|
700
|
+
* if the `value` property is set.
|
|
700
701
|
*/
|
|
701
702
|
if (hasValue) {
|
|
702
703
|
if (Array.isArray(valueToProcess)) {
|
|
@@ -721,28 +722,51 @@ const Datetime = /*@__PURE__*/ proxyCustomElement(class Datetime extends HTMLEle
|
|
|
721
722
|
*/
|
|
722
723
|
this.activeParts = [];
|
|
723
724
|
}
|
|
725
|
+
/**
|
|
726
|
+
* Only animate if:
|
|
727
|
+
* 1. We're using grid style (wheel style pickers should just jump to new value)
|
|
728
|
+
* 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
|
|
729
|
+
* 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
|
|
730
|
+
* 4. The month/year picker is not open (since you wouldn't see the animation anyway)
|
|
731
|
+
*/
|
|
724
732
|
const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
|
|
725
733
|
const bodyIsVisible = el.classList.contains('datetime-ready');
|
|
726
734
|
const { isGridStyle, showMonthAndYear } = this;
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
735
|
+
let areAllSelectedDatesInSameMonth = true;
|
|
736
|
+
if (Array.isArray(valueToProcess)) {
|
|
737
|
+
const firstMonth = valueToProcess[0].month;
|
|
738
|
+
for (const date of valueToProcess) {
|
|
739
|
+
if (date.month !== firstMonth) {
|
|
740
|
+
areAllSelectedDatesInSameMonth = false;
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
736
744
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
745
|
+
/**
|
|
746
|
+
* If there is more than one date selected
|
|
747
|
+
* and the dates aren't all in the same month,
|
|
748
|
+
* then we should neither animate to the date
|
|
749
|
+
* nor update the working parts because we do
|
|
750
|
+
* not know which date the user wants to view.
|
|
751
|
+
*/
|
|
752
|
+
if (areAllSelectedDatesInSameMonth) {
|
|
753
|
+
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
|
|
754
|
+
this.animateToDate(targetValue);
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
/**
|
|
758
|
+
* We only need to do this if we didn't just animate to a new month,
|
|
759
|
+
* since that calls prevMonth/nextMonth which calls setWorkingParts for us.
|
|
760
|
+
*/
|
|
761
|
+
this.setWorkingParts({
|
|
762
|
+
month,
|
|
763
|
+
day,
|
|
764
|
+
year,
|
|
765
|
+
hour,
|
|
766
|
+
minute,
|
|
767
|
+
ampm,
|
|
768
|
+
});
|
|
769
|
+
}
|
|
746
770
|
}
|
|
747
771
|
};
|
|
748
772
|
this.animateToDate = async (targetValue) => {
|
|
@@ -1737,7 +1761,7 @@ const Datetime = /*@__PURE__*/ proxyCustomElement(class Datetime extends HTMLEle
|
|
|
1737
1761
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1738
1762
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1739
1763
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
1740
|
-
return (h(Host, { key: '
|
|
1764
|
+
return (h(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
|
|
1741
1765
|
[mode]: true,
|
|
1742
1766
|
['datetime-readonly']: readonly,
|
|
1743
1767
|
['datetime-disabled']: disabled,
|
|
@@ -1747,7 +1771,7 @@ const Datetime = /*@__PURE__*/ proxyCustomElement(class Datetime extends HTMLEle
|
|
|
1747
1771
|
[`datetime-size-${size}`]: true,
|
|
1748
1772
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1749
1773
|
[`datetime-grid`]: isGridStyle,
|
|
1750
|
-
})) }, h("div", { key: '
|
|
1774
|
+
})) }, h("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1751
1775
|
}
|
|
1752
1776
|
get el() { return this; }
|
|
1753
1777
|
static get watchers() { return {
|
|
@@ -72,14 +72,14 @@ const InputPasswordToggle = /*@__PURE__*/ proxyCustomElement(class InputPassword
|
|
|
72
72
|
const isPasswordVisible = type === 'text';
|
|
73
73
|
return (h(Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: createColorClasses(color, {
|
|
74
74
|
[mode]: true,
|
|
75
|
-
}) }, h("ion-button", { key: '
|
|
75
|
+
}) }, h("ion-button", { key: '039d1bab764093bb6fe4a34299b0872abda087fd', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": "show password", role: "switch", type: "button", onPointerDown: (ev) => {
|
|
76
76
|
/**
|
|
77
77
|
* This prevents mobile browsers from
|
|
78
78
|
* blurring the input when the password toggle
|
|
79
79
|
* button is activated.
|
|
80
80
|
*/
|
|
81
81
|
ev.preventDefault();
|
|
82
|
-
}, onClick: this.togglePasswordVisibility }, h("ion-icon", { key: '
|
|
82
|
+
}, onClick: this.togglePasswordVisibility }, h("ion-icon", { key: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
|
|
83
83
|
}
|
|
84
84
|
get el() { return this; }
|
|
85
85
|
static get watchers() { return {
|
|
@@ -392,8 +392,8 @@ const Searchbar = /*@__PURE__*/ proxyCustomElement(class Searchbar extends HTMLE
|
|
|
392
392
|
const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
|
|
393
393
|
const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
|
|
394
394
|
const shouldShowCancelButton = this.shouldShowCancelButton();
|
|
395
|
-
const cancelButton = this.showCancelButton !== 'never' && (h("button", { key: '
|
|
396
|
-
return (h(Host, { key: '
|
|
395
|
+
const cancelButton = this.showCancelButton !== 'never' && (h("button", { key: '989f3e84c472ada6e66dd9b249d0d268bf17ce26', "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" }, h("div", { key: '7d335d4fde33822dc79d26b748ba2e98db7494bb', "aria-hidden": "true" }, mode === 'md' ? (h("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
|
|
396
|
+
return (h(Host, { key: 'd1a1972725e949fb102c91487aaa7b9d10c2d718', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses(this.color, {
|
|
397
397
|
[mode]: true,
|
|
398
398
|
'searchbar-animated': animated,
|
|
399
399
|
'searchbar-disabled': this.disabled,
|
|
@@ -403,14 +403,14 @@ const Searchbar = /*@__PURE__*/ proxyCustomElement(class Searchbar extends HTMLE
|
|
|
403
403
|
'searchbar-has-focus': this.focused,
|
|
404
404
|
'searchbar-should-show-clear': this.shouldShowClearButton(),
|
|
405
405
|
'searchbar-should-show-cancel': this.shouldShowCancelButton(),
|
|
406
|
-
}) }, h("div", { key: '
|
|
406
|
+
}) }, h("div", { key: 'add53640b2994cb6b2bf02792dafe51aba6b1684', class: "searchbar-input-container" }, h("input", Object.assign({ key: '160cc36459a4a652e7f41ccd14dcdc782278779e', "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, h("ion-icon", { key: '8825fd13af0d2dea451ccc0e00ae7b5021dc01c4', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), h("button", { key: '8a7b56da278b9ca5c4f5a4ee9c01924fd5ae29d8', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
|
|
407
407
|
/**
|
|
408
408
|
* This prevents mobile browsers from
|
|
409
409
|
* blurring the input when the clear
|
|
410
410
|
* button is activated.
|
|
411
411
|
*/
|
|
412
412
|
ev.preventDefault();
|
|
413
|
-
}, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: '
|
|
413
|
+
}, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: '24c55274516ab012d8c25f03525c6cdb9409e52f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
|
|
414
414
|
}
|
|
415
415
|
get el() { return this; }
|
|
416
416
|
static get watchers() { return {
|
package/components/modal.js
CHANGED
|
@@ -582,47 +582,7 @@ const iosEnterAnimation = (baseEl, opts) => {
|
|
|
582
582
|
.addElement(baseEl)
|
|
583
583
|
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
584
584
|
.duration(500)
|
|
585
|
-
.addAnimation([wrapperAnimation])
|
|
586
|
-
.beforeAddWrite(() => {
|
|
587
|
-
if (expandToScroll) {
|
|
588
|
-
// Scroll can only be done when the modal is fully expanded.
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
/**
|
|
592
|
-
* There are some browsers that causes flickering when
|
|
593
|
-
* dragging the content when scroll is enabled at every
|
|
594
|
-
* breakpoint. This is due to the wrapper element being
|
|
595
|
-
* transformed off the screen and having a snap animation.
|
|
596
|
-
*
|
|
597
|
-
* A workaround is to clone the footer element and append
|
|
598
|
-
* it outside of the wrapper element. This way, the footer
|
|
599
|
-
* is still visible and the drag can be done without
|
|
600
|
-
* flickering. The original footer is hidden until the modal
|
|
601
|
-
* is dismissed. This maintains the animation of the footer
|
|
602
|
-
* when the modal is dismissed.
|
|
603
|
-
*
|
|
604
|
-
* The workaround needs to be done before the animation starts
|
|
605
|
-
* so there are no flickering issues.
|
|
606
|
-
*/
|
|
607
|
-
const ionFooter = baseEl.querySelector('ion-footer');
|
|
608
|
-
/**
|
|
609
|
-
* This check is needed to prevent more than one footer
|
|
610
|
-
* from being appended to the shadow root.
|
|
611
|
-
* Otherwise, iOS and MD enter animations would append
|
|
612
|
-
* the footer twice.
|
|
613
|
-
*/
|
|
614
|
-
const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
|
|
615
|
-
if (ionFooter && !ionFooterAlreadyAppended) {
|
|
616
|
-
const footerHeight = ionFooter.clientHeight;
|
|
617
|
-
const clonedFooter = ionFooter.cloneNode(true);
|
|
618
|
-
baseEl.shadowRoot.appendChild(clonedFooter);
|
|
619
|
-
ionFooter.style.setProperty('display', 'none');
|
|
620
|
-
ionFooter.setAttribute('aria-hidden', 'true');
|
|
621
|
-
// Padding is added to prevent some content from being hidden.
|
|
622
|
-
const page = baseEl.querySelector('.ion-page');
|
|
623
|
-
page.style.setProperty('padding-bottom', `${footerHeight}px`);
|
|
624
|
-
}
|
|
625
|
-
});
|
|
585
|
+
.addAnimation([wrapperAnimation]);
|
|
626
586
|
if (contentAnimation) {
|
|
627
587
|
baseAnimation.addAnimation(contentAnimation);
|
|
628
588
|
}
|
|
@@ -703,7 +663,7 @@ const createLeaveAnimation$1 = () => {
|
|
|
703
663
|
* iOS Modal Leave Animation
|
|
704
664
|
*/
|
|
705
665
|
const iosLeaveAnimation = (baseEl, opts, duration = 500) => {
|
|
706
|
-
const { presentingEl, currentBreakpoint
|
|
666
|
+
const { presentingEl, currentBreakpoint } = opts;
|
|
707
667
|
const root = getElementRoot(baseEl);
|
|
708
668
|
const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation$1();
|
|
709
669
|
backdropAnimation.addElement(root.querySelector('ion-backdrop'));
|
|
@@ -712,29 +672,7 @@ const iosLeaveAnimation = (baseEl, opts, duration = 500) => {
|
|
|
712
672
|
.addElement(baseEl)
|
|
713
673
|
.easing('cubic-bezier(0.32,0.72,0,1)')
|
|
714
674
|
.duration(duration)
|
|
715
|
-
.addAnimation(wrapperAnimation)
|
|
716
|
-
.beforeAddWrite(() => {
|
|
717
|
-
if (expandToScroll) {
|
|
718
|
-
// Scroll can only be done when the modal is fully expanded.
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
/**
|
|
722
|
-
* If expandToScroll is disabled, we need to swap
|
|
723
|
-
* the visibility to the original, so the footer
|
|
724
|
-
* dismisses with the modal and doesn't stay
|
|
725
|
-
* until the modal is removed from the DOM.
|
|
726
|
-
*/
|
|
727
|
-
const ionFooter = baseEl.querySelector('ion-footer');
|
|
728
|
-
if (ionFooter) {
|
|
729
|
-
const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
|
|
730
|
-
ionFooter.style.removeProperty('display');
|
|
731
|
-
ionFooter.removeAttribute('aria-hidden');
|
|
732
|
-
clonedFooter.style.setProperty('display', 'none');
|
|
733
|
-
clonedFooter.setAttribute('aria-hidden', 'true');
|
|
734
|
-
const page = baseEl.querySelector('.ion-page');
|
|
735
|
-
page.style.removeProperty('padding-bottom');
|
|
736
|
-
}
|
|
737
|
-
});
|
|
675
|
+
.addAnimation(wrapperAnimation);
|
|
738
676
|
if (presentingEl) {
|
|
739
677
|
const isMobile = window.innerWidth < 768;
|
|
740
678
|
const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
|
|
@@ -830,47 +768,7 @@ const mdEnterAnimation = (baseEl, opts) => {
|
|
|
830
768
|
.addElement(baseEl)
|
|
831
769
|
.easing('cubic-bezier(0.36,0.66,0.04,1)')
|
|
832
770
|
.duration(280)
|
|
833
|
-
.addAnimation([backdropAnimation, wrapperAnimation])
|
|
834
|
-
.beforeAddWrite(() => {
|
|
835
|
-
if (expandToScroll) {
|
|
836
|
-
// Scroll can only be done when the modal is fully expanded.
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
/**
|
|
840
|
-
* There are some browsers that causes flickering when
|
|
841
|
-
* dragging the content when scroll is enabled at every
|
|
842
|
-
* breakpoint. This is due to the wrapper element being
|
|
843
|
-
* transformed off the screen and having a snap animation.
|
|
844
|
-
*
|
|
845
|
-
* A workaround is to clone the footer element and append
|
|
846
|
-
* it outside of the wrapper element. This way, the footer
|
|
847
|
-
* is still visible and the drag can be done without
|
|
848
|
-
* flickering. The original footer is hidden until the modal
|
|
849
|
-
* is dismissed. This maintains the animation of the footer
|
|
850
|
-
* when the modal is dismissed.
|
|
851
|
-
*
|
|
852
|
-
* The workaround needs to be done before the animation starts
|
|
853
|
-
* so there are no flickering issues.
|
|
854
|
-
*/
|
|
855
|
-
const ionFooter = baseEl.querySelector('ion-footer');
|
|
856
|
-
/**
|
|
857
|
-
* This check is needed to prevent more than one footer
|
|
858
|
-
* from being appended to the shadow root.
|
|
859
|
-
* Otherwise, iOS and MD enter animations would append
|
|
860
|
-
* the footer twice.
|
|
861
|
-
*/
|
|
862
|
-
const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
|
|
863
|
-
if (ionFooter && !ionFooterAlreadyAppended) {
|
|
864
|
-
const footerHeight = ionFooter.clientHeight;
|
|
865
|
-
const clonedFooter = ionFooter.cloneNode(true);
|
|
866
|
-
baseEl.shadowRoot.appendChild(clonedFooter);
|
|
867
|
-
ionFooter.style.setProperty('display', 'none');
|
|
868
|
-
ionFooter.setAttribute('aria-hidden', 'true');
|
|
869
|
-
// Padding is added to prevent some content from being hidden.
|
|
870
|
-
const page = baseEl.querySelector('.ion-page');
|
|
871
|
-
page.style.setProperty('padding-bottom', `${footerHeight}px`);
|
|
872
|
-
}
|
|
873
|
-
});
|
|
771
|
+
.addAnimation([backdropAnimation, wrapperAnimation]);
|
|
874
772
|
if (contentAnimation) {
|
|
875
773
|
baseAnimation.addAnimation(contentAnimation);
|
|
876
774
|
}
|
|
@@ -889,7 +787,7 @@ const createLeaveAnimation = () => {
|
|
|
889
787
|
* Md Modal Leave Animation
|
|
890
788
|
*/
|
|
891
789
|
const mdLeaveAnimation = (baseEl, opts) => {
|
|
892
|
-
const { currentBreakpoint
|
|
790
|
+
const { currentBreakpoint } = opts;
|
|
893
791
|
const root = getElementRoot(baseEl);
|
|
894
792
|
const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
|
|
895
793
|
backdropAnimation.addElement(root.querySelector('ion-backdrop'));
|
|
@@ -897,29 +795,7 @@ const mdLeaveAnimation = (baseEl, opts) => {
|
|
|
897
795
|
const baseAnimation = createAnimation()
|
|
898
796
|
.easing('cubic-bezier(0.47,0,0.745,0.715)')
|
|
899
797
|
.duration(200)
|
|
900
|
-
.addAnimation([backdropAnimation, wrapperAnimation])
|
|
901
|
-
.beforeAddWrite(() => {
|
|
902
|
-
if (expandToScroll) {
|
|
903
|
-
// Scroll can only be done when the modal is fully expanded.
|
|
904
|
-
return;
|
|
905
|
-
}
|
|
906
|
-
/**
|
|
907
|
-
* If expandToScroll is disabled, we need to swap
|
|
908
|
-
* the visibility to the original, so the footer
|
|
909
|
-
* dismisses with the modal and doesn't stay
|
|
910
|
-
* until the modal is removed from the DOM.
|
|
911
|
-
*/
|
|
912
|
-
const ionFooter = baseEl.querySelector('ion-footer');
|
|
913
|
-
if (ionFooter) {
|
|
914
|
-
const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
|
|
915
|
-
ionFooter.style.removeProperty('display');
|
|
916
|
-
ionFooter.removeAttribute('aria-hidden');
|
|
917
|
-
clonedFooter.style.setProperty('display', 'none');
|
|
918
|
-
clonedFooter.setAttribute('aria-hidden', 'true');
|
|
919
|
-
const page = baseEl.querySelector('.ion-page');
|
|
920
|
-
page.style.removeProperty('padding-bottom');
|
|
921
|
-
}
|
|
922
|
-
});
|
|
798
|
+
.addAnimation([backdropAnimation, wrapperAnimation]);
|
|
923
799
|
return baseAnimation;
|
|
924
800
|
};
|
|
925
801
|
|
|
@@ -951,6 +827,9 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
951
827
|
let offset = 0;
|
|
952
828
|
let canDismissBlocksGesture = false;
|
|
953
829
|
let cachedScrollEl = null;
|
|
830
|
+
let cachedFooterEl = null;
|
|
831
|
+
let cachedFooterYPosition = null;
|
|
832
|
+
let currentFooterState = null;
|
|
954
833
|
const canDismissMaxStep = 0.95;
|
|
955
834
|
const maxBreakpoint = breakpoints[breakpoints.length - 1];
|
|
956
835
|
const minBreakpoint = breakpoints[0];
|
|
@@ -980,29 +859,59 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
980
859
|
baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
|
|
981
860
|
};
|
|
982
861
|
/**
|
|
983
|
-
* Toggles the
|
|
984
|
-
*
|
|
862
|
+
* Toggles the footer to an absolute position while moving to prevent
|
|
863
|
+
* it from shaking while the sheet is being dragged.
|
|
864
|
+
* @param footer Whether the footer is in a moving or stationary position.
|
|
985
865
|
*/
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
866
|
+
const swapFooterPosition = (newPosition) => {
|
|
867
|
+
if (!cachedFooterEl) {
|
|
868
|
+
cachedFooterEl = baseEl.querySelector('ion-footer');
|
|
869
|
+
if (!cachedFooterEl) {
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
990
872
|
}
|
|
991
|
-
const clonedFooter = wrapperEl.nextElementSibling;
|
|
992
|
-
const footerToHide = footer === 'original' ? clonedFooter : originalFooter;
|
|
993
|
-
const footerToShow = footer === 'original' ? originalFooter : clonedFooter;
|
|
994
|
-
footerToShow.style.removeProperty('display');
|
|
995
|
-
footerToShow.removeAttribute('aria-hidden');
|
|
996
873
|
const page = baseEl.querySelector('.ion-page');
|
|
997
|
-
|
|
998
|
-
|
|
874
|
+
currentFooterState = newPosition;
|
|
875
|
+
if (newPosition === 'stationary') {
|
|
876
|
+
// Reset positioning styles to allow normal document flow
|
|
877
|
+
cachedFooterEl.classList.remove('modal-footer-moving');
|
|
878
|
+
cachedFooterEl.style.removeProperty('position');
|
|
879
|
+
cachedFooterEl.style.removeProperty('width');
|
|
880
|
+
cachedFooterEl.style.removeProperty('height');
|
|
881
|
+
cachedFooterEl.style.removeProperty('top');
|
|
882
|
+
cachedFooterEl.style.removeProperty('left');
|
|
883
|
+
page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
|
|
884
|
+
// Move to page
|
|
885
|
+
page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
|
|
999
886
|
}
|
|
1000
887
|
else {
|
|
1001
|
-
|
|
1002
|
-
|
|
888
|
+
// Get both the footer and document body positions
|
|
889
|
+
const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
|
|
890
|
+
const bodyRect = document.body.getBoundingClientRect();
|
|
891
|
+
// Add padding to the parent element to prevent content from being hidden
|
|
892
|
+
// when the footer is positioned absolutely. This has to be done before we
|
|
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
|
+
// Calculate absolute position relative to body
|
|
900
|
+
// We need to subtract the body's offsetTop to get true position within document.body
|
|
901
|
+
const absoluteTop = cachedFooterElRect.top - bodyRect.top;
|
|
902
|
+
const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
|
|
903
|
+
// Capture the footer's current dimensions and hard code them during the drag
|
|
904
|
+
cachedFooterEl.style.setProperty('position', 'absolute');
|
|
905
|
+
cachedFooterEl.style.setProperty('width', `${cachedFooterEl.clientWidth}px`);
|
|
906
|
+
cachedFooterEl.style.setProperty('height', `${cachedFooterEl.clientHeight}px`);
|
|
907
|
+
cachedFooterEl.style.setProperty('top', `${absoluteTop}px`);
|
|
908
|
+
cachedFooterEl.style.setProperty('left', `${absoluteLeft}px`);
|
|
909
|
+
// Also cache the footer Y position, which we use to determine if the
|
|
910
|
+
// sheet has been moved below the footer. When that happens, we need to swap
|
|
911
|
+
// the position back so it will collapse correctly.
|
|
912
|
+
cachedFooterYPosition = absoluteTop;
|
|
913
|
+
document.body.appendChild(cachedFooterEl);
|
|
1003
914
|
}
|
|
1004
|
-
footerToHide.style.setProperty('display', 'none');
|
|
1005
|
-
footerToHide.setAttribute('aria-hidden', 'true');
|
|
1006
915
|
};
|
|
1007
916
|
/**
|
|
1008
917
|
* After the entering animation completes,
|
|
@@ -1096,12 +1005,11 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1096
1005
|
}
|
|
1097
1006
|
/**
|
|
1098
1007
|
* If expandToScroll is disabled, we need to swap
|
|
1099
|
-
* the footer
|
|
1100
|
-
*
|
|
1101
|
-
* and doesn't stay on the screen after the modal is gone.
|
|
1008
|
+
* the footer position to moving so that it doesn't shake
|
|
1009
|
+
* while the sheet is being dragged.
|
|
1102
1010
|
*/
|
|
1103
1011
|
if (!expandToScroll) {
|
|
1104
|
-
|
|
1012
|
+
swapFooterPosition('moving');
|
|
1105
1013
|
}
|
|
1106
1014
|
/**
|
|
1107
1015
|
* If we are pulling down, then it is possible we are pulling on the content.
|
|
@@ -1120,6 +1028,21 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1120
1028
|
animation.progressStart(true, 1 - currentBreakpoint);
|
|
1121
1029
|
};
|
|
1122
1030
|
const onMove = (detail) => {
|
|
1031
|
+
/**
|
|
1032
|
+
* If `expandToScroll` is disabled, we need to see if we're currently below
|
|
1033
|
+
* the footer element and the footer is in a stationary position. If so,
|
|
1034
|
+
* we need to make the stationary the original position so that the footer
|
|
1035
|
+
* collapses with the sheet.
|
|
1036
|
+
*/
|
|
1037
|
+
if (!expandToScroll && cachedFooterYPosition !== null && currentFooterState !== null) {
|
|
1038
|
+
// Check if we need to swap the footer position
|
|
1039
|
+
if (detail.currentY >= cachedFooterYPosition && currentFooterState === 'moving') {
|
|
1040
|
+
swapFooterPosition('stationary');
|
|
1041
|
+
}
|
|
1042
|
+
else if (detail.currentY < cachedFooterYPosition && currentFooterState === 'stationary') {
|
|
1043
|
+
swapFooterPosition('moving');
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1123
1046
|
/**
|
|
1124
1047
|
* If `expandToScroll` is disabled, and an upwards swipe gesture is done within
|
|
1125
1048
|
* the scrollable content, we should not allow the swipe gesture to continue.
|
|
@@ -1253,14 +1176,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1253
1176
|
* snapping animation completes.
|
|
1254
1177
|
*/
|
|
1255
1178
|
gesture.enable(false);
|
|
1256
|
-
/**
|
|
1257
|
-
* If expandToScroll is disabled, we need to swap
|
|
1258
|
-
* the footer visibility to the cloned one so the footer
|
|
1259
|
-
* doesn't flicker when the sheet's height is animated.
|
|
1260
|
-
*/
|
|
1261
|
-
if (!expandToScroll && shouldRemainOpen) {
|
|
1262
|
-
swapFooterVisibility('cloned');
|
|
1263
|
-
}
|
|
1264
1179
|
if (shouldPreventDismiss) {
|
|
1265
1180
|
handleCanDismiss(baseEl, animation);
|
|
1266
1181
|
}
|
|
@@ -1277,6 +1192,14 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
|
|
|
1277
1192
|
if (contentEl && (snapToBreakpoint === breakpoints[breakpoints.length - 1] || !expandToScroll)) {
|
|
1278
1193
|
contentEl.scrollY = true;
|
|
1279
1194
|
}
|
|
1195
|
+
/**
|
|
1196
|
+
* If expandToScroll is disabled, we need to swap
|
|
1197
|
+
* the footer position to stationary so that it
|
|
1198
|
+
* will act as it would by default
|
|
1199
|
+
*/
|
|
1200
|
+
if (!expandToScroll) {
|
|
1201
|
+
swapFooterPosition('stationary');
|
|
1202
|
+
}
|
|
1280
1203
|
return new Promise((resolve) => {
|
|
1281
1204
|
animation
|
|
1282
1205
|
.onFinish(() => {
|
|
@@ -335,7 +335,7 @@ const PickerColumnCmp = /*@__PURE__*/ proxyCustomElement(class PickerColumnCmp e
|
|
|
335
335
|
const colEl = this.optsEl;
|
|
336
336
|
if (colEl) {
|
|
337
337
|
// DOM READ
|
|
338
|
-
// We perfom a DOM read over a rendered item, this needs to happen after the first render or after the column has changed
|
|
338
|
+
// We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
|
|
339
339
|
this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
|
|
340
340
|
}
|
|
341
341
|
this.refresh(forceRefresh, animated);
|
|
@@ -343,9 +343,9 @@ const PickerColumnCmp = /*@__PURE__*/ proxyCustomElement(class PickerColumnCmp e
|
|
|
343
343
|
render() {
|
|
344
344
|
const col = this.col;
|
|
345
345
|
const mode = getIonMode(this);
|
|
346
|
-
return (h(Host, { key: '
|
|
346
|
+
return (h(Host, { key: '88a3c9397c9ac92dd814074c8ae6ecf8e3420a2c', class: Object.assign({ [mode]: true, 'picker-col': true, 'picker-opts-left': this.col.align === 'left', 'picker-opts-right': this.col.align === 'right' }, getClassMap(col.cssClass)), style: {
|
|
347
347
|
'max-width': this.col.columnWidth,
|
|
348
|
-
} }, col.prefix && (h("div", { key: '
|
|
348
|
+
} }, col.prefix && (h("div", { key: '4491a705d15337e6f45f3cf6fd21af5242474729', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), h("div", { key: 'b0dd4b7a7a4c1edc4b73e7fb134ac85264072365', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (h("div", { key: 'c16419ce6481d60fc3ba6b8d102a4edf0ede02aa', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
|
|
349
349
|
}
|
|
350
350
|
get el() { return this; }
|
|
351
351
|
static get watchers() { return {
|