Skip to content

Instantly share code, notes, and snippets.

@Sebastian-Fitzner
Last active May 21, 2022 23:03
Show Gist options
  • Save Sebastian-Fitzner/39d920374e3c789aa160ce67617183a0 to your computer and use it in GitHub Desktop.
Save Sebastian-Fitzner/39d920374e3c789aa160ce67617183a0 to your computer and use it in GitHub Desktop.
const ScrollableList = ({ listItems }) => {
// States
const [scrollableListWidth, setScrollableListWidth] = React.useState(null);
const [listWidth, setListWidth] = React.useState(null);
const [leftButtonWidth, setLeftButtonWidth] = React.useState(null);
const [rightButtonWidth, setRightButtonWidth] = React.useState(null);
const [listPosition, setListPosition] = React.useState("left");
// Refs
const listRef = React.useRef(null);
const onWrapperMount = (el) => {
if (el) {
setScrollableListWidth(el.clientWidth);
}
};
const onLeftButtonMount = (el) => {
if (el) {
setLeftButtonWidth(el.clientWidth);
}
};
const onRightButtonMount = (el) => {
if (el) {
setRightButtonWidth(el.clientWidth);
}
};
// Effects
React.useEffect(() => {
if (listRef.current) {
setListWidth(listRef.current.clientWidth);
}
}, []);
// Inline Styles
const transformValue =
listPosition === "left" ? 0 : `calc(-100% + ${scrollableListWidth}px)`;
const listStyles = {
...(listWidth && { width: listWidth }),
transform: `translateX(${transformValue})`
};
// Optional Classes based on states
const cmpClasses = clsx("c-scrollable-list", {
["is-showing-right-btn"]:
scrollableListWidth < listWidth && listPosition === "left",
["is-showing-left-btn"]:
scrollableListWidth < listWidth && listPosition === "right"
});
return (
<div className={cmpClasses} ref={onWrapperMount}>
<ul className="c-scrollable-list__list" ref={listRef} style={listStyles}>
{listItems.map((item) => {
return (
<li className="c-scrollable-list__list-item">
<a href="#" className="c-scrollable-list__link">
{item.title}
</a>
</li>
);
})}
</ul>
<div className="c-scrollable-list__slide-buttons">
<button
className="c-scrollable-list__button is-show-less"
type="button"
ref={onLeftButtonMount}
onClick={() => setListPosition("left")}
>
Previous
</button>
<button
className="c-scrollable-list__button is-show-more"
type="button"
ref={onRightButtonMount}
onClick={() => setListPosition("right")}
>
Next
</button>
</div>
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment