Last active
August 12, 2021 16:30
-
-
Save kgregory/3bbe3bcf5465aa2a68f16c84281fe19e to your computer and use it in GitHub Desktop.
Sticky Material-UI ListSubheader that appears beneath fixed AppBar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ListSubheader from "@material-ui/core/ListSubheader"; | |
import { makeStyles } from "@material-ui/core/styles"; | |
/** | |
* I have a separate gist for this that explains it a bit | |
* we do this because the app bar's height is dynamic based on the viewport size | |
* see: https://gist.github.com/e15657481aea15c440867de710399ea9 | |
*/ | |
const toolbarRelativeStyles = (property, theme, modifier = (value) => value) => | |
Object.keys(theme.mixins.toolbar).reduce((style, key) => { | |
const value = theme.mixins.toolbar[key]; | |
if (key === "minHeight") { | |
return { ...style, [property]: modifier(value) }; | |
} | |
if (value.minHeight !== undefined) { | |
return { ...style, [key]: { [property]: modifier(value.minHeight) } }; | |
} | |
return style; | |
}, {}); | |
/** | |
* This function allows you to pin an element beneath one or more toolbars | |
* This is helpful if you've already stuck a toolbar beneath your app's bar and need to pin subheaders under both | |
* We'll effectively push the element beneath the toolbars using the app bar's height as a modifier for its `top` property | |
*/ | |
const stickyStyles = ( | |
theme, | |
{ | |
sticky = true, | |
backgroundColor = theme.palette.background.paper, | |
stuckToolbars = 1, | |
} = {} | |
) => { | |
return { | |
zIndex: 11, | |
position: "sticky", | |
backgroundColor, | |
...toolbarRelativeStyles( | |
"top", | |
theme, | |
(value) => value * stuckToolbars - 1 * stuckToolbars | |
), | |
}; | |
}; | |
/** | |
* We've created a `sticky` class that will be used to override the `sticky` class | |
*/ | |
const useStyles = makeStyles((theme) => ({ | |
sticky: { | |
...stickyStyles(theme), | |
}, | |
})); | |
/** | |
* a wrapper around the material-ui ListSubheader with an overridden `sticky` class | |
*/ | |
const StickyListSubheader = (props) => { | |
const classes = useStyles(); | |
return <ListSubheader {...props} classes={{ sticky: classes.sticky }} />; | |
}; | |
export default StickyListSubheader; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment