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(select): Convert JS to TypeScript #4386

Merged
merged 20 commits into from
Feb 13, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9313e66
feat(select): Convert JS to TypeScript
acdvorak Feb 9, 2019
135e09d
WIP: Add comment
acdvorak Feb 9, 2019
bc8bf0d
WIP: Fix compiler errors
acdvorak Feb 9, 2019
fb0b996
WIP: Make Istanbul happy
acdvorak Feb 9, 2019
7a7d960
Merge branch 'feat/typescript--select' of github.com:material-compone…
acdvorak Feb 9, 2019
91f5975
WIP: Change `MDCList.listElements` from `HTMLElement[]` back to `Elem…
acdvorak Feb 11, 2019
b50a47a
WIP: `extends CustomEvent<MenuItemEventDetail>`
acdvorak Feb 11, 2019
01edf0f
WIP: Remove Closure annotations
acdvorak Feb 11, 2019
a286663
WIP: Initialize `savedTabIndex_` inline
acdvorak Feb 11, 2019
5facf07
WIP: Remove unnecessary `@material/textfield` dependency from `packag…
acdvorak Feb 11, 2019
7b625f6
Merge remote-tracking branch 'origin/feat/typescript' into feat/types…
acdvorak Feb 11, 2019
f6de964
Merge remote-tracking branch 'origin/feat/typescript' into feat/types…
acdvorak Feb 11, 2019
4fa0e79
WIP: Update filename to `.ts` in `js-bundle-factory.js`
acdvorak Feb 11, 2019
dc34eb6
Merge remote-tracking branch 'origin/feat/typescript' into feat/types…
acdvorak Feb 12, 2019
de38dd6
WIP: Revert argument rename in `MDCComponent.emit()`
acdvorak Feb 12, 2019
01b22be
WIP: Address review comments
acdvorak Feb 12, 2019
ebbbbb9
WIP: Re-indent
acdvorak Feb 12, 2019
a236050
WIP: Address review comments
acdvorak Feb 12, 2019
1e8b7e2
WIP: Throw an error if required subelements are missing
acdvorak Feb 12, 2019
a0cce8c
WIP: Fix `TouchEvent` `clientX` bug
acdvorak Feb 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/mdc-list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class MDCList extends MDCComponent<MDCListFoundation> {
}
},
focusItemAtIndex: (index) => {
const element = this.listElements[index] as HTMLElement | null;
const element = this.listElements[index] as HTMLElement | undefined;
if (element) {
element.focus();
}
Expand Down
4 changes: 2 additions & 2 deletions packages/mdc-select/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import {MDCFoundation} from '@material/base/foundation';
import {MDCSelectAdapter} from './adapter';
import {cssClasses, numbers, strings} from './constants';
import {MDCSelectHelperTextFoundation} from './helper-text/index';
import {MDCSelectIconFoundation} from './icon/index';
import {MDCSelectHelperTextFoundation} from './helper-text/foundation';
import {MDCSelectIconFoundation} from './icon/foundation';
import {FoundationMapType} from './types';

class MDCSelectFoundation extends MDCFoundation<MDCSelectAdapter> {
Expand Down
2 changes: 1 addition & 1 deletion packages/mdc-select/helper-text/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class MDCSelectHelperText extends MDCComponent<MDCSelectHelperTextFoundation> {
hasClass: (className) => this.root_.classList.contains(className),
setAttr: (attr, value) => this.root_.setAttribute(attr, value),
removeAttr: (attr) => this.root_.removeAttribute(attr),
setContent: (content) => this.root_.textContent = content,
setContent: (content) => { this.root_.textContent = content; },
});
// tslint:enable:object-literal-sort-keys
}
Expand Down
4 changes: 2 additions & 2 deletions packages/mdc-select/icon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ Method Signature | Description
`setAttr(attr: string, value: string) => void` | Sets an attribute with a given value on the icon element.
`removeAttr(attr: string) => void` | Removes an attribute from the icon element.
`setContent(content: string) => void` | Sets the text content of the icon element.
`registerInteractionHandler(evtType: EventType, handler: EventListener) => void` | Registers an event listener for a given event.
`deregisterInteractionHandler(evtType: EventType, handler: EventListener) => void` | Deregisters an event listener for a given event.
`registerInteractionHandler(evtType: string, handler: EventListener) => void` | Registers an event listener for a given event.
`deregisterInteractionHandler(evtType: string, handler: EventListener) => void` | Deregisters an event listener for a given event.
`notifyIconAction() => void` | Emits a custom event "MDCSelect:icon" denoting a user has clicked the icon, which bubbles to the top-level select element.

### `MDCSelectIconFoundation`
Expand Down
16 changes: 10 additions & 6 deletions packages/mdc-select/icon/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
*/

import {MDCFoundation} from '@material/base/foundation';
import {EventType} from '@material/base/index';
import {SpecificEventListener} from '@material/base/types';
import {MDCSelectIconAdapter} from './adapter';
import {strings} from './constants';

const CLICK_KEYDOWN_EVENTS: EventType[] = ['click', 'keydown'];
type InteractionEventType = 'click' | 'keydown';

const INTERACTION_EVENTS: InteractionEventType[] = ['click', 'keydown'];

class MDCSelectIconFoundation extends MDCFoundation<MDCSelectIconAdapter> {
static get strings() {
Expand All @@ -51,7 +53,9 @@ class MDCSelectIconFoundation extends MDCFoundation<MDCSelectIconAdapter> {
}

private savedTabIndex_: string | null = null;
private readonly interactionHandler_!: EventListener; // assigned in initialSyncWithDOM()

// assigned in initialSyncWithDOM()
private readonly interactionHandler_!: SpecificEventListener<InteractionEventType>;

constructor(adapter?: Partial<MDCSelectIconAdapter>) {
super({...MDCSelectIconFoundation.defaultAdapter, ...adapter});
Expand All @@ -62,13 +66,13 @@ class MDCSelectIconFoundation extends MDCFoundation<MDCSelectIconAdapter> {
init() {
this.savedTabIndex_ = this.adapter_.getAttr('tabindex');

CLICK_KEYDOWN_EVENTS.forEach((evtType) => {
INTERACTION_EVENTS.forEach((evtType) => {
this.adapter_.registerInteractionHandler(evtType, this.interactionHandler_);
});
}

destroy() {
CLICK_KEYDOWN_EVENTS.forEach((evtType) => {
INTERACTION_EVENTS.forEach((evtType) => {
this.adapter_.deregisterInteractionHandler(evtType, this.interactionHandler_);
});
}
Expand All @@ -95,7 +99,7 @@ class MDCSelectIconFoundation extends MDCFoundation<MDCSelectIconAdapter> {
this.adapter_.setContent(content);
}

handleInteraction(evt: Event) {
handleInteraction(evt: MouseEvent | KeyboardEvent) {
const isEnterKey = (evt as KeyboardEvent).key === 'Enter' || (evt as KeyboardEvent).keyCode === 13;
if (evt.type === 'click' || isEnterKey) {
this.adapter_.notifyIconAction();
Expand Down
2 changes: 1 addition & 1 deletion packages/mdc-select/icon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MDCSelectIcon extends MDCComponent<MDCSelectIconFoundation> {
getAttr: (attr) => this.root_.getAttribute(attr),
setAttr: (attr, value) => this.root_.setAttribute(attr, value),
removeAttr: (attr) => this.root_.removeAttribute(attr),
setContent: (content) => this.root_.textContent = content,
setContent: (content) => { this.root_.textContent = content; },
registerInteractionHandler: (evtType, handler) => this.root_.addEventListener(evtType, handler),
deregisterInteractionHandler: (evtType, handler) => this.root_.removeEventListener(evtType, handler),
notifyIconAction: () => this.emit(
Expand Down
208 changes: 104 additions & 104 deletions packages/mdc-select/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class MDCSelect extends MDCComponent<MDCSelectFoundation> implements RippleCapab
private selectedText_!: HTMLElement | null;

private hiddenInput_!: HTMLInputElement | null;
private leadingIcon_!: MDCSelectIcon | null;
private leadingIcon_?: MDCSelectIcon;
private helperText_!: MDCSelectHelperText | null;
private menuElement_!: Element | null;
private ripple!: MDCRipple | null;
Expand All @@ -78,103 +78,6 @@ class MDCSelect extends MDCComponent<MDCSelectFoundation> implements RippleCapab
private handleMenuSelected_!: CustomEventListener<MenuItemEvent>; // assigned in initialize()
private validationObserver_!: MutationObserver; // assigned in initialize()

get value(): string {
return this.foundation_.getValue();
}

set value(value: string) {
this.foundation_.setValue(value);
}

get selectedIndex(): number {
let selectedIndex = -1;
if (this.menuElement_ && this.menu_) {
const selectedEl = this.menuElement_.querySelector(strings.SELECTED_ITEM_SELECTOR)!;
selectedIndex = this.menu_.items.indexOf(selectedEl);
} else if (this.nativeControl_) {
selectedIndex = this.nativeControl_.selectedIndex;
}
return selectedIndex;
}

set selectedIndex(selectedIndex: number) {
this.foundation_.setSelectedIndex(selectedIndex);
}

get disabled(): boolean {
return this.root_.classList.contains(cssClasses.DISABLED) ||
(this.nativeControl_ ? this.nativeControl_.disabled : false);
}

set disabled(disabled: boolean) {
this.foundation_.setDisabled(disabled);
}

set leadingIconAriaLabel(label: string) {
this.foundation_.setLeadingIconAriaLabel(label);
}

/**
* Sets the text content of the leading icon.
*/
set leadingIconContent(content: string) {
this.foundation_.setLeadingIconContent(content);
}

/**
* Sets the text content of the helper text.
*/
set helperTextContent(content: string) {
this.foundation_.setHelperTextContent(content);
}

/**
* Sets the current invalid state of the select.
*/
set valid(isValid: boolean) {
this.foundation_.setValid(isValid);
}

/**
* Checks if the select is in a valid state.
*/
get valid(): boolean {
return this.foundation_.isValid();
}

/**
* Sets the control to the required state.
*/
set required(isRequired: boolean) {
if (this.nativeControl_) {
this.nativeControl_.required = isRequired;
} else {
if (isRequired) {
this.selectedText_!.setAttribute('aria-required', isRequired.toString());
} else {
this.selectedText_!.removeAttribute('aria-required');
}
}
}

/**
* Returns whether the select is required.
*/
get required(): boolean {
if (this.nativeControl_) {
return this.nativeControl_.required;
} else {
return this.selectedText_!.getAttribute('aria-required') === 'true';
}
}

/**
* Recomputes the outline SVG path for the outline element.
*/
layout() {
this.foundation_.layout();
}

initialize(
labelFactory: LabelFactory = (el) => new MDCFloatingLabel(el),
lineRippleFactory: LineRippleFactory = (el) => new MDCLineRipple(el),
Expand Down Expand Up @@ -336,14 +239,111 @@ class MDCSelect extends MDCComponent<MDCSelectFoundation> implements RippleCapab
super.destroy();
}

get value(): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

wow I wish Github would just move the initialize method lol

return this.foundation_.getValue();
}

set value(value: string) {
this.foundation_.setValue(value);
}

get selectedIndex(): number {
let selectedIndex = -1;
if (this.menuElement_ && this.menu_) {
const selectedEl = this.menuElement_.querySelector(strings.SELECTED_ITEM_SELECTOR)!;
selectedIndex = this.menu_.items.indexOf(selectedEl);
} else if (this.nativeControl_) {
selectedIndex = this.nativeControl_.selectedIndex;
}
return selectedIndex;
}

set selectedIndex(selectedIndex: number) {
this.foundation_.setSelectedIndex(selectedIndex);
}

get disabled(): boolean {
return this.root_.classList.contains(cssClasses.DISABLED) ||
(this.nativeControl_ ? this.nativeControl_.disabled : false);
}

set disabled(disabled: boolean) {
this.foundation_.setDisabled(disabled);
}

set leadingIconAriaLabel(label: string) {
this.foundation_.setLeadingIconAriaLabel(label);
}

/**
* Sets the text content of the leading icon.
*/
set leadingIconContent(content: string) {
this.foundation_.setLeadingIconContent(content);
}

/**
* Sets the text content of the helper text.
*/
set helperTextContent(content: string) {
this.foundation_.setHelperTextContent(content);
}

/**
* Sets the current invalid state of the select.
*/
set valid(isValid: boolean) {
this.foundation_.setValid(isValid);
}

/**
* Checks if the select is in a valid state.
*/
get valid(): boolean {
return this.foundation_.isValid();
}

/**
* Sets the control to the required state.
*/
set required(isRequired: boolean) {
if (this.nativeControl_) {
this.nativeControl_.required = isRequired;
} else {
if (isRequired) {
this.selectedText_!.setAttribute('aria-required', isRequired.toString());
} else {
this.selectedText_!.removeAttribute('aria-required');
}
}
}

/**
* Returns whether the select is required.
*/
get required(): boolean {
if (this.nativeControl_) {
return this.nativeControl_.required;
} else {
return this.selectedText_!.getAttribute('aria-required') === 'true';
}
}

/**
* Recomputes the outline SVG path for the outline element.
*/
layout() {
this.foundation_.layout();
}

getDefaultFoundation(): MDCSelectFoundation {
return new MDCSelectFoundation({
...(this.nativeControl_ ? this.getNativeSelectAdapterMethods_() : this.getEnhancedSelectAdapterMethods_()),
...this.getCommonAdapterMethods_(),
...this.getOutlineAdapterMethods_(),
...this.getLabelAdapterMethods_(),
},
this.getFoundationMap_(),
...(this.nativeControl_ ? this.getNativeSelectAdapterMethods_() : this.getEnhancedSelectAdapterMethods_()),
...this.getCommonAdapterMethods_(),
...this.getOutlineAdapterMethods_(),
...this.getLabelAdapterMethods_(),
},
this.getFoundationMap_(),
);
}

Expand Down