Skip to content

Commit

Permalink
feat(menu-surface): Convert JS to TypeScript (#4273)
Browse files Browse the repository at this point in the history
Refs #4225
  • Loading branch information
acdvorak committed Feb 5, 2019
1 parent 869e44c commit a2ac8bc
Show file tree
Hide file tree
Showing 18 changed files with 1,042 additions and 1,035 deletions.
2 changes: 1 addition & 1 deletion packages/material-components-web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import * as linearProgress from '@material/linear-progress/index.ts';
import * as lineRipple from '@material/line-ripple/index';
import * as list from '@material/list/index';
import * as menu from '@material/menu/index';
import * as menuSurface from '@material/menu-surface/index';
import * as menuSurface from '@material/menu-surface/index.ts';
import * as notchedOutline from '@material/notched-outline/index';
import * as radio from '@material/radio/index';
import * as ripple from '@material/ripple/index.ts';
Expand Down
35 changes: 20 additions & 15 deletions packages/mdc-menu-surface/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,13 @@ Mixin | Description

Constant Name | Description
--- | ---
`Corner` | Enum for representing an element corner for positioning the menu-surface. See [constants.js](./constants.js).
`AnchorMargin` | Margin values representing the distance from anchor point that the menu surface should be shown. See [foundation.js](./foundation.js).
`Corner` | Enum for representing an element corner for positioning the menu-surface. See [constants.ts](constants.ts).

Type Name | Description
--- | ---
`MenuDimensions` | Width/height of an element. See [types.ts](types.ts).
`MenuDistance` | Margin values representing the distance from anchor point that the menu surface should be shown. See [types.ts](types.ts).
`MenuPoint` | X/Y coordinates. See [types.ts](types.ts).

## `MDCMenuSurface` Properties and Methods

Expand All @@ -165,7 +170,7 @@ Property | Value Type | Description
Method Signature | Description
--- | ---
`setAnchorCorner(Corner) => void` | Proxies to the foundation's `setAnchorCorner(Corner)` method.
`setAnchorMargin(AnchorMargin) => void` | Proxies to the foundation's `setAnchorMargin(AnchorMargin)` method.
`setAnchorMargin(Partial<MenuDistance>) => void` | Proxies to the foundation's `setAnchorMargin(Partial<MenuDistance>)` method.
`setFixedPosition(isFixed: boolean) => void` | Adds the `mdc-menu-surface--fixed` class to the `mdc-menu-surface` element. Proxies to the foundation's `setIsHoisted()` and `setFixedPosition()` methods.
`setAbsolutePosition(x: number, y: number) => void` | Proxies to the foundation's `setAbsolutePosition(x, y)` method. Used to set the absolute x/y position of the menu on the page. Should only be used when the menu is hoisted to the body.
`setMenuSurfaceAnchorElement(element: Element) => void` | Changes the element used as an anchor for `menu-surface` positioning logic. Should be used with conjunction with `hoistMenuToBody()`.
Expand Down Expand Up @@ -194,7 +199,7 @@ Method Signature | Description
`hasAnchor: () => boolean` | Returns whether the menu surface has an anchor for positioning.
`notifyClose() => void` | Dispatches an event notifying listeners that the menu surface has been closed.
`notifyOpen() => void` | Dispatches an event notifying listeners that the menu surface has been opened.
`isElementInContainer(el: Element) => Boolean` | Returns true if the `el` Element is inside the `mdc-menu-surface` container.
`isElementInContainer(el: Element) => boolean` | Returns true if the `el` Element is inside the `mdc-menu-surface` container.
`isRtl() => boolean` | Returns boolean indicating whether the current environment is RTL.
`setTransformOrigin(value: string) => void` | Sets the transform origin for the menu surface element.
`isFocused() => boolean` | Returns a boolean value indicating whether the root element of the menu surface is focused.
Expand All @@ -204,25 +209,25 @@ Method Signature | Description
`isLastElementFocused() => boolean` | Returns a boolean value indicating if the last focusable element of the menu-surface is focused.
`focusFirstElement() => void` | Focuses the first focusable element of the menu-surface.
`focusLastElement() => void` | Focuses the last focusable element of the menu-surface.
`getInnerDimensions() => {width: number, height: number}` | Returns an object with the items container width and height.
`getAnchorDimensions() => {width: number, height: number, top: number, right: number, bottom: number, left: number}` | Returns an object with the dimensions and position of the anchor (same semantics as `DOMRect`).
`getBodyDimensions() => {width: number, height: number}` | Returns an object with width and height of the body, in pixels.
`getWindowDimensions() => {width: number, height: number}` | Returns an object with width and height of the viewport, in pixels.
`getWindowScroll() => {x: number, y: number}` | Returns an object with the amount the body has been scrolled on the `x` and `y` axis.
`setPosition(position: {top: string, right: string, bottom: string, left: string}) => void` | Sets the position of the menu surface element.
`getInnerDimensions() => MenuDimensions` | Returns an object with the items container width and height.
`getAnchorDimensions() => ClientRect \| null` | Returns an object with the dimensions and position of the anchor.
`getBodyDimensions() => MenuDimensions` | Returns an object with width and height of the body, in pixels.
`getWindowDimensions() => MenuDimensions` | Returns an object with width and height of the viewport, in pixels.
`getWindowScroll() => MenuPoint` | Returns an object with the amount the body has been scrolled on the `x` and `y` axis.
`setPosition(position: Partial<MenuDistance>) => void` | Sets the position of the menu surface element.
`setMaxHeight(value: string) => void` | Sets `max-height` style for the menu surface element.

### `MDCMenuSurfaceFoundation`

Method Signature | Description
--- | ---
`setAnchorCorner(corner: Corner) => void` | Sets the corner that the menu surface will be anchored to. See [constants.js](./constants.js)
`setAnchorMargin(margin: AnchorMargin) => void` | Sets the distance from the anchor point that the menu surface should be shown.
`setAnchorCorner(corner: Corner) => void` | Sets the corner that the menu surface will be anchored to. See [constants.ts](constants.ts)
`setAnchorMargin(margin: Partial<MenuDistance>) => void` | Sets the distance from the anchor point that the menu surface should be shown.
`setIsHoisted(isHoisted: boolean) => void` | Sets whether the menu surface has been hoisted to the body so that the offsets are calculated relative to the page and not the anchor.
`setFixedPosition(isFixed: boolean) => void` | Sets whether the menu surface is using fixed positioning.
`setAbsolutePosition(x: number, y: numnber) => void` | Sets the absolute x/y position of the menu. Should only be used when the menu is hoisted or using fixed positioning.
`handleBodyClick(event: Event) => void` | Method used as the callback function for the `click` event.
`handleKeydown(event: Event) => void` | Method used as the callback function for the `keydown` events.
`setAbsolutePosition(x: number, y: number) => void` | Sets the absolute x/y position of the menu. Should only be used when the menu is hoisted or using fixed positioning.
`handleBodyClick(event: MouseEvent) => void` | Method used as the callback function for the `click` event.
`handleKeydown(event: KeyboardEvent) => void` | Method used as the callback function for the `keydown` events.
`open() => void` | Opens the menu surface.
`close() => void` | Closes the menu.
`isOpen() => boolean` | Returns a boolean indicating whether the menu surface is open.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,107 +21,52 @@
* THE SOFTWARE.
*/

/* eslint no-unused-vars: [2, {"args": "none"}] */
import {MenuDimensions, MenuDistance, MenuPoint} from './types';

/**
* Adapter for MDCMenuSurface. Provides an interface for managing
* - classes
* - dom
* - focus
* - position
* - dimensions
* - event handlers
*
* Additionally, provides type information for the adapter to the Closure
* compiler.
*
* 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 MDCMenuSurfaceAdapter {
/** @param {string} className */
addClass(className) {}

/** @param {string} className */
removeClass(className) {}

/**
* @param {string} className
* @return {boolean}
*/
hasClass(className) {}

/** @return {boolean} */
hasAnchor() {}

/** Emits an event when the menu surface is closed. */
notifyClose() {}

/** Emits an event when the menu surface is opened. */
notifyOpen() {}

/**
* @return {boolean}
* @param {EventTarget} el
*/
isElementInContainer(el) {}

/** @return {boolean} */
isRtl() {}

/** @param {string} origin */
setTransformOrigin(origin) {}

/** @return {boolean} */
isFocused() {}
interface MDCMenuSurfaceAdapter {
addClass(className: string): void;
removeClass(className: string): void;
hasClass(className: string): boolean;
hasAnchor(): boolean;

isElementInContainer(el: Element): boolean;
isFocused(): boolean;
isFirstElementFocused(): boolean;
isLastElementFocused(): boolean;
isRtl(): boolean;

getInnerDimensions(): MenuDimensions;
getAnchorDimensions(): ClientRect | null;
getWindowDimensions(): MenuDimensions;
getBodyDimensions(): MenuDimensions;
getWindowScroll(): MenuPoint;
setPosition(position: Partial<MenuDistance>): void;
setMaxHeight(height: string): void;
setTransformOrigin(origin: string): void;

/** Saves the element that was focused before the menu surface was opened. */
saveFocus() {}
saveFocus(): void;

/** Restores focus to the element that was focused before the menu surface was opened. */
restoreFocus() {}

/** @return {boolean} */
isFirstElementFocused() {}

/** @return {boolean} */
isLastElementFocused() {}
restoreFocus(): void;

/** Focuses the first focusable element in the menu-surface. */
focusFirstElement() {}
focusFirstElement(): void;

/** Focuses the first focusable element in the menu-surface. */
focusLastElement() {}

/** @return {!{width: number, height: number}} */
getInnerDimensions() {}

/** @return {!{width: number, height: number, top: number, right: number, bottom: number, left: number}} */
getAnchorDimensions() {}
focusLastElement(): void;

/** @return {!{ width: number, height: number }} */
getWindowDimensions() {}

/** @return {!{ width: number, height: number }} */
getBodyDimensions() {}

/** @return {!{ width: number, height: number }} */
getWindowScroll() {}

/** @param {!{
* top: (string|undefined),
* right: (string|undefined),
* bottom: (string|undefined),
* left: (string|undefined)
* }} position */
setPosition(position) {}
/** Emits an event when the menu surface is closed. */
notifyClose(): void;

/** @param {string} height */
setMaxHeight(height) {}
/** Emits an event when the menu surface is opened. */
notifyOpen(): void;
}

export {MDCMenuSurfaceAdapter};
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
* THE SOFTWARE.
*/

/** @enum {string} */
const cssClasses = {
ANCHOR: 'mdc-menu-surface--anchor',
ANIMATING_CLOSED: 'mdc-menu-surface--animating-closed',
Expand All @@ -31,55 +30,57 @@ const cssClasses = {
ROOT: 'mdc-menu-surface',
};

/** @enum {string} */
// tslint:disable:object-literal-sort-keys
const strings = {
CLOSED_EVENT: 'MDCMenuSurface:closed',
OPENED_EVENT: 'MDCMenuSurface:opened',
FOCUSABLE_ELEMENTS: 'button:not(:disabled), [href]:not([aria-disabled="true"]), input:not(:disabled), ' +
'select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex="-1"]):not([aria-disabled="true"])',
FOCUSABLE_ELEMENTS: [
'button:not(:disabled)', '[href]:not([aria-disabled="true"])', 'input:not(:disabled)',
'select:not(:disabled)', 'textarea:not(:disabled)', '[tabindex]:not([tabindex="-1"]):not([aria-disabled="true"])',
].join(', '),
};
// tslint:enable:object-literal-sort-keys

/** @enum {number} */
const numbers = {
// Total duration of menu-surface open animation.
/** Total duration of menu-surface open animation. */
TRANSITION_OPEN_DURATION: 120,
// Total duration of menu-surface close animation.

/** Total duration of menu-surface close animation. */
TRANSITION_CLOSE_DURATION: 75,
// Margin left to the edge of the viewport when menu-surface is at maximum possible height.

/** Margin left to the edge of the viewport when menu-surface is at maximum possible height. */
MARGIN_TO_EDGE: 32,
// Ratio of anchor width to menu-surface width for switching from corner positioning to center positioning.

/** Ratio of anchor width to menu-surface width for switching from corner positioning to center positioning. */
ANCHOR_TO_MENU_SURFACE_WIDTH_RATIO: 0.67,
};

/**
* Enum for bits in the {@see Corner) bitmap.
* @enum {number}
*/
const CornerBit = {
BOTTOM: 1,
CENTER: 2,
RIGHT: 4,
FLIP_RTL: 8,
};
enum CornerBit {
BOTTOM = 1,
CENTER = 2,
RIGHT = 4,
FLIP_RTL = 8,
}

/**
* Enum for representing an element corner for positioning the menu-surface.
*
* The START constants map to LEFT if element directionality is left
* to right and RIGHT if the directionality is right to left.
* Likewise END maps to RIGHT or LEFT depending on the directionality.
*
* @enum {number}
*/
const Corner = {
TOP_LEFT: 0,
TOP_RIGHT: CornerBit.RIGHT,
BOTTOM_LEFT: CornerBit.BOTTOM,
BOTTOM_RIGHT: CornerBit.BOTTOM | CornerBit.RIGHT,
TOP_START: CornerBit.FLIP_RTL,
TOP_END: CornerBit.FLIP_RTL | CornerBit.RIGHT,
BOTTOM_START: CornerBit.BOTTOM | CornerBit.FLIP_RTL,
BOTTOM_END: CornerBit.BOTTOM | CornerBit.RIGHT | CornerBit.FLIP_RTL,
};
enum Corner {
TOP_LEFT = 0,
TOP_RIGHT = CornerBit.RIGHT,
BOTTOM_LEFT = CornerBit.BOTTOM,
BOTTOM_RIGHT = CornerBit.BOTTOM | CornerBit.RIGHT, // tslint:disable-line:no-bitwise
TOP_START = CornerBit.FLIP_RTL,
TOP_END = CornerBit.FLIP_RTL | CornerBit.RIGHT, // tslint:disable-line:no-bitwise
BOTTOM_START = CornerBit.BOTTOM | CornerBit.FLIP_RTL, // tslint:disable-line:no-bitwise
BOTTOM_END = CornerBit.BOTTOM | CornerBit.RIGHT | CornerBit.FLIP_RTL, // tslint:disable-line:no-bitwise
}

export {cssClasses, strings, numbers, CornerBit, Corner};
Loading

0 comments on commit a2ac8bc

Please sign in to comment.