Compare commits

..

3 Commits

Author SHA1 Message Date
Liam DeBeasi
9e41eb485c 4.2.1 (#18149) 2019-04-26 14:42:09 -04:00
Liam DeBeasi
96d7fdd4b5 fix(): sanitize components using innerHTML (#18145) 2019-04-26 12:38:22 -04:00
Liam DeBeasi
26ca72ccc9 fix(angular): support replaceUrl with angular <7.2 (#18107) 2019-04-23 10:53:15 -04:00
166 changed files with 602 additions and 2746 deletions

View File

@@ -1,7 +1,7 @@
---
name: Bug Report
about: Create a report to help us improve
title: 'bug: '
title: ''
labels: ''
assignees: ''
---

View File

@@ -1,7 +1,7 @@
---
name: Feature Request
about: Suggest an idea for this project
title: 'feat: '
title: ''
labels: ''
assignees: ''
---

View File

@@ -1,7 +1,7 @@
---
name: Support Question
about: Question on how to use this project
title: 'support: '
title: ''
labels: 'ionitron: support'
assignees: ''
---

18
.github/PROCESS.md vendored
View File

@@ -140,14 +140,6 @@ Once the release is ready to ship, it will get merged into `stable` and `master`
See the [steps for releasing](#releasing) below for detailed information on how to publish a release.
### Version Branches
Once a release has shipped and the release branch has been merged into `stable` and `master` it should also be merged into its corrsponding version branch. These version branches allow us to ship updates for specific versions of the framework (i.e. Lets us ship a bug fix that only affects 4.2.x).
Patch releases should be merged into their corresponding version branches. For example, a `release-4.1.1` branch should be merged into the `4.1.x` version branch and a `release-5.0.1` branch should be merged into the `5.0.x` version branch.
When releasing a major version such as `5.0.0 ` or a minor version such as `4.1.0` , the version branch will not exist. The version branch should be created once the release branch has been merged into `stable` and `master`. For example, when releasing `4.1.0`, the `release-4.1.0` release branch should be merged into `stable` and `master` and then the `4.1.x` version branch should be created off the latest `stable`.
### Hotfix Branches
@@ -222,29 +214,19 @@ Hotfixes bypass `master` and should only be used for urgent fixes that can't wai
## Releasing
1. Create the release branch from `master`, for example: `release-4.1.0`.
1. Submit a pull request from the release branch into `stable`. Do not merge this pull request yet.
1. Verify all tests are passing, fix any bugs if needed and make sure no undesired commits are in.
1. Navigate to the root of the repository while on the release branch.
1. Run `npm i` if it hasn't already been done.
1. Run `npm run release.prepare`
- Select the version based on the type of commits and the [Ionic Versioning](https://ionicframework.com/docs/intro/versioning)
- After the process completes, verify the version number in all packages (`core`, `docs`, `angular`)
- Verify the changelog commits are accurate and follow the [proper format]((https://github.com/ionic-team/ionic/blob/master/.github/CONTRIBUTING.md#commit-message-format))
- Commit these changes with the version number as the message, e.g. `git commit -m "4.1.0"`
1. Run `npm run release`
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">
1. Rewrite the commit message to `merge release-4.1.0` with the proper release branch.
1. Create a pull request and merge the release branch back into `master` using the same commit format in the last step, to ensure any changes made on the release branch get added to future releases.
1. Merge the release branch into its corresponding version branch. If this is a major or minor release, create the version branch off the latest `stable`.

View File

@@ -1,51 +1,12 @@
<!-- Please refer to our contributing documentation for any questions on submitting a pull request, or let us know here if you need any help: https://ionicframework.com/docs/building/contributing -->
## Pull request checklist
Please check if your PR fulfills the following requirements:
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been reviewed and added / updated if needed (for bug fixes / features)
- [ ] Build (`npm run build`) was run locally and any changes were pushed
- [ ] Lint (`npm run lint`) has passed locally and any fixes were made for failures
#### Short description of what this resolves:
## Pull request type
<!-- Please do not submit updates to dependencies unless it fixes an issue. -->
<!-- Please try to limit your pull request to one type, submit multiple pull requests if needed. -->
Please check the type of change your PR introduces:
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] Documentation content changes
- [ ] Other (please describe):
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
Issue Number: N/A
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by this PR. -->
#### Changes proposed in this pull request:
-
-
-
## Does this introduce a breaking change?
**Ionic Version**:
- [ ] Yes
- [ ] No
<!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. -->
## Other information
<!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
**Fixes**: #

View File

@@ -118,15 +118,6 @@ labelPullRequest:
wrongRepo:
repos:
- label: "ionitron: capacitor"
repo: capacitor
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 Capacitor.
I am moving this issue to the Capacitor repository. Please track this issue over there.
Thank you for using Ionic!
- label: "ionitron: v3"
repo: ionic-v3
message: >

View File

@@ -1,40 +1,14 @@
## [4.3.1](https://github.com/ionic-team/ionic/compare/v4.3.0...v4.3.1) (2019-04-26)
## [4.2.1](https://github.com/ionic-team/ionic/compare/v4.2.0...v4.2.1) (2019-04-26)
### Bug Fixes
* **angular:** support replaceUrl with angular <7.2 ([#18106](https://github.com/ionic-team/ionic/issues/18106)) ([eb3cbe4](https://github.com/ionic-team/ionic/commit/eb3cbe4))
* sanitize components using innerHTML ([#18146](https://github.com/ionic-team/ionic/issues/18146)) ([b839e6f](https://github.com/ionic-team/ionic/commit/b839e6f))
* **angular:** support replaceUrl with angular <7.2 ([#18107](https://github.com/ionic-team/ionic/issues/18107)) ([26ca72c](https://github.com/ionic-team/ionic/commit/26ca72c))
* sanitize components using innerHTML ([#18145](https://github.com/ionic-team/ionic/issues/18145)) ([96d7fdd](https://github.com/ionic-team/ionic/commit/96d7fdd))
# [4.3.0 Lithium](https://github.com/ionic-team/ionic/compare/v4.2.0...v4.3.0) (2019-04-17)
### Bug Fixes
* **action-sheet:** default buttons to empty array ([9e63947](https://github.com/ionic-team/ionic/commit/9e63947))
* **angular:** back button correctly goes back to proper tab ([#18005](https://github.com/ionic-team/ionic/issues/18005)) ([52e5a8d](https://github.com/ionic-team/ionic/commit/52e5a8d)), closes [#17278](https://github.com/ionic-team/ionic/issues/17278) [#15216](https://github.com/ionic-team/ionic/issues/15216)
* **components:** add mode classes to components for use in shadow elements ([#17838](https://github.com/ionic-team/ionic/issues/17838)) ([e5c8c10](https://github.com/ionic-team/ionic/commit/e5c8c10)), closes [#17608](https://github.com/ionic-team/ionic/issues/17608)
* **datetime:** date strings no longer revert to previous day ([#18018](https://github.com/ionic-team/ionic/issues/18018)) ([cc60b60](https://github.com/ionic-team/ionic/commit/cc60b60)), closes [#17977](https://github.com/ionic-team/ionic/issues/17977)
* **input:** prevent input from losing focus when tapping clear button ([#18004](https://github.com/ionic-team/ionic/issues/18004)) ([29bb4fc](https://github.com/ionic-team/ionic/commit/29bb4fc)), closes [#18002](https://github.com/ionic-team/ionic/issues/18002)
* **item:** use the correct input highlight for an inset line item ([#18052](https://github.com/ionic-team/ionic/issues/18052)) ([72be80c](https://github.com/ionic-team/ionic/commit/72be80c)), closes [#18051](https://github.com/ionic-team/ionic/issues/18051)
* **item-sliding:** hide closed side options while dragging side options open ([#17986](https://github.com/ionic-team/ionic/issues/17986)) ([f13722c](https://github.com/ionic-team/ionic/commit/f13722c)), closes [#17822](https://github.com/ionic-team/ionic/issues/17822)
* **slides:** allow zoom to work ([18b347b](https://github.com/ionic-team/ionic/commit/18b347b)), closes [#17981](https://github.com/ionic-team/ionic/issues/17981)
* **slides:** expose interface to provide custom animations ([#17959](https://github.com/ionic-team/ionic/issues/17959)) ([4474974](https://github.com/ionic-team/ionic/commit/4474974)), closes [#16616](https://github.com/ionic-team/ionic/issues/16616)
* **textarea:** float label when a value is changed async ([#18024](https://github.com/ionic-team/ionic/issues/18024)) ([494991e](https://github.com/ionic-team/ionic/commit/494991e)), closes [#17555](https://github.com/ionic-team/ionic/issues/17555) [#17559](https://github.com/ionic-team/ionic/issues/17559)
* **textarea:** update label alignment for inputs and textareas ([#18042](https://github.com/ionic-team/ionic/issues/18042)) ([38ae362](https://github.com/ionic-team/ionic/commit/38ae362)), closes [#16187](https://github.com/ionic-team/ionic/issues/16187)
* **vue:** use direction type from core ([#17901](https://github.com/ionic-team/ionic/issues/17901)) ([fa13173](https://github.com/ionic-team/ionic/commit/fa13173))
### Features
* **toast:** add header and additional custom toast buttons ([#17147](https://github.com/ionic-team/ionic/issues/17147)) ([6e1a8f1](https://github.com/ionic-team/ionic/commit/6e1a8f1)), closes [#16791](https://github.com/ionic-team/ionic/issues/16791) [#16237](https://github.com/ionic-team/ionic/issues/16237) [#17611](https://github.com/ionic-team/ionic/issues/17611)
* **toast:** add variables to change position start/end of toast ([#17961](https://github.com/ionic-team/ionic/issues/17961)) ([07e739a](https://github.com/ionic-team/ionic/commit/07e739a)), closes [#17854](https://github.com/ionic-team/ionic/issues/17854)
# [4.2.0 Helium](https://github.com/ionic-team/ionic/compare/v4.1.2...v4.2.0) (2019-04-03)
# [4.2.0](https://github.com/ionic-team/ionic/compare/v4.1.2...v4.2.0) (2019-04-03)
### Bug Fixes

View File

@@ -182,14 +182,13 @@ These have been renamed to the following, and moved from the button element to t
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`. The `full` and `block` attributes have been combined under `expand`. And, lastly, the `round` attribute is now used under `shape`.
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. |
| `round`             | `shape` | Sets the button shape. |
**Old Usage Example:**
@@ -226,10 +225,6 @@ The `small` and `large` attributes are now combined under the `size` attribute.
<ion-button full>
Full-width Button
</ion-button>
<ion-button round>
Round Button
</ion-button>
```
**New Usage Example:**
@@ -256,10 +251,6 @@ The `small` and `large` attributes are now combined under the `size` attribute.
<ion-button expand="full">
Full-width Button
</ion-button>
<ion-button shape="round">
Round Button
</ion-button>
```
@@ -1074,11 +1065,11 @@ async openLoading() {
let loading = this.loadingCtrl.create({
content: 'Loading...'
});
await loading.present();
const { role, data } = await loading.onDidDismiss();
console.log('Loading dismissed!');
}
```

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "4.3.1",
"version": "4.2.1",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -45,7 +45,7 @@
"css/"
],
"dependencies": {
"@ionic/core": "4.3.1",
"@ionic/core": "4.2.1",
"tslib": "^1.9.3"
},
"peerDependencies": {

View File

@@ -116,23 +116,7 @@ export class StackController {
return Promise.resolve(false);
}
const view = views[views.length - deep - 1];
let url = view.url;
const viewSavedData = view.savedData;
if (viewSavedData) {
const primaryOutlet = viewSavedData.get('primary');
if (
primaryOutlet &&
primaryOutlet.route &&
primaryOutlet.route._routerState &&
primaryOutlet.route._routerState.snapshot &&
primaryOutlet.route._routerState.snapshot.url
) {
url = primaryOutlet.route._routerState.snapshot.url;
}
}
return this.navCtrl.navigateBack(url).then(() => true);
return this.navCtrl.navigateBack(view.url).then(() => true);
});
}

View File

@@ -130,25 +130,6 @@ describe('tabs', () => {
expect(await tab.$('ion-back-button').isDisplayed()).toBe(false);
});
});
describe('enter url - /tabs/contact/one', () => {
beforeEach(async () => {
await browser.get('/tabs/contact/one');
});
it('should return to correct tab after going to page in different outlet', async () => {
const tab = await getSelectedTab();
await tab.$('#goto-nested-page1').click();
await testStack('app-nested-outlet ion-router-outlet', ['app-nested-outlet-page']);
const nestedOutlet = await element(by.css('app-nested-outlet'));
const backButton = await nestedOutlet.$('ion-back-button');
await backButton.click();
await testTabTitle('Tab 2 - Page 1');
});
})
});
async function testState(count: number, tab: string) {

View File

@@ -1,8 +1,5 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>
NESTED OUTLET
</ion-title>

View File

@@ -9,6 +9,5 @@
<p>
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
<ion-button routerLink="/tabs/account/nested/12" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
</p>
</ion-content>

View File

@@ -23,8 +23,8 @@ The Ionic Core package contains the Web Components that make up the reusable UI
Easiest way to start using Ionic Core is by adding a script tag to the CDN:
```html
<link href="https://unpkg.com/@ionic/core@4.3.1/css/ionic.bundle.css" rel="stylesheet">
<script src="https://unpkg.com/@ionic/core@4.3.1/dist/ionic.js"></script>
<link href="https://unpkg.com/@ionic/core@4.2.1/css/ionic.bundle.css" rel="stylesheet">
<script src="https://unpkg.com/@ionic/core@4.2.1/dist/ionic.js"></script>
```
Any Ionic component added to the webpage will automatically load. This includes writing the component tag directly in HTML, or using JavaScript such as `document.createElement('ion-toggle')`.

View File

@@ -7,7 +7,7 @@ ion-action-sheet-controller,method,getTop,getTop() => Promise<HTMLIonActionSheet
ion-action-sheet,scoped
ion-action-sheet,prop,animated,boolean,true,false,false
ion-action-sheet,prop,backdropDismiss,boolean,true,false,false
ion-action-sheet,prop,buttons,(string | ActionSheetButton)[],[],false,false
ion-action-sheet,prop,buttons,(string | ActionSheetButton)[],undefined,true,false
ion-action-sheet,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-action-sheet,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) | undefined,undefined,false,false
ion-action-sheet,prop,header,string | undefined,undefined,false,false
@@ -1135,13 +1135,11 @@ ion-toast-controller,method,getTop,getTop() => Promise<HTMLIonToastElement | und
ion-toast,shadow
ion-toast,prop,animated,boolean,true,false,false
ion-toast,prop,buttons,(string | ToastButton)[] | undefined,undefined,false,false
ion-toast,prop,closeButtonText,string | undefined,undefined,false,false
ion-toast,prop,color,string | undefined,undefined,false,false
ion-toast,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-toast,prop,duration,number,0,false,false
ion-toast,prop,enterAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) | undefined,undefined,false,false
ion-toast,prop,header,string | undefined,undefined,false,false
ion-toast,prop,keyboardClose,boolean,false,false,false
ion-toast,prop,leaveAnimation,((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) | undefined,undefined,false,false
ion-toast,prop,message,string | undefined,undefined,false,false
@@ -1165,13 +1163,11 @@ ion-toast,css-prop,--border-width
ion-toast,css-prop,--box-shadow
ion-toast,css-prop,--button-color
ion-toast,css-prop,--color
ion-toast,css-prop,--end
ion-toast,css-prop,--height
ion-toast,css-prop,--max-height
ion-toast,css-prop,--max-width
ion-toast,css-prop,--min-height
ion-toast,css-prop,--min-width
ion-toast,css-prop,--start
ion-toast,css-prop,--width
ion-toggle,shadow

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "4.3.1",
"version": "4.2.1",
"description": "Base components for Ionic",
"keywords": [
"ionic",
@@ -30,7 +30,7 @@
"loader/"
],
"dependencies": {
"ionicons": "4.5.6"
"ionicons": "4.5.5"
},
"devDependencies": {
"@stencil/core": "0.17.3-0",

View File

@@ -68,7 +68,6 @@ import {
TabButtonLayout,
TextareaChangeEventDetail,
TextFieldTypes,
ToastButton,
ToastOptions,
ToggleChangeEventDetail,
TransitionDoneFn,
@@ -176,7 +175,7 @@ export namespace Components {
/**
* An array of buttons for the action sheet.
*/
'buttons'?: (ActionSheetButton | string)[];
'buttons': (ActionSheetButton | string)[];
/**
* Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces.
*/
@@ -4758,10 +4757,6 @@ export namespace Components {
*/
'animated': boolean;
/**
* An array of buttons for the toast.
*/
'buttons'?: (ToastButton | string)[];
/**
* Text to display in the close button.
*/
'closeButtonText'?: string;
@@ -4786,10 +4781,6 @@ export namespace Components {
*/
'enterAnimation'?: AnimationBuilder;
/**
* Header to be shown in the toast.
*/
'header'?: string;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
'keyboardClose': boolean;
@@ -4837,10 +4828,6 @@ export namespace Components {
*/
'animated'?: boolean;
/**
* An array of buttons for the toast.
*/
'buttons'?: (ToastButton | string)[];
/**
* Text to display in the close button.
*/
'closeButtonText'?: string;
@@ -4861,10 +4848,6 @@ export namespace Components {
*/
'enterAnimation'?: AnimationBuilder;
/**
* Header to be shown in the toast.
*/
'header'?: string;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
'keyboardClose'?: boolean;

View File

@@ -51,7 +51,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
/**
* An array of buttons for the action sheet.
*/
@Prop() buttons: (ActionSheetButton | string)[] = [];
@Prop() buttons!: (ActionSheetButton | string)[];
/**
* Additional classes to apply for custom CSS. If multiple classes are
@@ -196,8 +196,6 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
zIndex: 20000 + this.overlayIndex,
},
class: {
[`${this.mode}`]: true,
...getClassMap(this.cssClass),
'action-sheet-translucent': this.translucent
}

View File

@@ -257,19 +257,19 @@ export default {
## Properties
| Property | Attribute | Description | Type | Default |
| ----------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- |
| `animated` | `animated` | If `true`, the action sheet will animate. | `boolean` | `true` |
| `backdropDismiss` | `backdrop-dismiss` | If `true`, the action sheet will be dismissed when the backdrop is clicked. | `boolean` | `true` |
| `buttons` | -- | An array of buttons for the action sheet. | `(string \| ActionSheetButton)[]` | `[]` |
| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` |
| `enterAnimation` | -- | Animation to use when the action sheet is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
| `header` | `header` | Title for the action sheet. | `string \| undefined` | `undefined` |
| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` |
| `leaveAnimation` | -- | Animation to use when the action sheet is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `subHeader` | `sub-header` | Subtitle for the action sheet. | `string \| undefined` | `undefined` |
| `translucent` | `translucent` | If `true`, the action sheet will be translucent. Only applies when the mode is `"ios"` and the device supports backdrop-filter. | `boolean` | `false` |
| Property | Attribute | Description | Type | Default |
| ---------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- |
| `animated` | `animated` | If `true`, the action sheet will animate. | `boolean` | `true` |
| `backdropDismiss` | `backdrop-dismiss` | If `true`, the action sheet will be dismissed when the backdrop is clicked. | `boolean` | `true` |
| `buttons` _(required)_ | -- | An array of buttons for the action sheet. | `(string \| ActionSheetButton)[]` | `undefined` |
| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` |
| `enterAnimation` | -- | Animation to use when the action sheet is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
| `header` | `header` | Title for the action sheet. | `string \| undefined` | `undefined` |
| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` |
| `leaveAnimation` | -- | Animation to use when the action sheet is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `subHeader` | `sub-header` | Subtitle for the action sheet. | `string \| undefined` | `undefined` |
| `translucent` | `translucent` | If `true`, the action sheet will be translucent. Only applies when the mode is `"ios"` and the device supports backdrop-filter. | `boolean` | `false` |
## Events

View File

@@ -38,34 +38,34 @@ test('action-sheet: basic, scroll without cancel', async () => {
* RTL Tests
*/
test('action-sheet:rtl: basic', async () => {
test('action-sheet: basic', async () => {
await testActionSheet(DIRECTORY, '#basic', true);
});
test('action-sheet:rtl: basic, alert from action sheet', async () => {
test('action-sheet: basic, alert from action sheet', async () => {
await testActionSheet(DIRECTORY, '#alertFromActionSheet', true, testActionSheetAlert);
});
test('action-sheet:rtl: basic, cancel only', async () => {
test('action-sheet: basic, cancel only', async () => {
await testActionSheet(DIRECTORY, '#cancelOnly', true);
});
test('action-sheet:rtl: basic, custom', async () => {
test('action-sheet: basic, custom', async () => {
await testActionSheet(DIRECTORY, '#custom', true);
});
test('action-sheet:rtl: basic, icons', async () => {
test('action-sheet: basic, icons', async () => {
await testActionSheet(DIRECTORY, '#icons', true);
});
test('action-sheet:rtl: basic, no backdrop dismiss', async () => {
test('action-sheet: basic, no backdrop dismiss', async () => {
await testActionSheet(DIRECTORY, '#noBackdropDismiss', true, testActionSheetBackdrop);
});
test('action-sheet:rtl: basic, scrollable options', async () => {
test('action-sheet: basic, scrollable options', async () => {
await testActionSheet(DIRECTORY, '#scrollableOptions', true);
});
test('action-sheet:rtl: basic, scroll without cancel', async () => {
test('action-sheet: basic, scroll without cancel', async () => {
await testActionSheet(DIRECTORY, '#scrollWithoutCancel', true);
});

View File

@@ -1,15 +1,19 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testActionSheet(
type: string,
selector: string,
rtl = false,
afterScreenshotHook = async (..._args: any[]): Promise<void> => {/**/}
afterScreenshotHook = async (..._args: any[]): Promise<void> => {/**/},
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('action-sheet', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -23,14 +27,14 @@ export async function testActionSheet(
let actionSheet = await page.find('ion-action-sheet');
await actionSheet.waitForVisible();
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await afterScreenshotHook(page, screenshotCompares, actionSheet);
await afterScreenshotHook(page, screenshotName, screenshotCompares, actionSheet);
await actionSheet.callMethod('dismiss');
await actionSheet.waitForNotVisible();
screenshotCompares.push(await page.compareScreenshot('dismiss'));
screenshotCompares.push(await page.compareScreenshot(`dismissed ${screenshotName}`));
actionSheet = await page.find('ion-action-sheet');
expect(actionSheet).toBe(null);
@@ -46,6 +50,7 @@ export async function testActionSheet(
export async function testActionSheetBackdrop(
page: any,
screenshotName: string,
screenshotCompares: any,
actionSheet: any
) {
@@ -54,7 +59,7 @@ export async function testActionSheetBackdrop(
const backdrop = await page.find('ion-backdrop');
await backdrop.click();
screenshotCompares.push(await page.compareScreenshot(`dismiss backdrop`));
screenshotCompares.push(await page.compareScreenshot(`dismissed backdrop ${screenshotName}`));
const isVisible = await actionSheet.isVisible();
expect(isVisible).toBe(true);
@@ -65,6 +70,7 @@ export async function testActionSheetBackdrop(
export async function testActionSheetAlert(
page: any,
screenshotName: string,
screenshotCompares: any
) {
try {
@@ -75,7 +81,7 @@ export async function testActionSheetAlert(
await alert.waitForVisible();
await page.waitFor(250);
screenshotCompares.push(await page.compareScreenshot(`alert open`));
screenshotCompares.push(await page.compareScreenshot(`alert open ${screenshotName}`));
const alertOkayBtn = await page.find({ contains: 'Okay' });
await alertOkayBtn.click();

View File

@@ -399,7 +399,6 @@ export class Alert implements ComponentInterface, OverlayInterface {
},
class: {
...getClassMap(this.cssClass),
[`${this.mode}`]: true,
'alert-translucent': this.translucent
}
};

View File

@@ -37,34 +37,34 @@ test(`alert: basic, checkbox`, async () => {
// Right to Left tests
// ------------------------------------------------------
test(`alert:rtl: basic`, async () => {
test(`alert: basic`, async () => {
await testAlert(DIRECTORY, '#basic', true);
});
test(`alert:rtl: basic, long message`, async () => {
test(`alert: basic, long message`, async () => {
await testAlert(DIRECTORY, '#longMessage', true);
});
test(`alert:rtl: basic, multiple buttons`, async () => {
test(`alert: basic, multiple buttons`, async () => {
await testAlert(DIRECTORY, '#multipleButtons', true);
});
test(`alert:rtl: basic, no message`, async () => {
test(`alert: basic, no message`, async () => {
await testAlert(DIRECTORY, '#noMessage', true);
});
test(`alert:rtl: basic, confirm`, async () => {
test(`alert: basic, confirm`, async () => {
await testAlert(DIRECTORY, '#confirm', true);
});
test(`alert:rtl: basic, prompt`, async () => {
test(`alert: basic, prompt`, async () => {
await testAlert(DIRECTORY, '#prompt', true);
});
test(`alert:rtl: basic, radio`, async () => {
test(`alert: basic, radio`, async () => {
await testAlert(DIRECTORY, '#radio', true);
});
test(`alert:rtl: basic, checkbox`, async () => {
test(`alert: basic, checkbox`, async () => {
await testAlert(DIRECTORY, '#checkbox', true);
});

View File

@@ -1,14 +1,18 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testAlert(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('alert', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -24,12 +28,12 @@ export async function testAlert(
expect(alert).not.toBe(null);
await alert.waitForVisible();
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await alert.callMethod('dismiss');
await alert.waitForNotVisible();
screenshotCompares.push(await page.compareScreenshot('dismiss'));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
alert = await page.find('ion-alert');
expect(alert).toBe(null);

View File

@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Listen, Prop } from '@stencil/core';
import { Color, Mode, RouterDirection } from '../../interface';
import { Color, RouterDirection } from '../../interface';
import { createColorClasses, openURL } from '../../utils/theme';
@Component({
@@ -9,7 +9,6 @@ import { createColorClasses, openURL } from '../../utils/theme';
shadow: true
})
export class Anchor implements ComponentInterface {
mode!: Mode;
@Prop({ context: 'window' }) win!: Window;
@@ -41,7 +40,6 @@ export class Anchor implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'ion-activatable': true
}
};

View File

@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Prop, QueueApi } from '@stencil/core';
import { Config, Mode } from '../../interface';
import { Config } from '../../interface';
import { rIC } from '../../utils/helpers';
import { isPlatform } from '../../utils/platform';
@@ -9,7 +9,6 @@ import { isPlatform } from '../../utils/platform';
styleUrl: 'app.scss'
})
export class App implements ComponentInterface {
mode!: Mode;
@Element() el!: HTMLElement;
@@ -35,7 +34,6 @@ export class App implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'ion-page': true,
'force-statusbar-padding': this.config.getBoolean('_forceStatusbarPadding')
}

View File

@@ -1,7 +1,5 @@
import { Component, ComponentInterface } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-avatar',
styleUrls: {
@@ -11,15 +9,6 @@ import { Mode } from '../../interface';
shadow: true
})
export class Avatar implements ComponentInterface {
mode!: Mode;
hostData() {
return {
class: {
[`${this.mode}`]: true,
}
};
}
render() {
return <slot></slot>;

View File

@@ -62,7 +62,6 @@ export class BackButton implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'button': true, // ion-buttons target .button
'ion-activatable': true,

View File

@@ -1,6 +1,5 @@
import { Component, ComponentInterface, Event, EventEmitter, Listen, Prop } from '@stencil/core';
import { Mode } from '../../interface';
import { GESTURE_CONTROLLER } from '../../utils/gesture';
import { now } from '../../utils/helpers';
@@ -13,7 +12,6 @@ import { now } from '../../utils/helpers';
shadow: true
})
export class Backdrop implements ComponentInterface {
mode!: Mode;
private lastClick = -10000;
private blocker = GESTURE_CONTROLLER.createBlocker({
@@ -80,7 +78,6 @@ export class Backdrop implements ComponentInterface {
return {
tabindex: '-1',
class: {
[`${this.mode}`]: true,
'backdrop-hide': !this.visible,
'backdrop-no-tappable': !this.tappable,
}

View File

@@ -26,10 +26,7 @@ export class Badge implements ComponentInterface {
hostData() {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true
}
class: createColorClasses(this.color)
};
}

View File

@@ -148,7 +148,6 @@ export class Button implements ComponentInterface {
'aria-disabled': disabled ? 'true' : null,
class: {
...createColorClasses(color),
[`${this.mode}`]: true,
[buttonType]: true,
[`${buttonType}-${expand}`]: expand !== undefined,
[`${buttonType}-${size}`]: size !== undefined,

View File

@@ -1,7 +1,5 @@
import { Component, ComponentInterface } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-buttons',
styleUrls: {
@@ -10,14 +8,4 @@ import { Mode } from '../../interface';
},
scoped: true,
})
export class Buttons implements ComponentInterface {
mode!: Mode;
hostData() {
return {
class: {
[`${this.mode}`]: true
}
};
}
}
export class Buttons implements ComponentInterface {}

View File

@@ -1,6 +1,7 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-card-content',
@@ -18,12 +19,7 @@ export class CardContent implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`card-content-${this.mode}`]: true
}
class: createThemedClasses(this.mode, 'card-content')
};
}
}

View File

@@ -34,7 +34,6 @@ export class CardHeader implements ComponentInterface {
class: {
...createColorClasses(this.color),
'card-header-translucent': this.translucent,
[`${this.mode}`]: true
}
};
}

View File

@@ -26,10 +26,7 @@ export class CardSubtitle implements ComponentInterface {
hostData() {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true
},
class: createColorClasses(this.color),
'role': 'heading',
'aria-level': '3'
};

View File

@@ -26,10 +26,7 @@ export class CardTitle implements ComponentInterface {
hostData() {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true
},
class: createColorClasses(this.color),
'role': 'heading',
'aria-level': '2'
};

View File

@@ -27,10 +27,7 @@ export class Card implements ComponentInterface {
hostData() {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true
}
class: createColorClasses(this.color)
};
}
}

View File

@@ -137,7 +137,6 @@ export class Checkbox implements ComponentInterface {
'aria-labelledby': labelId,
class: {
...createColorClasses(color),
[`${this.mode}`]: true,
'in-item': hostContext('ion-item', el),
'checkbox-checked': checked,
'checkbox-disabled': disabled,

View File

@@ -33,7 +33,6 @@ export class Chip implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'chip-outline': this.outline,
'ion-activatable': true,
}

View File

@@ -1,6 +1,5 @@
import { Component, ComponentInterface, Element, Listen, Prop } from '@stencil/core';
import { Mode } from '../../interface';
import { matchBreakpoint } from '../../utils/media';
const win = window as any;
@@ -13,8 +12,6 @@ const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
shadow: true
})
export class Col implements ComponentInterface {
mode!: Mode;
@Prop({ context: 'window' }) win!: Window;
@Element() el!: HTMLStencilElement;
@@ -250,9 +247,6 @@ export class Col implements ComponentInterface {
hostData() {
const isRTL = this.win.document.dir === 'rtl';
return {
class: {
[`${this.mode}`]: true
},
style: {
...this.calculateOffset(isRTL),
...this.calculatePull(isRTL),

View File

@@ -293,7 +293,6 @@ export class Content implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'content-sizing': hostContext('ion-popover', this.el),
'overscroll': !!this.forceOverscroll,
},

View File

@@ -2,7 +2,7 @@ import { convertDataToISO, parseDate } from './datetime-util';
describe('datetime-util', () => {
describe('convertDataToISO', () => {
it('prints an empty string for an empty datetime', () => {
it('prints an emptry string for an empty datetime', () => {
expect(convertDataToISO({})).toEqual('');
});

View File

@@ -248,20 +248,8 @@ export function parseDate(val: string | undefined | null): DatetimeData | undefi
* such as "01:47"
*/
export const getLocalDateTime = (dateString: any = ''): Date => {
/**
* Ensures that YYYY-MM-DD, YYYY-MM,
* YYYY-DD, etc does not get affected
* by timezones and stays on the day/month
* that the user provided
*/
if (
dateString.length === 10 ||
dateString.length === 7
) {
dateString += ' ';
}
const date = (typeof dateString === 'string' && dateString.length > 0) ? new Date(dateString) : new Date();
return new Date(
Date.UTC(
date.getFullYear(),
@@ -279,6 +267,7 @@ export function updateDate(existingData: DatetimeData, newData: any): boolean {
if (!newData || typeof newData === 'string') {
const localDateTime = getLocalDateTime(newData);
if (!Number.isNaN(localDateTime.getTime())) {
newData = localDateTime.toISOString();
}

View File

@@ -615,7 +615,6 @@ export class Datetime implements ComponentInterface {
'aria-haspopup': 'true',
'aria-labelledby': labelId,
class: {
[`${this.mode}`]: true,
'datetime-disabled': disabled,
'datetime-readonly': readonly,
'datetime-placeholder': addPlaceholderClass,

View File

@@ -52,23 +52,6 @@ describe('Datetime', () => {
expect(convertToLocal.toISOString()).toEqual(expectedDateString);
});
});
it('should format a date string and not get affected by the timezone offset', () => {
const dateStringTests = [
{ input: '2019-03-20', expectedOutput: '2019-03-20' },
{ input: '1994-04-15', expectedOutput: '1994-04-15' },
{ input: '2008-09-02', expectedOutput: '2008-09-02' },
{ input: '1995-02', expectedOutput: '1995-02' },
{ input: '1994-03-14', expectedOutput: '1994-03-14' },
{ input: '9 01:47', expectedOutput: '09-01T01:47' }
];
dateStringTests.forEach(test => {
const convertToLocal = getLocalDateTime(test.input);
expect(convertToLocal.toISOString()).toContain(test.expectedOutput);
});
});
});
describe('daysInMonth()', () => {

View File

@@ -95,7 +95,6 @@ export class FabButton implements ComponentInterface {
'aria-disabled': disabled ? 'true' : null,
class: {
...createColorClasses(color),
[`${this.mode}`]: true,
'fab-button-in-list': inList,
'fab-button-translucent-in-list': inList && translucent,
'fab-button-close-active': activated,

View File

@@ -1,15 +1,11 @@
import { Component, ComponentInterface, Element, Prop, Watch } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-fab-list',
styleUrl: 'fab-list.scss',
shadow: true
})
export class FabList implements ComponentInterface {
mode!: Mode;
@Element() el!: HTMLIonFabElement;
/**
@@ -36,7 +32,6 @@ export class FabList implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'fab-list-active': this.activated,
[`fab-list-side-${this.side}`]: true
}

View File

@@ -1,14 +1,11 @@
import { Component, ComponentInterface, Element, Listen, Method, Prop, Watch } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-fab',
styleUrl: 'fab.scss',
shadow: true
})
export class Fab implements ComponentInterface {
mode!: Mode;
@Element() el!: HTMLElement;
@@ -78,7 +75,6 @@ export class Fab implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
[`fab-horizontal-${this.horizontal}`]: this.horizontal !== undefined,
[`fab-vertical-${this.vertical}`]: this.vertical !== undefined,
'fab-edge': this.edge

View File

@@ -1,21 +1,25 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testFab(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('fab', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
});
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(`${screenshotName}`));
const fab = await getFabComponent(page, selector);
await fab.click();
@@ -24,7 +28,7 @@ export async function testFab(
await ensureFabState(fab, 'active');
screenshotCompares.push(await page.compareScreenshot('open'));
screenshotCompares.push(await page.compareScreenshot(`${screenshotName} open`));
const fabButton = await getFabButton(fab);
await fabButton.click();
@@ -33,7 +37,7 @@ export async function testFab(
await ensureFabState(fab, 'inactive');
screenshotCompares.push(await page.compareScreenshot('close'));
screenshotCompares.push(await page.compareScreenshot(`${screenshotName} close`));
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
@@ -46,24 +50,28 @@ export async function testFab(
export async function testDisabledFab(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('fab', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
});
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot('disabled'));
screenshotCompares.push(await page.compareScreenshot(`disabled ${screenshotName}`));
const fab = await getFabComponent(page, selector);
await fab.click();
await ensureFabState(fab, 'inactive');
screenshotCompares.push(await page.compareScreenshot('disabled, attempt open'));
screenshotCompares.push(await page.compareScreenshot(`disabled ${screenshotName} attempt open`));
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();

View File

@@ -1,6 +1,7 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-footer',
@@ -24,15 +25,13 @@ export class Footer implements ComponentInterface {
@Prop() translucent = false;
hostData() {
const themedClasses = createThemedClasses(this.mode, 'footer');
const translucentClasses = this.translucent ? createThemedClasses(this.mode, 'footer-translucent') : null;
return {
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`footer-${this.mode}`]: true,
[`footer-translucent`]: this.translucent,
[`footer-translucent-${this.mode}`]: this.translucent,
...themedClasses,
...translucentClasses
}
};
}

View File

@@ -1,14 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
import { checkComponentModeClasses } from '../../../../utils/test/utils';
test('footer: translucent', async () => {
const page = await newE2EPage({
url: '/src/components/footer/test/translucent?ionic:_testing=true'
});
await checkComponentModeClasses(await page.find('ion-footer'), 'footer-translucent');
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

View File

@@ -1,14 +1,11 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-grid',
styleUrl: 'grid.scss',
shadow: true
})
export class Grid implements ComponentInterface {
mode!: Mode;
/**
* If `true`, the grid will have a fixed width based on the screen size.
@@ -18,7 +15,6 @@ export class Grid implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'grid-fixed': this.fixed
}
};

View File

@@ -1,6 +1,7 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Mode } from '../../interface';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-header',
@@ -24,15 +25,13 @@ export class Header implements ComponentInterface {
@Prop() translucent = false;
hostData() {
const themedClasses = createThemedClasses(this.mode, 'header');
const translucentClasses = this.translucent ? createThemedClasses(this.mode, 'header-translucent') : null;
return {
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`header-${this.mode}`]: true,
[`header-translucent`]: this.translucent,
[`header-translucent-${this.mode}`]: this.translucent,
...themedClasses,
...translucentClasses
}
};
}

View File

@@ -1,14 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
import { checkComponentModeClasses } from '../../../../utils/test/utils';
test('header: translucent', async () => {
const page = await newE2EPage({
url: '/src/components/header/test/translucent?ionic:_testing=true'
});
await checkComponentModeClasses(await page.find('ion-header'), 'header-translucent');
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

View File

@@ -1,14 +1,11 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, State, Watch } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-img',
styleUrl: 'img.scss',
shadow: true
})
export class Img implements ComponentInterface {
mode!: Mode;
private io?: IntersectionObserver;
@@ -84,14 +81,6 @@ export class Img implements ComponentInterface {
}
}
hostData() {
return {
class: {
[`${this.mode}`]: true,
}
};
}
render() {
return (
<img

View File

@@ -2,6 +2,7 @@ import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Config, Mode, SpinnerTypes } from '../../interface';
import { sanitizeDOMString } from '../../utils/sanitization';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-infinite-scroll-content',
@@ -43,12 +44,7 @@ export class InfiniteScrollContent implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`infinite-scroll-content-${this.mode}`]: true
}
class: createThemedClasses(this.mode, 'infinite-scroll-content')
};
}

View File

@@ -1,13 +1,10 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-infinite-scroll',
styleUrl: 'infinite-scroll.scss'
})
export class InfiniteScroll implements ComponentInterface {
mode!: Mode;
private thrPx = 0;
private thrPc = 0;
@@ -215,7 +212,6 @@ export class InfiniteScroll implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'infinite-scroll-loading': this.isLoading,
'infinite-scroll-enabled': !this.disabled
}

View File

@@ -307,12 +307,7 @@ export class Input implements ComponentInterface {
}
}
private clearTextInput = (ev?: Event) => {
if (this.clearInput && !this.readonly && !this.disabled && ev) {
ev.preventDefault();
ev.stopPropagation();
}
private clearTextInput = () => {
this.value = '';
}
@@ -332,7 +327,6 @@ export class Input implements ComponentInterface {
'aria-disabled': this.disabled ? 'true' : null,
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'has-value': this.hasValue(),
'has-focus': this.hasFocus
}

View File

@@ -1,15 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
test('input: spec', async () => {
const page = await newE2EPage({
url: '/src/components/input/test/spec?ionic:_testing=true'
});
const compares = [];
compares.push(await page.compareScreenshot());
for (const compare of compares) {
expect(compare).toMatchScreenshot();
}
});

View File

@@ -1,61 +0,0 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Input - Spec</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script src="../../../../../dist/ionic.js"></script>
</head>
<body>
<ion-app>
<ion-content class="ion-padding">
<ion-item>
<ion-label position="floating">Standard</ion-label>
<ion-input></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Standard</ion-label>
<ion-input value="value"></ion-input>
</ion-item>
<ion-item>
<ion-label position="stacked">Stacked</ion-label>
<ion-input></ion-input>
</ion-item>
<ion-item>
<ion-label position="stacked">Stacked</ion-label>
<ion-input value="value"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Floating</ion-label>
<ion-textarea></ion-textarea>
</ion-item>
<ion-item>
<ion-label position="floating">Floating</ion-label>
<ion-textarea value="value"></ion-textarea>
</ion-item>
<ion-item>
<ion-label position="stacked">Stacked</ion-label>
<ion-textarea></ion-textarea>
</ion-item>
<ion-item>
<ion-label position="stacked">Stacked</ion-label>
<ion-textarea value="value"></ion-textarea>
</ion-item>
</ion-content>
<style>
ion-item {
--background: #f5f5f5;
}
</style>
</ion-app>
</body>
</html>

View File

@@ -55,7 +55,6 @@ export class ItemDivider implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'item-divider-sticky': this.sticky,
'item': true,
}

View File

@@ -1,6 +1,7 @@
import { Component, ComponentInterface } from '@stencil/core';
import { Mode } from '../../interface';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-item-group',
@@ -17,12 +18,8 @@ export class ItemGroup implements ComponentInterface {
return {
'role': 'group',
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`item-group-${this.mode}`]: true,
'item': true
...createThemedClasses(this.mode, 'item-group'),
'item': true,
}
};
}

View File

@@ -64,8 +64,6 @@ export class ItemOption implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'item-option-disabled': disabled,
'item-option-expandable': expandable,
'ion-activatable': true,

View File

@@ -77,8 +77,6 @@ ion-item-options {
ion-item-options {
display: flex;
visibility: hidden;
}
&.item-sliding-active-options-start .item-options-start,

View File

@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop } from '@stencil/core';
import { Mode, Side } from '../../interface';
import { Side } from '../../interface';
import { isEndSide } from '../../utils/helpers';
@Component({
@@ -11,8 +11,6 @@ import { isEndSide } from '../../utils/helpers';
}
})
export class ItemOptions implements ComponentInterface {
mode!: Mode;
@Element() el!: HTMLElement;
@Prop({ context: 'window' }) win!: Window;
@@ -40,11 +38,6 @@ export class ItemOptions implements ComponentInterface {
const isEnd = isEndSide(this.win, this.side);
return {
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`item-options-${this.mode}`]: true,
'item-options-start': !isEnd,
'item-options-end': isEnd
}

View File

@@ -33,7 +33,7 @@ ion-item-sliding .item {
.item-sliding-active-swipe-end .item-options-end .item-option-expandable {
@include multi-dir() {
/* stylelint-disable-next-line property-blacklist */
padding-left: 100%;
padding-left: 90%;
}
@include ltr() {
@@ -51,7 +51,7 @@ ion-item-sliding .item {
.item-sliding-active-swipe-start .item-options-start .item-option-expandable {
@include multi-dir() {
/* stylelint-disable-next-line property-blacklist */
padding-right: 100%;
padding-right: 90%;
}
@include ltr() {

View File

@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
import { Gesture, GestureDetail, Mode } from '../../interface';
import { Gesture, GestureDetail } from '../../interface';
const SWIPE_MARGIN = 30;
const ELASTIC_FACTOR = 0.55;
@@ -29,7 +29,6 @@ let openSlidingItem: HTMLIonItemSlidingElement | undefined;
styleUrl: 'item-sliding.scss'
})
export class ItemSliding implements ComponentInterface {
mode!: Mode;
private item: HTMLIonItemElement | null = null;
private openAmount = 0;
@@ -308,7 +307,6 @@ export class ItemSliding implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'item-sliding-active-slide': (this.state !== SlidingState.Disabled),
'item-sliding-active-options-end': (this.state & SlidingState.End) !== 0,
'item-sliding-active-options-start': (this.state & SlidingState.Start) !== 0,

View File

@@ -310,44 +310,6 @@
</ion-item>
</ion-item-sliding>
<ion-item-sliding id="item10">
<ion-item detail>
<ion-label text-wrap>
<h2>RIGHT/LEFT side - many buttons</h2>
<p>Use mobile emulator to check</p>
</ion-label>
</ion-item>
<ion-item-options side="start" class="sliding-enabled">
<ion-item-option color="primary" expandable>
<ion-icon name="ios-checkmark"></ion-icon>Btn 1
</ion-item-option>
<ion-item-option color="secondary" expandable>
<ion-icon name="ios-checkmark"></ion-icon>Btn 2
</ion-item-option>
<ion-item-option color="danger" expandable>
<ion-icon name="ios-checkmark"></ion-icon>Btn 3
</ion-item-option>
<ion-item-option color="tertiary" expandable>
<ion-icon name="ios-checkmark"></ion-icon>Btn 4
</ion-item-option>
</ion-item-options>
<ion-item-options side="end" class="sliding-enabled">
<ion-item-option color="primary" expandable>
<ion-icon name="mail"></ion-icon>Btn 5
</ion-item-option>
<ion-item-option color="secondary" expandable>
<ion-icon name="mail"></ion-icon>Btn 6
</ion-item-option>
<ion-item-option color="danger" expandable>
<ion-icon name="mail"></ion-icon>Btn 7
</ion-item-option>
<ion-item-option color="tertiary" expandable>
<ion-icon name="mail"></ion-icon>Btn 8
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item>
<ion-label text-wrap>
<h2>Normal ion-item (no sliding)</h2>

View File

@@ -245,7 +245,7 @@
:host(.item-label-floating),
:host(.item-label-stacked) {
--min-height: 55px;
--min-height: 65px;
}
// TODO: refactor, ion-item and ion-textarea have the same CSS

View File

@@ -181,9 +181,6 @@ button, a {
display: flex;
/* This is required to work with an inset highlight */
position: relative;
flex: 1;
flex-direction: inherit;
align-items: inherit;

View File

@@ -136,11 +136,10 @@ export class Item implements ComponentInterface {
class: {
...childStyles,
...createColorClasses(this.color),
'item': true,
[`${this.mode}`]: true,
[`item-lines-${this.lines}`]: this.lines !== undefined,
'item-disabled': this.disabled,
'in-list': hostContext('ion-list', this.el),
'item': true,
'item-multiple-inputs': this.multipleInputs,
'ion-activatable': this.isClickable(),
'ion-focusable': true,

View File

@@ -33,12 +33,6 @@
color: $label-ios-text-color-focused;
}
:host-context(.item-has-focus).label-floating,
:host-context(.item-has-placeholder).label-floating,
:host-context(.item-has-value).label-floating {
@include transform(translate3d(0, 0, 0), scale(.8));
}
// iOS Typography
// --------------------------------------------------

View File

@@ -13,30 +13,19 @@
// --------------------------------------------------
:host(.label-stacked) {
@include transform-origin(start, top);
@include transform(translate3d(0, 50%, 0), scale(.75));
font-size: 12.8px;
}
:host(.label-floating) {
@include transform(translate3d(0, 96%, 0));
@include transform(translate3d(0, 27px, 0));
@include transform-origin(start, top);
transition: transform 150ms cubic-bezier(.4,0,.2,1);
transition: transform 150ms ease-in-out;
}
:host(.label-stacked),
:host(.label-floating) {
@include margin(0, 0, 0, 0);
}
:host-context(.item-select).label-floating {
@include transform(translate3d(0, 130%, 0));
}
:host-context(.item-has-focus).label-floating,
:host-context(.item-has-placeholder).label-floating,
:host-context(.item-has-value).label-floating {
@include transform(translate3d(0, 50%, 0), scale(.75));
@include margin(null, null, 0, 0);
}

View File

@@ -46,10 +46,6 @@
pointer-events: none;
}
:host-context(.item-textarea) {
align-self: baseline;
}
// Fixed Inputs
// --------------------------------------------------
@@ -75,6 +71,12 @@
max-width: 100%;
}
:host-context(.item-has-focus).label-floating,
:host-context(.item-has-placeholder).label-floating,
:host-context(.item-has-value).label-floating {
@include transform(translate3d(0, 0, 0), scale(.8));
}
:host(.label-no-animate.label-floating) {
transition: none;
}

View File

@@ -70,7 +70,6 @@ export class Label implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
[`label-${position}`]: position !== undefined,
[`label-no-animate`]: (this.noAnimate)
}

View File

@@ -27,10 +27,7 @@ export class ListHeader implements ComponentInterface {
hostData() {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
}
class: createColorClasses(this.color)
};
}

View File

@@ -1,6 +1,7 @@
import { Component, ComponentInterface, Element, Method, Prop } from '@stencil/core';
import { Mode } from '../../interface';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-list',
@@ -46,13 +47,9 @@ export class List implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`list-${this.mode}`]: true,
'list-inset': this.inset,
...createThemedClasses(this.mode, 'list'),
[`list-lines-${this.lines}`]: this.lines !== undefined,
'list-inset': this.inset,
[`list-${this.mode}-lines-${this.lines}`]: this.lines !== undefined
}
};

View File

@@ -174,7 +174,6 @@ export class Loading implements ComponentInterface, OverlayInterface {
},
class: {
...getClassMap(this.cssClass),
[`${this.mode}`]: true,
'loading-translucent': this.translucent
}
};

View File

@@ -1,14 +1,18 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testLoading(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('loading', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -24,12 +28,12 @@ export async function testLoading(
await loading.waitForVisible();
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await loading.callMethod('dismiss');
await loading.waitForNotVisible();
screenshotCompares.push(await page.compareScreenshot('dismiss'));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
loading = await page.find('ion-loading');
expect(loading).toBeNull();

View File

@@ -39,7 +39,6 @@ export class MenuButton implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'button': true, // ion-buttons target .button
'ion-activatable': true,
}

View File

@@ -1,14 +1,11 @@
import { Component, ComponentInterface, Listen, Prop, State } from '@stencil/core';
import { Mode } from '../../interface';
@Component({
tag: 'ion-menu-toggle',
styleUrl: 'menu-toggle.scss',
shadow: true
})
export class MenuToggle implements ComponentInterface {
mode!: Mode;
@Prop({ context: 'document' }) doc!: Document;
@@ -66,7 +63,6 @@ export class MenuToggle implements ComponentInterface {
return {
'aria-hidden': hidden ? 'true' : null,
class: {
[`${this.mode}`]: true,
'menu-toggle-hidden': hidden,
}
};

View File

@@ -510,7 +510,6 @@ export class Menu implements ComponentInterface, MenuI {
return {
role: 'complementary',
class: {
[`${this.mode}`]: true,
[`menu-type-${type}`]: true,
'menu-enabled': !disabled,
'menu-side-end': isEndSide,

View File

@@ -1,15 +1,19 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testMenu(
type: string,
selector: string,
menuId = '',
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('menu', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -28,12 +32,12 @@ export async function testMenu(
await menu.callMethod('open');
await page.waitFor(250);
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await menu.callMethod('close');
await page.waitFor(250);
screenshotCompares.push(await page.compareScreenshot('dismiss'));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();

View File

@@ -3,7 +3,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me
import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
import { attachComponent, detachComponent } from '../../utils/framework-delegate';
import { BACKDROP, dismiss, eventMethod, present } from '../../utils/overlays';
import { getClassMap } from '../../utils/theme';
import { createThemedClasses, getClassMap } from '../../utils/theme';
import { deepReady } from '../../utils/transition';
import { iosEnterAnimation } from './animations/ios.enter';
@@ -193,7 +193,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
'no-router': true,
'aria-modal': 'true',
class: {
[`${this.mode}`]: true,
...createThemedClasses(this.mode, 'modal'),
...getClassMap(this.cssClass)
},
style: {
@@ -203,10 +203,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
}
render() {
const dialogClasses = {
[`modal-wrapper`]: true,
[`${this.mode}`]: true,
};
const dialogClasses = createThemedClasses(this.mode, 'modal-wrapper');
return [
<ion-backdrop visible={this.showBackdrop} tappable={this.backdropDismiss}/>,

View File

@@ -8,9 +8,9 @@ A Modal is a dialog that appears on top of the app's content, and must be dismis
Modals can be created using a [Modal Controller](../modal-controller). They can be customized by passing modal options in the modal controller's create method.
### Passing parameters
### Passing paramaters
When a modal is created, parameters might be passed to the newly created modal:
When a modal is created, paramaters might be passed to the newly created modal:
```ts
// Create a modal using MyModalComponent with some initial data
@@ -53,6 +53,7 @@ modalController.dismiss({
})
```
<!-- Auto Generated Below -->
@@ -83,7 +84,7 @@ export class ModalExample {
```
```typescript
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
import { NavParams } from '@ionic/angular';
@Component({
@@ -101,37 +102,6 @@ export class ModalExample {
}
```
#### Lazy Loading
When lazy loading a modal, it's important to note that the modal will not be loaded when it is opened, but rather when the module that imports the modal's module is loaded.
For example, say there exists a `CalendarComponent` and an `EventModal`. The modal is presented by clicking a button in the `CalendarComponent`. In Angular, the `EventModalModule` would need to be included in the `CalendarComponentModule` since the modal is created in the `CalendarComponent`:
```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { CalendarComponent } from './calendar.component';
import { EventModalModule } from '../modals/event/event.module';
@NgModule({
declarations: [
CalendarComponent
],
imports: [
IonicModule,
CommonModule,
EventModalModule
],
exports: [
CalendarComponent
]
})
export class CalendarComponentModule {}
```
### Javascript

View File

@@ -1,14 +1,18 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testModal(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('modal', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -19,18 +23,18 @@ export async function testModal(
await page.click(selector);
await page.waitForSelector(selector);
let modal = await page.find('ion-modal');
await modal.waitForVisible();
let popover = await page.find('ion-modal');
await popover.waitForVisible();
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await modal.callMethod('dismiss');
await modal.waitForNotVisible();
await popover.callMethod('dismiss');
await popover.waitForNotVisible();
screenshotCompares.push(await page.compareScreenshot('dismiss'));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
modal = await page.find('ion-modal');
expect(modal).toBeNull();
popover = await page.find('ion-modal');
expect(popover).toBeNull();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();

View File

@@ -21,7 +21,7 @@ export class ModalExample {
```
```typescript
import { Component, Input } from '@angular/core';
import { Component } from '@angular/core';
import { NavParams } from '@ionic/angular';
@Component({
@@ -38,34 +38,3 @@ export class ModalExample {
}
```
#### Lazy Loading
When lazy loading a modal, it's important to note that the modal will not be loaded when it is opened, but rather when the module that imports the modal's module is loaded.
For example, say there exists a `CalendarComponent` and an `EventModal`. The modal is presented by clicking a button in the `CalendarComponent`. In Angular, the `EventModalModule` would need to be included in the `CalendarComponentModule` since the modal is created in the `CalendarComponent`:
```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { CalendarComponent } from './calendar.component';
import { EventModalModule } from '../modals/event/event.module';
@NgModule({
declarations: [
CalendarComponent
],
imports: [
IonicModule,
CommonModule,
EventModalModule
],
exports: [
CalendarComponent
]
})
export class CalendarComponentModule {}
```

View File

@@ -26,10 +26,7 @@ export class Note implements ComponentInterface {
hostData() {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
}
class: createColorClasses(this.color)
};
}

View File

@@ -349,7 +349,6 @@ export class PickerColumnCmp implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'picker-col': true,
'picker-opts-left': this.col.align === 'left',
'picker-opts-right': this.col.align === 'right'

View File

@@ -1,14 +1,18 @@
import { newE2EPage } from '@stencil/core/testing';
import { dragElementBy, generateE2EUrl, listenForEvent, waitForFunctionTestContext } from '../../../utils/test/utils';
import { cleanScreenshotName, dragElementBy, generateE2EUrl, listenForEvent, waitForFunctionTestContext } from '../../../utils/test/utils';
export async function testPickerColumn(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('picker-column', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -20,7 +24,7 @@ export async function testPickerColumn(
await openButton.click();
await page.waitFor(250);
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(`${screenshotName}`));
// Setup counter
let colChangeCounter: any;

View File

@@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me
import { Animation, AnimationBuilder, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface, PickerButton, PickerColumn } from '../../interface';
import { dismiss, eventMethod, present } from '../../utils/overlays';
import { getClassMap } from '../../utils/theme';
import { createThemedClasses, getClassMap } from '../../utils/theme';
import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave';
@@ -204,11 +204,7 @@ export class Picker implements ComponentInterface, OverlayInterface {
return {
'aria-modal': 'true',
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`picker-${this.mode}`]: true,
...createThemedClasses(this.mode, 'picker'),
...getClassMap(this.cssClass)
},
style: {

View File

@@ -205,7 +205,6 @@ export class Popover implements ComponentInterface, OverlayInterface {
},
class: {
...getClassMap(this.cssClass),
[`${this.mode}`]: true,
'popover-translucent': this.translucent
}
};

View File

@@ -1,14 +1,18 @@
import { newE2EPage } from '@stencil/core/testing';
import { generateE2EUrl } from '../../../utils/test/utils';
import { cleanScreenshotName, generateE2EUrl } from '../../../utils/test/utils';
export async function testPopover(
type: string,
selector: string,
rtl = false
rtl = false,
screenshotName: string = cleanScreenshotName(selector)
) {
try {
const pageUrl = generateE2EUrl('popover', type, rtl);
if (rtl) {
screenshotName = `${screenshotName} rtl`;
}
const page = await newE2EPage({
url: pageUrl
@@ -22,12 +26,12 @@ export async function testPopover(
let popover = await page.find('ion-popover');
await popover.waitForVisible();
screenshotCompares.push(await page.compareScreenshot());
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await popover.callMethod('dismiss');
await popover.waitForNotVisible();
screenshotCompares.push(await page.compareScreenshot('dismiss'));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
popover = await page.find('ion-popover');
expect(popover).toBeNull();

View File

@@ -62,7 +62,6 @@ export class ProgressBar implements ComponentInterface {
'aria-valuemax': 1,
class: {
...createColorClasses(color),
[`${this.mode}`]: true,
[`progress-bar-${type}`]: true,
'progress-paused': paused,
'progress-bar-reversed': document.dir === 'rtl' ? !reversed : reversed

View File

@@ -1,12 +1,11 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Prop, Watch } from '@stencil/core';
import { Mode, RadioGroupChangeEventDetail } from '../../interface';
import { RadioGroupChangeEventDetail } from '../../interface';
@Component({
tag: 'ion-radio-group'
})
export class RadioGroup implements ComponentInterface {
mode!: Mode;
private inputId = `ion-rg-${radioGroupIds++}`;
private labelId = `${this.inputId}-lbl`;
@@ -123,10 +122,7 @@ export class RadioGroup implements ComponentInterface {
hostData() {
return {
'role': 'radiogroup',
'aria-labelledby': this.labelId,
class: {
[`${this.mode}`]: true,
}
'aria-labelledby': this.labelId
};
}
}

View File

@@ -163,7 +163,6 @@ export class Radio implements ComponentInterface {
'aria-labelledby': labelId,
class: {
...createColorClasses(color),
[`${this.mode}`]: true,
'in-item': hostContext('ion-item', el),
'interactive': true,
'radio-checked': checked,

View File

@@ -379,7 +379,6 @@ export class Range implements ComponentInterface {
return {
class: {
...createColorClasses(this.color),
[`${this.mode}`]: true,
'in-item': hostContext('ion-item', this.el),
'range-disabled': this.disabled,
'range-pressed': this.pressedKnob !== undefined,

View File

@@ -56,14 +56,6 @@ export class RefresherContent implements ComponentInterface {
}
}
hostData() {
return {
class: {
[`${this.mode}`]: true,
}
};
}
render() {
return [
<div class="refresher-pulling">

View File

@@ -1,6 +1,7 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
import { Gesture, GestureDetail, Mode, RefresherEventDetail } from '../../interface';
import { createThemedClasses } from '../../utils/theme';
@Component({
tag: 'ion-refresher',
@@ -349,10 +350,7 @@ export class Refresher implements ComponentInterface {
return {
slot: 'fixed',
class: {
[`${this.mode}`]: true,
// Used internally for styling
[`refresher-${this.mode}`]: true,
...createThemedClasses(this.mode, 'refresher'),
'refresher-active': this.state !== RefresherState.Inactive,
'refresher-pulling': this.state === RefresherState.Pulling,

View File

@@ -1,9 +1,9 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi, State, Watch } from '@stencil/core';
import { Gesture, GestureDetail, ItemReorderEventDetail, Mode } from '../../interface';
import { Gesture, GestureDetail, ItemReorderEventDetail } from '../../interface';
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '../../utils/haptic';
const enum ReorderGroupState {
const enum ReordeGroupState {
Idle = 0,
Active = 1,
Complete = 2
@@ -14,7 +14,6 @@ const enum ReorderGroupState {
styleUrl: 'reorder-group.scss'
})
export class ReorderGroup implements ComponentInterface {
mode!: Mode;
private selectedItemEl?: HTMLElement;
private selectedItemHeight!: number;
@@ -30,7 +29,7 @@ export class ReorderGroup implements ComponentInterface {
private containerTop = 0;
private containerBottom = 0;
@State() state = ReorderGroupState.Idle;
@State() state = ReordeGroupState.Idle;
@Element() el!: HTMLElement;
@@ -99,7 +98,7 @@ export class ReorderGroup implements ComponentInterface {
}
private canStart(ev: GestureDetail): boolean {
if (this.selectedItemEl || this.state !== ReorderGroupState.Idle) {
if (this.selectedItemEl || this.state !== ReordeGroupState.Idle) {
return false;
}
const target = ev.event.target as HTMLElement;
@@ -152,7 +151,7 @@ export class ReorderGroup implements ComponentInterface {
this.lastToIndex = indexForItem(item);
this.selectedItemHeight = item.offsetHeight;
this.state = ReorderGroupState.Active;
this.state = ReordeGroupState.Active;
item.classList.add(ITEM_REORDER_SELECTED);
@@ -188,9 +187,9 @@ export class ReorderGroup implements ComponentInterface {
private onEnd() {
const selectedItem = this.selectedItemEl;
this.state = ReorderGroupState.Complete;
this.state = ReordeGroupState.Complete;
if (!selectedItem) {
this.state = ReorderGroupState.Idle;
this.state = ReordeGroupState.Idle;
return;
}
@@ -213,7 +212,7 @@ export class ReorderGroup implements ComponentInterface {
private completeSync(listOrReorder?: boolean | any[]): any {
const selectedItemEl = this.selectedItemEl;
if (selectedItemEl && this.state === ReorderGroupState.Complete) {
if (selectedItemEl && this.state === ReordeGroupState.Complete) {
const children = this.el.children as any;
const len = children.length;
const toIndex = this.lastToIndex;
@@ -238,7 +237,7 @@ export class ReorderGroup implements ComponentInterface {
selectedItemEl.style.transition = '';
selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
this.selectedItemEl = undefined;
this.state = ReorderGroupState.Idle;
this.state = ReordeGroupState.Idle;
}
return listOrReorder;
}
@@ -294,9 +293,8 @@ export class ReorderGroup implements ComponentInterface {
hostData() {
return {
class: {
[`${this.mode}`]: true,
'reorder-enabled': !this.disabled,
'reorder-list-active': this.state !== ReorderGroupState.Idle,
'reorder-list-active': this.state !== ReordeGroupState.Idle,
}
};
}

Some files were not shown because too many files have changed in this diff Show More