From 83423562a1353fecdf7d6fdc99b57a161c0b633d Mon Sep 17 00:00:00 2001 From: Matt Goo Date: Thu, 14 Mar 2019 17:20:47 -0700 Subject: [PATCH 1/5] feat(menu-surface): upgrade to mdc web v1 --- package-lock.json | 66 +++++++++--- package.json | 2 +- packages/menu-surface/index.tsx | 145 +++++++++++++------------- packages/menu-surface/package.json | 2 +- test/unit/menu-surface/index.test.tsx | 121 +++++++++++---------- 5 files changed, 193 insertions(+), 143 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5a0a1000a..9b7d55b3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -987,24 +987,64 @@ } }, "@material/menu-surface": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-0.41.0.tgz", - "integrity": "sha512-HiGFrEIF8DCfEtS8mRtc6MCcK2CJNCh0U6KWWeSIXv+9nW2oiN09piuULXM7aU46wETvfweVcgvHNJvBAXnXjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-1.0.1.tgz", + "integrity": "sha512-JFUa3kQ+NtpuK/mgWIcyhC1AClKmt9EQdW4SG2KQhPAGg0juWiZwyMySDIjf+V0buSUZXZ7N26bi32+Y1LvZ3w==", "dev": true, "requires": { - "@material/animation": "^0.41.0", - "@material/base": "^0.41.0", - "@material/elevation": "^0.41.0", - "@material/rtl": "^0.40.1", - "@material/shape": "^0.41.0", - "@material/theme": "^0.41.0" + "@material/animation": "^1.0.0", + "@material/base": "^1.0.0", + "@material/elevation": "^1.0.0", + "@material/feature-targeting": "^0.44.1", + "@material/rtl": "^0.42.0", + "@material/shape": "^1.0.0", + "@material/theme": "^1.0.0", + "tslib": "^1.9.3" }, "dependencies": { - "@material/base": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/base/-/base-0.41.0.tgz", - "integrity": "sha512-tEyzwBRu3d1H120SfKsDVYZHcqT5lKohh/7cWKR93aAaPDkSvjpKJIjyu2yuSkjpDduVZGzVocYbOvhUKhhzXQ==", + "@material/animation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-1.0.0.tgz", + "integrity": "sha512-Ed5/vggn6ZhSJ87yn3ZS1d826VJNFz73jHF2bSsgRtHDoB8KCuOwQMfdgAgDa4lKDF6CDIPCKBZPKrs2ubehdw==", + "dev": true, + "requires": { + "tslib": "^1.9.3" + } + }, + "@material/elevation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-1.0.0.tgz", + "integrity": "sha512-TqmvEXmZDYLm2X5lEnjKCsZMDkCXpxFFxL22AfCAQB5L4d0gAS7vqDEE797y4Rp+BBKEcOP71mum1l56RI3NBQ==", + "dev": true, + "requires": { + "@material/animation": "^1.0.0", + "@material/feature-targeting": "^0.44.1", + "@material/theme": "^1.0.0" + } + }, + "@material/rtl": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-0.42.0.tgz", + "integrity": "sha512-VrnrKJzhmspsN8WXHuxxBZ69yM5IwhCUqWr1t1eNfw3ZEvEj7i1g3P31HGowKThIN1dc1Wh4LE14rCISWCtv5w==", "dev": true + }, + "@material/shape": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-1.0.0.tgz", + "integrity": "sha512-zfXEacPQZmH+ujVtaFyfAsYiF46j1QCcFzJeZVouG4pznrbA7XD6614Ywg0wbyWX5iB6hD52ld/IN+R/6oxKqA==", + "dev": true, + "requires": { + "@material/feature-targeting": "^0.44.1" + } + }, + "@material/theme": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-1.0.0.tgz", + "integrity": "sha512-Bg/BQLU5MmCwtQ3DHcSs9DodZB8PTvuItv1wXrP54S/wBVwryIB5uMDmERhnItbNnAFbkKhlAuhn1asMmMzfkQ==", + "dev": true, + "requires": { + "@material/feature-targeting": "^0.44.1" + } } } }, diff --git a/package.json b/package.json index d4c85d40e..e24ed4b10 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@material/line-ripple": "^1.0.0", "@material/linear-progress": "^0.41.0", "@material/list": "^1.0.0", - "@material/menu-surface": "^0.41.0", + "@material/menu-surface": "^1.0.1", "@material/notched-outline": "^0.41.0", "@material/radio": "^0.41.0", "@material/ripple": "^1.0.0", diff --git a/packages/menu-surface/index.tsx b/packages/menu-surface/index.tsx index e3bf7e3c4..e65d8728f 100644 --- a/packages/menu-surface/index.tsx +++ b/packages/menu-surface/index.tsx @@ -23,8 +23,10 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import classnames from 'classnames'; -// @ts-ignore no .d.ts file -import {MDCMenuSurfaceFoundation, MDCMenuSurfaceAdapter, Corner} from '@material/menu-surface/dist/mdc.menuSurface'; +import {MDCMenuSurfaceFoundation} from '@material/menu-surface/foundation'; +import {MDCMenuSurfaceAdapter} from '@material/menu-surface/adapter'; +import {Corner} from '@material/menu-surface/index'; +import {MDCMenuDistance} from '@material/menu-surface/types'; export interface MenuSurfaceProps extends React.HTMLProps { className?: string; @@ -51,7 +53,7 @@ export interface MenuSurfaceProps extends React.HTMLProps { export interface MenuSurfaceState { transformOrigin: string; - maxHeight?: number; + maxHeight?: string; styleLeft?: number; styleRight?: number; styleTop?: number; @@ -60,18 +62,11 @@ export interface MenuSurfaceState { mounted: boolean; }; -interface Position { - top?: string; - right?: string; - bottom?: string; - left?: string; -}; - class MenuSurface extends React.Component { menuSurfaceElement: React.RefObject = React.createRef(); previousFocus: HTMLElement | null = null; - foundation: MDCMenuSurfaceFoundation; - handleWindowClick?: EventListener; + foundation!: MDCMenuSurfaceFoundation; + handleWindowClick?: (e: MouseEvent) => void; registerWindowClickListener?: () => void; deregisterWindowClickListener?: () => void; firstFocusableElement: HTMLElement | null = null; @@ -109,7 +104,7 @@ class MenuSurface extends React.Component { fixed, quickOpen, } = this.props; - this.handleWindowClick = (evt) => this.foundation.handleBodyClick(evt); + this.handleWindowClick = (evt: MouseEvent) => this.foundation.handleBodyClick(evt); this.registerWindowClickListener = () => window.addEventListener('click', this.handleWindowClick!); this.deregisterWindowClickListener = () => @@ -147,13 +142,13 @@ class MenuSurface extends React.Component { this.setCoordinates(); } if (this.props.anchorCorner !== prevProps.anchorCorner) { - this.foundation.setAnchorCorner(this.props.anchorCorner); + this.foundation.setAnchorCorner(this.props.anchorCorner!); } if (this.props.anchorMargin !== prevProps.anchorMargin) { - this.foundation.setAnchorMargin(this.props.anchorMargin); + this.foundation.setAnchorMargin(this.props.anchorMargin!); } if (this.props.quickOpen !== prevProps.quickOpen) { - this.foundation.setQuickOpen(this.props.quickOpen); + this.foundation.setQuickOpen(this.props.quickOpen!); } } @@ -217,15 +212,16 @@ class MenuSurface extends React.Component { this.previousFocus.focus(); }, isFirstElementFocused: () => - this.firstFocusableElement && + Boolean(this.firstFocusableElement) && this.firstFocusableElement === document.activeElement, isLastElementFocused: () => - this.lastFocusableElement && + Boolean(this.lastFocusableElement) && this.lastFocusableElement === document.activeElement, - focusFirstElement: () => - this.firstFocusableElement && - this.firstFocusableElement.focus && - this.firstFocusableElement.focus(), + focusFirstElement: () => { + if (!this.firstFocusableElement) return false; + return this.firstFocusableElement.focus && + this.firstFocusableElement.focus() + }, focusLastElement: () => this.lastFocusableElement && this.lastFocusableElement.focus && @@ -235,12 +231,13 @@ class MenuSurface extends React.Component { const dimensionAdapterMethods = { getInnerDimensions: () => { const element = this.menuSurfaceElement.current; - if (!element) return; + if (!element) return {width: 0, height: 0}; return {width: element.offsetWidth, height: element.offsetHeight}; }, - getAnchorDimensions: () => - this.props.anchorElement && - this.props.anchorElement.getBoundingClientRect(), + getAnchorDimensions: () => { + if (!this.props.anchorElement) return null; + return this.props.anchorElement.getBoundingClientRect() + }, getWindowDimensions: () => { return {width: window.innerWidth, height: window.innerHeight}; }, @@ -253,7 +250,7 @@ class MenuSurface extends React.Component { getWindowScroll: () => { return {x: window.pageXOffset, y: window.pageYOffset}; }, - setPosition: (position: Position) => { + setPosition: (position: Partial) => { this.setState((prevState) => Object.assign(prevState, { styleLeft: 'left' in position ? position.left : null, styleRight: 'right' in position ? position.right : null, @@ -261,54 +258,52 @@ class MenuSurface extends React.Component { styleBottom: 'bottom' in position ? position.bottom : null, })); }, - setMaxHeight: (maxHeight: number) => this.setState({maxHeight}), + setMaxHeight: (maxHeight: string) => this.setState({maxHeight}), }; - return Object.assign( - { - addClass: (className: string) => { - const classList = new Set(this.state.classList); - classList.add(className); - this.setState({classList}); - }, - removeClass: (className: string) => { - const classList = new Set(this.state.classList); - classList.delete(className); - this.setState({classList}); - }, - hasClass: (className: string) => this.classes.split(' ').includes(className), - hasAnchor: () => !!this.props.anchorElement, - notifyOpen: () => { - if (this.registerWindowClickListener) { - this.registerWindowClickListener(); - } - this.props.onOpen!(); - }, - notifyClose: () => { - if (this.deregisterWindowClickListener) { - this.deregisterWindowClickListener(); - } - this.props.onClose!(); - }, - isElementInContainer: (el: HTMLElement) => { - if (!this.menuSurfaceElement.current) return false; - if (this.menuSurfaceElement.current === el) { - return true; - } - return this.menuSurfaceElement.current.contains(el); - }, - isRtl: () => { - if (!this.menuSurfaceElement) return false; - if (!this.menuSurfaceElement.current) return false; - return window - .getComputedStyle(this.menuSurfaceElement.current) - .getPropertyValue('direction') === 'rtl'; - }, - setTransformOrigin: (transformOrigin: string) => this.setState({transformOrigin}), + return { + addClass: (className: string) => { + const classList = new Set(this.state.classList); + classList.add(className); + this.setState({classList}); }, - focusAdapterMethods, - dimensionAdapterMethods - ); + removeClass: (className: string) => { + const classList = new Set(this.state.classList); + classList.delete(className); + this.setState({classList}); + }, + hasClass: (className: string) => this.classes.split(' ').includes(className), + hasAnchor: () => !!this.props.anchorElement, + notifyOpen: () => { + if (this.registerWindowClickListener) { + this.registerWindowClickListener(); + } + this.props.onOpen!(); + }, + notifyClose: () => { + if (this.deregisterWindowClickListener) { + this.deregisterWindowClickListener(); + } + this.props.onClose!(); + }, + isElementInContainer: (el: HTMLElement) => { + if (!this.menuSurfaceElement.current) return false; + if (this.menuSurfaceElement.current === el) { + return true; + } + return this.menuSurfaceElement.current.contains(el); + }, + isRtl: () => { + if (!this.menuSurfaceElement) return false; + if (!this.menuSurfaceElement.current) return false; + return window + .getComputedStyle(this.menuSurfaceElement.current) + .getPropertyValue('direction') === 'rtl'; + }, + setTransformOrigin: (transformOrigin: string) => this.setState({transformOrigin}), + ...focusAdapterMethods, + ...dimensionAdapterMethods + }; } open_ = (): void => { @@ -318,10 +313,10 @@ class MenuSurface extends React.Component { MDCMenuSurfaceFoundation.strings.FOCUSABLE_ELEMENTS ); this.firstFocusableElement = - focusableElements.length > 0 ? focusableElements[0] : null; + focusableElements.length > 0 ? focusableElements[0] as HTMLElement : null; this.lastFocusableElement = focusableElements.length > 0 - ? focusableElements[focusableElements.length - 1] + ? focusableElements[focusableElements.length - 1] as HTMLElement : null; this.foundation.open(); } else { @@ -331,7 +326,7 @@ class MenuSurface extends React.Component { handleKeydown = (evt: React.KeyboardEvent) => { this.props.onKeyDown!(evt); - this.foundation.handleKeydown(evt); + this.foundation.handleKeydown(evt.nativeEvent); }; render() { diff --git a/packages/menu-surface/package.json b/packages/menu-surface/package.json index 8c0250a00..3ffa59a0d 100644 --- a/packages/menu-surface/package.json +++ b/packages/menu-surface/package.json @@ -17,7 +17,7 @@ "url": "https://github.com/material-components/material-components-web-react.git" }, "dependencies": { - "@material/menu-surface": "^0.41.0", + "@material/menu-surface": "^1.0.1", "classnames": "^2.2.6", "react": "^16.4.2", "react-dom": "^16.4.2" diff --git a/test/unit/menu-surface/index.test.tsx b/test/unit/menu-surface/index.test.tsx index 258ba449e..b2113d422 100644 --- a/test/unit/menu-surface/index.test.tsx +++ b/test/unit/menu-surface/index.test.tsx @@ -3,9 +3,24 @@ import {assert} from 'chai'; import * as td from 'testdouble'; import {shallow, mount} from 'enzyme'; import MenuSurface, {Corner} from '../../../packages/menu-surface/index'; +import {MenuSurfaceProps, MenuSurfaceState} from '../../../packages/menu-surface'; +import {MDCMenuDistance} from '@material/menu-surface'; suite('MenuSurface'); +function getAdapter(instance: MenuSurface) { + // @ts-ignore adapter_ property is protected and we need to override this + return instance.foundation.adapter_; +} + + +const removeMenuFromBody = (wrapper: ReactWrapper) => { + wrapper + .find('.mdc-menu-surface') + .getDOMNode() + .remove(); +}; + test('classNames adds classes', () => { const wrapper = mount(); assert.isTrue(wrapper.childAt(0).hasClass('test-class-name')); @@ -33,7 +48,7 @@ test('foundation is created', () => { test('update to props.open will call foundation.open', () => { const wrapper = mount(); - wrapper.instance().foundation.open = td.func(); + wrapper.instance().foundation.open = td.func<() => void>(); wrapper.setProps({open: true}); td.verify(wrapper.instance().foundation.open(), {times: 1}); wrapper.unmount(); @@ -69,7 +84,7 @@ test('update to props.open sets lastFocusableElement', () => { test('update to props.open from true to false will call foundation.close', () => { const wrapper = mount(); - wrapper.instance().foundation.close = td.func(); + wrapper.instance().foundation.close = td.func<() => void>(); wrapper.setProps({open: false}); td.verify(wrapper.instance().foundation.close(), {times: 1}); wrapper.unmount(); @@ -77,7 +92,7 @@ test('update to props.open from true to false will call foundation.close', () => test('foundation.setAbsolutePosition is called when props.coordinates updates', () => { const wrapper = shallow(); - wrapper.instance().foundation.setAbsolutePosition = td.func(); + wrapper.instance().foundation.setAbsolutePosition = td.func<(x: number, y: number) => void>(); wrapper.setProps({coordinates: {x: 1, y: 11}}); td.verify(wrapper.instance().foundation.setAbsolutePosition(1, 11), { times: 1, @@ -86,7 +101,7 @@ test('foundation.setAbsolutePosition is called when props.coordinates updates', test('foundation.setAnchorCorner is called when props.anchorCorner updates', () => { const wrapper = shallow(); - wrapper.instance().foundation.setAnchorCorner = td.func(); + wrapper.instance().foundation.setAnchorCorner = td.func<(corner: Corner) => void>(); wrapper.setProps({anchorCorner: Corner.TOP_RIGHT}); td.verify(wrapper.instance().foundation.setAnchorCorner(Corner.TOP_RIGHT), { times: 1, @@ -95,7 +110,7 @@ test('foundation.setAnchorCorner is called when props.anchorCorner updates', () test('foundation.setAnchorMargin is called when props.anchorMargin updates', () => { const wrapper = shallow(); - wrapper.instance().foundation.setAnchorMargin = td.func(); + wrapper.instance().foundation.setAnchorMargin = td.func<(margin: Partial) => void>(); wrapper.setProps({anchorMargin: {top: 20}}); td.verify(wrapper.instance().foundation.setAnchorMargin({top: 20}), { times: 1, @@ -104,14 +119,14 @@ test('foundation.setAnchorMargin is called when props.anchorMargin updates', () test('foundation.setQuickOpen is called when props.quickOpen updates to true', () => { const wrapper = shallow(); - wrapper.instance().foundation.setQuickOpen = td.func(); + wrapper.instance().foundation.setQuickOpen = td.func<(quickOpen: boolean) => void>(); wrapper.setProps({quickOpen: true}); td.verify(wrapper.instance().foundation.setQuickOpen(true), {times: 1}); }); test('foundation.setQuickOpen is called when props.quickOpen updates to false', () => { const wrapper = shallow(); - wrapper.instance().foundation.setQuickOpen = td.func(); + wrapper.instance().foundation.setQuickOpen = td.func<(quickOpen: boolean) => void>(); wrapper.setProps({quickOpen: false}); td.verify(wrapper.instance().foundation.setQuickOpen(false), {times: 1}); }); @@ -130,9 +145,9 @@ test('foundation.isOpen is false when props.open is false', () => { test('#registerWindowClickListener adds click event handler to window', () => { const wrapper = shallow(); - wrapper.instance().foundation.handleBodyClick = td.func(); + wrapper.instance().foundation.handleBodyClick = td.func<(evt: MouseEvent) => void>(); wrapper.instance().registerWindowClickListener!(); - const clickEvent = new Event('click'); + const clickEvent = new MouseEvent('click'); window.dispatchEvent(clickEvent); td.verify(wrapper.instance().foundation.handleBodyClick(clickEvent), { times: 1, @@ -141,10 +156,10 @@ test('#registerWindowClickListener adds click event handler to window', () => { test('#deregisterWindowClickListener removes click event handler to window', () => { const wrapper = shallow(); - wrapper.instance().foundation.handleBodyClick = td.func(); + wrapper.instance().foundation.handleBodyClick = td.func<(evt: MouseEvent) => void>(); wrapper.instance().registerWindowClickListener!(); wrapper.instance().deregisterWindowClickListener!(); - const clickEvent = new Event('click'); + const clickEvent = new MouseEvent('click'); window.dispatchEvent(clickEvent); td.verify(wrapper.instance().foundation.handleBodyClick(clickEvent), { times: 0, @@ -153,15 +168,15 @@ test('#deregisterWindowClickListener removes click event handler to window', () test('#adapter.notifyOpen calls #registerWindowClickListener', () => { const wrapper = shallow(); - wrapper.instance().registerWindowClickListener = td.func() as () => void; - wrapper.instance().foundation.adapter_.notifyOpen(); + wrapper.instance().registerWindowClickListener = td.func<() => void>(); + getAdapter(wrapper.instance()).notifyOpen(); td.verify(wrapper.instance().registerWindowClickListener!(), {times: 1}); }); test('#adapter.notifyOpen calls onOpen', () => { const onOpen = td.func() as () => void; const wrapper = shallow(); - wrapper.instance().foundation.adapter_.notifyOpen(); + getAdapter(wrapper.instance()).notifyOpen(); td.verify(onOpen(), {times: 1}); }); @@ -178,7 +193,7 @@ test('#adapter.isFocused returns true if menuSurfaceElement_ is the activeElemen options ); (wrapper.getDOMNode() as HTMLDivElement).focus(); - assert.isTrue(wrapper.instance().foundation.adapter_.isFocused()); + assert.isTrue(getAdapter(wrapper.instance()).isFocused()); wrapper.unmount(); div.remove(); }); @@ -189,7 +204,7 @@ test('#adapter.isFocused returns false if menuSurfaceElement_ is not the activeE hello ); - assert.isFalse(wrapper.instance().foundation.adapter_.isFocused()); + assert.isFalse(getAdapter(wrapper.instance()).isFocused()); wrapper.unmount(); }); @@ -207,7 +222,7 @@ test('#adapter.saveFocus saves the currently focused element', () => { .find('button') .getDOMNode() as HTMLButtonElement) .focus(); - wrapper.instance().foundation.adapter_.saveFocus(); + getAdapter(wrapper.instance()).saveFocus(); assert.equal( wrapper.instance().previousFocus, (wrapper.find('button').getDOMNode() as HTMLButtonElement) @@ -232,7 +247,7 @@ test('#adapter.restoreFocus restores focus to an element within the menuSurfaceE .find('button') .getDOMNode() as HTMLButtonElement) .focus(); - wrapper.instance().foundation.adapter_.restoreFocus(); + getAdapter(wrapper.instance()).restoreFocus(); assert.equal(document.activeElement, wrapper.find('a').getDOMNode()); wrapper.unmount(); div.remove(); @@ -252,7 +267,7 @@ test('#adapter.isFirstElementFocused returns true if firstFocusableElement is th .getDOMNode() as HTMLButtonElement) .focus(); assert.isTrue( - wrapper.instance().foundation.adapter_.isFirstElementFocused() + getAdapter(wrapper.instance()).isFirstElementFocused() ); wrapper.unmount(); }); @@ -270,7 +285,7 @@ test('#adapter.isLastElementFocused returns true if lastFocusableElement is the .find('button') .getDOMNode() as HTMLButtonElement) .focus(); - assert.isTrue(wrapper.instance().foundation.adapter_.isLastElementFocused()); + assert.isTrue(getAdapter(wrapper.instance()).isLastElementFocused()); wrapper.unmount(); }); @@ -283,7 +298,7 @@ test('#adapter.focusFirstElement focuses on firstFocusableElement', () => { wrapper.instance().firstFocusableElement = wrapper .find('button') .getDOMNode() as HTMLButtonElement; - wrapper.instance().foundation.adapter_.focusFirstElement(); + getAdapter(wrapper.instance()).focusFirstElement(); assert.equal(document.activeElement, wrapper.find('button').getDOMNode()); wrapper.unmount(); }); @@ -297,7 +312,7 @@ test('#adapter.focusLastElement focuses on lastFocusableElement', () => { wrapper.instance().lastFocusableElement = wrapper .find('button') .getDOMNode() as HTMLButtonElement; - wrapper.instance().foundation.adapter_.focusLastElement(); + getAdapter(wrapper.instance()).focusLastElement(); assert.equal(document.activeElement, wrapper.find('button').getDOMNode()); wrapper.unmount(); }); @@ -308,7 +323,7 @@ test('#adapter.getInnerDimensions returns width/height of menuSurfaceElement_', ); - const dim = wrapper.instance().foundation.adapter_.getInnerDimensions(); + const dim = getAdapter(wrapper.instance()).getInnerDimensions(); assert.isAbove(dim.width, 0); assert.isAbove(dim.height, 0); wrapper.unmount(); @@ -325,7 +340,7 @@ test('#adapter.getAnchorDimensions returns width/height of menuSurfaceElement_', options ); assert.deepInclude( - wrapper.instance().foundation.adapter_.getAnchorDimensions(), + getAdapter(wrapper.instance()).getAnchorDimensions(), div.getBoundingClientRect() ); wrapper.unmount(); @@ -334,10 +349,10 @@ test('#adapter.getAnchorDimensions returns width/height of menuSurfaceElement_', test('#adapter.getWindowDimensions returns width/height of menuSurfaceElement_', () => { const wrapper = shallow(); - const dim = wrapper + const dim = getAdapter(wrapper .update() - .instance() - .foundation.adapter_.getWindowDimensions(); + .instance()) + .getWindowDimensions(); assert.isAbove(dim.width, 0); assert.isAbove(dim.height, 0); }); @@ -352,10 +367,10 @@ test('#adapter.getBodyDimensions returns width/height of body', () => { , options ); - const dim = wrapper + const dim = getAdapter(wrapper .update() - .instance() - .foundation.adapter_.getBodyDimensions(); + .instance()) + .getBodyDimensions(); assert.isAtLeast(dim.width, 0); assert.isAtLeast(dim.height, 0); wrapper.unmount(); @@ -364,17 +379,17 @@ test('#adapter.getBodyDimensions returns width/height of body', () => { test('#adapter.getWindowScroll returns scroll of window', () => { const wrapper = shallow(); - const scroll = wrapper + const scroll = getAdapter(wrapper .update() - .instance() - .foundation.adapter_.getWindowScroll(); + .instance()) + .getWindowScroll(); assert.isAtLeast(scroll.x, 0); assert.isAtLeast(scroll.y, 0); }); test('#adapter.setPosition sets left, right, top, bottom state variables', () => { const wrapper = shallow(); - wrapper.instance().foundation.adapter_.setPosition({ + getAdapter(wrapper.instance()).setPosition({ left: 20, bottom: 30, top: 40, @@ -387,20 +402,20 @@ test('#adapter.setPosition sets left, right, top, bottom state variables', () => test('#adapter.setMaxHeight sets maxHeight state variables', () => { const wrapper = shallow(); - wrapper.instance().foundation.adapter_.setMaxHeight(500); - assert.equal(wrapper.state().maxHeight, 500); + getAdapter(wrapper.instance()).setMaxHeight('500'); + assert.equal(wrapper.state().maxHeight, '500'); }); test('#adapter.addClass adds to classList', () => { const wrapper = shallow(); - wrapper.instance().foundation.adapter_.addClass('test-class-name'); + getAdapter(wrapper.instance()).addClass('test-class-name'); assert.isTrue(wrapper.state().classList.has('test-class-name')); }); test('#adapter.removeClass removes from classList', () => { const wrapper = shallow(); wrapper.setState({classList: new Set(['test-class-name'])}); - wrapper.instance().foundation.adapter_.removeClass('test-class-name'); + getAdapter(wrapper.instance()).removeClass('test-class-name'); assert.isFalse(wrapper.state().classList.has('test-class-name')); }); @@ -408,40 +423,40 @@ test('#adapter.hasClass returns true if classList has class', () => { const wrapper = shallow(); wrapper.setState({classList: new Set(['test-class-name'])}); assert.isTrue( - wrapper.instance().foundation.adapter_.hasClass('test-class-name') + getAdapter(wrapper.instance()).hasClass('test-class-name') ); }); test('#adapter.notifyClose calls onClose', () => { const onClose = td.func() as () => void; const wrapper = shallow(); - wrapper.instance().foundation.adapter_.notifyClose(); + getAdapter(wrapper.instance()).notifyClose(); td.verify(onClose(), {times: 1}); }); test('#adapter.notifyClose calls deregisterWindowClickListener', () => { const wrapper = shallow(); wrapper.instance().deregisterWindowClickListener = td.func() as () => void; - wrapper.instance().foundation.adapter_.notifyClose(); + getAdapter(wrapper.instance()).notifyClose(); td.verify(wrapper.instance().deregisterWindowClickListener!(), {times: 1}); }); test('#adapter.hasAnchor calls returns false if there is no props.anchorElement', () => { const wrapper = shallow(); - assert.isFalse(wrapper.instance().foundation.adapter_.hasAnchor()); + assert.isFalse(getAdapter(wrapper.instance()).hasAnchor()); }); test('#adapter.hasAnchor calls returns true if there is props.anchorElement', () => { const anchorElement =
as unknown as HTMLDivElement; const wrapper = shallow(); - assert.isTrue(wrapper.instance().foundation.adapter_.hasAnchor()); + assert.isTrue(getAdapter(wrapper.instance()).hasAnchor()); }); test('#adapter.isElementInContainer returns true if the element is the menuSurfaceElement_', () => { const wrapper = mount(); const element = wrapper.getDOMNode(); assert.isTrue( - wrapper.instance().foundation.adapter_.isElementInContainer(element) + getAdapter(wrapper.instance()).isElementInContainer(element) ); wrapper.unmount(); }); @@ -454,7 +469,7 @@ test('#adapter.isElementInContainer returns true if the element is within the co ); const element = wrapper.find('button').getDOMNode(); assert.isTrue( - wrapper.instance().foundation.adapter_.isElementInContainer(element) + getAdapter(wrapper.instance()).isElementInContainer(element) ); wrapper.unmount(); }); @@ -470,37 +485,37 @@ test('#adapter.isRtl returns true is rtl', () => { options ); wrapper.getDOMNode().setAttribute('dir', 'rtl'); - assert.isTrue(wrapper.instance().foundation.adapter_.isRtl()); + assert.isTrue(getAdapter(wrapper.instance()).isRtl()); wrapper.unmount(); div.remove(); }); test('#adapter.setTransformOrigin sets maxHeight state variables', () => { const wrapper = shallow(); - wrapper.instance().foundation.adapter_.setTransformOrigin('translate()'); + getAdapter(wrapper.instance()).setTransformOrigin('translate()'); assert.equal(wrapper.state().transformOrigin, 'translate()'); }); test('onKeyDown calls props.onKeyDown', () => { const onKeyDown = td.func() as (event: React.KeyboardEvent) => {}; const wrapper = shallow(); - const evt = {} as React.KeyboardEvent; + const evt = {nativeEvent: {}} as React.KeyboardEvent; wrapper.instance().handleKeydown(evt); td.verify(onKeyDown(evt), {times: 1}); }); test('onKeyDown calls foundation.handleKeydown', () => { const wrapper = shallow(hello); - wrapper.instance().foundation.handleKeydown = td.func() as (event: React.KeyboardEvent) => {}; - const evt = {} as React.KeyboardEvent; + wrapper.instance().foundation.handleKeydown = td.func<(event: KeyboardEvent) => {}>(); + const evt = {nativeEvent: ({} as KeyboardEvent)} as React.KeyboardEvent; wrapper.instance().handleKeydown(evt); - td.verify(wrapper.instance().foundation.handleKeydown(evt), {times: 1}); + td.verify(wrapper.instance().foundation.handleKeydown(evt.nativeEvent), {times: 1}); }); test('component styles is applied from this.styles', () => { const wrapper = mount(); wrapper.setState({ - maxHeight: 200, + maxHeight: '200', styleLeft: 50, }); assert.equal(wrapper.childAt(0).props().style!.maxHeight, 200); @@ -519,7 +534,7 @@ test('#componentWillUnmount calls #deregisterWindowClickListener', () => { test('#componentWillUnmount destroys foundation', () => { const wrapper = shallow(); const foundation = wrapper.instance().foundation; - foundation.destroy = td.func(); + foundation.destroy = td.func<() => void>(); wrapper.unmount(); td.verify(foundation.destroy()); }); From 3526a04271dfddaa5ae56d33b8ce7adf5bff81a2 Mon Sep 17 00:00:00 2001 From: Matt Goo Date: Mon, 25 Mar 2019 16:06:28 -0700 Subject: [PATCH 2/5] WIP: packagelock --- package-lock.json | 265 +++++++++++++++++++++++++++------------------- 1 file changed, 157 insertions(+), 108 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b7d55b3b..9e1e191ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -692,21 +692,6 @@ "tslib": "^1.9.3" } }, - "@material/list": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/list/-/list-0.41.0.tgz", - "integrity": "sha512-HhYN0I02CTT8j91c1eeeI+L2KXVKdfzj0Zuapp2SdeCmQZLJO2tu2NYj0W6REBDTVBWBccr12Sn8o71CodEScQ==", - "dev": true, - "requires": { - "@material/base": "^0.41.0", - "@material/dom": "^0.41.0", - "@material/ripple": "^0.41.0", - "@material/rtl": "^0.40.1", - "@material/shape": "^0.41.0", - "@material/theme": "^0.41.0", - "@material/typography": "^0.41.0" - } - }, "@material/ripple": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-1.0.1.tgz", @@ -809,23 +794,51 @@ "dev": true }, "@material/floating-label": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-0.41.0.tgz", - "integrity": "sha512-qI6f1nZU3crXxWAI9fw3U5fHw2qOzEor49EvskbcaV5KSRW5qO+jtfUQ3ib/Vhki7lqhgwNHB/0n7KYhvhjRHQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-1.0.0.tgz", + "integrity": "sha512-yESFi8HEUO0PmPWvaU3VW4X8+xaoFHhj2xGxLPu2hGye4ZBjTpmjOX6y1vwYqZLD5KWXj91k695UAT6J2wtWFQ==", "dev": true, "requires": { - "@material/animation": "^0.41.0", - "@material/base": "^0.41.0", - "@material/rtl": "^0.40.1", - "@material/theme": "^0.41.0", - "@material/typography": "^0.41.0" + "@material/animation": "^1.0.0", + "@material/base": "^1.0.0", + "@material/rtl": "^0.42.0", + "@material/theme": "^1.0.0", + "@material/typography": "^1.0.0", + "tslib": "^1.9.3" }, "dependencies": { - "@material/base": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/base/-/base-0.41.0.tgz", - "integrity": "sha512-tEyzwBRu3d1H120SfKsDVYZHcqT5lKohh/7cWKR93aAaPDkSvjpKJIjyu2yuSkjpDduVZGzVocYbOvhUKhhzXQ==", + "@material/animation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-1.0.0.tgz", + "integrity": "sha512-Ed5/vggn6ZhSJ87yn3ZS1d826VJNFz73jHF2bSsgRtHDoB8KCuOwQMfdgAgDa4lKDF6CDIPCKBZPKrs2ubehdw==", + "dev": true, + "requires": { + "tslib": "^1.9.3" + } + }, + "@material/rtl": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-0.42.0.tgz", + "integrity": "sha512-VrnrKJzhmspsN8WXHuxxBZ69yM5IwhCUqWr1t1eNfw3ZEvEj7i1g3P31HGowKThIN1dc1Wh4LE14rCISWCtv5w==", "dev": true + }, + "@material/theme": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-1.0.0.tgz", + "integrity": "sha512-Bg/BQLU5MmCwtQ3DHcSs9DodZB8PTvuItv1wXrP54S/wBVwryIB5uMDmERhnItbNnAFbkKhlAuhn1asMmMzfkQ==", + "dev": true, + "requires": { + "@material/feature-targeting": "^0.44.1" + } + }, + "@material/typography": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-1.0.0.tgz", + "integrity": "sha512-Oeqbjci1cC7jTE8/n3dwnkqKe9ZeWiaE+rgMtRYtRFw1HvAw14SpGA5EEAS/Li2Hu2KZ50FYCe3HYqShfxtChA==", + "dev": true, + "requires": { + "@material/feature-targeting": "^0.44.1" + } } } }, @@ -942,6 +955,15 @@ "tslib": "^1.9.3" }, "dependencies": { + "@material/animation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-1.0.0.tgz", + "integrity": "sha512-Ed5/vggn6ZhSJ87yn3ZS1d826VJNFz73jHF2bSsgRtHDoB8KCuOwQMfdgAgDa4lKDF6CDIPCKBZPKrs2ubehdw==", + "dev": true, + "requires": { + "tslib": "^1.9.3" + } + }, "@material/dom": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@material/dom/-/dom-1.0.1.tgz", @@ -951,6 +973,20 @@ "tslib": "^1.9.3" } }, + "@material/ripple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-1.0.1.tgz", + "integrity": "sha512-aBigRoVMjIU2lLDq7TMocI2H2YFbO1hICs5FTdSRp4Yis/QFTrgaW32q8yuHdZI56j+b2BWIWapqA2xpSmCMXQ==", + "dev": true, + "requires": { + "@material/animation": "^1.0.0", + "@material/base": "^1.0.0", + "@material/dom": "^1.0.1", + "@material/feature-targeting": "^0.44.1", + "@material/theme": "^1.0.0", + "tslib": "^1.9.3" + } + }, "@material/rtl": { "version": "0.42.0", "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-0.42.0.tgz", @@ -1724,6 +1760,19 @@ "integrity": "sha512-tEyzwBRu3d1H120SfKsDVYZHcqT5lKohh/7cWKR93aAaPDkSvjpKJIjyu2yuSkjpDduVZGzVocYbOvhUKhhzXQ==", "dev": true }, + "@material/floating-label": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-0.41.0.tgz", + "integrity": "sha512-qI6f1nZU3crXxWAI9fw3U5fHw2qOzEor49EvskbcaV5KSRW5qO+jtfUQ3ib/Vhki7lqhgwNHB/0n7KYhvhjRHQ==", + "dev": true, + "requires": { + "@material/animation": "^0.41.0", + "@material/base": "^0.41.0", + "@material/rtl": "^0.40.1", + "@material/theme": "^0.41.0", + "@material/typography": "^0.41.0" + } + }, "@material/line-ripple": { "version": "0.41.0", "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-0.41.0.tgz", @@ -17722,7 +17771,7 @@ }, "ts-loader": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-3.5.0.tgz", + "resolved": "http://registry.npmjs.org/ts-loader/-/ts-loader-3.5.0.tgz", "integrity": "sha512-JTia3kObhTk36wPFgy0RnkZReiusYx7Le9IhcUWRrCTcFcr6Dy1zGsFd3x8DG4gevlbN65knI8W50FfoykXcng==", "dev": true, "requires": { @@ -18746,28 +18795,28 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "", + "resolved": false, "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "", + "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": "", + "resolved": false, "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "resolved": "", + "resolved": false, "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "dev": true, "optional": true, @@ -18778,14 +18827,14 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "", + "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, @@ -18796,28 +18845,28 @@ }, "chownr": { "version": "1.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "", + "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "", + "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true @@ -18831,7 +18880,7 @@ }, "debug": { "version": "2.6.9", - "resolved": "", + "resolved": false, "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "optional": true, @@ -18841,28 +18890,28 @@ }, "deep-extend": { "version": "0.5.1", - "resolved": "", + "resolved": false, "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "", + "resolved": false, "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": "", + "resolved": false, "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, @@ -18872,14 +18921,14 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "", + "resolved": false, "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, @@ -18896,7 +18945,7 @@ }, "glob": { "version": "7.1.2", - "resolved": "", + "resolved": false, "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "optional": true, @@ -18911,14 +18960,14 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.21", - "resolved": "", + "resolved": false, "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", "dev": true, "optional": true, @@ -18928,7 +18977,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": "", + "resolved": false, "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, @@ -18938,7 +18987,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "", + "resolved": false, "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, @@ -18949,21 +18998,21 @@ }, "inherits": { "version": "2.0.3", - "resolved": "", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": "", + "resolved": false, "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, @@ -18980,7 +19029,7 @@ }, "minimatch": { "version": "3.0.4", - "resolved": "", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, @@ -18990,14 +19039,14 @@ }, "minimist": { "version": "0.0.8", - "resolved": "", + "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true, "optional": true }, "minipass": { "version": "2.2.4", - "resolved": "", + "resolved": false, "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, "optional": true, @@ -19008,7 +19057,7 @@ }, "minizlib": { "version": "1.1.0", - "resolved": "", + "resolved": false, "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", "dev": true, "optional": true, @@ -19018,7 +19067,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "", + "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "optional": true, @@ -19028,14 +19077,14 @@ }, "ms": { "version": "2.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true, "optional": true }, "needle": { "version": "2.2.0", - "resolved": "", + "resolved": false, "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", "dev": true, "optional": true, @@ -19047,7 +19096,7 @@ }, "node-pre-gyp": { "version": "0.10.0", - "resolved": "", + "resolved": false, "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", "dev": true, "optional": true, @@ -19066,7 +19115,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, @@ -19077,14 +19126,14 @@ }, "npm-bundled": { "version": "1.0.3", - "resolved": "", + "resolved": false, "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.1.10", - "resolved": "", + "resolved": false, "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", "dev": true, "optional": true, @@ -19095,7 +19144,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "", + "resolved": false, "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, @@ -19108,21 +19157,21 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": "", + "resolved": false, "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": "", + "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, @@ -19132,21 +19181,21 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "", + "resolved": false, "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, @@ -19157,7 +19206,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true @@ -19171,7 +19220,7 @@ }, "rc": { "version": "1.2.7", - "resolved": "", + "resolved": false, "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", "dev": true, "optional": true, @@ -19184,7 +19233,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "", + "resolved": false, "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true @@ -19209,7 +19258,7 @@ }, "rimraf": { "version": "2.6.2", - "resolved": "", + "resolved": false, "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "optional": true, @@ -19219,49 +19268,49 @@ }, "safe-buffer": { "version": "5.1.1", - "resolved": "", + "resolved": false, "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "", + "resolved": false, "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": "", + "resolved": false, "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.5.0", - "resolved": "", + "resolved": false, "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, @@ -19283,7 +19332,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, @@ -19293,14 +19342,14 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.1", - "resolved": "", + "resolved": false, "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", "dev": true, "optional": true, @@ -19323,7 +19372,7 @@ }, "wide-align": { "version": "1.1.2", - "resolved": "", + "resolved": false, "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "optional": true, @@ -19333,14 +19382,14 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", "dev": true, "optional": true @@ -19803,21 +19852,21 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "", + "resolved": false, "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "", + "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": "", + "resolved": false, "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true @@ -19835,14 +19884,14 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "", + "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, @@ -19853,35 +19902,35 @@ }, "chownr": { "version": "1.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "", + "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "", + "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": "", + "resolved": false, "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true @@ -19898,21 +19947,21 @@ }, "deep-extend": { "version": "0.5.1", - "resolved": "", + "resolved": false, "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "", + "resolved": false, "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true @@ -19929,7 +19978,7 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true @@ -19968,7 +20017,7 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "", + "resolved": false, "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true @@ -19985,7 +20034,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": "", + "resolved": false, "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, @@ -20006,14 +20055,14 @@ }, "inherits": { "version": "2.0.3", - "resolved": "", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": "", + "resolved": false, "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true @@ -20030,14 +20079,14 @@ }, "isarray": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, From 9af572a80c503551662b55e1665c69e9f442a580 Mon Sep 17 00:00:00 2001 From: Matt Goo Date: Tue, 19 Mar 2019 17:07:29 -0700 Subject: [PATCH 3/5] fix: lint --- packages/menu-surface/index.tsx | 6 +++--- test/unit/menu-surface/index.test.tsx | 9 --------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/packages/menu-surface/index.tsx b/packages/menu-surface/index.tsx index e65d8728f..811f7f5d7 100644 --- a/packages/menu-surface/index.tsx +++ b/packages/menu-surface/index.tsx @@ -220,7 +220,7 @@ class MenuSurface extends React.Component { focusFirstElement: () => { if (!this.firstFocusableElement) return false; return this.firstFocusableElement.focus && - this.firstFocusableElement.focus() + this.firstFocusableElement.focus(); }, focusLastElement: () => this.lastFocusableElement && @@ -236,7 +236,7 @@ class MenuSurface extends React.Component { }, getAnchorDimensions: () => { if (!this.props.anchorElement) return null; - return this.props.anchorElement.getBoundingClientRect() + return this.props.anchorElement.getBoundingClientRect(); }, getWindowDimensions: () => { return {width: window.innerWidth, height: window.innerHeight}; @@ -302,7 +302,7 @@ class MenuSurface extends React.Component { }, setTransformOrigin: (transformOrigin: string) => this.setState({transformOrigin}), ...focusAdapterMethods, - ...dimensionAdapterMethods + ...dimensionAdapterMethods, }; } diff --git a/test/unit/menu-surface/index.test.tsx b/test/unit/menu-surface/index.test.tsx index b2113d422..b124bf727 100644 --- a/test/unit/menu-surface/index.test.tsx +++ b/test/unit/menu-surface/index.test.tsx @@ -3,7 +3,6 @@ import {assert} from 'chai'; import * as td from 'testdouble'; import {shallow, mount} from 'enzyme'; import MenuSurface, {Corner} from '../../../packages/menu-surface/index'; -import {MenuSurfaceProps, MenuSurfaceState} from '../../../packages/menu-surface'; import {MDCMenuDistance} from '@material/menu-surface'; suite('MenuSurface'); @@ -13,14 +12,6 @@ function getAdapter(instance: MenuSurface) { return instance.foundation.adapter_; } - -const removeMenuFromBody = (wrapper: ReactWrapper) => { - wrapper - .find('.mdc-menu-surface') - .getDOMNode() - .remove(); -}; - test('classNames adds classes', () => { const wrapper = mount(); assert.isTrue(wrapper.childAt(0).hasClass('test-class-name')); From 0d9ef5b5ef043c1bc9654ed6943f487c1c067980 Mon Sep 17 00:00:00 2001 From: Matt Goo Date: Thu, 21 Mar 2019 13:26:54 -0700 Subject: [PATCH 4/5] fix: pr updates --- packages/menu-surface/index.tsx | 9 ++------- test/unit/menu-surface/index.test.tsx | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/menu-surface/index.tsx b/packages/menu-surface/index.tsx index 811f7f5d7..038ff5d99 100644 --- a/packages/menu-surface/index.tsx +++ b/packages/menu-surface/index.tsx @@ -115,7 +115,7 @@ class MenuSurface extends React.Component { // here we force the menu to hoist, and require either // this.props.(x,y) or this.props.anchorElement. this.foundation.setIsHoisted(true); - this.foundation.setFixedPosition(fixed); + this.foundation.setFixedPosition(fixed!); if (coordinates) { this.setCoordinates(); } @@ -212,10 +212,8 @@ class MenuSurface extends React.Component { this.previousFocus.focus(); }, isFirstElementFocused: () => - Boolean(this.firstFocusableElement) && this.firstFocusableElement === document.activeElement, isLastElementFocused: () => - Boolean(this.lastFocusableElement) && this.lastFocusableElement === document.activeElement, focusFirstElement: () => { if (!this.firstFocusableElement) return false; @@ -288,9 +286,6 @@ class MenuSurface extends React.Component { }, isElementInContainer: (el: HTMLElement) => { if (!this.menuSurfaceElement.current) return false; - if (this.menuSurfaceElement.current === el) { - return true; - } return this.menuSurfaceElement.current.contains(el); }, isRtl: () => { @@ -324,7 +319,7 @@ class MenuSurface extends React.Component { } }; - handleKeydown = (evt: React.KeyboardEvent) => { + handleKeydown = (evt: React.KeyboardEvent) => { this.props.onKeyDown!(evt); this.foundation.handleKeydown(evt.nativeEvent); }; diff --git a/test/unit/menu-surface/index.test.tsx b/test/unit/menu-surface/index.test.tsx index b124bf727..376b39a21 100644 --- a/test/unit/menu-surface/index.test.tsx +++ b/test/unit/menu-surface/index.test.tsx @@ -490,7 +490,7 @@ test('#adapter.setTransformOrigin sets maxHeight state variables', () => { test('onKeyDown calls props.onKeyDown', () => { const onKeyDown = td.func() as (event: React.KeyboardEvent) => {}; const wrapper = shallow(); - const evt = {nativeEvent: {}} as React.KeyboardEvent; + const evt = {nativeEvent: {}} as React.KeyboardEvent; wrapper.instance().handleKeydown(evt); td.verify(onKeyDown(evt), {times: 1}); }); @@ -498,7 +498,7 @@ test('onKeyDown calls props.onKeyDown', () => { test('onKeyDown calls foundation.handleKeydown', () => { const wrapper = shallow(hello); wrapper.instance().foundation.handleKeydown = td.func<(event: KeyboardEvent) => {}>(); - const evt = {nativeEvent: ({} as KeyboardEvent)} as React.KeyboardEvent; + const evt = {nativeEvent: ({} as KeyboardEvent)} as React.KeyboardEvent; wrapper.instance().handleKeydown(evt); td.verify(wrapper.instance().foundation.handleKeydown(evt.nativeEvent), {times: 1}); }); From 5dbc51a0d6a0e5efe75879d37c682bbe30b870da Mon Sep 17 00:00:00 2001 From: Matt Goo Date: Mon, 25 Mar 2019 13:06:35 -0700 Subject: [PATCH 5/5] fix: add a handleOpen and handleClose method --- packages/menu-surface/index.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/menu-surface/index.tsx b/packages/menu-surface/index.tsx index 038ff5d99..fcd1e6ec5 100644 --- a/packages/menu-surface/index.tsx +++ b/packages/menu-surface/index.tsx @@ -273,15 +273,11 @@ class MenuSurface extends React.Component { hasClass: (className: string) => this.classes.split(' ').includes(className), hasAnchor: () => !!this.props.anchorElement, notifyOpen: () => { - if (this.registerWindowClickListener) { - this.registerWindowClickListener(); - } + this.handleOpen(); this.props.onOpen!(); }, notifyClose: () => { - if (this.deregisterWindowClickListener) { - this.deregisterWindowClickListener(); - } + this.handleClose(); this.props.onClose!(); }, isElementInContainer: (el: HTMLElement) => { @@ -324,6 +320,18 @@ class MenuSurface extends React.Component { this.foundation.handleKeydown(evt.nativeEvent); }; + private handleOpen = () => { + if (this.registerWindowClickListener) { + this.registerWindowClickListener(); + } + } + + private handleClose = () => { + if (this.deregisterWindowClickListener) { + this.deregisterWindowClickListener(); + } + } + render() { const { /* eslint-disable */