Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(top-app-bar): Convert JS to TypeScript #4397

Merged
merged 11 commits into from
Feb 14, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -21,87 +21,65 @@
* THE SOFTWARE.
*/

/* eslint no-unused-vars: [2, {"args": "none"}] */

/**
* Adapter for MDC Top App Bar
*
* Defines the shape of the adapter expected by the foundation. Implement this
* adapter to integrate the Top App Bar into your framework. See
* https://github.com/material-components/material-components-web/blob/master/docs/authoring-components.md
* for more information.
*
* @record
* Defines the shape of the adapter expected by the foundation.
* Implement this adapter for your framework of choice to delegate updates to
* the component in your framework of choice. See architecture documentation
* for more details.
* https://github.com/material-components/material-components-web/blob/master/docs/code/architecture.md
*/
class MDCTopAppBarAdapter {
interface MDCTopAppBarAdapter {
/**
* Adds a class to the root Element.
* @param {string} className
*/
addClass(className) {}
addClass(className: string): void;

/**
* Removes a class from the root Element.
* @param {string} className
*/
removeClass(className) {}
removeClass(className: string): void;

/**
* Returns true if the root Element contains the given class.
* @param {string} className
* @return {boolean}
*/
hasClass(className) {}
hasClass(className: string): boolean;

/**
* Sets the specified inline style property on the root Element to the given value.
* @param {string} property
* @param {string} value
*/
setStyle(property, value) {}
setStyle(property: string, value: string): void;

/**
* Gets the height of the top app bar.
* @return {number}
*/
getTopAppBarHeight() {}
getTopAppBarHeight(): number;

/**
* Registers an event handler on the navigation icon element for a given event.
* @param {string} type
* @param {function(!Event): undefined} handler
*/
registerNavigationIconInteractionHandler(type, handler) {}
registerNavigationIconInteractionHandler(type: string, handler: EventListener): void;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved

/**
* Deregisters an event handler on the navigation icon element for a given event.
* @param {string} type
* @param {function(!Event): undefined} handler
*/
deregisterNavigationIconInteractionHandler(type, handler) {}
deregisterNavigationIconInteractionHandler(type: string, handler: EventListener): void;

/**
* Emits an event when the navigation icon is clicked.
*/
notifyNavigationIconClicked() {}
notifyNavigationIconClicked(): void;

/** @param {function(!Event)} handler */
registerScrollHandler(handler) {}
registerScrollHandler(handler: EventListener): void;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved

/** @param {function(!Event)} handler */
deregisterScrollHandler(handler) {}
deregisterScrollHandler(handler: EventListener): void;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved

/** @param {function(!Event)} handler */
registerResizeHandler(handler) {}
registerResizeHandler(handler: EventListener): void;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved

/** @param {function(!Event)} handler */
deregisterResizeHandler(handler) {}
deregisterResizeHandler(handler: EventListener): void;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved

/** @return {number} */
getViewportScrollY() {}
getViewportScrollY(): number;

/** @return {number} */
getTotalActionItems() {}
getTotalActionItems(): number;
}

export default MDCTopAppBarAdapter;
export {MDCTopAppBarAdapter as default, MDCTopAppBarAdapter};
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,19 @@
* THE SOFTWARE.
*/

/** @enum {string} */
const cssClasses = {
FIXED_CLASS: 'mdc-top-app-bar--fixed',
FIXED_SCROLLED_CLASS: 'mdc-top-app-bar--fixed-scrolled',
SHORT_CLASS: 'mdc-top-app-bar--short',
SHORT_HAS_ACTION_ITEM_CLASS: 'mdc-top-app-bar--short-has-action-item',
SHORT_COLLAPSED_CLASS: 'mdc-top-app-bar--short-collapsed',
SHORT_HAS_ACTION_ITEM_CLASS: 'mdc-top-app-bar--short-has-action-item',
};

/** @enum {number} */
const numbers = {
DEBOUNCE_THROTTLE_RESIZE_TIME_MS: 100,
MAX_TOP_APP_BAR_HEIGHT: 128,
};

/** @enum {string} */
const strings = {
ACTION_ITEM_SELECTOR: '.mdc-top-app-bar__action-item',
NAVIGATION_EVENT: 'MDCTopAppBar:nav',
Expand All @@ -45,4 +42,4 @@ const strings = {
TITLE_SELECTOR: '.mdc-top-app-bar__title',
};

export {strings, cssClasses, numbers};
export {cssClasses, numbers, strings};
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,33 @@
* THE SOFTWARE.
*/

import {MDCTopAppBarAdapter} from '../adapter';
import {cssClasses} from '../constants';
import MDCTopAppBarAdapter from '../adapter';
import MDCTopAppBarFoundation from '../foundation';
import {MDCTopAppBarFoundation} from '../standard/foundation';

/**
* @extends {MDCTopAppBarFoundation<!MDCFixedTopAppBarFoundation>}
* @final
*/
class MDCFixedTopAppBarFoundation extends MDCTopAppBarFoundation {
/**
* @param {!MDCTopAppBarAdapter} adapter
* State variable for the previous scroll iteration top app bar state
*/
constructor(adapter) {
private wasScrolled_ = false;

/* istanbul ignore next */
acdvorak marked this conversation as resolved.
Show resolved Hide resolved
constructor(adapter?: Partial<MDCTopAppBarAdapter>) {
super(adapter);
/** State variable for the previous scroll iteration top app bar state */
this.wasScrolled_ = false;

this.scrollHandler_ = () => this.fixedScrollHandler_();
}

init() {
acdvorak marked this conversation as resolved.
Show resolved Hide resolved
super.init();
this.adapter_.registerScrollHandler(this.scrollHandler_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you decide to remove this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's redundant; it already happens in MDCTopAppBarBaseFoundation.

The duplication was actually causing unit tests to fail until I removed this.

}

destroy() {
super.destroy();
this.adapter_.deregisterScrollHandler(this.scrollHandler_);
}

/**
* Scroll handler for applying/removing the modifier class
* on the fixed top app bar.
* Scroll handler for applying/removing the modifier class on the fixed top app bar.
*/
fixedScrollHandler_() {
const currentScroll = this.adapter_.getViewportScrollY();
Expand All @@ -72,4 +66,4 @@ class MDCFixedTopAppBarFoundation extends MDCTopAppBarFoundation {
}
}

export default MDCFixedTopAppBarFoundation;
export {MDCFixedTopAppBarFoundation as default, MDCFixedTopAppBarFoundation};
99 changes: 0 additions & 99 deletions packages/mdc-top-app-bar/foundation.js

This file was deleted.

98 changes: 98 additions & 0 deletions packages/mdc-top-app-bar/foundation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* @license
* Copyright 2018 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

import {MDCFoundation} from '@material/base/foundation';
import {MDCTopAppBarAdapter} from './adapter';
import {cssClasses, numbers, strings} from './constants';

class MDCTopAppBarBaseFoundation extends MDCFoundation<MDCTopAppBarAdapter> {
static get strings() {
return strings;
}

static get cssClasses() {
return cssClasses;
}

static get numbers() {
/* istanbul ignore next */
return numbers;
}

/**
* See {@link MDCTopAppBarAdapter} for typing information on parameters and return types.
*/
static get defaultAdapter(): MDCTopAppBarAdapter {
// tslint:disable:object-literal-sort-keys
return {
addClass: () => undefined,
removeClass: () => undefined,
hasClass: () => false,
setStyle: () => undefined,
getTopAppBarHeight: () => 0,
registerNavigationIconInteractionHandler: () => undefined,
deregisterNavigationIconInteractionHandler: () => undefined,
notifyNavigationIconClicked: () => undefined,
registerScrollHandler: () => undefined,
deregisterScrollHandler: () => undefined,
registerResizeHandler: () => undefined,
deregisterResizeHandler: () => undefined,
getViewportScrollY: () => 0,
getTotalActionItems: () => 0,
};
// tslint:enable:object-literal-sort-keys
}

protected scrollHandler_?: EventListener;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved
protected resizeHandler_?: EventListener;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved
private readonly navClickHandler_: EventListener;
acdvorak marked this conversation as resolved.
Show resolved Hide resolved

/* istanbul ignore next */
constructor(adapter?: Partial<MDCTopAppBarAdapter>) {
super({...MDCTopAppBarBaseFoundation.defaultAdapter, ...adapter});

this.navClickHandler_ = () => this.adapter_.notifyNavigationIconClicked();
}

init() {
if (this.scrollHandler_) {
this.adapter_.registerScrollHandler(this.scrollHandler_);
}
if (this.resizeHandler_) {
this.adapter_.registerResizeHandler(this.resizeHandler_);
}
this.adapter_.registerNavigationIconInteractionHandler('click', this.navClickHandler_);
}

destroy() {
if (this.scrollHandler_) {
this.adapter_.deregisterScrollHandler(this.scrollHandler_);
}
if (this.resizeHandler_) {
this.adapter_.deregisterResizeHandler(this.resizeHandler_);
}
this.adapter_.deregisterNavigationIconInteractionHandler('click', this.navClickHandler_);
}
}

export {MDCTopAppBarBaseFoundation as default, MDCTopAppBarBaseFoundation};
Loading