diff --git a/package-lock.json b/package-lock.json index 8ae0e2508..d7891329f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1874,36 +1874,96 @@ "dev": true }, "@material/top-app-bar": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-0.41.0.tgz", - "integrity": "sha512-U3MK6pdzyfXC3zttsrEYihzR7aRqnKM3w2MWRwI0iub/lFygVOSa4qQfaJhwjz9TTyxB8tdtZOXBpEVDsH+xmA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-1.1.0.tgz", + "integrity": "sha512-fxVKFolNzPG4+LqH8GUxDKfjRZtQNDYX8sGD6c2pKbk1tigyiAGBO/Py31RQQkbAdCKPdmnanGJK2gewaUdw4g==", "dev": true, "requires": { - "@material/animation": "^0.41.0", - "@material/base": "^0.41.0", - "@material/elevation": "^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/animation": "^1.0.0", + "@material/base": "^1.0.0", + "@material/elevation": "^1.1.0", + "@material/ripple": "^1.1.0", + "@material/rtl": "^0.42.0", + "@material/shape": "^1.0.0", + "@material/theme": "^1.1.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==", - "dev": true + "@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.1.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-1.1.0.tgz", + "integrity": "sha512-+HWW38ZaM2UBPu4+7QCusLDSf4tFT31rsEXHkTkxYSg/QpDivfPx6YDz4OmYtafmhPR1d1YjqB3MYysUHdodyw==", + "dev": true, + "requires": { + "tslib": "^1.9.3" + } + }, + "@material/elevation": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-1.1.0.tgz", + "integrity": "sha512-m4eATJvDhWK1BT+yA1iHz5mhAk8cV9olC4mjVzm4PTAqhDH2yya4WzjN1HPVHE/a65ObyZ7V4qopxu9MRocm3A==", + "dev": true, + "requires": { + "@material/animation": "^1.0.0", + "@material/feature-targeting": "^0.44.1", + "@material/theme": "^1.1.0" + } }, "@material/ripple": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-0.41.0.tgz", - "integrity": "sha512-rxEUVWM4AByDlTCH0kkthZQmUuY6eeN0X6cOHBoioFN2vUDk0D0Nfzz/N9FF2AlAf8C2lDDLrTuqnJPVIn+NHA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-1.1.0.tgz", + "integrity": "sha512-mkfDBZAmxjpRG7V9TrfOmLxt1g/wvGHCXtYPgvH7W8ozjf53edqxLOFENEdvHbie27y9nyixzXn0gzU0HnxSeA==", "dev": true, "requires": { - "@material/animation": "^0.41.0", - "@material/base": "^0.41.0", - "@material/theme": "^0.41.0" + "@material/animation": "^1.0.0", + "@material/base": "^1.0.0", + "@material/dom": "^1.1.0", + "@material/feature-targeting": "^0.44.1", + "@material/theme": "^1.1.0", + "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/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.1.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-1.1.0.tgz", + "integrity": "sha512-YYUV9Rhbx4r/EMb/zoOYJUWjhXChNaLlH1rqt3vpNVyxRcxGqoVMGp5u1XALBCFiD9dACPKLIkKyRYa928nmPQ==", + "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" } }, "@material/typography": { diff --git a/package.json b/package.json index 28920d006..ffe4c2234 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@material/tab-indicator": "^1.0.0", "@material/tab-scroller": "^1.0.0", "@material/textfield": "^0.41.0", - "@material/top-app-bar": "^0.41.0", + "@material/top-app-bar": "^1.1.0", "@material/typography": "^1.0.0", "@types/chai": "^4.1.7", "@types/classnames": "^2.2.6", diff --git a/packages/top-app-bar/index.tsx b/packages/top-app-bar/index.tsx index e915c3954..d108d857c 100644 --- a/packages/top-app-bar/index.tsx +++ b/packages/top-app-bar/index.tsx @@ -28,12 +28,11 @@ import TopAppBarRow from './Row'; import TopAppBarTitle from './Title'; import TopAppBarIcon from './Icon'; import {cssClasses} from './constants'; -import { - MDCFixedTopAppBarFoundation, - MDCTopAppBarFoundation, - MDCShortTopAppBarFoundation, -// @ts-ignore no .d.ts file -} from '@material/top-app-bar/dist/mdc.topAppBar'; +import {MDCFixedTopAppBarFoundation} from '@material/top-app-bar/fixed/foundation'; +import {MDCTopAppBarAdapter} from '@material/top-app-bar/adapter'; +import {MDCTopAppBarFoundation} from '@material/top-app-bar/standard/foundation'; +import {MDCShortTopAppBarFoundation} from '@material/top-app-bar/short/foundation'; +import {SpecificEventListener} from '@material/base/types'; export type MDCTopAppBarFoundationTypes = MDCFixedTopAppBarFoundation | MDCTopAppBarFoundation | MDCShortTopAppBarFoundation; @@ -57,6 +56,7 @@ export interface TopAppBarProps extends React.HTMLProps, DeprecatedProps { style?: React.CSSProperties; scrollTarget?: React.RefObject; tag?: string; + onNavIconClicked?: () => void; } interface TopAppBarState { @@ -72,7 +72,7 @@ class TopAppBar extends React.Compon TopAppBarState > { topAppBarElement: React.RefObject = React.createRef(); - foundation?: MDCTopAppBarFoundationTypes; + foundation!: MDCTopAppBarFoundationTypes; state: TopAppBarState = { classList: new Set(), @@ -171,7 +171,7 @@ class TopAppBar extends React.Compon return Object.assign({}, style, this.props.style); }; - get adapter() { + get adapter(): MDCTopAppBarAdapter { return { addClass: (className: string) => this.setState({classList: this.state.classList.add(className)}), @@ -192,14 +192,14 @@ class TopAppBar extends React.Compon } return 0; }, - registerScrollHandler: (handler: EventListener) => { + registerScrollHandler: (handler: SpecificEventListener<'scroll'>) => { if (this.state.scrollTarget && this.state.scrollTarget.current) { this.state.scrollTarget.current.addEventListener('scroll', handler); } else { window.addEventListener('scroll', handler); } }, - deregisterScrollHandler: (handler: EventListener) => { + deregisterScrollHandler: (handler: SpecificEventListener<'scroll'>) => { if (this.state.scrollTarget && this.state.scrollTarget.current) { this.state.scrollTarget.current.removeEventListener('scroll', handler); } else { @@ -219,6 +219,21 @@ class TopAppBar extends React.Compon } return 0; }, + registerResizeHandler: (handler: SpecificEventListener<'resize'>) => { + window.addEventListener('resize', handler); + }, + deregisterResizeHandler: (handler: SpecificEventListener<'resize'>) => { + window.removeEventListener('resize', handler); + }, + // onClick handler of navigation bar is used instead + // see https://github.com/material-components/material-components-web/issues/2813 + registerNavigationIconInteractionHandler: () => null, + deregisterNavigationIconInteractionHandler: () => null, + notifyNavigationIconClicked: () => { + if (this.props.onNavIconClicked) { + this.props.onNavIconClicked(); + } + }, }; } diff --git a/packages/top-app-bar/package.json b/packages/top-app-bar/package.json index df5ec6b6c..d0314f1da 100644 --- a/packages/top-app-bar/package.json +++ b/packages/top-app-bar/package.json @@ -14,7 +14,7 @@ ], "dependencies": { "@material/react-ripple": "^0.9.0", - "@material/top-app-bar": "^0.44.0", + "@material/top-app-bar": "^1.1.0", "classnames": "^2.2.6", "react": "^16.4.2" }, diff --git a/test/unit/top-app-bar/index.test.tsx b/test/unit/top-app-bar/index.test.tsx index 2e7c6947d..c80475f32 100644 --- a/test/unit/top-app-bar/index.test.tsx +++ b/test/unit/top-app-bar/index.test.tsx @@ -158,7 +158,7 @@ test('Updating scrollTarget prop will call foundation method destroyScrollHandle const wrapper = mount(); const topAppBar: TopAppBar = coerceForTesting(wrapper.find('TopAppBar').instance()); const foundation = topAppBar.foundation; - foundation.destroyScrollHandler = td.func(); + foundation.destroyScrollHandler = td.func<() => void>(); wrapper.instance().withRef(); td.verify(foundation.destroyScrollHandler(), {times: 1}); @@ -168,7 +168,7 @@ test('Updating scrollTarget prop will call foundation method initScrollHandler', const wrapper = mount(); const topAppBar: TopAppBar = coerceForTesting(wrapper.find('TopAppBar').instance()); const foundation = topAppBar.foundation; - foundation.initScrollHandler = td.func(); + foundation.initScrollHandler = td.func<() => void>(); wrapper.instance().withRef(); td.verify(foundation.initScrollHandler(), {times: 1}); @@ -245,6 +245,28 @@ test( } ); +test('#adapter.registerResizeHandler triggers handler on window resize', () => { + const wrapper = shallow(); + const testHandler = coerceForTesting(td.func()); + wrapper.instance().adapter.registerResizeHandler(testHandler); + const event = new Event('resize'); + window.dispatchEvent(event); + td.verify(testHandler(event), {times: 1}); +}); + +test( + '#adapter.registerResizeHandler does not trigger handler ' + + 'after deregistering scroll handler on window', + () => { + const wrapper = shallow(); + const testHandler = coerceForTesting(td.func()); + wrapper.instance().adapter.registerResizeHandler(testHandler); + const event = new Event('resize'); + wrapper.instance().adapter.deregisterResizeHandler(testHandler); + window.dispatchEvent(event); + td.verify(testHandler(event), {times: 0}); + } +); test('#adapter.getTotalActionItems returns one with one actionItem passed', () => { const wrapper = mount( @@ -413,7 +435,7 @@ test( 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()); });