From bb1ad7f281bc10b2820b71b20a7c09707037c266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=B3n=20Rodr=C3=ADguez=20Davila?= Date: Thu, 15 Aug 2019 23:51:43 +0200 Subject: [PATCH] Extends ESLint from @typescript-eslint (#371) --- .eslintrc.yaml | 13 +++++++- packages/base/src/base-element.ts | 2 +- packages/base/src/form-element.ts | 4 +-- packages/base/src/observer.ts | 3 ++ packages/base/src/utils.ts | 1 + packages/button/src/mwc-button-base.ts | 4 +-- packages/checkbox/src/mwc-checkbox-base.ts | 2 +- packages/drawer/src/mwc-drawer-base.ts | 13 ++++---- packages/fab/src/mwc-fab-base.ts | 4 +-- packages/formfield/src/mwc-formfield-base.ts | 2 +- .../src/icon-button-toggle-base.ts | 2 +- .../src/mwc-icon-button-toggle.ts | 2 +- packages/icon-button/src/icon-button-base.ts | 2 +- packages/icon-button/src/mwc-icon-button.ts | 2 +- packages/icon/src/mwc-icon-font.ts | 1 + packages/icon/src/mwc-icon.ts | 2 +- .../src/mwc-linear-progress-base.ts | 2 +- packages/radio/src/mwc-radio-base.ts | 6 ++-- packages/ripple/src/mwc-ripple-base.ts | 2 +- packages/ripple/src/ripple-directive.ts | 25 +++++++------- packages/slider/src/mwc-slider-base.ts | 2 +- packages/snackbar/src/mwc-snackbar-base.ts | 33 +++++++------------ packages/switch/src/mwc-switch-base.ts | 4 +-- packages/tab-bar/src/mwc-tab-bar-base.ts | 8 ++--- .../src/mwc-tab-indicator-base.ts | 6 ++-- .../tab-scroller/src/mwc-tab-scroller-base.ts | 6 ++-- packages/tab/src/mwc-tab-base.ts | 10 +++--- .../top-app-bar/src/mwc-top-app-bar-base.ts | 8 ++--- test/benchmark/helpers.ts | 2 +- 29 files changed, 91 insertions(+), 82 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index cd7d2b675..c86a9e929 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -1,5 +1,8 @@ extends: + - eslint:recommended - google + - plugin:@typescript-eslint/eslint-recommended + - plugin:@typescript-eslint/recommended - plugin:wc/recommended globals: goog: false @@ -17,8 +20,16 @@ settings: wc: elementBaseClasses: ["BaseElement", "LitElement", "FormElement"] rules: + # Rules temporally disabled + "@typescript-eslint/explicit-function-return-type": off + + # Rules disabled in favor of clang-format + "@typescript-eslint/indent": off indent: off - max-len: off # clang-format fixes line lengths + max-len: off + + "@typescript-eslint/explicit-member-accessibility": [error, {"accessibility": "no-public"}] + no-new: warn quotes: [error, single, {"avoidEscape": true}] no-var: error diff --git a/packages/base/src/base-element.ts b/packages/base/src/base-element.ts index c365e2318..5f3662da4 100644 --- a/packages/base/src/base-element.ts +++ b/packages/base/src/base-element.ts @@ -68,7 +68,7 @@ export abstract class BaseElement extends LitElement { this.mdcFoundation.init(); } - firstUpdated() { + protected firstUpdated() { this.createFoundation(); } } diff --git a/packages/base/src/form-element.ts b/packages/base/src/form-element.ts index a378e0adc..7ea064df9 100644 --- a/packages/base/src/form-element.ts +++ b/packages/base/src/form-element.ts @@ -35,7 +35,7 @@ export abstract class FormElement extends BaseElement { */ protected abstract formElement: HTMLElement; - createRenderRoot() { + protected createRenderRoot() { return this.attachShadow({mode: 'open', delegatesFocus: true}); } @@ -57,7 +57,7 @@ export abstract class FormElement extends BaseElement { } } - firstUpdated() { + protected firstUpdated() { super.firstUpdated(); this.mdcRoot.addEventListener('change', (e) => { this.dispatchEvent(new Event('change', e)); diff --git a/packages/base/src/observer.ts b/packages/base/src/observer.ts index 8ee7d185c..2f240931f 100644 --- a/packages/base/src/observer.ts +++ b/packages/base/src/observer.ts @@ -17,10 +17,12 @@ limitations under the License. import {PropertyValues} from 'lit-element/lib/updating-element'; export interface Observer { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (value: any, old: any): void; } export const observer = (observer: Observer) => + // eslint-disable-next-line @typescript-eslint/no-explicit-any (proto: any, propName: PropertyKey) => { // if we haven't wrapped `updated` in this class, do so if (!proto.constructor._observers) { @@ -40,6 +42,7 @@ export const observer = (observer: Observer) => const observers = proto.constructor._observers; proto.constructor._observers = new Map(); observers.forEach( + // eslint-disable-next-line @typescript-eslint/no-explicit-any (v: any, k: PropertyKey) => proto.constructor._observers.set(k, v)); } // set this method diff --git a/packages/base/src/utils.ts b/packages/base/src/utils.ts index 7a379823c..ec30415e2 100644 --- a/packages/base/src/utils.ts +++ b/packages/base/src/utils.ts @@ -31,6 +31,7 @@ export function findAssignedElement(slot: HTMLSlotElement, selector: string) { return null; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type Constructor = new (...args: any[]) => T; export function addHasRemoveClass(element: HTMLElement) { diff --git a/packages/button/src/mwc-button-base.ts b/packages/button/src/mwc-button-base.ts index f64adc479..f4a3bfbc7 100644 --- a/packages/button/src/mwc-button-base.ts +++ b/packages/button/src/mwc-button-base.ts @@ -34,11 +34,11 @@ export class ButtonBase extends LitElement { @property() label = ''; - createRenderRoot() { + protected createRenderRoot() { return this.attachShadow({mode: 'open', delegatesFocus: true}); } - render() { + protected render() { const classes = { 'mdc-button--raised': this.raised, 'mdc-button--unelevated': this.unelevated, diff --git a/packages/checkbox/src/mwc-checkbox-base.ts b/packages/checkbox/src/mwc-checkbox-base.ts index 4fe40b904..9c0255742 100644 --- a/packages/checkbox/src/mwc-checkbox-base.ts +++ b/packages/checkbox/src/mwc-checkbox-base.ts @@ -66,7 +66,7 @@ export class CheckboxBase extends FormElement { }; } - render() { + protected render() { return html`
{ // Note, casting to avoid cumbersome runtime check. - this._previousFocus = - (this.getRootNode() as any as DocumentOrShadowRoot) - .activeElement as (HTMLElement | null); + this._previousFocus = (this.getRootNode() as ShadowRoot).activeElement as HTMLElement; }, restoreFocus: () => { const previousFocus = this._previousFocus && this._previousFocus.focus; if (previousFocus) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this._previousFocus!.focus(); } }, @@ -94,7 +93,7 @@ export class DrawerBase extends BaseElement { if (this.mdcFoundation instanceof MDCModalDrawerFoundation) { this.mdcFoundation.handleScrimClick(); } - }; + } @observer(function(this: DrawerBase, value: boolean) { if (this.type === '') { @@ -113,7 +112,7 @@ export class DrawerBase extends BaseElement { @property({reflect: true}) type = ''; - render() { + protected render() { const dismissible = this.type === 'dismissible' || this.type === 'modal'; const modal = this.type === 'modal'; const header = this.hasHeader ? html` @@ -145,14 +144,14 @@ export class DrawerBase extends BaseElement { // note, we avoid calling `super.firstUpdated()` to control when // `createFoundation()` is called. - firstUpdated() { + protected firstUpdated() { this.mdcRoot.addEventListener( 'keydown', (e) => this.mdcFoundation.handleKeydown(e)); this.mdcRoot.addEventListener( 'transitionend', (e) => this.mdcFoundation.handleTransitionEnd(e)); } - updated(changedProperties: PropertyValues) { + protected updated(changedProperties: PropertyValues) { if (changedProperties.has('type')) { this.createFoundation(); } diff --git a/packages/fab/src/mwc-fab-base.ts b/packages/fab/src/mwc-fab-base.ts index 3e0462eb9..885c47a93 100644 --- a/packages/fab/src/mwc-fab-base.ts +++ b/packages/fab/src/mwc-fab-base.ts @@ -32,11 +32,11 @@ export class FabBase extends LitElement { @property() label = ''; - createRenderRoot() { + protected createRenderRoot() { return this.attachShadow({mode: 'open', delegatesFocus: true}); } - render() { + protected render() { const classes = { 'mdc-fab--mini': this.mini, 'mdc-fab--exited': this.exited, diff --git a/packages/formfield/src/mwc-formfield-base.ts b/packages/formfield/src/mwc-formfield-base.ts index f4c1cc596..ca4e2feb2 100644 --- a/packages/formfield/src/mwc-formfield-base.ts +++ b/packages/formfield/src/mwc-formfield-base.ts @@ -80,7 +80,7 @@ export class FormfieldBase extends BaseElement { return findAssignedElement(this.slotEl as HTMLSlotElement, '*'); } - render() { + protected render() { return html`
`; } } diff --git a/packages/linear-progress/src/mwc-linear-progress-base.ts b/packages/linear-progress/src/mwc-linear-progress-base.ts index 633ecb2bf..17a9057f4 100644 --- a/packages/linear-progress/src/mwc-linear-progress-base.ts +++ b/packages/linear-progress/src/mwc-linear-progress-base.ts @@ -64,7 +64,7 @@ export class LinearProgressBase extends BaseElement { }) closed = false; - render() { + protected render() { return html`
diff --git a/packages/radio/src/mwc-radio-base.ts b/packages/radio/src/mwc-radio-base.ts index 14e0208ef..559bc5183 100644 --- a/packages/radio/src/mwc-radio-base.ts +++ b/packages/radio/src/mwc-radio-base.ts @@ -89,6 +89,7 @@ export class RadioBase extends FormElement { super(); // Selection Controller is only needed for native ShadowDOM if (!window['ShadyDOM'] || !window['ShadyDOM']['inUse']) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define this._selectionController = SelectionController.getController(this); } } @@ -141,7 +142,7 @@ export class RadioBase extends FormElement { this.formElement.focus(); } - render() { + protected render() { return html`
`; } - firstUpdated() { + protected firstUpdated() { super.firstUpdated(); // We might not have been able to synchronize this from the checked setter // earlier, if checked was set before the input was stamped. @@ -264,6 +265,7 @@ export class SelectionController { const currentFocusedSet = this.focusedSet; this.focusedSet = set; if (currentFocusedSet != set && set.selected && set.selected != element) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion set.selected!.focusNative(); } } diff --git a/packages/ripple/src/mwc-ripple-base.ts b/packages/ripple/src/mwc-ripple-base.ts index 80c701bac..8862cc15a 100644 --- a/packages/ripple/src/mwc-ripple-base.ts +++ b/packages/ripple/src/mwc-ripple-base.ts @@ -39,7 +39,7 @@ export class RippleBase extends LitElement { } // TODO(sorvell) #css: sizing. - render() { + protected render() { const classes = { 'mdc-ripple-surface--primary': this.primary, 'mdc-ripple-surface--accent': this.accent, diff --git a/packages/ripple/src/ripple-directive.ts b/packages/ripple/src/ripple-directive.ts index cc617a607..4a566b689 100644 --- a/packages/ripple/src/ripple-directive.ts +++ b/packages/ripple/src/ripple-directive.ts @@ -54,6 +54,7 @@ let didApplyRippleStyle = false; const applyRippleStyle = () => { didApplyRippleStyle = true; const part = new NodePart({templateFactory}); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion part.appendInto(document.head!); part.setValue(style); part.commit(); @@ -96,14 +97,14 @@ export const rippleNode = (options: RippleNodeOptions) => { interactionNode.removeEventListener(type, handler, applyPassive()), registerDocumentInteractionHandler: (evtType: K, handler: SpecificEventListener) => - document.documentElement!.addEventListener( - evtType, handler, applyPassive()), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + document.documentElement!.addEventListener( + evtType, handler, applyPassive()), deregisterDocumentInteractionHandler: ( evtType: string, handler: SpecificEventListener) => - document.documentElement!.removeEventListener( - evtType, - handler as EventListenerOrEventListenerObject, - applyPassive()), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + document.documentElement!.removeEventListener( + evtType, handler as EventListenerOrEventListenerObject, applyPassive()), registerResizeHandler: (handler: SpecificEventListener<'resize'>) => window.addEventListener('resize', handler), deregisterResizeHandler: (handler: SpecificEventListener<'resize'>) => @@ -129,13 +130,13 @@ export const ripple = directive((options: RippleOptions = {}) => (part: PropertyPart) => { const surfaceNode = part.committer.element as HTMLElement; const interactionNode = options.interactionNode || surfaceNode; - let rippleFoundation = (part.value as any); + let rippleFoundation = part.value as MDCRippleFoundation | typeof noChange; // if the interaction node changes, destroy and invalidate the foundation. const existingInteractionNode = rippleInteractionNodes.get(rippleFoundation); if (existingInteractionNode !== undefined && existingInteractionNode !== interactionNode) { - rippleFoundation.destroy(); + (rippleFoundation as MDCRippleFoundation).destroy(); rippleFoundation = noChange; } // make the ripple, if needed @@ -147,15 +148,15 @@ export const ripple = // otherwise update settings as needed. } else { if (options.unbounded !== undefined) { - rippleFoundation.setUnbounded(options.unbounded); + (rippleFoundation as MDCRippleFoundation).setUnbounded(options.unbounded); } if (options.disabled !== undefined) { - rippleFoundation.setUnbounded(options.disabled); + (rippleFoundation as MDCRippleFoundation).setUnbounded(options.disabled); } } if (options.active === true) { - rippleFoundation.activate(); + (rippleFoundation as MDCRippleFoundation).activate(); } else if (options.active === false) { - rippleFoundation.deactivate(); + (rippleFoundation as MDCRippleFoundation).deactivate(); } }); diff --git a/packages/slider/src/mwc-slider-base.ts b/packages/slider/src/mwc-slider-base.ts index 9abb567f5..00c2ee656 100644 --- a/packages/slider/src/mwc-slider-base.ts +++ b/packages/slider/src/mwc-slider-base.ts @@ -80,7 +80,7 @@ export class SliderBase extends FormElement { @property({type: Number}) private _numMarkers = 0; // TODO(sorvell) #css: needs a default width - render() { + protected render() { const {value, min, max, step, disabled, discrete, markers, _numMarkers} = this; const hostClassInfo = { diff --git a/packages/snackbar/src/mwc-snackbar-base.ts b/packages/snackbar/src/mwc-snackbar-base.ts index a2dad52d4..b5e3357c8 100644 --- a/packages/snackbar/src/mwc-snackbar-base.ts +++ b/packages/snackbar/src/mwc-snackbar-base.ts @@ -59,7 +59,7 @@ export class SnackbarBase extends BaseElement { */ private _earlyOpen: boolean|undefined; - render() { + protected render() { const classes = { 'mdc-snackbar--stacked': this.stacked, 'mdc-snackbar--leading': this.leading, @@ -85,24 +85,15 @@ export class SnackbarBase extends BaseElement { return { ...addHasRemoveClass(this.mdcRoot), announce: () => util.announce(this.labelElement), - notifyClosed: (reason: String) => { + notifyClosed: (reason: string) => { this.isOpen = false; - this.dispatchEvent(new CustomEvent(CLOSED_EVENT, { - bubbles: true, - cancelable: true, - detail: { - reason: reason - } - })); + this.dispatchEvent(new CustomEvent( + CLOSED_EVENT, + {bubbles: true, cancelable: true, detail: {reason: reason}})); }, - notifyClosing: (reason: String) => - this.dispatchEvent(new CustomEvent(CLOSING_EVENT, { - bubbles: true, - cancelable: true, - detail: { - reason: reason - } - })), + notifyClosing: (reason: string) => this.dispatchEvent(new CustomEvent( + CLOSING_EVENT, + {bubbles: true, cancelable: true, detail: {reason: reason}})), notifyOpened: () => { this.isOpen = true; this.dispatchEvent( @@ -129,22 +120,22 @@ export class SnackbarBase extends BaseElement { } } - firstUpdated() { + protected firstUpdated() { super.firstUpdated(); if (this._earlyOpen === true) { this.mdcFoundation.open(); } } - _handleKeydown(e: KeyboardEvent) { + private _handleKeydown(e: KeyboardEvent) { this.mdcFoundation.handleKeyDown(e); } - _handleActionClick(e: MouseEvent) { + private _handleActionClick(e: MouseEvent) { this.mdcFoundation.handleActionButtonClick(e); } - _handleDismissClick(e: MouseEvent) { + private _handleDismissClick(e: MouseEvent) { this.mdcFoundation.handleActionIconClick(e); } } diff --git a/packages/switch/src/mwc-switch-base.ts b/packages/switch/src/mwc-switch-base.ts index f88090d68..dddd06afe 100644 --- a/packages/switch/src/mwc-switch-base.ts +++ b/packages/switch/src/mwc-switch-base.ts @@ -42,7 +42,7 @@ export class SwitchBase extends FormElement { this.mdcFoundation.handleChange(e); // catch "click" event and sync properties this.checked = this.formElement.checked; - }; + } protected readonly mdcFoundationClass = MDCSwitchFoundation; @@ -65,7 +65,7 @@ export class SwitchBase extends FormElement { @query('.mdc-switch__thumb-underlay') protected rippleNode!: HTMLElementWithRipple; - render() { + protected render() { return html`
diff --git a/packages/tab-bar/src/mwc-tab-bar-base.ts b/packages/tab-bar/src/mwc-tab-bar-base.ts index 86e9c47a0..39c7b38a9 100644 --- a/packages/tab-bar/src/mwc-tab-bar-base.ts +++ b/packages/tab-bar/src/mwc-tab-bar-base.ts @@ -62,7 +62,7 @@ export class TabBarBase extends BaseElement { } // TODO(sorvell): can scroller be optional for perf? - render() { + protected render() { return html`
this.scrollerElement.scrollToPosition(scrollX), @@ -134,7 +134,7 @@ export class TabBarBase extends BaseElement { }, getFocusedTabIndex: () => { const tabElements = this._getTabs(); - const activeElement = (this as any).getRootNode().activeElement; + const activeElement = (this.getRootNode() as ShadowRoot).activeElement as Tab; return tabElements.indexOf(activeElement); }, getIndexOfTabById: (id: string) => { @@ -161,7 +161,7 @@ export class TabBarBase extends BaseElement { // NOTE: Delay creating foundation until scroller is fully updated. // This is necessary because the foundation/adapter synchronously addresses // the scroller element. - firstUpdated() { + protected firstUpdated() { } protected _getUpdateComplete() { return super._getUpdateComplete() diff --git a/packages/tab-indicator/src/mwc-tab-indicator-base.ts b/packages/tab-indicator/src/mwc-tab-indicator-base.ts index 75fd044d5..200ea855d 100644 --- a/packages/tab-indicator/src/mwc-tab-indicator-base.ts +++ b/packages/tab-indicator/src/mwc-tab-indicator-base.ts @@ -36,7 +36,7 @@ export class TabIndicatorBase extends BaseElement { @property({type: Boolean}) fade = false; - render() { + protected render() { const contentClasses = { 'mdc-tab-indicator__content--icon': this.icon, 'material-icons': this.icon, @@ -52,13 +52,13 @@ export class TabIndicatorBase extends BaseElement { `; } - updated(changedProperties: PropertyValues) { + protected updated(changedProperties: PropertyValues) { if (changedProperties.has('fade')) { this.createFoundation(); } } - createAdapter(): MDCTabIndicatorAdapter { + protected createAdapter(): MDCTabIndicatorAdapter { return { ...addHasRemoveClass(this.mdcRoot), computeContentClientRect: () => diff --git a/packages/tab-scroller/src/mwc-tab-scroller-base.ts b/packages/tab-scroller/src/mwc-tab-scroller-base.ts index bc246efb7..d2be706d4 100644 --- a/packages/tab-scroller/src/mwc-tab-scroller-base.ts +++ b/packages/tab-scroller/src/mwc-tab-scroller-base.ts @@ -32,7 +32,7 @@ export class TabScrollerBase extends BaseElement { @query('.mdc-tab-scroller__scroll-content') protected scrollContentElement!: HTMLElement; - @eventOptions({passive: true} as EventListenerOptions) + @eventOptions({passive: true}) private _handleInteraction() { this.mdcFoundation.handleInteraction(); } @@ -43,7 +43,7 @@ export class TabScrollerBase extends BaseElement { private _scrollbarHeight = -1; - render() { + protected render() { return html`
diff --git a/packages/tab/src/mwc-tab-base.ts b/packages/tab/src/mwc-tab-base.ts index be2970b66..2aad64953 100644 --- a/packages/tab/src/mwc-tab-base.ts +++ b/packages/tab/src/mwc-tab-base.ts @@ -66,7 +66,7 @@ export class TabBase extends BaseElement { this.mdcFoundation.handleClick(); } - createRenderRoot() { + protected createRenderRoot() { return this.attachShadow({mode: 'open', delegatesFocus: true}); } @@ -77,13 +77,13 @@ export class TabBase extends BaseElement { static styles = style; - firstUpdated() { + protected firstUpdated() { super.firstUpdated(); // create an unique id this.id = this.id || `mdc-tab-${++tabIdCounter}`; } - render() { + protected render() { const classes = { 'mdc-tab--min-width': this.minWidth, 'mdc-tab--stacked': this.stacked, @@ -115,14 +115,14 @@ export class TabBase extends BaseElement { `; } - renderIndicator() { + protected renderIndicator() { return html``; } - createAdapter(): MDCTabAdapter { + protected createAdapter(): MDCTabAdapter { return { ...addHasRemoveClass(this.mdcRoot), setAttr: (attr: string, value: string) => diff --git a/packages/top-app-bar/src/mwc-top-app-bar-base.ts b/packages/top-app-bar/src/mwc-top-app-bar-base.ts index c5e1e8ef2..d67f69db3 100644 --- a/packages/top-app-bar/src/mwc-top-app-bar-base.ts +++ b/packages/top-app-bar/src/mwc-top-app-bar-base.ts @@ -65,7 +65,7 @@ export class TopAppBarBase extends BaseElement { // TODO(sorvell): MDC decorates the navigation icon and action items with // ripples. Since these are slotted items here, the assumption is that the // user brings a web component with a ripple if rippling is desired. - render() { + protected render() { const classes = { 'mdc-top-app-bar--fixed': this.type === 'fixed' || this.type === 'prominentFixed', @@ -123,10 +123,10 @@ export class TopAppBarBase extends BaseElement { // override that prevents `super.firstUpdated` since we are controlling when // `createFoundation` is called. - firstUpdated() { + protected firstUpdated() { } - updated(changedProperties: PropertyValues) { + protected updated(changedProperties: PropertyValues) { // update foundation if `type` or `scrollTarget` changes if (changedProperties.has('type') || changedProperties.has('scrollTarget')) { @@ -163,7 +163,7 @@ export class TopAppBarBase extends BaseElement { } } - createFoundation() { + protected createFoundation() { super.createFoundation(); const windowScroller = this.scrollTarget === window; // we add support for top-app-bar's tied to an element scroller. diff --git a/test/benchmark/helpers.ts b/test/benchmark/helpers.ts index 944c17d9f..f61d76ac7 100644 --- a/test/benchmark/helpers.ts +++ b/test/benchmark/helpers.ts @@ -71,7 +71,7 @@ export class TestFixture extends LitElement { } } - render() { + protected render() { return html` ${this.shouldAttachContents ? this.template : ''} `;