Skip to content

Commit 33b6def

Browse files
docs(animation): add playground for override example (#3018)
Co-authored-by: dillionmegida <[email protected]>
1 parent 63d96f3 commit 33b6def

File tree

9 files changed

+401
-230
lines changed

9 files changed

+401
-230
lines changed

docs/utilities/animations.md

+2-229
Original file line numberDiff line numberDiff line change
@@ -1279,236 +1279,9 @@ Certain Ionic components allow developers to provide custom animations. All anim
12791279

12801280
### Modals
12811281

1282-
````mdx-code-block
1283-
<Tabs
1284-
groupId="framework"
1285-
defaultValue="javascript"
1286-
values={[
1287-
{ value: 'javascript', label: 'JavaScript' },
1288-
{ value: 'angular', label: 'Angular' },
1289-
{ value: 'react', label: 'React' },
1290-
{ value: 'vue', label: 'Vue' },
1291-
]
1292-
}>
1293-
<TabItem value="javascript">
1294-
1295-
```javascript
1296-
customElements.define('modal-page', class extends HTMLElement {
1297-
connectedCallback() {
1298-
this.innerHTML = `
1299-
<ion-header>
1300-
<ion-toolbar>
1301-
<ion-title>Modal Header</ion-title>
1302-
</ion-toolbar>
1303-
</ion-header>
1304-
<ion-content class="ion-padding">
1305-
Modal Content
1306-
</ion-content>
1307-
`;
1308-
}
1309-
});
1310-
1311-
function presentModal() {
1312-
const enterAnimation = (baseEl: any) => {
1313-
const root = baseEl.shadowRoot;
1314-
1315-
const backdropAnimation = createAnimation()
1316-
.addElement(root.querySelector('ion-backdrop')!)
1317-
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
1318-
1319-
const wrapperAnimation = createAnimation()
1320-
.addElement(root.querySelector('.modal-wrapper')!)
1321-
.keyframes([
1322-
{ offset: 0, opacity: '0', transform: 'scale(0)' },
1323-
{ offset: 1, opacity: '0.99', transform: 'scale(1)' }
1324-
]);
1325-
1326-
return createAnimation()
1327-
.addElement(baseEl)
1328-
.easing('ease-out')
1329-
.duration(500)
1330-
.addAnimation([backdropAnimation, wrapperAnimation]);
1331-
}
1332-
1333-
const leaveAnimation = (baseEl: any) => {
1334-
return enterAnimation(baseEl).direction('reverse');
1335-
}
1336-
1337-
// create the modal with the `modal-page` component
1338-
const modalElement = document.createElement('ion-modal');
1339-
modalElement.component = 'modal-page';
1340-
modalElement.enterAnimation = enterAnimation;
1341-
modalElement.leaveAnimation = leaveAnimation;
1342-
1343-
// present the modal
1344-
document.body.appendChild(modalElement);
1345-
return modalElement.present();
1346-
}
1347-
```
1348-
</TabItem>
1349-
<TabItem value="angular">
1350-
1351-
```tsx
1352-
import { Component } from '@angular/core';
1353-
import { ModalController, AnimationController } from '@ionic/angular';
1354-
import { ModalPage } from '../modal/modal.page';
1355-
1356-
@Component({
1357-
selector: 'modal-example',
1358-
templateUrl: 'modal-example.html',
1359-
styleUrls: ['./modal-example.css']
1360-
})
1361-
export class ModalExample {
1362-
constructor(public modalController: ModalController,
1363-
public animationCtrl: AnimationController) { }
1364-
1365-
async presentModal() {
1366-
const enterAnimation = (baseEl: any) => {
1367-
const root = baseEl.shadowRoot;
1368-
1369-
const backdropAnimation = this.animationCtrl.create()
1370-
.addElement(root.querySelector('ion-backdrop')!)
1371-
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
1372-
1373-
const wrapperAnimation = this.animationCtrl.create()
1374-
.addElement(root.querySelector('.modal-wrapper')!)
1375-
.keyframes([
1376-
{ offset: 0, opacity: '0', transform: 'scale(0)' },
1377-
{ offset: 1, opacity: '0.99', transform: 'scale(1)' }
1378-
]);
1379-
1380-
return this.animationCtrl.create()
1381-
.addElement(baseEl)
1382-
.easing('ease-out')
1383-
.duration(500)
1384-
.addAnimation([backdropAnimation, wrapperAnimation]);
1385-
}
1386-
1387-
const leaveAnimation = (baseEl: any) => {
1388-
return enterAnimation(baseEl).direction('reverse');
1389-
}
1390-
1391-
const modal = await this.modalController.create({
1392-
component: ModalPage,
1393-
enterAnimation,
1394-
leaveAnimation
1395-
});
1396-
return await modal.present();
1397-
}
1398-
}
1399-
```
1400-
</TabItem>
1401-
<TabItem value="react">
1402-
1403-
```jsx
1404-
import React, { useState } from 'react';
1405-
import { createAnimation, IonModal, IonButton, IonContent } from '@ionic/react';
1406-
1407-
export const ModalExample: React.FC = () => {
1408-
const [showModal, setShowModal] = useState(false);
1409-
1410-
const enterAnimation = (baseEl: any) => {
1411-
const root = baseEl.shadowRoot;
1412-
1413-
const backdropAnimation = createAnimation()
1414-
.addElement(root.querySelector('ion-backdrop')!)
1415-
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
1416-
1417-
const wrapperAnimation = createAnimation()
1418-
.addElement(root.querySelector('.modal-wrapper')!)
1419-
.keyframes([
1420-
{ offset: 0, opacity: '0', transform: 'scale(0)' },
1421-
{ offset: 1, opacity: '0.99', transform: 'scale(1)' }
1422-
]);
1423-
1424-
return createAnimation()
1425-
.addElement(baseEl)
1426-
.easing('ease-out')
1427-
.duration(500)
1428-
.addAnimation([backdropAnimation, wrapperAnimation]);
1429-
}
1430-
1431-
const leaveAnimation = (baseEl: any) => {
1432-
return enterAnimation(baseEl).direction('reverse');
1433-
}
1434-
1435-
return (
1436-
<IonContent>
1437-
<IonModal isOpen={showModal} enterAnimation={enterAnimation} leaveAnimation={leaveAnimation}>
1438-
<p>This is modal content</p>
1439-
<IonButton onClick={() => setShowModal(false)}>Close Modal</IonButton>
1440-
</IonModal>
1441-
<IonButton onClick={() => setShowModal(true)}>Show Modal</IonButton>
1442-
</IonContent>
1443-
);
1444-
};
1445-
```
1446-
</TabItem>
1447-
<TabItem value="vue">
1448-
1449-
```jsx
1450-
<template>
1451-
<ion-page>
1452-
<ion-content>
1453-
<ion-modal
1454-
:is-open="isModalOpen"
1455-
:enter-animation="enterAnimation"
1456-
:leave-animation="leaveAnimation"
1457-
@didDismiss="setModalOpen(false)"
1458-
>
1459-
Modal content goes here.
1460-
</ion-modal>
1461-
1462-
<ion-button @click="setModalOpen(true)">Show Modal</ion-button>
1463-
</ion-content>
1464-
</ion-page>
1465-
</template>
1466-
1467-
<script lang="ts">
1468-
import { createAnimation, IonButton, IonContent, IonModal, IonPage } from '@ionic/vue';
1469-
import { defineComponent, ref } from 'vue';
1470-
1471-
export default defineComponent({
1472-
components: { IonButton, IonContent, IonModal, IonPage },
1473-
setup() {
1474-
const isModalOpen = ref(false);
1475-
const setModalOpen = (state) => isModalOpen.value = state;
1476-
1477-
const enterAnimation = (baseEl: any) => {
1478-
const root = baseEl.shadowRoot;
1479-
1480-
const backdropAnimation = createAnimation()
1481-
.addElement(root.querySelector('ion-backdrop')!)
1482-
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
1483-
1484-
const wrapperAnimation = createAnimation()
1485-
.addElement(root.querySelector('.modal-wrapper')!)
1486-
.keyframes([
1487-
{ offset: 0, opacity: '0', transform: 'scale(0)' },
1488-
{ offset: 1, opacity: '0.99', transform: 'scale(1)' }
1489-
]);
1490-
1491-
return createAnimation()
1492-
.addElement(baseEl)
1493-
.easing('ease-out')
1494-
.duration(500)
1495-
.addAnimation([backdropAnimation, wrapperAnimation]);
1496-
}
1497-
1498-
const leaveAnimation = (baseEl: any) => {
1499-
return enterAnimation(baseEl).direction('reverse');
1500-
}
1501-
1502-
return { isModalOpen, setModalOpen, enterAnimation, leaveAnimation }
1503-
}
1504-
})
1505-
</script>
1506-
```
1507-
</TabItem>
1508-
</Tabs>
1509-
````
1282+
import ModalOverride from '@site/static/usage/v7/animations/modal-override/index.md';
15101283

1511-
<Codepen user="ionic" slug="ExapZBZ" />
1284+
<ModalOverride />
15121285

15131286
## Performance Considerations
15141287

static/code/stackblitz/v7/html/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { defineCustomElements } from '@ionic/core/loader';
22

3-
import { loadingController, modalController, pickerController, toastController } from '@ionic/core';
3+
import { createAnimation, loadingController, modalController, pickerController, toastController } from '@ionic/core';
44

55
/* Core CSS required for Ionic components to work properly */
66
import '@ionic/core/css/core.css';
@@ -27,3 +27,4 @@ defineCustomElements();
2727
(window as any).modalController = modalController;
2828
(window as any).pickerController = pickerController;
2929
(window as any).toastController = toastController;
30+
(window as any).createAnimation = createAnimation;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
```html
2+
<ion-header>
3+
<ion-toolbar>
4+
<ion-title>Page</ion-title>
5+
</ion-toolbar>
6+
</ion-header>
7+
<ion-content class="ion-padding">
8+
<ion-button id="modal-trigger">Present Modal</ion-button>
9+
<ion-modal trigger="modal-trigger" #modal>
10+
<ng-template>
11+
<ion-header>
12+
<ion-toolbar>
13+
<ion-title>Modal</ion-title>
14+
<ion-buttons slot="end">
15+
<ion-button (click)="closeModal()">Close</ion-button>
16+
</ion-buttons>
17+
</ion-toolbar>
18+
</ion-header>
19+
<ion-content class="ion-padding"> Modal Content </ion-content>
20+
</ng-template>
21+
</ion-modal>
22+
</ion-content>
23+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
```ts
2+
import { Component, ViewChild } from '@angular/core';
3+
import type { IonModal } from '@ionic/angular';
4+
import { AnimationController } from '@ionic/angular';
5+
6+
@Component({
7+
selector: 'app-example',
8+
templateUrl: 'example.component.html',
9+
})
10+
export class ExampleComponent {
11+
@ViewChild('modal', { static: true }) modal: IonModal;
12+
13+
constructor(private animationCtrl: AnimationController) {}
14+
15+
ngOnInit() {
16+
const enterAnimation = (baseEl: HTMLElement) => {
17+
const root = baseEl.shadowRoot;
18+
19+
const backdropAnimation = this.animationCtrl
20+
.create()
21+
.addElement(root.querySelector('ion-backdrop'))
22+
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
23+
24+
const wrapperAnimation = this.animationCtrl
25+
.create()
26+
.addElement(root.querySelector('.modal-wrapper'))
27+
.keyframes([
28+
{ offset: 0, opacity: '0', transform: 'scale(0)' },
29+
{ offset: 1, opacity: '0.99', transform: 'scale(1)' },
30+
]);
31+
32+
return this.animationCtrl
33+
.create()
34+
.addElement(baseEl)
35+
.easing('ease-out')
36+
.duration(500)
37+
.addAnimation([backdropAnimation, wrapperAnimation]);
38+
};
39+
40+
const leaveAnimation = (baseEl: HTMLElement) => {
41+
return enterAnimation(baseEl).direction('reverse');
42+
};
43+
44+
this.modal.enterAnimation = enterAnimation;
45+
this.modal.leaveAnimation = leaveAnimation;
46+
}
47+
48+
closeModal() {
49+
this.modal.dismiss();
50+
}
51+
}
52+
```

0 commit comments

Comments
 (0)