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 19 commits
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
3 changes: 1 addition & 2 deletions packages/mdc-base/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ class MDCComponent<FoundationType extends MDCFoundation> {
}

/**
* Fires a cross-browser-compatible custom event from the component root of the given type,
* with the given data.
* Fires a cross-browser-compatible custom event from the component root of the given type, with the given data.
*/
emit<T extends object>(evtType: string, evtData: T, shouldBubble = false) {
let evt: CustomEvent<T>;
Expand Down
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;
const element = this.listElements[index] as HTMLElement | undefined;
if (element) {
element.focus();
}
Expand Down
3 changes: 3 additions & 0 deletions packages/mdc-menu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import {MDCList} from '@material/list/index';
import {MDCMenuSurface} from '@material/menu-surface/index';

export type MenuItemEvent = CustomEvent<MenuItemEventDetail>;
export type DefaultMenuItemEvent = CustomEvent<DefaultMenuItemEventDetail>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess I overlooked this in the original Menu PR but I found the Default here confusing. Unsure whether #4407 could leave room for resolving this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had a hard time figuring out what to call this type, so I'm definitely open to suggestions.

  • MenuItemEvent is only used by foundation and adapter
  • DefaultMenuItemEvent is only used by the component, and has an additional property on its detail object

What would you prefer to call it?


/**
* Event properties used by the adapter and foundation.
*/
Expand Down
18 changes: 9 additions & 9 deletions packages/mdc-select/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,14 @@ The `MDCSelect` component API is modeled after a subset of the `HTMLSelectElemen

| Property | Type | Description |
| --- | --- | --- |
| `value` | string | The `value`/`data-value` of the currently selected option. |
| `selectedIndex` | number | The index of the currently selected option. Set to -1 if no option is currently selected. Changing this property will update the select element. |
| `disabled` | boolean | Whether or not the component is disabled. Setting this sets the disabled state on the component. |
| `valid` | boolean | Whether or not the component is in a valid state. Setting this updates styles on the component, but does not affect the native validity state. |
| `required` | boolean | Whether or not the component is required. Setting this updates the `required` or `aria-required` attribute on the component and enables validation. |
| `leadingIconAriaLabel` | string (write-only) | Proxies to the foundation's `setLeadingIconAriaLabel` method. |
| `leadingIconContent` | string (write-only) | Proxies to the foundation's `setLeadingIconContent` method. |
| `helperTextContent` | string (write-only)| Proxies to the foundation's `setHelperTextContent` method when set. |
| `value` | `string` | The `value`/`data-value` of the currently selected option. |
| `selectedIndex` | `number` | The index of the currently selected option. Set to -1 if no option is currently selected. Changing this property will update the select element. |
| `disabled` | `boolean` | Whether or not the component is disabled. Setting this sets the disabled state on the component. |
| `valid` | `boolean` | Whether or not the component is in a valid state. Setting this updates styles on the component, but does not affect the native validity state. |
| `required` | `boolean` | Whether or not the component is required. Setting this updates the `required` or `aria-required` attribute on the component and enables validation. |
| `leadingIconAriaLabel` | `string` (write-only) | Proxies to the foundation's `setLeadingIconAriaLabel` method. |
| `leadingIconContent` | `string` (write-only) | Proxies to the foundation's `setLeadingIconContent` method. |
| `helperTextContent` | `string` (write-only)| Proxies to the foundation's `setHelperTextContent` method when set. |

### Events

Expand Down Expand Up @@ -462,7 +462,7 @@ If you are using a JavaScript framework, such as React or Angular, you can creat
| `handleBlur() => void` | Handles a blur event on the `select` element. |
| `handleClick(normalizedX: number) => void` | Sets the line ripple center to the normalizedX for the line ripple. |
| `handleChange() => void` | Handles a change to the `select` element's value. This must be called both for `change` events and programmatic changes requested via the component API. |
| `handleKeydown(event: Event) => void` | Handles opening the menu (enhanced select) when the `mdc-select__selected-text` element is focused and the user presses the `Enter` or `Space` key. |
| `handleKeydown(event: KeyboardEvent) => void` | Handles opening the menu (enhanced select) when the `mdc-select__selected-text` element is focused and the user presses the `Enter` or `Space` key. |
| `setSelectedIndex(index: number) => void` | Handles setting the `mdc-select__selected-text` element and closing the menu (enhanced select only). Also causes the label to float and outline to notch if needed. |
| `setValue(value: string) => void` | Handles setting the value through the adapter and causes the label to float and outline to notch if needed. |
| `getValue() => string` | Handles getting the value through the adapter. |
Expand Down
89 changes: 24 additions & 65 deletions packages/mdc-select/adapter.js → packages/mdc-select/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,159 +21,118 @@
* THE SOFTWARE.
*/

/* eslint no-unused-vars: [2, {"args": "none"}] */
/* eslint-disable no-unused-vars */
import {MDCSelectIconFoundation} from './icon/index';
import {MDCSelectHelperTextFoundation} from './helper-text/index';
/* eslint-enable no-unused-vars */

/**
* @typedef {{
* leadingIcon: (!MDCSelectIconFoundation|undefined),
* helperText: (!MDCSelectHelperTextFoundation|undefined),
* }}
*/
let FoundationMapType;

/**
* Adapter for MDC Select. Provides an interface for managing
* - classes
* - dom
* - event handlers
*
* Additionally, provides type information for the adapter to the Closure
* compiler.
*
* 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
*
* @record
*/

class MDCSelectAdapter {
interface MDCSelectAdapter {
/**
* Adds class to 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 name.
* @param {string} className
* @return {boolean}
*/
hasClass(className) {}
hasClass(className: string): boolean;

/**
* Activates the bottom line, showing a focused state.
*/
activateBottomLine() {}
activateBottomLine(): void;

/**
* Deactivates the bottom line.
*/
deactivateBottomLine() {}
deactivateBottomLine(): void;

/**
* Sets the value of the select.
* @param {string} value
*/
setValue(value) {}
setValue(value: string): void;

/**
* Returns the selected value of the select element.
* @return {string}
*/
getValue() {}
getValue(): string;

/**
* Floats label determined based off of the shouldFloat argument.
* @param {boolean} shouldFloat
*/
floatLabel(shouldFloat) {}
floatLabel(shouldFloat: boolean): void;

/**
* Returns width of label in pixels, if the label exists.
* @return {number}
*/
getLabelWidth() {}
getLabelWidth(): number;

/**
* Returns true if outline element exists, false if it doesn't.
* @return {boolean}
*/
hasOutline() {}
hasOutline(): boolean;

/**
* Only implement if outline element exists.
* @param {number} labelWidth
*/
notchOutline(labelWidth) {}
notchOutline(labelWidth: number): void;

/**
* Closes notch in outline element, if the outline exists.
*/
closeOutline() {}
closeOutline(): void;

/**
* Opens the menu.
*/
openMenu() {}
openMenu(): void;

/**
* Closes the menu.
*/
closeMenu() {}
closeMenu(): void;

/**
* Returns true if the menu is currently open.
* @return {boolean}
*/
isMenuOpen() {}
isMenuOpen(): boolean;

/**
* Sets the selected index of the select to the index provided.
* @param {number} index
*/
setSelectedIndex(index) {}
setSelectedIndex(index: number): void;

/**
* Sets the select to disabled.
* @param {boolean} isDisabled
*/
setDisabled(isDisabled) {}
setDisabled(isDisabled: boolean): void;

/**
* Sets the line ripple transform origin center.
* @param {number} normalizedX
*/
setRippleCenter(normalizedX) {}
setRippleCenter(normalizedX: number): void;

/**
* Emits a change event when an element is selected.
* @param {string} value
*/
notifyChange(value) {}
notifyChange(value: string): void;

/**
* Checks if the select is currently valid.
* @return {boolean} isValid
*/
checkValidity() {}
checkValidity(): boolean;

/**
* Adds/Removes the invalid class.
* @param {boolean} isValid
*/
setValid(isValid) {}
setValid(isValid: boolean): void;
}

export {MDCSelectAdapter, FoundationMapType};
export {MDCSelectAdapter as default, MDCSelectAdapter};
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,33 @@
* THE SOFTWARE.
*/

/** @enum {string} */
const cssClasses = {
DISABLED: 'mdc-select--disabled',
ROOT: 'mdc-select',
OUTLINED: 'mdc-select--outlined',
FOCUSED: 'mdc-select--focused',
SELECTED_ITEM_CLASS: 'mdc-list-item--selected',
WITH_LEADING_ICON: 'mdc-select--with-leading-icon',
INVALID: 'mdc-select--invalid',
OUTLINED: 'mdc-select--outlined',
REQUIRED: 'mdc-select--required',
ROOT: 'mdc-select',
SELECTED_ITEM_CLASS: 'mdc-list-item--selected',
WITH_LEADING_ICON: 'mdc-select--with-leading-icon',
};

/** @enum {string} */
const strings = {
ARIA_CONTROLS: 'aria-controls',
ARIA_SELECTED_ATTR: 'aria-selected',
CHANGE_EVENT: 'MDCSelect:change',
SELECTED_ITEM_SELECTOR: `.${cssClasses.SELECTED_ITEM_CLASS}`,
LEADING_ICON_SELECTOR: '.mdc-select__icon',
SELECTED_TEXT_SELECTOR: '.mdc-select__selected-text',
ENHANCED_VALUE_ATTR: 'data-value',
HIDDEN_INPUT_SELECTOR: 'input[type="hidden"]',
MENU_SELECTOR: '.mdc-select__menu',
LINE_RIPPLE_SELECTOR: '.mdc-line-ripple',
LABEL_SELECTOR: '.mdc-floating-label',
LEADING_ICON_SELECTOR: '.mdc-select__icon',
LINE_RIPPLE_SELECTOR: '.mdc-line-ripple',
MENU_SELECTOR: '.mdc-select__menu',
NATIVE_CONTROL_SELECTOR: '.mdc-select__native-control',
OUTLINE_SELECTOR: '.mdc-notched-outline',
ENHANCED_VALUE_ATTR: 'data-value',
ARIA_SELECTED_ATTR: 'aria-selected',
SELECTED_ITEM_SELECTOR: `.${cssClasses.SELECTED_ITEM_CLASS}`,
SELECTED_TEXT_SELECTOR: '.mdc-select__selected-text',
};

/** @enum {number} */
const numbers = {
LABEL_SCALE: 0.75,
};
Expand Down
Loading