|
1 | 1 | ```html
|
2 | 2 | <template>
|
3 |
| - <ion-accordion-group> |
4 |
| - <ion-accordion value="first"> |
5 |
| - <ion-item slot="header" color="light"> |
6 |
| - <ion-label>First Accordion</ion-label> |
7 |
| - </ion-item> |
8 |
| - <div class="ion-padding" slot="content">First Content</div> |
9 |
| - </ion-accordion> |
10 |
| - <ion-accordion value="second"> |
11 |
| - <ion-item slot="header" color="light"> |
12 |
| - <ion-label>Second Accordion</ion-label> |
13 |
| - </ion-item> |
14 |
| - <div class="ion-padding" slot="content">Second Content</div> |
15 |
| - </ion-accordion> |
16 |
| - <ion-accordion value="third"> |
17 |
| - <ion-item slot="header" color="light"> |
18 |
| - <ion-label>Third Accordion</ion-label> |
19 |
| - </ion-item> |
20 |
| - <div class="ion-padding" slot="content">Third Content</div> |
21 |
| - </ion-accordion> |
22 |
| - </ion-accordion-group> |
| 3 | + <ion-header> |
| 4 | + <ion-toolbar> |
| 5 | + <ion-title>Page</ion-title> |
| 6 | + </ion-toolbar> |
| 7 | + </ion-header> |
| 8 | + <ion-content class="ion-padding"> |
| 9 | + <ion-button id="modal-trigger">Present Modal</ion-button> |
| 10 | + <ion-modal |
| 11 | + trigger="modal-trigger" |
| 12 | + ref="modalEl" |
| 13 | + :enterAnimation="enterAnimation" |
| 14 | + :leaveAnimation="leaveAnimation" |
| 15 | + > |
| 16 | + <ion-header> |
| 17 | + <ion-toolbar> |
| 18 | + <ion-title>Modal</ion-title> |
| 19 | + <ion-buttons slot="end"> |
| 20 | + <ion-button @click="closeModal()"> |
| 21 | + <ion-icon :icon="close" slot="icon-only"></ion-icon> |
| 22 | + </ion-button> |
| 23 | + </ion-buttons> |
| 24 | + </ion-toolbar> |
| 25 | + </ion-header> |
| 26 | + <ion-content class="ion-padding"> |
| 27 | + Modal Content |
| 28 | + </ion-content> |
| 29 | + </ion-modal> |
| 30 | + </ion-content> |
23 | 31 | </template>
|
24 | 32 |
|
25 | 33 | <script lang="ts">
|
26 |
| - import { IonAccordion, IonAccordionGroup, IonItem, IonLabel } from '@ionic/vue'; |
27 |
| - import { defineComponent } from 'vue'; |
| 34 | + import { IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonModal, IonToolbar, IonTitle, createAnimation } from '@ionic/vue'; |
| 35 | + import { close } from 'ionicons/icons'; |
| 36 | +
|
| 37 | + import { defineComponent, ref } from 'vue'; |
28 | 38 |
|
29 | 39 | export default defineComponent({
|
30 | 40 | components: {
|
31 |
| - IonAccordion, |
32 |
| - IonAccordionGroup, |
33 |
| - IonItem, |
34 |
| - IonLabel, |
| 41 | + IonButton, |
| 42 | + IonButtons, |
| 43 | + IonContent, |
| 44 | + IonHeader, |
| 45 | + IonIcon, |
| 46 | + IonModal, |
| 47 | + IonToolbar, |
| 48 | + IonTitle |
35 | 49 | },
|
| 50 | + setup() { |
| 51 | + const modalEl = ref(null); |
| 52 | + |
| 53 | + const enterAnimation = (baseEl: HTMLElement) => { |
| 54 | + const root = baseEl.shadowRoot; |
| 55 | + |
| 56 | + const backdropAnimation = createAnimation() |
| 57 | + .addElement(root!.querySelector('ion-backdrop')!) |
| 58 | + .fromTo('opacity', '0.01', 'var(--backdrop-opacity)'); |
| 59 | + |
| 60 | + const wrapperAnimation = createAnimation() |
| 61 | + .addElement(root!.querySelector('.modal-wrapper')!) |
| 62 | + .keyframes([ |
| 63 | + { offset: 0, opacity: '0', transform: 'scale(0)' }, |
| 64 | + { offset: 1, opacity: '0.99', transform: 'scale(1)' } |
| 65 | + ]); |
| 66 | + |
| 67 | + return createAnimation() |
| 68 | + .addElement(baseEl) |
| 69 | + .easing('ease-out') |
| 70 | + .duration(500) |
| 71 | + .addAnimation([backdropAnimation, wrapperAnimation]); |
| 72 | + } |
| 73 | + |
| 74 | + const leaveAnimation = (baseEl: HTMLElement) => { |
| 75 | + return enterAnimation(baseEl).direction('reverse'); |
| 76 | + } |
| 77 | + |
| 78 | + const closeModal = () => { |
| 79 | + modalEl.value?.$el.dismiss(); |
| 80 | + } |
| 81 | + |
| 82 | + return { |
| 83 | + close, |
| 84 | + modalEl, |
| 85 | + closeModal, |
| 86 | + enterAnimation, |
| 87 | + leaveAnimation |
| 88 | + } |
| 89 | + } |
36 | 90 | });
|
37 | 91 | </script>
|
38 | 92 | ```
|
0 commit comments