Reputation: 253
I am coding a website in React using Semantic UI and am tired of writing the following again and again.
<Grid.Row style={{ marginBottom: "4em" }}>
There are multiple drawbacks of this approach:
I want to convert this to a design token - encode these margin padding values with enums (S \ M \ L \ XL) as a component. It would be ideal to expose them inside Semantic components itself something like :
<Grid.Row paddingBottom='S'>
OR
<Grid.Row childrenPadding='S'>
But I know this isn't possible since the <Grid.Row> is Semantic UI's component, not mine. What is the best approach I can take to encode these 'tokens'? I don't know what to search for in a search engine for this either :(
Upvotes: 1
Views: 5310
Reputation: 464
One of great powers of ReactJS
is that you can create your own customized components. You can easily create a component called for example GridRow
which recives 2 props.
Your component should return something like this:
<Grid.Row style={{padding:getPadding()}}>
{children}
<Grid.Row>
Then you can use it like this:
<GridRow childrenPadding="S">
... //Your childrens
<Grid.Row>
getPadding
could be a function returning desired value by switch case for example.
If you're using Typescript you can use enums. But in a JS way you can do this:
const getPadding = () => {
switch(props.childrenPadding):
case 'S': return '10px';
case 'M': return '15px';
... // Other choices
}
Please be aware that this function's job is to return the padding value. You can do this by if else
either.
Upvotes: 2
Reputation: 77
Taking inspiration of material ui Box
, you can create a wrapper which will accept a component
prop to mount (which will be Grid.Row
in your case). You can pass a token mapping inside (I have specified a sample padding mapping for reference)
const BoxWrapper = <K extends {}>({
component: Component,
children,
props,
...style
}: React.CSSProperties & {
component: React.ComponentType<K>;
props: K;
children: React.ReactChild;
}) => {
const tokenToValueMapping = {
s: '8px',
m: '16px',
l: '32px',
xl: '64px',
};
if (style.padding in tokenToValueMapping)
style.padding = tokenToValueMapping[style.padding];
return (
<Component style={style} {...props}>
{children}
</Component>
);
};
You can than use it to mount your components:
<BoxWrapper component='div' padding='l'>Hello World</BoxWrapper>
Upvotes: 1