Reputation: 711
I am quite new of react, and I am designing a "design system" that reads from JSON so that I can drag and drop the application and use it in various project by just modifying the parameters of the data in the JSON.
I have link colors, and normal colors. Links colors can be applied only to text. While Colors can be applied to text and backgrounds.
To visualize the colors available I have created a palette of all the colors used by printing what I am calling as component ColorBox.
The whole code can be found here: https://github.com/Littlemad/myapp
import React from "react";
import dataJSON from "../../../data/data.json";
import "./ColorBox.scss";
const colorsJSON = dataJSON.colors;
const linksJSON = dataJSON.links;
const ColorBox = (props) => {
var myColor = colorsJSON.find((e) => e.var === props.var);
// TODO: revise this, it is not decent code
if (myColor === undefined) {
myColor = linksJSON.find((e) => e.var === props.var);
}
return (
<>
<div className="colorbox">
<div className="colorbox__name">{myColor.name}</div>
<div className={`colorbox__color color-bg--${myColor.var}`}></div>
<div className="colorbox__val">
<p>
<strong>{myColor.value}</strong>
</p>
<code>{myColor.var}</code>
</div>
</div>
</>
);
};
export default ColorBox;
The Json data looks like this
"colors": [
{"value": "#fff", "var": "white", "name": "White"},
{"value": "#f5f5f5", "var": "grey-l3", "name": "Very Light Grey"},
{"value": "#eee", "var": "grey-l2", "name": "Light Grey"},
{"value": "#ddd", "var": "grey-l1", "name": "Lightish Grey"},
{"value": "#bbb", "var": "grey", "name": "Grey"},
{"value": "#999", "var": "grey-d1", "name": "Darkish Grey"},
{"value": "#666", "var": "grey-d2", "name": "Dark Grey"},
{"value": "#333", "var": "grey-d3", "name": "Very Dark Grey"},
{"value": "#000", "var": "black", "name": "Black"},
{"value": "#68BBE3", "var": "primary-l2", "name": "Baby Blue"},
{"value": "#0E86D4", "var": "primary-l1", "name": "Blue Grotto"},
{"value": "#055C9D", "var": "primary", "name": "Blue"},
{"value": "#003060", "var": "primary-d1", "name": "Navy Blue"},
{"value": "#001040", "var": "primary-d2", "name": "Dark Navy Blue"},
{"value": "#390", "var": "success", "name": "Success"},
{"value": "#fc0", "var": "warn", "name": "Warning"},
{"value": "#c30", "var": "fail", "name": "Failure"}
],
"links": [
{"value": "#00c", "var": "link", "name": "Link"},
{"value": "#a4b", "var": "link-visited", "name": "Link Visited"},
{"value": "#c30", "var": "link-active", "name": "Link Active"}
]
The component are than being called like this
<div className="box">
<h2 className="h2 bold box__title">Accent</h2>
<div className="box-palette__grid">
<ColorBox var="success" />
<ColorBox var="warn" />
<ColorBox var="fail" />
</div>
</div>
<div className="box">
<h2 className="h2 bold box__title">Link values</h2>
<div className="box-palette__grid">
<ColorBox var="link" />
<ColorBox var="link-visited" />
<ColorBox var="link-active" />
</div>
</div>
I am assuming because I know what data there is, that with a check if !undefined on the colorsJSON it means that I have to load the other set of values. I am unable to think of a better way to cycle through the set of data, or how to find a more elegant way to collect the data and just read the part that I am interested.
I am thinking that if in the future I want to add other set of colors to other branch of data (for example only background elements, or only icons colors, or highContrast colors), this will be an issue for sure.
Thank you for your help, any tips on how to improve programming in react would be absolutely appreciated.
p.s. I keep links and colors separated because I am using differently across the design system, so I cannot put them together in the same category.
Upvotes: 1
Views: 63
Reputation: 13630
If you structure your JSON with objects instead of arrays then you can access the data you want to read directly.
"colors": {
"white": { "value": "#fff", "name": "White" },
"grey-l3": { "value": "#f5f5f5", "name": "Very Light Grey" },
etc.
},
"links": {
"link": { "value": "#00c", "name": "Link" },
"link-visited": { "value": "#a4b", "name": "Link Visited" },
etc.
}
Now you can myColor = linksJSON[props.var]
. If you need to convert the colors
or links
back to an array for rendering or whatever, you can simply do Object.keys(JSON.colors)
, or Object.values(JSON.links)
, etc., whatever best suits your needs.
Upvotes: 1
Reputation: 10498
I don't know if this fits your needs, but if you do need to get rid of the if
statement and since there is no other check at that point, you could search in the entire concatenated array
So instead of
var myColor = colorsJSON.find((e) => e.var === props.var);
if (myColor === undefined) {
myColor = linksJSON.find((e) => e.var === props.var);
}
you can use flat method and write this
var myColor = Object.values(dataJSON).flat().find((e) => e.var === props.var);
also this means that you get rid of this too
const colorsJSON = dataJSON.colors;
const linksJSON = dataJSON.links;
Upvotes: 1
Reputation: 281
Try this:
const predicate = (e) => e.var === props.var;
const myColor = colorsJSON.find(predicate) || linksJSON.find(predicate);
Upvotes: 1