mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
283 Commits
v0.1.4-0
...
v4.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1a3c7d37d | ||
|
|
d85e17c730 | ||
|
|
b1de56a41c | ||
|
|
64a9497f72 | ||
|
|
5e98939a70 | ||
|
|
79ba6391d6 | ||
|
|
a3cd5db3a7 | ||
|
|
c6e962c387 | ||
|
|
5153da458c | ||
|
|
b7395d5f0e | ||
|
|
80a94401fb | ||
|
|
b5f5812bb4 | ||
|
|
dc326c3887 | ||
|
|
6072a6e5ac | ||
|
|
5e0965260f | ||
|
|
2c5f5b3fe1 | ||
|
|
ddf2f2220d | ||
|
|
2215c6aaa1 | ||
|
|
3ba506c513 | ||
|
|
1bbd73cada | ||
|
|
25c852c2c8 | ||
|
|
f3b8ddb69d | ||
|
|
1db75aa72c | ||
|
|
9eb315fc05 | ||
|
|
8d13940188 | ||
|
|
d07246d7a0 | ||
|
|
3471dd66f7 | ||
|
|
57fbf6c396 | ||
|
|
c15772651a | ||
|
|
a436fdf201 | ||
|
|
d23108a16c | ||
|
|
2e5a6d6120 | ||
|
|
0a0959b3a7 | ||
|
|
219589598d | ||
|
|
6ecbe03b4f | ||
|
|
904af3901b | ||
|
|
974b949754 | ||
|
|
bb46b5f7b9 | ||
|
|
4db687ea17 | ||
|
|
7e97006753 | ||
|
|
11cb42facb | ||
|
|
6c8960abdd | ||
|
|
09e6b7e4a2 | ||
|
|
926c8859ce | ||
|
|
ae2cae635d | ||
|
|
1f78390c84 | ||
|
|
685d5a166c | ||
|
|
3d6a6bad8f | ||
|
|
14fedb9a44 | ||
|
|
5878ad9587 | ||
|
|
14f01177f9 | ||
|
|
a5e5403068 | ||
|
|
acd411dd6c | ||
|
|
af240a9ffa | ||
|
|
7aa5d059ad | ||
|
|
f237b7f3a9 | ||
|
|
853e55388b | ||
|
|
0793d2bf5e | ||
|
|
ff06dab3c0 | ||
|
|
0d44253da1 | ||
|
|
ff1ed888f0 | ||
|
|
230823915c | ||
|
|
cece447092 | ||
|
|
b35f95a4d8 | ||
|
|
238b7f9877 | ||
|
|
31de300256 | ||
|
|
062641d8ca | ||
|
|
f1987b6403 | ||
|
|
7923b55b84 | ||
|
|
3aa55bec17 | ||
|
|
94646fc81e | ||
|
|
6c6f867ce4 | ||
|
|
7887550166 | ||
|
|
aa085248b9 | ||
|
|
1508af4df8 | ||
|
|
172cf25380 | ||
|
|
d11bb1ed61 | ||
|
|
9c789ceac4 | ||
|
|
7b9a00e433 | ||
|
|
a36913e9db | ||
|
|
ce500858fe | ||
|
|
1f74d8dcd7 | ||
|
|
74e4b323ac | ||
|
|
9caeec7fcf | ||
|
|
d9d7462d87 | ||
|
|
a1346a9e89 | ||
|
|
88752dea51 | ||
|
|
54558c92af | ||
|
|
b0f8ca544d | ||
|
|
093feac6e4 | ||
|
|
2fa4623506 | ||
|
|
53b6471d2b | ||
|
|
f304480dfc | ||
|
|
a5d2a33016 | ||
|
|
67488b2eca | ||
|
|
0105a4ee47 | ||
|
|
b1b3c19908 | ||
|
|
eff2ef3892 | ||
|
|
d57122c382 | ||
|
|
b70837278d | ||
|
|
c31bcde720 | ||
|
|
5007c78a40 | ||
|
|
011a374f6b | ||
|
|
98403fa883 | ||
|
|
ce5b47ef99 | ||
|
|
6fbd708ae0 | ||
|
|
3f68031a09 | ||
|
|
57a5d490a6 | ||
|
|
726938f67c | ||
|
|
46bbd0fdf8 | ||
|
|
862e5719c6 | ||
|
|
49937eb98c | ||
|
|
4fdfddb6b8 | ||
|
|
113af9e53b | ||
|
|
00fc460c4e | ||
|
|
a428fdc48c | ||
|
|
7677e4f78a | ||
|
|
9e9f2a206f | ||
|
|
b26a56314b | ||
|
|
a718f7e1e3 | ||
|
|
ffaec1661a | ||
|
|
c9d2a0d33b | ||
|
|
8b4b5ba633 | ||
|
|
d0c5f53a08 | ||
|
|
1efc0f3a94 | ||
|
|
ac4ab0d767 | ||
|
|
97f1158cbc | ||
|
|
a1eabecc61 | ||
|
|
dddaee1719 | ||
|
|
076b7e55bd | ||
|
|
944140ce80 | ||
|
|
77fc792644 | ||
|
|
08f5976a57 | ||
|
|
153f8ca02c | ||
|
|
e6818369ff | ||
|
|
48d1bd412c | ||
|
|
44f343d3dc | ||
|
|
e20f76c3b1 | ||
|
|
ee1aaafd73 | ||
|
|
37345eee74 | ||
|
|
d86ee1f772 | ||
|
|
095f9c832e | ||
|
|
574c346d45 | ||
|
|
2b8e489f84 | ||
|
|
ce09978eee | ||
|
|
9836c60dae | ||
|
|
7a26162c5b | ||
|
|
69a6f8d012 | ||
|
|
eb0ff2f09d | ||
|
|
02173484eb | ||
|
|
a9bd76adc6 | ||
|
|
1f19cc48c7 | ||
|
|
59c6891249 | ||
|
|
1c06bfeaac | ||
|
|
5c2678f7ea | ||
|
|
4fcddadcc9 | ||
|
|
b29fce1b8f | ||
|
|
eae6869012 | ||
|
|
c2ce0f2d2d | ||
|
|
59a0341104 | ||
|
|
1a37493c79 | ||
|
|
332eaaebb0 | ||
|
|
7b50ea974f | ||
|
|
6f5b86982c | ||
|
|
2b8549bd3f | ||
|
|
f904fd111b | ||
|
|
7d53e49912 | ||
|
|
98b82537a9 | ||
|
|
72fab3665c | ||
|
|
814cf73a00 | ||
|
|
3829886a74 | ||
|
|
99610f7f08 | ||
|
|
943e2f73c0 | ||
|
|
f0a40fabb9 | ||
|
|
371fc19a06 | ||
|
|
605ec93179 | ||
|
|
08553f1bac | ||
|
|
fc30ba18f3 | ||
|
|
d26074a17f | ||
|
|
6e683c54e0 | ||
|
|
a98c764541 | ||
|
|
ee27549c84 | ||
|
|
c03afabc0f | ||
|
|
17a3001af5 | ||
|
|
4693229c84 | ||
|
|
779f02c932 | ||
|
|
e19b2142c5 | ||
|
|
97dc113a9f | ||
|
|
b49a45d81d | ||
|
|
7dbd42f9b2 | ||
|
|
fd0ceda0e9 | ||
|
|
9988c754ac | ||
|
|
769282935b | ||
|
|
9094c66f3d | ||
|
|
f39d3ad9dd | ||
|
|
d3105d1a76 | ||
|
|
b49e9eb027 | ||
|
|
f578122d15 | ||
|
|
41f54f8e2d | ||
|
|
3a26256a5c | ||
|
|
a73c461ed4 | ||
|
|
06ad60ea0c | ||
|
|
28215a3722 | ||
|
|
b82c38202f | ||
|
|
f16a9672b4 | ||
|
|
c85f7483c9 | ||
|
|
4d8a99f03b | ||
|
|
e8cf9927cc | ||
|
|
2afbd9dbb1 | ||
|
|
d8234e90dd | ||
|
|
50abcf5ab3 | ||
|
|
176d4994d1 | ||
|
|
7d2de18a7c | ||
|
|
a7373232da | ||
|
|
c41f9dd01c | ||
|
|
2bdf4add5a | ||
|
|
bb3f406ffc | ||
|
|
207f416686 | ||
|
|
f48d817a85 | ||
|
|
7c3cba0b92 | ||
|
|
147a6090e4 | ||
|
|
e729610dc8 | ||
|
|
b4f46ee3d2 | ||
|
|
3b5f758318 | ||
|
|
f398b3a945 | ||
|
|
9a0755a268 | ||
|
|
6e2ca85b2a | ||
|
|
cc4fecc1be | ||
|
|
de22ecae82 | ||
|
|
7dcf8a5bd4 | ||
|
|
73f2f2b2b2 | ||
|
|
c9f71dd2df | ||
|
|
a5923d6eb2 | ||
|
|
30f2ac2286 | ||
|
|
ba63d01f78 | ||
|
|
d37623a2ca | ||
|
|
097f1a2cd3 | ||
|
|
506b1ac53e | ||
|
|
6e2a9c936d | ||
|
|
12c78bcb62 | ||
|
|
fcdf35565f | ||
|
|
7df023abb7 | ||
|
|
cadcab9b40 | ||
|
|
22f6a34f5b | ||
|
|
b56c2a83e5 | ||
|
|
0b099ce2b8 | ||
|
|
6383a54f35 | ||
|
|
64f08669c2 | ||
|
|
7dcefe345c | ||
|
|
6b0327f2ef | ||
|
|
1ace0450cb | ||
|
|
f67100857b | ||
|
|
f5c6333417 | ||
|
|
88f2981044 | ||
|
|
f2ac6e3064 | ||
|
|
b075ae0e71 | ||
|
|
74e032a8cc | ||
|
|
64a787a9de | ||
|
|
8b6df5abbd | ||
|
|
743277eb6e | ||
|
|
7b67342690 | ||
|
|
5271f6845e | ||
|
|
3ce8a67409 | ||
|
|
d1263a8b9c | ||
|
|
1dad0adb03 | ||
|
|
878d7e64b0 | ||
|
|
4a3030f087 | ||
|
|
d609a222eb | ||
|
|
7387d34271 | ||
|
|
1bf50cb1a7 | ||
|
|
c7fe694a5d | ||
|
|
540c33bb6b | ||
|
|
f29e3f4ea4 | ||
|
|
cc365f829d | ||
|
|
dc8b363ea8 | ||
|
|
a8b90a3eb1 | ||
|
|
d313e69013 | ||
|
|
851aa838fa | ||
|
|
a1f942d45e | ||
|
|
7b264f983b | ||
|
|
9650bec06a | ||
|
|
174d9b5a41 | ||
|
|
c8a27b7a19 |
31
.github/ISSUE_TEMPLATE.md
vendored
31
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,12 +1,18 @@
|
||||
<!-- Before submitting an issue, please consult our troubleshooting guide (http://ionicframework.com/docs/troubleshooting/) and developer resources (http://ionicframework.com/docs/developer-resources/) -->
|
||||
|
||||
<!-- Please make sure you are posting an issue pertaining to the Ionic Framework. If you are having an issue with the Ionic Pro services (Ionic View, Ionic Deploy, etc.) please consult the Ionic Pro support portal (http://support.ionicjs.com) -->
|
||||
|
||||
**Ionic version:** (check one with "x")
|
||||
[ ] **1.x** (For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
(For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
[ ] **2.x**
|
||||
[ ] **3.x**
|
||||
[ ] **4.x**
|
||||
|
||||
**I'm submitting a ...** (check one with "x")
|
||||
[ ] bug report
|
||||
[ ] feature request
|
||||
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
|
||||
|
||||
<!-- Please do not submit support requests or "How to" questions here. Instead, please use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/ -->
|
||||
|
||||
**Current behavior:**
|
||||
<!-- Describe how the bug manifests. -->
|
||||
@@ -15,17 +21,22 @@
|
||||
<!-- Describe what the behavior would be without the bug. -->
|
||||
|
||||
**Steps to reproduce:**
|
||||
<!-- If you are able to illustrate the bug or feature request with an example, please provide steps to reproduce and if possible a demo using one of the following templates:
|
||||
|
||||
For Ionic V1 issues - http://plnkr.co/edit/Xo1QyAUx35ny1Xf9ODHx?p=preview
|
||||
|
||||
For Ionic issues - http://plnkr.co/edit/z0DzVL?p=preview
|
||||
-->
|
||||
<!-- Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. -->
|
||||
|
||||
**Related code:**
|
||||
|
||||
<!-- If you are able to illustrate the bug or feature request with an example, please provide a sample application via one of the following means:
|
||||
|
||||
A sample application via GitHub
|
||||
|
||||
StackBlitz (https://stackblitz.com)
|
||||
|
||||
Plunker (http://plnkr.co/edit/cpeRJs?p=preview)
|
||||
|
||||
-->
|
||||
|
||||
```
|
||||
insert any relevant code here
|
||||
insert short code snippets here
|
||||
```
|
||||
|
||||
**Other information:**
|
||||
@@ -36,5 +47,3 @@ insert any relevant code here
|
||||
```
|
||||
insert the output from ionic info here
|
||||
```
|
||||
|
||||
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -7,6 +7,6 @@
|
||||
-
|
||||
-
|
||||
|
||||
**Ionic Version**: 1.x / 2.x / 3.x
|
||||
**Ionic Version**: 1.x / 2.x / 3.x / 4.x
|
||||
|
||||
**Fixes**: #
|
||||
|
||||
69
.github/ionic-issue-bot.yml
vendored
69
.github/ionic-issue-bot.yml
vendored
@@ -2,28 +2,69 @@ triage:
|
||||
label: triage
|
||||
dryRun: false
|
||||
|
||||
support:
|
||||
label: support
|
||||
closeAndLock:
|
||||
labels:
|
||||
- label: "ionitron: support"
|
||||
message: >
|
||||
Thanks for the issue! This issue appears to be a support request. We use this issue tracker exclusively for
|
||||
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) or our
|
||||
[slack channel](https://ionicworldwide.herokuapp.com/) for questions about the framework.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
- label: "ionitron: missing template"
|
||||
message: >
|
||||
Thanks for the issue! It appears that you have not filled out the provided issue template. We use this issue
|
||||
template in order to gather more information and further assist you. Please create a new issue and ensure the
|
||||
template is fully filled out.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
close: true
|
||||
lock: true
|
||||
dryRun: false
|
||||
|
||||
stale:
|
||||
days: 365
|
||||
maxIssuesPerRun: 100
|
||||
exemptLabels:
|
||||
- good first issue
|
||||
- triage
|
||||
exemptProjects: true
|
||||
exemptMilestones: true
|
||||
label: "ionitron: stale issue"
|
||||
message: >
|
||||
Thanks for the issue! This issue appears to be a support request. We use this issue tracker exclusively for
|
||||
bug reports and feature requests. Please use our [forum](https://forum.ionicframework.com) or our
|
||||
[slack channel](https://ionicworldwide.herokuapp.com/) for questions about the framework.
|
||||
|
||||
|
||||
Thanks for the issue! This issue is being closed due to inactivity. If this is still
|
||||
an issue with the latest version of Ionic, please create a new issue and ensure the
|
||||
template is fully filled out.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
close: true
|
||||
lock: true
|
||||
dryRun: false
|
||||
|
||||
incomplete:
|
||||
label: missing template
|
||||
message: >
|
||||
Thanks for the issue! It appears that you have not filled out the provided issue template. We use this issue
|
||||
template in order to gather more information and further assist you. Please create a new issue and ensure the
|
||||
template is fully filled out.
|
||||
wrongRepo:
|
||||
repos:
|
||||
- label: "ionitron: cli"
|
||||
repo: ionic-cli
|
||||
message: >
|
||||
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
|
||||
associated with the Ionic Framework. It appears that this issue is associated with the Ionic CLI.
|
||||
I am moving this issue to the Ionic CLI repository. Please track this issue over there.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
Thank you for using Ionic!
|
||||
- label: "ionitron: stencil"
|
||||
repo: stencil
|
||||
message: >
|
||||
Thanks for the issue! We use this issue tracker exclusively for bug reports and feature requests
|
||||
associated with the Ionic Framework. It appears that this issue is associated with Stencil.
|
||||
I am moving this issue to the Stencil repository. Please track this issue over there.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
close: true
|
||||
lock: true
|
||||
dryRun: false
|
||||
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -18,8 +18,8 @@ dist/
|
||||
node_modules/
|
||||
tmp/
|
||||
temp/
|
||||
packages/core/theme-builder/
|
||||
packages/core/test-components/
|
||||
core/theme-builder/
|
||||
core/test-components/
|
||||
$RECYCLE.BIN/
|
||||
|
||||
.DS_Store
|
||||
|
||||
26
.scripts/README.md
Normal file
26
.scripts/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Build Scripts
|
||||
|
||||
## Release
|
||||
|
||||
The deploy scripts at the root, make a new release of all the packages in this monorepo.
|
||||
All packages will be released with the same version.
|
||||
|
||||
In order to make a new release:
|
||||
|
||||
1. `npm run release.prepare`
|
||||
2. Review/update changelog
|
||||
3. Commit updates using the package name and version number as the commit message.
|
||||
4. `npm run release`
|
||||
5. :tada:
|
||||
|
||||
|
||||
## Prerelease
|
||||
|
||||
It's also possible to make prereleases of individual packages (@ionic/core, @ionic/angular).
|
||||
In order to do so, move to the package you want to make a new release and execute:
|
||||
```
|
||||
npm run prerelease
|
||||
```
|
||||
|
||||
It will publish a new prerelease in NPM, but it will not create any new git tag
|
||||
or update the CHANGELOG.
|
||||
73
.scripts/common.js
Normal file
73
.scripts/common.js
Normal file
@@ -0,0 +1,73 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const execa = require('execa');
|
||||
const Listr = require('listr');
|
||||
const semver = require('semver');
|
||||
|
||||
const rootDir = path.join(__dirname, '../');
|
||||
|
||||
const packages = [
|
||||
'core',
|
||||
'angular'
|
||||
];
|
||||
|
||||
function readPkg(project) {
|
||||
const packageJsonPath = packagePath(project);
|
||||
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
||||
}
|
||||
|
||||
function writePkg(project, pkg) {
|
||||
const packageJsonPath = packagePath(project);
|
||||
const text = JSON.stringify(pkg, null, 2);
|
||||
return fs.writeFileSync(packageJsonPath, text);
|
||||
}
|
||||
|
||||
function packagePath(project) {
|
||||
return path.join(rootDir, project, 'package.json');
|
||||
}
|
||||
|
||||
function projectPath(project) {
|
||||
return path.join(rootDir, project);
|
||||
}
|
||||
|
||||
function checkGit(tasks) {
|
||||
tasks.push(
|
||||
{
|
||||
title: 'Check current branch',
|
||||
task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
|
||||
if (branch !== 'master') {
|
||||
throw new Error(`Not on "master" branch`);
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Check local working tree',
|
||||
task: () => execa.stdout('git', ['status', '--porcelain']).then(status => {
|
||||
if (status !== '') {
|
||||
throw new Error(`Unclean working tree. Commit or stash changes first.`);
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
title: 'Check remote history',
|
||||
task: () => execa.stdout('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']).then(result => {
|
||||
if (result !== '0') {
|
||||
throw new Error(`Remote history differs. Please pull changes.`);
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const isValidVersion = input => Boolean(semver.valid(input));
|
||||
|
||||
|
||||
module.exports = {
|
||||
isValidVersion,
|
||||
readPkg,
|
||||
writePkg,
|
||||
rootDir,
|
||||
projectPath,
|
||||
checkGit,
|
||||
packages
|
||||
};
|
||||
306
.scripts/prepare.js
Normal file
306
.scripts/prepare.js
Normal file
@@ -0,0 +1,306 @@
|
||||
/**
|
||||
* Deploy script adopted from https://github.com/sindresorhus/np
|
||||
* MIT License (c) Sindre Sorhus (sindresorhus.com)
|
||||
*/
|
||||
const chalk = require('chalk');
|
||||
const execa = require('execa');
|
||||
const inquirer = require('inquirer');
|
||||
const Listr = require('listr');
|
||||
const fs = require('fs-extra');
|
||||
const semver = require('semver');
|
||||
const common = require('./common');
|
||||
const path = require('path');
|
||||
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const version = await askVersion();
|
||||
|
||||
// compile and verify packages
|
||||
await preparePackages(common.packages, version);
|
||||
|
||||
console.log(`\nionic ${version} prepared 🤖\n`);
|
||||
console.log(`Next steps:`);
|
||||
console.log(` Verify CHANGELOG.md`);
|
||||
console.log(` git commit -m "${version}"`);
|
||||
console.log(` npm run release\n`);
|
||||
|
||||
} catch(err) {
|
||||
console.log('\n', chalk.red(err), '\n');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function askVersion() {
|
||||
const pkg = common.readPkg('core');
|
||||
const oldVersion = pkg.version;
|
||||
|
||||
const prompts = [
|
||||
{
|
||||
type: 'list',
|
||||
name: 'version',
|
||||
message: 'Select semver increment or specify new version',
|
||||
pageSize: SEMVER_INCREMENTS.length + 2,
|
||||
choices: SEMVER_INCREMENTS
|
||||
.map(inc => ({
|
||||
name: `${inc} ${prettyVersionDiff(oldVersion, inc)}`,
|
||||
value: inc
|
||||
}))
|
||||
.concat([
|
||||
new inquirer.Separator(),
|
||||
{
|
||||
name: 'Other (specify)',
|
||||
value: null
|
||||
}
|
||||
]),
|
||||
filter: input => isValidVersionInput(input) ? getNewVersion(oldVersion, input) : input
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'version',
|
||||
message: 'Version',
|
||||
when: answers => !answers.version,
|
||||
filter: input => isValidVersionInput(input) ? getNewVersion(pkg.version, input) : input,
|
||||
validate: input => {
|
||||
if (!isValidVersionInput(input)) {
|
||||
return 'Please specify a valid semver, for example, `1.2.3`. See http://semver.org';
|
||||
} else if (!isVersionGreater(oldVersion, input)) {
|
||||
return `Version must be greater than ${oldVersion}`;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: answers => {
|
||||
return `Will bump from ${chalk.cyan(oldVersion)} to ${chalk.cyan(answers.version)}. Continue?`;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const {version} = await inquirer.prompt(prompts);
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
async function preparePackages(packages, version) {
|
||||
// execution order matters
|
||||
const tasks = [];
|
||||
|
||||
// check git is nice and clean local and remote
|
||||
common.checkGit(tasks);
|
||||
|
||||
// test we're good with git
|
||||
validateGit(tasks, version);
|
||||
|
||||
// add all the prepare scripts
|
||||
// run all these tasks before updating package.json version
|
||||
packages.forEach(package => {
|
||||
preparePackage(tasks, package, version);
|
||||
});
|
||||
|
||||
// add update package.json of each project
|
||||
packages.forEach(package => {
|
||||
updatePackageVersion(tasks, package, version);
|
||||
});
|
||||
|
||||
// generate changelog
|
||||
generateChangeLog(tasks);
|
||||
|
||||
const listr = new Listr(tasks, { showSubtasks: true });
|
||||
await listr.run();
|
||||
}
|
||||
|
||||
|
||||
function validateGit(tasks, version) {
|
||||
tasks.push(
|
||||
{
|
||||
title: `Validate git tag ${chalk.dim(`(v${version})`)}`,
|
||||
task: () => execa('git', ['fetch'])
|
||||
.then(() => {
|
||||
return execa.stdout('npm', ['config', 'get', 'tag-version-prefix']);
|
||||
})
|
||||
.then(
|
||||
output => {
|
||||
tagPrefix = output;
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
.then(() => execa.stdout('git', ['rev-parse', '--quiet', '--verify', `refs/tags/${tagPrefix}${version}`]))
|
||||
.then(
|
||||
output => {
|
||||
if (output) {
|
||||
throw new Error(`Git tag \`${tagPrefix}${version}\` already exists.`);
|
||||
}
|
||||
},
|
||||
err => {
|
||||
// Command fails with code 1 and no output if the tag does not exist, even though `--quiet` is provided
|
||||
// https://github.com/sindresorhus/np/pull/73#discussion_r72385685
|
||||
if (err.stdout !== '' || err.stderr !== '') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function preparePackage(tasks, package, version) {
|
||||
const projectRoot = common.projectPath(package);
|
||||
const pkg = common.readPkg(package);
|
||||
|
||||
const projectTasks = [
|
||||
{
|
||||
title: `${pkg.name}: validate new version`,
|
||||
task: () => {
|
||||
if (!isVersionGreater(pkg.version, version)) {
|
||||
throw new Error(`New version \`${version}\` should be higher than current version \`${pkg.version}\``);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: `${pkg.name}: install npm dependencies`,
|
||||
task: async () => {
|
||||
await fs.remove(path.join(projectRoot, 'node_modules'))
|
||||
await execa('npm', ['ci'], { cwd: projectRoot });
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
if (package !== 'core') {
|
||||
projectTasks.push(
|
||||
{
|
||||
title: `${pkg.name}: npm link @ionic/core`,
|
||||
task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot })
|
||||
},
|
||||
{
|
||||
title: `${pkg.name}: update ionic/core dep to ${version}`,
|
||||
task: () => {
|
||||
updateDependency(pkg, "@ionic/core", version);
|
||||
common.writePkg(package, pkg);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
projectTasks.push(
|
||||
{
|
||||
title: `${pkg.name}: lint`,
|
||||
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
|
||||
},
|
||||
{
|
||||
title: `${pkg.name}: build`,
|
||||
task: () => execa('npm', ['run', 'build'], { cwd: projectRoot })
|
||||
},
|
||||
{
|
||||
title: `${pkg.name}: test`,
|
||||
task: () => execa('npm', ['test'], { cwd: projectRoot })
|
||||
}
|
||||
);
|
||||
|
||||
if (package === 'core') {
|
||||
projectTasks.push(
|
||||
{
|
||||
title: `${pkg.name}: npm link`,
|
||||
task: () => execa('npm', ['link'], { cwd: projectRoot })
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Add project tasks
|
||||
tasks.push({
|
||||
title: `Prepare ${chalk.bold(pkg.name)}`,
|
||||
task: () => new Listr(projectTasks)
|
||||
});
|
||||
}
|
||||
|
||||
function updateDependency(pkg, dependency, version) {
|
||||
if (pkg.dependencies && pkg.dependencies[dependency]) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
}
|
||||
if (pkg.devDependencies && pkg.devDependencies[dependency]) {
|
||||
pkg.devDependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updatePackageVersion(tasks, package, version) {
|
||||
const projectRoot = common.projectPath(package);
|
||||
const pkg = common.readPkg(package);
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `${pkg.name}: update package.json ${chalk.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
await execa('npm', ['version', version], { cwd: projectRoot });
|
||||
|
||||
const pkgLock = path.join(projectRoot, 'package-lock.json');
|
||||
const pkgLockData = JSON.parse(fs.readFileSync(pkgLock, 'utf-8'));
|
||||
pkgLockData.version = version;
|
||||
|
||||
fs.writeFileSync(pkgLock, JSON.stringify(pkgLockData));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
async function generateChangeLog(tasks) {
|
||||
tasks.push(
|
||||
{
|
||||
title: `Generate CHANGELOG.md`,
|
||||
task: () => execa('npm', ['run', 'changelog'], { cwd: common.rootDir }),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const SEMVER_INCREMENTS = ['patch', 'minor', 'major'];
|
||||
|
||||
const isValidVersion = input => Boolean(semver.valid(input));
|
||||
|
||||
const isValidVersionInput = input => SEMVER_INCREMENTS.indexOf(input) !== -1 || common.isValidVersion(input);
|
||||
|
||||
function getNewVersion(oldVersion, input) {
|
||||
if (!isValidVersionInput(input)) {
|
||||
throw new Error(`Version should be either ${SEMVER_INCREMENTS.join(', ')} or a valid semver version.`);
|
||||
}
|
||||
|
||||
return SEMVER_INCREMENTS.indexOf(input) === -1 ? input : semver.inc(oldVersion, input);
|
||||
};
|
||||
|
||||
const isVersionGreater = (oldVersion, newVersion) => {
|
||||
if (!common.isValidVersion(newVersion)) {
|
||||
throw new Error('Version should be a valid semver version.');
|
||||
}
|
||||
|
||||
return semver.gt(newVersion, oldVersion);
|
||||
};
|
||||
|
||||
|
||||
function prettyVersionDiff(oldVersion, inc) {
|
||||
const newVersion = getNewVersion(oldVersion, inc).split('.');
|
||||
oldVersion = oldVersion.split('.');
|
||||
let firstVersionChange = false;
|
||||
const output = [];
|
||||
|
||||
for (let i = 0; i < newVersion.length; i++) {
|
||||
if ((newVersion[i] !== oldVersion[i] && !firstVersionChange)) {
|
||||
output.push(`${chalk.dim.cyan(newVersion[i])}`);
|
||||
firstVersionChange = true;
|
||||
} else if (newVersion[i].indexOf('-') >= 1) {
|
||||
let preVersion = [];
|
||||
preVersion = newVersion[i].split('-');
|
||||
output.push(`${chalk.dim.cyan(`${preVersion[0]}-${preVersion[1]}`)}`);
|
||||
} else {
|
||||
output.push(chalk.reset.dim(newVersion[i]));
|
||||
}
|
||||
}
|
||||
return output.join(chalk.reset.dim('.'));
|
||||
}
|
||||
|
||||
main();
|
||||
92
.scripts/release.js
Normal file
92
.scripts/release.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Deploy script adopted from https://github.com/sindresorhus/np
|
||||
* MIT License (c) Sindre Sorhus (sindresorhus.com)
|
||||
*/
|
||||
const chalk = require('chalk');
|
||||
const execa = require('execa');
|
||||
const Listr = require('listr');
|
||||
const common = require('./common');
|
||||
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const {version} = common.readPkg('core');
|
||||
|
||||
// publish each package in NPM
|
||||
await publishPackages(common.packages, version);
|
||||
|
||||
console.log(`\nionic ${version} published!! 🎉\n`);
|
||||
|
||||
} catch (err) {
|
||||
console.log('\n', chalk.red(err), '\n');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function publishPackages(packages, version) {
|
||||
const tasks = [];
|
||||
|
||||
// repo must be clean
|
||||
common.checkGit(tasks);
|
||||
|
||||
// first verify version
|
||||
packages.forEach(package => {
|
||||
if (package === 'core') return;
|
||||
|
||||
const pkg = common.readPkg(package);
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `${pkg.name}: check version (must match: ${version})`,
|
||||
task: () => {
|
||||
if (version !== pkg.version) {
|
||||
throw new Error(`${pkg.name} version ${pkg.version} must match ${version}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// next publish
|
||||
packages.forEach(package => {
|
||||
const pkg = common.readPkg(package);
|
||||
const projectRoot = common.projectPath(package);
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `${pkg.name}: publish ${pkg.version}`,
|
||||
task: () =>execa('npm', ['publish', '--tag', 'latest'], { cwd: projectRoot })
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// push tag to git remote
|
||||
publishGitTag(tasks, version);
|
||||
|
||||
const listr = new Listr(tasks);
|
||||
await listr.run();
|
||||
}
|
||||
|
||||
|
||||
function publishGitTag(tasks, version) {
|
||||
const tag = `v${version}`;
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `Tag latest commit ${chalk.dim(`(${tag})`)}`,
|
||||
task: () => execa('git', ['tag', `${tag}`], { cwd: common.rootDir })
|
||||
},
|
||||
{
|
||||
title: 'Push branches to Github',
|
||||
task: () => execa('git', ['push'], { cwd: common.rootDir })
|
||||
},
|
||||
{
|
||||
title: 'Push tags to Github',
|
||||
task: () => execa('git', ['push', '--tags'], { cwd: common.rootDir })
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
main();
|
||||
907
BREAKING.md
907
BREAKING.md
@@ -1,908 +1,3 @@
|
||||
|
||||
# Breaking Changes
|
||||
|
||||
A list of the breaking changes introduced in Ionic Angular v4.
|
||||
|
||||
- [Dynamic Mode](#dynamic-mode)
|
||||
- [Button](#button)
|
||||
- [Chip](#chip)
|
||||
- [Colors](#colors)
|
||||
- [Datetime](#datetime)
|
||||
- [FAB](#fab)
|
||||
- [Fixed Content](#fixed-content)
|
||||
- [Icon](#icon)
|
||||
- [Input](#Input)
|
||||
- [Item](#item)
|
||||
- [Item Divider](#item-divider)
|
||||
- [Item Sliding](#item-sliding)
|
||||
- [List Header](#list-header)
|
||||
- [Menu Toggle](#menu-toggle)
|
||||
- [Nav](#nav)
|
||||
- [Option](#option)
|
||||
- [Radio](#radio)
|
||||
- [Range](#range)
|
||||
- [Segment](#segment)
|
||||
- [Select](#select)
|
||||
- [Text/Typography](#text-typography)
|
||||
- [Theming](#theming)
|
||||
- [Toolbar](#toolbar)
|
||||
|
||||
|
||||
## Dynamic Mode
|
||||
|
||||
Components are no longer able to have their mode changed dynamically. You can change the mode before the first render, but after that it will not style properly because only the initial mode's styles are included.
|
||||
|
||||
## Button
|
||||
|
||||
### Markup Changed
|
||||
|
||||
Button should now be written as an `<ion-button>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<button ion-button (click)="doSomething()">
|
||||
Default Button
|
||||
</button>
|
||||
|
||||
<a ion-button href="#">
|
||||
Default Anchor
|
||||
</a>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-button (click)="doSomething()">
|
||||
Default Button
|
||||
</ion-button>
|
||||
|
||||
<ion-button href="#">
|
||||
Default Anchor
|
||||
</ion-button>
|
||||
```
|
||||
|
||||
### Attributes Renamed
|
||||
|
||||
Previously to style icons inside of a button the following attributes were used: `icon-left`, `icon-right`, (and with the added support of RTL) `icon-start`, `icon-end`.
|
||||
|
||||
These have been renamed to the following, and moved from the button element to the icon itself:
|
||||
|
||||
| Old Property | New Property | Property Behavior |
|
||||
|---------------------------|----------------|-----------------------------------------------------------------------|
|
||||
| `icon-left`, `icon-start` | `slot="start"` | Positions to the left of the button in LTR, and to the right in RTL. |
|
||||
| `icon-right`, `icon-end` | `slot="end"` | Positions to the right of the button in LTR, and to the left in RTL. |
|
||||
|
||||
In addition, several sets of mutually exclusive boolean attributes have been combined into a single string attribute.
|
||||
|
||||
The `small` and `large` attributes are now combined under the `size` attribute. The `clear`, `outline`, and `solid` attributes have been combined under `fill`. And, lastly, the `full` and `block` attributes have been combined under `expand`.
|
||||
|
||||
| Old Property | New Property | Property Behavior |
|
||||
| --------------------------- | ------------ | --------------------------- |
|
||||
| `small`, `large` | `size` | Sets the button size. |
|
||||
| `clear`, `outline`, `solid` | `fill` | Sets the button fill style. |
|
||||
| `full`, `block` | `expand` | Sets the button width. |
|
||||
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-button icon-left>
|
||||
<ion-icon name="home"></ion-icon>
|
||||
Icon Left
|
||||
</ion-button>
|
||||
|
||||
<ion-button icon-start>
|
||||
<ion-icon name="home"></ion-icon>
|
||||
Icon Left on LTR, Right on RTL
|
||||
</ion-button>
|
||||
|
||||
<ion-button icon-right>
|
||||
Icon Right
|
||||
<ion-icon name="home"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button icon-end>
|
||||
Icon Right on LTR, Left on RTL
|
||||
<ion-icon name="home"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button large>
|
||||
Large Button
|
||||
</ion-button>
|
||||
|
||||
<ion-button outline>
|
||||
Outline Button
|
||||
</ion-button>
|
||||
|
||||
<ion-button full>
|
||||
Full-width Button
|
||||
</ion-button>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-button>
|
||||
<ion-icon slot="start" name="home"></ion-icon>
|
||||
Icon Left on LTR, Right on RTL
|
||||
</ion-button>
|
||||
|
||||
<ion-button>
|
||||
Icon Right on LTR, Left on RTL
|
||||
<ion-icon slot="end" name="home"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<ion-button size="large">
|
||||
Large Button
|
||||
</ion-button>
|
||||
|
||||
<ion-button fill="outline">
|
||||
Outline Button
|
||||
</ion-button>
|
||||
|
||||
<ion-button expand="full">
|
||||
Full-width Button
|
||||
</ion-button>
|
||||
```
|
||||
|
||||
## Chip
|
||||
|
||||
### Markup Changed
|
||||
|
||||
Buttons inside of an `<ion-chip>` container should now be written as an `<ion-chip-button>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-chip>
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-button clear color="light">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-chip>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-chip>
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-chip-button fill="clear" color="light">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
</ion-chip-button>
|
||||
</ion-chip>
|
||||
```
|
||||
|
||||
|
||||
## Colors
|
||||
|
||||
The default Ionic theme colors have changed. Previously we had:
|
||||
|
||||
```
|
||||
primary: #327eff
|
||||
secondary: #32db64
|
||||
danger: #f53d3d
|
||||
light: #f4f4f4
|
||||
dark: #222
|
||||
```
|
||||
|
||||
Some of their values have changed and we now include more colors by default:
|
||||
|
||||
```
|
||||
primary: #3880ff
|
||||
secondary: #0cd1e8
|
||||
tertiary: #7044ff
|
||||
success: #10dc60
|
||||
warning: #ffce00
|
||||
danger: #f04141
|
||||
light: #f4f5f8
|
||||
medium: #989aa2
|
||||
dark: #222428
|
||||
```
|
||||
|
||||
The `secondary` color saw the largest change. If you were previously using our `secondary` color we recommend switching to `success` instead.
|
||||
|
||||
|
||||
## Datetime
|
||||
|
||||
The Datetime classes and interfaces have changed capitalization from `DateTime` to `Datetime`. This is more consistent with other components and their tags.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```javascript
|
||||
import { DateTime } from 'ionic-angular';
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```javascript
|
||||
import { Datetime } from 'ionic-angular';
|
||||
```
|
||||
|
||||
## FAB
|
||||
|
||||
### Markup Changed
|
||||
|
||||
Buttons inside of an `<ion-fab>` container should now be written as an `<ion-fab-button>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-fab top right edge>
|
||||
<button ion-fab>
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</button>
|
||||
<ion-fab-list>
|
||||
<button ion-fab>
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</button>
|
||||
<button ion-fab>
|
||||
<ion-icon name="logo-twitter"></ion-icon>
|
||||
</button>
|
||||
<button ion-fab>
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</button>
|
||||
<button ion-fab>
|
||||
<ion-icon name="logo-googleplus"></ion-icon>
|
||||
</button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-fab top right edge>
|
||||
<ion-fab-button>
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-list>
|
||||
<ion-fab-button>
|
||||
<ion-icon name="logo-facebook"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button>
|
||||
<ion-icon name="logo-twitter"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button>
|
||||
<ion-icon name="logo-vimeo"></ion-icon>
|
||||
</ion-fab-button>
|
||||
<ion-fab-button>
|
||||
<ion-icon name="logo-googleplus"></ion-icon>
|
||||
</ion-fab-button>
|
||||
</ion-fab-list>
|
||||
</ion-fab>
|
||||
```
|
||||
|
||||
### Fixed Content
|
||||
|
||||
The `<ion-fab>` container was previously placed inside of the fixed content by default. Now, any fixed content should go inside of the `<ion-fixed>` container.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-content>
|
||||
<ion-fab top right edge>
|
||||
<!-- fab buttons and lists -->
|
||||
</ion-fab>
|
||||
Scrollable Content
|
||||
</ion-content>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-fixed>
|
||||
<ion-fab top right edge>
|
||||
<!-- fab buttons and lists -->
|
||||
</ion-fab>
|
||||
</ion-fixed>
|
||||
<ion-content>
|
||||
Scrollable Content
|
||||
</ion-content>
|
||||
```
|
||||
|
||||
## Icon
|
||||
|
||||
### Fonts Removed
|
||||
|
||||
Icons have been refactored to use SVGs instead of fonts. Ionic will only fetch the SVG for the icon when it is needed, instead of having a large font file that is always loaded in.
|
||||
|
||||
If any `CSS` is being overridden for an icon it will need to change to override the SVG itself. Below is a usage example of the differences in changing the icon color.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```css
|
||||
.icon {
|
||||
color: #000;
|
||||
}
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```css
|
||||
.icon {
|
||||
fill: #000;
|
||||
}
|
||||
```
|
||||
|
||||
### Property Removed
|
||||
|
||||
The `isActive` property has been removed. It only worked for `ios` icons previously. If you would like to switch between an outline and solid icon you should set it in the `name`, or `ios`/`md` attribute and then change it when needed.
|
||||
|
||||
## Input
|
||||
|
||||
The Sass variables were all renamed from having `$text-input` as the prefix to `$input`.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```css
|
||||
$text-input-highlight-color-valid: #32db64;
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```css
|
||||
$input-highlight-color-valid: #32db64;
|
||||
```
|
||||
|
||||
|
||||
## Item
|
||||
|
||||
### Markup Changed
|
||||
|
||||
Item should now be written as an `<ion-item>` element. Ionic will determine when to render an anchor tag based on the presence of an `href` attribute, and a button tag based on the presence of an `onclick` or `tappable` attribute. Otherwise, it will render a div.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
Default Item
|
||||
</ion-item>
|
||||
|
||||
<button ion-item (click)="doSomething()">
|
||||
Button Item
|
||||
</button>
|
||||
|
||||
<a ion-item href="#">
|
||||
Anchor Item
|
||||
</a>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
Default Item
|
||||
</ion-item>
|
||||
|
||||
<ion-item tappable (click)="doSomething()">
|
||||
Button Item
|
||||
</ion-item>
|
||||
|
||||
<ion-item href="#">
|
||||
Anchor Item
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
### Label Required
|
||||
|
||||
Previously an `ion-label` would automatically get added to an `ion-item` if one wasn't provided. Now an `ion-label` should always be added if the component is used to display text.
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
<ion-label>Item Label</ion-label>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
### Attributes Renamed
|
||||
|
||||
Previously to position elements inside of an `ion-item` the following attributes were used: `item-left`, `item-right`, (and with the added support of RTL) `item-start`, `item-end`.
|
||||
|
||||
These have been renamed to the following:
|
||||
|
||||
| Old Property | New Property | Property Behavior |
|
||||
|---------------------------|----------------|---------------------------------------------------------------------|
|
||||
| `item-left`, `item-start` | `slot="start"` | Positions to the left of the item in LTR, and to the right in RTL. |
|
||||
| `item-right`, `item-end` | `slot="end"` | Positions to the right of the item in LTR, and to the left in RTL. |
|
||||
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
<div item-left>Left</div>
|
||||
<ion-label>Item Label</ion-label>
|
||||
<div item-right>Right</div>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<div item-start>Left on LTR, Right on RTL</div>
|
||||
<ion-label>Item Label</ion-label>
|
||||
<div item-end>Right on LTR, Left on RTL</div>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
<div slot="start">Left on LTR, Right on RTL</div>
|
||||
<ion-label>Item Label</ion-label>
|
||||
<div slot="end">Right on LTR, Left on RTL</div>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
### Detail Push
|
||||
|
||||
The attributes to show/hide the detail arrows on items have been converted to a single property and value. Instead of writing `detail-push` or `detail-none` to show/hide the arrow, it should be written `detail`/`detail="true"` or `detail="false"`.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<button ion-item detail-none>
|
||||
<ion-label>Item Label</ion-label>
|
||||
</button>
|
||||
|
||||
<ion-item detail-push>
|
||||
<ion-label>Item Label</ion-label>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item tappable detail="false">
|
||||
<ion-label>Item Label</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item detail>
|
||||
<ion-label>Item Label</ion-label>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
By default, items that render buttons or anchor tags will show the arrow in `ios` mode.
|
||||
|
||||
## Item Divider
|
||||
|
||||
### Label Required
|
||||
|
||||
Previously an `ion-label` would automatically get added to an `ion-item-divider` if one wasn't provided. Now an `ion-label` should always be added if the component is used to display text.
|
||||
|
||||
```html
|
||||
<ion-item-divider>
|
||||
<ion-label>Item Divider Label</ion-label>
|
||||
</ion-item-divider>
|
||||
```
|
||||
|
||||
## List Header
|
||||
|
||||
### Label Required
|
||||
|
||||
Previously an `ion-label` would automatically get added to an `ion-list-header` if one wasn't provided. Now an `ion-label` should always be added if the component is used to display text.
|
||||
|
||||
```html
|
||||
<ion-list-header>
|
||||
<ion-label>List Header Label</ion-label>
|
||||
</ion-list-header>
|
||||
```
|
||||
|
||||
## Menu Toggle
|
||||
|
||||
### Markup Changed
|
||||
|
||||
The `menuToggle` attribute should not be added to an element anymore. Elements that should toggle a menu should be wrapped in an `ion-menu-toggle` element.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<button ion-button menuToggle>
|
||||
Toggle Menu
|
||||
</button>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-menu-toggle>
|
||||
<ion-button>
|
||||
Toggle Menu
|
||||
</ion-button>
|
||||
</ion-menu-toggle>
|
||||
```
|
||||
|
||||
## Item Sliding
|
||||
|
||||
### Markup Changed
|
||||
|
||||
The option component should not be written as a `button` with an `ion-button` directive anymore. It should be written as an `ion-item-option`. This will render a native button element inside of it.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item-sliding>
|
||||
<ion-item>
|
||||
Item 1
|
||||
</ion-item>
|
||||
<ion-item-options side="right">
|
||||
<button ion-button expandable>
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-item-sliding>
|
||||
<ion-item>
|
||||
<ion-label>Item 1</ion-label>
|
||||
</ion-item>
|
||||
<ion-item-options side="right">
|
||||
<ion-item-option expandable>
|
||||
<ion-icon name="star"></ion-icon>
|
||||
</ion-item-option>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
```
|
||||
|
||||
### Method Renamed
|
||||
|
||||
The `getSlidingPercent` method has been renamed to `getSlidingRatio` since the function is returning a ratio of the open amount of the item compared to the width of the options.
|
||||
|
||||
|
||||
## Toolbar
|
||||
|
||||
Previously if a `menuToggle` directive was added to an Ionic `button` in a toolbar, it would be positioned outside of the `ion-buttons` element. Since menu toggle is simply a wrapper to a button now, it should be placed inside of the `ion-buttons` element.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-toolbar>
|
||||
<button ion-button menuToggle>
|
||||
<ion-icon name="menu"></ion-icon>
|
||||
</button>
|
||||
<ion-title>Left side menu toggle</ion-title>
|
||||
</ion-toolbar>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-toggle>
|
||||
<ion-button>
|
||||
<ion-icon slot="icon-only" name="menu"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-menu-toggle>
|
||||
</ion-buttons>
|
||||
<ion-title>Left side menu toggle</ion-title>
|
||||
</ion-toolbar>
|
||||
```
|
||||
|
||||
## Nav
|
||||
|
||||
### Method renamed
|
||||
|
||||
The `remove` method has been renamed to `removeIndex` to avoid conflicts with HTML and be more descriptive as to what it does.
|
||||
|
||||
The `getActiveChildNavs` method has been renamed to `getChildNavs`.
|
||||
|
||||
## Option
|
||||
|
||||
### Markup Changed
|
||||
|
||||
Select's option element should now be written as `<ion-select-option>`. This makes it more obvious that the element should only be used with a Select.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-select>
|
||||
<ion-option>Option 1</ion-option>
|
||||
<ion-option>Option 2</ion-option>
|
||||
<ion-option>Option 3</ion-option>
|
||||
</ion-select>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-select>
|
||||
<ion-select-option>Option 1</ion-select-option>
|
||||
<ion-select-option>Option 2</ion-select-option>
|
||||
<ion-select-option>Option 3</ion-select-option>
|
||||
</ion-select>
|
||||
```
|
||||
|
||||
### Class Changed
|
||||
|
||||
The class has been renamed from `Option` to `SelectOption` to keep it consistent with the element tag name.
|
||||
|
||||
## Radio
|
||||
|
||||
### Slot Required
|
||||
|
||||
Previously radio was positioned inside of an item automatically or by using `item-left`/`item-right`. It is now required to have a `slot` to be positioned properly.
|
||||
|
||||
** Old Usage Example **
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
<ion-label>Apple</ion-label>
|
||||
<ion-radio value="apple"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Grape, checked, disabled</ion-label>
|
||||
<ion-radio item-left value="grape" checked disabled></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Cherry</ion-label>
|
||||
<ion-radio item-right color="danger" value="cherry"></ion-radio>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
** New Usage Example **
|
||||
|
||||
```html
|
||||
<ion-item>
|
||||
<ion-label>Apple</ion-label>
|
||||
<ion-radio slot="start" value="apple"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Grape, checked, disabled</ion-label>
|
||||
<ion-radio slot="start" value="grape" checked disabled></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Cherry</ion-label>
|
||||
<ion-radio slot="end" color="danger" value="cherry"></ion-radio>
|
||||
</ion-item>
|
||||
```
|
||||
|
||||
### Radio Group
|
||||
|
||||
Radio group has been changed to an element. It should now be wrapped around any `<ion-radio>` elements as `<ion-radio-group>`.
|
||||
|
||||
** Old Usage Example **
|
||||
|
||||
```html
|
||||
<ion-list radio-group>
|
||||
<ion-item>
|
||||
<ion-label>Apple</ion-label>
|
||||
<ion-radio value="apple"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Grape, checked, disabled</ion-label>
|
||||
<ion-radio value="grape" checked disabled></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Cherry</ion-label>
|
||||
<ion-radio color="danger" value="cherry"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
```
|
||||
|
||||
** New Usage Example **
|
||||
|
||||
```html
|
||||
<ion-list>
|
||||
<ion-radio-group>
|
||||
<ion-item>
|
||||
<ion-label>Apple</ion-label>
|
||||
<ion-radio slot="start" value="apple"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Grape, checked, disabled</ion-label>
|
||||
<ion-radio slot="start" value="grape" checked disabled></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Cherry</ion-label>
|
||||
<ion-radio slot="start" color="danger" value="cherry"></ion-radio>
|
||||
</ion-item>
|
||||
</ion-radio-group>
|
||||
</ion-list>
|
||||
```
|
||||
|
||||
|
||||
## Range
|
||||
|
||||
### Attributes Renamed
|
||||
|
||||
Previously to place content inside of a range the following attributes were used: `range-left`, `range-right`, (and with the added support of RTL) `range-start`, `range-end`.
|
||||
|
||||
These have been renamed to the following:
|
||||
|
||||
| Old Property | New Property | Property Behavior |
|
||||
|-----------------------------|----------------|-----------------------------------------------------------------------|
|
||||
| `range-left`, `range-start` | `slot="start"` | Positions to the left of the range in LTR, and to the right in RTL. |
|
||||
| `range-right`, `range-end` | `slot="end"` | Positions to the right of the range in LTR, and to the left in RTL. |
|
||||
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-range>
|
||||
<ion-icon name="sunny" range-left></ion-icon>
|
||||
<ion-icon name="sunny" range-right></ion-icon>
|
||||
</ion-range>
|
||||
|
||||
<ion-range>
|
||||
<ion-icon name="sunny" range-start></ion-icon>
|
||||
<ion-icon name="sunny" range-end></ion-icon>
|
||||
</ion-range>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-range>
|
||||
<ion-icon name="sunny" slot="start"></ion-icon>
|
||||
<ion-icon name="sunny" slot="end"></ion-icon>
|
||||
</ion-range>
|
||||
```
|
||||
|
||||
|
||||
## Segment
|
||||
|
||||
The markup hasn't changed for Segments, but now writing `<ion-segment-button>` will render a native button element inside of it.
|
||||
|
||||
|
||||
## Select
|
||||
|
||||
The `selectOptions` property was renamed to `interfaceOptions` since it directly correlates with the `interface` property.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-select [selectOptions]="customOptions">
|
||||
...
|
||||
</ion-select>
|
||||
```
|
||||
|
||||
```ts
|
||||
this.customOptions = {
|
||||
title: 'Pizza Toppings',
|
||||
subTitle: 'Select your toppings'
|
||||
};
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-select [interfaceOptions]="customOptions">
|
||||
...
|
||||
</ion-select>
|
||||
```
|
||||
|
||||
```ts
|
||||
this.customOptions = {
|
||||
title: 'Pizza Toppings',
|
||||
subTitle: 'Select your toppings'
|
||||
};
|
||||
```
|
||||
|
||||
## Text / Typography
|
||||
|
||||
### Markup Changed
|
||||
|
||||
Typography should now be written as an `<ion-text>` element. Previously the `ion-text` attribute could be added to any HTML element to set its color. It should now be used as a wrapper around the HTML elements to style.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```html
|
||||
<h1 ion-text color="secondary">H1: The quick brown fox jumps over the lazy dog</h1>
|
||||
|
||||
<h2 ion-text color="primary">H2: The quick brown fox jumps over the lazy dog</h2>
|
||||
|
||||
<h3 ion-text color="light">H3: The quick brown fox jumps over the lazy dog</h3>
|
||||
|
||||
<p>
|
||||
I saw a werewolf with a Chinese menu in his hand.
|
||||
Walking through the <sub ion-text color="danger">streets</sub> of Soho in the rain.
|
||||
He <i ion-text color="primary">was</i> looking for a place called Lee Ho Fook's.
|
||||
Gonna get a <a ion-text color="secondary">big dish of beef chow mein.</a>
|
||||
</p>
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```html
|
||||
<ion-text color="secondary">
|
||||
<h1>H1: The quick brown fox jumps over the lazy dog</h1>
|
||||
</ion-text>
|
||||
|
||||
<ion-text color="primary">
|
||||
<h2>H2: The quick brown fox jumps over the lazy dog</h2>
|
||||
</ion-text>
|
||||
|
||||
<ion-text color="light">
|
||||
<h3>H3: The quick brown fox jumps over the lazy dog</h3>
|
||||
</ion-text>
|
||||
|
||||
<p>
|
||||
I saw a werewolf with a Chinese menu in his hand.
|
||||
Walking through the <ion-text color="danger"><sub>streets</sub></ion-text> of Soho in the rain.
|
||||
He <ion-text color="primary"><i>was</i></ion-text> looking for a place called Lee Ho Fook's.
|
||||
Gonna get a <ion-text color="secondary"><a>big dish of beef chow mein.</a></ion-text>
|
||||
</p>
|
||||
```
|
||||
|
||||
|
||||
## Theming
|
||||
|
||||
### Including Sass
|
||||
|
||||
Previously all `scss` files in the `src` directory were imported. Now each `scss` file should be included for the component via Angular's `styleUrls` metadata. View [Angular's Component Styles](https://angular.io/guide/component-styles) for more information.
|
||||
|
||||
This means that any styles wrapped with a page should now be removed since they will automatically be scoped to the component.
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```scss
|
||||
page-schedule {
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```scss
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Sass Variables
|
||||
|
||||
Sass variables for changing the cordova statusbar have been renamed to app:
|
||||
|
||||
**Old Usage Example:**
|
||||
|
||||
```css
|
||||
$cordova-ios-statusbar-padding: 20px;
|
||||
$cordova-md-statusbar-padding: 20px;
|
||||
```
|
||||
|
||||
**New Usage Example:**
|
||||
|
||||
```css
|
||||
$app-ios-statusbar-padding: 20px;
|
||||
$app-md-statusbar-padding: 20px;
|
||||
```
|
||||
|
||||
|
||||
## Toolbar
|
||||
|
||||
### Attributes Renamed
|
||||
|
||||
The attributes to position an `ion-buttons` element inside of a toolbar have been renamed, as well as the behavior attached to the name. We noticed there was some confusion behind the behavior of the `start` and `end` attributes, and with the new support for RTL we wanted to make the behavior of these match RTL. In order to do this we had to rename the old `start`/`end` to something that makes more sense with their behavior.
|
||||
|
||||
The names and behavior of each of the properties was previously:
|
||||
|
||||
| Old Property | Property Behavior |
|
||||
|--------------|--------------------------------------------------------------------------------------------------------------|
|
||||
| `start` | Positions element to the left of the content in `ios` mode, and directly to the right in `md` and `wp` mode. |
|
||||
| `end` | Positions element to the right of the content in `ios` mode, and to the far right in `md` and `wp` mode. |
|
||||
| `left` | Positions element to the left of all other elements. |
|
||||
| `right` | Positions element to the right of all other elements. |
|
||||
|
||||
The properties have been renamed to the following:
|
||||
|
||||
| Old Property | New Property | Property Behavior |
|
||||
|--------------|---------------------|------------------------------------------------------------------------------------------------------------------|
|
||||
| `start` | `slot="mode-start"` | Positions element to the `left` of the content in `ios` mode, and directly to the `right` in `md` and `wp` mode. |
|
||||
| `end` | `slot="mode-end"` | Positions element to the `right` of the content in `ios` mode, and to the far right in `md` and `wp` mode. |
|
||||
| `left` | `slot="start"` | Positions element to the `left` of all other elements in `LTR`, and to the `right` in `RTL`. |
|
||||
| `right` | `slot="end"` | Positions element to the `right` of all other elements in `LTR`, and to the `left` in `RTL`. |
|
||||
The list of the breaking changes introduced in Ionic Angular v4 has been moved to [angular/BREAKING.md](https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md).
|
||||
385
CHANGELOG.md
Normal file
385
CHANGELOG.md
Normal file
@@ -0,0 +1,385 @@
|
||||
<a name="4.0.0-alpha.1"></a>
|
||||
# [4.0.0-alpha.1](https://github.com/ionic-team/ionic/compare/v0.2.2...v4.0.0-alpha.1) (2018-04-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** change detection ([79ba639](https://github.com/ionic-team/ionic/commit/79ba639))
|
||||
* **angular:** proxy methods ([5153da4](https://github.com/ionic-team/ionic/commit/5153da4))
|
||||
* **angular:** proxy outputs ([64a9497](https://github.com/ionic-team/ionic/commit/64a9497))
|
||||
* **menu:** prerender ([a3cd5db](https://github.com/ionic-team/ionic/commit/a3cd5db))
|
||||
* **split-pane:** prerender ([c6e962c](https://github.com/ionic-team/ionic/commit/c6e962c))
|
||||
|
||||
|
||||
|
||||
<a name="0.2.2"></a>
|
||||
## [0.2.2](https://github.com/ionic-team/ionic/compare/v0.2.1...v0.2.2) (2018-04-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **back-button:** fix menu and back button alignment ([#14268](https://github.com/ionic-team/ionic/issues/14268)) ([57fbf6c](https://github.com/ionic-team/ionic/commit/57fbf6c))
|
||||
* **ripple-effect:** animation ([25c852c](https://github.com/ionic-team/ionic/commit/25c852c))
|
||||
* **sass:** add missing alert css properties ([#14269](https://github.com/ionic-team/ionic/issues/14269)) ([3471dd6](https://github.com/ionic-team/ionic/commit/3471dd6)), closes [#14258](https://github.com/ionic-team/ionic/issues/14258)
|
||||
* **script:** release script pushes tags ([d23108a](https://github.com/ionic-team/ionic/commit/d23108a))
|
||||
* **scripts:** improve script ([2215c6a](https://github.com/ionic-team/ionic/commit/2215c6a))
|
||||
* **select:** pass header and subHeader to interfaces ([2195895](https://github.com/ionic-team/ionic/commit/2195895))
|
||||
* **select:** wrap the text for the message in a popover ([0a0959b](https://github.com/ionic-team/ionic/commit/0a0959b))
|
||||
|
||||
|
||||
|
||||
<a name="0.2.1"></a>
|
||||
## [0.2.1](https://github.com/ionic-team/ionic/compare/v0.2.0...v0.2.1) (2018-04-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** back button prevents default ([4db687e](https://github.com/ionic-team/ionic/commit/4db687e))
|
||||
* **angular:** back-button ([1f78390](https://github.com/ionic-team/ionic/commit/1f78390))
|
||||
* **angular:** back-button does not push view ([bb46b5f](https://github.com/ionic-team/ionic/commit/bb46b5f))
|
||||
* **angular:** tabs flickering ([7e97006](https://github.com/ionic-team/ionic/commit/7e97006))
|
||||
* **app:** hide elements ([11cb42f](https://github.com/ionic-team/ionic/commit/11cb42f))
|
||||
* **scripts:** update dep version ([974b949](https://github.com/ionic-team/ionic/commit/974b949))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **angular:** href integration ([09e6b7e](https://github.com/ionic-team/ionic/commit/09e6b7e))
|
||||
|
||||
|
||||
|
||||
<a name="0.2.0"></a>
|
||||
# [0.2.0](https://github.com/ionic-team/ionic/compare/v0.1.6...v0.2.0) (2018-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** URL based tabs ([14fedb9](https://github.com/ionic-team/ionic/commit/14fedb9))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.6"></a>
|
||||
## [0.1.6](https://github.com/ionic-team/ionic/compare/v0.1.5...v0.1.6) (2018-04-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** lifecycles ([062641d](https://github.com/ionic-team/ionic/commit/062641d))
|
||||
* **angular:** modal and popover ([acd411d](https://github.com/ionic-team/ionic/commit/acd411d))
|
||||
* **angular:** module exports ([cece447](https://github.com/ionic-team/ionic/commit/cece447))
|
||||
* **angular:** proxies ([2308239](https://github.com/ionic-team/ionic/commit/2308239))
|
||||
* **angular:** tabs angular tests ([ff1ed88](https://github.com/ionic-team/ionic/commit/ff1ed88))
|
||||
* **router-outlet:** enteringEl !== leavingEl ([0d44253](https://github.com/ionic-team/ionic/commit/0d44253))
|
||||
* **router-outlet:** mutable prop ([ff06dab](https://github.com/ionic-team/ionic/commit/ff06dab))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.5"></a>
|
||||
## [0.1.5](https://github.com/ionic-team/ionic/compare/v0.1.4...v0.1.5) (2018-03-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **all:** absolute positioning ([4fcddad](https://github.com/ionic-team/ionic/commit/4fcddad))
|
||||
* **angular:** goback navigation ([7b9a00e](https://github.com/ionic-team/ionic/commit/7b9a00e))
|
||||
* **angular:** ion-back-button ([9c789ce](https://github.com/ionic-team/ionic/commit/9c789ce))
|
||||
* **angular:** stack based navigation ([726938f](https://github.com/ionic-team/ionic/commit/726938f))
|
||||
* **avatar:** adjust wide images to fill instead of squish ([b0f8ca5](https://github.com/ionic-team/ionic/commit/b0f8ca5))
|
||||
* **back-button:** empty text is a valid value ([eb0ff2f](https://github.com/ionic-team/ionic/commit/eb0ff2f))
|
||||
* **back-button:** ios style ([2b8e489](https://github.com/ionic-team/ionic/commit/2b8e489))
|
||||
* **button:** dynamic bar-button ([d0c5f53](https://github.com/ionic-team/ionic/commit/d0c5f53))
|
||||
* **checkbox:** update ios checkbox to be closer to native ([b29fce1](https://github.com/ionic-team/ionic/commit/b29fce1))
|
||||
* **components:** add font-smoothing to mixing components ([9caeec7](https://github.com/ionic-team/ionic/commit/9caeec7))
|
||||
* **covers:** absolute positioning ([ce09978](https://github.com/ionic-team/ionic/commit/ce09978))
|
||||
* **item-option:** remove outline on active/focus ([eae6869](https://github.com/ionic-team/ionic/commit/eae6869)), closes [#14191](https://github.com/ionic-team/ionic/issues/14191)
|
||||
* **label:** add missing text-wrap styles for ios ([a9bd76a](https://github.com/ionic-team/ionic/commit/a9bd76a)), closes [#13157](https://github.com/ionic-team/ionic/issues/13157)
|
||||
* **menu:** default menu mode ([c31bcde](https://github.com/ionic-team/ionic/commit/c31bcde))
|
||||
* **nav:** animated opts ([57a5d49](https://github.com/ionic-team/ionic/commit/57a5d49))
|
||||
* **nav:** no animation ([4fdfddb](https://github.com/ionic-team/ionic/commit/4fdfddb))
|
||||
* **nav:** transition name ([011a374](https://github.com/ionic-team/ionic/commit/011a374))
|
||||
* **picker:** do not scroll ([1c06bfe](https://github.com/ionic-team/ionic/commit/1c06bfe))
|
||||
* **ripple-effect:** tapclick is required in ionic ([d57122c](https://github.com/ionic-team/ionic/commit/d57122c))
|
||||
* **router:** change detection for componentProps ([a718f7e](https://github.com/ionic-team/ionic/commit/a718f7e))
|
||||
* **router:** explicit goback should not push ([7a26162](https://github.com/ionic-team/ionic/commit/7a26162))
|
||||
* **router:** fixes navChanged() ([dddaee1](https://github.com/ionic-team/ionic/commit/dddaee1))
|
||||
* **router:** ion-nav ([113af9e](https://github.com/ionic-team/ionic/commit/113af9e))
|
||||
* **router:** loging ([ffaec16](https://github.com/ionic-team/ionic/commit/ffaec16))
|
||||
* **router:** route change detection ([9e9f2a2](https://github.com/ionic-team/ionic/commit/9e9f2a2))
|
||||
* **router:** wait RAF ([b26a563](https://github.com/ionic-team/ionic/commit/b26a563))
|
||||
* **slides:** unload slides correctly ([59c6891](https://github.com/ionic-team/ionic/commit/59c6891))
|
||||
* **thumbnail:** adjust wide images to fill instead of squish ([54558c9](https://github.com/ionic-team/ionic/commit/54558c9))
|
||||
* **toast:** dismiss timeout ([44f343d](https://github.com/ionic-team/ionic/commit/44f343d))
|
||||
* **toolbar:** unused private ([c9d2a0d](https://github.com/ionic-team/ionic/commit/c9d2a0d))
|
||||
* **transition:** nav ios transition ([095f9c8](https://github.com/ionic-team/ionic/commit/095f9c8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **button:** goback attribute ([00fc460](https://github.com/ionic-team/ionic/commit/00fc460))
|
||||
* **config:** add set to config ([69a6f8d](https://github.com/ionic-team/ionic/commit/69a6f8d))
|
||||
* **content:** scrollEnabled ([5c2678f](https://github.com/ionic-team/ionic/commit/5c2678f))
|
||||
* **menu-controller:** expose registerAnimation ([153f8ca](https://github.com/ionic-team/ionic/commit/153f8ca))
|
||||
* **nav:** goBack directive ([862e571](https://github.com/ionic-team/ionic/commit/862e571))
|
||||
* **nav-controller:** goback best guess ([46bbd0f](https://github.com/ionic-team/ionic/commit/46bbd0f))
|
||||
* **ripple:** css variable color ([77fc792](https://github.com/ionic-team/ionic/commit/77fc792))
|
||||
* **tab:** framework support ([48d1bd4](https://github.com/ionic-team/ionic/commit/48d1bd4))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **app:** platform is not needed ([e681836](https://github.com/ionic-team/ionic/commit/e681836))
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* **toolbar:** revert to use old button attributes ([574c346](https://github.com/ionic-team/ionic/commit/574c346)), closes [#14172](https://github.com/ionic-team/ionic/issues/14172)
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4"></a>
|
||||
## [0.1.4](https://github.com/ionic-team/ionic/compare/v0.1.4-9...v0.1.4) (2018-03-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **action-sheet:** update padding on title to match native ([f0a40fa](https://github.com/ionic-team/ionic/commit/f0a40fa))
|
||||
* **alert:** update colors for alert text and input borders ([605ec93](https://github.com/ionic-team/ionic/commit/605ec93)), closes [#14196](https://github.com/ionic-team/ionic/issues/14196)
|
||||
* **alert:** update md alert to closer match spec ([7d53e49](https://github.com/ionic-team/ionic/commit/7d53e49))
|
||||
* **all:** ts strict (part 4) ([4693229](https://github.com/ionic-team/ionic/commit/4693229))
|
||||
* **angular:** router-outlet animation ([943e2f7](https://github.com/ionic-team/ionic/commit/943e2f7))
|
||||
* **chip:** use lighter background color ([08553f1](https://github.com/ionic-team/ionic/commit/08553f1)), closes [#14196](https://github.com/ionic-team/ionic/issues/14196)
|
||||
* **picker:** does not scroll ([b49a45d](https://github.com/ionic-team/ionic/commit/b49a45d))
|
||||
* **router:** reusing checks params ([371fc19](https://github.com/ionic-team/ionic/commit/371fc19))
|
||||
* **router-outlet:** css and change logic ([6e683c5](https://github.com/ionic-team/ionic/commit/6e683c5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **fab:** add box shadow and transition for ios ([d26074a](https://github.com/ionic-team/ionic/commit/d26074a))
|
||||
* **ion-router-outlet:** adds router-outlet ([c03afab](https://github.com/ionic-team/ionic/commit/c03afab))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-9"></a>
|
||||
## [0.1.4-9](https://github.com/ionic-team/ionic/compare/v0.1.4-8...v0.1.4-9) (2018-03-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **all:** ts strict (part 3) ([06ad60e](https://github.com/ionic-team/ionic/commit/06ad60e))
|
||||
* **angular:** ion-nav no routing ([9094c66](https://github.com/ionic-team/ionic/commit/9094c66))
|
||||
* **angular:** removeViewFromDom ([41f54f8](https://github.com/ionic-team/ionic/commit/41f54f8))
|
||||
* **back-button:** use correct color for ios back button ([b82c382](https://github.com/ionic-team/ionic/commit/b82c382)), closes [#14177](https://github.com/ionic-team/ionic/issues/14177)
|
||||
* **overlays:** page is removed properly ([9988c75](https://github.com/ionic-team/ionic/commit/9988c75))
|
||||
* **theming:** update spinner classes to new names ([f578122](https://github.com/ionic-team/ionic/commit/f578122))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **angular:** ion-nav ([f39d3ad](https://github.com/ionic-team/ionic/commit/f39d3ad))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-8"></a>
|
||||
## [0.1.4-8](https://github.com/ionic-team/ionic/compare/v0.1.4-7...v0.1.4-8) (2018-03-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **back-button:** apply the proper color to the back button ([7d2de18](https://github.com/ionic-team/ionic/commit/7d2de18)), closes [#14177](https://github.com/ionic-team/ionic/issues/14177)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **nav:** support for rootParams ([50abcf5](https://github.com/ionic-team/ionic/commit/50abcf5))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-7"></a>
|
||||
## [0.1.4-7](https://github.com/ionic-team/ionic/compare/v0.1.4-6...v0.1.4-7) (2018-03-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** wildcard redirects ([2bdf4ad](https://github.com/ionic-team/ionic/commit/2bdf4ad))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-6"></a>
|
||||
## [0.1.4-6](https://github.com/ionic-team/ionic/compare/v0.1.4-5...v0.1.4-6) (2018-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **alert:** backdrop calls cancel handler ([de22eca](https://github.com/ionic-team/ionic/commit/de22eca))
|
||||
* **alert:** set input value ([6e2a9c9](https://github.com/ionic-team/ionic/commit/6e2a9c9))
|
||||
* **angular:** create angular delegate ([3b5f758](https://github.com/ionic-team/ionic/commit/3b5f758))
|
||||
* **angular:** fix overlays ([cc4fecc](https://github.com/ionic-team/ionic/commit/cc4fecc))
|
||||
* **angular:** modal and popover support ([9a0755a](https://github.com/ionic-team/ionic/commit/9a0755a))
|
||||
* **demos:** fixes angular ([f398b3a](https://github.com/ionic-team/ionic/commit/f398b3a))
|
||||
* **overlay:** using hostData for zIndex ([64f0866](https://github.com/ionic-team/ionic/commit/64f0866))
|
||||
* **overlay:** wrong stencil import ([22f6a34](https://github.com/ionic-team/ionic/commit/22f6a34))
|
||||
* **overlays:** OverlayController interface ([6e2ca85](https://github.com/ionic-team/ionic/commit/6e2ca85))
|
||||
* **popover:** lifecycles ([b56c2a8](https://github.com/ionic-team/ionic/commit/b56c2a8))
|
||||
* **router:** ambiguous routes ([b4f46ee](https://github.com/ionic-team/ionic/commit/b4f46ee))
|
||||
* **router:** fix selection ([207f416](https://github.com/ionic-team/ionic/commit/207f416))
|
||||
* **router:** rename API to match stencil-router ([e729610](https://github.com/ionic-team/ionic/commit/e729610))
|
||||
* **router:** retuning string path ([f48d817](https://github.com/ionic-team/ionic/commit/f48d817))
|
||||
* **toggle:** ios shadow ([7df023a](https://github.com/ionic-team/ionic/commit/7df023a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **ion-router:** dynamic routes ([7c3cba0](https://github.com/ionic-team/ionic/commit/7c3cba0))
|
||||
* **overlay:** adds lifecycle events ([0b099ce](https://github.com/ionic-team/ionic/commit/0b099ce))
|
||||
* **overlays:** adds onDidDismiss and onWillDismiss ([7dcf8a5](https://github.com/ionic-team/ionic/commit/7dcf8a5))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **scss:** optimize multi dir ([#14156](https://github.com/ionic-team/ionic/issues/14156)) ([ba63d01](https://github.com/ionic-team/ionic/commit/ba63d01))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-5"></a>
|
||||
## [0.1.4-5](https://github.com/ionic-team/ionic/compare/v0.1.4-4...v0.1.4-5) (2018-03-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **item:** button outline ([f671008](https://github.com/ionic-team/ionic/commit/f671008))
|
||||
* **router:** fix flickering ([f2ac6e3](https://github.com/ionic-team/ionic/commit/f2ac6e3))
|
||||
* **router:** flickering 2 ([88f2981](https://github.com/ionic-team/ionic/commit/88f2981))
|
||||
* **router:** tslint ([1ace045](https://github.com/ionic-team/ionic/commit/1ace045))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** adds redirectTo ([f5c6333](https://github.com/ionic-team/ionic/commit/f5c6333))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-4"></a>
|
||||
## [0.1.4-4](https://github.com/ionic-team/ionic/compare/v0.1.4-3...v0.1.4-4) (2018-03-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **back-button:** implements back animation ([64a787a](https://github.com/ionic-team/ionic/commit/64a787a))
|
||||
* **route:** params is not undefined ([8b6df5a](https://github.com/ionic-team/ionic/commit/8b6df5a))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-3"></a>
|
||||
## [0.1.4-3](https://github.com/ionic-team/ionic/compare/v0.1.4-2...v0.1.4-3) (2018-03-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **router:** passing params to ion-nav ([d1263a8](https://github.com/ionic-team/ionic/commit/d1263a8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **back-button:** adds defaultHref ([5271f68](https://github.com/ionic-team/ionic/commit/5271f68))
|
||||
* **nav:** params ([878d7e6](https://github.com/ionic-team/ionic/commit/878d7e6))
|
||||
* **route:** adds route-link ([4a3030f](https://github.com/ionic-team/ionic/commit/4a3030f))
|
||||
* **router:** reverse lookup with params ([3ce8a67](https://github.com/ionic-team/ionic/commit/3ce8a67))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-2"></a>
|
||||
## [0.1.4-2](https://github.com/ionic-team/ionic/compare/v0.1.4-0...v0.1.4-2) (2018-03-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **fab:** add side as a property for fab list ([7387d34](https://github.com/ionic-team/ionic/commit/7387d34))
|
||||
* **ion-router:** fixes routing algorithm ([c8a27b7](https://github.com/ionic-team/ionic/commit/c8a27b7))
|
||||
* **item:** href ([540c33b](https://github.com/ionic-team/ionic/commit/540c33b))
|
||||
* **overlays:** bundling of overlays ([9650bec](https://github.com/ionic-team/ionic/commit/9650bec))
|
||||
* **router:** invalid url ([c7fe694](https://github.com/ionic-team/ionic/commit/c7fe694))
|
||||
* **routing:** flickering (part 1) ([7b264f9](https://github.com/ionic-team/ionic/commit/7b264f9))
|
||||
* **tabs:** do not select when using router ([174d9b5](https://github.com/ionic-team/ionic/commit/174d9b5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** adds parameters ([f29e3f4](https://github.com/ionic-team/ionic/commit/f29e3f4))
|
||||
* **virtual-scroll:** adds JSX support ([dc8b363](https://github.com/ionic-team/ionic/commit/dc8b363))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-1"></a>
|
||||
## [0.1.4-1](https://github.com/ionic-team/ionic/compare/v0.1.4-0...v0.1.4-1) (2018-03-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ion-router:** fixes routing algorithm ([c8a27b7](https://github.com/ionic-team/ionic/commit/c8a27b7))
|
||||
* **overlays:** bundling of overlays ([9650bec](https://github.com/ionic-team/ionic/commit/9650bec))
|
||||
* **routing:** flickering (part 1) ([7b264f9](https://github.com/ionic-team/ionic/commit/7b264f9))
|
||||
* **tabs:** do not select when using router ([174d9b5](https://github.com/ionic-team/ionic/commit/174d9b5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **virtual-scroll:** adds JSX support ([dc8b363](https://github.com/ionic-team/ionic/commit/dc8b363))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.4-0"></a>
|
||||
## [0.1.4-0](https://github.com/ionic-team/ionic/compare/v0.1.3...v0.1.4-0) (2018-03-06)
|
||||
|
||||
### Refactor
|
||||
|
||||
- Refactored navigation system
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **testing:** do not throw error for missing Ionic global ([aa91d11](https://github.com/ionic-team/ionic/commit/aa91d11))
|
||||
* **zone:** forgot to remove console.logs ([4ec3e48](https://github.com/ionic-team/ionic/commit/4ec3e48))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.3"></a>
|
||||
## [0.1.3](https://github.com/ionic-team/ionic/compare/v0.1.2...v0.1.3) (2018-03-03)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* Updates to latest stencil, that includes the zone bypassing abilities.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ts:** ts strict fixes ([8ff02c7](https://github.com/ionic-team/ionic/commit/8ff02c7))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.2"></a>
|
||||
## [0.1.2](https://github.com/ionic-team/ionic/compare/v0.1.1...v0.1.2) (2018-03-03)
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **events:** bypass ngzone ([7366c38](https://github.com/ionic-team/ionic/commit/7366c38))
|
||||
* **scroll:** watchdog + simplification ([33a6274](https://github.com/ionic-team/ionic/commit/33a6274))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **scroll:** clearInterval just to be safe ([6da9882](https://github.com/ionic-team/ionic/commit/6da9882))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.1"></a>
|
||||
## [0.1.1](https://github.com/ionic-team/ionic/commit/291e85e61128b2f3101d9cea6b42d4cf751dc481) (2018-03-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **button:** pass the property type instead of hardcoding button ([10e481a](https://github.com/ionic-team/ionic/commit/10e481a))
|
||||
|
||||
|
||||
|
||||
<a name="0.1.0"></a>
|
||||
## [0.1.0](https://github.com/ionic-team/ionic/commit/43a8c4c7a719169336a84964fc1c737562d764a6) (2018-03-01)
|
||||
@@ -8,8 +8,8 @@ Ionic is based on [Web Components](https://www.webcomponents.org/introduction) a
|
||||
|
||||
# Packages
|
||||
|
||||
- [Core](packages/core/README.md)
|
||||
- [Ionic Angular](packages/ionic-angular/README.md)
|
||||
- [Core](core/README.md)
|
||||
- [Ionic Angular](angular/README.md)
|
||||
|
||||
|
||||
### Getting Started
|
||||
@@ -46,3 +46,8 @@ As Ionic components migrate to the web component standard, a goal of ours is to
|
||||
|
||||
The source code for Ionic V1 has been moved to [ionic-team/ionic-v1](https://github.com/ionic-team/ionic-v1).
|
||||
Please open any issues and pull requests related to Ionic V1 on that repository.
|
||||
|
||||
|
||||
### Ionic V3
|
||||
|
||||
The source code for Ionic V3 has been moved to the [v3 branch](https://github.com/ionic-team/ionic/tree/v3).
|
||||
|
||||
1091
angular/BREAKING.md
Normal file
1091
angular/BREAKING.md
Normal file
File diff suppressed because it is too large
Load Diff
1
angular/package-lock.json
generated
Normal file
1
angular/package-lock.json
generated
Normal file
File diff suppressed because one or more lines are too long
66
angular/package.json
Normal file
66
angular/package.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "4.0.0-alpha.1",
|
||||
"description": "Angular specific wrappers for @ionic/core",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
"framework",
|
||||
"angular",
|
||||
"mobile",
|
||||
"app",
|
||||
"webapp",
|
||||
"capacitor",
|
||||
"cordova",
|
||||
"progressive web app",
|
||||
"pwa"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ionic-team/ionic.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run clean && npm run compile && npm run clean-generated && npm run ionic-core",
|
||||
"build.link": "npm run build && node scripts/link-copy.js",
|
||||
"clean": "node scripts/clean.js",
|
||||
"clean-generated": "node ./scripts/clean-generated.js",
|
||||
"compile": "./node_modules/.bin/ngc",
|
||||
"ionic-core": "node ../core/node_modules/.bin/stencil build",
|
||||
"ionic-core-dev": "node ../core/node_modules/.bin/stencil build --dev",
|
||||
"lint": "tslint --project .",
|
||||
"prerelease": "npm run validate && np prerelease --yolo --any-branch --tag next",
|
||||
"test": "echo 'angular no tests yet'",
|
||||
"tsc": "tsc -p .",
|
||||
"validate": "npm i && npm run lint && npm run test && npm run build"
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "4.0.0-alpha.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/common": "5.2.9",
|
||||
"@angular/compiler": "5.2.9",
|
||||
"@angular/compiler-cli": "5.2.9",
|
||||
"@angular/core": "5.2.9",
|
||||
"@angular/forms": "5.2.9",
|
||||
"@angular/platform-browser": "5.2.9",
|
||||
"@angular/platform-browser-dynamic": "5.2.9",
|
||||
"@angular/router": "5.2.9",
|
||||
"chalk": "^2.3.2",
|
||||
"execa": "^0.10.0",
|
||||
"fs-extra": "^5.0.0",
|
||||
"glob": "7.1.2",
|
||||
"inquirer": "^5.2.0",
|
||||
"listr": "^0.13.0",
|
||||
"rxjs": "5.5.8",
|
||||
"semver": "^5.5.0",
|
||||
"tslint": "^5.8.0",
|
||||
"tslint-ionic-rules": "0.0.14",
|
||||
"typescript": "2.7.2",
|
||||
"zone.js": "^0.8.20"
|
||||
}
|
||||
}
|
||||
19
angular/scripts/README.md
Normal file
19
angular/scripts/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Local @ionic/angular test app development
|
||||
|
||||
1. `npm install` at the root of `angular`
|
||||
2. `npm run build` to build local `@ionic/angular`
|
||||
3. `npm link` to locally link `@ionic/angular`
|
||||
4. `cd` to the test app, such as `angular/test/nav`
|
||||
5. `npm install` in the test app directory
|
||||
6. `npm link @ionic/angular` in the test app directory
|
||||
7. `ng serve` in the test app directory
|
||||
8. [http://localhost:4200/](http://localhost:4200/)
|
||||
|
||||
|
||||
# npm link local development
|
||||
|
||||
`npm link` doesn't work as expected due to the `devDependency` on `@angular/core`. This is the work around...
|
||||
|
||||
npm run build.link ../ionic-conference-app
|
||||
|
||||
When the command above is ran from the `angular` directory, it will build `@ionic/angular` and copy the `dist` directory to the correct location of another local project. In the example above, the end result is that it copies the `dist` directory to `../ionic-conference-app/node_modules/@ionic/angular/dist`. The path given should be relative to the root of this mono repo.
|
||||
@@ -2,23 +2,12 @@ const path = require('path');
|
||||
const cwd = process.cwd();
|
||||
|
||||
const glob = require('glob');
|
||||
const rimRaf = require('rimraf');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const distDir = path.join(cwd, 'dist');
|
||||
const distDir = path.join(__dirname, '../dist');
|
||||
|
||||
const distGeneratedNodeModules = path.join(distDir, 'node_modules');
|
||||
|
||||
function rimRafAsync(dir) {
|
||||
return new Promise((resolve, reject) => {
|
||||
rimRaf(dir, {}, err => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function doGlob(globString) {
|
||||
return new Promise((resolve, reject) => {
|
||||
glob(globString, (err, matches) => {
|
||||
@@ -40,15 +29,14 @@ function getCodegenedFilesToDelete() {
|
||||
const deleteFilePromises = [];
|
||||
listOfGlobResults.forEach(fileMatches => {
|
||||
fileMatches.forEach(filePath => {
|
||||
deleteFilePromises.push(rimRafAsync(filePath));
|
||||
deleteFilePromises.push(fs.remove(filePath));
|
||||
})
|
||||
})
|
||||
return Promise.all(deleteFilePromises);
|
||||
});
|
||||
}
|
||||
|
||||
const taskPromises = [];
|
||||
taskPromises.push(getCodegenedFilesToDelete());
|
||||
taskPromises.push(rimRafAsync(distGeneratedNodeModules));
|
||||
|
||||
return Promise.all(taskPromises);
|
||||
Promise.all([
|
||||
getCodegenedFilesToDelete(),
|
||||
fs.remove(distGeneratedNodeModules)
|
||||
]);
|
||||
28
angular/src/components.d.ts
vendored
Normal file
28
angular/src/components.d.ts
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* This is an autogenerated file created by the Stencil build process.
|
||||
* It contains typing information for all components that exist in this project
|
||||
* and imports for stencil collections that might be configured in your stencil.config.js file
|
||||
*/
|
||||
|
||||
import '@stencil/core';
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface Element {}
|
||||
export interface IntrinsicElements {}
|
||||
}
|
||||
namespace JSXElements {}
|
||||
|
||||
interface HTMLStencilElement extends HTMLElement {
|
||||
componentOnReady(): Promise<this>;
|
||||
componentOnReady(done: (ele?: this) => void): void;
|
||||
|
||||
forceUpdate(): void;
|
||||
}
|
||||
|
||||
interface HTMLAttributes {}
|
||||
}
|
||||
|
||||
import 'ionicons';
|
||||
import '@ionic/core';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
@@ -15,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
|
||||
]
|
||||
})
|
||||
export class BooleanValueAccessor implements ControlValueAccessor {
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
@@ -24,14 +25,15 @@ export class BooleanValueAccessor implements ControlValueAccessor {
|
||||
onTouched: () => void;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.renderer.setProperty(this.element.nativeElement, 'checked', value);
|
||||
this.element.nativeElement.checked = value;
|
||||
setIonicClasses(this.element);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.checked'])
|
||||
_handleIonChange(value: any) {
|
||||
this.onChange(value);
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
@@ -39,24 +41,21 @@ export class BooleanValueAccessor implements ControlValueAccessor {
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void): void {
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
@@ -15,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
|
||||
]
|
||||
})
|
||||
export class NumericValueAccessor implements ControlValueAccessor {
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
@@ -23,49 +24,42 @@ export class NumericValueAccessor implements ControlValueAccessor {
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
writeValue(value: any): void {
|
||||
writeValue(value: any) {
|
||||
// The value needs to be normalized for IE9, otherwise it is set to 'null' when null
|
||||
// Probably not an issue for us, but it doesn't really cost anything either
|
||||
const normalizedValue = value == null ? '' : value;
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'value',
|
||||
normalizedValue
|
||||
);
|
||||
this.element.nativeElement.value = value == null ? '' : value;
|
||||
setIonicClasses(this.element);
|
||||
}
|
||||
|
||||
@HostListener('input', ['$event.target.value'])
|
||||
_handleInputEvent(value: any): void {
|
||||
_handleInputEvent(value: any) {
|
||||
this.onChange(value);
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent(): void {
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: number | null) => void): void {
|
||||
registerOnChange(fn: (_: number | null) => void) {
|
||||
this.onChange = value => {
|
||||
fn(value === '' ? null : parseFloat(value));
|
||||
};
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
@@ -20,24 +20,24 @@ export class RadioValueAccessor implements ControlValueAccessor {
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
|
||||
writeValue(value: any) {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'checked',
|
||||
value === this.value
|
||||
);
|
||||
setIonicClasses(this.element);
|
||||
this.element.nativeElement.checked = this.value = value;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionSelect', ['$event.target.checked'])
|
||||
_handleIonSelect(value: any) {
|
||||
this.onChange(value);
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
@@ -45,26 +45,23 @@ export class RadioValueAccessor implements ControlValueAccessor {
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void): void {
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = () => {
|
||||
fn(this.value);
|
||||
};
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
|
||||
// NOTE: May need to look at this to see if we need anything else:
|
||||
// https://github.com/angular/angular/blob/5.0.2/packages/forms/src/directives/select_control_value_accessor.ts#L28-L158
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-range, ion-select, ion-radio-group, ion-segment, ion-datetime',
|
||||
@@ -17,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
|
||||
]
|
||||
})
|
||||
export class SelectValueAccessor implements ControlValueAccessor {
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
@@ -26,14 +25,18 @@ export class SelectValueAccessor implements ControlValueAccessor {
|
||||
onTouched: () => void;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.renderer.setProperty(this.element.nativeElement, 'value', value);
|
||||
setIonicClasses(this.element);
|
||||
this.element.nativeElement.value = value;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleChangeEvent(value: any) {
|
||||
this.onChange(value);
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
@@ -41,7 +44,8 @@ export class SelectValueAccessor implements ControlValueAccessor {
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
@@ -54,11 +58,7 @@ export class SelectValueAccessor implements ControlValueAccessor {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
@@ -15,7 +15,8 @@ import { setIonicClasses } from './util/set-ionic-classes';
|
||||
]
|
||||
})
|
||||
export class TextValueAccessor implements ControlValueAccessor {
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
@@ -24,14 +25,18 @@ export class TextValueAccessor implements ControlValueAccessor {
|
||||
onTouched: () => void;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.renderer.setProperty(this.element.nativeElement, 'value', value);
|
||||
setIonicClasses(this.element);
|
||||
this.element.nativeElement.value = value;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('input', ['$event.target.value'])
|
||||
_handleInputEvent(value: any) {
|
||||
this.onChange(value);
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
@@ -39,7 +44,8 @@ export class TextValueAccessor implements ControlValueAccessor {
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
setTimeout(() => {
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
@@ -52,11 +58,7 @@ export class TextValueAccessor implements ControlValueAccessor {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
45
angular/src/directives/icon.ts
Normal file
45
angular/src/directives/icon.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Directive, ElementRef, Input } from '@angular/core';
|
||||
import { inputs } from './proxies';
|
||||
|
||||
|
||||
@Directive({ selector: 'ion-icon' })
|
||||
export class Icon {
|
||||
|
||||
/**
|
||||
* The color to use from your Sass `$colors` map.
|
||||
* Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
|
||||
* For more information, see [Theming your App](/docs/theming/theming-your-app).
|
||||
*/
|
||||
@Input() color: string;
|
||||
|
||||
/**
|
||||
* Specifies the label to use for accessibility. Defaults to the icon name.
|
||||
*/
|
||||
@Input() ariaLabel = '';
|
||||
|
||||
/**
|
||||
* Specifies which icon to use on `ios` mode.
|
||||
*/
|
||||
@Input() ios = '';
|
||||
|
||||
/**
|
||||
* Specifies which icon to use on `md` mode.
|
||||
*/
|
||||
@Input() md = '';
|
||||
|
||||
/**
|
||||
* Specifies which icon to use. The appropriate icon will be used based on the mode.
|
||||
* For more information, see [Ionicons](/docs/ionicons/).
|
||||
*/
|
||||
@Input() name = '';
|
||||
|
||||
/**
|
||||
* The size of the icon.
|
||||
* Available options are: `"small"` and `"large"`.
|
||||
*/
|
||||
@Input() size: string;
|
||||
|
||||
constructor(el: ElementRef) {
|
||||
inputs(this, el, ['color', 'ariaLabel', 'ios', 'md', 'name', 'size']);
|
||||
}
|
||||
}
|
||||
20
angular/src/directives/index.ts
Normal file
20
angular/src/directives/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
export { BooleanValueAccessor } from './control-value-accessors/boolean-value-accessor';
|
||||
export { NumericValueAccessor } from './control-value-accessors/numeric-value-accesssor';
|
||||
export { RadioValueAccessor } from './control-value-accessors/radio-value-accessor';
|
||||
export { SelectValueAccessor } from './control-value-accessors/select-value-accessor';
|
||||
export { TextValueAccessor } from './control-value-accessors/text-value-accessor';
|
||||
|
||||
export { GoBack } from './navigation/go-back';
|
||||
export { IonBackButton } from './navigation/ion-back-button';
|
||||
export { NavDelegate } from './navigation/nav-delegate';
|
||||
export { TabDelegate } from './navigation/tab-delegate';
|
||||
export { TabsDelegate } from './navigation/tabs-delegate';
|
||||
export { IonRouterOutlet } from './navigation/ion-router-outlet';
|
||||
export { HrefDelegate } from './navigation/href-delegate';
|
||||
|
||||
export { Icon } from './icon';
|
||||
export { VirtualScroll } from './virtual-scroll/virtual-scroll';
|
||||
export { VirtualItem } from './virtual-scroll/virtual-item';
|
||||
export { VirtualHeader } from './virtual-scroll/virtual-header';
|
||||
export { VirtualFooter } from './virtual-scroll/virtual-footer';
|
||||
17
angular/src/directives/navigation/go-back.ts
Normal file
17
angular/src/directives/navigation/go-back.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Directive, HostListener } from '@angular/core';
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
@Directive({
|
||||
selector: '[goBack]',
|
||||
})
|
||||
export class GoBack {
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
) {}
|
||||
|
||||
@HostListener('click')
|
||||
onClick() {
|
||||
this.navCtrl.setGoback();
|
||||
}
|
||||
}
|
||||
30
angular/src/directives/navigation/href-delegate.ts
Normal file
30
angular/src/directives/navigation/href-delegate.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-anchor,ion-button,ion-item'
|
||||
})
|
||||
export class HrefDelegate {
|
||||
|
||||
@Input()
|
||||
set href(value: string) {
|
||||
this.elementRef.nativeElement.href = value;
|
||||
}
|
||||
get href() {
|
||||
return this.elementRef.nativeElement.href;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Optional() private router: Router,
|
||||
private elementRef: ElementRef
|
||||
) {}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
onClick(ev: Event) {
|
||||
const url = this.href;
|
||||
if (this.router && url != null && url[0] !== '#' && url.indexOf('://') === -1) {
|
||||
ev.preventDefault();
|
||||
this.router.navigateByUrl(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
angular/src/directives/navigation/ion-back-button.ts
Normal file
37
angular/src/directives/navigation/ion-back-button.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
import { IonRouterOutlet } from './ion-router-outlet';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-back-button'
|
||||
})
|
||||
export class IonBackButton {
|
||||
|
||||
@Input()
|
||||
set defaultHref(value: string) {
|
||||
this.elementRef.nativeElement.defaultHref = value;
|
||||
}
|
||||
get defaultHref() {
|
||||
return this.elementRef.nativeElement.defaultHref;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Optional() private router: Router,
|
||||
@Optional() private routerOutlet: IonRouterOutlet,
|
||||
private navCtrl: NavController,
|
||||
private elementRef: ElementRef,
|
||||
) {}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
onClick(ev: Event) {
|
||||
if (this.routerOutlet && this.routerOutlet.canGoBack()) {
|
||||
this.routerOutlet.pop();
|
||||
ev.preventDefault();
|
||||
} else if (this.router && this.defaultHref != null) {
|
||||
this.navCtrl.setGoback();
|
||||
this.router.navigateByUrl(this.defaultHref);
|
||||
ev.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
185
angular/src/directives/navigation/ion-router-outlet.ts
Normal file
185
angular/src/directives/navigation/ion-router-outlet.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core';
|
||||
import { ActivatedRoute, ChildrenOutletContexts, PRIMARY_OUTLET, Router } from '@angular/router';
|
||||
import { StackController } from './router-controller';
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
import { bindLifecycleEvents } from '../../providers/angular-delegate';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-router-outlet',
|
||||
exportAs: 'outlet'
|
||||
})
|
||||
export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
|
||||
private activated: ComponentRef<any>|null = null;
|
||||
|
||||
private _activatedRoute: ActivatedRoute|null = null;
|
||||
private name: string;
|
||||
private stackCtrl: StackController;
|
||||
|
||||
@Output('activate') activateEvents = new EventEmitter<any>();
|
||||
@Output('deactivate') deactivateEvents = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private parentContexts: ChildrenOutletContexts,
|
||||
private location: ViewContainerRef,
|
||||
private resolver: ComponentFactoryResolver,
|
||||
private elementRef: ElementRef,
|
||||
@Attribute('name') name: string,
|
||||
@Optional() @Attribute('stack') stack: any,
|
||||
private changeDetector: ChangeDetectorRef,
|
||||
private navCtrl: NavController,
|
||||
router: Router
|
||||
) {
|
||||
this.name = name || PRIMARY_OUTLET;
|
||||
parentContexts.onChildOutletCreated(this.name, this as any);
|
||||
this.stackCtrl = new StackController(stack != null, elementRef.nativeElement, router, this.navCtrl);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.parentContexts.onChildOutletDestroyed(this.name);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (!this.activated) {
|
||||
// If the outlet was not instantiated at the time the route got activated we need to populate
|
||||
// the outlet when it is initialized (ie inside a NgIf)
|
||||
const context = this.parentContexts.getContext(this.name);
|
||||
if (context && context.route) {
|
||||
if (context.attachRef) {
|
||||
// `attachRef` is populated when there is an existing component to mount
|
||||
this.attach(context.attachRef, context.route);
|
||||
} else {
|
||||
// otherwise the component defined in the configuration is created
|
||||
this.activateWith(context.route, context.resolver || null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get isActivated(): boolean { return !!this.activated; }
|
||||
|
||||
get component(): Object {
|
||||
if (!this.activated) {
|
||||
throw new Error('Outlet is not activated');
|
||||
}
|
||||
return this.activated.instance;
|
||||
}
|
||||
|
||||
get activatedRoute(): ActivatedRoute {
|
||||
if (!this.activated) {
|
||||
throw new Error('Outlet is not activated');
|
||||
}
|
||||
return this._activatedRoute as ActivatedRoute;
|
||||
}
|
||||
|
||||
get activatedRouteData() {
|
||||
if (this._activatedRoute) {
|
||||
return this._activatedRoute.snapshot.data;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the `RouteReuseStrategy` instructs to detach the subtree
|
||||
*/
|
||||
detach(): ComponentRef<any> {
|
||||
if (!this.activated) {
|
||||
throw new Error('Outlet is not activated');
|
||||
}
|
||||
this.location.detach();
|
||||
const cmp = this.activated;
|
||||
this.activated = null;
|
||||
this._activatedRoute = null;
|
||||
return cmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
|
||||
*/
|
||||
attach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute) {
|
||||
this.activated = ref;
|
||||
this._activatedRoute = activatedRoute;
|
||||
this.location.insert(ref.hostView);
|
||||
}
|
||||
|
||||
deactivate(): void {
|
||||
if (this.activated) {
|
||||
const c = this.component;
|
||||
this.activated = null;
|
||||
this._activatedRoute = null;
|
||||
this.deactivateEvents.emit(c);
|
||||
}
|
||||
}
|
||||
|
||||
async activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver|null) {
|
||||
if (this.isActivated) {
|
||||
throw new Error('Cannot activate an already activated outlet');
|
||||
}
|
||||
this._activatedRoute = activatedRoute;
|
||||
|
||||
let enteringView = this.stackCtrl.getExistingView(activatedRoute);
|
||||
if (enteringView) {
|
||||
this.activated = enteringView.ref;
|
||||
} else {
|
||||
const snapshot = (activatedRoute as any)._futureSnapshot;
|
||||
const component = <any>snapshot.routeConfig !.component;
|
||||
resolver = resolver || this.resolver;
|
||||
|
||||
const factory = resolver.resolveComponentFactory(component);
|
||||
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
|
||||
|
||||
const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
|
||||
const cmp = this.activated = this.location.createComponent(factory, this.location.length, injector);
|
||||
|
||||
bindLifecycleEvents(cmp.instance, cmp.location.nativeElement);
|
||||
|
||||
// Calling `markForCheck` to make sure we will run the change detection when the
|
||||
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
|
||||
this.changeDetector.markForCheck();
|
||||
enteringView = this.stackCtrl.createView(this.activated, activatedRoute);
|
||||
}
|
||||
|
||||
const direction = this.navCtrl.consumeDirection();
|
||||
await this.stackCtrl.setActive(enteringView, direction);
|
||||
this.activateEvents.emit(this.activated.instance);
|
||||
|
||||
emitEvent(this.elementRef.nativeElement);
|
||||
}
|
||||
|
||||
canGoBack(deep = 1) {
|
||||
return this.stackCtrl.canGoBack(deep);
|
||||
}
|
||||
|
||||
pop(deep = 1) {
|
||||
return this.stackCtrl.pop(deep);
|
||||
}
|
||||
}
|
||||
|
||||
function emitEvent(el: HTMLElement) {
|
||||
console.log('ionRouterOutletActivated');
|
||||
const event = new CustomEvent('ionRouterOutletActivated', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
el.dispatchEvent(event);
|
||||
}
|
||||
|
||||
class OutletInjector implements Injector {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private childContexts: ChildrenOutletContexts,
|
||||
private parent: Injector
|
||||
) {}
|
||||
|
||||
get(token: any, notFoundValue?: any): any {
|
||||
if (token === ActivatedRoute) {
|
||||
return this.route;
|
||||
}
|
||||
|
||||
if (token === ChildrenOutletContexts) {
|
||||
return this.childContexts;
|
||||
}
|
||||
|
||||
return this.parent.get(token, notFoundValue);
|
||||
}
|
||||
}
|
||||
16
angular/src/directives/navigation/nav-delegate.ts
Normal file
16
angular/src/directives/navigation/nav-delegate.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, Injector } from '@angular/core';
|
||||
import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-nav',
|
||||
})
|
||||
export class NavDelegate {
|
||||
constructor(
|
||||
ref: ElementRef,
|
||||
cfr: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
angularDelegate: AngularDelegate,
|
||||
) {
|
||||
ref.nativeElement.delegate = angularDelegate.create(cfr, injector);
|
||||
}
|
||||
}
|
||||
138
angular/src/directives/navigation/router-controller.ts
Normal file
138
angular/src/directives/navigation/router-controller.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
import { ComponentRef } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NavDirection } from '@ionic/core';
|
||||
|
||||
import { NavController } from '../../providers/nav-controller';
|
||||
|
||||
|
||||
export class StackController {
|
||||
|
||||
private viewsSnapshot: RouteView[] = [];
|
||||
private views: RouteView[] = [];
|
||||
|
||||
constructor(
|
||||
private stack: boolean,
|
||||
private containerEl: HTMLIonRouterOutletElement,
|
||||
private router: Router,
|
||||
private navCtrl: NavController,
|
||||
) {}
|
||||
|
||||
createView(enteringRef: ComponentRef<any>, route: ActivatedRoute): RouteView {
|
||||
return {
|
||||
ref: enteringRef,
|
||||
element: (enteringRef && enteringRef.location && enteringRef.location.nativeElement) as HTMLElement,
|
||||
url: this.getUrl(route),
|
||||
deactivatedId: -1
|
||||
};
|
||||
}
|
||||
|
||||
getExistingView(activatedRoute: ActivatedRoute): RouteView|null {
|
||||
const activatedUrlKey = this.getUrl(activatedRoute);
|
||||
return this.views.find(vw => vw.url === activatedUrlKey);
|
||||
}
|
||||
|
||||
canGoBack(deep: number): boolean {
|
||||
return this.views.length > deep;
|
||||
}
|
||||
|
||||
async setActive(enteringView: RouteView, direction: number | undefined) {
|
||||
const leavingView = this.getActive();
|
||||
const forcedGoBack = direction === -1;
|
||||
const reused = this.insertView(enteringView, forcedGoBack);
|
||||
direction = direction != null ? direction : (reused ? -1 : 1);
|
||||
await this.transition(enteringView, leavingView, direction, this.canGoBack(1));
|
||||
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
pop(deep: number) {
|
||||
const view = this.views[this.views.length - deep - 1];
|
||||
this.navCtrl.setGoback();
|
||||
this.router.navigateByUrl(view.url);
|
||||
}
|
||||
|
||||
private insertView(enteringView: RouteView, forcedGoBack: boolean): boolean {
|
||||
if (this.stack) {
|
||||
const index = this.views.indexOf(enteringView);
|
||||
if (index >= 0) {
|
||||
this.views = this.views.slice(0, index + 1);
|
||||
return true;
|
||||
} else {
|
||||
if (forcedGoBack) {
|
||||
this.views = [enteringView];
|
||||
} else {
|
||||
this.views.push(enteringView);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
this.views = [enteringView];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private cleanup() {
|
||||
this.viewsSnapshot
|
||||
.filter(view => !this.views.includes(view))
|
||||
.forEach(view => destroyView(view));
|
||||
|
||||
for (let i = 0; i < this.views.length - 1; i++) {
|
||||
this.views[i].element.hidden = true;
|
||||
}
|
||||
this.viewsSnapshot = this.views.slice();
|
||||
}
|
||||
|
||||
getActive(): RouteView | null {
|
||||
return this.views.length > 0 ? this.views[this.views.length - 1] : null;
|
||||
}
|
||||
|
||||
private async transition(enteringView: RouteView, leavingView: RouteView, direction: number, showGoBack: boolean) {
|
||||
const enteringEl = enteringView ? enteringView.element : undefined;
|
||||
const leavingEl = leavingView ? leavingView.element : undefined;
|
||||
const containerEl = this.containerEl;
|
||||
if (enteringEl && enteringEl !== leavingEl) {
|
||||
enteringEl.classList.add('ion-page', 'hide-page');
|
||||
containerEl.appendChild(enteringEl);
|
||||
|
||||
await containerEl.componentOnReady();
|
||||
await containerEl.commit(enteringEl, leavingEl, {
|
||||
duration: direction === 0 ? 0 : undefined,
|
||||
direction: direction === -1 ? NavDirection.Back : NavDirection.Forward,
|
||||
deepWait: true,
|
||||
showGoBack
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private getUrl(activatedRoute: ActivatedRoute) {
|
||||
const urlTree = this.router.createUrlTree(['.'], { relativeTo: activatedRoute });
|
||||
return this.router.serializeUrl(urlTree);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function destroyView(view: RouteView) {
|
||||
if (view) {
|
||||
// TODO lifecycle event
|
||||
view.ref.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
export function getLastDeactivatedRef(views: RouteView[]) {
|
||||
if (views.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return views.sort((a, b) => {
|
||||
if (a.deactivatedId > b.deactivatedId) return -1;
|
||||
if (a.deactivatedId < b.deactivatedId) return 1;
|
||||
return 0;
|
||||
})[0].ref;
|
||||
}
|
||||
|
||||
export interface RouteView {
|
||||
url: string;
|
||||
element: HTMLElement;
|
||||
ref: ComponentRef<any>;
|
||||
deactivatedId: number;
|
||||
}
|
||||
31
angular/src/directives/navigation/tab-delegate.ts
Normal file
31
angular/src/directives/navigation/tab-delegate.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, HostListener, Injector } from '@angular/core';
|
||||
import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-tab'
|
||||
})
|
||||
export class TabDelegate {
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
cfr: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
angularDelegate: AngularDelegate,
|
||||
) {
|
||||
elementRef.nativeElement.delegate = angularDelegate.create(cfr, injector);
|
||||
}
|
||||
|
||||
@HostListener('ionRouterOutletActivated', ['$event'])
|
||||
async onNavChanged() {
|
||||
const tab = this.elementRef.nativeElement as HTMLIonTabElement;
|
||||
await tab.componentOnReady();
|
||||
const tabs = tab.closest('ion-tabs');
|
||||
if (tabs) {
|
||||
await tabs.componentOnReady();
|
||||
await tabs.select(tab);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
25
angular/src/directives/navigation/tabs-delegate.ts
Normal file
25
angular/src/directives/navigation/tabs-delegate.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Directive, ElementRef, HostListener, Optional } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-tabs'
|
||||
})
|
||||
export class TabsDelegate {
|
||||
|
||||
constructor(
|
||||
@Optional() private router: Router,
|
||||
elementRef: ElementRef
|
||||
) {
|
||||
if (router) {
|
||||
elementRef.nativeElement.useRouter = true;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('ionTabbarClick', ['$event'])
|
||||
onTabbarClick(ev: UIEvent) {
|
||||
const tabElm: HTMLIonTabElement = ev.detail as any;
|
||||
if (this.router && tabElm && tabElm.href) {
|
||||
this.router.navigateByUrl(tabElm.href);
|
||||
}
|
||||
}
|
||||
}
|
||||
79
angular/src/directives/proxies-list.txt
Normal file
79
angular/src/directives/proxies-list.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
import * as d from './proxies';
|
||||
|
||||
export const DIRECTIVES = [
|
||||
d.App,
|
||||
d.Avatar,
|
||||
d.BackButton,
|
||||
d.Badge,
|
||||
d.Button,
|
||||
d.Buttons,
|
||||
d.Card,
|
||||
d.CardContent,
|
||||
d.CardHeader,
|
||||
d.CardSubtitle,
|
||||
d.CardTitle,
|
||||
d.Checkbox,
|
||||
d.Chip,
|
||||
d.ChipButton,
|
||||
d.Col,
|
||||
d.Content,
|
||||
d.Datetime,
|
||||
d.Fab,
|
||||
d.FabButton,
|
||||
d.FabList,
|
||||
d.Footer,
|
||||
d.Grid,
|
||||
d.Header,
|
||||
d.HideWhen,
|
||||
d.InfiniteScroll,
|
||||
d.InfiniteScrollContent,
|
||||
d.Input,
|
||||
d.Item,
|
||||
d.ItemDivider,
|
||||
d.ItemGroup,
|
||||
d.ItemOption,
|
||||
d.ItemOptions,
|
||||
d.ItemSliding,
|
||||
d.Label,
|
||||
d.List,
|
||||
d.ListHeader,
|
||||
d.Menu,
|
||||
d.MenuButton,
|
||||
d.MenuToggle,
|
||||
d.Nav,
|
||||
d.NavPop,
|
||||
d.NavPush,
|
||||
d.NavSetRoot,
|
||||
d.Note,
|
||||
d.Radio,
|
||||
d.RadioGroup,
|
||||
d.Range,
|
||||
d.Refresher,
|
||||
d.RefresherContent,
|
||||
d.Reorder,
|
||||
d.ReorderGroup,
|
||||
d.RippleEffect,
|
||||
d.Row,
|
||||
d.Scroll,
|
||||
d.Searchbar,
|
||||
d.Segment,
|
||||
d.SegmentButton,
|
||||
d.Select,
|
||||
d.SelectOption,
|
||||
d.SelectPopover,
|
||||
d.ShowWhen,
|
||||
d.SkeletonText,
|
||||
d.Slide,
|
||||
d.Slides,
|
||||
d.Spinner,
|
||||
d.SplitPane,
|
||||
d.Tab,
|
||||
d.Tabs,
|
||||
d.Text,
|
||||
d.Textarea,
|
||||
d.Thumbnail,
|
||||
d.Toggle,
|
||||
d.Toolbar,
|
||||
d.ToolbarTitle
|
||||
];
|
||||
2000
angular/src/directives/proxies.ts
Normal file
2000
angular/src/directives/proxies.ts
Normal file
File diff suppressed because one or more lines are too long
17
angular/src/index.ts
Normal file
17
angular/src/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// export module
|
||||
export { IonicModule } from './module';
|
||||
|
||||
// export auto generated directive
|
||||
export * from './directives/proxies';
|
||||
|
||||
// export custom directives
|
||||
export * from './directives';
|
||||
|
||||
// export custom providers
|
||||
export * from './providers';
|
||||
|
||||
// ionic types
|
||||
export * from './types/interfaces';
|
||||
|
||||
/*tslint:disable*/
|
||||
import './ionic-angular';
|
||||
32
angular/src/ionic-angular.ts
Normal file
32
angular/src/ionic-angular.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/*tslint:disable*/
|
||||
import './ionic';
|
||||
import { IonicWindow } from './types/interfaces';
|
||||
|
||||
const win = (window as IonicWindow);
|
||||
const Ionic = win.Ionic;
|
||||
|
||||
if (Ionic) {
|
||||
Ionic.ael = function ngAddEventListener(elm, eventName, cb, opts) {
|
||||
if (elm.__zone_symbol__addEventListener) {
|
||||
elm.__zone_symbol__addEventListener(eventName, cb, opts);
|
||||
} else {
|
||||
elm.addEventListener(eventName, cb, opts);
|
||||
}
|
||||
};
|
||||
|
||||
Ionic.rel = function ngRemoveEventListener(elm, eventName, cb, opts) {
|
||||
if (elm.__zone_symbol__removeEventListener) {
|
||||
elm.__zone_symbol__removeEventListener(eventName, cb, opts);
|
||||
} else {
|
||||
elm.removeEventListener(eventName, cb, opts);
|
||||
}
|
||||
};
|
||||
|
||||
Ionic.raf = function ngRequestAnimationFrame(cb: any) {
|
||||
if (win.__zone_symbol__requestAnimationFrame) {
|
||||
win.__zone_symbol__requestAnimationFrame(cb);
|
||||
} else {
|
||||
win.requestAnimationFrame(cb);
|
||||
}
|
||||
};
|
||||
}
|
||||
3
angular/src/ionic.ts
Normal file
3
angular/src/ionic.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
// placeholder for ionic loader js
|
||||
// created by the stencil build process
|
||||
145
angular/src/module.ts
Normal file
145
angular/src/module.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import * as c from './directives';
|
||||
import * as d from './directives/proxies';
|
||||
import * as p from './providers';
|
||||
|
||||
|
||||
const DECLARATIONS = [
|
||||
// proxies
|
||||
d.App,
|
||||
d.Avatar,
|
||||
d.BackButton,
|
||||
d.Badge,
|
||||
d.Button,
|
||||
d.Buttons,
|
||||
d.Card,
|
||||
d.CardContent,
|
||||
d.CardHeader,
|
||||
d.CardSubtitle,
|
||||
d.CardTitle,
|
||||
d.Checkbox,
|
||||
d.Chip,
|
||||
d.ChipButton,
|
||||
d.Col,
|
||||
d.Content,
|
||||
d.Datetime,
|
||||
d.Fab,
|
||||
d.FabButton,
|
||||
d.FabList,
|
||||
d.Footer,
|
||||
d.Grid,
|
||||
d.Header,
|
||||
d.HideWhen,
|
||||
d.InfiniteScroll,
|
||||
d.InfiniteScrollContent,
|
||||
d.Input,
|
||||
d.Item,
|
||||
d.ItemDivider,
|
||||
d.ItemGroup,
|
||||
d.ItemOption,
|
||||
d.ItemOptions,
|
||||
d.ItemSliding,
|
||||
d.Label,
|
||||
d.List,
|
||||
d.ListHeader,
|
||||
d.Menu,
|
||||
d.MenuButton,
|
||||
d.MenuToggle,
|
||||
d.Nav,
|
||||
d.NavPop,
|
||||
d.NavPush,
|
||||
d.NavSetRoot,
|
||||
d.Note,
|
||||
d.Radio,
|
||||
d.RadioGroup,
|
||||
d.Range,
|
||||
d.Refresher,
|
||||
d.RefresherContent,
|
||||
d.Reorder,
|
||||
d.ReorderGroup,
|
||||
d.RippleEffect,
|
||||
d.Row,
|
||||
d.Scroll,
|
||||
d.Searchbar,
|
||||
d.Segment,
|
||||
d.SegmentButton,
|
||||
d.Select,
|
||||
d.SelectOption,
|
||||
d.SelectPopover,
|
||||
d.ShowWhen,
|
||||
d.SkeletonText,
|
||||
d.Slide,
|
||||
d.Slides,
|
||||
d.Spinner,
|
||||
d.SplitPane,
|
||||
d.Tab,
|
||||
d.Tabs,
|
||||
d.Text,
|
||||
d.Textarea,
|
||||
d.Thumbnail,
|
||||
d.Toggle,
|
||||
d.Toolbar,
|
||||
d.ToolbarTitle,
|
||||
|
||||
// custom proxy
|
||||
c.Icon,
|
||||
|
||||
// ngModel accessors
|
||||
c.BooleanValueAccessor,
|
||||
c.NumericValueAccessor,
|
||||
c.RadioValueAccessor,
|
||||
c.SelectValueAccessor,
|
||||
c.TextValueAccessor,
|
||||
|
||||
// navigation
|
||||
c.GoBack,
|
||||
c.IonBackButton,
|
||||
c.IonRouterOutlet,
|
||||
c.NavDelegate,
|
||||
c.TabDelegate,
|
||||
c.TabsDelegate,
|
||||
c.HrefDelegate,
|
||||
|
||||
// virtual scroll
|
||||
c.VirtualFooter,
|
||||
c.VirtualHeader,
|
||||
c.VirtualItem,
|
||||
c.VirtualScroll,
|
||||
];
|
||||
|
||||
const PROVIDERS = [
|
||||
p.ActionSheetController,
|
||||
p.AlertController,
|
||||
p.LoadingController,
|
||||
p.PickerController,
|
||||
p.ToastController,
|
||||
p.MenuController,
|
||||
p.NavController,
|
||||
p.Platform,
|
||||
p.Events,
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: DECLARATIONS,
|
||||
exports: DECLARATIONS,
|
||||
providers: [
|
||||
p.AngularDelegate,
|
||||
p.ModalController,
|
||||
p.PopoverController,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
]
|
||||
})
|
||||
export class IonicModule {
|
||||
static forRoot(): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: IonicModule,
|
||||
providers: [
|
||||
...PROVIDERS,
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
10
angular/src/providers/action-sheet-controller.ts
Normal file
10
angular/src/providers/action-sheet-controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActionSheetOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
|
||||
@Injectable()
|
||||
export class ActionSheetController extends OverlayBaseController<ActionSheetOptions, HTMLIonActionSheetElement> {
|
||||
constructor() {
|
||||
super('ion-action-sheet-controller');
|
||||
}
|
||||
}
|
||||
10
angular/src/providers/alert-controller.ts
Normal file
10
angular/src/providers/alert-controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AlertOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
|
||||
@Injectable()
|
||||
export class AlertController extends OverlayBaseController<AlertOptions, HTMLIonAlertElement> {
|
||||
constructor() {
|
||||
super('ion-alert-controller');
|
||||
}
|
||||
}
|
||||
97
angular/src/providers/angular-delegate.ts
Normal file
97
angular/src/providers/angular-delegate.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { ApplicationRef, ComponentFactoryResolver, Injectable, Injector, NgZone } from '@angular/core';
|
||||
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class AngularDelegate {
|
||||
|
||||
constructor(
|
||||
private appRef: ApplicationRef,
|
||||
private zone: NgZone
|
||||
) {}
|
||||
|
||||
create(cfr: ComponentFactoryResolver, injector: Injector) {
|
||||
return new AngularFrameworkDelegate(cfr, injector, this.appRef, this.zone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
|
||||
private elRefMap = new WeakMap<HTMLElement, any>();
|
||||
|
||||
constructor(
|
||||
private cfr: ComponentFactoryResolver,
|
||||
private injector: Injector,
|
||||
private appRef: ApplicationRef,
|
||||
private zone: NgZone,
|
||||
) {}
|
||||
|
||||
attachViewToDom(container: any, component: any, params?: any, cssClasses?: string[]): Promise<any> {
|
||||
return new Promise(resolve => {
|
||||
this.zone.run(() => {
|
||||
const el = attachView(
|
||||
this.cfr, this.injector, this.appRef, this.elRefMap,
|
||||
container, component, params, cssClasses
|
||||
);
|
||||
resolve(el);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
removeViewFromDom(_container: any, component: any): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.zone.run(() => {
|
||||
const componentRef = this.elRefMap.get(component);
|
||||
if (componentRef) {
|
||||
componentRef.destroy();
|
||||
this.elRefMap.delete(component);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function attachView(
|
||||
cfr: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
appRef: ApplicationRef,
|
||||
elRefMap: WeakMap<HTMLElement, any>,
|
||||
container: any, component: any, data?: any, cssClasses?: string[]) {
|
||||
const componentFactory = cfr.resolveComponentFactory(component);
|
||||
const hostElement = document.createElement(componentFactory.selector);
|
||||
if (data) {
|
||||
Object.assign(hostElement, data);
|
||||
}
|
||||
|
||||
const childInjector = Injector.create([], injector);
|
||||
const componentRef = componentFactory.create(childInjector, [], hostElement);
|
||||
for (const clazz of cssClasses) {
|
||||
hostElement.classList.add(clazz);
|
||||
}
|
||||
bindLifecycleEvents(componentRef.instance, hostElement);
|
||||
container.appendChild(hostElement);
|
||||
|
||||
appRef.attachView(componentRef.hostView);
|
||||
elRefMap.set(hostElement, componentRef);
|
||||
return hostElement;
|
||||
}
|
||||
|
||||
const LIFECYCLES = [
|
||||
ViewLifecycle.WillEnter,
|
||||
ViewLifecycle.DidEnter,
|
||||
ViewLifecycle.WillLeave,
|
||||
ViewLifecycle.DidLeave,
|
||||
ViewLifecycle.WillUnload
|
||||
];
|
||||
|
||||
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
|
||||
LIFECYCLES.forEach(eventName => {
|
||||
element.addEventListener(eventName, (ev: CustomEvent) => {
|
||||
if (typeof instance[eventName] === 'function') {
|
||||
instance[eventName](ev.detail);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
13
angular/src/providers/index.ts
Normal file
13
angular/src/providers/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
export { AngularDelegate } from './angular-delegate';
|
||||
export { ActionSheetController } from './action-sheet-controller';
|
||||
export { AlertController } from './alert-controller';
|
||||
export { Events } from './events';
|
||||
export { LoadingController } from './loading-controller';
|
||||
export { MenuController } from './menu-controller';
|
||||
export { PickerController } from './picker-controller';
|
||||
export { ModalController } from './modal-controller';
|
||||
export { Platform } from './platform';
|
||||
export { PopoverController } from './popover-controller';
|
||||
export { ToastController } from './toast-controller';
|
||||
export { NavController } from './nav-controller';
|
||||
10
angular/src/providers/loading-controller.ts
Normal file
10
angular/src/providers/loading-controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { LoadingOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
|
||||
@Injectable()
|
||||
export class LoadingController extends OverlayBaseController<LoadingOptions, HTMLIonLoadingElement> {
|
||||
constructor() {
|
||||
super('ion-loading-controller');
|
||||
}
|
||||
}
|
||||
104
angular/src/providers/menu-controller.ts
Normal file
104
angular/src/providers/menu-controller.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { proxyMethod } from '../util/util';
|
||||
|
||||
const CTRL = 'ion-menu-controller';
|
||||
@Injectable()
|
||||
export class MenuController {
|
||||
|
||||
/**
|
||||
* Programatically open the Menu.
|
||||
* @param {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {Promise} returns a promise when the menu is fully opened
|
||||
*/
|
||||
open(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'open', menuId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Programatically 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 {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {Promise} 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 {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {Promise} 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 {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {HTMLIonMenuElement} 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 {boolean} shouldEnable True if it should be swipe-able, false if not.
|
||||
* @param {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {HTMLIonMenuElement} Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
swipeEnable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'swipeEnable', shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {boolean} 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 {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {boolean} 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 {string} [menuId] Optionally get the menu by its id, or side.
|
||||
* @return {HTMLIonMenuElement} Returns the instance of the menu if found, otherwise `null`.
|
||||
*/
|
||||
get(menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'get', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Menu} Returns the instance of the menu already opened, otherwise `null`.
|
||||
*/
|
||||
getOpen(): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'getOpen');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Array<HTMLIonMenuElement>} Returns an array of all menu instances.
|
||||
*/
|
||||
getMenus(): Promise<HTMLIonMenuElement[]> {
|
||||
return proxyMethod(CTRL, 'getMenus');
|
||||
}
|
||||
}
|
||||
22
angular/src/providers/modal-controller.ts
Normal file
22
angular/src/providers/modal-controller.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
|
||||
import { ModalOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
import { AngularDelegate } from './angular-delegate';
|
||||
|
||||
@Injectable()
|
||||
export class ModalController extends OverlayBaseController<ModalOptions, HTMLIonModalElement> {
|
||||
constructor(
|
||||
private cfr: ComponentFactoryResolver,
|
||||
private injector: Injector,
|
||||
private angularDelegate: AngularDelegate,
|
||||
) {
|
||||
super('ion-modal-controller');
|
||||
}
|
||||
|
||||
create(opts?: ModalOptions): Promise<HTMLIonModalElement> {
|
||||
return super.create({
|
||||
...opts,
|
||||
delegate: this.angularDelegate.create(this.cfr, this.injector)
|
||||
});
|
||||
}
|
||||
}
|
||||
34
angular/src/providers/nav-controller.ts
Normal file
34
angular/src/providers/nav-controller.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class NavController {
|
||||
|
||||
private direction = 0;
|
||||
private goBack = false;
|
||||
private stack: string[] = [];
|
||||
|
||||
setGoback() {
|
||||
this.goBack = true;
|
||||
}
|
||||
|
||||
consumeDirection() {
|
||||
if (this.direction === 0) {
|
||||
const index = this.stack.indexOf(document.location.href);
|
||||
if (index === -1) {
|
||||
this.stack.push(document.location.href);
|
||||
this.direction = 1;
|
||||
} else if (index < this.stack.length - 1) {
|
||||
this.stack = this.stack.slice(0, index + 1);
|
||||
this.direction = -1;
|
||||
}
|
||||
}
|
||||
|
||||
const direction = this.goBack
|
||||
? -1
|
||||
: this.direction;
|
||||
|
||||
this.goBack = false;
|
||||
this.direction = 0;
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
10
angular/src/providers/picker-controller.ts
Normal file
10
angular/src/providers/picker-controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PickerOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
|
||||
@Injectable()
|
||||
export class PickerController extends OverlayBaseController<PickerOptions, HTMLIonPickerElement> {
|
||||
constructor() {
|
||||
super('ion-picker-controller');
|
||||
}
|
||||
}
|
||||
22
angular/src/providers/popover-controller.ts
Normal file
22
angular/src/providers/popover-controller.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ComponentFactoryResolver, Injectable, Injector } from '@angular/core';
|
||||
import { PopoverOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
import { AngularDelegate } from './angular-delegate';
|
||||
|
||||
@Injectable()
|
||||
export class PopoverController extends OverlayBaseController<PopoverOptions, HTMLIonPopoverElement> {
|
||||
constructor(
|
||||
private cfr: ComponentFactoryResolver,
|
||||
private injector: Injector,
|
||||
private angularDelegate: AngularDelegate,
|
||||
) {
|
||||
super('ion-popover-controller');
|
||||
}
|
||||
|
||||
create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
||||
return super.create({
|
||||
...opts,
|
||||
delegate: this.angularDelegate.create(this.cfr, this.injector)
|
||||
});
|
||||
}
|
||||
}
|
||||
10
angular/src/providers/toast-controller.ts
Normal file
10
angular/src/providers/toast-controller.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ToastOptions } from '@ionic/core';
|
||||
import { OverlayBaseController } from '../util/overlay';
|
||||
|
||||
@Injectable()
|
||||
export class ToastController extends OverlayBaseController<ToastOptions, HTMLIonToastElement> {
|
||||
constructor() {
|
||||
super('ion-toast-controller');
|
||||
}
|
||||
}
|
||||
12
angular/src/types/interfaces.ts
Normal file
12
angular/src/types/interfaces.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
export interface IonicGlobal {
|
||||
config: any;
|
||||
ael: (elm: any, eventName: string, cb: Function, opts: any) => void;
|
||||
raf: Function;
|
||||
rel: (elm: any, eventName: string, cb: Function, opts: any) => void;
|
||||
}
|
||||
|
||||
export interface IonicWindow extends Window {
|
||||
Ionic: IonicGlobal;
|
||||
__zone_symbol__requestAnimationFrame: Function;
|
||||
}
|
||||
17
angular/src/util/overlay.ts
Normal file
17
angular/src/util/overlay.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { proxyMethod } from '../util/util';
|
||||
|
||||
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 = -1): Promise<void> {
|
||||
return proxyMethod(this.ctrl, 'dismiss', data, role, id);
|
||||
}
|
||||
|
||||
getTop(): Promise<Overlay> {
|
||||
return proxyMethod(this.ctrl, 'getTop');
|
||||
}
|
||||
}
|
||||
22
angular/src/util/util.ts
Normal file
22
angular/src/util/util.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ElementRef } from '@angular/core';
|
||||
|
||||
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 proxyEl(ref: ElementRef, methodName: string, ...args: any[]) {
|
||||
return ref.nativeElement.componentOnReady()
|
||||
.then((el: any) => el[methodName].apply(el, 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;
|
||||
}
|
||||
69
angular/stencil.config.js
Normal file
69
angular/stencil.config.js
Normal file
@@ -0,0 +1,69 @@
|
||||
const path = require('path');
|
||||
|
||||
// use ionic/core's stencil config
|
||||
exports.config = require('../core/stencil.config.js').config;
|
||||
|
||||
// update where to find the original ionic/core src
|
||||
exports.config.srcDir = '../core/src';
|
||||
exports.config.globalScript = '../core/src/global/ionic-global.ts';
|
||||
|
||||
// update the output targets
|
||||
exports.config.outputTargets = [
|
||||
{
|
||||
type: 'angular',
|
||||
directivesProxyFile: 'src/directives/proxies.ts',
|
||||
directivesArrayFile: 'src/directives/proxies-list.txt',
|
||||
empty: false,
|
||||
excludeComponents: [
|
||||
// overlays
|
||||
'ion-action-sheet',
|
||||
'ion-action-sheet-controller',
|
||||
'ion-alert',
|
||||
'ion-alert-controller',
|
||||
'ion-loading',
|
||||
'ion-loading-controller',
|
||||
'ion-modal',
|
||||
'ion-modal-controller',
|
||||
'ion-picker',
|
||||
'ion-picker-controller',
|
||||
'ion-popover',
|
||||
'ion-popover-controller',
|
||||
'ion-toast',
|
||||
'ion-toast-controller',
|
||||
'ion-toast',
|
||||
|
||||
// controllers
|
||||
'ion-menu-controller',
|
||||
'ion-animation-controller',
|
||||
'ion-animation-controller',
|
||||
'ion-gesture-controller',
|
||||
'ion-platform',
|
||||
'ion-cordova-platform',
|
||||
|
||||
// navigation
|
||||
'ion-router',
|
||||
'ion-route',
|
||||
'ion-route-redirect',
|
||||
'ion-router-outlet',
|
||||
'ion-anchor',
|
||||
'ion-tabbar',
|
||||
'ion-tab-button',
|
||||
|
||||
// auxiliar
|
||||
'ion-gesture',
|
||||
'ion-status-tap',
|
||||
'ion-tap-click',
|
||||
'ion-picker-column',
|
||||
'ion-range-knob',
|
||||
'ion-input-shims',
|
||||
'ion-backdrop',
|
||||
'ion-anchor',
|
||||
'ion-virtual-scroll'
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
exports.devServer = {
|
||||
root: '.',
|
||||
watchGlob: ['dist/*.*', 'dist/ionic/**/**', 'src/**/*.html']
|
||||
};
|
||||
@@ -10,7 +10,11 @@
|
||||
"assets": [
|
||||
"assets",
|
||||
"favicon.ico",
|
||||
{ "glob": "**/*", "input": "../node_modules/@ionic/core/dist", "output": "./ionic/core" }
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "../node_modules/@ionic/angular/dist/ionic",
|
||||
"output": "./ionic"
|
||||
}
|
||||
],
|
||||
"index": "index.html",
|
||||
"main": "main.ts",
|
||||
@@ -57,5 +61,8 @@
|
||||
"defaults": {
|
||||
"styleExt": "scss",
|
||||
"component": {}
|
||||
},
|
||||
"warnings": {
|
||||
"typescriptMismatch": false
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,7 @@ module.exports = function(config) {
|
||||
angularCli: {
|
||||
environment: 'dev'
|
||||
},
|
||||
files: [
|
||||
// TODO: I have not fully worked out how this will work.
|
||||
// Perhaps just the base include with a plugin?
|
||||
{ pattern: '../node_modules/@ionic/core/dist/ionic.js', watched: false, served: false, nocache: true, included: true }
|
||||
],
|
||||
files: [],
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@ionic/angular-demo",
|
||||
"version": "0.0.0",
|
||||
"name": "@ionic/angular-test-nav",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
@@ -8,10 +9,8 @@
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"override-router": "rm -rf ./node_modules/@angular/router && mkdir ./node_modules/@angular/router && cp -R ./scripts/router ./node_modules/@angular"
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "latest",
|
||||
"@angular/common": "latest",
|
||||
@@ -23,7 +22,6 @@
|
||||
"@angular/platform-browser-dynamic": "latest",
|
||||
"@angular/router": "latest",
|
||||
"@ionic/angular": "next",
|
||||
"@ionic/core": "next",
|
||||
"body-parser": "^1.18.2",
|
||||
"core-js": "^2.4.1",
|
||||
"express": "^4.16.2",
|
||||
@@ -6,16 +6,14 @@ import { ActionSheetController } from '@ionic/angular';
|
||||
selector: 'app-action-sheet-page',
|
||||
template: `
|
||||
<ion-app>
|
||||
<ion-page class="show-page">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Test</ion-title>
|
||||
<ion-title>Action Sheet</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-button (click)="clickMe()">Open Basic ActionSheet</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</ion-app>
|
||||
`
|
||||
})
|
||||
@@ -25,9 +23,9 @@ export class ActionSheetPageComponent {
|
||||
|
||||
}
|
||||
|
||||
clickMe() {
|
||||
const actionSheet = this.actionSheetController.create({
|
||||
title: 'Albums',
|
||||
async clickMe() {
|
||||
const actionSheet = await this.actionSheetController.create({
|
||||
header: 'Albums',
|
||||
buttons: [{
|
||||
text: 'Delete',
|
||||
role: 'destructive',
|
||||
@@ -1,15 +1,16 @@
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { ActionSheetPageComponent } from './action-sheet-page.component';
|
||||
import { ActionSheetRoutingModule } from './action-sheet-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
ActionSheetRoutingModule
|
||||
],
|
||||
declarations: [ActionSheetPageComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
declarations: [ActionSheetPageComponent]
|
||||
})
|
||||
export class ActionSheetModule { }
|
||||
@@ -6,28 +6,24 @@ import { AlertController } from '@ionic/angular';
|
||||
selector: 'app-alert-page',
|
||||
template: `
|
||||
<ion-app>
|
||||
<ion-page class="show-page">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Test</ion-title>
|
||||
<ion-title>Alert</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-button (click)="clickMe()">Open Basic Alert</ion-button>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</ion-app>
|
||||
`
|
||||
})
|
||||
export class AlertPageComponent {
|
||||
|
||||
constructor(private alertController: AlertController) {
|
||||
constructor(private alertController: AlertController) {}
|
||||
|
||||
}
|
||||
|
||||
clickMe() {
|
||||
const alert = this.alertController.create({
|
||||
title: 'ohhhh snap',
|
||||
async clickMe() {
|
||||
const alert = await this.alertController.create({
|
||||
header: 'ohhhh snap',
|
||||
message: 'Ive been injected via Angular keeping the old api',
|
||||
buttons: [
|
||||
{
|
||||
@@ -45,14 +41,8 @@ export class AlertPageComponent {
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
});
|
||||
alert.present().then(() => {
|
||||
// return alert.dismiss();
|
||||
|
||||
}).then(() => {
|
||||
console.log('dismissed');
|
||||
});
|
||||
return alert.present();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { AlertPageComponent } from './alert-page.component';
|
||||
import { AlertRoutingModule } from './alert-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
AlertRoutingModule
|
||||
],
|
||||
declarations: [AlertPageComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
declarations: [AlertPageComponent]
|
||||
})
|
||||
export class AlertModule { }
|
||||
35
angular/test/nav/src/app/app-routing.module.ts
Normal file
35
angular/test/nav/src/app/app-routing.module.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||
{ path: 'basic-inputs', loadChildren: './basic-inputs-page/basic-inputs-page.module#BasicInputsPageModule' },
|
||||
{ path: 'show-hide-when', loadChildren: './show-hide-when/show-hide-when.module#ShowHideWhenModule' },
|
||||
{ path: 'form-sample', loadChildren: './form-sample-page/form-sample-page.module#FormSamplePageModule' },
|
||||
{ path: 'group-inputs', loadChildren: './group-inputs-page/group-inputs-page.module#GroupInputsPageModule' },
|
||||
{ path: 'home', loadChildren: './home-page/home-page.module#HomePageModule' },
|
||||
{ path: 'alert', loadChildren: './alert/alert.module#AlertModule' },
|
||||
{ path: 'actionSheet', loadChildren: './action-sheet/action-sheet.module#ActionSheetModule' },
|
||||
{ path: 'badge', loadChildren: './badge/badge.module#BadgeModule' },
|
||||
{ path: 'card', loadChildren: './card/card.module#CardModule' },
|
||||
{ path: 'content', loadChildren: './content/content.module#ContentModule' },
|
||||
{ path: 'toast', loadChildren: './toast/toast.module#ToastModule' },
|
||||
{ path: 'loading', loadChildren: './loading/loading.module#LoadingModule' },
|
||||
{ path: 'modal', loadChildren: './modal/modal.module#ModalModule' },
|
||||
{ path: 'ng-if', loadChildren: './ng-if/ng-if.module#NgIfModule' },
|
||||
{ path: 'popover', loadChildren: './popover/popover.module#PopoverModule' },
|
||||
{ path: 'segment', loadChildren: './segment/segment.module#SegmentModule' },
|
||||
{ path: 'virtual-scroll', loadChildren: './virtual-scroll/virtual-scroll.module#VirtualScrollModule' },
|
||||
|
||||
{ path: 'no-routing-nav', loadChildren: './no-routing-nav/no-routing-nav.module#NoRoutingNavModule' },
|
||||
{ path: 'simple-nav', loadChildren: './simple-nav/simple-nav.module#SimpleNavModule' },
|
||||
{ path: 'lazy-load-tabs', loadChildren: './lazy-load-tabs/tabs.module#TabsModule' },
|
||||
{ path: 'simple-tabs', loadChildren: './simple-tabs/tabs.module#TabsModule' },
|
||||
{ path: 'static-tabs', loadChildren: './static-tabs/tabs.module#TabsModule' },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, { enableTracing: true })],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user