mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
chore(): remove old ionic vue directory (#22315)
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
root = true
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{js,vue,ts}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
continuation_indent_size = 6
|
||||
|
||||
21
vue/.gitignore
vendored
21
vue/.gitignore
vendored
@@ -1,21 +0,0 @@
|
||||
.*
|
||||
~*
|
||||
|
||||
dist/
|
||||
node_modules/
|
||||
src/**/*.js
|
||||
types/**/*.map
|
||||
|
||||
# ignore log files
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
test-report.xml
|
||||
|
||||
!.gitignore
|
||||
!.editorconfig
|
||||
!.eslintrc.js
|
||||
!.prettierrc
|
||||
!.babelrc
|
||||
!.circleci
|
||||
@@ -1,54 +0,0 @@
|
||||
# @ionic/vue (beta)
|
||||
|
||||
Ionic Vue.js specific building blocks on top of [@ionic/core](https://www.npmjs.com/package/@ionic/core) components.
|
||||
|
||||
To get started simply install `@ionic/vue` and `@ionic/core` with npm into your project and then register `@ionic/vue` as a plugin to your vue application.
|
||||
|
||||
```ts
|
||||
import Vue from 'vue';
|
||||
import Ionic from '@ionic/vue';
|
||||
|
||||
Vue.use(Ionic);
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
}).$mount('#app');
|
||||
```
|
||||
|
||||
## Publishing a Native Application
|
||||
|
||||
You can now make use of all of the ionic components in your vue application.
|
||||
If you want to publish your app to the App Store or Google Play you will need to use the ionic cli to execute Capacitor commands to do so.
|
||||
|
||||
More information on this can be found here. https://ionicframework.com/docs/cli
|
||||
If you want to learn more about Capacitor our dedicated site can be found here. https://capacitor.ionicframework.com/
|
||||
|
||||
The commands that you will need to execute are below.
|
||||
|
||||
```sh
|
||||
ionic capacitor add
|
||||
ionic capacitor copy
|
||||
ionic capacitor run
|
||||
```
|
||||
|
||||
## Current known limitations
|
||||
|
||||
This is an beta release of @ionic/vue so please understand that there are some missing pieces but know that many of the components will work.
|
||||
|
||||
- The shorthand `v-model` binding is currently not supported
|
||||
- Stack navigation for deep transitions is under heavy development at this time.
|
||||
|
||||
## Related
|
||||
|
||||
- [Ionic Core Components](https://www.npmjs.com/package/@ionic/core)
|
||||
- [Ionic Documentation](https://ionicframework.com/docs/)
|
||||
- [Ionic Worldwide Slack](http://ionicworldwide.herokuapp.com/)
|
||||
- [Ionic Forum](https://forum.ionicframework.com/)
|
||||
- [Ionicons](http://ionicons.com/)
|
||||
- [Capacitor](https://capacitor.ionicframework.com/)
|
||||
|
||||
## License
|
||||
|
||||
- [MIT](https://raw.githubusercontent.com/ionic-team/ionic/master/LICENSE)
|
||||
@@ -1,86 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Custom transitions</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<!-- Disable Ionic transitions -->
|
||||
<script>window.disableIonicTransitions = true</script>
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
<style>
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-vue-router></ion-vue-router>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = {
|
||||
template: `<transition name="fade">
|
||||
<ion-page class="ion-page">
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<router-link to="/page">Go to page</router-link>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</transition>`
|
||||
}
|
||||
|
||||
const Page = {
|
||||
template: `<transition name="fade">
|
||||
<ion-page class="ion-page">
|
||||
<toolbar title="Page" backURL="/"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-button @click="goHome">Go home</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</transition>`,
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vue.config.ignoredElements.push(/^ion-/)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/page', component: Page },
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,72 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Basic routing</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-vue-router></ion-vue-router>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<router-link to="/page">Go to page</router-link>
|
||||
</ion-content>
|
||||
</ion-page>`
|
||||
}
|
||||
|
||||
const Page = {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Page" backURL="/"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-button @click="goHome">Go home</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>`,
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vue.config.ignoredElements.push(/^ion-/)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/page', component: Page },
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,134 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Ionic Controllers</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-menu side="end">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Hola</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
hola macho
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-vue-router></ion-vue-router>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = {
|
||||
template: `<ion-page class="ion-page" main>
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-button @click="alert">Trigger Alert</ion-button>
|
||||
<ion-button @click="loading">Trigger Loading</ion-button>
|
||||
<ion-button @click="menu">Toggle Menu</ion-button>
|
||||
<ion-button @click="modal">Open Modal</ion-button>
|
||||
<ion-button @click="popover">Open Popover</ion-button>
|
||||
<ion-button @click="toast">Trigger Toast</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>`,
|
||||
methods: {
|
||||
alert() {
|
||||
this.$ionic.alertController.create({
|
||||
header: 'Hello!',
|
||||
message: 'How are you?',
|
||||
buttons: ['OK, thanks!'],
|
||||
})
|
||||
.then(a => a.present())
|
||||
},
|
||||
loading() {
|
||||
this.$ionic.loadingController.create()
|
||||
.then(l => {
|
||||
l.present()
|
||||
setTimeout(function() {
|
||||
l.dismiss()
|
||||
}, 1000)
|
||||
})
|
||||
},
|
||||
menu() {
|
||||
this.$ionic.menuController.toggle()
|
||||
},
|
||||
modal() {
|
||||
this.$ionic.modalController.create({
|
||||
component: {
|
||||
template: `<div>
|
||||
<ion-content padding>
|
||||
<h1>Howdy!</h1>
|
||||
</ion-content>
|
||||
</div>`,
|
||||
}
|
||||
})
|
||||
.then(m => m.present())
|
||||
},
|
||||
popover(event) {
|
||||
this.$ionic.popoverController.create({
|
||||
component: {
|
||||
template: `<ion-list>
|
||||
<ion-list-header>
|
||||
<ion-label>Ionic</ion-label>
|
||||
</ion-list-header>
|
||||
<ion-item>Learn Ionic</ion-item>
|
||||
<ion-item>Documentation</ion-item>
|
||||
<ion-item>Showcase</ion-item>
|
||||
<ion-item>GitHub Repo</ion-item>
|
||||
</ion-list>`,
|
||||
},
|
||||
translucent: true,
|
||||
event
|
||||
})
|
||||
.then(p => p.present())
|
||||
},
|
||||
toast() {
|
||||
this.$ionic.toastController.create({
|
||||
message: 'Here\'s to IonicVue!',
|
||||
buttons: ['Done'],
|
||||
position: 'top',
|
||||
})
|
||||
.then(t => t.present())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Vue.use(IonicVue.IonicAPI)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', component: Home },
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,86 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Mixed transitions</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
<style>
|
||||
/* hide the nasty black BG on ios */
|
||||
.show-decor .nav-decor {
|
||||
background: transparent !important;
|
||||
}
|
||||
.slide-enter-active, .slide-leave-active {
|
||||
transition: margin 1s ease;
|
||||
}
|
||||
.slide-enter, .slide-leave-to {
|
||||
margin-top: 1000px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-vue-router></ion-vue-router>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = {
|
||||
template: `<transition name="slide"><ion-page class="ion-page">
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<router-link to="/page">Go to page</router-link>
|
||||
</ion-content>
|
||||
</ion-page></transition>`
|
||||
}
|
||||
|
||||
const Page = {
|
||||
template: `<transition name="slide">
|
||||
<ion-page class="ion-page">
|
||||
<toolbar title="Page" backURL="/"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-button @click="goHome">Go home</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</transition>`,
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vue.config.ignoredElements.push(/^ion-/)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/page', meta: { customTransition: true }, component: Page },
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,85 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Transitions with named views</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
<style>
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-vue-router></ion-vue-router>
|
||||
<router-view name="extra" style="pointer-events:none !important;"></router-view>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<router-link to="/page">Go to page</router-link>
|
||||
</ion-content>
|
||||
</ion-page>`
|
||||
}
|
||||
|
||||
const Page = {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Page" backURL="/"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-button @click="goHome">Go home</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>`,
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Extra = {
|
||||
template: '<transition name="fade"><h1 style="z-index:999;margin:150px 0 0 16px">Some extra conent</h1></transition>'
|
||||
}
|
||||
|
||||
Vue.config.ignoredElements.push(/^ion-/)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/page', components: {default: Page, extra: Extra} },
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,77 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Routing with named views</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-vue-router></ion-vue-router>
|
||||
<ion-vue-router name="extra" style="pointer-events:none !important;"></ion-vue-router>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<router-link to="/page">Go to page</router-link>
|
||||
</ion-content>
|
||||
</ion-page>`
|
||||
}
|
||||
|
||||
const Page = {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Page" backURL="/"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-button @click="goHome">Go home</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>`,
|
||||
methods: {
|
||||
goHome() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Extra = {
|
||||
template: '<h1 style="z-index:999;margin:150px 0 0 16px">Some extra conent</h1>'
|
||||
}
|
||||
|
||||
Vue.config.ignoredElements.push(/^ion-/)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/page', components: {default: Page, extra: Extra} },
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,82 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Ionic v4 + Vue.js - Ionic tabs</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
|
||||
<script src="https://unpkg.com/vue-class-component@latest/dist/vue-class-component.js"></script>
|
||||
<script src="https://unpkg.com/vue-property-decorator@latest/lib/vue-property-decorator.umd.js"></script>
|
||||
<script src="https://unpkg.com/@modus/ionic-vue@latest/dist/ionic-vue.js"></script>
|
||||
<script src="https://unpkg.com/@ionic/core@latest/dist/ionic.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@ionic/core@latest/css/ionic.bundle.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<Home/>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const Toolbar = Vue.component('Toolbar', {
|
||||
name: 'Toolbar',
|
||||
props: { title: String, backURL: String },
|
||||
template: `<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button :default-href="backURL"/>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ title }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>`
|
||||
})
|
||||
|
||||
const Home = Vue.component('Home', {
|
||||
template: `<ion-page class="ion-page">
|
||||
<toolbar title="Home"/>
|
||||
<ion-content class="ion-content" padding>
|
||||
<ion-tabs>
|
||||
<ion-tab href="schedule" label="schedule" icon="calendar" name="schedule">
|
||||
<ion-vue-router/>
|
||||
</ion-tab>
|
||||
<ion-tab href="speakers" label="speakers" icon="contacts" name="speakers">
|
||||
<ion-vue-router name="speakers"/>
|
||||
</ion-tab>
|
||||
</ion-tabs>
|
||||
</ion-content>
|
||||
</ion-page>`
|
||||
})
|
||||
|
||||
const Page = {
|
||||
template: '<ion-button @click="goBack">Go back</ion-button>',
|
||||
methods: {
|
||||
goBack() {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Schedule = {
|
||||
template: `<ion-button @click="$router.push('page')">To page</ion-button>`
|
||||
}
|
||||
|
||||
const Speakers = {
|
||||
template: '<h1>Speakers list</h1>'
|
||||
}
|
||||
|
||||
Vue.config.ignoredElements.push(/^ion-/)
|
||||
|
||||
new Vue({
|
||||
router: new IonicVue.IonicVueRouter({
|
||||
routes: [
|
||||
{ path: '/', components: {default: Schedule, speakers: Speakers} },
|
||||
{ path: '/page', component: Page }
|
||||
],
|
||||
}),
|
||||
}).$mount('ion-app')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1597
vue/package-lock.json
generated
1597
vue/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"name": "@ionic/vue",
|
||||
"version": "0.0.9",
|
||||
"description": "Vue specific wrappers for @ionic/core",
|
||||
"main": "dist/ionic-vue.common.js",
|
||||
"types": "dist/types/index.d.ts",
|
||||
"module": "dist/ionic-vue.esm.js",
|
||||
"unpkg": "dist/ionic-vue.js",
|
||||
"jsdelivr": "dist/ionic-vue.js",
|
||||
"contributors": [
|
||||
"Josh Thomas <josh@ionic.io>",
|
||||
"Mike Hartington <mikehartington@gmail.com",
|
||||
"Michael Tintiuc <michael.tintiuc@moduscreate.com>"
|
||||
],
|
||||
"files": [
|
||||
"dist/"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/ionic-team/ionic/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"ionic",
|
||||
"framework",
|
||||
"vue",
|
||||
"mobile",
|
||||
"app",
|
||||
"webapp",
|
||||
"capacitor",
|
||||
"cordova",
|
||||
"progressive web app",
|
||||
"pwa"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ionic-team/ionic.git"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "rollup -c",
|
||||
"watch": "rollup -c -w",
|
||||
"build": "npm run clean && NODE_ENV=production rollup -c --configProd",
|
||||
"clean": "node scripts/clean.js",
|
||||
"lint": "tslint --project .",
|
||||
"lint.fix": "tslint --project . --fix",
|
||||
"test": "jest --coverage --verbose"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/core": "^5.2.2",
|
||||
"ionicons": "^5.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rollup": "^2.18.1",
|
||||
"rollup-plugin-terser": "^6.1.0",
|
||||
"rollup-plugin-vue": "^4.3.0",
|
||||
"rollup-plugin-typescript2": "^0.27.1",
|
||||
"tslib": "1.9.3",
|
||||
"tslint": "5.11.0",
|
||||
"tslint-ionic-rules": "0.0.19",
|
||||
"typescript": "3.9.5",
|
||||
"vue": "^2.5.17",
|
||||
"vue-template-compiler": "^2.5.17",
|
||||
"vue-router": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.5.17",
|
||||
"vue-router": "^3.0.1"
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import path from 'path'
|
||||
import vue from 'rollup-plugin-vue'
|
||||
import { terser } from 'rollup-plugin-terser'
|
||||
import typescript from 'rollup-plugin-typescript2'
|
||||
|
||||
const resolve = _path => path.resolve(__dirname, './', _path)
|
||||
|
||||
function outputConfig(suffix, format, opts = {}) {
|
||||
return Object.assign(
|
||||
{
|
||||
file: resolve(`./dist/ionic-vue${suffix}.js`),
|
||||
name: 'IonicVue',
|
||||
exports: 'named',
|
||||
sourcemap: true,
|
||||
format,
|
||||
},
|
||||
opts
|
||||
)
|
||||
}
|
||||
|
||||
function baseConfig() {
|
||||
return {
|
||||
input: resolve('./src/index.ts'),
|
||||
output: [
|
||||
outputConfig('', 'umd', {
|
||||
globals: {
|
||||
vue: 'Vue'
|
||||
},
|
||||
}),
|
||||
outputConfig('.esm', 'esm'),
|
||||
outputConfig('.common', 'cjs'),
|
||||
],
|
||||
external: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
'@ionic/core',
|
||||
'@ionic/core/loader',
|
||||
'ionicons',
|
||||
'ionicons/icons',
|
||||
],
|
||||
plugins: [
|
||||
vue(),
|
||||
typescript({
|
||||
useTsconfigDeclarationDir: true,
|
||||
objectHashIgnoreUnknownHack: true,
|
||||
clean: true
|
||||
})
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export default args => {
|
||||
const configs = [baseConfig()]
|
||||
|
||||
if (args.configProd === true) {
|
||||
const prodConfig = baseConfig()
|
||||
prodConfig.plugins.push(terser())
|
||||
|
||||
for (const item of prodConfig.output) {
|
||||
item.file = item.file.replace('.js', '.min.js')
|
||||
item.sourcemap = false
|
||||
}
|
||||
|
||||
configs.push(prodConfig)
|
||||
}
|
||||
|
||||
return configs
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
|
||||
const cleanDirs = ['dist']
|
||||
|
||||
cleanDirs.forEach(dir => {
|
||||
const cleanDir = path.join(__dirname, '../', dir)
|
||||
fs.removeSync(cleanDir)
|
||||
})
|
||||
@@ -1,17 +0,0 @@
|
||||
import { HTMLStencilElement } from '@ionic/core';
|
||||
|
||||
// A proxy method that initializes the controller and calls requested method
|
||||
export function proxyMethod(tag: string, method: string, ...opts: any[]): Promise<any> {
|
||||
return initController(tag).then((ctrl: any) => ctrl[method].apply(ctrl, opts));
|
||||
}
|
||||
|
||||
// Initialize an Ionic controller and append it to DOM
|
||||
export function initController(tag: string): Promise<HTMLStencilElement> {
|
||||
let element = document.querySelector(tag) as HTMLElement;
|
||||
|
||||
if (!element) {
|
||||
element = document.body.appendChild(document.createElement(tag));
|
||||
}
|
||||
|
||||
return (element as HTMLStencilElement).componentOnReady();
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Core Ionic types
|
||||
// tslint:disable-next-line:no-import-side-effect
|
||||
import { IonicConfig } from '@ionic/core';
|
||||
|
||||
// Webpack import for ionicons
|
||||
import { addIcons } from 'ionicons';
|
||||
import { arrowBackSharp, chevronBack, chevronForward, closeCircle, closeSharp, menuOutline, menuSharp, reorderThreeOutline, reorderTwoSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
||||
|
||||
// import '@ionic/core/css/ionic.bundle.css';
|
||||
// import 'ionicons/dist/collection/icon/icon.css';
|
||||
|
||||
import { applyPolyfills, defineCustomElements } from '@ionic/core/loader';
|
||||
import { IonicWindow } from './interfaces';
|
||||
|
||||
export function appInitialize(config?: IonicConfig) {
|
||||
const win: IonicWindow = window as any;
|
||||
const Ionic = (win.Ionic = win.Ionic || {});
|
||||
|
||||
Ionic.config = config;
|
||||
applyPolyfills().then(() => defineCustomElements(win));
|
||||
|
||||
// Icons that are used by internal components
|
||||
addIcons({
|
||||
'arrow-back-sharp': arrowBackSharp,
|
||||
'chevron-back': chevronBack,
|
||||
'chevron-forward': chevronForward,
|
||||
'close-circle': closeCircle,
|
||||
'close-sharp': closeSharp,
|
||||
'menu-outline': menuOutline,
|
||||
'menu-sharp': menuSharp,
|
||||
'reorder-two-sharp': reorderTwoSharp,
|
||||
'reorder-three-outline': reorderThreeOutline,
|
||||
'search-outline': searchOutline,
|
||||
'search-sharp': searchSharp,
|
||||
});
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
/**
|
||||
* Create a wrapped input component that captures typical ionic input events
|
||||
* and emits core ones so v-model works.
|
||||
* @param {} name the vue name of the component
|
||||
* @param {*} coreTag the actual tag to render (such as ion-datetime)
|
||||
*/
|
||||
export function createInputComponent(name: string, coreTag: string, modelEvent = 'ionChange', valueProperty = 'value') {
|
||||
return Vue.component(name, {
|
||||
model: {
|
||||
event: modelEvent,
|
||||
prop: valueProperty
|
||||
},
|
||||
render(createElement: any) {
|
||||
// Vue types have a bug accessing member properties:
|
||||
// https://github.com/vuejs/vue/issues/8721
|
||||
const cmp: any = this;
|
||||
|
||||
return createElement(coreTag, {
|
||||
'attrs': cmp.attrs,
|
||||
'on': {
|
||||
'ionChange': cmp.handleChange,
|
||||
'ionInput': cmp.handleInput,
|
||||
'ionBlur': cmp.handleBlur,
|
||||
'ionFocus': cmp.handleFocus
|
||||
}
|
||||
}, this.$slots.default);
|
||||
},
|
||||
methods: {
|
||||
handleChange($event: any) {
|
||||
if (modelEvent === 'ionChange') {
|
||||
// Vue expects the value to be sent as the argument for v-model, not the
|
||||
// actual event object
|
||||
this.$emit('ionChange', $event.target[valueProperty]);
|
||||
} else {
|
||||
this.$emit('ionChange', $event);
|
||||
}
|
||||
},
|
||||
handleInput($event: any) {
|
||||
if (modelEvent === 'ionInput') {
|
||||
// Vue expects the value to be sent as the argument for v-model, not the
|
||||
// actual event object
|
||||
this.$emit('ionInput', $event.target[valueProperty]);
|
||||
} else {
|
||||
this.$emit('ionInput', $event);
|
||||
}
|
||||
},
|
||||
handleBlur($event: any) {
|
||||
this.$emit('ionBlur', $event);
|
||||
},
|
||||
handleFocus($event: any) {
|
||||
this.$emit('ionFocus', $event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { CreateElement, RenderContext } from 'vue';
|
||||
|
||||
export default {
|
||||
name: 'IonPage',
|
||||
functional: true,
|
||||
render(h: CreateElement, { children }: RenderContext) {
|
||||
return h('div', { class: { 'ion-page': true } }, children);
|
||||
}
|
||||
};
|
||||
@@ -1,227 +0,0 @@
|
||||
import Vue, { CreateElement, RenderContext, VNode } from 'vue';
|
||||
import { Route } from 'vue-router';
|
||||
|
||||
interface EventListeners {
|
||||
[key: string]: Function | Function[];
|
||||
}
|
||||
|
||||
const tabBars = [] as VNode[];
|
||||
const cachedTabs = [] as VNode[];
|
||||
|
||||
export default {
|
||||
name: 'IonTabs',
|
||||
functional: true,
|
||||
render(h: CreateElement, { parent, data, slots, listeners }: RenderContext) {
|
||||
const renderQueue = [] as VNode[];
|
||||
const postRenderQueue = [] as VNode[];
|
||||
const route = parent.$route;
|
||||
let selectedTab = '';
|
||||
|
||||
if (!parent.$router) {
|
||||
throw new Error('IonTabs requires an instance of either VueRouter or IonicVueRouter');
|
||||
}
|
||||
|
||||
// Loop through all of the children in the default slot
|
||||
for (let i = 0; i < slots().default.length; i++) {
|
||||
const vnode = slots().default[i];
|
||||
|
||||
// Not an ion-tab, push to render and post-render processing queues
|
||||
if (!vnode.tag || vnode.tag.match(/ion-tab$/) === null) {
|
||||
renderQueue.push(vnode);
|
||||
postRenderQueue[i] = vnode;
|
||||
continue;
|
||||
}
|
||||
|
||||
const tabName = matchRouteToTab(vnode, route);
|
||||
const tabIsCached = cachedTabs[i];
|
||||
|
||||
// Landed on tab route
|
||||
// Cache the tab, push to render queue and continue iteration
|
||||
if (tabName) {
|
||||
if (!tabIsCached) {
|
||||
cachedTabs[i] = vnode;
|
||||
}
|
||||
|
||||
selectedTab = tabName;
|
||||
vnode.data.attrs.active = true;
|
||||
renderQueue.push(vnode);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If tab was previously cached, push to render queue but don't activate
|
||||
// Otherwise push an empty node
|
||||
renderQueue.push(tabIsCached ? vnode : h());
|
||||
}
|
||||
|
||||
// Post processing after initial render
|
||||
// Required for tabs within Vue components or router view
|
||||
Vue.nextTick(() => {
|
||||
for (let i = 0; i < postRenderQueue.length; i++) {
|
||||
const vnode = postRenderQueue[i];
|
||||
|
||||
if (vnode && vnode.elm && vnode.elm.nodeName === 'ION-TAB') {
|
||||
const ionTab = vnode.elm as HTMLIonTabElement;
|
||||
const vnodeData = {
|
||||
data: {
|
||||
attrs: { tab: ionTab.getAttribute('tab'), routes: ionTab.getAttribute('route') },
|
||||
},
|
||||
};
|
||||
const tabName = matchRouteToTab(vnodeData as any, route);
|
||||
|
||||
// Set tab active state
|
||||
ionTab.active = !!tabName;
|
||||
|
||||
// Loop through all tab-bars and set active tab
|
||||
if (tabName) {
|
||||
for (const tabBar of tabBars) {
|
||||
(tabBar.elm as HTMLIonTabBarElement).selectedTab = tabName;
|
||||
}
|
||||
}
|
||||
|
||||
cachedTabs[i] = vnode;
|
||||
}
|
||||
}
|
||||
|
||||
// Free tab-bars references
|
||||
tabBars.length = 0;
|
||||
});
|
||||
|
||||
// Render
|
||||
return h('div', { ...data, style: hostStyles }, [
|
||||
parseSlot(slots().top, selectedTab, listeners),
|
||||
h('div', { class: 'tabs-inner', style: tabsInner }, renderQueue),
|
||||
parseSlot(slots().bottom, selectedTab, listeners),
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
// Search for ion-tab-bar in VNode array
|
||||
function parseSlot(slot: VNode[], tab: string, listeners: EventListeners): VNode[] {
|
||||
const vnodes = [] as VNode[];
|
||||
|
||||
if (!slot) {
|
||||
return vnodes;
|
||||
}
|
||||
|
||||
for (const vnode of slot) {
|
||||
vnodes.push(vnode.tag && vnode.tag.match(/ion-tab-bar$/) ? parseTabBar(vnode, tab, listeners) : vnode);
|
||||
}
|
||||
|
||||
return vnodes;
|
||||
}
|
||||
|
||||
// Set selected tab attribute and click handlers
|
||||
function parseTabBar(vnode: VNode, tab: string, listeners: EventListeners): VNode {
|
||||
const { IonTabsWillChange, IonTabsDidChange } = listeners;
|
||||
|
||||
if (!vnode.data) {
|
||||
vnode.data = {
|
||||
attrs: {
|
||||
'selected-tab': tab,
|
||||
},
|
||||
};
|
||||
} else if (!vnode.data.attrs) {
|
||||
vnode.data.attrs = { 'selected-tab': tab };
|
||||
} else {
|
||||
vnode.data.attrs['selected-tab'] = tab;
|
||||
}
|
||||
|
||||
// Loop through ion-tab-buttons and assign click handlers
|
||||
// If custom click handler was provided, do not override it
|
||||
if (vnode.children) {
|
||||
for (const child of vnode.children) {
|
||||
if (child.tag && child.tag === 'ion-tab-button') {
|
||||
const clickHandler = (e: Event) => {
|
||||
const path = (child.elm as HTMLIonTabButtonElement).tab || '/';
|
||||
const route = hasDataAttr(child, 'to') ? child.data!.attrs!.to : { path };
|
||||
e.preventDefault();
|
||||
|
||||
if (Array.isArray(IonTabsWillChange)) {
|
||||
IonTabsWillChange.map(item => item(route));
|
||||
} else if (IonTabsWillChange) {
|
||||
IonTabsWillChange(route);
|
||||
}
|
||||
|
||||
vnode.context!.$router.push(route, () => {
|
||||
if (Array.isArray(IonTabsDidChange)) {
|
||||
IonTabsDidChange.map(item => item(route));
|
||||
} else if (IonTabsDidChange) {
|
||||
IonTabsDidChange(route);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (!child.data || !child.data.on || !child.data.on.click) {
|
||||
Object.assign(child.data, { on: { click: clickHandler } });
|
||||
} else if (child.data.on.click) {
|
||||
// Always push our click handler to end of array
|
||||
if (Array.isArray(child.data.on.click)) {
|
||||
child.data.on.click.push(clickHandler);
|
||||
} else {
|
||||
child.data.on.click = [child.data.on.click as Function, clickHandler];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store a reference to the matched ion-tab-bar
|
||||
tabBars.push(vnode);
|
||||
|
||||
return vnode;
|
||||
}
|
||||
|
||||
// Check if a VNode has a specific attribute set
|
||||
function hasDataAttr(vnode: VNode, attr: string) {
|
||||
return vnode.data && vnode.data.attrs && vnode.data.attrs[attr];
|
||||
}
|
||||
|
||||
// Match tab to route through :routes property
|
||||
// Otherwise match by URL
|
||||
function matchRouteToTab(vnode: VNode, route: Route): string {
|
||||
if (!vnode.data || !vnode.data.attrs || !vnode.data.attrs.tab) {
|
||||
throw new Error('The tab attribute is required for an ion-tab element');
|
||||
}
|
||||
|
||||
const tabName = vnode.data.attrs.tab;
|
||||
|
||||
// Handle route matching by :routes attribute
|
||||
if (vnode.data.attrs.routes) {
|
||||
const routes = Array.isArray(vnode.data.attrs.routes)
|
||||
? vnode.data.attrs.routes
|
||||
: vnode.data.attrs.routes.replace(' ', '').split(',');
|
||||
|
||||
// Parse an array of possible matches
|
||||
for (const r of routes) {
|
||||
if (route.name === r) {
|
||||
return tabName;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (route.path.indexOf(tabName) > -1) {
|
||||
return tabName;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// CSS for ion-tabs inner and outer elements
|
||||
const hostStyles = {
|
||||
display: 'flex',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
contain: 'layout size style',
|
||||
};
|
||||
|
||||
const tabsInner = {
|
||||
position: 'relative',
|
||||
flex: 1,
|
||||
contain: 'layout size style',
|
||||
};
|
||||
@@ -1,154 +0,0 @@
|
||||
import Vue, { CreateElement, RenderContext, VNodeData } from 'vue';
|
||||
import { NavDirection } from '@ionic/core';
|
||||
|
||||
type TransitionDone = () => void;
|
||||
interface Props {
|
||||
name: string;
|
||||
animated: boolean;
|
||||
}
|
||||
|
||||
// Component entering the view
|
||||
let enteringEl: HTMLElement;
|
||||
|
||||
export default {
|
||||
name: 'IonVueRouter',
|
||||
functional: true,
|
||||
|
||||
props: {
|
||||
// Router view name
|
||||
name: { default: 'default', type: String },
|
||||
// Disable transitions
|
||||
animated: { default: true, type: Boolean },
|
||||
},
|
||||
|
||||
render(h: CreateElement, { parent, props, data, children }: RenderContext) {
|
||||
if (!parent.$router) {
|
||||
throw new Error('IonTabs requires an instance of either VueRouter or IonicVueRouter');
|
||||
}
|
||||
|
||||
const ionRouterOutletData: VNodeData = {
|
||||
...data,
|
||||
ref: 'ionRouterOutlet',
|
||||
on: { click: (event: Event) => catchIonicGoBack(parent, event) },
|
||||
};
|
||||
const routerViewData: VNodeData = { props: { name: props.name } };
|
||||
const transitionData: VNodeData = {
|
||||
props: { css: false, mode: 'in-out' },
|
||||
on: {
|
||||
leave: (el: HTMLElement, done: TransitionDone) => {
|
||||
leave(parent, props as Props, el, done);
|
||||
},
|
||||
beforeEnter,
|
||||
enter,
|
||||
afterEnter,
|
||||
beforeLeave,
|
||||
afterLeave,
|
||||
enterCancelled,
|
||||
leaveCancelled,
|
||||
}
|
||||
};
|
||||
|
||||
return h('ion-router-outlet', ionRouterOutletData, [
|
||||
h('transition', transitionData, [
|
||||
h('router-view', routerViewData, children)
|
||||
])
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
function catchIonicGoBack(parent: Vue, event: Event): void {
|
||||
// In case of nested ion-vue-routers run only once
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
if (!event.target) return;
|
||||
|
||||
// We only care for the event coming from Ionic's back button
|
||||
const backButton = (event.target as HTMLElement).closest('ion-back-button') as HTMLIonBackButtonElement;
|
||||
if (!backButton) return;
|
||||
|
||||
const $router = parent.$router;
|
||||
let defaultHref: string;
|
||||
|
||||
// Explicitly override router direction to always trigger a back transition
|
||||
$router.directionOverride = 'back';
|
||||
|
||||
// If we can go back - do so
|
||||
if ($router.canGoBack()) {
|
||||
event.preventDefault();
|
||||
$router.back();
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's a default fallback - use it
|
||||
defaultHref = backButton.defaultHref as string;
|
||||
if (undefined !== defaultHref) {
|
||||
event.preventDefault();
|
||||
$router.push(defaultHref);
|
||||
}
|
||||
}
|
||||
|
||||
// Transition when we leave the route
|
||||
function leave(parent: Vue, props: Props, el: HTMLElement, done: TransitionDone) {
|
||||
const promise = transition(parent, props, el);
|
||||
|
||||
// Skip any transition if we don't get back a Promise
|
||||
if (!promise) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform navigation once the transition was finished
|
||||
parent.$router.transition = new Promise(resolve => {
|
||||
promise.then(() => {
|
||||
resolve();
|
||||
done();
|
||||
}).catch(console.error);
|
||||
});
|
||||
}
|
||||
|
||||
// Trigger the ionic/core transitions
|
||||
function transition(parent: Vue, props: Props, leavingEl: HTMLElement) {
|
||||
const ionRouterOutlet = parent.$refs.ionRouterOutlet as HTMLIonRouterOutletElement;
|
||||
|
||||
// The Ionic framework didn't load - skip animations
|
||||
if (typeof ionRouterOutlet.componentOnReady === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip animations if there's no component to navigate to
|
||||
// or the current and the "to-be-rendered" components are the same
|
||||
if (!enteringEl || enteringEl === leavingEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the proper Ionic classes, important for smooth transitions
|
||||
enteringEl.classList.add('ion-page');
|
||||
enteringEl.classList.add('ion-page-invisible');
|
||||
|
||||
// Commit to the transition as soon as the Ionic Router Outlet is ready
|
||||
return ionRouterOutlet.componentOnReady().then((el: HTMLIonRouterOutletElement) => {
|
||||
return el.commit(enteringEl, leavingEl, {
|
||||
deepWait: true,
|
||||
duration: !props.animated || parent.$router.direction === 'root' ? 0 : undefined,
|
||||
direction: parent.$router.direction as NavDirection,
|
||||
showGoBack: parent.$router.canGoBack(),
|
||||
});
|
||||
}).catch(console.error);
|
||||
}
|
||||
|
||||
// Set the component to be rendered before we render the new route
|
||||
function beforeEnter(el: HTMLElement) {
|
||||
enteringEl = el;
|
||||
}
|
||||
|
||||
// Enter the new route
|
||||
function enter(_el: HTMLElement, done: TransitionDone) {
|
||||
done();
|
||||
}
|
||||
|
||||
// Vue transition stub functions
|
||||
function afterEnter(_el: HTMLElement) { /* */ }
|
||||
function afterLeave(_el: HTMLElement) { /* */ }
|
||||
function beforeLeave(_el: HTMLElement) { /* */ }
|
||||
function enterCancelled(_el: HTMLElement) { /* */ }
|
||||
function leaveCancelled(_el: HTMLElement) { /* */ }
|
||||
@@ -1,9 +0,0 @@
|
||||
import { ActionSheetOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
|
||||
export const CTRL = 'ion-action-sheet-controller';
|
||||
export class ActionSheetController extends OverlayBaseController<ActionSheetOptions, HTMLIonActionSheetElement> {
|
||||
constructor() {
|
||||
super(CTRL);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { AlertOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
|
||||
export const CTRL = 'ion-alert-controller';
|
||||
export class AlertController extends OverlayBaseController<AlertOptions, HTMLIonAlertElement> {
|
||||
constructor() {
|
||||
super(CTRL);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export { ActionSheetController } from './action-sheet-controller';
|
||||
export { AlertController } from './alert-controller';
|
||||
export { LoadingController } from './loading-controller';
|
||||
export { MenuController } from './menu-controller';
|
||||
export { ModalController } from './modal-controller';
|
||||
export { PopoverController } from './popover-controller';
|
||||
export { ToastController } from './toast-controller';
|
||||
@@ -1,8 +0,0 @@
|
||||
import { LoadingOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
|
||||
export class LoadingController extends OverlayBaseController<LoadingOptions, HTMLIonLoadingElement> {
|
||||
constructor() {
|
||||
super('ion-loading-controller');
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
import { proxyMethod } from '../util';
|
||||
|
||||
export const CTRL = 'ion-menu-controller';
|
||||
export class MenuController {
|
||||
|
||||
/**
|
||||
* Programmatically open the Menu.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu is fully opened
|
||||
*/
|
||||
open(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'open', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Programmatically close the Menu. If no `menuId` is given as the first
|
||||
* argument then it'll close any menu which is open. If a `menuId`
|
||||
* is given then it'll close that exact menu.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu is fully closed
|
||||
*/
|
||||
close(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'close', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the menu. If it's closed, it will open, and if opened, it
|
||||
* will close.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu has been toggled
|
||||
*/
|
||||
toggle(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'toggle', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to enable or disable a menu. For example, there could be multiple
|
||||
* left menus, but only one of them should be able to be opened at the same
|
||||
* time. If there are multiple menus on the same side, then enabling one menu
|
||||
* will also automatically disable all the others that are on the same side.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'enable', shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to enable or disable the ability to swipe open the menu.
|
||||
* @param shouldEnable True if it should be swipe-able, false if not.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
swipeGesture(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'swipeGesture', shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns true if the specified menu is currently open, otherwise false.
|
||||
* If the menuId is not specified, it returns true if ANY menu is currenly open.
|
||||
*/
|
||||
isOpen(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'isOpen', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns true if the menu is currently enabled, otherwise false.
|
||||
*/
|
||||
isEnabled(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'isEnabled', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a menu instance. If a `menuId` is not provided then it'll
|
||||
* return the first menu found. If a `menuId` is `left` or `right`, then
|
||||
* it'll return the enabled menu on that side. Otherwise, if a `menuId` is
|
||||
* provided, then it'll try to find the menu using the menu's `id`
|
||||
* property. If a menu is not found then it'll return `null`.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu if found, otherwise `null`.
|
||||
*/
|
||||
get(menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'get', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the instance of the menu already opened, otherwise `null`.
|
||||
*/
|
||||
getOpen(): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'getOpen');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns an array of all menu instances.
|
||||
*/
|
||||
getMenus(): Promise<HTMLIonMenuElement[]> {
|
||||
return proxyMethod(CTRL, 'getMenus');
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { ModalOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
import { VueDelegate } from './vue-delegate';
|
||||
|
||||
export const CTRL = 'ion-modal-controller';
|
||||
export class ModalController extends OverlayBaseController<ModalOptions, HTMLIonModalElement> {
|
||||
|
||||
constructor(
|
||||
private delegate: VueDelegate
|
||||
) {
|
||||
super(CTRL);
|
||||
}
|
||||
|
||||
create(opts: ModalOptions): Promise<HTMLIonModalElement> {
|
||||
return super.create({
|
||||
...opts,
|
||||
delegate: this.delegate
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { PickerOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
|
||||
export const CTRL = 'ion-picker-controller';
|
||||
export class PickerController extends OverlayBaseController<PickerOptions, HTMLIonPickerElement> {
|
||||
constructor() {
|
||||
super(CTRL);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { PopoverOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
import { VueDelegate } from './vue-delegate';
|
||||
|
||||
export const CTRL = 'ion-popover-controller';
|
||||
export class PopoverController extends OverlayBaseController<PopoverOptions, HTMLIonPopoverElement> {
|
||||
|
||||
constructor(
|
||||
private delegate: VueDelegate
|
||||
) {
|
||||
super(CTRL);
|
||||
}
|
||||
|
||||
create(opts: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
||||
return super.create({
|
||||
...opts,
|
||||
delegate: this.delegate
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import { ToastOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util';
|
||||
|
||||
export class ToastController extends OverlayBaseController<ToastOptions, HTMLIonToastElement> {
|
||||
constructor() {
|
||||
super('ion-toast-controller');
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
import { VueConstructor } from 'vue';
|
||||
import { FrameworkDelegate, LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE, LIFECYCLE_WILL_UNLOAD } from '@ionic/core';
|
||||
import { EsModule, HTMLVueElement, WebpackFunction } from '../interfaces';
|
||||
|
||||
|
||||
// Handle creation of sync and async components
|
||||
function createVueComponent(vue: VueConstructor, component: WebpackFunction | object | VueConstructor): Promise<VueConstructor> {
|
||||
return Promise.resolve(
|
||||
typeof component === 'function' && (component as WebpackFunction).cid === undefined
|
||||
? (component as WebpackFunction)().then((cmp: any) => vue.extend(isESModule(cmp) ? cmp.default : cmp))
|
||||
: vue.extend(component)
|
||||
);
|
||||
}
|
||||
|
||||
export class VueDelegate implements FrameworkDelegate {
|
||||
constructor(
|
||||
public vue: VueConstructor,
|
||||
) {}
|
||||
|
||||
// Attach the passed Vue component to DOM
|
||||
attachViewToDom(parentElement: HTMLElement, component: HTMLElement | WebpackFunction | object | VueConstructor, opts?: object, classes?: string[]): Promise<HTMLElement> {
|
||||
// Handle HTML elements
|
||||
if (isElement(component)) {
|
||||
// Add any classes to the element
|
||||
addClasses(component as HTMLElement, classes);
|
||||
|
||||
// Append the element to DOM
|
||||
parentElement.appendChild(component as HTMLElement);
|
||||
bindLifecycleEvents(component, parentElement);
|
||||
return Promise.resolve(component as HTMLElement);
|
||||
}
|
||||
|
||||
// Get the Vue controller
|
||||
return createVueComponent(this.vue, component).then((Component: VueConstructor) => {
|
||||
const componentInstance = new Component(opts);
|
||||
componentInstance.$mount();
|
||||
|
||||
// Add any classes to the Vue component's root element
|
||||
addClasses(componentInstance.$el as HTMLElement, classes);
|
||||
|
||||
// Append the Vue component to DOM
|
||||
parentElement.appendChild(componentInstance.$el);
|
||||
return componentInstance.$el as HTMLElement;
|
||||
});
|
||||
}
|
||||
|
||||
// Remove the earlier created Vue component from DOM
|
||||
removeViewFromDom(_parentElement: HTMLElement, childElement: HTMLVueElement): Promise<void> {
|
||||
// Destroy the Vue component instance
|
||||
if (childElement.__vue__) {
|
||||
childElement.__vue__.$destroy();
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
const LIFECYCLES = [
|
||||
LIFECYCLE_WILL_ENTER,
|
||||
LIFECYCLE_DID_ENTER,
|
||||
LIFECYCLE_WILL_LEAVE,
|
||||
LIFECYCLE_DID_LEAVE,
|
||||
LIFECYCLE_WILL_UNLOAD
|
||||
];
|
||||
|
||||
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
|
||||
LIFECYCLES.forEach(eventName => {
|
||||
element.addEventListener(eventName, (ev: any) => {
|
||||
if (typeof instance[eventName] === 'function') {
|
||||
instance[eventName](ev.detail);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Check Symbol support
|
||||
const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
|
||||
|
||||
// Check if object is an ES module
|
||||
function isESModule(obj: EsModule) {
|
||||
return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module');
|
||||
}
|
||||
|
||||
// Check if value is an Element
|
||||
function isElement(el: any) {
|
||||
return typeof Element !== 'undefined' && el instanceof Element;
|
||||
}
|
||||
|
||||
// Add an array of classes to an element
|
||||
function addClasses(element: HTMLElement, classes: string[] = []) {
|
||||
for (const cls of classes) {
|
||||
element.classList.add(cls);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { install } from './ionic';
|
||||
|
||||
export default {
|
||||
install,
|
||||
version: '__VERSION__'
|
||||
};
|
||||
|
||||
export { Controllers } from './ionic';
|
||||
export { default as IonicVueRouter } from './router';
|
||||
|
||||
export * from './components/inputs';
|
||||
@@ -1,89 +0,0 @@
|
||||
import Vue from 'vue';
|
||||
import VueRouter from 'vue-router';
|
||||
import { RouterDirection, HTMLStencilElement } from '@ionic/core';
|
||||
import { RouterOptions } from 'vue-router/types/router';
|
||||
|
||||
declare module 'vue-router/types/router' {
|
||||
interface VueRouter {
|
||||
direction: RouterDirection;
|
||||
directionOverride: RouterDirection | null;
|
||||
transition: Promise<void>;
|
||||
canGoBack(): boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export interface HTMLVueElement extends HTMLElement {
|
||||
__vue__: Vue;
|
||||
}
|
||||
|
||||
export interface VueWindow extends Window {
|
||||
Vue: typeof Vue;
|
||||
VueRouter: typeof VueRouter;
|
||||
disableIonicTransitions: boolean;
|
||||
}
|
||||
|
||||
export interface WebpackFunction extends Function {
|
||||
cid: number;
|
||||
}
|
||||
|
||||
export interface EsModule extends Object {
|
||||
__esModule?: boolean;
|
||||
[Symbol.toStringTag]: string;
|
||||
}
|
||||
|
||||
export interface IonicGlobal {
|
||||
config?: any;
|
||||
ael?: (elm: any, eventName: string, cb: (ev: Event) => void, opts: any) => void;
|
||||
raf?: (ts: number) => void;
|
||||
rel?: (elm: any, eventName: string, cb: (ev: Event) => void, opts: any) => void;
|
||||
}
|
||||
|
||||
export interface IonicWindow extends Window {
|
||||
Ionic: IonicGlobal;
|
||||
}
|
||||
|
||||
export interface FrameworkDelegate {
|
||||
attachViewToDom(parentElement: HTMLElement, component: HTMLElement | WebpackFunction | object | Vue, opts?: object, classes?: string[]): Promise<HTMLElement>;
|
||||
removeViewFromDom(parentElement: HTMLElement, childElement: HTMLVueElement): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IonBackButton extends HTMLStencilElement {
|
||||
defaultHref?: string;
|
||||
}
|
||||
|
||||
export interface IonRouterOutlet extends HTMLStencilElement {
|
||||
commit(enterinEl: HTMLElement, leavingEl: HTMLElement | undefined, opts?: object | undefined): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface ApiCache {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface RouterArgs extends RouterOptions {
|
||||
direction?: RouterDirection;
|
||||
viewCount?: number;
|
||||
}
|
||||
|
||||
export interface ProxyControllerInterface {
|
||||
create(opts: object): Promise<HTMLElement>;
|
||||
dismiss(): Promise<void>;
|
||||
getTop(): Promise<HTMLElement>;
|
||||
}
|
||||
|
||||
export interface ProxyDelegateOptions extends Object {
|
||||
[key: string]: any;
|
||||
delegate?: FrameworkDelegate;
|
||||
}
|
||||
|
||||
export interface ProxyMenuControllerInterface {
|
||||
open(menuId?: string): Promise<boolean>;
|
||||
close(menuId?: string): Promise<boolean>;
|
||||
toggle(menuId?: string): Promise<boolean>;
|
||||
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLElement>;
|
||||
swipeGesture(shouldEnable: boolean, menuId?: string): Promise<HTMLElement>;
|
||||
isOpen(menuId?: string): Promise<boolean>;
|
||||
isEnabled(menuId?: string): Promise<boolean>;
|
||||
get(menuId?: string): Promise<HTMLElement>;
|
||||
getOpen(): Promise<HTMLElement>;
|
||||
getMenus(): Promise<HTMLElement>;
|
||||
}
|
||||
118
vue/src/ionic.ts
118
vue/src/ionic.ts
@@ -1,118 +0,0 @@
|
||||
import { PluginFunction, VueConstructor, default as VueImport } from 'vue';
|
||||
import {
|
||||
ActionSheetController,
|
||||
AlertController,
|
||||
LoadingController,
|
||||
MenuController,
|
||||
ModalController,
|
||||
PopoverController,
|
||||
ToastController
|
||||
} from './controllers';
|
||||
import { IonicConfig } from '@ionic/core';
|
||||
import { appInitialize } from './app-initialize';
|
||||
import { VueDelegate } from './controllers/vue-delegate';
|
||||
import IonTabs from './components/navigation/ion-tabs';
|
||||
import IonPage from './components/navigation/ion-page';
|
||||
import { createInputComponent } from './components/inputs';
|
||||
|
||||
export interface Controllers {
|
||||
actionSheetController: ActionSheetController;
|
||||
alertController: AlertController;
|
||||
loadingController: LoadingController;
|
||||
menuController: MenuController;
|
||||
modalController: ModalController;
|
||||
popoverController: PopoverController;
|
||||
toastController: ToastController;
|
||||
}
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
$ionic: Controllers;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function createApi(vueInstance: VueConstructor) {
|
||||
const cache: Partial<Controllers> = {};
|
||||
const vueDelegate = new VueDelegate(vueInstance);
|
||||
|
||||
return {
|
||||
get actionSheetController() {
|
||||
if (!cache.actionSheetController) {
|
||||
cache.actionSheetController = new ActionSheetController();
|
||||
}
|
||||
return cache.actionSheetController;
|
||||
},
|
||||
get alertController() {
|
||||
if (!cache.alertController) {
|
||||
cache.alertController = new AlertController();
|
||||
}
|
||||
return cache.alertController;
|
||||
},
|
||||
get loadingController() {
|
||||
if (!cache.loadingController) {
|
||||
cache.loadingController = new LoadingController();
|
||||
}
|
||||
return cache.loadingController;
|
||||
},
|
||||
get menuController() {
|
||||
if (!cache.menuController) {
|
||||
cache.menuController = new MenuController();
|
||||
}
|
||||
return cache.menuController;
|
||||
},
|
||||
get modalController() {
|
||||
if (!cache.modalController) {
|
||||
cache.modalController = new ModalController(vueDelegate);
|
||||
}
|
||||
return cache.modalController;
|
||||
},
|
||||
get popoverController() {
|
||||
if (!cache.popoverController) {
|
||||
cache.popoverController = new PopoverController(vueDelegate);
|
||||
}
|
||||
return cache.popoverController;
|
||||
},
|
||||
get toastController() {
|
||||
if (!cache.toastController) {
|
||||
cache.toastController = new ToastController();
|
||||
}
|
||||
return cache.toastController;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let Vue: typeof VueImport;
|
||||
|
||||
export const install: PluginFunction<IonicConfig> = (_Vue, config) => {
|
||||
if (Vue && _Vue === Vue) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.error(
|
||||
'[Ionic] already installed. Vue.use(Ionic) should be called only once.'
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Vue = _Vue;
|
||||
Vue.config.ignoredElements.push(/^ion-/);
|
||||
Vue.component('IonTabs', IonTabs);
|
||||
Vue.component('IonPage', IonPage);
|
||||
|
||||
createInputComponent('IonCheckboxVue', 'ion-checkbox', 'ionChange', 'checked');
|
||||
createInputComponent('IonDatetimeVue', 'ion-datetime');
|
||||
createInputComponent('IonInputVue', 'ion-input', 'ionInput');
|
||||
createInputComponent('IonRadioVue', 'ion-radio');
|
||||
createInputComponent('IonRangeVue', 'ion-range');
|
||||
createInputComponent('IonSearchbarVue', 'ion-searchbar', 'ionInput');
|
||||
createInputComponent('IonSelectVue', 'ion-select');
|
||||
createInputComponent('IonTextareaVue', 'ion-textarea');
|
||||
createInputComponent('IonToggleVue', 'ion-toggle', 'ionChange', 'checked');
|
||||
|
||||
appInitialize(config);
|
||||
|
||||
const api = createApi(Vue);
|
||||
|
||||
Object.defineProperty(Vue.prototype, '$ionic', {
|
||||
get() { return api; }
|
||||
});
|
||||
};
|
||||
@@ -1,124 +0,0 @@
|
||||
import VueRouter, { Route } from 'vue-router';
|
||||
import { PluginFunction } from 'vue';
|
||||
import { RouterArgs } from './interfaces';
|
||||
import IonVueRouter from './components/navigation/ion-vue-router';
|
||||
import { BackButtonEvent, RouterDirection } from '@ionic/core';
|
||||
|
||||
// Extend the official VueRouter
|
||||
export default class Router extends VueRouter {
|
||||
direction: RouterDirection;
|
||||
directionOverride: RouterDirection | null;
|
||||
viewCount: number;
|
||||
prevRouteStack: Route[];
|
||||
history: any;
|
||||
static installed: boolean;
|
||||
static install: PluginFunction<never>;
|
||||
|
||||
constructor(args: RouterArgs = {} as RouterArgs) {
|
||||
super(args);
|
||||
|
||||
// The direction user navigates in
|
||||
this.direction = args.direction || 'forward';
|
||||
|
||||
// Override normal direction
|
||||
this.directionOverride = null;
|
||||
|
||||
// Number of views navigated
|
||||
this.viewCount = args.viewCount || 0;
|
||||
|
||||
// Stack of previous routes
|
||||
this.prevRouteStack = [];
|
||||
|
||||
// Extend the existing history object
|
||||
this.extendHistory();
|
||||
|
||||
// Wait for transition to finish before confirming navigation
|
||||
this.extendTransitionConfirmation();
|
||||
|
||||
// Listen to Ionic's back button event
|
||||
document.addEventListener('ionBackButton', (e: Event) => {
|
||||
(e as BackButtonEvent).detail.register(0, processNextHandler => {
|
||||
this.back();
|
||||
processNextHandler();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
extendTransitionConfirmation() {
|
||||
this.history._confirmTransition = this.history.confirmTransition;
|
||||
this.history.confirmTransition = async (...opts: any) => {
|
||||
if (undefined !== this.transition) {
|
||||
await this.transition;
|
||||
}
|
||||
this.history._confirmTransition(...opts);
|
||||
};
|
||||
}
|
||||
|
||||
extendHistory() {
|
||||
// Save a reference to the original method
|
||||
this.history._updateRoute = this.history.updateRoute;
|
||||
|
||||
this.history.updateRoute = (nextRoute: Route) => {
|
||||
// Guesstimate the direction of the next route
|
||||
this.direction = this.guessDirection(nextRoute);
|
||||
|
||||
// Override the direction
|
||||
if (this.directionOverride) {
|
||||
this.direction = this.directionOverride;
|
||||
}
|
||||
|
||||
// Increment or decrement the view count
|
||||
this.viewCount += this.direction === 'back' ? -1 : 1;
|
||||
|
||||
// Call the original method
|
||||
this.history._updateRoute(nextRoute);
|
||||
|
||||
// Reset direction overrides
|
||||
this.directionOverride = null;
|
||||
};
|
||||
}
|
||||
|
||||
canGoBack(): boolean {
|
||||
// We can display the back button if we're not on /
|
||||
// or there were more than 1 views rendered
|
||||
return this.viewCount > 1 && this.currentRoute.fullPath.length > 1;
|
||||
}
|
||||
|
||||
guessDirection(nextRoute: Route): RouterDirection {
|
||||
if (this.prevRouteStack.length !== 0) {
|
||||
const prevRoute: Route = this.prevRouteStack[this.prevRouteStack.length - 1];
|
||||
|
||||
// Last route is the same as the next one - go back
|
||||
// If we're going to / reset the stack otherwise pop a route
|
||||
if (prevRoute.fullPath === nextRoute.fullPath) {
|
||||
if (prevRoute.fullPath.length === 1) {
|
||||
this.prevRouteStack = [];
|
||||
} else {
|
||||
this.prevRouteStack.pop();
|
||||
}
|
||||
return 'back';
|
||||
}
|
||||
}
|
||||
|
||||
// Forward movement, push next route to stack
|
||||
if (this.history.current.fullPath !== nextRoute.fullPath) {
|
||||
this.prevRouteStack.push(this.history.current);
|
||||
}
|
||||
return 'forward';
|
||||
}
|
||||
}
|
||||
|
||||
Router.install = (Vue) => {
|
||||
// If already installed - skip
|
||||
if (Router.installed) {
|
||||
return;
|
||||
}
|
||||
|
||||
Router.installed = true;
|
||||
|
||||
// Install the official VueRouter
|
||||
VueRouter.install(Vue);
|
||||
|
||||
// Register the IonVueRouter component globally
|
||||
Vue.component('IonVueRouter', IonVueRouter);
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import { HTMLStencilElement } from '@ionic/core';
|
||||
|
||||
export class OverlayBaseController<Opts, Overlay> {
|
||||
constructor(private ctrl: string) {}
|
||||
|
||||
create(opts?: Opts): Promise<Overlay> {
|
||||
return proxyMethod(this.ctrl, 'create', opts);
|
||||
}
|
||||
|
||||
dismiss(data?: any, role?: string, id?: string): Promise<void> {
|
||||
return proxyMethod(this.ctrl, 'dismiss', data, role, id);
|
||||
}
|
||||
|
||||
getTop(): Promise<Overlay> {
|
||||
return proxyMethod(this.ctrl, 'getTop');
|
||||
}
|
||||
}
|
||||
|
||||
export function proxyMethod(ctrlName: string, methodName: string, ...args: any[]) {
|
||||
const controller = ensureElementInBody(ctrlName);
|
||||
return controller.componentOnReady()
|
||||
.then(() => (controller as any)[methodName].apply(controller, args));
|
||||
}
|
||||
|
||||
export function ensureElementInBody(elementName: string) {
|
||||
let element = document.querySelector(elementName);
|
||||
if (!element) {
|
||||
element = document.createElement(elementName);
|
||||
document.body.appendChild(element);
|
||||
}
|
||||
return element as HTMLStencilElement;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"alwaysStrict": true,
|
||||
"strict": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowUnreachableCode": false,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"declarationDir": "dist/types",
|
||||
"experimentalDecorators": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "h",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2017"
|
||||
],
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "dist",
|
||||
"pretty": true,
|
||||
"removeComments": false,
|
||||
"rootDir": "src",
|
||||
"strictPropertyInitialization": false,
|
||||
"target": "es5"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"extends": "tslint-ionic-rules",
|
||||
"rules": {
|
||||
"no-non-null-assertion": false,
|
||||
"no-import-side-effect": [true, {"ignore-module": "(svg|\\.css)$"}]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user