From ad43639a906175f48f5bd273eed2509cd1a8ce7f Mon Sep 17 00:00:00 2001 From: cvanem Date: Mon, 29 Apr 2019 18:48:56 -0600 Subject: [PATCH 01/32] [AppBar] Hide an Elevate on Scroll --- docs/src/modules/components/DemoFrame.js | 2 + docs/src/pages/demos/app-bar/ElevateAppBar.js | 141 ++++++++++++++++++ .../app-bar/ElevateAppBarScrollContainer.js | 135 +++++++++++++++++ docs/src/pages/demos/app-bar/HideAppBar.js | 127 ++++++++++++++++ docs/src/pages/demos/app-bar/app-bar.md | 18 +++ packages/material-ui/src/AppBar/AppBar.d.ts | 1 + packages/material-ui/src/AppBar/AppBar.js | 7 +- .../src/useScrollTrigger/index.d.ts | 1 + .../material-ui/src/useScrollTrigger/index.js | 1 + .../useScrollTrigger/useScrollTrigger.d.ts | 13 ++ .../src/useScrollTrigger/useScrollTrigger.js | 45 ++++++ .../useScrollTrigger/useScrollTrigger.test.js | 44 ++++++ pages/api/app-bar.md | 1 + 13 files changed, 535 insertions(+), 1 deletion(-) create mode 100644 docs/src/pages/demos/app-bar/ElevateAppBar.js create mode 100644 docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js create mode 100644 docs/src/pages/demos/app-bar/HideAppBar.js create mode 100644 packages/material-ui/src/useScrollTrigger/index.d.ts create mode 100644 packages/material-ui/src/useScrollTrigger/index.js create mode 100644 packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts create mode 100644 packages/material-ui/src/useScrollTrigger/useScrollTrigger.js create mode 100644 packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js diff --git a/docs/src/modules/components/DemoFrame.js b/docs/src/modules/components/DemoFrame.js index bb460dba3c1a2a..6a074f8b9095c3 100644 --- a/docs/src/modules/components/DemoFrame.js +++ b/docs/src/modules/components/DemoFrame.js @@ -36,6 +36,7 @@ class DemoFrame extends React.Component { }), sheetsManager: new Map(), container: this.contentDocument.body, + window: () => this.contentWindow, }); }; @@ -60,6 +61,7 @@ class DemoFrame extends React.Component { {React.cloneElement(children, { container: this.state.container, + window: this.state.window, })} ) : null} diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js new file mode 100644 index 00000000000000..fe756a14e4ef31 --- /dev/null +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -0,0 +1,141 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import { styles } from '@material-ui/core/AppBar/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; +import PropTypes from 'prop-types'; + +// Create the transition class for the associated elevation +// Since ElevationScroll overrides the className property, we need to include root and positionFixed here as well +const useElevationStyles = makeStyles(theme => { + const classes = styles(theme); + return { + elevationX: { + ...classes.root, + ...classes.positionFixed, + boxShadow: props => theme.shadows[props.elevation], + background: theme.palette.background.default, + transition: theme.transitions.create('box-shadow', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + }; +}); + +function ElevationScroll(props) { + const { children, elevation = 4, trigger } = props; + return React.cloneElement(children, { + PaperProps: { + elevation: trigger ? elevation : 0, + className: useElevationStyles().elevationX, + }, + }); +} + +const useStyles = makeStyles({ + root: { + flexGrow: 1, + }, +}); + +function ElevateAppBar(props) { + const classes = useStyles(); + const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); + + // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. + // This is only being set here because the demo is in an iframe + const { window } = props; + React.useEffect(() => { + setRef(window); + }, [setRef, window]); + + return ( +
+ + + + Scroll to Elevate App Bar + + + + + + + {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into`} + + +
+ ); +} + +ElevateAppBar.propTypes = { + window: PropTypes.func, +}; + +export default ElevateAppBar; diff --git a/docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js b/docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js new file mode 100644 index 00000000000000..2402b5b4064fbc --- /dev/null +++ b/docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js @@ -0,0 +1,135 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import { styles } from '@material-ui/core/AppBar/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; + +// Create the transition class for the associated elevation +// Since ElevationScroll overrides the className property, we need to include root and positionFixed here as well +const useElevationStyles = makeStyles(theme => { + const classes = styles(theme); + return { + elevationX: { + ...classes.root, + ...classes.positionFixed, + boxShadow: props => theme.shadows[props.elevation], + background: theme.palette.background.default, + transition: theme.transitions.create('box-shadow', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + }; +}); + +function ElevationScroll(props) { + const { children, elevation = 4, trigger } = props; + return React.cloneElement(children, { + PaperProps: { + elevation: trigger ? elevation : 0, + className: useElevationStyles().elevationX, + }, + }); +} + +const useStyles = makeStyles(theme => ({ + root: { + flexGrow: 1, + background: theme.palette.background.default, + }, + container: { + maxHeight: 332, + overflow: 'scroll', + overflowX: 'hidden', + }, +})); + +function ElevateAppBar() { + const classes = useStyles(); + const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); + + return ( +
+ + + + Scroll to Elevate App Bar + + + + + + + {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into`} + + +
+ ); +} + +export default ElevateAppBar; diff --git a/docs/src/pages/demos/app-bar/HideAppBar.js b/docs/src/pages/demos/app-bar/HideAppBar.js new file mode 100644 index 00000000000000..be10854b5cfb51 --- /dev/null +++ b/docs/src/pages/demos/app-bar/HideAppBar.js @@ -0,0 +1,127 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; +import { Slide } from '@material-ui/core'; +import PropTypes from 'prop-types'; + +function HideOnScroll(props) { + const { children, trigger, ...other } = props; + return ( + + {children} + + ); +} + +HideOnScroll.propTypes = { + children: PropTypes.node.isRequired, + trigger: PropTypes.bool.isRequired, +}; + +const useStyles = makeStyles({ + root: { + flexGrow: 1, + }, +}); + +function HideAppBar(props) { + const [trigger, setRef] = useScrollTrigger({ directional: true, threshold: 400 }); + const classes = useStyles(trigger); + + // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. + // This is only being set here because the demo is in an iframe + const { window } = props; + React.useEffect(() => { + setRef(window); + }, [setRef, window]); + + return ( +
+ + + + Scroll to Hide App Bar + + + + + + + {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into`} + + +
+ ); +} + +HideAppBar.propTypes = { + window: PropTypes.func, +}; + +export default HideAppBar; diff --git a/docs/src/pages/demos/app-bar/app-bar.md b/docs/src/pages/demos/app-bar/app-bar.md index d35331230c1c13..34cd763f52a533 100644 --- a/docs/src/pages/demos/app-bar/app-bar.md +++ b/docs/src/pages/demos/app-bar/app-bar.md @@ -42,3 +42,21 @@ A side searchbar. ## Bottom App Bar {{"demo": "pages/demos/app-bar/BottomAppBar.js", "iframe": true, "maxWidth": 500}} + +## Hide App Bar on scroll + +An App Bar that hides on scroll + +{{"demo": "pages/demos/app-bar/HideAppBar.js", "iframe": "true", "maxWidth": 500}} + +## Elevate App Bar on sroll + +An App Bar that elevates on scroll + +{{"demo": "pages/demos/app-bar/ElevateAppBar.js", "iframe": "true", "maxWidth": 500}} + +## Elevate App Bar on container sroll + +An App Bar that elevates on scroll of a container + +{{"demo": "pages/demos/app-bar/ElevateAppBarScrollContainer.js", "iframe": "true", "maxWidth": 500}} \ No newline at end of file diff --git a/packages/material-ui/src/AppBar/AppBar.d.ts b/packages/material-ui/src/AppBar/AppBar.d.ts index fc5f18faaa2999..4f702c07c515cf 100644 --- a/packages/material-ui/src/AppBar/AppBar.d.ts +++ b/packages/material-ui/src/AppBar/AppBar.d.ts @@ -3,6 +3,7 @@ import { PaperProps } from '../Paper'; export interface AppBarProps extends StandardProps { color?: PropTypes.Color; + PaperProps?: Partial; position?: 'fixed' | 'absolute' | 'sticky' | 'static' | 'relative'; } diff --git a/packages/material-ui/src/AppBar/AppBar.js b/packages/material-ui/src/AppBar/AppBar.js index d06b8261f7a8b3..86aa4abf208148 100644 --- a/packages/material-ui/src/AppBar/AppBar.js +++ b/packages/material-ui/src/AppBar/AppBar.js @@ -69,7 +69,7 @@ export const styles = theme => { }; const AppBar = React.forwardRef(function AppBar(props, ref) { - const { classes, className, color, position, ...other } = props; + const { classes, className, color, PaperProps, position, ...other } = props; return ( ); }); @@ -109,6 +110,10 @@ AppBar.propTypes = { * The color of the component. It supports those theme colors that make sense for this component. */ color: PropTypes.oneOf(['inherit', 'primary', 'secondary', 'default']), + /** + * Properties applied to the [`Paper`](/api/paper/) element. + */ + PaperProps: PropTypes.object, /** * The positioning type. The behavior of the different options is described * [in the MDN web docs](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning). diff --git a/packages/material-ui/src/useScrollTrigger/index.d.ts b/packages/material-ui/src/useScrollTrigger/index.d.ts new file mode 100644 index 00000000000000..e996f70c773ee6 --- /dev/null +++ b/packages/material-ui/src/useScrollTrigger/index.d.ts @@ -0,0 +1 @@ +export { default } from './useScrollTrigger'; diff --git a/packages/material-ui/src/useScrollTrigger/index.js b/packages/material-ui/src/useScrollTrigger/index.js new file mode 100644 index 00000000000000..e996f70c773ee6 --- /dev/null +++ b/packages/material-ui/src/useScrollTrigger/index.js @@ -0,0 +1 @@ +export { default } from './useScrollTrigger'; diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts new file mode 100644 index 00000000000000..dd83cb5752f549 --- /dev/null +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts @@ -0,0 +1,13 @@ +export interface defaultTriggerProps { + directional?: boolean; + threshhold?: number; +} + +export type TriggerFunc = (next: number, current: number, props?: any) => boolean; + +export interface Options { + triggerFunc?: TriggerFunc; + props?: any; +} + +export default function useScrollTrigger(options?: Options): boolean; diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js new file mode 100644 index 00000000000000..5130b8f5e24067 --- /dev/null +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -0,0 +1,45 @@ +import React from 'react'; + +function getScrollY(ref) { + if (ref && ref.pageYOffset !== undefined) { + return ref.pageYOffset; + } + if (ref && ref.scrollTop !== undefined) { + return ref.scrollTop; + } + return document !== undefined + ? (document.documentElement || document.body.parentNode || document.body).scrollTop + : 0; +} + +function defaultTrigger(next, current, props = {}) { + const { directional = true, threshold = 100 } = props; + if (directional) { + return next < current ? false : !!(next > current && next > threshold); + } + return next > threshold; +} + +const useScrollTrigger = (options = {}) => { + const { triggerFunc = defaultTrigger, ...props } = options; + const [ref, setRef] = React.useState(); + const yRef = React.useRef(); + const [trigger, setTrigger] = React.useState(false); + + const handleScroll = React.useCallback(() => { + const scrollY = getScrollY(ref); + setTrigger(triggerFunc(scrollY, yRef.current, props)); + yRef.current = scrollY; + }, [props, ref, triggerFunc]); + + React.useEffect(() => { + (ref || window).addEventListener('scroll', handleScroll); + return () => { + (ref || window).removeEventListener('scroll', handleScroll); + }; + }, [handleScroll, ref, setRef]); + + return [trigger, setRef]; +}; + +export default useScrollTrigger; diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js new file mode 100644 index 00000000000000..8553190b7c548d --- /dev/null +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -0,0 +1,44 @@ +import React from 'react'; +import { createMount } from '@material-ui/core/test-utils'; +import { assert } from 'chai'; +import { spy } from 'sinon'; +import useScrollTrigger from './useScrollTrigger'; + +describe('useScrollTrigger', () => { + let mount; + let values; + + // Only run the test on node. + // Waiting for https://github.com/facebook/react/issues/14050 + if (!/jsdom/.test(window.navigator.userAgent)) { + return; + } + + before(() => { + mount = createMount({ strict: true }); + }); + + beforeEach(() => { + values = spy(); + }); + + after(() => { + mount.cleanUp(); + }); + + describe('defaultTrigger', () => { + it('should be false by default', () => { + const ref = React.createRef(); + const text = () => ref.current.textContent; + const Test = () => { + const trigger = useScrollTrigger(); + React.useEffect(() => values(trigger)); + return {`${trigger}`}; + }; + + mount(); + assert.strictEqual(text(), 'false'); + assert.strictEqual(values.callCount, 1); + }); + }); +}); diff --git a/pages/api/app-bar.md b/pages/api/app-bar.md index 640d088586b3d8..4f57a5ee9b69e2 100644 --- a/pages/api/app-bar.md +++ b/pages/api/app-bar.md @@ -21,6 +21,7 @@ import AppBar from '@material-ui/core/AppBar'; | children * | node | | The content of the component. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | | color | enum: 'inherit' |
 'primary' |
 'secondary' |
 'default'
| 'primary' | The color of the component. It supports those theme colors that make sense for this component. | +| PaperProps | object | | Properties applied to the [`Paper`](/api/paper/) element. | | position | enum: 'fixed', 'absolute', 'sticky', 'static', 'relative'
| 'fixed' | The positioning type. The behavior of the different options is described [in the MDN web docs](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning). Note: `sticky` is not universally supported and will fall back to `static` when unavailable. | The `ref` is forwarded to the root element. From bf7653bb8f87ad65d51689e6762b6b91c0925f53 Mon Sep 17 00:00:00 2001 From: cvanem Date: Mon, 29 Apr 2019 19:58:33 -0600 Subject: [PATCH 02/32] [useSCrollTrigger] Fix test --- .../src/useScrollTrigger/useScrollTrigger.test.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index 8553190b7c548d..a9f18a749437c9 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -6,13 +6,7 @@ import useScrollTrigger from './useScrollTrigger'; describe('useScrollTrigger', () => { let mount; - let values; - - // Only run the test on node. - // Waiting for https://github.com/facebook/react/issues/14050 - if (!/jsdom/.test(window.navigator.userAgent)) { - return; - } + let values; before(() => { mount = createMount({ strict: true }); @@ -31,12 +25,12 @@ describe('useScrollTrigger', () => { const ref = React.createRef(); const text = () => ref.current.textContent; const Test = () => { - const trigger = useScrollTrigger(); + const [trigger] = useScrollTrigger(); React.useEffect(() => values(trigger)); return {`${trigger}`}; }; - mount(); + mount(); assert.strictEqual(text(), 'false'); assert.strictEqual(values.callCount, 1); }); From c03512acf0848cafac48d759de09a524a428b7f4 Mon Sep 17 00:00:00 2001 From: cvanem Date: Mon, 29 Apr 2019 20:01:05 -0600 Subject: [PATCH 03/32] [useScrollTrigger] Fix test --- .../material-ui/src/useScrollTrigger/useScrollTrigger.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index a9f18a749437c9..941685f9829b72 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -6,7 +6,7 @@ import useScrollTrigger from './useScrollTrigger'; describe('useScrollTrigger', () => { let mount; - let values; + let values; before(() => { mount = createMount({ strict: true }); @@ -30,7 +30,7 @@ describe('useScrollTrigger', () => { return {`${trigger}`}; }; - mount(); + mount(); assert.strictEqual(text(), 'false'); assert.strictEqual(values.callCount, 1); }); From 9923c32d6338c86418a083baf50471595532fd05 Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 01:11:34 -0600 Subject: [PATCH 04/32] [useScrollTrigger] Add tests and set default values --- .../src/useScrollTrigger/useScrollTrigger.js | 4 +- .../useScrollTrigger/useScrollTrigger.test.js | 230 +++++++++++++++++- 2 files changed, 228 insertions(+), 6 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index 5130b8f5e24067..072ef99a8fd1b6 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -1,6 +1,6 @@ import React from 'react'; -function getScrollY(ref) { +function getScrollY(ref = window) { if (ref && ref.pageYOffset !== undefined) { return ref.pageYOffset; } @@ -23,7 +23,7 @@ function defaultTrigger(next, current, props = {}) { const useScrollTrigger = (options = {}) => { const { triggerFunc = defaultTrigger, ...props } = options; const [ref, setRef] = React.useState(); - const yRef = React.useRef(); + const yRef = React.useRef(0); const [trigger, setTrigger] = React.useState(false); const handleScroll = React.useCallback(() => { diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index 941685f9829b72..fe850f7ce7bdb9 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -1,8 +1,16 @@ import React from 'react'; import { createMount } from '@material-ui/core/test-utils'; +import Container from '@material-ui/core/Container'; +import Box from '@material-ui/core/Box'; import { assert } from 'chai'; import { spy } from 'sinon'; import useScrollTrigger from './useScrollTrigger'; +import PropTypes from 'prop-types'; + +const dispatchScroll = (offset, ref = window) => { + ref.pageYOffset = offset; + ref.dispatchEvent(new window.Event('scroll', {})); +}; describe('useScrollTrigger', () => { let mount; @@ -20,19 +28,233 @@ describe('useScrollTrigger', () => { mount.cleanUp(); }); + const ref = React.createRef(); + const containerParent = React.createRef(); // Get the scroll container's parent + const getContainer = () => containerParent.current.children[0]; // Get the scroll container + const mountWrapper = props => mount(); // Mount using window as the scroll target + const mountWrapperWithRef = props => mount(); // Mount using a container ref instead of the default window + const text = () => ref.current.textContent; // Retrieve the trigger value + + const Test = props => { + const { useContainerRef, ...other } = props; + const [trigger, setRef] = useScrollTrigger(other); + React.useEffect(() => { + values(trigger); + }); + return ( + + {`${trigger}`} +
+ + some text here + +
+
+ ); + }; + Test.propTypes = { + useContainerRef: PropTypes.bool, + }; + describe('defaultTrigger', () => { it('should be false by default', () => { - const ref = React.createRef(); - const text = () => ref.current.textContent; - const Test = () => { + const TestDefault = () => { const [trigger] = useScrollTrigger(); React.useEffect(() => values(trigger)); return {`${trigger}`}; }; - mount(); + mount(); assert.strictEqual(text(), 'false'); assert.strictEqual(values.callCount, 1); }); + + it('should be false by default when using setRef', () => { + const TestDefaultWithRef = () => { + const [trigger, setRef] = useScrollTrigger(); + React.useEffect(() => { + values(trigger); + }); + return ( + + {`${trigger}`} + + + ); + }; + mount(); + assert.strictEqual(text(), 'false'); + }); + }); + + describe('scrollPositions', () => { + it('should trigger correctly with default threshold', () => { + mountWrapper(); + [ + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 9999, result: 'true' }, + { offset: 101, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 102, result: 'true' }, + { offset: -3, result: 'false' }, + { offset: 3, result: 'false' }, + { offset: 103, result: 'true' }, + { offset: 102, result: 'false' }, + ].forEach(test => { + dispatchScroll(test.offset); + assert.strictEqual(text(), test.result); + }); + }); + + it('should trigger correctly with custom threshold', () => { + mountWrapper({ threshold: 30 }); + [ + { offset: 100, result: 'true' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 100, result: 'true' }, + { offset: 9999, result: 'true' }, + { offset: 101, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 75, result: 'false' }, + { offset: 45, result: 'false' }, + { offset: 31, result: 'false' }, + { offset: 30, result: 'false' }, + { offset: 29, result: 'false' }, + { offset: 30, result: 'false' }, + { offset: 31, result: 'true' }, + { offset: -5, result: 'false' }, + { offset: 0, result: 'false' }, + { offset: 1, result: 'false' }, + { offset: 29, result: 'false' }, + { offset: 28, result: 'false' }, + { offset: 30, result: 'false' }, + { offset: 28, result: 'false' }, + { offset: 31, result: 'true' }, + ].forEach(test => { + dispatchScroll(test.offset); + assert.strictEqual(text(), test.result); + }); + }); + + it('should not trigger with negative direction default threshold', () => { + mountWrapper(); + dispatchScroll(300); + assert.strictEqual(text(), 'true'); + dispatchScroll(299); + assert.strictEqual(text(), 'false'); + }); + + it('should trigger with positive direction exceeding default threshold', () => { + mountWrapper(); + dispatchScroll(300); + assert.strictEqual(text(), 'true'); + dispatchScroll(299); + assert.strictEqual(text(), 'false'); + dispatchScroll(300); + assert.strictEqual(text(), 'true'); + }); + }); + + describe('scrollPositionsWithRef', () => { + it('scroll container should render', () => { + const wrapper = mountWrapperWithRef(); + const container = wrapper.find(Container); + assert.strictEqual(container.exists(), true); + }); + it('should not trigger from window scroll events', () => { + mountWrapperWithRef(); + [101, 200, 300, -10, 100, 101, 99, 200, 199, 0, 1, -1, 150].forEach(offset => { + dispatchScroll(offset); + assert.strictEqual(text(), 'false'); + }); + }); + it('should trigger above default threshold', () => { + mountWrapperWithRef(); + dispatchScroll(300, getContainer()); + assert.strictEqual(text(), 'true'); + }); + it('should have correct directional triggering threshold', () => { + mountWrapperWithRef(); + [ + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 9999, result: 'true' }, + { offset: 101, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 102, result: 'true' }, + { offset: -3, result: 'false' }, + { offset: 3, result: 'false' }, + { offset: 103, result: 'true' }, + { offset: 102, result: 'false' }, + ].forEach(test => { + dispatchScroll(test.offset, getContainer()); + assert.strictEqual(text(), test.result); + }); + }); + + it('should have correct non-directional triggering with default threshold', () => { + mountWrapperWithRef({ directional: false }); + [ + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 200, result: 'true' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 9999, result: 'true' }, + { offset: 0, result: 'false' }, + { offset: 99, result: 'false' }, + { offset: 100, result: 'false' }, + { offset: 101, result: 'true' }, + { offset: 100, result: 'false' }, + { offset: 102, result: 'true' }, + { offset: -3, result: 'false' }, + { offset: 3, result: 'false' }, + { offset: 103, result: 'true' }, + ].forEach(test => { + dispatchScroll(test.offset, getContainer()); + assert.strictEqual(text(), test.result); + }); + }); + + it('should have correct non-directional triggering with custom threshold', () => { + mountWrapperWithRef({ directional: false, threshold: 50 }); + [ + { offset: 100, result: 'true' }, + { offset: 101, result: 'true' }, + { offset: 101, result: 'true' }, + { offset: 9999, result: 'true' }, + { offset: 51, result: 'true' }, + { offset: 50, result: 'false' }, + { offset: 49, result: 'false' }, + { offset: 50, result: 'false' }, + { offset: 51, result: 'true' }, + { offset: 49, result: 'false' }, + { offset: 150, result: 'true' }, + { offset: -50, result: 'false' }, + { offset: 50, result: 'false' }, + { offset: 51, result: 'true' }, + ].forEach(test => { + dispatchScroll(test.offset, getContainer()); + assert.strictEqual(text(), test.result); + }); + }); }); }); From 1154b2a351b6d6820eb998fdacc7e0a5bba889b1 Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 01:28:14 -0600 Subject: [PATCH 05/32] [useScrollTrigger] Add test error message info --- .../src/useScrollTrigger/useScrollTrigger.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index fe850f7ce7bdb9..896d0f71f7ef09 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -110,7 +110,7 @@ describe('useScrollTrigger', () => { { offset: 102, result: 'false' }, ].forEach(test => { dispatchScroll(test.offset); - assert.strictEqual(text(), test.result); + assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); }); }); @@ -142,7 +142,7 @@ describe('useScrollTrigger', () => { { offset: 31, result: 'true' }, ].forEach(test => { dispatchScroll(test.offset); - assert.strictEqual(text(), test.result); + assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); }); }); @@ -205,7 +205,7 @@ describe('useScrollTrigger', () => { { offset: 102, result: 'false' }, ].forEach(test => { dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result); + assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); }); }); @@ -230,7 +230,7 @@ describe('useScrollTrigger', () => { { offset: 103, result: 'true' }, ].forEach(test => { dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result); + assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); }); }); @@ -253,7 +253,7 @@ describe('useScrollTrigger', () => { { offset: 51, result: 'true' }, ].forEach(test => { dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result); + assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); }); }); }); From 887ebed9d4f0c72937d9deefa9ff630e947aa00a Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 10:44:10 -0600 Subject: [PATCH 06/32] [useScrollTrigger] Add clock to tests --- .../useScrollTrigger/useScrollTrigger.test.js | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index 896d0f71f7ef09..c9bb02bfda5df4 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -3,21 +3,19 @@ import { createMount } from '@material-ui/core/test-utils'; import Container from '@material-ui/core/Container'; import Box from '@material-ui/core/Box'; import { assert } from 'chai'; -import { spy } from 'sinon'; +import { spy, useFakeTimers } from 'sinon'; import useScrollTrigger from './useScrollTrigger'; import PropTypes from 'prop-types'; -const dispatchScroll = (offset, ref = window) => { - ref.pageYOffset = offset; - ref.dispatchEvent(new window.Event('scroll', {})); -}; - describe('useScrollTrigger', () => { let mount; let values; + let clock; + const dispatchheckTime = 1000; before(() => { mount = createMount({ strict: true }); + clock = useFakeTimers(); }); beforeEach(() => { @@ -26,8 +24,15 @@ describe('useScrollTrigger', () => { after(() => { mount.cleanUp(); + clock.restore(); }); + const dispatchScroll = (offset, ref = window) => { + ref.pageYOffset = offset; + ref.dispatchEvent(new window.Event('scroll', {})); + clock.tick(dispatchheckTime); + }; + const ref = React.createRef(); const containerParent = React.createRef(); // Get the scroll container's parent const getContainer = () => containerParent.current.children[0]; // Get the scroll container @@ -108,9 +113,9 @@ describe('useScrollTrigger', () => { { offset: 3, result: 'false' }, { offset: 103, result: 'true' }, { offset: 102, result: 'false' }, - ].forEach(test => { + ].forEach((test, i) => { dispatchScroll(test.offset); - assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -140,9 +145,9 @@ describe('useScrollTrigger', () => { { offset: 30, result: 'false' }, { offset: 28, result: 'false' }, { offset: 31, result: 'true' }, - ].forEach(test => { + ].forEach((test, i) => { dispatchScroll(test.offset); - assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -173,9 +178,9 @@ describe('useScrollTrigger', () => { }); it('should not trigger from window scroll events', () => { mountWrapperWithRef(); - [101, 200, 300, -10, 100, 101, 99, 200, 199, 0, 1, -1, 150].forEach(offset => { + [101, 200, 300, -10, 100, 101, 99, 200, 199, 0, 1, -1, 150].forEach((offset, i) => { dispatchScroll(offset); - assert.strictEqual(text(), 'false'); + assert.strictEqual(text(), 'false', `Index: ${i} Offset: ${offset}`); }); }); it('should trigger above default threshold', () => { @@ -203,9 +208,9 @@ describe('useScrollTrigger', () => { { offset: 3, result: 'false' }, { offset: 103, result: 'true' }, { offset: 102, result: 'false' }, - ].forEach(test => { + ].forEach((test, i) => { dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -228,9 +233,9 @@ describe('useScrollTrigger', () => { { offset: -3, result: 'false' }, { offset: 3, result: 'false' }, { offset: 103, result: 'true' }, - ].forEach(test => { + ].forEach((test, i) => { dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -251,9 +256,9 @@ describe('useScrollTrigger', () => { { offset: -50, result: 'false' }, { offset: 50, result: 'false' }, { offset: 51, result: 'true' }, - ].forEach(test => { + ].forEach((test, i) => { dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result, `Offset: ${test.offset}`); + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); }); From c8cb13c438863e8c814e286accebd616965660aa Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 30 Apr 2019 11:09:43 -0600 Subject: [PATCH 07/32] Update docs/src/pages/demos/app-bar/app-bar.md Co-Authored-By: cvanem --- docs/src/pages/demos/app-bar/app-bar.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/demos/app-bar/app-bar.md b/docs/src/pages/demos/app-bar/app-bar.md index 34cd763f52a533..fa7438a5cdca8c 100644 --- a/docs/src/pages/demos/app-bar/app-bar.md +++ b/docs/src/pages/demos/app-bar/app-bar.md @@ -45,7 +45,7 @@ A side searchbar. ## Hide App Bar on scroll -An App Bar that hides on scroll +An App Bar that hides on scroll. {{"demo": "pages/demos/app-bar/HideAppBar.js", "iframe": "true", "maxWidth": 500}} @@ -59,4 +59,4 @@ An App Bar that elevates on scroll An App Bar that elevates on scroll of a container -{{"demo": "pages/demos/app-bar/ElevateAppBarScrollContainer.js", "iframe": "true", "maxWidth": 500}} \ No newline at end of file +{{"demo": "pages/demos/app-bar/ElevateAppBarScrollContainer.js", "iframe": "true", "maxWidth": 500}} From 7f07ba7a8b3ceea7e83a57f9effeed6636f0bde7 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 30 Apr 2019 11:09:50 -0600 Subject: [PATCH 08/32] Update docs/src/pages/demos/app-bar/app-bar.md Co-Authored-By: cvanem --- docs/src/pages/demos/app-bar/app-bar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/demos/app-bar/app-bar.md b/docs/src/pages/demos/app-bar/app-bar.md index fa7438a5cdca8c..771ec9c1be40aa 100644 --- a/docs/src/pages/demos/app-bar/app-bar.md +++ b/docs/src/pages/demos/app-bar/app-bar.md @@ -51,7 +51,7 @@ An App Bar that hides on scroll. ## Elevate App Bar on sroll -An App Bar that elevates on scroll +An App Bar that elevates on scroll. {{"demo": "pages/demos/app-bar/ElevateAppBar.js", "iframe": "true", "maxWidth": 500}} From 3340dab9886d77b7f79aafaa1b19a908ca9a2f57 Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 12:52:49 -0600 Subject: [PATCH 09/32] [Docuementation] Remove duplicate App Bar elevate demo --- .../app-bar/ElevateAppBarScrollContainer.js | 135 ------------------ docs/src/pages/demos/app-bar/app-bar.md | 5 - 2 files changed, 140 deletions(-) delete mode 100644 docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js diff --git a/docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js b/docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js deleted file mode 100644 index 2402b5b4064fbc..00000000000000 --- a/docs/src/pages/demos/app-bar/ElevateAppBarScrollContainer.js +++ /dev/null @@ -1,135 +0,0 @@ -import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; -import AppBar from '@material-ui/core/AppBar'; -import { styles } from '@material-ui/core/AppBar/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import useScrollTrigger from '@material-ui/core/useScrollTrigger'; -import Box from '@material-ui/core/Box'; -import Container from '@material-ui/core/Container'; - -// Create the transition class for the associated elevation -// Since ElevationScroll overrides the className property, we need to include root and positionFixed here as well -const useElevationStyles = makeStyles(theme => { - const classes = styles(theme); - return { - elevationX: { - ...classes.root, - ...classes.positionFixed, - boxShadow: props => theme.shadows[props.elevation], - background: theme.palette.background.default, - transition: theme.transitions.create('box-shadow', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - }; -}); - -function ElevationScroll(props) { - const { children, elevation = 4, trigger } = props; - return React.cloneElement(children, { - PaperProps: { - elevation: trigger ? elevation : 0, - className: useElevationStyles().elevationX, - }, - }); -} - -const useStyles = makeStyles(theme => ({ - root: { - flexGrow: 1, - background: theme.palette.background.default, - }, - container: { - maxHeight: 332, - overflow: 'scroll', - overflowX: 'hidden', - }, -})); - -function ElevateAppBar() { - const classes = useStyles(); - const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); - - return ( -
- - - - Scroll to Elevate App Bar - - - - - - - {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into`} - - -
- ); -} - -export default ElevateAppBar; diff --git a/docs/src/pages/demos/app-bar/app-bar.md b/docs/src/pages/demos/app-bar/app-bar.md index 771ec9c1be40aa..6d1a233c46e0bb 100644 --- a/docs/src/pages/demos/app-bar/app-bar.md +++ b/docs/src/pages/demos/app-bar/app-bar.md @@ -55,8 +55,3 @@ An App Bar that elevates on scroll. {{"demo": "pages/demos/app-bar/ElevateAppBar.js", "iframe": "true", "maxWidth": 500}} -## Elevate App Bar on container sroll - -An App Bar that elevates on scroll of a container - -{{"demo": "pages/demos/app-bar/ElevateAppBarScrollContainer.js", "iframe": "true", "maxWidth": 500}} From df3d7a3969fb8b40c4d138c3124b749b5ed3e2fe Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 16:30:54 -0600 Subject: [PATCH 10/32] [Documentiation] Remove unused props --- docs/src/pages/demos/app-bar/ElevateAppBar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js index fe756a14e4ef31..27a4afc4b97de0 100644 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.js +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -56,9 +56,9 @@ function ElevateAppBar(props) { return (
- - - + + + Scroll to Elevate App Bar From 4e2a9b185e9909a382ff151053911d157b3d84a6 Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 16:39:37 -0600 Subject: [PATCH 11/32] [Documentation] Polish comments --- docs/src/pages/demos/app-bar/ElevateAppBar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js index 27a4afc4b97de0..5ba319ea50606d 100644 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.js +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -10,7 +10,7 @@ import Container from '@material-ui/core/Container'; import PropTypes from 'prop-types'; // Create the transition class for the associated elevation -// Since ElevationScroll overrides the className property, we need to include root and positionFixed here as well +// Since ElevationScroll overrides the className property, include root and positionFixed here as well const useElevationStyles = makeStyles(theme => { const classes = styles(theme); return { @@ -47,8 +47,8 @@ function ElevateAppBar(props) { const classes = useStyles(); const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); - // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. - // This is only being set here because the demo is in an iframe + // Note that normally setRef(window) won't be needed as useScrollTrigger defaults to window. + // It is included here because the demo is in an iframe const { window } = props; React.useEffect(() => { setRef(window); From f422c68b8c216bbb9385c78b005214500ac10591 Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 19:17:09 -0600 Subject: [PATCH 12/32] [useScrollTrigger,Documentation] Update demos and prop names --- docs/src/pages/demos/app-bar/ElevateAppBar.js | 22 ++- .../src/pages/demos/app-bar/ElevateAppBar.tsx | 160 ++++++++++++++++++ docs/src/pages/demos/app-bar/HideAppBar.tsx | 126 ++++++++++++++ .../useScrollTrigger/useScrollTrigger.d.ts | 15 +- .../src/useScrollTrigger/useScrollTrigger.js | 8 +- 5 files changed, 319 insertions(+), 12 deletions(-) create mode 100644 docs/src/pages/demos/app-bar/ElevateAppBar.tsx create mode 100644 docs/src/pages/demos/app-bar/HideAppBar.tsx diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js index 5ba319ea50606d..9bc44692bb3e56 100644 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.js +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -1,7 +1,6 @@ import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import AppBar from '@material-ui/core/AppBar'; -import { styles } from '@material-ui/core/AppBar/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; import useScrollTrigger from '@material-ui/core/useScrollTrigger'; @@ -9,10 +8,29 @@ import Box from '@material-ui/core/Box'; import Container from '@material-ui/core/Container'; import PropTypes from 'prop-types'; +const appBarStyles = theme => { + return { + root: { + display: 'flex', + flexDirection: 'column', + width: '100%', + boxSizing: 'border-box', // Prevent padding issue with the Modal and fixed positioned AppBar. + zIndex: theme.zIndex.appBar, + flexShrink: 0, + }, + positionFixed: { + position: 'fixed', + top: 0, + left: 'auto', + right: 0, + }, + }; +}; + // Create the transition class for the associated elevation // Since ElevationScroll overrides the className property, include root and positionFixed here as well const useElevationStyles = makeStyles(theme => { - const classes = styles(theme); + const classes = appBarStyles(theme); return { elevationX: { ...classes.root, diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.tsx b/docs/src/pages/demos/app-bar/ElevateAppBar.tsx new file mode 100644 index 00000000000000..d56c31ed2883a4 --- /dev/null +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.tsx @@ -0,0 +1,160 @@ +import React from 'react'; +import { makeStyles, Theme } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; + +const appBarStyles = (theme: Theme) => { + return { + root: { + display: 'flex', + flexDirection: 'column', + width: '100%', + boxSizing: 'border-box', // Prevent padding issue with the Modal and fixed positioned AppBar. + zIndex: theme.zIndex.appBar, + flexShrink: 0, + }, + positionFixed: { + position: 'fixed', + top: 0, + left: 'auto', + right: 0, + }, + }; +}; + +// Create the transition class for the associated elevation +// Since ElevationScroll overrides the className property, include root and positionFixed here as well +const useElevationStyles = makeStyles((theme: Theme) => { + const classes = appBarStyles(theme); + return { + elevationX: { + ...classes.root, + ...classes.positionFixed, + boxShadow: (props: ElevationScrollProps) => theme.shadows[props.elevation as number], + background: theme.palette.background.default, + transition: theme.transitions.create('box-shadow', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + }; +}); + +function ElevationScroll(props: ElevationScrollProps) { + const { children, elevation = 4, trigger } = props; + return React.cloneElement(children, { + PaperProps: { + elevation: trigger ? elevation : 0, + className: useElevationStyles().elevationX, + }, + }); +} + +interface ElevationScrollProps { + elevation?: number; + trigger: boolean; + children?: any; +} + +const useStyles = makeStyles({ + root: { + flexGrow: 1, + }, +}); + +function ElevateAppBar(props: any) { + const classes = useStyles(); + const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); + + // Note that normally setRef(window) won't be needed as useScrollTrigger defaults to window. + // It is included here because the demo is in an iframe + const { window } = props; + React.useEffect(() => { + setRef(window); + }, [setRef, window]); + + return ( +
+ + + + Scroll to Elevate App Bar + + + + + + + {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into`} + + +
+ ); +} + +export default ElevateAppBar; diff --git a/docs/src/pages/demos/app-bar/HideAppBar.tsx b/docs/src/pages/demos/app-bar/HideAppBar.tsx new file mode 100644 index 00000000000000..34046a0bf6b0db --- /dev/null +++ b/docs/src/pages/demos/app-bar/HideAppBar.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import { createStyles, makeStyles } from '@material-ui/core/styles'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; +import { Slide, Theme } from '@material-ui/core'; +import { SlideProps } from '@material-ui/core/Slide'; + +function HideOnScroll(props: HideOnScrollProps) { + const { children, trigger, ...other } = props; + return ( + + {children} + + ); +} + +interface HideOnScrollProps { + trigger: boolean; + other?: SlideProps; + children?: any; +} + +const useStyles = makeStyles( + createStyles({ + root: { + flexGrow: 1, + }, + }), +); + +function HideAppBar(props: any) { + const [trigger, setRef] = useScrollTrigger({ directional: true, threshold: 400 }); + const classes = useStyles(trigger); + + // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. + // This is only being set here because the demo is in an iframe + const { window } = props; + React.useEffect(() => { + setRef(window); + }, [setRef, window]); + + return ( +
+ + + + Scroll to Hide App Bar + + + + + + + {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into + electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s + with the release of Letraset sheets containing Lorem Ipsum passages, and more recently + with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. + Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has + been the industry's standard dummy text ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. It has survived not only + five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus + PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the + printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took a galley of type and scrambled it to + make a type specimen book. It has survived not only five centuries, but also the leap into`} + + +
+ ); +} + +export default HideAppBar; diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts index dd83cb5752f549..a923bfe00daf08 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts @@ -1,13 +1,16 @@ -export interface defaultTriggerProps { +export interface DefaultTriggerProps { directional?: boolean; threshhold?: number; } -export type TriggerFunc = (next: number, current: number, props?: any) => boolean; +export type TriggerProps = DefaultTriggerProps & any; -export interface Options { +export type TriggerFunc = (next: number, current: number, props?: TriggerProps) => boolean; + +export type UseScrollTriggerProps = { triggerFunc?: TriggerFunc; - props?: any; -} +} & TriggerProps; -export default function useScrollTrigger(options?: Options): boolean; +export default function useScrollTrigger( + props?: UseScrollTriggerProps, +): [boolean, (ref: any) => void]; diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index 072ef99a8fd1b6..9fcb76a83e33e4 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -20,17 +20,17 @@ function defaultTrigger(next, current, props = {}) { return next > threshold; } -const useScrollTrigger = (options = {}) => { - const { triggerFunc = defaultTrigger, ...props } = options; +const useScrollTrigger = (props = {}) => { + const { triggerFunc = defaultTrigger, ...triggerProps } = props; const [ref, setRef] = React.useState(); const yRef = React.useRef(0); const [trigger, setTrigger] = React.useState(false); const handleScroll = React.useCallback(() => { const scrollY = getScrollY(ref); - setTrigger(triggerFunc(scrollY, yRef.current, props)); + setTrigger(triggerFunc(scrollY, yRef.current, triggerProps)); yRef.current = scrollY; - }, [props, ref, triggerFunc]); + }, [triggerProps, ref, triggerFunc]); React.useEffect(() => { (ref || window).addEventListener('scroll', handleScroll); From a31a1a5c4b5f9da00744661070fbb41c3358274f Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 19:53:16 -0600 Subject: [PATCH 13/32] Remove typescript demos --- .../src/pages/demos/app-bar/ElevateAppBar.tsx | 160 ------------------ docs/src/pages/demos/app-bar/HideAppBar.tsx | 126 -------------- 2 files changed, 286 deletions(-) delete mode 100644 docs/src/pages/demos/app-bar/ElevateAppBar.tsx delete mode 100644 docs/src/pages/demos/app-bar/HideAppBar.tsx diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.tsx b/docs/src/pages/demos/app-bar/ElevateAppBar.tsx deleted file mode 100644 index d56c31ed2883a4..00000000000000 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import React from 'react'; -import { makeStyles, Theme } from '@material-ui/core/styles'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import useScrollTrigger from '@material-ui/core/useScrollTrigger'; -import Box from '@material-ui/core/Box'; -import Container from '@material-ui/core/Container'; - -const appBarStyles = (theme: Theme) => { - return { - root: { - display: 'flex', - flexDirection: 'column', - width: '100%', - boxSizing: 'border-box', // Prevent padding issue with the Modal and fixed positioned AppBar. - zIndex: theme.zIndex.appBar, - flexShrink: 0, - }, - positionFixed: { - position: 'fixed', - top: 0, - left: 'auto', - right: 0, - }, - }; -}; - -// Create the transition class for the associated elevation -// Since ElevationScroll overrides the className property, include root and positionFixed here as well -const useElevationStyles = makeStyles((theme: Theme) => { - const classes = appBarStyles(theme); - return { - elevationX: { - ...classes.root, - ...classes.positionFixed, - boxShadow: (props: ElevationScrollProps) => theme.shadows[props.elevation as number], - background: theme.palette.background.default, - transition: theme.transitions.create('box-shadow', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - }; -}); - -function ElevationScroll(props: ElevationScrollProps) { - const { children, elevation = 4, trigger } = props; - return React.cloneElement(children, { - PaperProps: { - elevation: trigger ? elevation : 0, - className: useElevationStyles().elevationX, - }, - }); -} - -interface ElevationScrollProps { - elevation?: number; - trigger: boolean; - children?: any; -} - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - }, -}); - -function ElevateAppBar(props: any) { - const classes = useStyles(); - const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); - - // Note that normally setRef(window) won't be needed as useScrollTrigger defaults to window. - // It is included here because the demo is in an iframe - const { window } = props; - React.useEffect(() => { - setRef(window); - }, [setRef, window]); - - return ( -
- - - - Scroll to Elevate App Bar - - - - - - - {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into`} - - -
- ); -} - -export default ElevateAppBar; diff --git a/docs/src/pages/demos/app-bar/HideAppBar.tsx b/docs/src/pages/demos/app-bar/HideAppBar.tsx deleted file mode 100644 index 34046a0bf6b0db..00000000000000 --- a/docs/src/pages/demos/app-bar/HideAppBar.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React from 'react'; -import { createStyles, makeStyles } from '@material-ui/core/styles'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import useScrollTrigger from '@material-ui/core/useScrollTrigger'; -import Box from '@material-ui/core/Box'; -import Container from '@material-ui/core/Container'; -import { Slide, Theme } from '@material-ui/core'; -import { SlideProps } from '@material-ui/core/Slide'; - -function HideOnScroll(props: HideOnScrollProps) { - const { children, trigger, ...other } = props; - return ( - - {children} - - ); -} - -interface HideOnScrollProps { - trigger: boolean; - other?: SlideProps; - children?: any; -} - -const useStyles = makeStyles( - createStyles({ - root: { - flexGrow: 1, - }, - }), -); - -function HideAppBar(props: any) { - const [trigger, setRef] = useScrollTrigger({ directional: true, threshold: 400 }); - const classes = useStyles(trigger); - - // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. - // This is only being set here because the demo is in an iframe - const { window } = props; - React.useEffect(() => { - setRef(window); - }, [setRef, window]); - - return ( -
- - - - Scroll to Hide App Bar - - - - - - - {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into`} - - -
- ); -} - -export default HideAppBar; From 7bef4e3478c490863d02047de8ede933bc8f34d3 Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 22:49:56 -0600 Subject: [PATCH 14/32] [AppBar] Revert PaperProps property addition --- docs/src/pages/demos/app-bar/ElevateAppBar.js | 32 ++----------------- packages/material-ui/src/AppBar/AppBar.js | 7 +--- .../useScrollTrigger/useScrollTrigger.test.js | 9 ++---- 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js index 9bc44692bb3e56..4e0742eee0d7b0 100644 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.js +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -8,35 +8,11 @@ import Box from '@material-ui/core/Box'; import Container from '@material-ui/core/Container'; import PropTypes from 'prop-types'; -const appBarStyles = theme => { - return { - root: { - display: 'flex', - flexDirection: 'column', - width: '100%', - boxSizing: 'border-box', // Prevent padding issue with the Modal and fixed positioned AppBar. - zIndex: theme.zIndex.appBar, - flexShrink: 0, - }, - positionFixed: { - position: 'fixed', - top: 0, - left: 'auto', - right: 0, - }, - }; -}; - // Create the transition class for the associated elevation -// Since ElevationScroll overrides the className property, include root and positionFixed here as well const useElevationStyles = makeStyles(theme => { - const classes = appBarStyles(theme); return { elevationX: { - ...classes.root, - ...classes.positionFixed, boxShadow: props => theme.shadows[props.elevation], - background: theme.palette.background.default, transition: theme.transitions.create('box-shadow', { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.enteringScreen, @@ -48,10 +24,8 @@ const useElevationStyles = makeStyles(theme => { function ElevationScroll(props) { const { children, elevation = 4, trigger } = props; return React.cloneElement(children, { - PaperProps: { - elevation: trigger ? elevation : 0, - className: useElevationStyles().elevationX, - }, + className: useElevationStyles().elevationX, + elevation: trigger ? elevation : 0, }); } @@ -65,7 +39,7 @@ function ElevateAppBar(props) { const classes = useStyles(); const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); - // Note that normally setRef(window) won't be needed as useScrollTrigger defaults to window. + // Normally setRef(window) won't be needed as useScrollTrigger defaults to window. // It is included here because the demo is in an iframe const { window } = props; React.useEffect(() => { diff --git a/packages/material-ui/src/AppBar/AppBar.js b/packages/material-ui/src/AppBar/AppBar.js index 86aa4abf208148..d06b8261f7a8b3 100644 --- a/packages/material-ui/src/AppBar/AppBar.js +++ b/packages/material-ui/src/AppBar/AppBar.js @@ -69,7 +69,7 @@ export const styles = theme => { }; const AppBar = React.forwardRef(function AppBar(props, ref) { - const { classes, className, color, PaperProps, position, ...other } = props; + const { classes, className, color, position, ...other } = props; return ( ); }); @@ -110,10 +109,6 @@ AppBar.propTypes = { * The color of the component. It supports those theme colors that make sense for this component. */ color: PropTypes.oneOf(['inherit', 'primary', 'secondary', 'default']), - /** - * Properties applied to the [`Paper`](/api/paper/) element. - */ - PaperProps: PropTypes.object, /** * The positioning type. The behavior of the different options is described * [in the MDN web docs](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning). diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index c9bb02bfda5df4..de1de269c0c312 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -3,19 +3,16 @@ import { createMount } from '@material-ui/core/test-utils'; import Container from '@material-ui/core/Container'; import Box from '@material-ui/core/Box'; import { assert } from 'chai'; -import { spy, useFakeTimers } from 'sinon'; +import { spy } from 'sinon'; import useScrollTrigger from './useScrollTrigger'; import PropTypes from 'prop-types'; describe('useScrollTrigger', () => { let mount; let values; - let clock; - const dispatchheckTime = 1000; before(() => { mount = createMount({ strict: true }); - clock = useFakeTimers(); }); beforeEach(() => { @@ -24,13 +21,11 @@ describe('useScrollTrigger', () => { after(() => { mount.cleanUp(); - clock.restore(); }); const dispatchScroll = (offset, ref = window) => { ref.pageYOffset = offset; ref.dispatchEvent(new window.Event('scroll', {})); - clock.tick(dispatchheckTime); }; const ref = React.createRef(); @@ -97,7 +92,7 @@ describe('useScrollTrigger', () => { mountWrapper(); [ { offset: 100, result: 'false' }, - { offset: 101, result: 'true' }, + { offset: 201, result: 'true' }, { offset: 100, result: 'false' }, { offset: 99, result: 'false' }, { offset: 100, result: 'false' }, From a288a790d7e359de04618dfce42056630b36ddea Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 22:53:19 -0600 Subject: [PATCH 15/32] [AppBar] Revert typescript PaperProp changes --- packages/material-ui/src/AppBar/AppBar.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/material-ui/src/AppBar/AppBar.d.ts b/packages/material-ui/src/AppBar/AppBar.d.ts index 4f702c07c515cf..fc5f18faaa2999 100644 --- a/packages/material-ui/src/AppBar/AppBar.d.ts +++ b/packages/material-ui/src/AppBar/AppBar.d.ts @@ -3,7 +3,6 @@ import { PaperProps } from '../Paper'; export interface AppBarProps extends StandardProps { color?: PropTypes.Color; - PaperProps?: Partial; position?: 'fixed' | 'absolute' | 'sticky' | 'static' | 'relative'; } From 8bb2338ca667fe0f0d042d32aec57be9d7ec529b Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 22:57:54 -0600 Subject: [PATCH 16/32] [Documentation] Revert PaperProps changes --- pages/api/app-bar.md | 1 - 1 file changed, 1 deletion(-) diff --git a/pages/api/app-bar.md b/pages/api/app-bar.md index 4f57a5ee9b69e2..640d088586b3d8 100644 --- a/pages/api/app-bar.md +++ b/pages/api/app-bar.md @@ -21,7 +21,6 @@ import AppBar from '@material-ui/core/AppBar'; | children * | node | | The content of the component. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | | color | enum: 'inherit' |
 'primary' |
 'secondary' |
 'default'
| 'primary' | The color of the component. It supports those theme colors that make sense for this component. | -| PaperProps | object | | Properties applied to the [`Paper`](/api/paper/) element. | | position | enum: 'fixed', 'absolute', 'sticky', 'static', 'relative'
| 'fixed' | The positioning type. The behavior of the different options is described [in the MDN web docs](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning). Note: `sticky` is not universally supported and will fall back to `static` when unavailable. | The `ref` is forwarded to the root element. From 26c8e35e925a7bd5386c30d048c4f3a30b0e17de Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 23:29:47 -0600 Subject: [PATCH 17/32] [useScrollTrigger] Fixing tests --- .../material-ui/src/useScrollTrigger/useScrollTrigger.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index 9fcb76a83e33e4..7ed3db496a015d 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -1,13 +1,13 @@ import React from 'react'; function getScrollY(ref = window) { - if (ref && ref.pageYOffset !== undefined) { + if (ref && ref.pageYOffset !== undefined && ref.pageYOffset !== null) { return ref.pageYOffset; } - if (ref && ref.scrollTop !== undefined) { + if (ref && ref.scrollTop !== undefined && ref.pageYOffset !== null) { return ref.scrollTop; } - return document !== undefined + return document ? (document.documentElement || document.body.parentNode || document.body).scrollTop : 0; } From fdb4c276152fdc1c054bfdb54e1da25cbd9ef45f Mon Sep 17 00:00:00 2001 From: cvanem Date: Tue, 30 Apr 2019 23:44:29 -0600 Subject: [PATCH 18/32] Tests --- .../material-ui/src/useScrollTrigger/useScrollTrigger.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index de1de269c0c312..20b67a60eae0f8 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -25,6 +25,7 @@ describe('useScrollTrigger', () => { const dispatchScroll = (offset, ref = window) => { ref.pageYOffset = offset; + assert.strictEqual(ref.pageYOffset, offset, 'Failed to set ref.pageYOffset'); ref.dispatchEvent(new window.Event('scroll', {})); }; From 5809e8e5ce05706cbf982a20281de457ceacc95e Mon Sep 17 00:00:00 2001 From: cvanem Date: Wed, 1 May 2019 00:08:58 -0600 Subject: [PATCH 19/32] [useScrollTrigger] Filter Chrome OS X browser tests --- .../src/useScrollTrigger/useScrollTrigger.js | 4 +- .../useScrollTrigger/useScrollTrigger.test.js | 44 ++++++++----------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index 7ed3db496a015d..cae10cebf116fd 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -1,10 +1,10 @@ import React from 'react'; function getScrollY(ref = window) { - if (ref && ref.pageYOffset !== undefined && ref.pageYOffset !== null) { + if (ref && ref.pageYOffset !== undefined) { return ref.pageYOffset; } - if (ref && ref.scrollTop !== undefined && ref.pageYOffset !== null) { + if (ref && ref.scrollTop !== undefined) { return ref.scrollTop; } return document diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js index 20b67a60eae0f8..9ed2309066e5fe 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.test.js @@ -25,8 +25,8 @@ describe('useScrollTrigger', () => { const dispatchScroll = (offset, ref = window) => { ref.pageYOffset = offset; - assert.strictEqual(ref.pageYOffset, offset, 'Failed to set ref.pageYOffset'); ref.dispatchEvent(new window.Event('scroll', {})); + return ref.pageYoffset === offset; // The Chrome Browser on Mac OS X fails to set pageYOffset, so do not test the result if pageYoffset was not set }; const ref = React.createRef(); @@ -110,8 +110,8 @@ describe('useScrollTrigger', () => { { offset: 103, result: 'true' }, { offset: 102, result: 'false' }, ].forEach((test, i) => { - dispatchScroll(test.offset); - assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); + if (dispatchScroll(test.offset)) + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -142,27 +142,22 @@ describe('useScrollTrigger', () => { { offset: 28, result: 'false' }, { offset: 31, result: 'true' }, ].forEach((test, i) => { - dispatchScroll(test.offset); - assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); + if (dispatchScroll(test.offset)) + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); it('should not trigger with negative direction default threshold', () => { mountWrapper(); - dispatchScroll(300); - assert.strictEqual(text(), 'true'); - dispatchScroll(299); - assert.strictEqual(text(), 'false'); + if (dispatchScroll(300)) assert.strictEqual(text(), 'true'); + if (dispatchScroll(299)) assert.strictEqual(text(), 'false'); }); it('should trigger with positive direction exceeding default threshold', () => { mountWrapper(); - dispatchScroll(300); - assert.strictEqual(text(), 'true'); - dispatchScroll(299); - assert.strictEqual(text(), 'false'); - dispatchScroll(300); - assert.strictEqual(text(), 'true'); + if (dispatchScroll(300)) assert.strictEqual(text(), 'true'); + if (dispatchScroll(299)) assert.strictEqual(text(), 'false'); + if (dispatchScroll(300)) assert.strictEqual(text(), 'true'); }); }); @@ -175,14 +170,13 @@ describe('useScrollTrigger', () => { it('should not trigger from window scroll events', () => { mountWrapperWithRef(); [101, 200, 300, -10, 100, 101, 99, 200, 199, 0, 1, -1, 150].forEach((offset, i) => { - dispatchScroll(offset); - assert.strictEqual(text(), 'false', `Index: ${i} Offset: ${offset}`); + if (dispatchScroll(offset)) + assert.strictEqual(text(), 'false', `Index: ${i} Offset: ${offset}`); }); }); it('should trigger above default threshold', () => { mountWrapperWithRef(); - dispatchScroll(300, getContainer()); - assert.strictEqual(text(), 'true'); + if (dispatchScroll(300, getContainer())) assert.strictEqual(text(), 'true'); }); it('should have correct directional triggering threshold', () => { mountWrapperWithRef(); @@ -205,8 +199,8 @@ describe('useScrollTrigger', () => { { offset: 103, result: 'true' }, { offset: 102, result: 'false' }, ].forEach((test, i) => { - dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); + if (dispatchScroll(test.offset, getContainer())) + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -230,8 +224,8 @@ describe('useScrollTrigger', () => { { offset: 3, result: 'false' }, { offset: 103, result: 'true' }, ].forEach((test, i) => { - dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); + if (dispatchScroll(test.offset, getContainer())) + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); @@ -253,8 +247,8 @@ describe('useScrollTrigger', () => { { offset: 50, result: 'false' }, { offset: 51, result: 'true' }, ].forEach((test, i) => { - dispatchScroll(test.offset, getContainer()); - assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); + if (dispatchScroll(test.offset, getContainer())) + assert.strictEqual(text(), test.result, `Index: ${i} ${JSON.stringify(test)}`); }); }); }); From 40d5e463bedbca1629594937fa1fbc7b3d96120e Mon Sep 17 00:00:00 2001 From: cvanem Date: Wed, 1 May 2019 11:43:44 -0600 Subject: [PATCH 20/32] [useScrollTrigger] Seperate onTrigger event --- docs/src/pages/demos/app-bar/ElevateAppBar.js | 8 ++--- docs/src/pages/demos/app-bar/HideAppBar.js | 6 ++-- .../useScrollTrigger/useScrollTrigger.d.ts | 8 +++-- .../src/useScrollTrigger/useScrollTrigger.js | 33 ++++++++++--------- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js index 4e0742eee0d7b0..2ec38e0bb9a595 100644 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.js +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -37,14 +37,14 @@ const useStyles = makeStyles({ function ElevateAppBar(props) { const classes = useStyles(); - const [trigger, setRef] = useScrollTrigger({ directional: false, threshold: 100 }); + const [trigger, setTarget] = useScrollTrigger({ directional: false, threshold: 100 }); - // Normally setRef(window) won't be needed as useScrollTrigger defaults to window. + // Normally setTarget(window) won't be needed as useScrollTrigger defaults to window. // It is included here because the demo is in an iframe const { window } = props; React.useEffect(() => { - setRef(window); - }, [setRef, window]); + setTarget(window); + }, [setTarget, window]); return (
diff --git a/docs/src/pages/demos/app-bar/HideAppBar.js b/docs/src/pages/demos/app-bar/HideAppBar.js index be10854b5cfb51..4a6f1d0a9e5309 100644 --- a/docs/src/pages/demos/app-bar/HideAppBar.js +++ b/docs/src/pages/demos/app-bar/HideAppBar.js @@ -30,15 +30,15 @@ const useStyles = makeStyles({ }); function HideAppBar(props) { - const [trigger, setRef] = useScrollTrigger({ directional: true, threshold: 400 }); + const [trigger, setTarget] = useScrollTrigger({ directional: true, threshold: 400 }); const classes = useStyles(trigger); // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. // This is only being set here because the demo is in an iframe const { window } = props; React.useEffect(() => { - setRef(window); - }, [setRef, window]); + setTarget(window); + }, [setTarget, window]); return (
diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts index a923bfe00daf08..e22cd6847a0eef 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts @@ -5,10 +5,14 @@ export interface DefaultTriggerProps { export type TriggerProps = DefaultTriggerProps & any; -export type TriggerFunc = (next: number, current: number, props?: TriggerProps) => boolean; +export type OnTrigger = ( + event: Event, + value: React.MutableRefObject, + props?: TriggerProps, +) => boolean; export type UseScrollTriggerProps = { - triggerFunc?: TriggerFunc; + onTrigger?: OnTrigger; } & TriggerProps; export default function useScrollTrigger( diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index cae10cebf116fd..b772124a5edb43 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -12,34 +12,37 @@ function getScrollY(ref = window) { : 0; } -function defaultTrigger(next, current, props = {}) { +function defaultTrigger(event, value, props = {}) { const { directional = true, threshold = 100 } = props; + const scrollY = getScrollY(event.currentTarget); if (directional) { - return next < current ? false : !!(next > current && next > threshold); + return scrollY < value.current ? false : !!(scrollY > value.current && scrollY > threshold); } - return next > threshold; + value.current = scrollY; + return scrollY > threshold; } const useScrollTrigger = (props = {}) => { - const { triggerFunc = defaultTrigger, ...triggerProps } = props; - const [ref, setRef] = React.useState(); - const yRef = React.useRef(0); + const { onTrigger = defaultTrigger, ...triggerProps } = props; + const [target, setTarget] = React.useState(); + const value = React.useRef(0); const [trigger, setTrigger] = React.useState(false); - const handleScroll = React.useCallback(() => { - const scrollY = getScrollY(ref); - setTrigger(triggerFunc(scrollY, yRef.current, triggerProps)); - yRef.current = scrollY; - }, [triggerProps, ref, triggerFunc]); + const handleScroll = React.useCallback( + event => { + setTrigger(onTrigger(event, value, triggerProps)); + }, + [triggerProps, onTrigger], + ); React.useEffect(() => { - (ref || window).addEventListener('scroll', handleScroll); + (target || window).addEventListener('scroll', handleScroll); return () => { - (ref || window).removeEventListener('scroll', handleScroll); + (target || window).removeEventListener('scroll', handleScroll); }; - }, [handleScroll, ref, setRef]); + }, [handleScroll, target, setTarget]); - return [trigger, setRef]; + return [trigger, setTarget]; }; export default useScrollTrigger; From 6df4c27c02c1a138d18d2c763a7d8b0841fbf1bf Mon Sep 17 00:00:00 2001 From: cvanem Date: Wed, 1 May 2019 12:12:26 -0600 Subject: [PATCH 21/32] Update prop types and typings --- .../material-ui/src/useScrollTrigger/useScrollTrigger.d.ts | 6 +++--- .../material-ui/src/useScrollTrigger/useScrollTrigger.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts index e22cd6847a0eef..f53eae59f916e0 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts @@ -5,16 +5,16 @@ export interface DefaultTriggerProps { export type TriggerProps = DefaultTriggerProps & any; -export type OnTrigger = ( +export type OnTriggerEval = ( event: Event, value: React.MutableRefObject, props?: TriggerProps, ) => boolean; export type UseScrollTriggerProps = { - onTrigger?: OnTrigger; + onTriggerEval?: OnTriggerEval; } & TriggerProps; export default function useScrollTrigger( props?: UseScrollTriggerProps, -): [boolean, (ref: any) => void]; +): [boolean, React.Dispatch]; diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index b772124a5edb43..2af663bb4b46dd 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -23,16 +23,16 @@ function defaultTrigger(event, value, props = {}) { } const useScrollTrigger = (props = {}) => { - const { onTrigger = defaultTrigger, ...triggerProps } = props; + const { onTriggerEval = defaultTrigger, ...triggerProps } = props; const [target, setTarget] = React.useState(); const value = React.useRef(0); const [trigger, setTrigger] = React.useState(false); const handleScroll = React.useCallback( event => { - setTrigger(onTrigger(event, value, triggerProps)); + setTrigger(onTriggerEval(event, value, triggerProps)); }, - [triggerProps, onTrigger], + [triggerProps, onTriggerEval], ); React.useEffect(() => { From 9244a4c0da8954792b1d57548a1a2f3d26dda80e Mon Sep 17 00:00:00 2001 From: cvanem Date: Wed, 1 May 2019 12:55:12 -0600 Subject: [PATCH 22/32] Remove setTarget useEffect dependency --- packages/material-ui/src/useScrollTrigger/useScrollTrigger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index 2af663bb4b46dd..9d8a8f5f1b4669 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -40,7 +40,7 @@ const useScrollTrigger = (props = {}) => { return () => { (target || window).removeEventListener('scroll', handleScroll); }; - }, [handleScroll, target, setTarget]); + }, [handleScroll, target]); return [trigger, setTarget]; }; From 388baff7b1630d6cbd6f0c8a870f8dbd27c225c9 Mon Sep 17 00:00:00 2001 From: cvanem Date: Wed, 1 May 2019 16:33:17 -0600 Subject: [PATCH 23/32] Move trigger options to state, update typings --- .../useScrollTrigger/useScrollTrigger.d.ts | 7 ++++--- .../src/useScrollTrigger/useScrollTrigger.js | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts index f53eae59f916e0..280a7b8e843037 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts @@ -3,17 +3,18 @@ export interface DefaultTriggerProps { threshhold?: number; } -export type TriggerProps = DefaultTriggerProps & any; +export type TriggerOptions = DefaultTriggerProps & any; export type OnTriggerEval = ( event: Event, value: React.MutableRefObject, - props?: TriggerProps, + options?: TriggerOptions, ) => boolean; export type UseScrollTriggerProps = { onTriggerEval?: OnTriggerEval; -} & TriggerProps; + initialOptions?: TriggerOptions; +}; export default function useScrollTrigger( props?: UseScrollTriggerProps, diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js index 9d8a8f5f1b4669..a7bebdf97e1468 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.js @@ -15,24 +15,29 @@ function getScrollY(ref = window) { function defaultTrigger(event, value, props = {}) { const { directional = true, threshold = 100 } = props; const scrollY = getScrollY(event.currentTarget); - if (directional) { - return scrollY < value.current ? false : !!(scrollY > value.current && scrollY > threshold); - } + // eslint-disable-next-line no-nested-ternary + const trigger = directional + ? scrollY < value.current + ? false + : !!(scrollY > value.current && scrollY > threshold) + : scrollY > threshold; + value.current = scrollY; - return scrollY > threshold; + return trigger; } const useScrollTrigger = (props = {}) => { - const { onTriggerEval = defaultTrigger, ...triggerProps } = props; + const { onTriggerEval = defaultTrigger, ...initialOptions } = props; const [target, setTarget] = React.useState(); const value = React.useRef(0); const [trigger, setTrigger] = React.useState(false); + const [options, setOptions] = React.useState(initialOptions); const handleScroll = React.useCallback( event => { - setTrigger(onTriggerEval(event, value, triggerProps)); + setTrigger(onTriggerEval(event, value, options)); }, - [triggerProps, onTriggerEval], + [onTriggerEval, options], ); React.useEffect(() => { @@ -42,7 +47,7 @@ const useScrollTrigger = (props = {}) => { }; }, [handleScroll, target]); - return [trigger, setTarget]; + return [trigger, setTarget, setOptions]; }; export default useScrollTrigger; From aa7a67cd152717b31b27519c2c1b21ebe0eaac48 Mon Sep 17 00:00:00 2001 From: cvanem Date: Wed, 1 May 2019 16:42:35 -0600 Subject: [PATCH 24/32] Update typings --- .../material-ui/src/useScrollTrigger/useScrollTrigger.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts index 280a7b8e843037..6e8ea9be7d331b 100644 --- a/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts +++ b/packages/material-ui/src/useScrollTrigger/useScrollTrigger.d.ts @@ -11,11 +11,11 @@ export type OnTriggerEval = ( options?: TriggerOptions, ) => boolean; -export type UseScrollTriggerProps = { +export interface UseScrollTriggerProps { onTriggerEval?: OnTriggerEval; initialOptions?: TriggerOptions; -}; +} export default function useScrollTrigger( props?: UseScrollTriggerProps, -): [boolean, React.Dispatch]; +): [boolean, React.Dispatch, React.Dispatch>]; From 7cbb5a55182c340c5e8833ad644f5f7799d3edf9 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Wed, 1 May 2019 23:48:58 +0200 Subject: [PATCH 25/32] Simplify demo --- docs/src/modules/components/AppFrame.js | 2 +- .../modules/components/AppTableOfContents.js | 1 - docs/src/pages/demos/app-bar/ButtonAppBar.js | 2 +- docs/src/pages/demos/app-bar/ButtonAppBar.tsx | 2 +- docs/src/pages/demos/app-bar/ElevateAppBar.js | 139 +++++------------- .../src/pages/demos/app-bar/ElevateAppBar.tsx | 67 +++++++++ docs/src/pages/demos/app-bar/HideAppBar.js | 126 ++++------------ docs/src/pages/demos/app-bar/HideAppBar.tsx | 70 +++++++++ docs/src/pages/demos/app-bar/MenuAppBar.js | 2 +- docs/src/pages/demos/app-bar/MenuAppBar.tsx | 2 +- .../demos/app-bar/PrimarySearchAppBar.js | 2 +- .../demos/app-bar/PrimarySearchAppBar.tsx | 2 +- docs/src/pages/demos/app-bar/SearchAppBar.js | 2 +- docs/src/pages/demos/app-bar/SearchAppBar.tsx | 2 +- docs/src/pages/demos/app-bar/app-bar.md | 7 +- .../pages/demos/dialogs/FullScreenDialog.js | 2 +- .../pages/demos/dialogs/FullScreenDialog.tsx | 2 +- docs/src/pages/demos/drawers/ClippedDrawer.js | 2 +- .../src/pages/demos/drawers/ClippedDrawer.tsx | 2 +- docs/src/pages/demos/drawers/MiniDrawer.js | 2 +- docs/src/pages/demos/drawers/MiniDrawer.tsx | 2 +- .../demos/drawers/PermanentDrawerLeft.js | 2 +- .../demos/drawers/PermanentDrawerLeft.tsx | 2 +- .../demos/drawers/PermanentDrawerRight.js | 2 +- .../demos/drawers/PermanentDrawerRight.tsx | 2 +- .../demos/drawers/PersistentDrawerLeft.js | 2 +- .../demos/drawers/PersistentDrawerLeft.tsx | 2 +- .../demos/drawers/PersistentDrawerRight.js | 2 +- .../demos/drawers/PersistentDrawerRight.tsx | 2 +- .../pages/demos/drawers/ResponsiveDrawer.js | 2 +- .../pages/demos/drawers/ResponsiveDrawer.tsx | 2 +- packages/material-ui/src/Paper/Paper.js | 1 + .../src/useScrollTrigger/index.d.ts | 1 + .../src/useScrollTrigger/useScrollTrigger.js | 6 +- 34 files changed, 236 insertions(+), 232 deletions(-) create mode 100644 docs/src/pages/demos/app-bar/ElevateAppBar.tsx create mode 100644 docs/src/pages/demos/app-bar/HideAppBar.tsx diff --git a/docs/src/modules/components/AppFrame.js b/docs/src/modules/components/AppFrame.js index d02e7d0a09a26e..28bd723a814444 100644 --- a/docs/src/modules/components/AppFrame.js +++ b/docs/src/modules/components/AppFrame.js @@ -252,7 +252,7 @@ class AppFrame extends React.Component { {title !== null && ( - + {title} )} diff --git a/docs/src/modules/components/AppTableOfContents.js b/docs/src/modules/components/AppTableOfContents.js index ef78e829f9168e..d7e281d118e59a 100644 --- a/docs/src/modules/components/AppTableOfContents.js +++ b/docs/src/modules/components/AppTableOfContents.js @@ -22,7 +22,6 @@ const styles = theme => ({ flexShrink: 0, order: 2, position: 'sticky', - wordBreak: 'break-all', height: 'calc(100vh - 70px - 29px)', overflowY: 'auto', padding: theme.spacing(2, 2, 2, 0), diff --git a/docs/src/pages/demos/app-bar/ButtonAppBar.js b/docs/src/pages/demos/app-bar/ButtonAppBar.js index 8c3e041be02e98..3ff8bfeffe5447 100644 --- a/docs/src/pages/demos/app-bar/ButtonAppBar.js +++ b/docs/src/pages/demos/app-bar/ButtonAppBar.js @@ -28,7 +28,7 @@ function ButtonAppBar() { - + News diff --git a/docs/src/pages/demos/app-bar/ButtonAppBar.tsx b/docs/src/pages/demos/app-bar/ButtonAppBar.tsx index 7f6ab1a7588436..172464c760f905 100644 --- a/docs/src/pages/demos/app-bar/ButtonAppBar.tsx +++ b/docs/src/pages/demos/app-bar/ButtonAppBar.tsx @@ -30,7 +30,7 @@ function ButtonAppBar() { - + News diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.js b/docs/src/pages/demos/app-bar/ElevateAppBar.js index 2ec38e0bb9a595..61a13e8427e4b8 100644 --- a/docs/src/pages/demos/app-bar/ElevateAppBar.js +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.js @@ -1,54 +1,43 @@ +/* eslint-disable prefer-spread */ + import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; +import PropTypes from 'prop-types'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; +import CssBaseline from '@material-ui/core/CssBaseline'; import useScrollTrigger from '@material-ui/core/useScrollTrigger'; import Box from '@material-ui/core/Box'; import Container from '@material-ui/core/Container'; -import PropTypes from 'prop-types'; - -// Create the transition class for the associated elevation -const useElevationStyles = makeStyles(theme => { - return { - elevationX: { - boxShadow: props => theme.shadows[props.elevation], - transition: theme.transitions.create('box-shadow', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - }; -}); function ElevationScroll(props) { - const { children, elevation = 4, trigger } = props; - return React.cloneElement(children, { - className: useElevationStyles().elevationX, - elevation: trigger ? elevation : 0, - }); -} - -const useStyles = makeStyles({ - root: { - flexGrow: 1, - }, -}); + const { children, window } = props; + const [trigger, setTarget] = useScrollTrigger({ directional: false, threshold: 0 }); -function ElevateAppBar(props) { - const classes = useStyles(); - const [trigger, setTarget] = useScrollTrigger({ directional: false, threshold: 100 }); - - // Normally setTarget(window) won't be needed as useScrollTrigger defaults to window. - // It is included here because the demo is in an iframe - const { window } = props; + // Note that you normally won't need to set the window ref as useScrollTrigger + // will default to window. + // This is only being set here because the demo is in an iframe. React.useEffect(() => { setTarget(window); }, [setTarget, window]); + return React.cloneElement(children, { + elevation: trigger ? 4 : 0, + }); +} + +ElevationScroll.propTypes = { + children: PropTypes.node.isRequired, + // Injected by the documentation to work in an iframe. + // You won't need it on your project. + window: PropTypes.func, +}; + +export default function ElevateAppBar(props) { return ( -
- + + + Scroll to Elevate App Bar @@ -58,76 +47,16 @@ function ElevateAppBar(props) { - {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into`} + {Array.apply(null, Array(12)) + .map( + () => `Cras mattis consectetur purus sit amet fermentum. +Cras justo odio, dapibus ac facilisis in, egestas eget quam. +Morbi leo risus, porta ac consectetur ac, vestibulum at eros. +Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, + ) + .join('\n')} -
+ ); } - -ElevateAppBar.propTypes = { - window: PropTypes.func, -}; - -export default ElevateAppBar; diff --git a/docs/src/pages/demos/app-bar/ElevateAppBar.tsx b/docs/src/pages/demos/app-bar/ElevateAppBar.tsx new file mode 100644 index 00000000000000..44818014152c0b --- /dev/null +++ b/docs/src/pages/demos/app-bar/ElevateAppBar.tsx @@ -0,0 +1,67 @@ +/* eslint-disable prefer-spread */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import CssBaseline from '@material-ui/core/CssBaseline'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; + +interface Props { + window: Window; + children: React.ReactElement; +} + +function ElevationScroll(props: Props) { + const { children, window } = props; + const [trigger, setTarget] = useScrollTrigger({ directional: false, threshold: 0 }); + + // Note that you normally won't need to set the window ref as useScrollTrigger + // will default to window. + // This is only being set here because the demo is in an iframe. + React.useEffect(() => { + setTarget(window); + }, [setTarget, window]); + + return React.cloneElement(children, { + elevation: trigger ? 4 : 0, + }); +} + +ElevationScroll.propTypes = { + children: PropTypes.node.isRequired, + // Injected by the documentation to work in an iframe. + // You won't need it on your project. + window: PropTypes.func, +}; + +export default function ElevateAppBar(props: Props) { + return ( + + + + + + Scroll to Elevate App Bar + + + + + + + {Array.apply(null, Array(12)) + .map( + () => `Cras mattis consectetur purus sit amet fermentum. +Cras justo odio, dapibus ac facilisis in, egestas eget quam. +Morbi leo risus, porta ac consectetur ac, vestibulum at eros. +Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, + ) + .join('\n')} + + + + ); +} diff --git a/docs/src/pages/demos/app-bar/HideAppBar.js b/docs/src/pages/demos/app-bar/HideAppBar.js index 4a6f1d0a9e5309..ceaad66b96c6e3 100644 --- a/docs/src/pages/demos/app-bar/HideAppBar.js +++ b/docs/src/pages/demos/app-bar/HideAppBar.js @@ -1,18 +1,29 @@ +/* eslint-disable prefer-spread */ + import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; +import PropTypes from 'prop-types'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; +import CssBaseline from '@material-ui/core/CssBaseline'; import useScrollTrigger from '@material-ui/core/useScrollTrigger'; import Box from '@material-ui/core/Box'; import Container from '@material-ui/core/Container'; -import { Slide } from '@material-ui/core'; -import PropTypes from 'prop-types'; +import Slide from '@material-ui/core/Slide'; function HideOnScroll(props) { - const { children, trigger, ...other } = props; + const { children, window } = props; + const [trigger, setTarget] = useScrollTrigger({ directional: true, threshold: 100 }); + + // Note that you normally won't need to set the window ref as useScrollTrigger + // will default to window. + // This is only being set here because the demo is in an iframe. + React.useEffect(() => { + setTarget(window); + }, [setTarget, window]); + return ( - + {children} ); @@ -20,29 +31,16 @@ function HideOnScroll(props) { HideOnScroll.propTypes = { children: PropTypes.node.isRequired, - trigger: PropTypes.bool.isRequired, + // Injected by the documentation to work in an iframe. + // You won't need it on your project. + window: PropTypes.func, }; -const useStyles = makeStyles({ - root: { - flexGrow: 1, - }, -}); - -function HideAppBar(props) { - const [trigger, setTarget] = useScrollTrigger({ directional: true, threshold: 400 }); - const classes = useStyles(trigger); - - // Note that you normally won't need to set the window ref as useScrollTrigger will default to window. - // This is only being set here because the demo is in an iframe - const { window } = props; - React.useEffect(() => { - setTarget(window); - }, [setTarget, window]); - +export default function HideAppBar(props) { return ( -
- + + + Scroll to Hide App Bar @@ -52,76 +50,16 @@ function HideAppBar(props) { - {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s - with the release of Letraset sheets containing Lorem Ipsum passages, and more recently - with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. - Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has - been the industry's standard dummy text ever since the 1500s, when an unknown printer took - a galley of type and scrambled it to make a type specimen book. It has survived not only - five centuries, but also the leap into electronic typesetting, remaining essentially - unchanged. It was popularised in the 1960s with the release of Letraset sheets containing - Lorem Ipsum passages, and more recently with desktop publishing software like Aldus - PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the - printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text - ever since the 1500s, when an unknown printer took a galley of type and scrambled it to - make a type specimen book. It has survived not only five centuries, but also the leap into`} + {Array.apply(null, Array(12)) + .map( + () => `Cras mattis consectetur purus sit amet fermentum. +Cras justo odio, dapibus ac facilisis in, egestas eget quam. +Morbi leo risus, porta ac consectetur ac, vestibulum at eros. +Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, + ) + .join('\n')} -
+ ); } - -HideAppBar.propTypes = { - window: PropTypes.func, -}; - -export default HideAppBar; diff --git a/docs/src/pages/demos/app-bar/HideAppBar.tsx b/docs/src/pages/demos/app-bar/HideAppBar.tsx new file mode 100644 index 00000000000000..ffb09bb0c482e9 --- /dev/null +++ b/docs/src/pages/demos/app-bar/HideAppBar.tsx @@ -0,0 +1,70 @@ +/* eslint-disable prefer-spread */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import AppBar from '@material-ui/core/AppBar'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import CssBaseline from '@material-ui/core/CssBaseline'; +import useScrollTrigger from '@material-ui/core/useScrollTrigger'; +import Box from '@material-ui/core/Box'; +import Container from '@material-ui/core/Container'; +import Slide from '@material-ui/core/Slide'; + +interface Props { + window: Window; + children: React.ReactElement; +} + +function HideOnScroll(props: Props) { + const { children, window } = props; + const [trigger, setTarget] = useScrollTrigger({ directional: true, threshold: 100 }); + + // Note that you normally won't need to set the window ref as useScrollTrigger + // will default to window. + // This is only being set here because the demo is in an iframe. + React.useEffect(() => { + setTarget(window); + }, [setTarget, window]); + + return ( + + {children} + + ); +} + +HideOnScroll.propTypes = { + children: PropTypes.node.isRequired, + // Injected by the documentation to work in an iframe. + // You won't need it on your project. + window: PropTypes.func, +}; + +export default function HideAppBar(props: Props) { + return ( + + + + + + Scroll to Hide App Bar + + + + + + + {Array.apply(null, Array(12)) + .map( + () => `Cras mattis consectetur purus sit amet fermentum. +Cras justo odio, dapibus ac facilisis in, egestas eget quam. +Morbi leo risus, porta ac consectetur ac, vestibulum at eros. +Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`, + ) + .join('\n')} + + + + ); +} diff --git a/docs/src/pages/demos/app-bar/MenuAppBar.js b/docs/src/pages/demos/app-bar/MenuAppBar.js index af13e66b13f3c0..a03ffa08f5dd33 100644 --- a/docs/src/pages/demos/app-bar/MenuAppBar.js +++ b/docs/src/pages/demos/app-bar/MenuAppBar.js @@ -55,7 +55,7 @@ function MenuAppBar() { - + Photos {auth && ( diff --git a/docs/src/pages/demos/app-bar/MenuAppBar.tsx b/docs/src/pages/demos/app-bar/MenuAppBar.tsx index ac4535eafc3739..949e0ce43f4e8a 100644 --- a/docs/src/pages/demos/app-bar/MenuAppBar.tsx +++ b/docs/src/pages/demos/app-bar/MenuAppBar.tsx @@ -57,7 +57,7 @@ function MenuAppBar() { - + Photos {auth && ( diff --git a/docs/src/pages/demos/app-bar/PrimarySearchAppBar.js b/docs/src/pages/demos/app-bar/PrimarySearchAppBar.js index 02c369096c70f6..2570f43a4c5d5d 100644 --- a/docs/src/pages/demos/app-bar/PrimarySearchAppBar.js +++ b/docs/src/pages/demos/app-bar/PrimarySearchAppBar.js @@ -161,7 +161,7 @@ function PrimarySearchAppBar() { > - + Material-UI
diff --git a/docs/src/pages/demos/app-bar/PrimarySearchAppBar.tsx b/docs/src/pages/demos/app-bar/PrimarySearchAppBar.tsx index 223d655728712f..b58eabaa50c54b 100644 --- a/docs/src/pages/demos/app-bar/PrimarySearchAppBar.tsx +++ b/docs/src/pages/demos/app-bar/PrimarySearchAppBar.tsx @@ -163,7 +163,7 @@ function PrimarySearchAppBar() { > - + Material-UI
diff --git a/docs/src/pages/demos/app-bar/SearchAppBar.js b/docs/src/pages/demos/app-bar/SearchAppBar.js index 97ce8e95c9ce31..bee3b9def177b8 100644 --- a/docs/src/pages/demos/app-bar/SearchAppBar.js +++ b/docs/src/pages/demos/app-bar/SearchAppBar.js @@ -76,7 +76,7 @@ function SearchAppBar() { > - + Material-UI
diff --git a/docs/src/pages/demos/app-bar/SearchAppBar.tsx b/docs/src/pages/demos/app-bar/SearchAppBar.tsx index 31058c9e3bd23c..0adb81993f376a 100644 --- a/docs/src/pages/demos/app-bar/SearchAppBar.tsx +++ b/docs/src/pages/demos/app-bar/SearchAppBar.tsx @@ -78,7 +78,7 @@ function SearchAppBar() { > - + Material-UI
diff --git a/docs/src/pages/demos/app-bar/app-bar.md b/docs/src/pages/demos/app-bar/app-bar.md index 6d1a233c46e0bb..d0603856a7bf37 100644 --- a/docs/src/pages/demos/app-bar/app-bar.md +++ b/docs/src/pages/demos/app-bar/app-bar.md @@ -43,15 +43,16 @@ A side searchbar. {{"demo": "pages/demos/app-bar/BottomAppBar.js", "iframe": true, "maxWidth": 500}} -## Hide App Bar on scroll +## Scrolling + +### Hide App Bar on scroll An App Bar that hides on scroll. {{"demo": "pages/demos/app-bar/HideAppBar.js", "iframe": "true", "maxWidth": 500}} -## Elevate App Bar on sroll +### Elevate App Bar on sroll An App Bar that elevates on scroll. {{"demo": "pages/demos/app-bar/ElevateAppBar.js", "iframe": "true", "maxWidth": 500}} - diff --git a/docs/src/pages/demos/dialogs/FullScreenDialog.js b/docs/src/pages/demos/dialogs/FullScreenDialog.js index 75b61ee4ea6c71..9d53e073668b8a 100644 --- a/docs/src/pages/demos/dialogs/FullScreenDialog.js +++ b/docs/src/pages/demos/dialogs/FullScreenDialog.js @@ -50,7 +50,7 @@ function FullScreenDialog() { - + Sound