<div id="root"></div>
@import url('https://fonts.googleapis.com/css2?family=Fira+Code&family=Kaushan+Script&family=Nunito&family=Righteous&family=Spectral&display=swap');
body {
margin: 1em;
font-size: 17px;
line-height: 1.7;
font-family: "Spectral", serif;
}
code {
font-family: "Fira Code", monospace;
font-style: normal;
font-weight: 400;
font-size: 0.8em;
display: inline-block;
transform: translateY(-0.03em);
padding: 0 0.3em;
border-radius: 3px;
background-color: #f1f1f1;
color: #f44;
}
main {
margin: auto;
max-width: 1080px;
}
.boxes {
display: flex;
align-items: stretch;
gap: 1em;
}
.boxes > div {
flex-basis: 0;
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
font-size: 20px;
padding: 1em;
border-radius: 4px;
}
// from themes.json
const themesJSON = {
red: {
font: "Kaushan Script, cursive",
color: {
text: "#844",
background: "#faa"
}
},
blue: {
font: "Nunito, sans-serif",
color: {
text: "#448",
background: "#aaf"
}
},
dark: {
font: "Righteous, monospace",
color: {
text: "#8c8",
background: "#000"
}
}
}
// from styles.json
const stylesJSON = {
emphasis: {
fontFamily: "<font>",
color: "<color.text>",
backgroundColor: "<color.background>",
border: "3px solid <color.text>"
}
}
const App = () => {
const makeStyles = (theme) => {
const pattern = /<[^>]*>/; // matches with <EXPRESSION>
const t = themesJSON[theme];
// Find all matches of `pattern` in `styleData` and replace them with their evaluated counterparts.
let s = JSON.stringify(stylesJSON);
while (s.match(pattern)) {
const match = s.match(pattern)[0];
s = s.replace(match, eval("t." + match.slice(1, -1)));
}
return JSON.parse(s);
}
return (
<main>
<p>The only styling differences between these boxes is through <code>makeStyles(...)</code>.</p>
<div class="boxes">
<div style={makeStyles("red").emphasis}>
Red theme
</div>
<div style={makeStyles("blue").emphasis}>
Blue theme
</div>
<div style={makeStyles("dark").emphasis}>
Dark mode B)
</div>
</div>
</main>
);
}
// render <App /> component
ReactDOM.render(<App />, document.querySelector("#root"))
View Compiled
This Pen doesn't use any external CSS resources.