harshikerfuffle
harshikerfuffle

Reputation: 253

React: Make padding into a component

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

Answers (2)

Hossein Ahmadi
Hossein Ahmadi

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.

  • children
  • childrenPadding

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

Usman Mani
Usman Mani

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

Related Questions