skip to Main Content

I have a react button component that pulls in button classnames from a module.scss file.
It works just fine if I want to select a single style/class from my object, but I can’t figure out how to display multiple (in the case I want to use augment classes). I have tried fiddling around with arrays but can’t seem to get it.

Button.jsx component code

import React from "react";
import styles from "./button.module.scss";
import Link from "next/link";

const {
  buttonPrimary,
  buttonSecondary,
  buttonTertiary,
  smallButton
} = styles;

export const Button = ({
                         variant = "primary",
                         label,
                         href,
                         ...props // allows for other custom props
                       }) => {
  const variants = {
    primary: buttonPrimary,
    secondary: buttonSecondary,
    tertiary: buttonTertiary,
    small: smallButton
  };

    return (
      <Link href={href ? href : "#"}>
        <a className={${variants[variant]}}>
          {label}
        </a>
      </Link>
    );
};

Component usage in jsx page:

<Button label={'Test'} variant={'primary'}/>

Desired outcome would be to have multiple variants selectable from the list, so we can combine them E.G.:

<Button label={'Test'} variant={['primary', 'small']} />

Thanks in advance 🙂

2

Answers


  1. You need to map the variants to the class names from the scss module. (And separate them with spaces)

    const classNames = variant.map(v =>  variants[v]).join(' ')
    

    In your component it’d be:

    import React from "react";
    import styles from "./button.module.scss";
    import Link from "next/link";
    
    const {
      buttonPrimary,
      buttonSecondary,
      buttonTertiary,
      smallButton
    } = styles;
    
    export const Button = ({
                             variant = "primary",
                             label,
                             href,
                             ...props // allows for other custom props
                           }) => {
      const variants = {
        primary: buttonPrimary,
        secondary: buttonSecondary,
        tertiary: buttonTertiary,
        small: smallButton
      };
    
        return (
          <Link href={href ? href : "#"}>
            <a className={variant.map(v => variants[v]).join(' ')}>
              {label}
            </a>
          </Link>
        );
    };
    
    Login or Signup to reply.
  2. If you really want to keep the possibilities to pass one element outside of an array you can do something like this :

    return (
      <Link href={href ? href : "#"}>
        <a className={[variant].flat().map((current) => variants[current]).join(' '))}>
          {label}
        </a>
      </Link>
    );
    

    What this does is :

    • Put the variant prop in a array
    • Use the flat method to transform an eventual 2D array to a 1D array (So [['primary']] become ['primary'] for example (a 1D array remains a 1D array)
    • Use the map method to get an array of the differents variants (each return value replace the current element)
    • Transform the final array into a string, separating each element with an empty space
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search