React
by Abdul Ahmad
HTML
<div id="app"></div>
SCSS
body {
margin: 0;
font-family: Helvetica;
box-sizing: border-box;
}
#app {
padding: 20px;
}
.magnifiable-box {
border: 1px solid #ddd;
border-radius: 5px;
padding: 30px;
display: flex;
align-items: center;
background: white;
}
.magnification-boxes {
display: flex;
margin-top: 50px;
background: #ddd;
padding: 20px;
}
React
function App() {
const [magnificationLevel, setMagnificationLevel] = React.useState(0);
return (
<div>
<div>
Magnification Level { magnificationLevel }
</div>
<div className='buttons'>
<button onClick={() => setMagnificationLevel(magnificationLevel - 1)}>
-
</button>
<button onClick={() => setMagnificationLevel(magnificationLevel + 1)}>
+
</button>
</div>
<div className='magnification-boxes'>
<MagnifiableBox magnificationLevel={magnificationLevel} />
</div>
</div>
);
}
function MagnifiableBoxWrap({ children, data = {} }) {
let titles = getTitlesRecursively({ originalData: data });
if (titles.length === 1 && titles[0] === data.content) titles = [];
return (
<div className='magnifiable-box'>
<div>
{ titles.map(i => <div key={i}>{i}</div>) }
{ children }
</div>
</div>
);
}
function MagnifiableBox({ magnificationLevel, contentPerLevel = getContent() }) {
let content = contentPerLevel[magnificationLevel];
if (!content) {
return (
<MagnifiableBoxWrap>
No Data
</MagnifiableBoxWrap>
);
} else {
content = Object.entries(content).map(([k, v]) => (
<MagnifiableBoxWrap key={k + v} data={v}>
{ v.content }
</MagnifiableBoxWrap>
));
return (
<div>
{ content }
</div>
);
}
}
function getTitlesRecursively({
data = getContent(), title = [], nextData, originalData
}) {
if (!nextData) nextData = originalData;
const hasParent = hasValue({ field: nextData.parentMagnificationLevel })
&& hasValue({ field: nextData.parentIndex });
let newTitle;
if (hasParent && originalData) {
newTitle = [];
} else {
newTitle = [nextData.content, ...title];
}
if (!hasParent) return newTitle;
const { parentMagnificationLevel, parentIndex } = nextData;
return getTitlesRecursively({
data,
nextData:...