mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
2 Commits
v4.0.0-bet
...
v0.0.2-29
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd0ff2caad | ||
|
|
5fff315f6d |
@@ -1,158 +0,0 @@
|
||||
version: 2
|
||||
|
||||
aliases:
|
||||
- &restore-cache
|
||||
keys:
|
||||
- dependency-cache-{{ checksum "package.json" }}-2
|
||||
|
||||
- &save-cache
|
||||
key: dependency-cache-{{ checksum "package.json" }}-2
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
- &restore-cache-core
|
||||
keys:
|
||||
- dependency-cache-{{ checksum "core/package.json" }}-2
|
||||
|
||||
- &save-cache-core
|
||||
key: dependency-cache-{{ checksum "core/package.json" }}-2
|
||||
paths:
|
||||
- core/node_modules
|
||||
|
||||
- &restore-cache-core-stencil
|
||||
keys:
|
||||
- stencil-cache-1
|
||||
|
||||
- &save-cache-core-stencil
|
||||
key: stencil-cache-1
|
||||
paths:
|
||||
- core/.stencil
|
||||
- core/screenshot/images
|
||||
|
||||
defaults: &defaults
|
||||
docker:
|
||||
- image: circleci/node:latest-browsers
|
||||
working_directory: /tmp/workspace
|
||||
|
||||
jobs:
|
||||
build:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache: *restore-cache
|
||||
- run: npm install
|
||||
- save_cache: *save-cache
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- "*"
|
||||
|
||||
build-core:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- restore_cache: *restore-cache-core
|
||||
- restore_cache: *restore-cache-core-stencil
|
||||
- run:
|
||||
command: npm install
|
||||
working_directory: /tmp/workspace/core
|
||||
- save_cache: *save-cache-core
|
||||
- run:
|
||||
command: npm run build # --max-workers 1 --debug
|
||||
working_directory: /tmp/workspace/core
|
||||
- save_cache: *save-cache-core-stencil
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
paths:
|
||||
- "*"
|
||||
|
||||
test-core-clean-build:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Checking clean build
|
||||
command: git diff --exit-code
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-lint:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run lint
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-spec:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run test.spec
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-treeshake:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
command: npm run test.treeshake
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-screenshot:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Run Screenshot
|
||||
command: npx stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci || true
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
test-core-screenshot-master:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Run Screenshot
|
||||
command: npx stencil test --e2e --screenshot --screenshot-connector=scripts/screenshot/ci.js --ci --update-screenshot || true
|
||||
working_directory: /tmp/workspace/core
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build:
|
||||
jobs:
|
||||
- build
|
||||
- build-core:
|
||||
requires: [build]
|
||||
- test-core-clean-build:
|
||||
requires: [build-core]
|
||||
- test-core-lint:
|
||||
requires: [build-core]
|
||||
- test-core-spec:
|
||||
requires: [build-core]
|
||||
- test-core-treeshake:
|
||||
requires: [build-core]
|
||||
- test-core-screenshot:
|
||||
requires: [build-core]
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
- test-core-screenshot-master:
|
||||
requires: [build-core]
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
12
.github/CONTRIBUTING.md
vendored
12
.github/CONTRIBUTING.md
vendored
@@ -52,16 +52,20 @@ Please see our [Contributor Code of Conduct](https://github.com/ionic-team/ionic
|
||||
|
||||
#### Sass Changes
|
||||
|
||||
1. After any changes to the Sass files run [stylelint](https://stylelint.io/):
|
||||
- Switch to the `core` directory
|
||||
- Run `npm run lint.sass` and manually fix the errors or `npm run lint.fix` to autofix the errors
|
||||
1. If the css property is something that the user may want to override and it won't break the component layout, it should be given a Sass variable. See our [doc on naming Sass variables](https://docs.google.com/document/d/1OyOyrRE5lpB_9mdkF0HWVQLV97fHma450N8XqE4mjZQ/edit?usp=sharing).
|
||||
2. After any changes to the Sass files run the [Sass Linter](https://github.com/brigade/scss-lint):
|
||||
- Requires [Ruby](https://www.ruby-lang.org/en/documentation/installation/). **Skip this step entirely if you are unable to install Ruby.**
|
||||
- Install the linter: `gem install scss_lint`
|
||||
- Make sure to run the linter at the root of the repository.
|
||||
- Run `gulp lint.sass` and fix any linter errors.
|
||||
|
||||
|
||||
#### Viewing Changes
|
||||
|
||||
1. Run the gulp e2e task to build all tests: `gulp e2e`
|
||||
2. Run the gulp e2e.watch task to watch your specific test (replace `button` with the component you are modifying and `basic` with the test folder): `gulp e2e.watch --f=button/basic`
|
||||
3. A browser should open at `http://localhost:8080/dist/e2e`. From here, navigate to the component you are changing.
|
||||
4. If your changes look good, you're ready to [commit](#commit-message-format)!
|
||||
4. If your changes look good, you're ready to [commit](#committing)!
|
||||
|
||||
|
||||
#### Adding Documentation
|
||||
|
||||
34
.github/ISSUE_TEMPLATE.md
vendored
34
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,17 +1,12 @@
|
||||
<!-- 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")
|
||||
(For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
(For Ionic 2.x & 3.x issues, please use https://github.com/ionic-team/ionic-v3)
|
||||
[ ] **4.x**
|
||||
[ ] **1.x** (For Ionic 1.x issues, please use https://github.com/ionic-team/ionic-v1)
|
||||
[ ] **2.x**
|
||||
[ ] **3.x**
|
||||
|
||||
**I'm submitting a ...** (check one with "x")
|
||||
[ ] bug report
|
||||
[ ] feature request
|
||||
|
||||
<!-- 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/ -->
|
||||
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
|
||||
|
||||
**Current behavior:**
|
||||
<!-- Describe how the bug manifests. -->
|
||||
@@ -20,22 +15,17 @@
|
||||
<!-- Describe what the behavior would be without the bug. -->
|
||||
|
||||
**Steps to reproduce:**
|
||||
<!-- Please explain the steps required to duplicate the issue, especially if you are able to provide a sample application. -->
|
||||
<!-- 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
|
||||
-->
|
||||
|
||||
**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 short code snippets here
|
||||
insert any relevant code here
|
||||
```
|
||||
|
||||
**Other information:**
|
||||
@@ -46,3 +36,5 @@ insert short code snippets here
|
||||
```
|
||||
insert the output from ionic info here
|
||||
```
|
||||
|
||||
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/Custom.md
vendored
9
.github/ISSUE_TEMPLATE/Custom.md
vendored
@@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Support Question
|
||||
about: Question on how to use this project
|
||||
|
||||
---
|
||||
|
||||
# Support Question
|
||||
|
||||
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/
|
||||
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,39 +0,0 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
|
||||
|
||||
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
|
||||
-->
|
||||
|
||||
# Bug Report
|
||||
|
||||
**Ionic Info**
|
||||
Run `ionic info` from a terminal/cmd prompt and paste the output below.
|
||||
|
||||
```
|
||||
insert the output from ionic info here
|
||||
```
|
||||
|
||||
**Describe the Bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Steps to Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Related Code**
|
||||
If you are able to illustrate the bug with an example, please provide a sample application via an online code collaborator such as [StackBlitz](https://stackblitz.com), or [GitHub](https://github.com).
|
||||
|
||||
**Expected Behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Additional Context**
|
||||
List any other information that is relevant to your issue. Stack traces, related issues, suggestions on how to fix, Stack Overflow links, forum links, screenshots, OS if applicable, etc.
|
||||
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,35 +0,0 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
|
||||
|
||||
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
|
||||
-->
|
||||
|
||||
# Feature Request
|
||||
|
||||
**Ionic Info**
|
||||
Run `ionic info` from a terminal/cmd prompt and paste the output below.
|
||||
|
||||
```
|
||||
insert the output from ionic info here
|
||||
```
|
||||
|
||||
**Describe the Feature Request**
|
||||
A clear and concise description of what the feature request is. Please include if your feature request is related to a problem.
|
||||
|
||||
**Describe Preferred Solution**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe Alternatives**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Related Code**
|
||||
If you are able to illustrate the feature request with an example, please provide a sample application via an online code collaborator such as [StackBlitz](https://stackblitz.com), or [GitHub](https://github.com).
|
||||
|
||||
**Additional Context**
|
||||
List any other information that is relevant to your issue. Stack traces, related issues, suggestions on how to add, use case, Stack Overflow links, forum links, screenshots, OS if applicable, etc.
|
||||
166
.github/PROCESS.md
vendored
166
.github/PROCESS.md
vendored
@@ -1,166 +0,0 @@
|
||||
# Process
|
||||
|
||||
This document is to describe the internal process that the Ionic team uses for issue management and project planning.
|
||||
|
||||
## Table of contents
|
||||
* [Project Boards](#project-boards)
|
||||
* [Managing Issues](#managing-issues)
|
||||
* [Workflow](#workflow)
|
||||
|
||||
## Project Boards
|
||||
|
||||
The project boards are located under the `Projects` tab in GitHub: https://github.com/ionic-team/ionic/projects/
|
||||
|
||||
### Core Project Board
|
||||
|
||||
The `Core` project board contains issues related to the `@ionic/core` package. A description of each column is below.
|
||||
|
||||
#### Backlog :robot:
|
||||
|
||||
Contains up to 20 issues that are important to work on soon but we don't think we can fit in the current sprint. If we finish everything we planned for the week we can pull from this column. Issues will automatically move to this column when they are added to the project board.
|
||||
|
||||
#### On Deck :baseball:
|
||||
|
||||
Contains issues that we believe we can accomplish in the current sprint. Issues should be manually moved to this column when we have our sprint planning meeting.
|
||||
|
||||
#### In Progress :person_fencing:
|
||||
|
||||
Issues and pull requests that are currently being worked on. Issues should be manually moved to this column and assigned to yourself when you begin working on them. Pull requests are automatically added to this column when added to the project board.
|
||||
|
||||
#### Needs Review :thinking:
|
||||
|
||||
Issues and pull requests that need review. Pull requests will automatically move here when a reviewer requests changes, or it no longer meets the minimum number of required approving reviews.
|
||||
|
||||
#### Done :tada:
|
||||
|
||||
Issues and pull requests that are completed. Issues will automatically move here when they are closed. Pull requests will automatically moved here when they are merged or closed with unmerged commits.
|
||||
|
||||
## Managing Issues
|
||||
|
||||
### Issues to Triage
|
||||
|
||||
The issues that need to be triaged all have the `triage` label. In many cases the issue can be automatically processed by the Ionic Issue Bot by applying a specific label.
|
||||
|
||||
Once another label is applied to the issue, the `triage` label is automatically be removed by the bot.
|
||||
|
||||
### Wrong Repo
|
||||
|
||||
If an issue does not pertain to the Ionic Framework but does pertain to another repo, it should be moved to that repo. The bot has been set up to automatically create the issue in other repositories while closing and locking the issue in this repository. Use one of the following labels to perform that action:
|
||||
|
||||
- ionitron: cli
|
||||
- ionitron: docs
|
||||
- ionitron: stencil
|
||||
- ionitron: native
|
||||
|
||||
### Ionic Pro Issues
|
||||
|
||||
If the issue is associated with Ionic Pro the submitter should be told to use the [Ionic Pro Support Forum](https://ionic.zendesk.com/hc/en-us/requests/new). The issue should be closed and locked. Use the `ionitron: ionic pro` label to accomplish this.
|
||||
|
||||
### Support Questions
|
||||
|
||||
If the issue is a support question, the submitter should be redirected to our [forum](https://forum.ionicframework.com) or [slack channel](https://ionicworldwide.herokuapp.com/). The issue should be closed and locked. Use the `ionitron: support` label to accomplish this.
|
||||
|
||||
### Incomplete Template
|
||||
|
||||
If the issue template has not been filled out completely, the issue should be closed and locked. The submitter should be informed top re-submit the issue making sure they fill the form out completely. Use the `ionitron: missing template` label to accomplish this.
|
||||
|
||||
### Issues with Open Questions
|
||||
|
||||
In many cases, the template is mostly filled out but just missing a thing or two or you may have a question or need clarification. In such a case, the submitter should be asked to supply that information.
|
||||
|
||||
1. create a comment requesting the additional information or clarification
|
||||
1. add the `needs reply` label to the task
|
||||
|
||||
NOTE: be sure to perform those actions in the order stated. If you add the comment second it will trigger the removal of the label.
|
||||
|
||||
If there is a response to the question, the bot will remove the `needs reply` and apply the `triage` label. The issue will then go through the triage handling again.
|
||||
|
||||
if there is no response within 30 days, the issue will be closed and locked.
|
||||
|
||||
## Workflow
|
||||
|
||||
We have two long-living branches:
|
||||
|
||||
- `master`: completed features, bug fixes, refactors, chores
|
||||
- `stable`: the latest release
|
||||
|
||||
### Examples
|
||||
|
||||
#### Making a Change
|
||||
|
||||
1. Create a branch from `master`.
|
||||
1. Make changes. Limit your changes to a "unit of work", meaning don't include irrelevant changes that may confuse and delay the change.
|
||||
1. Push changes.
|
||||
1. Create a PR with the base of `master`.
|
||||
1. Have someone approve your change (optional right now--at your discretion).
|
||||
|
||||
<img width="236" alt="image" src="https://user-images.githubusercontent.com/236501/47031893-913e0480-d136-11e8-9d9a-4b6297a4d7ba.png">
|
||||
|
||||
1. Wait for status checks to succeed. Fix errors if any occur.
|
||||
|
||||
<img width="223" alt="All checks have passed" src="https://user-images.githubusercontent.com/236501/47031830-62c02980-d136-11e8-9055-08af1b717304.png">
|
||||
|
||||
1. Click **Squash and merge**. Use the dropdown to select this option if necessary.
|
||||
|
||||
<img width="192" alt="Squash and merge button" src="https://user-images.githubusercontent.com/236501/47031620-da418900-d135-11e8-91ff-e84f2478b2b3.png">
|
||||
|
||||
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `master` become permanent.
|
||||
|
||||
<img width="672" alt="Squash and merge confirmation" src="https://user-images.githubusercontent.com/236501/47031753-31dff480-d136-11e8-9116-03934961bdc2.png">
|
||||
|
||||
1. Confirm squash and merge into `master`.
|
||||
|
||||
#### Merging Changes from `master` into your Branch
|
||||
|
||||
1. Pull the latest changes locally.
|
||||
1. Merge the changes, fixing any conflicts.
|
||||
1. Push the merged changes.
|
||||
|
||||
OR
|
||||
|
||||
1. Click **Update branch** on the PR:
|
||||
|
||||
<img width="672" alt="Update branch button" src="https://user-images.githubusercontent.com/236501/47032205-66a07b80-d137-11e8-8c9b-ee37d2d147c9.png">
|
||||
|
||||
1. Pull the merged changes locally.
|
||||
|
||||
#### Making a Release
|
||||
|
||||
1. Freeze `master`. Only the person doing the release should be modifying `master`.
|
||||
1. Follow the [Making a Change](#making-a-change) steps to prepare the release.
|
||||
|
||||
- Run `npm run release.prepare`
|
||||
- Version changes
|
||||
- `CHANGELOG.MD` tweaks
|
||||
|
||||
1. Create a PR to merge `master` into `stable`.
|
||||
1. Click **Merge pull request**. Use the dropdown to select this option if necessary. This will preserve the commit history from `master` by creating a merge commit.
|
||||
|
||||
<img width="191" alt="Merge pull request button" src="https://user-images.githubusercontent.com/236501/47032669-8be1b980-d138-11e8-9a90-d1518c223184.png">
|
||||
|
||||
1. CI builds `stable`, performing the release.
|
||||
1. Unfreeze `master`.
|
||||
|
||||
#### Hotfixes
|
||||
|
||||
Hotfixes bypass `master` and should only be used for urgent fixes that can't wait for the next release to be ready.
|
||||
|
||||
1. Create a branch from `stable`.
|
||||
1. Make changes.
|
||||
1. Run `npm run release.prepare`.
|
||||
1. Push changes.
|
||||
1. Create a PR, making sure the PR will merge into `stable`.
|
||||
1. Click **Squash and merge**. Use the dropdown to select this option if necessary.
|
||||
|
||||
<img width="192" alt="Squash and merge button" src="https://user-images.githubusercontent.com/236501/47031620-da418900-d135-11e8-91ff-e84f2478b2b3.png">
|
||||
|
||||
1. During confirmation, rewrite the commit message using our [Commit Message Format guidelines](https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format). Keep the `(#1234)` at the end; it will create a link to the PR in the commit history and `CHANGELOG.md`. This is where commits on `master` become permanent.
|
||||
|
||||
<img width="672" alt="Squash and merge confirmation" src="https://user-images.githubusercontent.com/236501/47031753-31dff480-d136-11e8-9116-03934961bdc2.png">
|
||||
|
||||
1. Confirm squash and merge into `stable`.
|
||||
1. CI builds `stable`, performing the release.
|
||||
1. Create a PR to merge `stable` into `master`.
|
||||
1. Click **Merge pull request**. Use the dropdown to select this option if necessary.
|
||||
|
||||
<img width="191" alt="Merge pull request button" src="https://user-images.githubusercontent.com/236501/47032669-8be1b980-d138-11e8-9a90-d1518c223184.png">
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -7,6 +7,6 @@
|
||||
-
|
||||
-
|
||||
|
||||
**Ionic Version**:
|
||||
**Ionic Version**: 1.x / 2.x / 3.x
|
||||
|
||||
**Fixes**: #
|
||||
|
||||
144
.github/ionic-issue-bot.yml
vendored
144
.github/ionic-issue-bot.yml
vendored
@@ -1,147 +1,29 @@
|
||||
triage:
|
||||
label: triage
|
||||
removeLabelWhenProjectAssigned: true
|
||||
dryRun: false
|
||||
|
||||
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: ionic pro"
|
||||
message: >
|
||||
Thanks for the issue! This issue appears to be related to Ionic Pro. We use this issue tracker exclusively for
|
||||
bug reports and feature requests. Please use the [Ionic Pro Support Forum](https://ionic.zendesk.com/hc/en-us/requests/new)
|
||||
to report this issue.
|
||||
|
||||
|
||||
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
|
||||
|
||||
lockClosed:
|
||||
days: 30
|
||||
maxIssuesPerRun: 100
|
||||
support:
|
||||
label: support
|
||||
message: >
|
||||
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue.
|
||||
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.
|
||||
dryRun: false
|
||||
|
||||
stale:
|
||||
days: 365
|
||||
maxIssuesPerRun: 100
|
||||
exemptLabels:
|
||||
- good first issue
|
||||
- triage
|
||||
exemptAssigned: true
|
||||
exemptProjects: true
|
||||
exemptMilestones: true
|
||||
label: "ionitron: stale issue"
|
||||
message: >
|
||||
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.
|
||||
|
||||
|
||||
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!
|
||||
close: true
|
||||
lock: true
|
||||
dryRun: false
|
||||
|
||||
noReply:
|
||||
days: 30
|
||||
maxIssuesPerRun: 100
|
||||
label: needs reply
|
||||
responseLabel: triage
|
||||
exemptProjects: true
|
||||
exemptMilestones: true
|
||||
incomplete:
|
||||
label: missing template
|
||||
message: >
|
||||
Thanks for the issue! This issue is being closed due to the lack of a reply. If this is still
|
||||
an issue with the latest version of Ionic, please create a new issue and ensure the
|
||||
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
|
||||
|
||||
labelPullRequest:
|
||||
labels:
|
||||
- label: angular
|
||||
branch: master
|
||||
path: ^angular
|
||||
- label: core
|
||||
branch: master
|
||||
path: ^core
|
||||
dryRun: false
|
||||
|
||||
wrongRepo:
|
||||
repos:
|
||||
- label: "ionitron: v3"
|
||||
repo: ionic-v3
|
||||
message: >
|
||||
Thanks for the issue! We have moved the source code and issues for Ionic 3 into a separate repository.
|
||||
I am moving this issue to the repository for Ionic 3. Please track this issue over there.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
- 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!
|
||||
- label: "ionitron: docs"
|
||||
repo: ionic-docs
|
||||
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 Documentation.
|
||||
I am moving this issue to the Ionic Docs repository. Please track this issue over there.
|
||||
|
||||
|
||||
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!
|
||||
- label: "ionitron: native"
|
||||
repo: ionic-native
|
||||
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 Ionic Native.
|
||||
I am moving this issue to the Ionic Native repository. Please track this issue over there.
|
||||
|
||||
|
||||
Thank you for using Ionic!
|
||||
close: true
|
||||
lock: true
|
||||
dryRun: false
|
||||
|
||||
screenshot:
|
||||
appId: 18001
|
||||
checkName: "build"
|
||||
baseUrl: "https://screenshot.ionicframework.com"
|
||||
dryRun: false
|
||||
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
@@ -18,10 +18,8 @@ dist/
|
||||
node_modules/
|
||||
tmp/
|
||||
temp/
|
||||
core/theme-builder/
|
||||
core/test-components/
|
||||
core/css/
|
||||
angular/css/
|
||||
packages/core/theme-builder/
|
||||
packages/core/test-components/
|
||||
$RECYCLE.BIN/
|
||||
|
||||
.DS_Store
|
||||
@@ -36,7 +34,7 @@ scripts/e2e/webpackEntryPoints.json
|
||||
scripts/build/e2e-generated-tsconfig.json
|
||||
*.css.ts
|
||||
|
||||
stats.json
|
||||
stencil-stats.json
|
||||
|
||||
# demo stuff
|
||||
demos/node_modules
|
||||
@@ -49,9 +47,3 @@ demos/src/**/*.ngfactory.ts
|
||||
demos/src/**/*.d.ts
|
||||
demos/src/**/*.metadata.json
|
||||
demos/src/**/*.css.shim.ts
|
||||
|
||||
# stencil
|
||||
angular/css/
|
||||
core/css/
|
||||
core/loader/
|
||||
.stencil/
|
||||
@@ -1,26 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,15 +0,0 @@
|
||||
const common = require('./common');
|
||||
const Listr = require('listr');
|
||||
|
||||
|
||||
async function main() {
|
||||
const tasks = [];
|
||||
common.packages.forEach(package => {
|
||||
common.preparePackage(tasks, package);
|
||||
});
|
||||
|
||||
const listr = new Listr(tasks, { showSubtasks: true });
|
||||
await listr.run();
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,164 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const execa = require('execa');
|
||||
const Listr = require('listr');
|
||||
const semver = require('semver');
|
||||
const tc = require('turbocolor');
|
||||
|
||||
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));
|
||||
|
||||
|
||||
function preparePackage(tasks, package, version) {
|
||||
const projectRoot = projectPath(package);
|
||||
const pkg = readPkg(package);
|
||||
|
||||
const projectTasks = [];
|
||||
if (version) {
|
||||
projectTasks.push({
|
||||
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}\``);
|
||||
}
|
||||
}
|
||||
});
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: install npm dependencies`,
|
||||
task: async () => {
|
||||
await fs.remove(path.join(projectRoot, 'node_modules'))
|
||||
await execa('npm', ['i'], { cwd: projectRoot });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (package !== 'core') {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: npm link @ionic/core`,
|
||||
task: () => execa('npm', ['link', '@ionic/core'], { cwd: projectRoot })
|
||||
});
|
||||
if (version) {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: update ionic/core dep to ${version}`,
|
||||
task: () => {
|
||||
updateDependency(pkg, "@ionic/core", version);
|
||||
writePkg(package, pkg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (version) {
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: lint`,
|
||||
task: () => execa('npm', ['run', 'lint'], { cwd: projectRoot })
|
||||
});
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: test`,
|
||||
task: () => execa('npm', ['test'], { cwd: projectRoot })
|
||||
});
|
||||
}
|
||||
|
||||
projectTasks.push({
|
||||
title: `${pkg.name}: build`,
|
||||
task: () => execa('npm', ['run', 'build'], { 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 ${tc.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 isVersionGreater(oldVersion, newVersion) {
|
||||
if (!isValidVersion(newVersion)) {
|
||||
throw new Error('Version should be a valid semver version.');
|
||||
}
|
||||
|
||||
return semver.gt(newVersion, oldVersion);
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
isValidVersion,
|
||||
isVersionGreater,
|
||||
readPkg,
|
||||
writePkg,
|
||||
rootDir,
|
||||
projectPath,
|
||||
checkGit,
|
||||
packages,
|
||||
preparePackage
|
||||
};
|
||||
@@ -1,223 +0,0 @@
|
||||
/**
|
||||
* Deploy script adopted from https://github.com/sindresorhus/np
|
||||
* MIT License (c) Sindre Sorhus (sindresorhus.com)
|
||||
*/
|
||||
const tc = require('turbocolor');
|
||||
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 {
|
||||
if (!process.env.GH_TOKEN) {
|
||||
throw new Error('env.GH_TOKEN is undefined');
|
||||
}
|
||||
|
||||
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', tc.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 (!common.isVersionGreater(oldVersion, input)) {
|
||||
return `Version must be greater than ${oldVersion}`;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: answers => {
|
||||
return `Will bump from ${tc.cyan(oldVersion)} to ${tc.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 => {
|
||||
common.preparePackage(tasks, package, version);
|
||||
});
|
||||
|
||||
// add update package.json of each project
|
||||
packages.forEach(package => {
|
||||
updatePackageVersion(tasks, package, version);
|
||||
});
|
||||
|
||||
// generate changelog
|
||||
generateChangeLog(tasks);
|
||||
|
||||
// update core readme with version number
|
||||
updateCoreReadme(tasks, version);
|
||||
|
||||
const listr = new Listr(tasks, { showSubtasks: true });
|
||||
await listr.run();
|
||||
}
|
||||
|
||||
|
||||
function validateGit(tasks, version) {
|
||||
tasks.push(
|
||||
{
|
||||
title: `Validate git tag ${tc.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 updatePackageVersion(tasks, package, version) {
|
||||
const projectRoot = common.projectPath(package);
|
||||
const pkg = common.readPkg(package);
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `${pkg.name}: update package.json ${tc.dim(`(${version})`)}`,
|
||||
task: async () => {
|
||||
await execa('npm', ['version', version], { cwd: projectRoot });
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function generateChangeLog(tasks) {
|
||||
tasks.push({
|
||||
title: `Generate CHANGELOG.md`,
|
||||
task: () => execa('npm', ['run', 'changelog'], { cwd: common.rootDir }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function updateCoreReadme(tasks, version) {
|
||||
tasks.push({
|
||||
title: `Update core README.md`,
|
||||
task: () => execa('node', ['update-readme.js', version], { cwd: path.join(common.rootDir, 'core', 'scripts') }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const SEMVER_INCREMENTS = ['patch', 'minor', 'major'];
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
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(`${tc.dim.cyan(newVersion[i])}`);
|
||||
firstVersionChange = true;
|
||||
} else if (newVersion[i].indexOf('-') >= 1) {
|
||||
let preVersion = [];
|
||||
preVersion = newVersion[i].split('-');
|
||||
output.push(`${tc.dim.cyan(`${preVersion[0]}-${preVersion[1]}`)}`);
|
||||
} else {
|
||||
output.push(tc.reset.dim(newVersion[i]));
|
||||
}
|
||||
}
|
||||
return output.join(tc.reset.dim('.'));
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,135 +0,0 @@
|
||||
/**
|
||||
* Deploy script adopted from https://github.com/sindresorhus/np
|
||||
* MIT License (c) Sindre Sorhus (sindresorhus.com)
|
||||
*/
|
||||
const tc = require('turbocolor');
|
||||
const execa = require('execa');
|
||||
const Listr = require('listr');
|
||||
const octokit = require('@octokit/rest')()
|
||||
const common = require('./common');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
if (!process.env.GH_TOKEN) {
|
||||
throw new Error('env.GH_TOKEN is undefined');
|
||||
}
|
||||
|
||||
const tasks = [];
|
||||
const { version } = common.readPkg('core');
|
||||
const changelog = findChangelog();
|
||||
|
||||
// repo must be clean
|
||||
common.checkGit(tasks);
|
||||
|
||||
// publish each package in NPM
|
||||
publishPackages(tasks, common.packages, version);
|
||||
|
||||
// push tag to git remote
|
||||
publishGit(tasks, version, changelog);
|
||||
|
||||
const listr = new Listr(tasks);
|
||||
await listr.run();
|
||||
console.log(`\nionic ${version} published!! 🎉\n`);
|
||||
|
||||
} catch (err) {
|
||||
console.log('\n', tc.red(err), '\n');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function publishPackages(tasks, packages, version) {
|
||||
// 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 })
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function publishGit(tasks, version, changelog) {
|
||||
const tag = `v${version}`;
|
||||
|
||||
tasks.push(
|
||||
{
|
||||
title: `Tag latest commit ${tc.dim(`(${tag})`)}`,
|
||||
task: () => execa('git', ['tag', `${tag}`], { cwd: common.rootDir })
|
||||
},
|
||||
{
|
||||
title: 'Push branches to remote',
|
||||
task: () => execa('git', ['push'], { cwd: common.rootDir })
|
||||
},
|
||||
{
|
||||
title: 'Push tags to remove',
|
||||
task: () => execa('git', ['push', '--tags'], { cwd: common.rootDir })
|
||||
},
|
||||
{
|
||||
title: 'Publish Github release',
|
||||
task: () => publishGithub(version, tag, changelog)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function findChangelog() {
|
||||
const lines = fs.readFileSync('CHANGELOG.md', 'utf-8').toString().split('\n');
|
||||
let start = -1;
|
||||
let end = -1;
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line.startsWith('# [')) {
|
||||
if (start === -1) {
|
||||
start = i + 1;
|
||||
} else {
|
||||
end = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(start === -1 || end === -1) {
|
||||
throw new Error('changelog diff was not found');
|
||||
}
|
||||
return lines.slice(start, end).join('\n').trim();
|
||||
}
|
||||
|
||||
async function publishGithub(version, tag, changelog) {
|
||||
octokit.authenticate({
|
||||
type: 'oauth',
|
||||
token: process.env.GH_TOKEN
|
||||
});
|
||||
|
||||
await octokit.repos.createRelease({
|
||||
owner: 'ionic-team',
|
||||
repo: 'ionic',
|
||||
target_commitish: 'master',
|
||||
tag_name: tag,
|
||||
name: version,
|
||||
body: changelog,
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
18
.scss-linters/default_rule.rb
Normal file
18
.scss-linters/default_rule.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module SCSSLint
|
||||
# Reports the use of !default at the end of variable declarations.
|
||||
class Linter::DefaultRule < Linter
|
||||
include LinterRegistry
|
||||
|
||||
def visit_function(node)
|
||||
return true
|
||||
end
|
||||
|
||||
def visit_variable(node)
|
||||
return if source_from_range(node.source_range).include?('!default')
|
||||
|
||||
return unless node_ancestor(node, 2).nil?
|
||||
|
||||
add_lint(node, '!default should be used')
|
||||
end
|
||||
end
|
||||
end
|
||||
907
BREAKING.md
907
BREAKING.md
@@ -1,3 +1,908 @@
|
||||
|
||||
# Breaking Changes
|
||||
|
||||
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).
|
||||
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`. |
|
||||
|
||||
1387
CHANGELOG.md
1387
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
21
README.md
21
README.md
@@ -6,15 +6,11 @@ build top quality native and progressive web apps with web technologies.
|
||||
Ionic is based on [Web Components](https://www.webcomponents.org/introduction) and comes with many significant performance, usability, and feature improvements over the past versions.
|
||||
|
||||
|
||||
### Packages
|
||||
# Packages
|
||||
|
||||
| Project | Package | Version | Links |
|
||||
| ------- | ------- | ------- |:-----:|
|
||||
| **Core** | [`@ionic/core`](https://www.npmjs.com/package/@ionic/core) | [](https://www.npmjs.com/package/@ionic/core) | [`README.md`](core/README.md)
|
||||
| **Angular** | [`@ionic/angular`](https://www.npmjs.com/package/@ionic/angular) | [](https://www.npmjs.com/package/@ionic/angular) | [`README.md`](angular/README.md)
|
||||
| **Vue** | `@ionic/vue` | | [`README.md`](vue/README.md)
|
||||
- [Core](packages/core/README.md)
|
||||
- [Ionic Angular](packages/ionic-angular/README.md)
|
||||
|
||||
Looking for the `ionic-angular` package? Ionic 3 has been moved to the [`ionic-v3`](https://github.com/ionic-team/ionic-v3) repo. See [Earlier Versions](#earlier-versions).
|
||||
|
||||
### Getting Started
|
||||
|
||||
@@ -41,9 +37,12 @@ It is the perfect starting point for learning and building your own app.
|
||||
|
||||
As Ionic components migrate to the web component standard, a goal of ours is to have Ionic components easily work within all of the popular frameworks.
|
||||
|
||||
### Earlier Versions
|
||||
[](https://badge.fury.io/js/ionic-angular)
|
||||
[](https://circleci.com/gh/ionic-team/ionic)
|
||||
[](https://www.codetriage.com/ionic-team/ionic)
|
||||
|
||||
The source code for earlier versions of the Ionic Framework may exist in other repositories. Please open issues and pull requests in their respective repositories.
|
||||
|
||||
* **Ionic 2/3**: Moved to [`ionic-team/ionic-v3`](https://github.com/ionic-team/ionic-v3)
|
||||
* **Ionic 1**: Moved to [`ionic-team/ionic-v1`](https://github.com/ionic-team/ionic-v1)
|
||||
### Ionic V1
|
||||
|
||||
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.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
package-lock=false
|
||||
1590
angular/BREAKING.md
1590
angular/BREAKING.md
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
# @ionic/angular
|
||||
|
||||
Ionic Angular specific building blocks on top of [@ionic/core](https://www.npmjs.com/package/@ionic/core) components.
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
* [Ionic Core Components](https://www.npmjs.com/package/@ionic/core)
|
||||
* [Ionic Documentation](https://ionicframework.com/docs/)
|
||||
* [Ionic Worldwide Slack](http://ionicworldwide.herokuapp.com/)
|
||||
* [Ionic Forum](https://forum.ionicframework.com/)
|
||||
* [Ionicons](http://ionicons.com/)
|
||||
* [Stencil](https://stenciljs.com/)
|
||||
* [Stencil Worldwide Slack](https://stencil-worldwide.herokuapp.com/)
|
||||
* [Capacitor](https://capacitor.ionicframework.com/)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
* [MIT](https://raw.githubusercontent.com/ionic-team/ionic/master/LICENSE)
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"name": "@ionic/angular",
|
||||
"version": "4.0.0-beta.14",
|
||||
"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 build.core && npm run build.ng && npm run clean-generated",
|
||||
"build.dev": "npm run clean && npm run build.core.dev && npm run build.ng && npm run clean-generated",
|
||||
"build.core": "node scripts/build-core.js",
|
||||
"build.core.dev": "node scripts/build-core.js --dev",
|
||||
"build.link": "npm run build && node scripts/link-copy.js",
|
||||
"build.ng": "./node_modules/.bin/ngc",
|
||||
"clean": "node scripts/clean.js",
|
||||
"clean-generated": "node ./scripts/clean-generated.js",
|
||||
"lint": "echo TODO",
|
||||
"lint.ts": "tslint --project .",
|
||||
"lint.fix": "tslint --project . --fix",
|
||||
"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"
|
||||
},
|
||||
"module": "dist/index.js",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/",
|
||||
"css/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ionic/core": "4.0.0-beta.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/common": "^6.1.0",
|
||||
"@angular/compiler": "^6.1.0",
|
||||
"@angular/compiler-cli": "^6.1.0",
|
||||
"@angular/core": "^6.1.0",
|
||||
"@angular/forms": "^6.1.0",
|
||||
"@angular/platform-browser": "^6.1.0",
|
||||
"@angular/platform-browser-dynamic": "^6.1.0",
|
||||
"@angular/router": "^6.1.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
"glob": "^7.1.2",
|
||||
"rxjs": "^6.2.0",
|
||||
"tslint": "^5.10.0",
|
||||
"tslint-ionic-rules": "0.0.17",
|
||||
"typescript": "2.9.2",
|
||||
"zone.js": "^0.8.26"
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
# Local @ionic/angular test/testapp development
|
||||
|
||||
1. `npm install` at the root of `angular`
|
||||
2. `npm run build.dev` to build local `@ionic/angular` and `@ionic/core`
|
||||
3. `cd test/testapp` to the test app
|
||||
4. `npm install` in the test app directory
|
||||
5. `npm run serve` copies packages and serve the app (see package.json for more options)
|
||||
6. [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.
|
||||
24
angular/scripts/build-core.js
vendored
24
angular/scripts/build-core.js
vendored
@@ -1,24 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const spawn = require('child_process').spawn;
|
||||
|
||||
const stencilPath = path.join(__dirname, '..', '..', 'core', 'node_modules', '.bin');
|
||||
|
||||
function copyIonicons() {
|
||||
const src = path.join(__dirname, '..', '..', 'core', 'node_modules', 'ionicons');
|
||||
const dst = path.join(__dirname, '..', 'node_modules', 'ionicons');
|
||||
|
||||
fs.removeSync(dst);
|
||||
fs.copySync(src, dst);
|
||||
}
|
||||
|
||||
function copyCSS() {
|
||||
const src = path.join(__dirname, '..', '..', 'core', 'css');
|
||||
const dst = path.join(__dirname, '..', 'css');
|
||||
|
||||
fs.removeSync(dst);
|
||||
fs.copySync(src, dst);
|
||||
}
|
||||
|
||||
copyIonicons();
|
||||
copyCSS();
|
||||
42
angular/scripts/clean-generated.js
vendored
42
angular/scripts/clean-generated.js
vendored
@@ -1,42 +0,0 @@
|
||||
const path = require('path');
|
||||
const cwd = process.cwd();
|
||||
|
||||
const glob = require('glob');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const distDir = path.join(__dirname, '../dist');
|
||||
|
||||
const distGeneratedNodeModules = path.join(distDir, 'node_modules');
|
||||
|
||||
function doGlob(globString) {
|
||||
return new Promise((resolve, reject) => {
|
||||
glob(globString, (err, matches) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(matches);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function getCodegenedFilesToDelete() {
|
||||
const ngFactoryGlob = path.join(distDir, '**', '*ngfactory*');
|
||||
const ngSummaryGlob = path.join(distDir, '**', '*ngsummary*');
|
||||
const promises = [];
|
||||
promises.push(doGlob(ngFactoryGlob));
|
||||
promises.push(doGlob(ngSummaryGlob));
|
||||
return Promise.all(promises).then(listOfGlobResults => {
|
||||
const deleteFilePromises = [];
|
||||
listOfGlobResults.forEach(fileMatches => {
|
||||
fileMatches.forEach(filePath => {
|
||||
deleteFilePromises.push(fs.remove(filePath));
|
||||
})
|
||||
})
|
||||
return Promise.all(deleteFilePromises);
|
||||
});
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
getCodegenedFilesToDelete(),
|
||||
fs.remove(distGeneratedNodeModules)
|
||||
]);
|
||||
40
angular/scripts/link-copy.js
vendored
40
angular/scripts/link-copy.js
vendored
@@ -1,40 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
|
||||
let prjDir = process.argv[2];
|
||||
if (!prjDir) {
|
||||
throw new Error('local path required as last argument to "npm run build.link" command');
|
||||
}
|
||||
prjDir = path.join(__dirname, '../../../', prjDir);
|
||||
|
||||
copyPackage(prjDir, 'angular');
|
||||
copyPackage(prjDir, 'core');
|
||||
|
||||
|
||||
function copyPackage(prjDir, pkgName) {
|
||||
const prjDest = path.join(prjDir, 'node_modules', '@ionic', pkgName);
|
||||
|
||||
const pkgSrcDir = path.join(__dirname, '..', '..', pkgName);
|
||||
const pkgSrcDist = path.join(pkgSrcDir, 'dist');
|
||||
const pkgJsonPath = path.join(pkgSrcDir, 'package.json');
|
||||
const pkgJson = require(pkgJsonPath);
|
||||
|
||||
// make sure this local project exists
|
||||
fs.emptyDirSync(prjDest);
|
||||
|
||||
pkgJson.files.push('package.json');
|
||||
|
||||
pkgJson.files.forEach(f => {
|
||||
const src = path.join(pkgSrcDir, f);
|
||||
const dest = path.join(prjDest, f);
|
||||
|
||||
console.log('copying:', src, 'to', dest);
|
||||
fs.copySync(src, dest);
|
||||
});
|
||||
|
||||
const prjReadme = path.join(prjDest, 'README.md');
|
||||
console.log('readme:', prjReadme);
|
||||
|
||||
fs.writeFileSync(prjReadme, '@ionic/' + pkgName + ' copied from ' + pkgSrcDir + ', ' + new Date());
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import { defineCustomElements } from '@ionic/core/loader';
|
||||
import { Config } from './providers/config';
|
||||
import { IonicWindow } from './types/interfaces';
|
||||
|
||||
// Webpack import for ionicons
|
||||
// @ts-ignore
|
||||
// tslint:disable-next-line:no-import-side-effect
|
||||
import '@ionic/core/dist/ionic/svg';
|
||||
|
||||
export function appInitialize(config: Config) {
|
||||
return () => {
|
||||
const win: IonicWindow = window as any;
|
||||
if (typeof win !== 'undefined') {
|
||||
const Ionic = win.Ionic = win.Ionic || {};
|
||||
|
||||
Ionic.config = config;
|
||||
Ionic.asyncQueue = false;
|
||||
|
||||
Ionic.ael = (elm, eventName, cb, opts) => {
|
||||
if (elm.__zone_symbol__addEventListener && skipZone(eventName)) {
|
||||
elm.__zone_symbol__addEventListener(eventName, cb, opts);
|
||||
} else {
|
||||
elm.addEventListener(eventName, cb, opts);
|
||||
}
|
||||
};
|
||||
|
||||
Ionic.rel = (elm, eventName, cb, opts) => {
|
||||
if (elm.__zone_symbol__removeEventListener && skipZone(eventName)) {
|
||||
elm.__zone_symbol__removeEventListener(eventName, cb, opts);
|
||||
} else {
|
||||
elm.removeEventListener(eventName, cb, opts);
|
||||
}
|
||||
};
|
||||
|
||||
Ionic.raf = (cb: any) => {
|
||||
if (win.__zone_symbol__requestAnimationFrame) {
|
||||
win.__zone_symbol__requestAnimationFrame(cb);
|
||||
} else {
|
||||
win.requestAnimationFrame(cb);
|
||||
}
|
||||
};
|
||||
|
||||
// define all of Ionic's custom elements
|
||||
defineCustomElements(win);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const PASS_ZONE = [
|
||||
'click',
|
||||
];
|
||||
|
||||
function skipZone(eventName: string) {
|
||||
return PASS_ZONE.indexOf(eventName) < 0;
|
||||
}
|
||||
28
angular/src/components.d.ts
vendored
28
angular/src/components.d.ts
vendored
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* 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,72 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-checkbox,ion-toggle',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: BooleanValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class BooleanValueAccessor implements ControlValueAccessor {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
/**
|
||||
* Whether onChange should be mutted (not be fired). Will be true only when writeValue was called, which
|
||||
* means that value changed inside angular form (e.g. calling setValue on a control).
|
||||
*/
|
||||
private muteOnChange = false;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.muteOnChange = true;
|
||||
this.element.nativeElement.checked = value;
|
||||
setIonicClasses(this.element);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.checked'])
|
||||
_handleIonChange(value: any) {
|
||||
if (!this.muteOnChange) {
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
this.muteOnChange = false;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-input[type=number]',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: NumericValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class NumericValueAccessor implements ControlValueAccessor {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
/**
|
||||
* Whether onChange should be mutted (not be fired). Will be true only when writeValue was called, which
|
||||
* means that value changed inside angular form (e.g. calling setValue on a control).
|
||||
*/
|
||||
private muteOnChange = false;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.muteOnChange = true;
|
||||
|
||||
// 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
|
||||
this.element.nativeElement.value = value == null ? '' : value;
|
||||
setIonicClasses(this.element);
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleInputEvent(value: any) {
|
||||
if (!this.muteOnChange) {
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
this.muteOnChange = false;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: number | null) => void) {
|
||||
this.onChange = value => {
|
||||
fn(value === '' ? null : parseFloat(value));
|
||||
};
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-radio',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: RadioValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class RadioValueAccessor implements ControlValueAccessor {
|
||||
@Input() value: any;
|
||||
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether onChange should be mutted (not be fired). Will be true only when writeValue was called, which
|
||||
* means that value changed inside angular form (e.g. calling setValue on a control).
|
||||
*/
|
||||
private muteOnChange = false;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.muteOnChange = true;
|
||||
this.element.nativeElement.checked = this.value = value;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionSelect', ['$event.target.checked'])
|
||||
_handleIonSelect(value: any) {
|
||||
if (!this.muteOnChange) {
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
this.muteOnChange = false;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = () => {
|
||||
fn(this.value);
|
||||
};
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-range, ion-select, ion-radio-group, ion-segment, ion-datetime',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: SelectValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class SelectValueAccessor implements ControlValueAccessor {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
/**
|
||||
* Whether onChange should be mutted (not be fired). Will be true only when writeValue was called, which
|
||||
* means that value changed inside angular form (e.g. calling setValue on a control).
|
||||
*/
|
||||
private muteOnChange = false;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.muteOnChange = true;
|
||||
this.element.nativeElement.value = value;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleChangeEvent(value: any) {
|
||||
if (!this.muteOnChange) {
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
this.muteOnChange = false;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
import { setIonicClasses } from './util/set-ionic-classes';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-input:not([type=number]),ion-textarea,ion-searchbar',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: TextValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class TextValueAccessor implements ControlValueAccessor {
|
||||
|
||||
constructor(private element: ElementRef) {
|
||||
this.onChange = () => {/**/};
|
||||
this.onTouched = () => {/**/};
|
||||
}
|
||||
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
/**
|
||||
* Whether onChange should be mutted (not be fired). Will be true only when writeValue was called, which
|
||||
* means that value changed inside angular form (e.g. calling setValue on a control).
|
||||
*/
|
||||
private muteOnChange = false;
|
||||
|
||||
writeValue(value: any) {
|
||||
this.muteOnChange = true;
|
||||
this.element.nativeElement.value = value;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionChange', ['$event.target.value'])
|
||||
_handleInputEvent(value: any) {
|
||||
if (!this.muteOnChange) {
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
this.muteOnChange = false;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent() {
|
||||
this.onTouched();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setIonicClasses(this.element);
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: any) => void) {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.element.nativeElement.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
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 { RouterDirection } from './navigation/router-direction';
|
||||
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 { NavParams } from './navigation/nav-params';
|
||||
|
||||
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';
|
||||
@@ -1,35 +0,0 @@
|
||||
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 routerLink(_: any) {
|
||||
this.elementRef.nativeElement.button = true;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { NavController, NavIntent } 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.setIntent(NavIntent.Back);
|
||||
this.router.navigateByUrl(this.defaultHref);
|
||||
ev.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, Input, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core';
|
||||
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
|
||||
import { RouteView, 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 activatedView: RouteView | 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>();
|
||||
|
||||
@Input()
|
||||
set animated(animated: boolean) {
|
||||
(this.elementRef.nativeElement as HTMLIonRouterOutletElement).animated = animated;
|
||||
}
|
||||
|
||||
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);
|
||||
const hasStack = stack !== 'false' && stack !== false;
|
||||
this.stackCtrl = new StackController(hasStack, elementRef.nativeElement, router, this.navCtrl);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
console.log('router-outlet destroyed');
|
||||
this.parentContexts.onChildOutletDestroyed(this.name);
|
||||
}
|
||||
|
||||
getContext(): OutletContext | null {
|
||||
return this.parentContexts.getContext(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.getContext();
|
||||
if (context && context.route) {
|
||||
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(): any {
|
||||
if (this._activatedRoute) {
|
||||
return this._activatedRoute.snapshot.data;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the `RouteReuseStrategy` instructs to detach the subtree
|
||||
*/
|
||||
detach(): ComponentRef<any> {
|
||||
throw new Error('incompatible reuse strategy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
|
||||
*/
|
||||
attach(_ref: ComponentRef<any>, _activatedRoute: ActivatedRoute) {
|
||||
throw new Error('incompatible reuse strategy');
|
||||
}
|
||||
|
||||
deactivate(): void {
|
||||
if (this.activated) {
|
||||
if (this.activatedView) {
|
||||
this.activatedView.savedData = new Map(this.getContext()!.children['contexts']);
|
||||
}
|
||||
const c = this.component;
|
||||
this.activatedView = null;
|
||||
this.activated = null;
|
||||
this._activatedRoute = null;
|
||||
this.deactivateEvents.emit(c);
|
||||
}
|
||||
}
|
||||
|
||||
activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver | null) {
|
||||
if (this.isActivated) {
|
||||
throw new Error('Cannot activate an already activated outlet');
|
||||
}
|
||||
this._activatedRoute = activatedRoute;
|
||||
|
||||
let cmpRef: any;
|
||||
let enteringView = this.stackCtrl.getExistingView(activatedRoute);
|
||||
if (enteringView) {
|
||||
cmpRef = this.activated = enteringView.ref;
|
||||
const saved = enteringView.savedData;
|
||||
if (saved) {
|
||||
// self-restore
|
||||
const context = this.getContext()!;
|
||||
context.children['contexts'] = saved;
|
||||
}
|
||||
} else {
|
||||
const snapshot = (activatedRoute as any)._futureSnapshot;
|
||||
const component = snapshot.routeConfig!.component as any;
|
||||
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);
|
||||
cmpRef = this.activated = this.location.createComponent(factory, this.location.length, injector);
|
||||
|
||||
bindLifecycleEvents(cmpRef.instance, cmpRef.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, animated } = this.navCtrl.consumeTransition();
|
||||
this.activatedView = enteringView;
|
||||
this.stackCtrl.setActive(enteringView, direction, animated).then(() => {
|
||||
this.activateEvents.emit(cmpRef.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) {
|
||||
const ev = new CustomEvent('ionRouterOutletActivated', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
el.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line
|
||||
return this.parent.get(token, notFoundValue);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, Injector, ViewContainerRef } from '@angular/core';
|
||||
import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-nav',
|
||||
})
|
||||
export class NavDelegate {
|
||||
constructor(
|
||||
ref: ElementRef,
|
||||
resolver: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
angularDelegate: AngularDelegate,
|
||||
location: ViewContainerRef
|
||||
) {
|
||||
ref.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @description
|
||||
* NavParams are an object that exists on a page and can contain data for that particular view.
|
||||
* Similar to how data was pass to a view in V1 with `$stateParams`, NavParams offer a much more flexible
|
||||
* option with a simple `get` method.
|
||||
*
|
||||
* @usage
|
||||
* ```ts
|
||||
* import { NavParams } from '@ionic/angular';
|
||||
*
|
||||
* export class MyClass{
|
||||
*
|
||||
* constructor(navParams: NavParams){
|
||||
* // userParams is an object we have in our nav-parameters
|
||||
* navParams.get('userParams');
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export class NavParams {
|
||||
|
||||
constructor(public data: {[key: string]: any} = {}) {}
|
||||
|
||||
/**
|
||||
* Get the value of a nav-parameter for the current view
|
||||
*
|
||||
* ```ts
|
||||
* import { NavParams } from 'ionic-angular';
|
||||
*
|
||||
* export class MyClass{
|
||||
* constructor(public navParams: NavParams){
|
||||
* // userParams is an object we have in our nav-parameters
|
||||
* this.navParams.get('userParams');
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param param Which param you want to look up
|
||||
*/
|
||||
get(param: string): any {
|
||||
return this.data[param];
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
import { ComponentRef } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
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),
|
||||
fullpath: document.location!.pathname,
|
||||
deactivatedId: -1
|
||||
};
|
||||
}
|
||||
|
||||
getExistingView(activatedRoute: ActivatedRoute): RouteView | undefined {
|
||||
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, animated: boolean) {
|
||||
const leavingView = this.getActive();
|
||||
this.insertView(enteringView, direction);
|
||||
await this.transition(enteringView, leavingView, direction, animated, this.canGoBack(1));
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
pop(deep: number) {
|
||||
const view = this.views[this.views.length - deep - 1];
|
||||
this.navCtrl.navigateBack(view.url);
|
||||
}
|
||||
|
||||
private insertView(enteringView: RouteView, direction: number) {
|
||||
// no stack
|
||||
if (!this.stack) {
|
||||
this.views = [enteringView];
|
||||
return;
|
||||
}
|
||||
|
||||
// stack setRoot
|
||||
if (direction === 0) {
|
||||
this.views = [enteringView];
|
||||
return;
|
||||
}
|
||||
|
||||
// stack
|
||||
const index = this.views.indexOf(enteringView);
|
||||
if (index >= 0) {
|
||||
this.views = this.views.slice(0, index + 1);
|
||||
} else {
|
||||
if (direction === 1) {
|
||||
this.views.push(enteringView);
|
||||
} else {
|
||||
this.views = [enteringView];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private cleanup() {
|
||||
const views = this.views;
|
||||
this.viewsSnapshot
|
||||
.filter(view => !views.includes(view))
|
||||
.forEach(view => destroyView(view));
|
||||
|
||||
for (let i = 0; i < views.length - 1; i++) {
|
||||
const view = views[i];
|
||||
const element = view.element;
|
||||
element.setAttribute('aria-hidden', 'true');
|
||||
element.classList.add('ion-page-hidden');
|
||||
// view.ref.changeDetectorRef.detach();
|
||||
}
|
||||
|
||||
this.viewsSnapshot = views.slice();
|
||||
}
|
||||
|
||||
getActive(): RouteView | undefined {
|
||||
const views = this.views;
|
||||
return views.length > 0 ? views[views.length - 1] : undefined;
|
||||
}
|
||||
|
||||
private async transition(
|
||||
enteringView: RouteView | undefined,
|
||||
leavingView: RouteView | undefined,
|
||||
direction: number,
|
||||
animated: boolean,
|
||||
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', 'ion-page-invisible');
|
||||
if (enteringEl.parentElement !== containerEl) {
|
||||
containerEl.appendChild(enteringEl);
|
||||
}
|
||||
|
||||
await containerEl.componentOnReady();
|
||||
await containerEl.commit(enteringEl, leavingEl, {
|
||||
duration: !animated ? 0 : undefined,
|
||||
direction: direction === 1 ? 'forward' : 'back',
|
||||
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;
|
||||
fullpath: string;
|
||||
element: HTMLElement;
|
||||
ref: ComponentRef<any>;
|
||||
deactivatedId: number;
|
||||
savedData?: any;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
import { NavController, NavIntent } from '../../providers/nav-controller';
|
||||
|
||||
@Directive({
|
||||
selector: '[routerDirection]',
|
||||
})
|
||||
export class RouterDirection {
|
||||
|
||||
@Input() routerDirection: string;
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
) {}
|
||||
|
||||
@HostListener('click')
|
||||
onClick() {
|
||||
this.navCtrl.setIntent(textToIntent(this.routerDirection));
|
||||
}
|
||||
}
|
||||
|
||||
function textToIntent(direction: string) {
|
||||
switch (direction) {
|
||||
case 'forward': return NavIntent.Forward;
|
||||
case 'back': return NavIntent.Back;
|
||||
case 'root': return NavIntent.Root;
|
||||
default: return NavIntent.Auto;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { ComponentFactoryResolver, Directive, ElementRef, HostListener, Injector, ViewContainerRef } from '@angular/core';
|
||||
import { AngularDelegate } from '../../providers/angular-delegate';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-tab'
|
||||
})
|
||||
export class TabDelegate {
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
resolver: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
angularDelegate: AngularDelegate,
|
||||
location: ViewContainerRef
|
||||
) {
|
||||
elementRef.nativeElement.delegate = angularDelegate.create(resolver, injector, location);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
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('ionTabButtonClick', ['$event'])
|
||||
onTabbarClick(ev: UIEvent) {
|
||||
const tabElm: HTMLIonTabButtonElement = ev.detail as any;
|
||||
if (this.router && tabElm && tabElm.href) {
|
||||
this.router.navigateByUrl(tabElm.href);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
|
||||
import * as d from './proxies';
|
||||
|
||||
export const DIRECTIVES = [
|
||||
d.App,
|
||||
d.Avatar,
|
||||
d.BackButton,
|
||||
d.Backdrop,
|
||||
d.Badge,
|
||||
d.Button,
|
||||
d.Buttons,
|
||||
d.Card,
|
||||
d.CardContent,
|
||||
d.CardHeader,
|
||||
d.CardSubtitle,
|
||||
d.CardTitle,
|
||||
d.Checkbox,
|
||||
d.Chip,
|
||||
d.ChipButton,
|
||||
d.ChipIcon,
|
||||
d.Col,
|
||||
d.Content,
|
||||
d.Datetime,
|
||||
d.Fab,
|
||||
d.FabButton,
|
||||
d.FabList,
|
||||
d.Footer,
|
||||
d.Grid,
|
||||
d.Header,
|
||||
d.Icon,
|
||||
d.Img,
|
||||
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.Searchbar,
|
||||
d.Segment,
|
||||
d.SegmentButton,
|
||||
d.Select,
|
||||
d.SelectOption,
|
||||
d.SelectPopover,
|
||||
d.SkeletonText,
|
||||
d.Slide,
|
||||
d.Slides,
|
||||
d.Spinner,
|
||||
d.SplitPane,
|
||||
d.Tab,
|
||||
d.TabBar,
|
||||
d.TabButton,
|
||||
d.Tabs,
|
||||
d.Text,
|
||||
d.Textarea,
|
||||
d.Thumbnail,
|
||||
d.Toggle,
|
||||
d.Toolbar,
|
||||
d.ToolbarTitle
|
||||
];
|
||||
@@ -1,979 +0,0 @@
|
||||
/* tslint:disable */
|
||||
/* auto-generated angular directive proxies */
|
||||
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
type StencilComponents<T extends keyof StencilElementInterfaces> = StencilElementInterfaces[T];
|
||||
|
||||
export function proxyInputs(instance: any, el: any, props: string[]) {
|
||||
props.forEach(propName => {
|
||||
Object.defineProperty(instance, propName, {
|
||||
get: () => el[propName], set: (val: any) => el[propName] = val
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function proxyOutputs(instance: any, el: any, events: string[]) {
|
||||
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
|
||||
}
|
||||
|
||||
export function proxyMethods(instance: any, el: any, methods: string[]) {
|
||||
methods.forEach(methodName => {
|
||||
Object.defineProperty(instance, methodName, {
|
||||
get: function() {
|
||||
return function() {
|
||||
const args = arguments;
|
||||
return el.componentOnReady().then((el: any) => el[methodName].apply(el, args));
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export declare interface App extends StencilComponents<'IonApp'> {}
|
||||
@Component({ selector: 'ion-app', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class App {
|
||||
}
|
||||
|
||||
export declare interface Avatar extends StencilComponents<'IonAvatar'> {}
|
||||
@Component({ selector: 'ion-avatar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Avatar {
|
||||
}
|
||||
|
||||
export declare interface BackButton extends StencilComponents<'IonBackButton'> {}
|
||||
@Component({ selector: 'ion-back-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'defaultHref', 'icon', 'text'] })
|
||||
export class BackButton {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'defaultHref', 'icon', 'text']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Backdrop extends StencilComponents<'IonBackdrop'> {}
|
||||
@Component({ selector: 'ion-backdrop', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['visible', 'tappable', 'stopPropagation'] })
|
||||
export class Backdrop {
|
||||
ionBackdropTap: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['visible', 'tappable', 'stopPropagation']);
|
||||
proxyOutputs(this, el, ['ionBackdropTap']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Badge extends StencilComponents<'IonBadge'> {}
|
||||
@Component({ selector: 'ion-badge', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class Badge {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Button extends StencilComponents<'IonButton'> {}
|
||||
@Component({ selector: 'ion-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'buttonType', 'disabled', 'expand', 'fill', 'routerDirection', 'href', 'shape', 'size', 'strong', 'type'] })
|
||||
export class Button {
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'buttonType', 'disabled', 'expand', 'fill', 'routerDirection', 'href', 'shape', 'size', 'strong', 'type']);
|
||||
proxyOutputs(this, el, ['ionFocus', 'ionBlur']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Buttons extends StencilComponents<'IonButtons'> {}
|
||||
@Component({ selector: 'ion-buttons', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Buttons {
|
||||
}
|
||||
|
||||
export declare interface Card extends StencilComponents<'IonCard'> {}
|
||||
@Component({ selector: 'ion-card', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class Card {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface CardContent extends StencilComponents<'IonCardContent'> {}
|
||||
@Component({ selector: 'ion-card-content', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode'] })
|
||||
export class CardContent {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface CardHeader extends StencilComponents<'IonCardHeader'> {}
|
||||
@Component({ selector: 'ion-card-header', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'translucent'] })
|
||||
export class CardHeader {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'translucent']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface CardSubtitle extends StencilComponents<'IonCardSubtitle'> {}
|
||||
@Component({ selector: 'ion-card-subtitle', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class CardSubtitle {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface CardTitle extends StencilComponents<'IonCardTitle'> {}
|
||||
@Component({ selector: 'ion-card-title', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class CardTitle {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Checkbox extends StencilComponents<'IonCheckbox'> {}
|
||||
@Component({ selector: 'ion-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'name', 'checked', 'disabled', 'value'] })
|
||||
export class Checkbox {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'name', 'checked', 'disabled', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionFocus', 'ionBlur', 'ionStyle']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Chip extends StencilComponents<'IonChip'> {}
|
||||
@Component({ selector: 'ion-chip', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class Chip {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ChipButton extends StencilComponents<'IonChipButton'> {}
|
||||
@Component({ selector: 'ion-chip-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'disabled', 'fill', 'href'] })
|
||||
export class ChipButton {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'disabled', 'fill', 'href']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ChipIcon extends StencilComponents<'IonChipIcon'> {}
|
||||
@Component({ selector: 'ion-chip-icon', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'fill', 'name', 'src'] })
|
||||
export class ChipIcon {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'fill', 'name', 'src']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Col extends StencilComponents<'IonCol'> {}
|
||||
@Component({ selector: 'ion-col', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['offset', 'offsetXs', 'offsetSm', 'offsetMd', 'offsetLg', 'offsetXl', 'pull', 'pullXs', 'pullSm', 'pullMd', 'pullLg', 'pullXl', 'push', 'pushXs', 'pushSm', 'pushMd', 'pushLg', 'pushXl', 'size', 'sizeXs', 'sizeSm', 'sizeMd', 'sizeLg', 'sizeXl'] })
|
||||
export class Col {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['offset', 'offsetXs', 'offsetSm', 'offsetMd', 'offsetLg', 'offsetXl', 'pull', 'pullXs', 'pullSm', 'pullMd', 'pullLg', 'pullXl', 'push', 'pushXs', 'pushSm', 'pushMd', 'pushLg', 'pushXl', 'size', 'sizeXs', 'sizeSm', 'sizeMd', 'sizeLg', 'sizeXl']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Content extends StencilComponents<'IonContent'> {}
|
||||
@Component({ selector: 'ion-content', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'fullscreen', 'forceOverscroll', 'scrollX', 'scrollY', 'scrollEvents'] })
|
||||
export class Content {
|
||||
ionScrollStart: EventEmitter<CustomEvent>;
|
||||
ionScroll: EventEmitter<CustomEvent>;
|
||||
ionScrollEnd: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['getScrollElement', 'scrollToTop', 'scrollToBottom', 'scrollByPoint', 'scrollToPoint']);
|
||||
proxyInputs(this, el, ['color', 'fullscreen', 'forceOverscroll', 'scrollX', 'scrollY', 'scrollEvents']);
|
||||
proxyOutputs(this, el, ['ionScrollStart', 'ionScroll', 'ionScrollEnd']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Datetime extends StencilComponents<'IonDatetime'> {}
|
||||
@Component({ selector: 'ion-datetime', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'name', 'disabled', 'min', 'max', 'displayFormat', 'pickerFormat', 'cancelText', 'doneText', 'yearValues', 'monthValues', 'dayValues', 'hourValues', 'minuteValues', 'monthNames', 'monthShortNames', 'dayNames', 'dayShortNames', 'pickerOptions', 'placeholder', 'value'] })
|
||||
export class Datetime {
|
||||
ionCancel: EventEmitter<CustomEvent>;
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['open']);
|
||||
proxyInputs(this, el, ['mode', 'name', 'disabled', 'min', 'max', 'displayFormat', 'pickerFormat', 'cancelText', 'doneText', 'yearValues', 'monthValues', 'dayValues', 'hourValues', 'minuteValues', 'monthNames', 'monthShortNames', 'dayNames', 'dayShortNames', 'pickerOptions', 'placeholder', 'value']);
|
||||
proxyOutputs(this, el, ['ionCancel', 'ionChange', 'ionStyle']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Fab extends StencilComponents<'IonFab'> {}
|
||||
@Component({ selector: 'ion-fab', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['horizontal', 'vertical', 'edge', 'activated'] })
|
||||
export class Fab {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['close']);
|
||||
proxyInputs(this, el, ['horizontal', 'vertical', 'edge', 'activated']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface FabButton extends StencilComponents<'IonFabButton'> {}
|
||||
@Component({ selector: 'ion-fab-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'activated', 'disabled', 'href', 'routerDirection', 'show', 'translucent', 'type'] })
|
||||
export class FabButton {
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'color', 'activated', 'disabled', 'href', 'routerDirection', 'show', 'translucent', 'type']);
|
||||
proxyOutputs(this, el, ['ionFocus', 'ionBlur']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface FabList extends StencilComponents<'IonFabList'> {}
|
||||
@Component({ selector: 'ion-fab-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['activated', 'side'] })
|
||||
export class FabList {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['activated', 'side']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Footer extends StencilComponents<'IonFooter'> {}
|
||||
@Component({ selector: 'ion-footer', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
|
||||
export class Footer {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'translucent']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Grid extends StencilComponents<'IonGrid'> {}
|
||||
@Component({ selector: 'ion-grid', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['fixed'] })
|
||||
export class Grid {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['fixed']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Header extends StencilComponents<'IonHeader'> {}
|
||||
@Component({ selector: 'ion-header', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'translucent'] })
|
||||
export class Header {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'translucent']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Icon extends StencilComponents<'IonIcon'> {}
|
||||
@Component({ selector: 'ion-icon', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['ariaLabel', 'color', 'icon', 'ios', 'lazy', 'md', 'mode', 'name', 'size', 'src'] })
|
||||
export class Icon {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['ariaLabel', 'color', 'icon', 'ios', 'lazy', 'md', 'mode', 'name', 'size', 'src']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Img extends StencilComponents<'IonImg'> {}
|
||||
@Component({ selector: 'ion-img', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['alt', 'src'] })
|
||||
export class Img {
|
||||
ionImgDidLoad: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['alt', 'src']);
|
||||
proxyOutputs(this, el, ['ionImgDidLoad']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface InfiniteScroll extends StencilComponents<'IonInfiniteScroll'> {}
|
||||
@Component({ selector: 'ion-infinite-scroll', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['threshold', 'disabled', 'position'] })
|
||||
export class InfiniteScroll {
|
||||
ionInfinite: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['complete']);
|
||||
proxyInputs(this, el, ['threshold', 'disabled', 'position']);
|
||||
proxyOutputs(this, el, ['ionInfinite']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface InfiniteScrollContent extends StencilComponents<'IonInfiniteScrollContent'> {}
|
||||
@Component({ selector: 'ion-infinite-scroll-content', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['loadingSpinner', 'loadingText'] })
|
||||
export class InfiniteScrollContent {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['loadingSpinner', 'loadingText']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Input extends StencilComponents<'IonInput'> {}
|
||||
@Component({ selector: 'ion-input', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'accept', 'autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'debounce', 'disabled', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'results', 'spellcheck', 'step', 'size', 'type', 'value'] })
|
||||
export class Input {
|
||||
ionInput: EventEmitter<CustomEvent>;
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionInputDidLoad: EventEmitter<CustomEvent>;
|
||||
ionInputDidUnload: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['setFocus']);
|
||||
proxyInputs(this, el, ['color', 'mode', 'accept', 'autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'debounce', 'disabled', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'results', 'spellcheck', 'step', 'size', 'type', 'value']);
|
||||
proxyOutputs(this, el, ['ionInput', 'ionChange', 'ionStyle', 'ionBlur', 'ionFocus', 'ionInputDidLoad', 'ionInputDidUnload']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Item extends StencilComponents<'IonItem'> {}
|
||||
@Component({ selector: 'ion-item', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'type'] })
|
||||
export class Item {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'button', 'detail', 'detailIcon', 'disabled', 'href', 'lines', 'routerDirection', 'type']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ItemDivider extends StencilComponents<'IonItemDivider'> {}
|
||||
@Component({ selector: 'ion-item-divider', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class ItemDivider {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ItemGroup extends StencilComponents<'IonItemGroup'> {}
|
||||
@Component({ selector: 'ion-item-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class ItemGroup {
|
||||
}
|
||||
|
||||
export declare interface ItemOption extends StencilComponents<'IonItemOption'> {}
|
||||
@Component({ selector: 'ion-item-option', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'disabled', 'expandable', 'href'] })
|
||||
export class ItemOption {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'disabled', 'expandable', 'href']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ItemOptions extends StencilComponents<'IonItemOptions'> {}
|
||||
@Component({ selector: 'ion-item-options', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['side'] })
|
||||
export class ItemOptions {
|
||||
ionSwipe: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['fireSwipeEvent']);
|
||||
proxyInputs(this, el, ['side']);
|
||||
proxyOutputs(this, el, ['ionSwipe']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ItemSliding extends StencilComponents<'IonItemSliding'> {}
|
||||
@Component({ selector: 'ion-item-sliding', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['disabled'] })
|
||||
export class ItemSliding {
|
||||
ionDrag: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['getOpenAmount', 'getSlidingRatio', 'close', 'closeOpened']);
|
||||
proxyInputs(this, el, ['disabled']);
|
||||
proxyOutputs(this, el, ['ionDrag']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Label extends StencilComponents<'IonLabel'> {}
|
||||
@Component({ selector: 'ion-label', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'position'] })
|
||||
export class Label {
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'position']);
|
||||
proxyOutputs(this, el, ['ionStyle']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface List extends StencilComponents<'IonList'> {}
|
||||
@Component({ selector: 'ion-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'lines', 'inset'] })
|
||||
export class List {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['closeSlidingItems']);
|
||||
proxyInputs(this, el, ['mode', 'lines', 'inset']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ListHeader extends StencilComponents<'IonListHeader'> {}
|
||||
@Component({ selector: 'ion-list-header', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color'] })
|
||||
export class ListHeader {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'color']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Menu extends StencilComponents<'IonMenu'> {}
|
||||
@Component({ selector: 'ion-menu', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['contentId', 'menuId', 'type', 'disabled', 'side', 'swipeGesture', 'maxEdgeStart'] })
|
||||
export class Menu {
|
||||
ionWillOpen: EventEmitter<CustomEvent>;
|
||||
ionWillClose: EventEmitter<CustomEvent>;
|
||||
ionDidOpen: EventEmitter<CustomEvent>;
|
||||
ionDidClose: EventEmitter<CustomEvent>;
|
||||
ionMenuChange: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['isOpen', 'isActive', 'open', 'close', 'toggle', 'setOpen']);
|
||||
proxyInputs(this, el, ['contentId', 'menuId', 'type', 'disabled', 'side', 'swipeGesture', 'maxEdgeStart']);
|
||||
proxyOutputs(this, el, ['ionWillOpen', 'ionWillClose', 'ionDidOpen', 'ionDidClose', 'ionMenuChange']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface MenuButton extends StencilComponents<'IonMenuButton'> {}
|
||||
@Component({ selector: 'ion-menu-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'menu', 'autoHide'] })
|
||||
export class MenuButton {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'menu', 'autoHide']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface MenuToggle extends StencilComponents<'IonMenuToggle'> {}
|
||||
@Component({ selector: 'ion-menu-toggle', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['menu', 'autoHide'] })
|
||||
export class MenuToggle {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['menu', 'autoHide']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Nav extends StencilComponents<'IonNav'> {}
|
||||
@Component({ selector: 'ion-nav', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['delegate', 'swipeGesture', 'animated', 'animation', 'rootParams', 'root'] })
|
||||
export class Nav {
|
||||
ionNavWillLoad: EventEmitter<CustomEvent>;
|
||||
ionNavWillChange: EventEmitter<CustomEvent>;
|
||||
ionNavDidChange: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['push', 'insert', 'insertPages', 'pop', 'popTo', 'popToRoot', 'removeIndex', 'setRoot', 'setPages', 'setRouteId', 'getRouteId', 'getActive', 'getByIndex', 'canGoBack', 'getPrevious']);
|
||||
proxyInputs(this, el, ['delegate', 'swipeGesture', 'animated', 'animation', 'rootParams', 'root']);
|
||||
proxyOutputs(this, el, ['ionNavWillLoad', 'ionNavWillChange', 'ionNavDidChange']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface NavPop extends StencilComponents<'IonNavPop'> {}
|
||||
@Component({ selector: 'ion-nav-pop', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class NavPop {
|
||||
}
|
||||
|
||||
export declare interface NavPush extends StencilComponents<'IonNavPush'> {}
|
||||
@Component({ selector: 'ion-nav-push', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
|
||||
export class NavPush {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['component', 'componentProps']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface NavSetRoot extends StencilComponents<'IonNavSetRoot'> {}
|
||||
@Component({ selector: 'ion-nav-set-root', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['component', 'componentProps'] })
|
||||
export class NavSetRoot {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['component', 'componentProps']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Note extends StencilComponents<'IonNote'> {}
|
||||
@Component({ selector: 'ion-note', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class Note {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Radio extends StencilComponents<'IonRadio'> {}
|
||||
@Component({ selector: 'ion-radio', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'name', 'disabled', 'checked', 'value'] })
|
||||
export class Radio {
|
||||
ionRadioDidLoad: EventEmitter<CustomEvent>;
|
||||
ionRadioDidUnload: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
ionSelect: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'name', 'disabled', 'checked', 'value']);
|
||||
proxyOutputs(this, el, ['ionRadioDidLoad', 'ionRadioDidUnload', 'ionStyle', 'ionSelect', 'ionFocus', 'ionBlur']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface RadioGroup extends StencilComponents<'IonRadioGroup'> {}
|
||||
@Component({ selector: 'ion-radio-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['allowEmptySelection', 'name', 'value'] })
|
||||
export class RadioGroup {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['allowEmptySelection', 'name', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Range extends StencilComponents<'IonRange'> {}
|
||||
@Component({ selector: 'ion-range', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'debounce', 'name', 'dualKnobs', 'min', 'max', 'pin', 'snaps', 'step', 'disabled', 'value'] })
|
||||
export class Range {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'debounce', 'name', 'dualKnobs', 'min', 'max', 'pin', 'snaps', 'step', 'disabled', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionStyle', 'ionFocus', 'ionBlur']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Refresher extends StencilComponents<'IonRefresher'> {}
|
||||
@Component({ selector: 'ion-refresher', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['pullMin', 'pullMax', 'closeDuration', 'snapbackDuration', 'disabled'] })
|
||||
export class Refresher {
|
||||
ionRefresh: EventEmitter<CustomEvent>;
|
||||
ionPull: EventEmitter<CustomEvent>;
|
||||
ionStart: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['complete', 'cancel', 'getProgress']);
|
||||
proxyInputs(this, el, ['pullMin', 'pullMax', 'closeDuration', 'snapbackDuration', 'disabled']);
|
||||
proxyOutputs(this, el, ['ionRefresh', 'ionPull', 'ionStart']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface RefresherContent extends StencilComponents<'IonRefresherContent'> {}
|
||||
@Component({ selector: 'ion-refresher-content', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText'] })
|
||||
export class RefresherContent {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['pullingIcon', 'pullingText', 'refreshingSpinner', 'refreshingText']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Reorder extends StencilComponents<'IonReorder'> {}
|
||||
@Component({ selector: 'ion-reorder', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Reorder {
|
||||
}
|
||||
|
||||
export declare interface ReorderGroup extends StencilComponents<'IonReorderGroup'> {}
|
||||
@Component({ selector: 'ion-reorder-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['disabled'] })
|
||||
export class ReorderGroup {
|
||||
ionItemReorder: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['complete']);
|
||||
proxyInputs(this, el, ['disabled']);
|
||||
proxyOutputs(this, el, ['ionItemReorder']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface RippleEffect extends StencilComponents<'IonRippleEffect'> {}
|
||||
@Component({ selector: 'ion-ripple-effect', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class RippleEffect {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['addRipple']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Row extends StencilComponents<'IonRow'> {}
|
||||
@Component({ selector: 'ion-row', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Row {
|
||||
}
|
||||
|
||||
export declare interface Searchbar extends StencilComponents<'IonSearchbar'> {}
|
||||
@Component({ selector: 'ion-searchbar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'debounce', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value'] })
|
||||
export class Searchbar {
|
||||
ionInput: EventEmitter<CustomEvent>;
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionCancel: EventEmitter<CustomEvent>;
|
||||
ionClear: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['setFocus']);
|
||||
proxyInputs(this, el, ['color', 'mode', 'animated', 'autocomplete', 'autocorrect', 'cancelButtonIcon', 'cancelButtonText', 'clearIcon', 'debounce', 'placeholder', 'searchIcon', 'showCancelButton', 'spellcheck', 'type', 'value']);
|
||||
proxyOutputs(this, el, ['ionInput', 'ionChange', 'ionCancel', 'ionClear', 'ionBlur', 'ionFocus']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Segment extends StencilComponents<'IonSegment'> {}
|
||||
@Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'disabled', 'value'] })
|
||||
export class Segment {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'disabled', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface SegmentButton extends StencilComponents<'IonSegmentButton'> {}
|
||||
@Component({ selector: 'ion-segment-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'checked', 'disabled', 'value'] })
|
||||
export class SegmentButton {
|
||||
ionSelect: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode', 'checked', 'disabled', 'value']);
|
||||
proxyOutputs(this, el, ['ionSelect']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Select extends StencilComponents<'IonSelect'> {}
|
||||
@Component({ selector: 'ion-select', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'disabled', 'cancelText', 'okText', 'placeholder', 'name', 'selectedText', 'multiple', 'interface', 'interfaceOptions', 'value'] })
|
||||
export class Select {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionCancel: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['open']);
|
||||
proxyInputs(this, el, ['mode', 'disabled', 'cancelText', 'okText', 'placeholder', 'name', 'selectedText', 'multiple', 'interface', 'interfaceOptions', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionCancel', 'ionFocus', 'ionBlur', 'ionStyle']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface SelectOption extends StencilComponents<'IonSelectOption'> {}
|
||||
@Component({ selector: 'ion-select-option', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['disabled', 'selected', 'value'] })
|
||||
export class SelectOption {
|
||||
ionSelectOptionDidLoad: EventEmitter<CustomEvent>;
|
||||
ionSelectOptionDidUnload: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['disabled', 'selected', 'value']);
|
||||
proxyOutputs(this, el, ['ionSelectOptionDidLoad', 'ionSelectOptionDidUnload']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface SelectPopover extends StencilComponents<'IonSelectPopover'> {}
|
||||
@Component({ selector: 'ion-select-popover', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['header', 'subHeader', 'message', 'options'] })
|
||||
export class SelectPopover {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['header', 'subHeader', 'message', 'options']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface SkeletonText extends StencilComponents<'IonSkeletonText'> {}
|
||||
@Component({ selector: 'ion-skeleton-text', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['width'] })
|
||||
export class SkeletonText {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['width']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Slide extends StencilComponents<'IonSlide'> {}
|
||||
@Component({ selector: 'ion-slide', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Slide {
|
||||
ionSlideChanged: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyOutputs(this, el, ['ionSlideChanged']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Slides extends StencilComponents<'IonSlides'> {}
|
||||
@Component({ selector: 'ion-slides', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'options', 'pager', 'scrollbar'] })
|
||||
export class Slides {
|
||||
ionSlidesDidLoad: EventEmitter<CustomEvent>;
|
||||
ionSlideTap: EventEmitter<CustomEvent>;
|
||||
ionSlideDoubleTap: EventEmitter<CustomEvent>;
|
||||
ionSlideWillChange: EventEmitter<CustomEvent>;
|
||||
ionSlideDidChange: EventEmitter<CustomEvent>;
|
||||
ionSlideNextStart: EventEmitter<CustomEvent>;
|
||||
ionSlidePrevStart: EventEmitter<CustomEvent>;
|
||||
ionSlideNextEnd: EventEmitter<CustomEvent>;
|
||||
ionSlidePrevEnd: EventEmitter<CustomEvent>;
|
||||
ionSlideTransitionStart: EventEmitter<CustomEvent>;
|
||||
ionSlideTransitionEnd: EventEmitter<CustomEvent>;
|
||||
ionSlideDrag: EventEmitter<CustomEvent>;
|
||||
ionSlideReachStart: EventEmitter<CustomEvent>;
|
||||
ionSlideReachEnd: EventEmitter<CustomEvent>;
|
||||
ionSlideTouchStart: EventEmitter<CustomEvent>;
|
||||
ionSlideTouchEnd: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['update', 'slideTo', 'slideNext', 'slidePrev', 'getActiveIndex', 'getPreviousIndex', 'length', 'isEnd', 'isBeginning', 'startAutoplay', 'stopAutoplay', 'lockSwipeToNext', 'lockSwipeToPrev', 'lockSwipes']);
|
||||
proxyInputs(this, el, ['mode', 'options', 'pager', 'scrollbar']);
|
||||
proxyOutputs(this, el, ['ionSlidesDidLoad', 'ionSlideTap', 'ionSlideDoubleTap', 'ionSlideWillChange', 'ionSlideDidChange', 'ionSlideNextStart', 'ionSlidePrevStart', 'ionSlideNextEnd', 'ionSlidePrevEnd', 'ionSlideTransitionStart', 'ionSlideTransitionEnd', 'ionSlideDrag', 'ionSlideReachStart', 'ionSlideReachEnd', 'ionSlideTouchStart', 'ionSlideTouchEnd']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Spinner extends StencilComponents<'IonSpinner'> {}
|
||||
@Component({ selector: 'ion-spinner', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'duration', 'name', 'paused'] })
|
||||
export class Spinner {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'duration', 'name', 'paused']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface SplitPane extends StencilComponents<'IonSplitPane'> {}
|
||||
@Component({ selector: 'ion-split-pane', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['disabled', 'when'] })
|
||||
export class SplitPane {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionSplitPaneVisible: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['disabled', 'when']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionSplitPaneVisible']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Tab extends StencilComponents<'IonTab'> {}
|
||||
@Component({ selector: 'ion-tab', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['active', 'delegate', 'tab', 'component'] })
|
||||
export class Tab {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['setActive']);
|
||||
proxyInputs(this, el, ['active', 'delegate', 'tab', 'component']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface TabBar extends StencilComponents<'IonTabBar'> {}
|
||||
@Component({ selector: 'ion-tab-bar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'layout', 'placement', 'selectedTab', 'translucent'] })
|
||||
export class TabBar {
|
||||
ionTabBarChanged: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'color', 'layout', 'placement', 'selectedTab', 'translucent']);
|
||||
proxyOutputs(this, el, ['ionTabBarChanged']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface TabButton extends StencilComponents<'IonTabButton'> {}
|
||||
@Component({ selector: 'ion-tab-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'layout', 'href', 'tab', 'disabled'] })
|
||||
export class TabButton {
|
||||
ionTabButtonClick: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'color', 'layout', 'href', 'tab', 'disabled']);
|
||||
proxyOutputs(this, el, ['ionTabButtonClick']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Tabs extends StencilComponents<'IonTabs'> {}
|
||||
@Component({ selector: 'ion-tabs', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Tabs {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionNavWillLoad: EventEmitter<CustomEvent>;
|
||||
ionNavWillChange: EventEmitter<CustomEvent>;
|
||||
ionNavDidChange: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['select', 'setRouteId', 'getRouteId', 'getTab', 'getSelected']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionNavWillLoad', 'ionNavWillChange', 'ionNavDidChange']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Text extends StencilComponents<'IonText'> {}
|
||||
@Component({ selector: 'ion-text', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class Text {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Textarea extends StencilComponents<'IonTextarea'> {}
|
||||
@Component({ selector: 'ion-textarea', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'autocapitalize', 'autofocus', 'clearOnEdit', 'debounce', 'disabled', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'spellcheck', 'cols', 'rows', 'wrap', 'value'] })
|
||||
export class Textarea {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionInput: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyMethods(this, el, ['setFocus']);
|
||||
proxyInputs(this, el, ['mode', 'color', 'autocapitalize', 'autofocus', 'clearOnEdit', 'debounce', 'disabled', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'spellcheck', 'cols', 'rows', 'wrap', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionInput', 'ionStyle', 'ionBlur', 'ionFocus']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Thumbnail extends StencilComponents<'IonThumbnail'> {}
|
||||
@Component({ selector: 'ion-thumbnail', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>' })
|
||||
export class Thumbnail {
|
||||
}
|
||||
|
||||
export declare interface Toggle extends StencilComponents<'IonToggle'> {}
|
||||
@Component({ selector: 'ion-toggle', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'name', 'checked', 'disabled', 'value'] })
|
||||
export class Toggle {
|
||||
ionChange: EventEmitter<CustomEvent>;
|
||||
ionFocus: EventEmitter<CustomEvent>;
|
||||
ionBlur: EventEmitter<CustomEvent>;
|
||||
ionStyle: EventEmitter<CustomEvent>;
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['mode', 'color', 'name', 'checked', 'disabled', 'value']);
|
||||
proxyOutputs(this, el, ['ionChange', 'ionFocus', 'ionBlur', 'ionStyle']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface Toolbar extends StencilComponents<'IonToolbar'> {}
|
||||
@Component({ selector: 'ion-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode'] })
|
||||
export class Toolbar {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color', 'mode']);
|
||||
}
|
||||
}
|
||||
|
||||
export declare interface ToolbarTitle extends StencilComponents<'IonTitle'> {}
|
||||
@Component({ selector: 'ion-title', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color'] })
|
||||
export class ToolbarTitle {
|
||||
|
||||
constructor(c: ChangeDetectorRef, r: ElementRef) {
|
||||
c.detach();
|
||||
const el = r.nativeElement;
|
||||
proxyInputs(this, el, ['color']);
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
import { ChangeDetectorRef, ContentChild, Directive, ElementRef, EmbeddedViewRef } from '@angular/core';
|
||||
import { proxyInputs } from '../proxies';
|
||||
import { VirtualItem } from './virtual-item';
|
||||
import { VirtualHeader } from './virtual-header';
|
||||
import { VirtualFooter } from './virtual-footer';
|
||||
import { VirtualContext } from './virtual-utils';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: 'ion-virtual-scroll',
|
||||
inputs: [
|
||||
'approxItemHeight',
|
||||
'approxHeaderHeight',
|
||||
'approxFooterHeight',
|
||||
'headerFn',
|
||||
'footerFn',
|
||||
'items',
|
||||
'itemHeight'
|
||||
]
|
||||
})
|
||||
export class VirtualScroll {
|
||||
|
||||
@ContentChild(VirtualItem) itmTmp: VirtualItem;
|
||||
@ContentChild(VirtualHeader) hdrTmp: VirtualHeader;
|
||||
@ContentChild(VirtualFooter) ftrTmp: VirtualFooter;
|
||||
|
||||
constructor(
|
||||
private el: ElementRef,
|
||||
public cd: ChangeDetectorRef,
|
||||
) {
|
||||
el.nativeElement.nodeRender = this.nodeRender.bind(this);
|
||||
|
||||
proxyInputs(this, this.el.nativeElement, [
|
||||
'approxItemHeight',
|
||||
'approxHeaderHeight',
|
||||
'approxFooterHeight',
|
||||
'headerFn',
|
||||
'footerFn',
|
||||
'items',
|
||||
'itemHeight'
|
||||
]);
|
||||
}
|
||||
|
||||
private nodeRender(el: HTMLElement | null, cell: any, index: number) {
|
||||
if (!el) {
|
||||
const view = this.itmTmp.viewContainer.createEmbeddedView(
|
||||
this.getComponent(cell.type),
|
||||
{ $implicit: null, index },
|
||||
index
|
||||
);
|
||||
el = getElement(view);
|
||||
(el as any)['$ionView'] = view;
|
||||
}
|
||||
const node = (el as any)['$ionView'];
|
||||
const ctx = node.context as VirtualContext;
|
||||
ctx.$implicit = cell.value;
|
||||
ctx.index = cell.index;
|
||||
node.detectChanges();
|
||||
return el;
|
||||
}
|
||||
|
||||
private getComponent(type: number) {
|
||||
switch (type) {
|
||||
case 0: return this.itmTmp.templateRef;
|
||||
case 1: return this.hdrTmp.templateRef;
|
||||
case 2: return this.ftrTmp.templateRef;
|
||||
}
|
||||
throw new Error('template for virtual item was not provided');
|
||||
}
|
||||
}
|
||||
|
||||
function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement | null {
|
||||
const rootNodes = view.rootNodes;
|
||||
for (let i = 0; i < rootNodes.length; i++) {
|
||||
if (rootNodes[i].nodeType === 1) {
|
||||
return rootNodes[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
export interface VirtualContext {
|
||||
$implicit: any;
|
||||
index: number;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// export module
|
||||
export { IonicModule } from './ionic-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';
|
||||
|
||||
// ionic route reuse strategy
|
||||
export * from './util/ionic-router-reuse-strategy';
|
||||
@@ -1,157 +0,0 @@
|
||||
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
|
||||
import { IonicConfig } from '@ionic/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { appInitialize } from './app-initialize';
|
||||
import { ConfigToken } from './providers/config';
|
||||
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.Backdrop,
|
||||
d.Badge,
|
||||
d.Button,
|
||||
d.Buttons,
|
||||
d.Card,
|
||||
d.CardContent,
|
||||
d.CardHeader,
|
||||
d.CardSubtitle,
|
||||
d.CardTitle,
|
||||
d.Checkbox,
|
||||
d.Chip,
|
||||
d.ChipButton,
|
||||
d.ChipIcon,
|
||||
d.Col,
|
||||
d.Content,
|
||||
d.Datetime,
|
||||
d.Fab,
|
||||
d.FabButton,
|
||||
d.FabList,
|
||||
d.Footer,
|
||||
d.Grid,
|
||||
d.Header,
|
||||
d.Icon,
|
||||
d.Img,
|
||||
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.Searchbar,
|
||||
d.Segment,
|
||||
d.SegmentButton,
|
||||
d.Select,
|
||||
d.SelectOption,
|
||||
d.SelectPopover,
|
||||
d.SkeletonText,
|
||||
d.Slide,
|
||||
d.Slides,
|
||||
d.Spinner,
|
||||
d.SplitPane,
|
||||
d.Tab,
|
||||
d.TabBar,
|
||||
d.TabButton,
|
||||
d.Tabs,
|
||||
d.Text,
|
||||
d.Textarea,
|
||||
d.Thumbnail,
|
||||
d.Toggle,
|
||||
d.Toolbar,
|
||||
d.ToolbarTitle,
|
||||
|
||||
// ngModel accessors
|
||||
c.BooleanValueAccessor,
|
||||
c.NumericValueAccessor,
|
||||
c.RadioValueAccessor,
|
||||
c.SelectValueAccessor,
|
||||
c.TextValueAccessor,
|
||||
|
||||
// navigation
|
||||
c.IonBackButton,
|
||||
c.IonRouterOutlet,
|
||||
c.RouterDirection,
|
||||
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.Config,
|
||||
p.LoadingController,
|
||||
p.PickerController,
|
||||
p.ToastController,
|
||||
p.MenuController,
|
||||
p.NavController,
|
||||
p.Platform,
|
||||
p.Events,
|
||||
p.DomController
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: DECLARATIONS,
|
||||
exports: DECLARATIONS,
|
||||
providers: [p.AngularDelegate, p.ModalController, p.PopoverController],
|
||||
imports: [CommonModule]
|
||||
})
|
||||
export class IonicModule {
|
||||
static forRoot(config?: IonicConfig): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: IonicModule,
|
||||
providers: [
|
||||
{
|
||||
provide: ConfigToken,
|
||||
useValue: config
|
||||
},
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: appInitialize,
|
||||
multi: true,
|
||||
deps: [
|
||||
ConfigToken
|
||||
]
|
||||
},
|
||||
...PROVIDERS
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
import { ApplicationRef, ComponentFactoryResolver, Injectable, InjectionToken, Injector, NgZone, ViewContainerRef } from '@angular/core';
|
||||
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
|
||||
import { NavParams } from '../directives/navigation/nav-params';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class AngularDelegate {
|
||||
|
||||
constructor(
|
||||
private zone: NgZone,
|
||||
private appRef: ApplicationRef
|
||||
) {}
|
||||
|
||||
create(
|
||||
resolver: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
location?: ViewContainerRef,
|
||||
) {
|
||||
return new AngularFrameworkDelegate(resolver, injector, location, this.appRef, this.zone);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class AngularFrameworkDelegate implements FrameworkDelegate {
|
||||
|
||||
private elRefMap = new WeakMap<HTMLElement, any>();
|
||||
|
||||
constructor(
|
||||
private resolver: ComponentFactoryResolver,
|
||||
private injector: Injector,
|
||||
private location: ViewContainerRef | undefined,
|
||||
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.resolver, this.injector, this.location, 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(
|
||||
resolver: ComponentFactoryResolver,
|
||||
injector: Injector,
|
||||
location: ViewContainerRef | undefined,
|
||||
appRef: ApplicationRef,
|
||||
elRefMap: WeakMap<HTMLElement, any>,
|
||||
container: any, component: any, params: any, cssClasses: string[] | undefined
|
||||
) {
|
||||
const factory = resolver.resolveComponentFactory(component);
|
||||
const childInjector = Injector.create({
|
||||
providers: getProviders(params),
|
||||
parent: injector
|
||||
});
|
||||
const componentRef = (location)
|
||||
? location.createComponent(factory, location.length, childInjector)
|
||||
: factory.create(childInjector);
|
||||
|
||||
const instance = componentRef.instance;
|
||||
const hostElement = componentRef.location.nativeElement;
|
||||
if (params) {
|
||||
Object.assign(instance, params);
|
||||
}
|
||||
if (cssClasses) {
|
||||
for (const clazz of cssClasses) {
|
||||
hostElement.classList.add(clazz);
|
||||
}
|
||||
}
|
||||
bindLifecycleEvents(instance, hostElement);
|
||||
container.appendChild(hostElement);
|
||||
|
||||
if (!location) {
|
||||
appRef.attachView(componentRef.hostView);
|
||||
}
|
||||
|
||||
componentRef.changeDetectorRef.reattach();
|
||||
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: any) => {
|
||||
if (typeof instance[eventName] === 'function') {
|
||||
instance[eventName](ev.detail);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const NavParamsToken = new InjectionToken<any>('NavParamsToken');
|
||||
|
||||
|
||||
function getProviders(params: {[key: string]: any}) {
|
||||
return [
|
||||
{
|
||||
provide: NavParamsToken, useValue: params
|
||||
},
|
||||
{
|
||||
provide: NavParams, useFactory: provideNavParamsInjectable, deps: [NavParamsToken]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function provideNavParamsInjectable(params: {[key: string]: any}) {
|
||||
return new NavParams(params);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import { Config as CoreConfig, IonicConfig } from '@ionic/core';
|
||||
import { InjectionToken } from '@angular/core';
|
||||
import { IonicWindow } from '../types/interfaces';
|
||||
|
||||
|
||||
export class Config {
|
||||
|
||||
get(key: keyof IonicConfig, fallback?: any): any {
|
||||
const c = getConfig();
|
||||
if (c) {
|
||||
return c.get(key, fallback);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getBoolean(key: keyof IonicConfig, fallback?: boolean): boolean {
|
||||
const c = getConfig();
|
||||
if (c) {
|
||||
return c.getBoolean(key, fallback);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
getNumber(key: keyof IonicConfig, fallback?: number): number {
|
||||
const c = getConfig();
|
||||
if (c) {
|
||||
return c.getNumber(key, fallback);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
set(key: keyof IonicConfig, value?: any) {
|
||||
const c = getConfig();
|
||||
if (c) {
|
||||
c.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const ConfigToken = new InjectionToken<any>('USERCONFIG');
|
||||
|
||||
function getConfig(): CoreConfig | null {
|
||||
const win: IonicWindow = window as any;
|
||||
if (typeof win !== 'undefined') {
|
||||
const Ionic = win.Ionic;
|
||||
if (Ionic && Ionic.config) {
|
||||
return Ionic.config;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class DomController {
|
||||
|
||||
read(cb: RafCallback) {
|
||||
getQueue().read(cb);
|
||||
}
|
||||
|
||||
write(cb: RafCallback) {
|
||||
getQueue().write(cb);
|
||||
}
|
||||
}
|
||||
|
||||
function getQueue() {
|
||||
const Ionic = (window as any).Ionic;
|
||||
if (Ionic && Ionic.queue) {
|
||||
return Ionic.queue;
|
||||
}
|
||||
|
||||
return {
|
||||
read: (cb: any) => window.requestAnimationFrame(cb),
|
||||
write: (cb: any) => window.requestAnimationFrame(cb)
|
||||
};
|
||||
}
|
||||
|
||||
export type RafCallback = (timeStamp?: number) => void;
|
||||
@@ -1,95 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
|
||||
export type EventHandler = (...args: any[]) => any;
|
||||
@Injectable()
|
||||
export class Events {
|
||||
private c = new Map<string, EventHandler[]>();
|
||||
|
||||
/**
|
||||
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
|
||||
*
|
||||
* @param topic the topic to subscribe to
|
||||
* @param handler the event handler
|
||||
*/
|
||||
subscribe(topic: string, ...handlers: EventHandler[]) {
|
||||
let topics = this.c.get(topic);
|
||||
if (!topics) {
|
||||
this.c.set(topic, topics = []);
|
||||
}
|
||||
topics.push(...handlers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
|
||||
*
|
||||
* @param topic the topic to unsubscribe from
|
||||
* @param handler the event handler
|
||||
*
|
||||
* @return true if a handler was removed
|
||||
*/
|
||||
unsubscribe(topic: string, handler?: EventHandler): boolean {
|
||||
if (!handler) {
|
||||
return this.c.delete(topic);
|
||||
}
|
||||
|
||||
const topics = this.c.get(topic);
|
||||
if (!topics) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to find and remove a specific handler
|
||||
const index = topics.indexOf(handler);
|
||||
|
||||
if (index < 0) {
|
||||
// Wasn't found, wasn't removed
|
||||
return false;
|
||||
}
|
||||
topics.splice(index, 1);
|
||||
if (topics.length === 0) {
|
||||
this.c.delete(topic);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish an event to the given topic.
|
||||
*
|
||||
* @param topic the topic to publish to
|
||||
* @param eventData the data to send as the event
|
||||
*/
|
||||
publish(topic: string, ...args: any[]): any[] | null {
|
||||
const topics = this.c.get(topic);
|
||||
if (!topics) {
|
||||
return null;
|
||||
}
|
||||
return topics.map(handler => {
|
||||
try {
|
||||
return handler(...args);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function setupEvents() {
|
||||
const events = new Events();
|
||||
|
||||
window.addEventListener('online', ev => events.publish('app:online', ev));
|
||||
|
||||
window.addEventListener('offline', ev => events.publish('app:offline', ev));
|
||||
|
||||
window.addEventListener('orientationchange', ev => events.publish('app:rotated', ev));
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
export function setupProvideEvents() {
|
||||
return () => {
|
||||
return setupEvents();
|
||||
};
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
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';
|
||||
export { DomController } from './dom-controller';
|
||||
export { Config, ConfigToken } from './config';
|
||||
@@ -1,10 +0,0 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { proxyMethod } from '../util/util';
|
||||
|
||||
const CTRL = 'ion-menu-controller';
|
||||
@Injectable()
|
||||
export class MenuController {
|
||||
|
||||
/**
|
||||
* Programmatically open the Menu.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu is fully opened
|
||||
*/
|
||||
open(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'open', menuId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Programmatically close the Menu. If no `menuId` is given as the first
|
||||
* argument then it'll close any menu which is open. If a `menuId`
|
||||
* is given then it'll close that exact menu.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu is fully closed
|
||||
*/
|
||||
close(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'close', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the menu. If it's closed, it will open, and if opened, it
|
||||
* will close.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return returns a promise when the menu has been toggled
|
||||
*/
|
||||
toggle(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'toggle', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to enable or disable a menu. For example, there could be multiple
|
||||
* left menus, but only one of them should be able to be opened at the same
|
||||
* time. If there are multiple menus on the same side, then enabling one menu
|
||||
* will also automatically disable all the others that are on the same side.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'enable', shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to enable or disable the ability to swipe open the menu.
|
||||
* @param shouldEnable True if it should be swipe-able, false if not.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu, which is useful for chaining.
|
||||
*/
|
||||
swipeEnable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'swipeEnable', shouldEnable, menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns true if the specified menu is currently open, otherwise false.
|
||||
* If the menuId is not specified, it returns true if ANY menu is currenly open.
|
||||
*/
|
||||
isOpen(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'isOpen', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns true if the menu is currently enabled, otherwise false.
|
||||
*/
|
||||
isEnabled(menuId?: string): Promise<boolean> {
|
||||
return proxyMethod(CTRL, 'isEnabled', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a menu instance. If a `menuId` is not provided then it'll
|
||||
* return the first menu found. If a `menuId` is `left` or `right`, then
|
||||
* it'll return the enabled menu on that side. Otherwise, if a `menuId` is
|
||||
* provided, then it'll try to find the menu using the menu's `id`
|
||||
* property. If a menu is not found then it'll return `null`.
|
||||
* @param [menuId] Optionally get the menu by its id, or side.
|
||||
* @return Returns the instance of the menu if found, otherwise `null`.
|
||||
*/
|
||||
get(menuId?: string): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'get', menuId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the instance of the menu already opened, otherwise `null`.
|
||||
*/
|
||||
getOpen(): Promise<HTMLIonMenuElement> {
|
||||
return proxyMethod(CTRL, 'getOpen');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns an array of all menu instances.
|
||||
*/
|
||||
getMenus(): Promise<HTMLIonMenuElement[]> {
|
||||
return proxyMethod(CTRL, 'getMenus');
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
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 angularDelegate: AngularDelegate,
|
||||
private resolver: ComponentFactoryResolver,
|
||||
private injector: Injector,
|
||||
) {
|
||||
super('ion-modal-controller');
|
||||
}
|
||||
|
||||
create(opts: ModalOptions): Promise<HTMLIonModalElement> {
|
||||
return super.create({
|
||||
...opts,
|
||||
delegate: this.angularDelegate.create(this.resolver, this.injector)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
import { Injectable, Optional } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { NavigationExtras, Router, UrlTree } from '@angular/router';
|
||||
import { BackButtonEvent } from '@ionic/core';
|
||||
|
||||
export const enum NavIntent {
|
||||
Auto,
|
||||
Forward,
|
||||
Back,
|
||||
Root
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class NavController {
|
||||
|
||||
private intent: NavIntent = NavIntent.Auto;
|
||||
private animated = true;
|
||||
private stack: string[] = [];
|
||||
|
||||
constructor(
|
||||
private location: Location,
|
||||
@Optional() private router?: Router
|
||||
) {
|
||||
window && window.document.addEventListener('ionBackButton', (ev) => {
|
||||
(ev as BackButtonEvent).detail.register(0, () => this.goBack());
|
||||
});
|
||||
}
|
||||
|
||||
navigateForward(url: string | UrlTree | any[], animated?: boolean, extras?: NavigationExtras) {
|
||||
this.setIntent(NavIntent.Forward, animated);
|
||||
if (Array.isArray(url)) {
|
||||
return this.router!.navigate(url, extras);
|
||||
} else {
|
||||
return this.router!.navigateByUrl(url, extras);
|
||||
}
|
||||
}
|
||||
|
||||
navigateBack(url: string | UrlTree | any[], animated?: boolean, extras?: NavigationExtras) {
|
||||
this.setIntent(NavIntent.Back, animated);
|
||||
extras = { replaceUrl: true, ...extras };
|
||||
if (Array.isArray(url)) {
|
||||
return this.router!.navigate(url, extras);
|
||||
} else {
|
||||
return this.router!.navigateByUrl(url, extras);
|
||||
}
|
||||
}
|
||||
|
||||
navigateRoot(url: string | UrlTree | any[], animated?: boolean, extras?: NavigationExtras) {
|
||||
this.setIntent(NavIntent.Root, animated);
|
||||
if (Array.isArray(url)) {
|
||||
return this.router!.navigate(url, extras);
|
||||
} else {
|
||||
return this.router!.navigateByUrl(url, extras);
|
||||
}
|
||||
}
|
||||
|
||||
goBack(animated?: boolean) {
|
||||
this.setIntent(NavIntent.Back, animated);
|
||||
return this.location.back();
|
||||
}
|
||||
|
||||
setIntent(intent: NavIntent, animated?: boolean) {
|
||||
this.intent = intent;
|
||||
this.animated = (animated === undefined)
|
||||
? intent !== NavIntent.Root
|
||||
: animated;
|
||||
}
|
||||
|
||||
consumeTransition() {
|
||||
const guessDirection = this.guessDirection();
|
||||
|
||||
let direction = 0;
|
||||
let animated = false;
|
||||
|
||||
if (this.intent === NavIntent.Auto) {
|
||||
direction = guessDirection;
|
||||
animated = direction !== 0;
|
||||
} else {
|
||||
animated = this.animated;
|
||||
direction = intentToDirection(this.intent);
|
||||
}
|
||||
this.intent = NavIntent.Auto;
|
||||
this.animated = true;
|
||||
|
||||
return {
|
||||
direction,
|
||||
animated
|
||||
};
|
||||
}
|
||||
|
||||
private guessDirection() {
|
||||
const index = this.stack.indexOf(document.location.href);
|
||||
if (index === -1) {
|
||||
this.stack.push(document.location.href);
|
||||
return 1;
|
||||
} else if (index < this.stack.length - 1) {
|
||||
this.stack = this.stack.slice(0, index + 1);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function intentToDirection(intent: NavIntent): number {
|
||||
switch (intent) {
|
||||
case NavIntent.Forward: return 1;
|
||||
case NavIntent.Back: return -1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
import { EventEmitter, Injectable } from '@angular/core';
|
||||
import { BackButtonDetail, Platforms, getPlatforms, isPlatform } from '@ionic/core';
|
||||
import { proxyEvent } from '../util/util';
|
||||
|
||||
|
||||
export class BackButtonEmitter extends EventEmitter<BackButtonDetail> {
|
||||
subscribeWithPriority(priority: number, callback: () => Promise<any> | void) {
|
||||
return this.subscribe((ev: BackButtonDetail) => {
|
||||
ev.register(priority, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class Platform {
|
||||
|
||||
private _readyPromise: Promise<string>;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
backButton = new BackButtonEmitter();
|
||||
|
||||
/**
|
||||
* The pause event emits when the native platform puts the application
|
||||
* into the background, typically when the user switches to a different
|
||||
* application. This event would emit when a Cordova app is put into
|
||||
* the background, however, it would not fire on a standard web browser.
|
||||
*/
|
||||
pause = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* The resume event emits when the native platform pulls the application
|
||||
* out from the background. This event would emit when a Cordova app comes
|
||||
* out from the background, however, it would not fire on a standard web browser.
|
||||
*/
|
||||
resume = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* The resize event emits when the browser window has changed dimensions. This
|
||||
* could be from a browser window being physically resized, or from a device
|
||||
* changing orientation.
|
||||
*/
|
||||
resize = new EventEmitter<void>();
|
||||
|
||||
constructor() {
|
||||
proxyEvent(this.pause, document, 'pause');
|
||||
proxyEvent(this.resume, document, 'resume');
|
||||
proxyEvent(this.backButton, document, 'ionBackButton');
|
||||
proxyEvent(this.resize, window, 'resize');
|
||||
|
||||
let readyResolve: (value: string) => void;
|
||||
this._readyPromise = new Promise(res => { readyResolve = res; });
|
||||
if ((window as any)['cordova']) {
|
||||
document.addEventListener('deviceready', () => {
|
||||
readyResolve('cordova');
|
||||
}, { once: true });
|
||||
} else {
|
||||
readyResolve!('dom');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns returns true/false based on platform.
|
||||
* @description
|
||||
* Depending on the platform the user is on, `is(platformName)` will
|
||||
* return `true` or `false`. Note that the same app can return `true`
|
||||
* for more than one platform name. For example, an app running from
|
||||
* an iPad would return `true` for the platform names: `mobile`,
|
||||
* `ios`, `ipad`, and `tablet`. Additionally, if the app was running
|
||||
* from Cordova then `cordova` would be true, and if it was running
|
||||
* from a web browser on the iPad then `mobileweb` would be `true`.
|
||||
*
|
||||
* ```
|
||||
* import { Platform } from 'ionic-angular';
|
||||
*
|
||||
* @Component({...})
|
||||
* export MyPage {
|
||||
* constructor(public platform: Platform) {
|
||||
* if (this.platform.is('ios')) {
|
||||
* // This will only print when on iOS
|
||||
* console.log('I am an iOS device!');
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* | Platform Name | Description |
|
||||
* |-----------------|------------------------------------|
|
||||
* | android | on a device running Android. |
|
||||
* | cordova | on a device running Cordova. |
|
||||
* | ios | on a device running iOS. |
|
||||
* | ipad | on an iPad device. |
|
||||
* | iphone | on an iPhone device. |
|
||||
* | phablet | on a phablet device. |
|
||||
* | tablet | on a tablet device. |
|
||||
* | electron | in Electron on a desktop device. |
|
||||
* | pwa | as a PWA app. |
|
||||
* | mobile | on a mobile device. |
|
||||
* | desktop | on a desktop device. |
|
||||
* | hybrid | is a cordova or capacitor app. |
|
||||
*
|
||||
*/
|
||||
is(platformName: Platforms): boolean {
|
||||
return isPlatform(window, platformName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the array of platforms
|
||||
* @description
|
||||
* Depending on what device you are on, `platforms` can return multiple values.
|
||||
* Each possible value is a hierarchy of platforms. For example, on an iPhone,
|
||||
* it would return `mobile`, `ios`, and `iphone`.
|
||||
*
|
||||
* ```
|
||||
* import { Platform } from 'ionic-angular';
|
||||
*
|
||||
* @Component({...})
|
||||
* export MyPage {
|
||||
* constructor(public platform: Platform) {
|
||||
* // This will print an array of the current platforms
|
||||
* console.log(this.platform.platforms());
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
platforms(): string[] {
|
||||
return getPlatforms(window);
|
||||
}
|
||||
|
||||
ready(): Promise<string> {
|
||||
return this._readyPromise;
|
||||
}
|
||||
|
||||
get isRTL(): boolean {
|
||||
return document.dir === 'rtl';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query string parameter
|
||||
*/
|
||||
getQueryParam(key: string): string | null {
|
||||
return readQueryParam(window.location.href, key);
|
||||
}
|
||||
|
||||
isLandscape(): boolean {
|
||||
return !this.isPortrait();
|
||||
}
|
||||
|
||||
isPortrait(): boolean {
|
||||
return window.matchMedia('(orientation: portrait)').matches;
|
||||
}
|
||||
|
||||
testUserAgent(expression: string): boolean {
|
||||
return navigator.userAgent.indexOf(expression) >= 0;
|
||||
}
|
||||
|
||||
url() {
|
||||
return window.location.href;
|
||||
}
|
||||
|
||||
width() {
|
||||
return window.innerWidth;
|
||||
}
|
||||
|
||||
height(): number {
|
||||
return window.innerHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function readQueryParam(url: string, key: string) {
|
||||
key = key.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
|
||||
const regex = new RegExp('[\\?&]' + key + '=([^&#]*)');
|
||||
const results = regex.exec(url);
|
||||
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
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 angularDelegate: AngularDelegate,
|
||||
private resolver: ComponentFactoryResolver,
|
||||
private injector: Injector,
|
||||
) {
|
||||
super('ion-popover-controller');
|
||||
}
|
||||
|
||||
create(opts: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
||||
return super.create({
|
||||
...opts,
|
||||
delegate: this.angularDelegate.create(this.resolver, this.injector)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
export interface IonicGlobal {
|
||||
config?: any;
|
||||
ael?: (elm: any, eventName: string, cb: (ev: Event) => void, opts: any) => void;
|
||||
raf?: (ts: number) => void;
|
||||
rel?: (elm: any, eventName: string, cb: (ev: Event) => void, opts: any) => void;
|
||||
asyncQueue?: boolean;
|
||||
}
|
||||
|
||||
export interface IonicWindow extends Window {
|
||||
Ionic: IonicGlobal;
|
||||
__zone_symbol__requestAnimationFrame: (ts: number) => void;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
export class IonicRouteStrategy implements RouteReuseStrategy {
|
||||
|
||||
shouldDetach(_route: ActivatedRouteSnapshot): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
shouldAttach(_route: ActivatedRouteSnapshot): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
store(_route: ActivatedRouteSnapshot, _detachedTree: DetachedRouteHandle): void {
|
||||
return;
|
||||
}
|
||||
|
||||
retrieve(_route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
shouldReuseRoute(
|
||||
future: ActivatedRouteSnapshot,
|
||||
curr: ActivatedRouteSnapshot
|
||||
): boolean {
|
||||
if (future.routeConfig !== curr.routeConfig) {
|
||||
return false;
|
||||
}
|
||||
if (future.component !== curr.component) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// checking router params
|
||||
const futureParams = future.params;
|
||||
const currentParams = curr.params;
|
||||
const keysA = Object.keys(futureParams);
|
||||
const keysB = Object.keys(currentParams);
|
||||
|
||||
if (keysA.length !== keysB.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test for A's keys different from B.
|
||||
for (const key of keysA) {
|
||||
if (currentParams[key] !== futureParams[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
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?: string): Promise<void> {
|
||||
return proxyMethod(this.ctrl, 'dismiss', data, role, id);
|
||||
}
|
||||
|
||||
getTop(): Promise<Overlay> {
|
||||
return proxyMethod(this.ctrl, 'getTop');
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { ElementRef, EventEmitter } from '@angular/core';
|
||||
|
||||
export function inputs(instance: any, el: ElementRef, props: string[]) {
|
||||
props.forEach(propName => {
|
||||
Object.defineProperty(instance, propName, {
|
||||
get: () => el.nativeElement[propName], set: (val: any) => el.nativeElement[propName] = val
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function proxyEvent<T>(emitter: EventEmitter<T>, el: EventTarget, eventName: string) {
|
||||
el.addEventListener(eventName, (ev) => {
|
||||
emitter.emit(ev ? (ev as any).detail as T : undefined);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function proxyMethod(ctrlName: string, methodName: string, ...args: any[]) {
|
||||
const controller = ensureElementInBody(ctrlName);
|
||||
return controller.componentOnReady()
|
||||
.then(() => (controller as any)[methodName].apply(controller, args));
|
||||
}
|
||||
|
||||
export function ensureElementInBody(elementName: string) {
|
||||
let element = document.querySelector(elementName);
|
||||
if (!element) {
|
||||
element = document.createElement(elementName);
|
||||
document.body.appendChild(element);
|
||||
}
|
||||
return element as HTMLStencilElement;
|
||||
}
|
||||
|
||||
export function deepEqual(x: any, y: any) {
|
||||
if (x === y) {
|
||||
return true;
|
||||
} else if (typeof x === 'object' && x != null && (typeof y === 'object' && y != null)) {
|
||||
if (Object.keys(x).length !== Object.keys(y).length) return false;
|
||||
|
||||
for (const prop in x) {
|
||||
if (y.hasOwnProperty(prop)) {
|
||||
if (!deepEqual(x[prop], y[prop])) return false;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
39
angular/test/testapp/.gitignore
vendored
39
angular/test/testapp/.gitignore
vendored
@@ -1,39 +0,0 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -1,27 +0,0 @@
|
||||
# Testapp
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.0.
|
||||
|
||||
## Developing
|
||||
|
||||
Run `npm run serve` to copy ionic and run a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
@@ -1,127 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"testapp": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/testapp",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets",
|
||||
{
|
||||
"glob": "**/*.svg",
|
||||
"input": "../../dist/ionic/svg",
|
||||
"output": "./svg"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "testapp:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "testapp:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "testapp:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"styles": [
|
||||
"styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"testapp-e2e": {
|
||||
"root": "e2e/",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "testapp:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "testapp"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { AppPage } from './app.po';
|
||||
|
||||
describe('workspace-project App', () => {
|
||||
let page: AppPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new AppPage();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
||||
10428
angular/test/testapp/package-lock.json
generated
10428
angular/test/testapp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"name": "testapp",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "npm run copy-ionic-angular && ng",
|
||||
"serve": "npm run copy-ionic-angular && ng serve",
|
||||
"serve.aot": "npm run copy-ionic-angular && ng serve --aot",
|
||||
"build": "npm run copy-ionic-angular && ng build",
|
||||
"build.aot": "npm run copy-ionic-angular && ng build --aot",
|
||||
"build.prod": "npm run copy-ionic-angular && ng build --prod --aot",
|
||||
"test": "npm run copy-ionic-angular && ng test",
|
||||
"lint": "npm run copy-ionic-angular && ng lint",
|
||||
"e2e": "npm run copy-ionic-angular && ng e2e",
|
||||
"copy-ionic-angular": "node ../../scripts/link-copy.js ionic/angular/test/testapp"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^6.0.9",
|
||||
"@angular/common": "^6.0.9",
|
||||
"@angular/compiler": "^6.0.9",
|
||||
"@angular/core": "^6.0.9",
|
||||
"@angular/forms": "^6.0.9",
|
||||
"@angular/http": "^6.0.9",
|
||||
"@angular/platform-browser": "^6.0.9",
|
||||
"@angular/platform-browser-dynamic": "^6.0.9",
|
||||
"@angular/router": "^6.0.9",
|
||||
"@ionic/angular": "^4.0.0-alpha.6",
|
||||
"core-js": "^2.5.4",
|
||||
"rxjs": "^6.0.9",
|
||||
"zone.js": "^0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.6.0",
|
||||
"@angular/cli": "^6.0.8",
|
||||
"@angular/compiler-cli": "^6.0.9",
|
||||
"@angular/language-service": "^6.0.9",
|
||||
"@types/jasmine": "~2.8.6",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "~8.9.4",
|
||||
"codelyzer": "~4.2.1",
|
||||
"ionicons": "^4.2.4",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"karma": "~1.7.1",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "~1.4.2",
|
||||
"karma-jasmine": "~1.1.1",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"protractor": "~5.3.0",
|
||||
"ts-node": "~5.0.1",
|
||||
"tslint": "~5.9.1",
|
||||
"typescript": "~2.7.2"
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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]
|
||||
})
|
||||
export class ActionSheetModule { }
|
||||
@@ -1,48 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { AlertController } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-alert-page',
|
||||
template: `
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Alert</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-button (click)="clickMe()">Open Basic Alert</ion-button>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
`
|
||||
})
|
||||
export class AlertPageComponent {
|
||||
|
||||
constructor(private alertController: AlertController) {}
|
||||
|
||||
async clickMe() {
|
||||
const alert = await this.alertController.create({
|
||||
header: 'ohhhh snap',
|
||||
message: 'Ive been injected via Angular keeping the old api',
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'Cancel',
|
||||
handler: () => {
|
||||
// console.log('cancel');
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Okay',
|
||||
role: 'Okay',
|
||||
handler: () => {
|
||||
// console.log('okay');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
return alert.present();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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]
|
||||
})
|
||||
export class AlertModule { }
|
||||
@@ -1,36 +0,0 @@
|
||||
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: 'button', loadChildren: './button/button.module#ButtonModule' },
|
||||
{ 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 { }
|
||||
@@ -1,22 +0,0 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { PostTestService } from './post-test/post-test.service';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [
|
||||
AppRoutingModule,
|
||||
BrowserModule,
|
||||
HttpClientModule,
|
||||
IonicModule.forRoot(),
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
providers: [PostTestService]
|
||||
})
|
||||
export class AppModule { }
|
||||
@@ -1,95 +0,0 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Badge } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-badge-page',
|
||||
template: `
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Badges</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-list-header>Badges Right</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-badge slot="end" color="primary">99</ion-badge>
|
||||
<ion-label>Default Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="end" color="primary">99</ion-badge>
|
||||
<ion-label>Primary Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="end" color="secondary">99</ion-badge>
|
||||
<ion-label>Secondary Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="end" color="danger">99</ion-badge>
|
||||
<ion-label>Danger Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="end" color="light">99</ion-badge>
|
||||
<ion-label>Light Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="end" color="dark">99</ion-badge>
|
||||
<ion-label>Dark Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item (click)="toggleColor()">
|
||||
<ion-badge slot="end" [color]="dynamicColor">{{dynamicColor}}</ion-badge>
|
||||
<ion-label>Dynamic Badge Color (toggle)</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-list-header>Badges Left</ion-list-header>
|
||||
<ion-item>
|
||||
<ion-badge slot="start" color="primary">99</ion-badge>
|
||||
<ion-label>Default Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="start" color="primary">99</ion-badge>
|
||||
<ion-label>Primary Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="start" color="secondary">99</ion-badge>
|
||||
<ion-label>Secondary Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="start" color="danger">99</ion-badge>
|
||||
<ion-label>Danger Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="start" color="light">99</ion-badge>
|
||||
<ion-label>Light Badge</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-badge slot="start" color="dark">99</ion-badge>
|
||||
<ion-label>Dark Badge</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
`
|
||||
})
|
||||
export class BadgePageComponent implements OnInit {
|
||||
dynamicColor = 'primary';
|
||||
|
||||
@ViewChild(Badge) badge: Badge;
|
||||
|
||||
ngOnInit() {
|
||||
console.log(this.badge);
|
||||
}
|
||||
|
||||
toggleColor() {
|
||||
if (this.dynamicColor === 'primary') {
|
||||
this.dynamicColor = 'secondary';
|
||||
} else if (this.dynamicColor === 'secondary') {
|
||||
this.dynamicColor = 'danger';
|
||||
} else {
|
||||
this.dynamicColor = 'primary';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { BadgePageComponent } from './badge-page.component';
|
||||
import { BadgeRoutingModule } from './badge-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
BadgeRoutingModule,
|
||||
IonicModule
|
||||
],
|
||||
declarations: [BadgePageComponent]
|
||||
})
|
||||
export class BadgeModule { }
|
||||
@@ -1,275 +0,0 @@
|
||||
<ion-app>
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Basic Inputs</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<ion-grid>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Disable Inputs</ion-label>
|
||||
<ion-checkbox id="disableCheckbox" name="disableCheckbox" [(ngModel)]="disableInputs"></ion-checkbox>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Text Input</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdTextInput">Standard Input</label>
|
||||
<input id="stdTextInput" name="stdTextInput" [(ngModel)]="textValue" minlength="10" [disabled]="disableInputs" />
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="textOutput">{{textValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Text Input</ion-label>
|
||||
<ion-input id="ionTextInput" name="ionTextInput" [(ngModel)]="textValue" minlength="10" [disabled]="disableInputs"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Search Input</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Text Input</ion-label>
|
||||
<ion-searchbar id="ionSearchInput" name="ionSearchInput" [(ngModel)]="searchValue" minlength="10" [disabled]="disableInputs"></ion-searchbar>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="searchOutput">{{searchValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Numeric Input</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Numeric Input</ion-label>
|
||||
<ion-input type="number" id="ionNumericInput" name="ionNumericInput" [(ngModel)]="numericValue" [disabled]="disableInputs"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<div>
|
||||
Value:
|
||||
<span id="numericOutput">{{numericValue}}</span>
|
||||
</div>
|
||||
<div>
|
||||
Type:
|
||||
<span id="numericOutputType">{{typeOf(numericValue)}}</span>
|
||||
</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Textarea Input</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdTextareaInput">Standard Textarea Input</label>
|
||||
<textarea id="stdTextareaInput" name="stdTextareaInput" [(ngModel)]="textareaValue" minlength="10" [disabled]="disableInputs"></textarea>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="textareaOutput">{{textareaValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Textarea Input</ion-label>
|
||||
<ion-textarea id="ionTextareaInput" name="ionTextareaInput" [(ngModel)]="textareaValue" minlength="10" [disabled]="disableInputs"></ion-textarea>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Checkbox</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdCheckbox">Standard Checkbox</label>
|
||||
<input type="checkbox" id="stdCheckbox" name="stdCheckbox" [(ngModel)]="checkboxValue" [disabled]="disableInputs" />
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="checkboxOutput">{{checkboxValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Checkbox</ion-label>
|
||||
<ion-checkbox id="ionCheckbox" name="ionCheckbox" [(ngModel)]="checkboxValue" [disabled]="disableInputs"></ion-checkbox>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Checkbox No ngModel</ion-label>
|
||||
<ion-checkbox id="ionCheckboxNoModel" name="ionCheckboxNoModel" [checked]="checkboxValue" (ionChange)="checkboxValue=$event.target.checked"
|
||||
[disabled]="disableInputs"></ion-checkbox>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Toggle</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdToggle">Standard Toggle</label>
|
||||
<input type="checkbox" id="stdToggle" name="stdToggle" [(ngModel)]="toggleValue" [disabled]="disableInputs" />
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="toggleOutput">{{toggleValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Toggle</ion-label>
|
||||
<ion-toggle id="ionToggle" name="ionToggle" [(ngModel)]="toggleValue" [disabled]="disableInputs"></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Select</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdSelect">Select</label>
|
||||
<select id="stdSelect" name="stdSelect" [(ngModel)]="selectValue" placeholder="YYYY-MM-DDTHH:mm:ssZ" [disabled]="disableInputs">
|
||||
<option value="bacon">Bacon</option>
|
||||
<option value="pepperoni">Pepperoni</option>
|
||||
<option value="ham" selected>Ham</option>
|
||||
<option value="sausage">Sausage</option>
|
||||
<option value="pineapple">Pineapple</option>
|
||||
</select>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="selectOutput">{{selectValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Select</ion-label>
|
||||
<ion-select id="ionSelectInput" [(ngModel)]="selectValue" [disabled]="disableInputs">
|
||||
<ion-select-option value="bacon">Bacon</ion-select-option>
|
||||
<ion-select-option value="pepperoni">Pepperoni</ion-select-option>
|
||||
<ion-select-option value="ham" selected>Ham</ion-select-option>
|
||||
<ion-select-option value="sausage">Sausage</ion-select-option>
|
||||
<ion-select-option value="pineapple">Pineapple</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Date Time Picker</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdToggle">ISO Formatted Date</label>
|
||||
<input id="stdDatetimeInput" name="stdDatetimeInput" [(ngModel)]="datetimeValue" placeholder="YYYY-MM-DDTHH:mm:ssZ" [disabled]="disableInputs"
|
||||
/>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span id="datetimeOutput">{{datetimeValue}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Date</ion-label>
|
||||
<ion-datetime id="ionDatetimeInput" pickerFormat="YYYY-MM-DD HH:mm:ss" displayFormat="MM/DD/YYYY HH:mm:ss" name="ionDatetimeInput"
|
||||
[(ngModel)]="datetimeValue" [disabled]="disableInputs"></ion-datetime>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Range</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<label for="stdRangeInput">Range Value</label>
|
||||
<input id="stdRangeInput" type="number" [(ngModel)]="rangeValue" [disabled]="disableInputs" />
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
Value:
|
||||
<span>{{rangeValue}}</span>
|
||||
<span>{{typeOf(rangeValue)}}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-range id="ionRangeInput" [(ngModel)]="rangeValue" [disabled]="disableInputs"></ion-range>
|
||||
</ion-col>
|
||||
<ion-col></ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<a href='home'>Home</a>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
|
||||
</ion-app>
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Component, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-basic-inputs-page',
|
||||
templateUrl: './basic-inputs-page.component.html',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class BasicInputsPageComponent {
|
||||
disableInputs = false;
|
||||
|
||||
datetimeValue = '2017-11-18T14:17:45-06:00';
|
||||
textareaValue = 'This is the Textarea Input';
|
||||
textValue = 'This is the Text Input';
|
||||
numericValue = 1138;
|
||||
selectValue = 'pineapple';
|
||||
|
||||
checkboxValue = true;
|
||||
toggleValue = false;
|
||||
|
||||
rangeValue = 15;
|
||||
|
||||
searchValue: string;
|
||||
|
||||
typeOf(v: any): string {
|
||||
return typeof v;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { BasicInputsPageComponent } from './basic-inputs-page.component';
|
||||
import { BasicInputsPageRoutingModule } from './basic-inputs-page-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BasicInputsPageRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule
|
||||
],
|
||||
declarations: [BasicInputsPageComponent]
|
||||
})
|
||||
export class BasicInputsPageModule {}
|
||||
@@ -1,49 +0,0 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Button } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-button-page',
|
||||
template: `
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Buttons</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-button>Default</ion-button>
|
||||
<ion-button color="primary">Primary</ion-button>
|
||||
<ion-button [color]="dynamicColor" (click)="toggleColor()">{{ dynamicColor }}</ion-button>
|
||||
|
||||
<p>
|
||||
<ion-button (click)="disableClick()" [disabled]="isDisabled">Disabled</ion-button>
|
||||
<ion-button (click)="isDisabled = !isDisabled">Toggle Disabled</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
`
|
||||
})
|
||||
export class ButtonPageComponent implements OnInit {
|
||||
dynamicColor = 'primary';
|
||||
isDisabled = true;
|
||||
|
||||
@ViewChild(Button) button: Button;
|
||||
|
||||
ngOnInit() {
|
||||
console.log(this.button);
|
||||
}
|
||||
|
||||
disableClick() {
|
||||
console.log('Clicked disabled button');
|
||||
}
|
||||
|
||||
toggleColor() {
|
||||
if (this.dynamicColor === 'primary') {
|
||||
this.dynamicColor = 'secondary';
|
||||
} else if (this.dynamicColor === 'secondary') {
|
||||
this.dynamicColor = 'danger';
|
||||
} else {
|
||||
this.dynamicColor = 'primary';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { ButtonPageComponent } from './button-page.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: ButtonPageComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ButtonRoutingModule { }
|
||||
@@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { ButtonPageComponent } from './button-page.component';
|
||||
import { ButtonRoutingModule } from './button-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
ButtonRoutingModule,
|
||||
IonicModule
|
||||
],
|
||||
declarations: [ButtonPageComponent]
|
||||
})
|
||||
export class ButtonModule { }
|
||||
@@ -1,21 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule, DomController } from '@ionic/angular';
|
||||
import { CardPageComponent } from './card-page.component';
|
||||
import { CardRoutingModule } from './card-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
CardRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
CardPageComponent
|
||||
],
|
||||
providers: [
|
||||
DomController
|
||||
]
|
||||
})
|
||||
export class CardModule { }
|
||||
@@ -1,16 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { ContentPageComponent } from './content-page.component';
|
||||
import { ContentRoutingModule } from './content-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
ContentRoutingModule
|
||||
],
|
||||
declarations: [ContentPageComponent]
|
||||
})
|
||||
export class ContentModule { }
|
||||
@@ -1,88 +0,0 @@
|
||||
<ion-app>
|
||||
<form #myForm="ngForm" class="ion-page">
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Sample Form</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label position="floating">First Name</ion-label>
|
||||
<ion-input name="firstName" #viewFirstName="ngModel" [(ngModel)]="firstName" required minlength="2"></ion-input>
|
||||
</ion-item>
|
||||
<ion-text *ngIf="viewFirstName.invalid && (viewFirstName.dirty || viewFirstName.touched)" color="danger">
|
||||
<small *ngIf="viewFirstName.errors['required']">First Name is required</small>
|
||||
<small *ngIf="viewFirstName.errors['minlength']">First Name must be at least 2 characters long</small>
|
||||
</ion-text>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Last Name</ion-label>
|
||||
<ion-input name="lastName" #viewLastName="ngModel" [(ngModel)]="lastName" required minlength="4"></ion-input>
|
||||
</ion-item>
|
||||
<ion-text *ngIf="viewLastName.invalid && (viewLastName.dirty || viewLastName.touched)" color="danger">
|
||||
<small *ngIf="viewLastName.errors['required']">Last Name is required</small>
|
||||
<small *ngIf="viewLastName.errors['minlength']">Last Name must be at least 4 characters long</small>
|
||||
</ion-text>
|
||||
<ion-item>
|
||||
<ion-label>Desired Job Title</ion-label>
|
||||
<ion-select name="jobTitle" [(ngModel)]="jobTitle" #viewJobTitle="ngModel" required>
|
||||
<ion-select-option value="manager">Cat Herder</ion-select-option>
|
||||
<ion-select-option value="captain">Nerf Herder (Scruffy)</ion-select-option>
|
||||
<ion-select-option value="engineer">Cat</ion-select-option>
|
||||
<ion-select-option value="tester">Trier of Things</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-text *ngIf="viewJobTitle.invalid && (viewJobTitle.dirty || viewJobTitle.touched)" color="danger">
|
||||
<small *ngIf="viewJobTitle.errors['required']">Job Title is required</small>
|
||||
</ion-text>
|
||||
<ion-item-divider>
|
||||
<ion-label>I Would Like To:</ion-label>
|
||||
</ion-item-divider>
|
||||
<ion-item>
|
||||
<ion-label>Drink the Beers</ion-label>
|
||||
<ion-toggle name="drinkBeers" color="dark" [(ngModel)]="drinkBeers"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Drink the Teas</ion-label>
|
||||
<ion-toggle name="drinkTeas" color="secondary" [(ngModel)]="drinkTeas"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Make the Coffees</ion-label>
|
||||
<ion-toggle name="makeCoffee" color="primary" [(ngModel)]="makeCoffee"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Feed the Engineers</ion-label>
|
||||
<ion-toggle name="feedEngineers" color="danger" [(ngModel)]="feedEngineers"></ion-toggle>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Short Self Description</ion-label>
|
||||
<ion-textarea name="selfDescription" #viewSelfDescription="ngModel" [(ngModel)]="selfDescription" required minlength="25"></ion-textarea>
|
||||
</ion-item>
|
||||
<ion-text *ngIf="viewSelfDescription.invalid && (viewSelfDescription.dirty || viewSelfDescription.touched)" color="danger">
|
||||
<small *ngIf="viewSelfDescription.errors['required']">Self Description is required</small>
|
||||
<small *ngIf="viewSelfDescription.errors['minlength']">Please tell us more</small>
|
||||
</ion-text>
|
||||
<ion-item>
|
||||
<ion-label position="floating">Desired Salary</ion-label>
|
||||
<ion-input name="desiredSalary" #viewSalary="ngModel" type="number" required [(ngModel)]="desiredSalary"></ion-input>
|
||||
</ion-item>
|
||||
<ion-text *ngIf="viewSalary.invalid && (viewSalary.dirty || viewSalary.touched)" color="danger">
|
||||
<small *ngIf="viewSalary.errors['required']">Desired Salary is required</small>
|
||||
</ion-text>
|
||||
<ion-item-divider>
|
||||
<ion-label>My Level of Happy</ion-label>
|
||||
</ion-item-divider>
|
||||
<ion-item>
|
||||
<ion-range name="levelOfHappy" [(ngModel)]="levelOfHappy">
|
||||
<ion-icon name="sad" slot="start"></ion-icon>
|
||||
<ion-icon name="happy" slot="end"></ion-icon>
|
||||
</ion-range>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
<ion-footer>
|
||||
<ion-button expand="block" [disabled]="myForm.invalid" (click)="save(myForm.value)">
|
||||
<ion-icon name="save" slot="start"></ion-icon>Looks Good to Me</ion-button>
|
||||
</ion-footer>
|
||||
</form>
|
||||
</ion-app>
|
||||
@@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { FormSamplePageComponent } from './form-sample-page.component';
|
||||
import { FormSamplePageRoutingModule } from './form-sample-page-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormSamplePageRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule
|
||||
],
|
||||
declarations: [FormSamplePageComponent]
|
||||
})
|
||||
export class FormSamplePageModule {}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { GroupInputsPageComponent } from './group-inputs-page.component';
|
||||
|
||||
describe('GroupInputsPageComponent', () => {
|
||||
let component: GroupInputsPageComponent;
|
||||
let fixture: ComponentFixture<GroupInputsPageComponent>;
|
||||
|
||||
beforeEach(
|
||||
async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
IonicModule
|
||||
],
|
||||
declarations: [GroupInputsPageComponent]
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(GroupInputsPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { GroupInputsPageComponent } from './group-inputs-page.component';
|
||||
import { GroupInputsPageRoutingModule } from './group-inputs-page-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
GroupInputsPageRoutingModule,
|
||||
IonicModule
|
||||
],
|
||||
declarations: [GroupInputsPageComponent]
|
||||
})
|
||||
export class GroupInputsPageModule {}
|
||||
@@ -1,109 +0,0 @@
|
||||
|
||||
<h1>@ionic/angular tests</h1>
|
||||
|
||||
<h3>Overlays</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a [routerLink]="['/actionSheet']">Action Sheet Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/alert']">Alert Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/loading']">Loading Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/modal']">Modal Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/popover']">Popover Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/toast']">Toast Page</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Inputs</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a [routerLink]="['/basic-inputs']">Basic Inputs Test Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/group-inputs']">Group Inputs Test Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/form-sample']">Form Sample Test Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/segment']">Segment Page</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="no-routing-nav">No Routing</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="simple-nav/page-one">Simple Nav</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="lazy-load-tabs">Lazy Loaded Route Tabs</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a [routerLink]="['/lazy-load-tabs', 'tabs', { outlets: { tab1: ['mustang'] } }]">Tab 1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/lazy-load-tabs', 'tabs', { outlets: { tab2: ['camaro'] } }]">Tab 2</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/lazy-load-tabs', 'tabs', { outlets: { tab3: ['charger'] } }]">Tab 3</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="simple-tabs">Simple Route Tabs</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a [routerLink]="['/simple-tabs', 'tabs', { outlets: { tab1: ['mustang'] } }]">Tab 1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/simple-tabs', 'tabs', { outlets: { tab2: ['camaro'] } }]">Tab 2</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/simple-tabs', 'tabs', { outlets: { tab3: ['charger'] } }]">Tab 3</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="static-tabs">Static Tabs</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Content</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a [routerLink]="['/badge']">Badge Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/button']">Button Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/card']">Card Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/content']">Content Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/ng-if']">ngIf Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/show-hide-when']">Show/Hide When Page</a>
|
||||
</li>
|
||||
<li>
|
||||
<a [routerLink]="['/virtual-scroll']">Virtual Scroll Page</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1,15 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { CamaroPage } from './camaro.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: CamaroPage, outlet: 'tab2' }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes), IonicModule],
|
||||
exports: [RouterModule, IonicModule]
|
||||
})
|
||||
export class CamaroPageRoutingModule { }
|
||||
@@ -1,19 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { CamaroPage } from './camaro.page';
|
||||
import { CamaroPageRoutingModule } from './camaro-routing.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
CamaroPageRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
CamaroPage
|
||||
]
|
||||
})
|
||||
export class CamaroModule {}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'camaro-page',
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Camaro</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
Camaro
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
export class CamaroPage {}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user