React
by Abdul Ahmad
HTML
<div id="app"></div>
SCSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
box-sizing: border-box;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.accordion {
// border: 1px dashed #ddd;
max-width: 500px;
>.title {
padding: 10px 0;
font-size: 18px;
}
.items {
}
}
.accordion-item {
border: 1px solid #ddd;
border-radius: 5px;
padding: 20px;
margin-top: 3px;
.top-row {
display: flex;
align-items: center;
}
.title {
font-weight: bold;
flex-grow: 1;
flex-shrink: 1;
}
.collapser {
width: 20px;
height: 20px;
border-radius: 50%;
background: #aaa;
transition: all 0.15s ease;
&:hover {
cursor: pointer;
background: tomato;
transition: all 0.15s ease;
}
}
.content {
margin-top: 10px;
}
}
React
function AccordionItemOne(props) {
return (
<AccordionItem title='Item 1' { ...props }>
Content 1
</AccordionItem>
);
}
function AccordionItemTwo(props) {
return (
<AccordionItem title='Item 2' { ...props }>
Content 2
</AccordionItem>
);
}
function App() {
const accordionItems = [
AccordionItemOne,
AccordionItemTwo,
].map((Item, index) => (
<Item index={index} accordionName='Accordion1' />
));
return (
<Accordion title='Accordion1'>
{ accordionItems }
</Accordion>
);
}
function Accordion({ title, children }) {
const { state, setState, clearState } = useAccordionState({
numItems: children.length,
expandedItems: [0],
});
return (
<div className='accordion'>
<h3 className='title'>{ title }</h3>
<div className='items'>
{ children }
</div>
</div>
);
}
function AccordionItem({
title,
children,
index,
accordionName,
}) {
const { state } = useAccordionState({ accordionName });
return (
<div className='accordion-item'>
<div className='top-row'>
<h4 className='title'>{ title }</h4>
<div className='collapser' />
</div>
{ !collapsed && (
<div className='content'>
{ children }
</div>
)}
</div>
);
}
const accordionStates = {};
function getAccordionState({ accordionName, numItems, expandedItems } = {}) {
let state = accordionStates[accordionName];
if (!state) {
state = {
numItems,
expandedItems: expandedItems || [],
};
accordionStates[accordionName] = state;
}
return state;
}
function useAccordionState({ accordionName, numItems, expandedItems } = {}) {
const initialState = getAccordionState({ accordionName, numItems, expandedItems });
const [state, _setState] = React.useState(initialState);
function submitItem() {
}
function setState(newState) {
_setState({ ...newState });
accordionStates[accordionName] = {...