Skip to content

Instantly share code, notes, and snippets.

@kgregory
Last active August 12, 2021 16:30
Show Gist options
  • Save kgregory/3bbe3bcf5465aa2a68f16c84281fe19e to your computer and use it in GitHub Desktop.
Save kgregory/3bbe3bcf5465aa2a68f16c84281fe19e to your computer and use it in GitHub Desktop.
Sticky Material-UI ListSubheader that appears beneath fixed AppBar
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