mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
merge release-6.2.0
Release 6.2.0
This commit is contained in:
@ -3,6 +3,27 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [6.2.0](https://github.com/ionic-team/ionic/compare/v6.1.15...v6.2.0) (2022-07-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **vue:** input v-model accepts numbers ([#25666](https://github.com/ionic-team/ionic/issues/25666)) ([ab65e9a](https://github.com/ionic-team/ionic/commit/ab65e9a7b51c3a3f8c59962d3e1faff1564ab801)), closes [#25575](https://github.com/ionic-team/ionic/issues/25575)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **angular, react, vue:** add support for autoMountComponent ([#25552](https://github.com/ionic-team/ionic/issues/25552)) ([805dfa0](https://github.com/ionic-team/ionic/commit/805dfa05663098ef9c02b0745a383b5e7555908b))
|
||||
* **datetime-button:** add button for displaying datetime in overlays ([#25655](https://github.com/ionic-team/ionic/issues/25655)) ([4997331](https://github.com/ionic-team/ionic/commit/499733105e4be23405e8afeeb26fee5cd2afc25b)), closes [#24316](https://github.com/ionic-team/ionic/issues/24316)
|
||||
* **datetime:** add multiple date selection ([#25514](https://github.com/ionic-team/ionic/issues/25514)) ([9d31608](https://github.com/ionic-team/ionic/commit/9d31608f2d471f531eb253832c8558d1effaf68a))
|
||||
* **datetime:** add wheel style picker for dates and times ([#25468](https://github.com/ionic-team/ionic/issues/25468)) ([3d19771](https://github.com/ionic-team/ionic/commit/3d19771185301870a2eb60f1ef4afd6f1c182494))
|
||||
* **modal:** clicking handle advances to the next breakpoint ([#25540](https://github.com/ionic-team/ionic/issues/25540)) ([7cdc388](https://github.com/ionic-team/ionic/commit/7cdc388b7805cbf23c9e1e928aa977cd77ebc8c4)), closes [#24069](https://github.com/ionic-team/ionic/issues/24069)
|
||||
* **range:** add reference point for start position of range slider ([#25598](https://github.com/ionic-team/ionic/issues/25598)) ([c2781cc](https://github.com/ionic-team/ionic/commit/c2781cc1c3b7e56a0e6f6c03cfa04fc2c82d6e8a)), closes [#24348](https://github.com/ionic-team/ionic/issues/24348)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [6.1.15](https://github.com/ionic-team/ionic/compare/v6.1.14...v6.1.15) (2022-07-20)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue
|
||||
|
18
packages/vue/package-lock.json
generated
18
packages/vue/package-lock.json
generated
@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "6.1.15",
|
||||
"version": "6.2.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/vue",
|
||||
"version": "6.1.15",
|
||||
"version": "6.2.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.1.15",
|
||||
"@ionic/core": "^6.2.0",
|
||||
"ionicons": "^6.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -59,9 +59,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ionic/core": {
|
||||
"version": "6.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.15.tgz",
|
||||
"integrity": "sha512-NvBlHR7O4kfp9KYz6oLsghFzGZImA7hM4qS4tFRUI62R+Q5iCJEY4OmXE5bif5K+SQkMhQY+x1l2Nq20waLzLg==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.0.tgz",
|
||||
"integrity": "sha512-3qUNsVcSAdrjhIhPr5M2RRnh+1xuc9RFaxoeUgI9xQ0YjTmn2FWiH4urDCXuE/rZAwnvHF4X17P0L2EqCPSfWA==",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
@ -768,9 +768,9 @@
|
||||
}
|
||||
},
|
||||
"@ionic/core": {
|
||||
"version": "6.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.1.15.tgz",
|
||||
"integrity": "sha512-NvBlHR7O4kfp9KYz6oLsghFzGZImA7hM4qS4tFRUI62R+Q5iCJEY4OmXE5bif5K+SQkMhQY+x1l2Nq20waLzLg==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.0.tgz",
|
||||
"integrity": "sha512-3qUNsVcSAdrjhIhPr5M2RRnh+1xuc9RFaxoeUgI9xQ0YjTmn2FWiH4urDCXuE/rZAwnvHF4X17P0L2EqCPSfWA==",
|
||||
"requires": {
|
||||
"@stencil/core": "^2.16.0",
|
||||
"ionicons": "^6.0.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "6.1.15",
|
||||
"version": "6.2.0",
|
||||
"description": "Vue specific wrapper for @ionic/core",
|
||||
"scripts": {
|
||||
"prepublishOnly": "npm run build",
|
||||
@ -61,7 +61,7 @@
|
||||
"vue-router": "^4.0.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^6.1.15",
|
||||
"@ionic/core": "^6.2.0",
|
||||
"ionicons": "^6.0.2"
|
||||
},
|
||||
"vetur": {
|
||||
|
@ -29,7 +29,7 @@ export const IonPicker = /*@__PURE__*/ defineOverlayContainer<JSX.IonPicker>('io
|
||||
|
||||
export const IonToast = /*@__PURE__*/ defineOverlayContainer<JSX.IonToast>('ion-toast', defineIonToastCustomElement, ['animated', 'buttons', 'color', 'cssClass', 'duration', 'enterAnimation', 'header', 'htmlAttributes', 'icon', 'keyboardClose', 'leaveAnimation', 'message', 'mode', 'position', 'translucent'], toastController);
|
||||
|
||||
export const IonModal = /*@__PURE__*/ defineOverlayContainer<JSX.IonModal>('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'handle', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'swipeToClose', 'trigger']);
|
||||
export const IonModal = /*@__PURE__*/ defineOverlayContainer<JSX.IonModal>('ion-modal', defineIonModalCustomElement, ['animated', 'backdropBreakpoint', 'backdropDismiss', 'breakpoints', 'canDismiss', 'enterAnimation', 'handle', 'handleBehavior', 'htmlAttributes', 'initialBreakpoint', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'presentingElement', 'showBackdrop', 'swipeToClose', 'trigger']);
|
||||
|
||||
export const IonPopover = /*@__PURE__*/ defineOverlayContainer<JSX.IonPopover>('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'translucent', 'trigger', 'triggerAction']);
|
||||
export const IonPopover = /*@__PURE__*/ defineOverlayContainer<JSX.IonPopover>('ion-popover', defineIonPopoverCustomElement, ['alignment', 'animated', 'arrow', 'backdropDismiss', 'component', 'componentProps', 'dismissOnSelect', 'enterAnimation', 'event', 'htmlAttributes', 'isOpen', 'keepContentsMounted', 'keyboardClose', 'leaveAnimation', 'mode', 'reference', 'showBackdrop', 'side', 'size', 'translucent', 'trigger', 'triggerAction']);
|
||||
|
||||
|
@ -24,6 +24,7 @@ import { defineCustomElement as defineIonChip } from '@ionic/core/components/ion
|
||||
import { defineCustomElement as defineIonCol } from '@ionic/core/components/ion-col.js';
|
||||
import { defineCustomElement as defineIonContent } from '@ionic/core/components/ion-content.js';
|
||||
import { defineCustomElement as defineIonDatetime } from '@ionic/core/components/ion-datetime.js';
|
||||
import { defineCustomElement as defineIonDatetimeButton } from '@ionic/core/components/ion-datetime-button.js';
|
||||
import { defineCustomElement as defineIonFab } from '@ionic/core/components/ion-fab.js';
|
||||
import { defineCustomElement as defineIonFabButton } from '@ionic/core/components/ion-fab-button.js';
|
||||
import { defineCustomElement as defineIonFabList } from '@ionic/core/components/ion-fab-list.js';
|
||||
@ -285,6 +286,7 @@ export const IonDatetime = /*@__PURE__*/ defineContainer<JSX.IonDatetime>('ion-d
|
||||
'minuteValues',
|
||||
'locale',
|
||||
'firstDayOfWeek',
|
||||
'multiple',
|
||||
'value',
|
||||
'showDefaultTitle',
|
||||
'showDefaultButtons',
|
||||
@ -292,15 +294,24 @@ export const IonDatetime = /*@__PURE__*/ defineContainer<JSX.IonDatetime>('ion-d
|
||||
'showDefaultTimeLabel',
|
||||
'hourCycle',
|
||||
'size',
|
||||
'preferWheel',
|
||||
'ionCancel',
|
||||
'ionChange',
|
||||
'ionFocus',
|
||||
'ionBlur',
|
||||
'ionStyle'
|
||||
'ionStyle',
|
||||
'ionRender'
|
||||
],
|
||||
'value', 'v-ion-change', 'ionChange');
|
||||
|
||||
|
||||
export const IonDatetimeButton = /*@__PURE__*/ defineContainer<JSX.IonDatetimeButton>('ion-datetime-button', defineIonDatetimeButton, [
|
||||
'color',
|
||||
'disabled',
|
||||
'datetime'
|
||||
]);
|
||||
|
||||
|
||||
export const IonFab = /*@__PURE__*/ defineContainer<JSX.IonFab>('ion-fab', defineIonFab, [
|
||||
'horizontal',
|
||||
'vertical',
|
||||
@ -586,6 +597,7 @@ export const IonRange = /*@__PURE__*/ defineContainer<JSX.IonRange>('ion-range',
|
||||
'snaps',
|
||||
'step',
|
||||
'ticks',
|
||||
'activeBarStart',
|
||||
'disabled',
|
||||
'value',
|
||||
'ionChange',
|
||||
@ -816,6 +828,7 @@ export const IonToggle = /*@__PURE__*/ defineContainer<JSX.IonToggle>('ion-toggl
|
||||
'checked',
|
||||
'disabled',
|
||||
'value',
|
||||
'enableOnOffLabels',
|
||||
'ionChange',
|
||||
'ionFocus',
|
||||
'ionBlur',
|
||||
|
@ -162,7 +162,7 @@ export const defineOverlayContainer = <Props extends object>(name: string, defin
|
||||
return h(
|
||||
name,
|
||||
{ ...restOfProps, ref: elementRef },
|
||||
(isOpen.value) ? slots : undefined
|
||||
(isOpen.value || restOfProps.keepContentsMounted) ? slots : undefined
|
||||
)
|
||||
}
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { VNode, defineComponent, getCurrentInstance, h, inject, ref, Ref } from 'vue';
|
||||
|
||||
export interface InputProps {
|
||||
modelValue?: string | boolean;
|
||||
export interface InputProps<T> {
|
||||
modelValue?: T;
|
||||
}
|
||||
|
||||
const UPDATE_VALUE_EVENT = 'update:modelValue';
|
||||
@ -49,7 +49,7 @@ const getElementClasses = (ref: Ref<HTMLElement | undefined>, componentClasses:
|
||||
* @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.
|
||||
*/
|
||||
export const defineContainer = <Props>(
|
||||
export const defineContainer = <Props, VModelType=string|number|boolean>(
|
||||
name: string,
|
||||
defineCustomElement: any,
|
||||
componentProps: string[] = [],
|
||||
@ -67,7 +67,7 @@ export const defineContainer = <Props>(
|
||||
defineCustomElement();
|
||||
}
|
||||
|
||||
const Container = defineComponent<Props & InputProps>((props: any, { attrs, slots, emit }) => {
|
||||
const Container = defineComponent<Props & InputProps<VModelType>>((props: any, { attrs, slots, emit }) => {
|
||||
let modelPropValue = props[modelProp];
|
||||
const containerRef = ref<HTMLElement>();
|
||||
const classes = new Set(getComponentClasses(attrs.class));
|
||||
@ -76,7 +76,7 @@ export const defineContainer = <Props>(
|
||||
if (vnode.el) {
|
||||
const eventsNames = Array.isArray(modelUpdateEvent) ? modelUpdateEvent : [modelUpdateEvent];
|
||||
eventsNames.forEach((eventName: string) => {
|
||||
vnode.el.addEventListener(eventName.toLowerCase(), (e: Event) => {
|
||||
vnode.el!.addEventListener(eventName.toLowerCase(), (e: Event) => {
|
||||
modelPropValue = (e?.target as any)[modelProp];
|
||||
emit(UPDATE_VALUE_EVENT, modelPropValue);
|
||||
|
||||
|
@ -1,11 +1,16 @@
|
||||
<template>
|
||||
<ion-content class="ion-padding">
|
||||
{{ title }}
|
||||
<ion-button id="dismiss" @click="dismiss">Dismiss</ion-button> <br />
|
||||
|
||||
<div id="title">
|
||||
{{ title }}
|
||||
</div>
|
||||
</ion-content>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
IonButton,
|
||||
IonContent,
|
||||
popoverController
|
||||
} from '@ionic/vue';
|
||||
@ -16,6 +21,7 @@ export default defineComponent({
|
||||
title: { type: String, default: 'Default Title' }
|
||||
},
|
||||
components: {
|
||||
IonButton,
|
||||
IonContent
|
||||
},
|
||||
setup() {
|
||||
|
@ -25,6 +25,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||
path: '/overlays',
|
||||
component: () => import('@/views/Overlays.vue')
|
||||
},
|
||||
{
|
||||
path: '/keep-contents-mounted',
|
||||
component: () => import('@/views/OverlaysKeepContentsMounted.vue')
|
||||
},
|
||||
{
|
||||
path: '/inputs',
|
||||
component: () => import('@/views/Inputs.vue')
|
||||
|
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<ion-page data-pageid="overlays-automount">
|
||||
<ion-header :translucent="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons>
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Overlays - Auto Mount</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding" :fullscreen="true">
|
||||
<ion-button id="open-auto-mount-modal">Open Auto Mount Modal</ion-button>
|
||||
|
||||
<ion-button id="open-auto-mount-popover">Open Auto Mount Popover</ion-button>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<ion-modal
|
||||
id="auto-mount-modal"
|
||||
:keep-contents-mounted="true"
|
||||
trigger="open-auto-mount-modal"
|
||||
>
|
||||
<ModalContent :title="overlayProps.title"></ModalContent>
|
||||
</ion-modal>
|
||||
|
||||
<ion-popover
|
||||
id="auto-mount-popover"
|
||||
:keep-contents-mounted="true"
|
||||
trigger="open-auto-mount-popover"
|
||||
>
|
||||
<PopoverContent :title="overlayProps.title"></PopoverContent>
|
||||
</ion-popover>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
IonBackButton,
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
IonModal,
|
||||
IonPopover,
|
||||
} from '@ionic/vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import ModalContent from '@/components/ModalContent.vue';
|
||||
import PopoverContent from '@/components/PopoverContent.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
ModalContent,
|
||||
PopoverContent,
|
||||
IonBackButton,
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar,
|
||||
IonModal,
|
||||
IonPopover,
|
||||
},
|
||||
setup() {
|
||||
const overlayProps = {
|
||||
title: 'Custom Title'
|
||||
}
|
||||
|
||||
return {
|
||||
overlayProps
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -0,0 +1,52 @@
|
||||
describe('overlays - keepContentsMounted', () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1000, 900);
|
||||
cy.visit('http://localhost:8080/keep-contents-mounted')
|
||||
})
|
||||
describe('modal', () => {
|
||||
it('should not mount component if false', () => {
|
||||
cy.get('ion-modal#default-modal ion-content').should('not.exist');
|
||||
});
|
||||
|
||||
it('should mount component if true', () => {
|
||||
cy.get('ion-modal#auto-mount-modal ion-content').should('exist');
|
||||
});
|
||||
|
||||
it('should keep component mounted after dismissing if true', () => {
|
||||
cy.get('#open-auto-mount-modal').click();
|
||||
|
||||
cy.get('ion-modal#auto-mount-modal ion-content').should('exist');
|
||||
|
||||
cy.get('ion-modal#auto-mount-modal #dismiss').click();
|
||||
|
||||
cy.get('ion-modal#auto-mount-modal')
|
||||
.should('not.be.visible')
|
||||
.should('have.class', 'overlay-hidden');
|
||||
|
||||
cy.get('ion-modal#auto-mount-modal ion-content').should('exist');
|
||||
});
|
||||
})
|
||||
describe('popover', () => {
|
||||
it('should not mount component if false', () => {
|
||||
cy.get('ion-popover#default-popover ion-content').should('not.exist');
|
||||
});
|
||||
|
||||
it('should mount component if true', () => {
|
||||
cy.get('ion-popover#auto-mount-popover ion-content').should('exist');
|
||||
});
|
||||
|
||||
it('should keep component mounted after dismissing if true', () => {
|
||||
cy.get('#open-auto-mount-popover').click();
|
||||
|
||||
cy.get('ion-popover#auto-mount-popover ion-content').should('exist');
|
||||
|
||||
cy.get('ion-popover#auto-mount-popover #dismiss').click();
|
||||
|
||||
cy.get('ion-popover#auto-mount-popover')
|
||||
.should('not.be.visible')
|
||||
.should('have.class', 'overlay-hidden');
|
||||
|
||||
cy.get('ion-popover#auto-mount-popover ion-content').should('exist');
|
||||
});
|
||||
})
|
||||
})
|
@ -134,7 +134,7 @@ describe('Overlays', () => {
|
||||
cy.get('ion-button#present-overlay').click();
|
||||
cy.get('ion-popover.ion-popover-controller').should('exist');
|
||||
|
||||
cy.get('ion-popover.ion-popover-controller ion-content').should('have.text', 'Custom Title');
|
||||
cy.get('ion-popover.ion-popover-controller ion-content #title').should('have.text', 'Custom Title');
|
||||
});
|
||||
|
||||
it('should pass props to popover via component', () => {
|
||||
@ -144,7 +144,7 @@ describe('Overlays', () => {
|
||||
cy.get('ion-button#present-overlay').click();
|
||||
cy.get('ion-popover').should('exist');
|
||||
|
||||
cy.get('ion-popover.popover-inline ion-content').should('have.text', 'Custom Title');
|
||||
cy.get('ion-popover.popover-inline ion-content #title').should('have.text', 'Custom Title');
|
||||
});
|
||||
|
||||
it('should only open one instance at a time when props change quickly on component', () => {
|
||||
|
Reference in New Issue
Block a user