refactor(all): additional tslint rules

This commit is contained in:
Manu Mtz.-Almeida
2018-09-01 17:21:42 +02:00
parent ba2230510e
commit e7416435d8
42 changed files with 419 additions and 380 deletions

View File

@ -43,6 +43,7 @@
"stylelint-order": "^0.8.1", "stylelint-order": "^0.8.1",
"tslint": "^5.10.0", "tslint": "^5.10.0",
"tslint-ionic-rules": "0.0.17", "tslint-ionic-rules": "0.0.17",
"tslint-react": "^3.6.0",
"typescript": "^2.9.2", "typescript": "^2.9.2",
"yargs": "^12.0.1" "yargs": "^12.0.1"
}, },

File diff suppressed because it is too large Load Diff

View File

@ -329,8 +329,8 @@ export class Alert implements OverlayInterface {
disabled={i.disabled} disabled={i.disabled}
tabIndex={0} tabIndex={0}
role="checkbox" role="checkbox"
class="alert-tappable alert-checkbox alert-checkbox-button"> class="alert-tappable alert-checkbox alert-checkbox-button"
>
<div class="alert-button-inner"> <div class="alert-button-inner">
<div class="alert-checkbox-icon"> <div class="alert-checkbox-icon">
<div class="alert-checkbox-inner"></div> <div class="alert-checkbox-inner"></div>
@ -339,7 +339,7 @@ export class Alert implements OverlayInterface {
{i.label} {i.label}
</div> </div>
</div> </div>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</button> </button>
))} ))}
</div> </div>
@ -359,16 +359,18 @@ export class Alert implements OverlayInterface {
onClick={() => this.rbClick(i)} onClick={() => this.rbClick(i)}
aria-checked={i.checked ? 'true' : null} aria-checked={i.checked ? 'true' : null}
disabled={i.disabled} disabled={i.disabled}
id={i.id} tabIndex={0} id={i.id}
tabIndex={0}
class="alert-radio-button alert-tappable alert-radio" class="alert-radio-button alert-tappable alert-radio"
role="radio"> role="radio"
>
<div class="alert-button-inner"> <div class="alert-button-inner">
<div class="alert-radio-icon"><div class="alert-radio-inner"></div></div> <div class="alert-radio-icon"><div class="alert-radio-inner"></div></div>
<div class="alert-radio-label"> <div class="alert-radio-label">
{i.label} {i.label}
</div> </div>
</div> </div>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</button> </button>
))} ))}
</div> </div>
@ -394,7 +396,8 @@ export class Alert implements OverlayInterface {
id={i.id} id={i.id}
disabled={i.disabled} disabled={i.disabled}
tabIndex={0} tabIndex={0}
class="alert-input"/> class="alert-input"
/>
</div> </div>
))} ))}
</div> </div>
@ -451,14 +454,14 @@ export class Alert implements OverlayInterface {
<div class="alert-wrapper"> <div class="alert-wrapper">
<div class="alert-head"> <div class="alert-head">
{ this.header && <h2 id={hdrId} class="alert-title">{this.header}</h2> } {this.header && <h2 id={hdrId} class="alert-title">{this.header}</h2>}
{ this.subHeader && <h2 id={subHdrId} class="alert-sub-title">{this.subHeader}</h2> } {this.subHeader && <h2 id={subHdrId} class="alert-sub-title">{this.subHeader}</h2>}
</div> </div>
<div id={msgId} class="alert-message" innerHTML={this.message}></div> <div id={msgId} class="alert-message" innerHTML={this.message}></div>
{ this.renderAlertInputs(labelledById) } {this.renderAlertInputs(labelledById)}
{ this.renderAlertButtons() } {this.renderAlertButtons()}
</div> </div>
]; ];

View File

@ -41,7 +41,8 @@ export class Anchor {
return ( return (
<a <a
href={this.href} href={this.href}
onClick={ev => openURL(this.win, this.href, ev, this.routerDirection)}> onClick={ev => openURL(this.win, this.href, ev, this.routerDirection)}
>
<slot></slot> <slot></slot>
</a> </a>
); );

View File

@ -25,7 +25,9 @@ export const TRANSFORM_PROPS: {[key: string]: number} = {
'perspective': 1 'perspective': 1
}; };
const raf = window.requestAnimationFrame || ((f: FrameRequestCallback) => f(Date.now())); const raf = window.requestAnimationFrame
? window.requestAnimationFrame.bind(window)
: (f: FrameRequestCallback) => f(Date.now());
export class Animator { export class Animator {
@ -627,10 +629,7 @@ export class Animator {
/** /**
* Immediately stop at the end of the animation. * Immediately stop at the end of the animation.
*/ */
stop(stepValue?: number) { stop(stepValue = 1) {
if (stepValue === undefined) {
stepValue = 1;
}
// ensure all past transition end events have been cleared // ensure all past transition end events have been cleared
this._clearAsync(); this._clearAsync();
this._hasDur = true; this._hasDur = true;
@ -1045,7 +1044,7 @@ export class Animator {
/** /**
* End the progress animation. * End the progress animation.
*/ */
progressEnd(shouldComplete: boolean, currentStepValue: number, dur?: number) { progressEnd(shouldComplete: boolean, currentStepValue: number, dur = -1) {
if (this._isReverse) { if (this._isReverse) {
// if the animation is going in reverse then // if the animation is going in reverse then
// flip the step value: 0 becomes 1, 1 becomes 0 // flip the step value: 0 becomes 1, 1 becomes 0
@ -1053,9 +1052,6 @@ export class Animator {
} }
const stepValue = shouldComplete ? 1 : 0; const stepValue = shouldComplete ? 1 : 0;
const diff = Math.abs(currentStepValue - stepValue); const diff = Math.abs(currentStepValue - stepValue);
if (dur === undefined) {
dur = -1;
}
if (dur < 0) { if (dur < 0) {
dur = this._duration || 0; dur = this._duration || 0;
} else if (diff < 0.05) { } else if (diff < 0.05) {
@ -1178,10 +1174,7 @@ export class Animator {
/** /**
* Reverse the animation. * Reverse the animation.
*/ */
reverse(shouldReverse?: boolean): Animator { reverse(shouldReverse = true): Animator {
if (shouldReverse === undefined) {
shouldReverse = true;
}
const children = this._childAnimations; const children = this._childAnimations;
if (children) { if (children) {
for (const child of children) { for (const child of children) {

View File

@ -77,11 +77,12 @@ export class BackButton {
<button <button
type="button" type="button"
class="back-button-native" class="back-button-native"
onClick={ev => this.onClick(ev)}> onClick={ev => this.onClick(ev)}
>
<span class="back-button-inner"> <span class="back-button-inner">
{ backButtonIcon && <ion-icon icon={backButtonIcon} lazy={false}/> } {backButtonIcon && <ion-icon icon={backButtonIcon} lazy={false}/>}
{ this.mode === 'ios' && backButtonText && <span class="button-text">{backButtonText}</span> } {this.mode === 'ios' && backButtonText && <span class="button-text">{backButtonText}</span>}
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</span> </span>
</button> </button>
); );

View File

@ -68,7 +68,7 @@
// okay cool, we're in the DOM now // okay cool, we're in the DOM now
await nav.push(secondPage); await nav.push(secondPage);
const nextButton = secondPage.querySelector('ion-button .next'); const nextButton = secondPage.querySelector('ion-button.next');
nextButton.addEventListener('click', async () => { nextButton.addEventListener('click', async () => {
await goToPageThree(nav); await goToPageThree(nav);
}); });
@ -96,7 +96,7 @@
// okay cool, we're in the DOM now // okay cool, we're in the DOM now
await nav.push(thirdPage); await nav.push(thirdPage);
const nextButton = thirdPage.querySelector('ion-button .next'); const nextButton = thirdPage.querySelector('ion-button.next');
nextButton.addEventListener('click', async () => { nextButton.addEventListener('click', async () => {
await goToPageFour(nav); await goToPageFour(nav);
}); });

View File

@ -68,7 +68,7 @@
// okay cool, we're in the DOM now // okay cool, we're in the DOM now
await nav.push(secondPage); await nav.push(secondPage);
const nextButton = secondPage.querySelector('ion-button .next'); const nextButton = secondPage.querySelector('ion-button.next');
nextButton.addEventListener('click', async () => { nextButton.addEventListener('click', async () => {
await goToPageThree(nav); await goToPageThree(nav);
}); });
@ -96,7 +96,7 @@
// okay cool, we're in the DOM now // okay cool, we're in the DOM now
await nav.push(thirdPage); await nav.push(thirdPage);
const nextButton = thirdPage.querySelector('ion-button .next'); const nextButton = thirdPage.querySelector('ion-button.next');
nextButton.addEventListener('click', async () => { nextButton.addEventListener('click', async () => {
await goToPageFour(nav); await goToPageFour(nav);
}); });

View File

@ -177,14 +177,15 @@ export class Button {
onFocus={this.onFocus.bind(this)} onFocus={this.onFocus.bind(this)}
onKeyUp={this.onKeyUp.bind(this)} onKeyUp={this.onKeyUp.bind(this)}
onBlur={this.onBlur.bind(this)} onBlur={this.onBlur.bind(this)}
onClick={this.onClick.bind(this)}> onClick={this.onClick.bind(this)}
>
<span class="button-inner"> <span class="button-inner">
<slot name="icon-only"></slot> <slot name="icon-only"></slot>
<slot name="start"></slot> <slot name="start"></slot>
<slot></slot> <slot></slot>
<slot name="end"></slot> <slot name="end"></slot>
</span> </span>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</TagType> </TagType>
); );
} }
@ -212,7 +213,6 @@ function getButtonTypeClassMap(buttonType: string, type: string | undefined, mod
if (type === undefined) { if (type === undefined) {
return {}; return {};
} }
type = type.toLocaleLowerCase();
return { return {
[`${buttonType}-${type}`]: true, [`${buttonType}-${type}`]: true,
[`${buttonType}-${type}-${mode}`]: true [`${buttonType}-${type}-${mode}`]: true

View File

@ -147,7 +147,8 @@ export class Checkbox {
checked={this.checked} checked={this.checked}
name={this.name} name={this.name}
value={this.value} value={this.value}
disabled={this.disabled} /> disabled={this.disabled}
/>
]; ];
} }
} }

View File

@ -58,11 +58,12 @@ export class ChipButton {
type="button" type="button"
class="chip-button-native" class="chip-button-native"
disabled={this.disabled} disabled={this.disabled}
href={this.href}> href={this.href}
>
<span class="chip-button-inner"> <span class="chip-button-inner">
<slot></slot> <slot></slot>
</span> </span>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</TagType> </TagType>
); );
} }

View File

@ -295,7 +295,8 @@ export class Content {
'overscroll': (scrollX || scrollY) && !!forceOverscroll 'overscroll': (scrollX || scrollY) && !!forceOverscroll
}} }}
ref={el => this.scrollEl = el!} ref={el => this.scrollEl = el!}
onScroll={ev => this.onScroll(ev)}> onScroll={ev => this.onScroll(ev)}
>
<slot></slot> <slot></slot>
</div>, </div>,
<slot name="fixed"></slot> <slot name="fixed"></slot>

View File

@ -528,7 +528,7 @@ export class Datetime {
}; };
return [ return [
<div class={datetimeTextClasses}>{ datetimeText }</div>, <div class={datetimeTextClasses}>{datetimeText}</div>,
<button <button
type="button" type="button"
aria-haspopup="true" aria-haspopup="true"
@ -536,8 +536,9 @@ export class Datetime {
aria-labelledby={this.labelId} aria-labelledby={this.labelId}
aria-disabled={this.disabled ? 'true' : null} aria-disabled={this.disabled ? 'true' : null}
onClick={this.open.bind(this)} onClick={this.open.bind(this)}
class="datetime-cover"> class="datetime-cover"
{ this.mode === 'md' && <ion-ripple-effect /> } >
{this.mode === 'md' && <ion-ripple-effect />}
</button> </button>
]; ];
} }

View File

@ -216,7 +216,7 @@ dates in JavaScript.
| `hourValues` | -- | Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers. | `number[]`, `number`, `string` | | `hourValues` | -- | Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers. | `number[]`, `number`, `string` |
| `max` | `max` | The maximum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the maximum could just be the year, such as `1994`. Defaults to the end of this year. | `string` | | `max` | `max` | The maximum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the maximum could just be the year, such as `1994`. Defaults to the end of this year. | `string` |
| `min` | `min` | The minimum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), such as `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the minimum could just be the year, such as `1994`. Defaults to the beginning of the year, 100 years ago from today. | `string` | | `min` | `min` | The minimum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), such as `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the minimum could just be the year, such as `1994`. Defaults to the beginning of the year, 100 years ago from today. | `string` |
| `minuteValues` | -- | Values used to create the list of selectable minutes. By default the mintues range from `0` to `59`. However, to control exactly which minutes to display, the `minuteValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if the minute selections should only be every 15 minutes, then this input value would be `minuteValues="0,15,30,45"`. | `number[]`, `number`, `string` | | `minuteValues` | -- | Values used to create the list of selectable minutes. By default the minutes range from `0` to `59`. However, to control exactly which minutes to display, the `minuteValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if the minute selections should only be every 15 minutes, then this input value would be `minuteValues="0,15,30,45"`. | `number[]`, `number`, `string` |
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `Mode` | | `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `Mode` |
| `monthNames` | `month-names` | Full names for each month name. This can be used to provide locale month names. Defaults to English. | `string[]`, `string` | | `monthNames` | `month-names` | Full names for each month name. This can be used to provide locale month names. Defaults to English. | `string[]`, `string` |
| `monthShortNames` | `month-short-names` | Short abbreviated names for each month name. This can be used to provide locale month names. Defaults to English. | `string[]`, `string` | | `monthShortNames` | `month-short-names` | Short abbreviated names for each month name. This can be used to provide locale month names. Defaults to English. | `string[]`, `string` |

View File

@ -94,14 +94,15 @@ export class FabButton {
<TagType <TagType
class="fab-button-native" class="fab-button-native"
disabled={this.disabled} disabled={this.disabled}
href={this.href}> href={this.href}
>
<span class="fab-button-close-icon"> <span class="fab-button-close-icon">
<ion-icon name="close" lazy={false}></ion-icon> <ion-icon name="close" lazy={false}></ion-icon>
</span> </span>
<span class="fab-button-inner"> <span class="fab-button-inner">
<slot></slot> <slot></slot>
</span> </span>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</TagType> </TagType>
); );
} }

View File

@ -72,7 +72,8 @@ export class Img {
<img <img
src={this.loadSrc} src={this.loadSrc}
alt={this.alt} alt={this.alt}
decoding="async"></img> decoding="async"
/>
); );
} }
} }

View File

@ -369,7 +369,8 @@ export class Input {
type="button" type="button"
class="input-clear-icon" class="input-clear-icon"
onTouchStart={this.clearTextInput.bind(this)} onTouchStart={this.clearTextInput.bind(this)}
onMouseDown={this.clearTextInput.bind(this)}/> onMouseDown={this.clearTextInput.bind(this)}
/>
]; ];
} }
} }

View File

@ -158,10 +158,10 @@ export class Item {
<slot></slot> <slot></slot>
</div> </div>
<slot name="end"></slot> <slot name="end"></slot>
{ showDetail && <ion-icon icon={detailIcon} lazy={false} class="item-detail-icon"></ion-icon> } {showDetail && <ion-icon icon={detailIcon} lazy={false} class="item-detail-icon"></ion-icon>}
</div> </div>
{ state && <div class="item-state"></div> } {state && <div class="item-state"></div>}
{ clickable && mode === 'md' && <ion-ripple-effect /> } {clickable && mode === 'md' && <ion-ripple-effect />}
</TagType> </TagType>
); );
} }

View File

@ -12,12 +12,6 @@ import { createColorClasses } from '../../utils/theme';
shadow: true shadow: true
}) })
export class ListHeader { export class ListHeader {
/**
* The color to use from your application's color palette.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
* For more information on colors, see [theming](/docs/theming/basics).
*/
@Prop() color?: Color;
/** /**
* The mode determines which platform styles to use. * The mode determines which platform styles to use.
@ -25,6 +19,13 @@ export class ListHeader {
*/ */
@Prop() mode!: Mode; @Prop() mode!: Mode;
/**
* The color to use from your application's color palette.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
* For more information on colors, see [theming](/docs/theming/basics).
*/
@Prop() color?: Color;
hostData() { hostData() {
return { return {
class: createColorClasses(this.color) class: createColorClasses(this.color)

View File

@ -11,6 +11,7 @@ import { menuRevealAnimation } from './animations/reveal';
styleUrl: 'menu-controller.scss' styleUrl: 'menu-controller.scss'
}) })
export class MenuController implements MenuControllerI { export class MenuController implements MenuControllerI {
private menus: MenuI[] = []; private menus: MenuI[] = [];
private menuAnimations = new Map<string, AnimationBuilder>(); private menuAnimations = new Map<string, AnimationBuilder>();
@ -26,7 +27,7 @@ export class MenuController implements MenuControllerI {
* Open the menu. * Open the menu.
*/ */
@Method() @Method()
async open(menuId?: string): Promise<boolean> { async open(menuId?: string | null): Promise<boolean> {
const menu = await this.get(menuId); const menu = await this.get(menuId);
if (menu) { if (menu) {
return menu.open(); return menu.open();
@ -39,7 +40,7 @@ export class MenuController implements MenuControllerI {
* that is open. If a menu is specified, it will close that menu. * that is open. If a menu is specified, it will close that menu.
*/ */
@Method() @Method()
async close(menuId?: string): Promise<boolean> { async close(menuId?: string | null): Promise<boolean> {
const menu = await (menuId !== undefined ? this.get(menuId) : this.getOpen()); const menu = await (menuId !== undefined ? this.get(menuId) : this.getOpen());
if (menu !== undefined) { if (menu !== undefined) {
return menu.close(); return menu.close();
@ -52,7 +53,7 @@ export class MenuController implements MenuControllerI {
* will close. * will close.
*/ */
@Method() @Method()
async toggle(menuId?: string): Promise<boolean> { async toggle(menuId?: string | null): Promise<boolean> {
const menu = await this.get(menuId); const menu = await this.get(menuId);
if (menu) { if (menu) {
return menu.toggle(); return menu.toggle();
@ -67,7 +68,7 @@ export class MenuController implements MenuControllerI {
* will also automatically disable all the others that are on the same side. * will also automatically disable all the others that are on the same side.
*/ */
@Method() @Method()
async enable(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement | undefined> { async enable(shouldEnable: boolean, menuId?: string | null): Promise<HTMLIonMenuElement | undefined> {
const menu = await this.get(menuId); const menu = await this.get(menuId);
if (menu) { if (menu) {
menu.disabled = !shouldEnable; menu.disabled = !shouldEnable;
@ -79,7 +80,7 @@ export class MenuController implements MenuControllerI {
* Used to enable or disable the ability to swipe open the menu. * Used to enable or disable the ability to swipe open the menu.
*/ */
@Method() @Method()
async swipeGesture(shouldEnable: boolean, menuId?: string): Promise<HTMLIonMenuElement | undefined> { async swipeGesture(shouldEnable: boolean, menuId?: string | null): Promise<HTMLIonMenuElement | undefined> {
const menu = await this.get(menuId); const menu = await this.get(menuId);
if (menu) { if (menu) {
menu.swipeGesture = shouldEnable; menu.swipeGesture = shouldEnable;
@ -92,8 +93,8 @@ export class MenuController implements MenuControllerI {
* will return true if any menu is currently open. * will return true if any menu is currently open.
*/ */
@Method() @Method()
async isOpen(menuId?: string): Promise<boolean> { async isOpen(menuId?: string | null): Promise<boolean> {
if (menuId !== undefined) { if (menuId != null) {
const menu = await this.get(menuId); const menu = await this.get(menuId);
return (menu !== undefined && menu.isOpen()); return (menu !== undefined && menu.isOpen());
} else { } else {
@ -106,7 +107,7 @@ export class MenuController implements MenuControllerI {
* Returns true if the specified menu is enabled. * Returns true if the specified menu is enabled.
*/ */
@Method() @Method()
async isEnabled(menuId?: string): Promise<boolean> { async isEnabled(menuId?: string | null): Promise<boolean> {
const menu = await this.get(menuId); const menu = await this.get(menuId);
if (menu) { if (menu) {
return !menu.disabled; return !menu.disabled;
@ -122,7 +123,7 @@ export class MenuController implements MenuControllerI {
* return `null`. * return `null`.
*/ */
@Method() @Method()
async get(menuId?: string): Promise<HTMLIonMenuElement | undefined> { async get(menuId?: string | null): Promise<HTMLIonMenuElement | undefined> {
if (Build.isDev) { if (Build.isDev) {
if (menuId === 'left') { if (menuId === 'left') {
console.error('menu.side=left is deprecated, use "start" instead'); console.error('menu.side=left is deprecated, use "start" instead');
@ -145,7 +146,7 @@ export class MenuController implements MenuControllerI {
// so try to get the first menu side found // so try to get the first menu side found
return this.find(m => m.side === menuId); return this.find(m => m.side === menuId);
} else if (menuId !== undefined) { } else if (menuId != null) {
// the menuId was not left or right // the menuId was not left or right
// so try to get the menu by its "id" // so try to get the menu by its "id"
return this.find(m => m.menuId === menuId); return this.find(m => m.menuId === menuId);

View File

@ -6,8 +6,8 @@ import { Component, Listen, Prop, State } from '@stencil/core';
shadow: true shadow: true
}) })
export class MenuToggle { export class MenuToggle {
@Prop({ context: 'document' })
doc!: Document; @Prop({ context: 'document' }) doc!: Document;
@State() visible = false; @State() visible = false;

View File

@ -78,7 +78,7 @@
// okay cool, we're in the DOM now // okay cool, we're in the DOM now
await nav.push(secondPage); await nav.push(secondPage);
const nextButton = secondPage.querySelector('ion-button .next'); const nextButton = secondPage.querySelector('ion-button.next');
nextButton.addEventListener('click', async () => { nextButton.addEventListener('click', async () => {
await goToPageThree(nav); await goToPageThree(nav);
}); });

View File

@ -83,7 +83,7 @@
// okay cool, we're in the DOM now // okay cool, we're in the DOM now
await nav.push(secondPage); await nav.push(secondPage);
const nextButton = secondPage.querySelector('ion-button .next'); const nextButton = secondPage.querySelector('ion-button.next');
nextButton.addEventListener('click', async () => { nextButton.addEventListener('click', async () => {
await goToPageThree(nav); await goToPageThree(nav);
}); });

View File

@ -315,13 +315,14 @@ export class PickerColumnCmp {
<div <div
class="picker-opts" class="picker-opts"
style={{ maxWidth: col.optionsWidth! }} style={{ maxWidth: col.optionsWidth! }}
ref={ el => this.optsEl = el }> ref={el => this.optsEl = el}
>
{ col.options.map((o, index) => { col.options.map((o, index) =>
<Button <Button
type="button" type="button"
class={{ 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }} class={{ 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }}
disable-activated opt-index={index}
opt-index={index}> >
{o.text} {o.text}
</Button> </Button>
)} )}

View File

@ -260,8 +260,10 @@ export class Picker implements OverlayInterface {
<div class={buttonWrapperClass(b)}> <div class={buttonWrapperClass(b)}>
<button <button
type="button" type="button"
ion-activable
onClick={() => this.buttonClick(b)} onClick={() => this.buttonClick(b)}
class={buttonClass(b)}> class={buttonClass(b)}
>
{b.text} {b.text}
</button> </button>
</div> </div>
@ -270,7 +272,7 @@ export class Picker implements OverlayInterface {
<div class="picker-columns"> <div class="picker-columns">
<div class="picker-above-highlight" /> <div class="picker-above-highlight" />
{ this.columns.map(c => <ion-picker-column col={c} />) } {this.columns.map(c => <ion-picker-column col={c} />)}
<div class="picker-below-highlight" /> <div class="picker-below-highlight" />
</div> </div>
</div> </div>

View File

@ -40,11 +40,11 @@ A Picker is a dialog that displays a row of buttons and columns underneath. It a
## Methods ## Methods
| Method | Description | | Method | Description |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------- | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `dismiss` | Dismiss the picker overlay after it has been presented. | | `dismiss` | Dismiss the picker overlay after it has been presented. |
| `getColumn` | Returns the column the matches the specified name | | `getColumn` | Returns the column the matches the specified name |
| `onDidDismiss` | Returns a promise that resolves when the picker did dismiss. It also accepts a callback that is called in the same circustances. | | `onDidDismiss` | Returns a promise that resolves when the picker did dismiss. It also accepts a callback that is called in the same circustances. |
| `onWillDismiss` | Returns a promise that resolves when the picker will dismiss. It also accepts a callback that is called in the same circustances. | | `onWillDismiss` | Returns a promise that resolves when the picker will dismiss. It also accepts a callback that is called in the same circumstances. |
| `present` | Present the picker overlay after it has been created. | | `present` | Present the picker overlay after it has been created. |

View File

@ -197,7 +197,8 @@ export class Radio {
name={this.name} name={this.name}
value={this.value} value={this.value}
disabled={this.disabled} disabled={this.disabled}
ref={r => this.nativeInput = (r as any)}/> ref={r => this.nativeInput = (r as any)}
/>
]; ];
} }
} }

View File

@ -451,8 +451,9 @@ function renderKnob({ knob, value, ratio, min, max, disabled, pressed, pin, hand
aria-valuemin={min} aria-valuemin={min}
aria-valuemax={max} aria-valuemax={max}
aria-disabled={disabled ? 'true' : null} aria-disabled={disabled ? 'true' : null}
aria-valuenow={value}> aria-valuenow={value}
{ pin && <div class="range-pin" role="presentation">{Math.round(value)}</div>} >
{pin && <div class="range-pin" role="presentation">{Math.round(value)}</div>}
<div class="range-knob" role="presentation" /> <div class="range-knob" role="presentation" />
</div> </div>
); );

View File

@ -328,17 +328,19 @@ export class Searchbar {
const clearIcon = this.clearIcon || (this.mode === 'ios' ? 'ios-close-circle' : 'md-close'); const clearIcon = this.clearIcon || (this.mode === 'ios' ? 'ios-close-circle' : 'md-close');
const searchIcon = this.searchIcon || 'search'; const searchIcon = this.searchIcon || 'search';
const cancelButton = (this.showCancelButton) const cancelButton = this.showCancelButton && (
? <button <button
type="button" type="button"
tabIndex={this.mode === 'ios' && !this.focused ? -1 : undefined} tabIndex={this.mode === 'ios' && !this.focused ? -1 : undefined}
onClick={this.cancelSearchbar.bind(this)} onClick={this.cancelSearchbar.bind(this)}
class="searchbar-cancel-button"> class="searchbar-cancel-button"
>
{ this.mode === 'md' { this.mode === 'md'
? <ion-icon mode={this.mode} icon={this.cancelButtonIcon} lazy={false}></ion-icon> ? <ion-icon mode={this.mode} icon={this.cancelButtonIcon} lazy={false}></ion-icon>
: this.cancelButtonText } : this.cancelButtonText
}
</button> </button>
: null; );
return [ return [
<div class="searchbar-input-container"> <div class="searchbar-input-container">
@ -353,19 +355,21 @@ export class Searchbar {
value={this.value} value={this.value}
autoComplete={this.autocomplete} autoComplete={this.autocomplete}
autoCorrect={this.autocorrect} autoCorrect={this.autocorrect}
spellCheck={this.spellcheck}/> spellCheck={this.spellcheck}
/>
{ this.mode === 'md' && cancelButton } {this.mode === 'md' && cancelButton}
<ion-icon mode={this.mode} icon={searchIcon} lazy={false} class="searchbar-search-icon"></ion-icon> <ion-icon mode={this.mode} icon={searchIcon} lazy={false} class="searchbar-search-icon"></ion-icon>
<button <button
type="button" type="button"
no-blur={true} no-blur
class="searchbar-clear-button" class="searchbar-clear-button"
onClick={this.clearInput.bind(this)} onClick={this.clearInput.bind(this)}
onMouseDown={this.clearInput.bind(this)} onMouseDown={this.clearInput.bind(this)}
onTouchStart={this.clearInput.bind(this)}> onTouchStart={this.clearInput.bind(this)}
>
<ion-icon mode={this.mode} icon={clearIcon} lazy={false} class="searchbar-clear-icon"></ion-icon> <ion-icon mode={this.mode} icon={clearIcon} lazy={false} class="searchbar-clear-icon"></ion-icon>
</button> </button>
</div>, </div>,

View File

@ -73,9 +73,10 @@ export class SegmentButton {
aria-pressed={this.checked ? 'true' : null} aria-pressed={this.checked ? 'true' : null}
class="segment-button-native" class="segment-button-native"
disabled={this.disabled} disabled={this.disabled}
onClick={() => this.checked = true }> onClick={() => this.checked = true}
>
<slot></slot> <slot></slot>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</button> </button>
]; ];
} }

View File

@ -9,10 +9,10 @@ SelectOption is a component that is a child element of Select. For more informat
## Properties ## Properties
| Property | Attribute | Description | Type | | Property | Attribute | Description | Type |
| ---------- | ---------- | ------------------------------------------------------------------------------ | ------------- | | ---------- | ---------- | ------------------------------------------------------------------------------ | --------- |
| `disabled` | `disabled` | If true, the user cannot interact with the select option. Defaults to `false`. | `boolean` | | `disabled` | `disabled` | If true, the user cannot interact with the select option. Defaults to `false`. | `boolean` |
| `selected` | `selected` | If true, the element is selected. | `boolean` | | `selected` | `selected` | If true, the element is selected. | `boolean` |
| `value` | -- | The text value of the option. | `any`, `null` | | `value` | -- | The text value of the option. | `any` |
## Events ## Events

View File

@ -22,7 +22,7 @@ export class SelectOption {
/** /**
* The text value of the option. * The text value of the option.
*/ */
@Prop({ mutable: true }) value!: any | null; @Prop({ mutable: true }) value?: any;
/** /**
* Emitted when the select option loads. * Emitted when the select option loads.

View File

@ -40,12 +40,12 @@ export class SelectPopover {
render() { render() {
return ( return (
<ion-list> <ion-list>
{ this.header !== undefined && <ion-list-header>{this.header}</ion-list-header> } {this.header !== undefined && <ion-list-header>{this.header}</ion-list-header>}
{ (this.subHeader !== undefined || this.message !== undefined) && { (this.subHeader !== undefined || this.message !== undefined) &&
<ion-item> <ion-item>
<ion-label text-wrap> <ion-label text-wrap>
{ this.subHeader !== undefined && <h3>{this.subHeader}</h3> } {this.subHeader !== undefined && <h3>{this.subHeader}</h3>}
{ this.message !== undefined && <p>{this.message}</p> } {this.message !== undefined && <p>{this.message}</p>}
</ion-label> </ion-label>
</ion-item> </ion-item>
} }
@ -58,7 +58,8 @@ export class SelectPopover {
<ion-radio <ion-radio
checked={option.checked} checked={option.checked}
value={option.value} value={option.value}
disabled={option.disabled}> disabled={option.disabled}
>
</ion-radio> </ion-radio>
</ion-item> </ion-item>
)} )}

View File

@ -369,6 +369,7 @@ export class Select {
const interfaceOptions = this.interfaceOptions; const interfaceOptions = this.interfaceOptions;
const inputType = (this.multiple ? 'checkbox' : 'radio'); const inputType = (this.multiple ? 'checkbox' : 'radio');
const alertOpts: AlertOptions = { const alertOpts: AlertOptions = {
...interfaceOptions, ...interfaceOptions,
@ -484,7 +485,9 @@ export class Select {
<div <div
role="textbox" role="textbox"
aria-multiline="false" aria-multiline="false"
class={ selectTextClasses }>{ selectText } class={selectTextClasses}
>
{selectText}
</div>, </div>,
<div class="select-icon" role="presentation"> <div class="select-icon" role="presentation">
<div class="select-icon-inner"></div> <div class="select-icon-inner"></div>
@ -500,9 +503,10 @@ export class Select {
onKeyUp={this.onKeyUp.bind(this)} onKeyUp={this.onKeyUp.bind(this)}
onFocus={this.onFocus.bind(this)} onFocus={this.onFocus.bind(this)}
onBlur={this.onBlur.bind(this)} onBlur={this.onBlur.bind(this)}
class="select-cover"> class="select-cover"
>
<slot></slot> <slot></slot>
{ this.mode === 'md' && <ion-ripple-effect /> } {this.mode === 'md' && <ion-ripple-effect />}
</button> </button>
]; ];
} }

View File

@ -25,8 +25,8 @@
<ion-item> <ion-item>
<ion-label>Gender</ion-label> <ion-label>Gender</ion-label>
<ion-select id="gender" placeholder="Select One"> <ion-select id="gender" placeholder="Select One">
<ion-select-option value="f">Female</ion-select-option> <ion-select-option value="fn">Female</ion-select-option>
<ion-select-option value="m">Male</ion-select-option> <ion-select-option value="ml">Male</ion-select-option>
</ion-select> </ion-select>
</ion-item> </ion-item>

View File

@ -396,12 +396,12 @@ export class Slides {
render() { render() {
return ( return (
<div class="swiper-container" ref={el => this.container = el as HTMLElement }> <div class="swiper-container" ref={el => this.container = el as HTMLElement}>
<div class="swiper-wrapper"> <div class="swiper-wrapper">
<slot></slot> <slot></slot>
</div> </div>
{ this.pager ? <div class="swiper-pagination"></div> : null } {this.pager ? <div class="swiper-pagination"></div> : null}
{ this.scrollbar ? <div class="swiper-scrollbar"></div> : null } {this.scrollbar ? <div class="swiper-scrollbar"></div> : null}
</div> </div>
); );
} }

View File

@ -131,11 +131,12 @@ export class Tabbar {
this.ionTabbarClick.emit(tab); this.ionTabbarClick.emit(tab);
} }
ev.preventDefault(); ev.preventDefault();
}}> }}
{ icon && <ion-icon class="tab-btn-icon" icon={icon} lazy={false}></ion-icon> } >
{ label && <span class="tab-btn-text">{label}</span> } {icon && <ion-icon class="tab-btn-icon" icon={icon} lazy={false}></ion-icon>}
{ badge && <ion-badge class="tab-btn-badge" color={badgeColor}>{badge}</ion-badge> } {label && <span class="tab-btn-text">{label}</span>}
{ this.mode === 'md' && <ion-ripple-effect /> } {badge && <ion-badge class="tab-btn-badge" color={badgeColor}>{badge}</ion-badge>}
{this.mode === 'md' && <ion-ripple-effect />}
</a> </a>
); );
} }

View File

@ -312,7 +312,8 @@ export class Tabs implements NavOutlet {
highlight={this.tabbarHighlight} highlight={this.tabbarHighlight}
placement={this.tabbarPlacement} placement={this.tabbarPlacement}
layout={this.tabbarLayout} layout={this.tabbarLayout}
translucent={this.translucent}> translucent={this.translucent}
>
</ion-tabbar> </ion-tabbar>
) )
]; ];

View File

@ -203,7 +203,8 @@ export class Toggle {
name={this.name} name={this.name}
value={this.value} value={this.value}
disabled={this.disabled} disabled={this.disabled}
ref={r => this.nativeInput = (r as any)}/>, ref={r => this.nativeInput = (r as any)}
/>,
<slot></slot> <slot></slot>
]; ];
} }

View File

@ -243,9 +243,9 @@ export function calcCells(
export function calcHeightIndex(buf: Uint32Array, cells: Cell[], index: number): number { export function calcHeightIndex(buf: Uint32Array, cells: Cell[], index: number): number {
let acum = buf[index]; let acum = buf[index];
for (; index < buf.length; index++) { for (let i = index; i < buf.length; i++) {
buf[index] = acum; buf[i] = acum;
acum += cells[index].height; acum += cells[i].height;
} }
return acum; return acum;
} }

View File

@ -159,9 +159,10 @@ export class VirtualScroll {
if (!this.items) { if (!this.items) {
return; return;
} }
if (len === -1) { const length = (len === -1)
len = this.items.length - offset; ? this.items.length - offset
} : len;
const max = this.lastItemLen; const max = this.lastItemLen;
let j = 0; let j = 0;
if (offset > 0 && offset < max) { if (offset > 0 && offset < max) {
@ -182,7 +183,7 @@ export class VirtualScroll {
this.approxHeaderHeight, this.approxHeaderHeight,
this.approxFooterHeight, this.approxFooterHeight,
this.approxItemHeight, this.approxItemHeight,
j, offset, len j, offset, length
); );
console.debug('[virtual] cells recalculated', cells.length); console.debug('[virtual] cells recalculated', cells.length);
this.cells = inplaceUpdate(this.cells, cells, offset); this.cells = inplaceUpdate(this.cells, cells, offset);
@ -383,7 +384,7 @@ export class VirtualScroll {
if (this.renderItem) { if (this.renderItem) {
return ( return (
<VirtualProxy dom={this.virtualDom}> <VirtualProxy dom={this.virtualDom}>
{ this.virtualDom.map(node => this.renderVirtualNode(node)) } {this.virtualDom.map(node => this.renderVirtualNode(node))}
</VirtualProxy> </VirtualProxy>
); );
} }

View File

@ -1,5 +1,11 @@
{ {
"extends": "tslint-ionic-rules/strict", "extends": ["tslint-ionic-rules/strict", "tslint-react"],
"linterOptions": {
"exclude": [
"**/*.spec.ts",
"**/*.spec.tsx"
]
},
"rules": { "rules": {
"no-conditional-assignment": false, "no-conditional-assignment": false,
"no-non-null-assertion": false, "no-non-null-assertion": false,
@ -8,9 +14,15 @@
"trailing-comma": false, "trailing-comma": false,
"no-null-keyword": false, "no-null-keyword": false,
"no-console": false, "no-console": false,
"no-unbound-method": true,
"strict-type-predicates": true, "jsx-key": false,
"await-promise": true, "jsx-self-close": false,
"strict-boolean-expressions": [true, "allow-null-union", "allow-undefined-union", "allow-boolean-or-undefined"] "jsx-curly-spacing": [true, "never"],
"jsx-boolean-value": [true, "never"],
"jsx-no-bind": false,
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"jsx-wrap-multiline": false
} }
} }