@ionic/vue
Version:
Vue specific wrapper for @ionic/core
1,307 lines (1,293 loc) • 90.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const vue = require('vue');
const ionAccordion_js = require('@ionic/core/components/ion-accordion.js');
const ionAccordionGroup_js = require('@ionic/core/components/ion-accordion-group.js');
const ionAvatar_js = require('@ionic/core/components/ion-avatar.js');
const ionBackdrop_js = require('@ionic/core/components/ion-backdrop.js');
const ionBadge_js = require('@ionic/core/components/ion-badge.js');
const ionBreadcrumb_js = require('@ionic/core/components/ion-breadcrumb.js');
const ionBreadcrumbs_js = require('@ionic/core/components/ion-breadcrumbs.js');
const ionButton_js = require('@ionic/core/components/ion-button.js');
const ionButtons_js = require('@ionic/core/components/ion-buttons.js');
const ionCard_js = require('@ionic/core/components/ion-card.js');
const ionCardContent_js = require('@ionic/core/components/ion-card-content.js');
const ionCardHeader_js = require('@ionic/core/components/ion-card-header.js');
const ionCardSubtitle_js = require('@ionic/core/components/ion-card-subtitle.js');
const ionCardTitle_js = require('@ionic/core/components/ion-card-title.js');
const ionCheckbox_js = require('@ionic/core/components/ion-checkbox.js');
const ionChip_js = require('@ionic/core/components/ion-chip.js');
const ionCol_js = require('@ionic/core/components/ion-col.js');
const ionContent_js = require('@ionic/core/components/ion-content.js');
const ionDatetime_js = require('@ionic/core/components/ion-datetime.js');
const ionDatetimeButton_js = require('@ionic/core/components/ion-datetime-button.js');
const ionFab_js = require('@ionic/core/components/ion-fab.js');
const ionFabButton_js = require('@ionic/core/components/ion-fab-button.js');
const ionFabList_js = require('@ionic/core/components/ion-fab-list.js');
const ionFooter_js = require('@ionic/core/components/ion-footer.js');
const ionGrid_js = require('@ionic/core/components/ion-grid.js');
const ionHeader_js = require('@ionic/core/components/ion-header.js');
const ionImg_js = require('@ionic/core/components/ion-img.js');
const ionInfiniteScroll_js = require('@ionic/core/components/ion-infinite-scroll.js');
const ionInfiniteScrollContent_js = require('@ionic/core/components/ion-infinite-scroll-content.js');
const ionInput_js = require('@ionic/core/components/ion-input.js');
const ionItem_js = require('@ionic/core/components/ion-item.js');
const ionItemDivider_js = require('@ionic/core/components/ion-item-divider.js');
const ionItemGroup_js = require('@ionic/core/components/ion-item-group.js');
const ionItemOption_js = require('@ionic/core/components/ion-item-option.js');
const ionItemOptions_js = require('@ionic/core/components/ion-item-options.js');
const ionItemSliding_js = require('@ionic/core/components/ion-item-sliding.js');
const ionLabel_js = require('@ionic/core/components/ion-label.js');
const ionList_js = require('@ionic/core/components/ion-list.js');
const ionListHeader_js = require('@ionic/core/components/ion-list-header.js');
const ionMenu_js = require('@ionic/core/components/ion-menu.js');
const ionMenuButton_js = require('@ionic/core/components/ion-menu-button.js');
const ionMenuToggle_js = require('@ionic/core/components/ion-menu-toggle.js');
const ionNav_js = require('@ionic/core/components/ion-nav.js');
const ionNavLink_js = require('@ionic/core/components/ion-nav-link.js');
const ionNote_js = require('@ionic/core/components/ion-note.js');
const ionProgressBar_js = require('@ionic/core/components/ion-progress-bar.js');
const ionRadio_js = require('@ionic/core/components/ion-radio.js');
const ionRadioGroup_js = require('@ionic/core/components/ion-radio-group.js');
const ionRange_js = require('@ionic/core/components/ion-range.js');
const ionRefresher_js = require('@ionic/core/components/ion-refresher.js');
const ionRefresherContent_js = require('@ionic/core/components/ion-refresher-content.js');
const ionReorder_js = require('@ionic/core/components/ion-reorder.js');
const ionReorderGroup_js = require('@ionic/core/components/ion-reorder-group.js');
const ionRippleEffect_js = require('@ionic/core/components/ion-ripple-effect.js');
const ionRow_js = require('@ionic/core/components/ion-row.js');
const ionSearchbar_js = require('@ionic/core/components/ion-searchbar.js');
const ionSegment_js = require('@ionic/core/components/ion-segment.js');
const ionSegmentButton_js = require('@ionic/core/components/ion-segment-button.js');
const ionSelect_js = require('@ionic/core/components/ion-select.js');
const ionSelectOption_js = require('@ionic/core/components/ion-select-option.js');
const ionSkeletonText_js = require('@ionic/core/components/ion-skeleton-text.js');
const ionSlide_js = require('@ionic/core/components/ion-slide.js');
const ionSlides_js = require('@ionic/core/components/ion-slides.js');
const ionSpinner_js = require('@ionic/core/components/ion-spinner.js');
const ionSplitPane_js = require('@ionic/core/components/ion-split-pane.js');
const ionText_js = require('@ionic/core/components/ion-text.js');
const ionTextarea_js = require('@ionic/core/components/ion-textarea.js');
const ionThumbnail_js = require('@ionic/core/components/ion-thumbnail.js');
const ionTitle_js = require('@ionic/core/components/ion-title.js');
const ionToggle_js = require('@ionic/core/components/ion-toggle.js');
const ionToolbar_js = require('@ionic/core/components/ion-toolbar.js');
const ionVirtualScroll_js = require('@ionic/core/components/ion-virtual-scroll.js');
const components = require('@ionic/core/components');
const ionBackButton_js = require('@ionic/core/components/ion-back-button.js');
const ionRouterOutlet_js = require('@ionic/core/components/ion-router-outlet.js');
const vueRouter = require('vue-router');
const ionTabButton_js = require('@ionic/core/components/ion-tab-button.js');
const ionTabBar_js = require('@ionic/core/components/ion-tab-bar.js');
const ionApp_js = require('@ionic/core/components/ion-app.js');
const ionIcon_js = require('ionicons/components/ion-icon.js');
const ionActionSheet_js = require('@ionic/core/components/ion-action-sheet.js');
const ionAlert_js = require('@ionic/core/components/ion-alert.js');
const ionLoading_js = require('@ionic/core/components/ion-loading.js');
const ionPicker_js = require('@ionic/core/components/ion-picker.js');
const ionToast_js = require('@ionic/core/components/ion-toast.js');
const ionModal_js = require('@ionic/core/components/ion-modal.js');
const ionPopover_js = require('@ionic/core/components/ion-popover.js');
const UPDATE_VALUE_EVENT = 'update:modelValue';
const MODEL_VALUE = 'modelValue';
const ROUTER_LINK_VALUE = 'routerLink';
const NAV_MANAGER = 'navManager';
const ROUTER_PROP_PREFIX = 'router';
/**
* Starting in Vue 3.1.0, all properties are
* added as keys to the props object, even if
* they are not being used. In order to correctly
* account for both value props and v-model props,
* we need to check if the key exists for Vue <3.1.0
* and then check if it is not undefined for Vue >= 3.1.0.
* See https://github.com/vuejs/vue-next/issues/3889
*/
const EMPTY_PROP = Symbol();
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
const getComponentClasses = (classes) => {
return (classes === null || classes === void 0 ? void 0 : classes.split(' ')) || [];
};
const getElementClasses = (ref, componentClasses, defaultClasses = []) => {
var _a;
return [...Array.from(((_a = ref.value) === null || _a === void 0 ? void 0 : _a.classList) || []), ...defaultClasses]
.filter((c, i, self) => !componentClasses.has(c) && self.indexOf(c) === i);
};
/**
* Create a callback to define a Vue component wrapper around a Web Component.
*
* @prop name - The component tag name (i.e. `ion-button`)
* @prop componentProps - An array of properties on the
* component. These usually match up with the @Prop definitions
* in each component's TSX file.
* @prop customElement - An option custom element instance to pass
* to customElements.define. Only set if `includeImportCustomElements: true` in your config.
* @prop modelProp - The prop that v-model binds to (i.e. value)
* @prop modelUpdateEvent - The event that is fired from your Web Component when the value changes (i.e. ionChange)
* @prop externalModelUpdateEvent - The external event to fire from your Vue component when modelUpdateEvent fires. This is used for ensuring that v-model references have been
* correctly updated when a user's event callback fires.
*/
const defineContainer = (name, defineCustomElement, componentProps = [], modelProp, modelUpdateEvent, externalModelUpdateEvent) => {
/**
* Create a Vue component wrapper around a Web Component.
* Note: The `props` here are not all properties on a component.
* They refer to whatever properties are set on an instance of a component.
*/
if (defineCustomElement !== undefined) {
defineCustomElement();
}
const Container = vue.defineComponent((props, { attrs, slots, emit }) => {
var _a;
let modelPropValue = props[modelProp];
const containerRef = vue.ref();
const classes = new Set(getComponentClasses(attrs.class));
const onVnodeBeforeMount = (vnode) => {
// Add a listener to tell Vue to update the v-model
if (vnode.el) {
const eventsNames = Array.isArray(modelUpdateEvent) ? modelUpdateEvent : [modelUpdateEvent];
eventsNames.forEach((eventName) => {
vnode.el.addEventListener(eventName.toLowerCase(), (e) => {
modelPropValue = (e === null || e === void 0 ? void 0 : e.target)[modelProp];
emit(UPDATE_VALUE_EVENT, modelPropValue);
/**
* We need to emit the change event here
* rather than on the web component to ensure
* that any v-model bindings have been updated.
* Otherwise, the developer will listen on the
* native web component, but the v-model will
* not have been updated yet.
*/
if (externalModelUpdateEvent) {
emit(externalModelUpdateEvent, e);
}
});
});
}
};
const currentInstance = vue.getCurrentInstance();
const hasRouter = (_a = currentInstance === null || currentInstance === void 0 ? void 0 : currentInstance.appContext) === null || _a === void 0 ? void 0 : _a.provides[NAV_MANAGER];
const navManager = hasRouter ? vue.inject(NAV_MANAGER) : undefined;
const handleRouterLink = (ev) => {
const { routerLink } = props;
if (routerLink === EMPTY_PROP)
return;
if (navManager !== undefined) {
let navigationPayload = { event: ev };
for (const key in props) {
const value = props[key];
if (props.hasOwnProperty(key) && key.startsWith(ROUTER_PROP_PREFIX) && value !== EMPTY_PROP) {
navigationPayload[key] = value;
}
}
navManager.navigate(navigationPayload);
}
else {
console.warn('Tried to navigate, but no router was found. Make sure you have mounted Vue Router.');
}
};
return () => {
modelPropValue = props[modelProp];
getComponentClasses(attrs.class).forEach(value => {
classes.add(value);
});
const oldClick = props.onClick;
const handleClick = (ev) => {
if (oldClick !== undefined) {
oldClick(ev);
}
if (!ev.defaultPrevented) {
handleRouterLink(ev);
}
};
let propsToAdd = {
ref: containerRef,
class: getElementClasses(containerRef, classes),
onClick: handleClick,
onVnodeBeforeMount: (modelUpdateEvent) ? onVnodeBeforeMount : undefined
};
/**
* We can use Object.entries here
* to avoid the hasOwnProperty check,
* but that would require 2 iterations
* where as this only requires 1.
*/
for (const key in props) {
const value = props[key];
if (props.hasOwnProperty(key) && value !== EMPTY_PROP) {
propsToAdd[key] = value;
}
}
if (modelProp) {
/**
* If form value property was set using v-model
* then we should use that value.
* Otherwise, check to see if form value property
* was set as a static value (i.e. no v-model).
*/
if (props[MODEL_VALUE] !== EMPTY_PROP) {
propsToAdd = Object.assign(Object.assign({}, propsToAdd), { [modelProp]: props[MODEL_VALUE] });
}
else if (modelPropValue !== EMPTY_PROP) {
propsToAdd = Object.assign(Object.assign({}, propsToAdd), { [modelProp]: modelPropValue });
}
}
return vue.h(name, propsToAdd, slots.default && slots.default());
};
});
Container.displayName = name;
Container.props = {
[ROUTER_LINK_VALUE]: DEFAULT_EMPTY_PROP
};
componentProps.forEach(componentProp => {
Container.props[componentProp] = DEFAULT_EMPTY_PROP;
});
if (modelProp) {
Container.props[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
Container.emits = [UPDATE_VALUE_EVENT, externalModelUpdateEvent];
}
return Container;
};
/* eslint-disable */
const IonAccordion = /*@__PURE__*/ defineContainer('ion-accordion', ionAccordion_js.defineCustomElement, [
'value',
'disabled',
'readonly',
'toggleIcon',
'toggleIconSlot'
]);
const IonAccordionGroup = /*@__PURE__*/ defineContainer('ion-accordion-group', ionAccordionGroup_js.defineCustomElement, [
'animated',
'multiple',
'value',
'disabled',
'readonly',
'expand',
'ionChange'
], 'value', 'v-ion-change', 'ionChange');
const IonAvatar = /*@__PURE__*/ defineContainer('ion-avatar', ionAvatar_js.defineCustomElement);
const IonBackdrop = /*@__PURE__*/ defineContainer('ion-backdrop', ionBackdrop_js.defineCustomElement, [
'visible',
'tappable',
'stopPropagation',
'ionBackdropTap'
]);
const IonBadge = /*@__PURE__*/ defineContainer('ion-badge', ionBadge_js.defineCustomElement, [
'color'
]);
const IonBreadcrumb = /*@__PURE__*/ defineContainer('ion-breadcrumb', ionBreadcrumb_js.defineCustomElement, [
'collapsed',
'last',
'showCollapsedIndicator',
'color',
'active',
'disabled',
'download',
'href',
'rel',
'separator',
'target',
'routerDirection',
'routerAnimation',
'ionFocus',
'ionBlur',
'collapsedClick'
]);
const IonBreadcrumbs = /*@__PURE__*/ defineContainer('ion-breadcrumbs', ionBreadcrumbs_js.defineCustomElement, [
'color',
'maxItems',
'itemsBeforeCollapse',
'itemsAfterCollapse',
'ionCollapsedClick'
]);
const IonButton = /*@__PURE__*/ defineContainer('ion-button', ionButton_js.defineCustomElement, [
'color',
'buttonType',
'disabled',
'expand',
'fill',
'routerDirection',
'routerAnimation',
'download',
'href',
'rel',
'shape',
'size',
'strong',
'target',
'type',
'form',
'ionFocus',
'ionBlur'
]);
const IonButtons = /*@__PURE__*/ defineContainer('ion-buttons', ionButtons_js.defineCustomElement, [
'collapse'
]);
const IonCard = /*@__PURE__*/ defineContainer('ion-card', ionCard_js.defineCustomElement, [
'color',
'button',
'type',
'disabled',
'download',
'href',
'rel',
'routerDirection',
'routerAnimation',
'target'
]);
const IonCardContent = /*@__PURE__*/ defineContainer('ion-card-content', ionCardContent_js.defineCustomElement);
const IonCardHeader = /*@__PURE__*/ defineContainer('ion-card-header', ionCardHeader_js.defineCustomElement, [
'color',
'translucent'
]);
const IonCardSubtitle = /*@__PURE__*/ defineContainer('ion-card-subtitle', ionCardSubtitle_js.defineCustomElement, [
'color'
]);
const IonCardTitle = /*@__PURE__*/ defineContainer('ion-card-title', ionCardTitle_js.defineCustomElement, [
'color'
]);
const IonCheckbox = /*@__PURE__*/ defineContainer('ion-checkbox', ionCheckbox_js.defineCustomElement, [
'color',
'name',
'checked',
'indeterminate',
'disabled',
'value',
'ionChange',
'ionFocus',
'ionBlur',
'ionStyle'
], 'checked', 'v-ion-change', 'ionChange');
const IonChip = /*@__PURE__*/ defineContainer('ion-chip', ionChip_js.defineCustomElement, [
'color',
'outline',
'disabled'
]);
const IonCol = /*@__PURE__*/ defineContainer('ion-col', ionCol_js.defineCustomElement, [
'offset',
'offsetXs',
'offsetSm',
'offsetMd',
'offsetLg',
'offsetXl',
'pull',
'pullXs',
'pullSm',
'pullMd',
'pullLg',
'pullXl',
'push',
'pushXs',
'pushSm',
'pushMd',
'pushLg',
'pushXl',
'size',
'sizeXs',
'sizeSm',
'sizeMd',
'sizeLg',
'sizeXl'
]);
const IonContent = /*@__PURE__*/ defineContainer('ion-content', ionContent_js.defineCustomElement, [
'color',
'fullscreen',
'forceOverscroll',
'scrollX',
'scrollY',
'scrollEvents',
'ionScrollStart',
'ionScroll',
'ionScrollEnd'
]);
const IonDatetime = /*@__PURE__*/ defineContainer('ion-datetime', ionDatetime_js.defineCustomElement, [
'color',
'name',
'disabled',
'readonly',
'isDateEnabled',
'min',
'max',
'presentation',
'cancelText',
'doneText',
'clearText',
'yearValues',
'monthValues',
'dayValues',
'hourValues',
'minuteValues',
'locale',
'firstDayOfWeek',
'titleSelectedDatesFormatter',
'multiple',
'value',
'showDefaultTitle',
'showDefaultButtons',
'showClearButton',
'showDefaultTimeLabel',
'hourCycle',
'size',
'preferWheel',
'ionCancel',
'ionChange',
'ionFocus',
'ionBlur',
'ionStyle',
'ionRender'
], 'value', 'v-ion-change', 'ionChange');
const IonDatetimeButton = /*@__PURE__*/ defineContainer('ion-datetime-button', ionDatetimeButton_js.defineCustomElement, [
'color',
'disabled',
'datetime'
]);
const IonFab = /*@__PURE__*/ defineContainer('ion-fab', ionFab_js.defineCustomElement, [
'horizontal',
'vertical',
'edge',
'activated'
]);
const IonFabButton = /*@__PURE__*/ defineContainer('ion-fab-button', ionFabButton_js.defineCustomElement, [
'color',
'activated',
'disabled',
'download',
'href',
'rel',
'routerDirection',
'routerAnimation',
'target',
'show',
'translucent',
'type',
'size',
'closeIcon',
'ionFocus',
'ionBlur'
]);
const IonFabList = /*@__PURE__*/ defineContainer('ion-fab-list', ionFabList_js.defineCustomElement, [
'activated',
'side'
]);
const IonFooter = /*@__PURE__*/ defineContainer('ion-footer', ionFooter_js.defineCustomElement, [
'collapse',
'translucent'
]);
const IonGrid = /*@__PURE__*/ defineContainer('ion-grid', ionGrid_js.defineCustomElement, [
'fixed'
]);
const IonHeader = /*@__PURE__*/ defineContainer('ion-header', ionHeader_js.defineCustomElement, [
'collapse',
'translucent'
]);
const IonImg = /*@__PURE__*/ defineContainer('ion-img', ionImg_js.defineCustomElement, [
'alt',
'src',
'ionImgWillLoad',
'ionImgDidLoad',
'ionError'
]);
const IonInfiniteScroll = /*@__PURE__*/ defineContainer('ion-infinite-scroll', ionInfiniteScroll_js.defineCustomElement, [
'threshold',
'disabled',
'position',
'ionInfinite'
]);
const IonInfiniteScrollContent = /*@__PURE__*/ defineContainer('ion-infinite-scroll-content', ionInfiniteScrollContent_js.defineCustomElement, [
'loadingSpinner',
'loadingText'
]);
const IonInput = /*@__PURE__*/ defineContainer('ion-input', ionInput_js.defineCustomElement, [
'fireFocusEvents',
'color',
'accept',
'autocapitalize',
'autocomplete',
'autocorrect',
'autofocus',
'clearInput',
'clearOnEdit',
'debounce',
'disabled',
'enterkeyhint',
'inputmode',
'max',
'maxlength',
'min',
'minlength',
'multiple',
'name',
'pattern',
'placeholder',
'readonly',
'required',
'spellcheck',
'step',
'size',
'type',
'value',
'ionInput',
'ionChange',
'ionBlur',
'ionFocus',
'ionStyle'
], 'value', 'v-ion-change', 'ionChange');
const IonItem = /*@__PURE__*/ defineContainer('ion-item', ionItem_js.defineCustomElement, [
'color',
'button',
'detail',
'detailIcon',
'disabled',
'download',
'fill',
'shape',
'href',
'rel',
'lines',
'counter',
'routerAnimation',
'routerDirection',
'target',
'type',
'counterFormatter'
]);
const IonItemDivider = /*@__PURE__*/ defineContainer('ion-item-divider', ionItemDivider_js.defineCustomElement, [
'color',
'sticky'
]);
const IonItemGroup = /*@__PURE__*/ defineContainer('ion-item-group', ionItemGroup_js.defineCustomElement);
const IonItemOption = /*@__PURE__*/ defineContainer('ion-item-option', ionItemOption_js.defineCustomElement, [
'color',
'disabled',
'download',
'expandable',
'href',
'rel',
'target',
'type'
]);
const IonItemOptions = /*@__PURE__*/ defineContainer('ion-item-options', ionItemOptions_js.defineCustomElement, [
'side',
'ionSwipe'
]);
const IonItemSliding = /*@__PURE__*/ defineContainer('ion-item-sliding', ionItemSliding_js.defineCustomElement, [
'disabled',
'ionDrag'
]);
const IonLabel = /*@__PURE__*/ defineContainer('ion-label', ionLabel_js.defineCustomElement, [
'color',
'position',
'ionColor',
'ionStyle'
]);
const IonList = /*@__PURE__*/ defineContainer('ion-list', ionList_js.defineCustomElement, [
'lines',
'inset'
]);
const IonListHeader = /*@__PURE__*/ defineContainer('ion-list-header', ionListHeader_js.defineCustomElement, [
'color',
'lines'
]);
const IonMenu = /*@__PURE__*/ defineContainer('ion-menu', ionMenu_js.defineCustomElement, [
'contentId',
'menuId',
'type',
'disabled',
'side',
'swipeGesture',
'maxEdgeStart',
'ionWillOpen',
'ionWillClose',
'ionDidOpen',
'ionDidClose',
'ionMenuChange'
]);
const IonMenuButton = /*@__PURE__*/ defineContainer('ion-menu-button', ionMenuButton_js.defineCustomElement, [
'color',
'disabled',
'menu',
'autoHide',
'type'
]);
const IonMenuToggle = /*@__PURE__*/ defineContainer('ion-menu-toggle', ionMenuToggle_js.defineCustomElement, [
'menu',
'autoHide'
]);
const IonNavLink = /*@__PURE__*/ defineContainer('ion-nav-link', ionNavLink_js.defineCustomElement, [
'component',
'componentProps',
'routerDirection',
'routerAnimation'
]);
const IonNote = /*@__PURE__*/ defineContainer('ion-note', ionNote_js.defineCustomElement, [
'color'
]);
const IonProgressBar = /*@__PURE__*/ defineContainer('ion-progress-bar', ionProgressBar_js.defineCustomElement, [
'type',
'reversed',
'value',
'buffer',
'color'
]);
const IonRadio = /*@__PURE__*/ defineContainer('ion-radio', ionRadio_js.defineCustomElement, [
'color',
'name',
'disabled',
'value',
'ionStyle',
'ionFocus',
'ionBlur'
], 'value', 'v-ion-change', 'ionChange');
const IonRadioGroup = /*@__PURE__*/ defineContainer('ion-radio-group', ionRadioGroup_js.defineCustomElement, [
'allowEmptySelection',
'name',
'value',
'ionChange'
], 'value', 'v-ion-change', 'ionChange');
const IonRange = /*@__PURE__*/ defineContainer('ion-range', ionRange_js.defineCustomElement, [
'color',
'debounce',
'name',
'dualKnobs',
'min',
'max',
'pin',
'pinFormatter',
'snaps',
'step',
'ticks',
'activeBarStart',
'disabled',
'value',
'ionChange',
'ionStyle',
'ionFocus',
'ionBlur',
'ionKnobMoveStart',
'ionKnobMoveEnd'
], 'value', 'v-ion-change', 'ionChange');
const IonRefresher = /*@__PURE__*/ defineContainer('ion-refresher', ionRefresher_js.defineCustomElement, [
'pullMin',
'pullMax',
'closeDuration',
'snapbackDuration',
'pullFactor',
'disabled',
'ionRefresh',
'ionPull',
'ionStart'
]);
const IonRefresherContent = /*@__PURE__*/ defineContainer('ion-refresher-content', ionRefresherContent_js.defineCustomElement, [
'pullingIcon',
'pullingText',
'refreshingSpinner',
'refreshingText'
]);
const IonReorder = /*@__PURE__*/ defineContainer('ion-reorder', ionReorder_js.defineCustomElement);
const IonReorderGroup = /*@__PURE__*/ defineContainer('ion-reorder-group', ionReorderGroup_js.defineCustomElement, [
'disabled',
'ionItemReorder'
]);
const IonRippleEffect = /*@__PURE__*/ defineContainer('ion-ripple-effect', ionRippleEffect_js.defineCustomElement, [
'type'
]);
const IonRow = /*@__PURE__*/ defineContainer('ion-row', ionRow_js.defineCustomElement);
const IonSearchbar = /*@__PURE__*/ defineContainer('ion-searchbar', ionSearchbar_js.defineCustomElement, [
'color',
'animated',
'autocomplete',
'autocorrect',
'cancelButtonIcon',
'cancelButtonText',
'clearIcon',
'debounce',
'disabled',
'inputmode',
'enterkeyhint',
'placeholder',
'searchIcon',
'showCancelButton',
'showClearButton',
'spellcheck',
'type',
'value',
'ionInput',
'ionChange',
'ionCancel',
'ionClear',
'ionBlur',
'ionFocus',
'ionStyle'
], 'value', 'v-ion-change', 'ionChange');
const IonSegment = /*@__PURE__*/ defineContainer('ion-segment', ionSegment_js.defineCustomElement, [
'color',
'disabled',
'scrollable',
'swipeGesture',
'value',
'selectOnFocus',
'ionChange',
'ionSelect',
'ionStyle'
], 'value', 'v-ion-change', 'ionChange');
const IonSegmentButton = /*@__PURE__*/ defineContainer('ion-segment-button', ionSegmentButton_js.defineCustomElement, [
'disabled',
'layout',
'type',
'value'
], 'value', 'v-ion-change', 'ionChange');
const IonSelect = /*@__PURE__*/ defineContainer('ion-select', ionSelect_js.defineCustomElement, [
'disabled',
'cancelText',
'okText',
'placeholder',
'name',
'selectedText',
'multiple',
'interface',
'interfaceOptions',
'compareWith',
'value',
'ionChange',
'ionCancel',
'ionDismiss',
'ionFocus',
'ionBlur',
'ionStyle'
], 'value', 'v-ion-change', 'ionChange');
const IonSelectOption = /*@__PURE__*/ defineContainer('ion-select-option', ionSelectOption_js.defineCustomElement, [
'disabled',
'value'
]);
const IonSkeletonText = /*@__PURE__*/ defineContainer('ion-skeleton-text', ionSkeletonText_js.defineCustomElement, [
'animated'
]);
const IonSlide = /*@__PURE__*/ defineContainer('ion-slide', ionSlide_js.defineCustomElement);
const IonSlides = /*@__PURE__*/ defineContainer('ion-slides', ionSlides_js.defineCustomElement, [
'options',
'pager',
'scrollbar',
'ionSlidesDidLoad',
'ionSlideTap',
'ionSlideDoubleTap',
'ionSlideWillChange',
'ionSlideDidChange',
'ionSlideNextStart',
'ionSlidePrevStart',
'ionSlideNextEnd',
'ionSlidePrevEnd',
'ionSlideTransitionStart',
'ionSlideTransitionEnd',
'ionSlideDrag',
'ionSlideReachStart',
'ionSlideReachEnd',
'ionSlideTouchStart',
'ionSlideTouchEnd'
]);
const IonSpinner = /*@__PURE__*/ defineContainer('ion-spinner', ionSpinner_js.defineCustomElement, [
'color',
'duration',
'name',
'paused'
]);
const IonSplitPane = /*@__PURE__*/ defineContainer('ion-split-pane', ionSplitPane_js.defineCustomElement, [
'contentId',
'disabled',
'when',
'ionSplitPaneVisible'
]);
const IonText = /*@__PURE__*/ defineContainer('ion-text', ionText_js.defineCustomElement, [
'color'
]);
const IonTextarea = /*@__PURE__*/ defineContainer('ion-textarea', ionTextarea_js.defineCustomElement, [
'fireFocusEvents',
'color',
'autocapitalize',
'autofocus',
'clearOnEdit',
'debounce',
'disabled',
'inputmode',
'enterkeyhint',
'maxlength',
'minlength',
'name',
'placeholder',
'readonly',
'required',
'spellcheck',
'cols',
'rows',
'wrap',
'autoGrow',
'value',
'ionChange',
'ionInput',
'ionStyle',
'ionBlur',
'ionFocus'
], 'value', 'v-ion-change', 'ionChange');
const IonThumbnail = /*@__PURE__*/ defineContainer('ion-thumbnail', ionThumbnail_js.defineCustomElement);
const IonTitle = /*@__PURE__*/ defineContainer('ion-title', ionTitle_js.defineCustomElement, [
'color',
'size',
'ionStyle'
]);
const IonToggle = /*@__PURE__*/ defineContainer('ion-toggle', ionToggle_js.defineCustomElement, [
'color',
'name',
'checked',
'disabled',
'value',
'enableOnOffLabels',
'ionChange',
'ionFocus',
'ionBlur',
'ionStyle'
], 'checked', 'v-ion-change', 'ionChange');
const IonToolbar = /*@__PURE__*/ defineContainer('ion-toolbar', ionToolbar_js.defineCustomElement, [
'color'
]);
const IonVirtualScroll = /*@__PURE__*/ defineContainer('ion-virtual-scroll', ionVirtualScroll_js.defineCustomElement, [
'approxItemHeight',
'approxHeaderHeight',
'approxFooterHeight',
'headerFn',
'footerFn',
'items',
'itemHeight',
'headerHeight',
'footerHeight',
'renderItem',
'renderHeader',
'renderFooter',
'nodeRender',
'domRender'
]);
const useBackButton = (priority, handler) => {
const callback = (ev) => ev.detail.register(priority, handler);
const unregister = () => document.removeEventListener('ionBackButton', callback);
document.addEventListener('ionBackButton', callback);
return { unregister };
};
const useKeyboard = () => {
let isOpen = vue.ref(false);
let keyboardHeight = vue.ref(0);
const showCallback = (ev) => {
isOpen.value = true;
keyboardHeight.value = ev.detail.keyboardHeight;
};
const hideCallback = () => {
isOpen.value = false;
keyboardHeight.value = 0;
};
const unregister = () => {
if (typeof window !== 'undefined') {
window.removeEventListener('ionKeyboardDidShow', showCallback);
window.removeEventListener('ionKeyboardDidHide', hideCallback);
}
};
if (typeof window !== 'undefined') {
window.addEventListener('ionKeyboardDidShow', showCallback);
window.addEventListener('ionKeyboardDidHide', hideCallback);
}
return {
isOpen,
keyboardHeight,
unregister
};
};
var LifecycleHooks;
(function (LifecycleHooks) {
LifecycleHooks["WillEnter"] = "onIonViewWillEnter";
LifecycleHooks["DidEnter"] = "onIonViewDidEnter";
LifecycleHooks["WillLeave"] = "onIonViewWillLeave";
LifecycleHooks["DidLeave"] = "onIonViewDidLeave";
})(LifecycleHooks || (LifecycleHooks = {}));
const hookNames = {
[components.LIFECYCLE_WILL_ENTER]: LifecycleHooks.WillEnter,
[components.LIFECYCLE_DID_ENTER]: LifecycleHooks.DidEnter,
[components.LIFECYCLE_WILL_LEAVE]: LifecycleHooks.WillLeave,
[components.LIFECYCLE_DID_LEAVE]: LifecycleHooks.DidLeave
};
const ids = { main: 0 };
const generateId = (type = 'main') => {
var _a;
const id = ((_a = ids[type]) !== null && _a !== void 0 ? _a : 0) + 1;
ids[type] = id;
return (id).toString();
};
const fireLifecycle = (vueComponent, vueInstance, lifecycle) => {
if (vueComponent === null || vueComponent === void 0 ? void 0 : vueComponent[lifecycle]) {
vueComponent[lifecycle].bind(vueInstance === null || vueInstance === void 0 ? void 0 : vueInstance.value)();
}
const instance = vueInstance === null || vueInstance === void 0 ? void 0 : vueInstance.value;
if (instance === null || instance === void 0 ? void 0 : instance[lifecycle]) {
instance[lifecycle]();
}
/**
* Fire any Composition API
* Ionic Lifecycle hooks
*/
if (instance) {
const hook = hookNames[lifecycle];
const hooks = instance[hook];
if (hooks) {
hooks.forEach((hook) => hook());
}
}
};
const getConfig = () => {
if (typeof window !== 'undefined') {
const Ionic = window.Ionic;
if (Ionic && Ionic.config) {
return Ionic.config;
}
}
return null;
};
/**
* Creates an returns a function that
* can be used to provide a lifecycle hook.
*/
const injectHook = (lifecycleType, hook, component) => {
if (component) {
// Add to public instance so it is accessible to IonRouterOutlet
const target = component;
const hooks = target.proxy[lifecycleType] || (target.proxy[lifecycleType] = []);
/**
* Define property on public instances using `setup` syntax in Vue 3.x
*/
if (target.exposed) {
target.exposed[lifecycleType] = hooks;
}
const wrappedHook = (...args) => {
if (target.isUnmounted) {
return;
}
return args ? hook(...args) : hook();
};
hooks.push(wrappedHook);
return wrappedHook;
}
else {
console.warn('[@ionic/vue]: Ionic Lifecycle Hooks can only be used during execution of setup().');
}
};
const createHook = (lifecycle) => {
return (hook, target = vue.getCurrentInstance()) => injectHook(lifecycle, hook, target);
};
const onIonViewWillEnter = createHook(LifecycleHooks.WillEnter);
const onIonViewDidEnter = createHook(LifecycleHooks.DidEnter);
const onIonViewWillLeave = createHook(LifecycleHooks.WillLeave);
const onIonViewDidLeave = createHook(LifecycleHooks.DidLeave);
/**
* Used to navigate within Vue Router
* while controlling the animation.
*/
const useIonRouter = () => {
const { canGoBack, goBack, goForward, handleNavigate } = vue.inject('navManager');
const navigate = (location, routerDirection, routerAction, routerAnimation) => handleNavigate(location, routerAction, routerDirection, routerAnimation);
const push = (location, routerAnimation) => navigate(location, 'forward', 'push', routerAnimation);
const replace = (location, routerAnimation) => navigate(location, 'root', 'replace', routerAnimation);
const back = (routerAnimation) => goBack(routerAnimation);
const forward = (routerAnimation) => goForward(routerAnimation);
return {
canGoBack,
push,
replace,
back,
forward,
navigate
};
};
/**
* We need to make sure that the web component fires an event
* that will not conflict with the user's @ionChange binding,
* otherwise the binding's callback will fire before any
* v-model values have been updated.
*/
const toKebabCase = (eventName) => eventName === 'ionChange' ? 'v-ion-change' : eventName.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
const getHelperFunctions = () => {
return {
ael: (el, eventName, cb, opts) => el.addEventListener(toKebabCase(eventName), cb, opts),
rel: (el, eventName, cb, opts) => el.removeEventListener(toKebabCase(eventName), cb, opts),
ce: (eventName, opts) => new CustomEvent(toKebabCase(eventName), opts)
};
};
const IonicVue = {
async install(_, config = {}) {
/**
* By default Ionic Framework hides elements that
* are not hydrated, but in the CE build there is no
* hydration.
* TODO FW-2797: Remove when all integrations have been
* migrated to CE build.
*/
if (typeof document !== 'undefined') {
document.documentElement.classList.add('ion-ce');
}
const { ael, rel, ce } = getHelperFunctions();
components.initialize(Object.assign(Object.assign({}, config), { _ael: ael, _rel: rel, _ce: ce }));
}
};
const IonBackButton = /*@__PURE__*/ vue.defineComponent((_, { attrs, slots }) => {
ionBackButton_js.defineCustomElement();
const ionRouter = vue.inject('navManager');
const onClick = () => {
/**
* When using ion-back-button outside of
* a routing context, ionRouter is undefined.
*/
if (ionRouter === undefined) {
return;
}
const defaultHref = attrs['default-href'] || attrs['defaultHref'];
const routerAnimation = attrs['router-animation'] || attrs['routerAnimation'];
ionRouter.handleNavigateBack(defaultHref, routerAnimation);
};
return () => {
return vue.h('ion-back-button', Object.assign({ onClick }, attrs), slots.default && slots.default());
};
});
const IonPage = /*@__PURE__*/ vue.defineComponent({
name: 'IonPage',
props: {
registerIonPage: { type: Function, default: () => { } }
},
mounted() {
this.$props.registerIonPage(this.$refs.ionPage);
},
setup(_, { attrs, slots }) {
return () => {
return vue.h('div', Object.assign(Object.assign({}, attrs), { ['class']: 'ion-page', ref: 'ionPage' }), slots.default && slots.default());
};
}
});
const isViewVisible = (enteringEl) => {
return !enteringEl.classList.contains('ion-page-hidden') && !enteringEl.classList.contains('ion-page-invisible');
};
let viewDepthKey = Symbol(0);
const IonRouterOutlet = /*@__PURE__*/ vue.defineComponent({
name: 'IonRouterOutlet',
setup() {
ionRouterOutlet_js.defineCustomElement();
const injectedRoute = vue.inject(vueRouter.routeLocationKey);
const route = vueRouter.useRoute();
const depth = vue.inject(viewDepthKey, 0);
const matchedRouteRef = vue.computed(() => route.matched[depth]);
let previousMatchedRouteRef;
let previousMatchedPath;
vue.provide(viewDepthKey, depth + 1);
vue.provide(vueRouter.matchedRouteKey, matchedRouteRef);
const ionRouterOutlet = vue.ref();
const id = generateId('ion-router-outlet');
const ionRouter = vue.inject('navManager');
const viewStacks = vue.inject('viewStacks');
const components$1 = vue.shallowRef([]);
let skipTransition = false;
// The base url for this router outlet
let parentOutletPath;
/**
* Note: Do not listen for matchedRouteRef by itself here
* as the callback will not fire for parameterized routes (i.e. /page/:id).
* So going from /page/1 to /page/2 would not fire this callback if we
* only listened for changes to matchedRouteRef.
*/
vue.watch(() => [route, matchedRouteRef.value], ([currentRoute, currentMatchedRouteRef]) => {
/**
* This callback checks whether or not a router outlet
* needs to respond to a change in the matched route.
* It handles a few cases:
* 1. The matched route is undefined. This means that
* the matched route is not applicable to this outlet.
* For example, a /settings route is not applicable
* to a /tabs/... route.
*
* Note: When going back to a tabs outlet from a non-tabs outlet,
* the tabs outlet should NOT attempt a page transition from the
* previous tab to the active tab. To do this we compare the current
* route with the previous route. Unfortunately, we cannot rely on the
* previous value provided by Vue in the watch callback. This is because
* when coming back to the tabs context, the previous matched route will
* be undefined (because nothing in the tabs context matches /settings)
* but the current matched route will be defined and so a transition
* will always occur.
*
* 2. The matched route is defined and is different than
* the previously matched route. This is the most
* common case such as when you go from /page1 to /page2.
*
* 3. The matched route is the same but the parameters are different.
* This is a special case for parameterized routes (i.e. /page/:id).
* When going from /page/1 to /page/2, the matched route object will
* be the same, but we still need to perform a page transition. To do this
* we check if the parameters are different (i.e. 1 vs 2). To avoid enumerating
* all of the keys in the params object, we check the url path to
* see if they are different after ensuring we are in a parameterized route.
*/
if (currentMatchedRouteRef !== undefined) {
const matchedDifferentRoutes = currentMatchedRouteRef !== previousMatchedRouteRef;
const matchedDifferentParameterRoutes = (currentRoute.matched[currentRoute.matched.length - 1] === currentMatchedRouteRef &&
currentRoute.path !== previousMatchedPath);
if (matchedDifferentRoutes || matchedDifferentParameterRoutes) {
setupViewItem(matchedRouteRef);
}
}
previousMatchedRouteRef = currentMatchedRouteRef;
previousMatchedPath = currentRoute.path;
});
const canStart = () => {
const config = getConfig();
const swipeEnabled = config && config.get('swipeBackEnabled', ionRouterOutlet.value.mode === 'ios');
if (!swipeEnabled)
return false;
const stack = viewStacks.getViewStack(id);
if (!stack || stack.length <= 1)
return false;
/**
* We only want to outlet of the entering view
* to respond to this gesture, so check
* to make sure the view is in the outlet we want.
*/
const routeInfo = ionRouter.getLeavingRouteInfo();
const enteringViewItem = viewStacks.findViewItemByRouteInfo({ pathname: routeInfo.pushedByRoute || '' }, id);
return !!enteringViewItem;
};
const onStart = async () => {
const routeInfo = ionRouter.getLeavingRouteInfo();
const { routerAnimation } = routeInfo;
const enteringViewItem = viewStacks.findViewItemByRouteInfo({ pathname: routeInfo.pushedByRoute || '' }, id);
const leavingViewItem = viewStacks.findViewItemByRouteInfo(routeInfo, id);
if (leavingViewItem) {
let animationBuilder = routerAnimation;
const enteringEl = enteringViewItem.ionPageElement;
const leavingEl = leavingViewItem.ionPageElement;
/**
* If we are going back from a page that
* was presented using a custom animation
* we should default to using that
* unless the developer explicitly
* provided another animation.
*/
const customAnimation = enteringViewItem.routerAnimation;
if (animationBuilder === undefined &&
customAnimation !== undefined) {
animationBuilder = customAnimation;
}
leavingViewItem.routerAnimation = animationBuilder;
await transition(enteringEl, leavingEl, 'back', ionRouter.canGoBack(2), true, animationBuilder);
}
return Promise.resolve();
};
const onEnd = (shouldContinue) => {
if (shouldContinue) {
skipTransition = true;
/**
* Use the same logic as clicking
* ion-back-button to determine where
* to go back to.
*/
ionRouter.handleNavigateBack();
}
else {
/**
* In the event that the swipe
* gesture was aborted, we should
* re-hide the page that was going to enter.
*/
const routeInfo = ionRouter.getCurrentRouteInfo();
const enteringViewItem = viewStacks.findViewItemByRouteInfo({ pathname: routeInfo.pushedByRoute || '' }, id);
enteringViewItem.ionPageElement.setAttribute('aria-hidden', 'true');
enteringViewItem.ionPageElement.classList.add('ion-page-hidden');
}
};
vue.watch(ionRouterOutlet, () => {
ionRouterOutlet.value.swipeHandler = {
canStart,
onStart,
onEnd
};
});
const transition = (enteringEl, leavingEl, direction, showGoBack, progressAnimation, animationBuilder) => {
return new Promise(resolve => {
if (skipTransition) {
skipTransition = false;
return resolve(false);
}
if (enteringEl === leavingEl) {
return resolve(false);
}
requestAnimationFrame(() => {
requestAnimationFrame(async () => {
enteringEl.classList.add('ion-page-invisible');
const hasRootDirection = direction === undefined || direction === 'root' || direction === 'none';
const result = await ionRouterOutlet.value.commit(enteringEl, leavingEl, {
deepWait: true,
/**
* replace operations result in a direction of none.
* These typically do not have need animations, so we set
* the duration to 0. However, if a developer explicitly
* passes an animationBuilder, we should assume that
* they want an animation to be played even
* though it is a replace operation.
*/
duration: hasRootDirection && animationBuilder === undefined ? 0 : undefined,
direction,
showGoBack,
progressAnimation,
animationBuilder
});
return resolve(result);
});
});
});
};
const handlePageTransition = async () => {
const routeInfo = ionRouter.getCurrentRouteInfo();
const { routerDirection, routerAction, routerAnimation, prevRouteLastPathname, delta } = routeInfo;
const enteringViewItem = viewStacks.findViewItemByRouteInfo(routeInfo, id);
let leavingViewItem = viewStacks.findLeavingViewItemByRouteInfo(routeInfo, id);
const enteringEl = enteringViewItem.ionPageElement;
/**
* All views that can be transitioned to must have
* an `<ion-page>` element for transitions and lifecycle
* methods to work properly.
*/
if (enteringEl === undefined) {
console.warn(`[@ionic/vue Warning]: The view you are trying to render for path ${routeInfo.pathname} does not have the required <ion-page> component. Transitions and lifecycle methods may not work as expected.
See https://ionicframework.com/docs/vue/navigation#ionpage for more information.`);
}
if (enteringViewItem === leavingViewItem)
return;
if (!leavingViewItem && prevRouteLastPathname) {
leavingViewItem = viewStacks.findViewItemByPathname(prevRouteLastPathname, id);
}
/**
* If the entering view is already
* visible, then no transition is needed.
* This is most common when navigating
* from a tabs page to a non-tabs page
* and then back to the tabs page.
* Even when the tabs context navigated away,
* the inner tabs page was still active.
* This also avoids an issue where
* the previous tabs page is incorrectly
* unmounted since it would automatically
* unmount the previous view.
*
* This should also only apply to entering and
* leaving items in the same router outlet (i.e.
* Tab1 and Tab2), otherwise this will
* return early for swipe to go back when
* going from a non-tabs page to a tabs page.
*/
if (isViewVisible(enteringEl) && (leavingViewItem === null || leavingViewItem === void 0 ? void 0 : leavingViewItem.ionPageElement) !== undefined && !isViewVisible(leavingViewItem.ionPageElement)) {
return;
}
fireLifecycle(enteringViewItem.vueComponent, enteringViewItem.vueComponentRef, components.LIFECYCLE_WILL_ENTER);
if ((leavingViewItem === null || leavingViewItem === void 0 ? void 0 : leavingViewItem.ionPageElement) && enteringViewItem !== leavingViewItem) {
let animationBuilder = routerAnimation;
const leavingEl = leavingViewItem.ionPageElement;
fireLifecycle(leavingViewItem.vueComponent, leavingViewItem.vueComponentRef, components.LIFECYCLE_WILL_LEAVE);
/**
* If we are going back from a page that
* was presented using a custom a