Skip to content

Instantly share code, notes, and snippets.

@jsmanifest
Created April 14, 2020 15:04
Show Gist options
  • Save jsmanifest/55f45a902a1da9e6173a3f233795cfd8 to your computer and use it in GitHub Desktop.
Save jsmanifest/55f45a902a1da9e6173a3f233795cfd8 to your computer and use it in GitHub Desktop.
function ListComponent({
label,
items = [],
collapsed,
toggle,
limit,
total,
renderListItem,
renderCollapser,
renderExpander,
}) {
let expandCollapse
if (total > limit) {
if (collapsed) {
expandCollapse = renderExpander ? (
renderExpander({ collapsed, toggle })
) : (
<button type="button" onClick={toggle}>
Expand
</button>
)
} else {
expandCollapse = renderCollapser ? (
renderCollapser({ collapsed, toggle })
) : (
<button type="button" onClick={toggle}>
Collapse
</button>
)
}
}
return (
<ul>
<p>{label}</p>
{items.map((member) =>
renderListItem ? (
<React.Fragment key={member}>
{renderListItem({ collapsed, toggle, member })}
</React.Fragment>
) : (
<ListItem key={member}>{member}</ListItem>
),
)}
{total > limit && (
<ListItem className="expand">{expandCollapse}</ListItem>
)}
</ul>
)
}
function ListItem({ children, ...rest }) {
return <li {...rest}>{children}</li>
}
function List({
component: RootComponent = ListRoot,
collapsed,
toggle,
header,
label,
items = [],
limit = 3,
renderHeader,
renderList,
renderListItem,
renderCollapser,
renderExpander,
}) {
return (
<RootComponent>
{renderHeader ? (
renderHeader()
) : header !== null ? (
<ListHeader>{header}</ListHeader>
) : null}
{renderList ? (
renderList()
) : (
<ListComponent
label={label}
items={
collapsed && items.length > limit ? items.slice(0, limit) : items
}
collapsed={collapsed}
toggle={toggle}
limit={limit}
total={items.length}
renderListItem={renderListItem}
renderCollapser={renderCollapser}
renderExpander={renderExpander}
/>
)}
</RootComponent>
)
}
function App() {
const [collapsed, setCollapsed] = React.useState(true)
function toggle() {
setCollapsed((prevValue) => !prevValue)
}
const pediatricians = ['Home', 'Posts', 'About', 'More', 'Contact', 'FAQ']
const limit = 3
function renderCollapser({ collapsed, toggle }) {
return <ChevronLeftIcon onClick={toggle} />
}
function renderExpander({ collapsed, toggle }) {
return <ChevronRightIcon onClick={toggle} />
}
function renderListItem({ collapsed, toggle, member }) {
function onClick() {
window.alert(`Clicked ${member}`)
}
return (
<li className="custom-li" onClick={onClick}>
{member}
</li>
)
}
return (
<div className="navbar">
<div className="listContainer">
<List
collapsed={collapsed}
toggle={toggle}
header={null}
items={pediatricians}
limit={limit}
renderCollapser={renderCollapser}
renderExpander={renderExpander}
renderListItem={renderListItem}
/>
</div>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment