Button Group B

A group of buttons that are displayed together. They are often used to present a set of related options to the user.

Preview

Code

import React, { CSSProperties, ReactNode } from "react"; import styles from "./button-group-b.module.css"; // ButtonItem type (element of buttons array of the ButtonGroupA) type ButtonItemType = { icon?: React.ReactNode; content?: React.ReactNode; className?: string; style?: CSSProperties; type?: "button" | "submit" | "reset" | "link" | "static"; href?: string; iconOnly?: boolean; iconPosition?: "before-text" | "after-text"; active?: boolean; // Put additional variants here, then define them in the CSS as .btn-color-XXX variant?: | "default" | "light" | "light-opaque" | "dark" | "dark-opaque" | "blue"; // Optional event handler onClick?: React.MouseEventHandler; }; // Button Component function ButtonItem({ content, icon, style, className, active, iconOnly, iconPosition = "before-text", type, variant, href, onClick, }: ButtonItemType) { const _classNames = [ styles["button"], styles[`btn-color-${variant}`], styles[`icon-${iconPosition}`], active && styles[`active`], type === "static" && styles[`static`], iconOnly && styles[`icon-only`], className, ].join(" "); const buttonContent = ( <> {icon && <span className={styles["icon"]}>{icon}</span>} {content && !iconOnly && ( <span className={styles["text"]}>{content}</span> )} </> ); // type of the button if (type === "link" || href) { // You may need to replace the <a ...> element with a Link if you use Next or Remix. return ( <a href={href} onClick={onClick} className={_classNames} style={style} title={`${content}`} > {buttonContent} </a> ); } else if (type === "static") { // Static such as text only return ( <span onClick={onClick} className={_classNames} style={style}> {buttonContent} </span> ); } else { // Button return ( <button type={type} className={_classNames} style={style} onClick={onClick} title={`${content}`} > {buttonContent} </button> ); } } // ButtonGroupA props type Props = { className?: string; buttons?: ButtonItemType[]; size?: "x-small" | "small" | "medium" | "large"; width?: "fit" | "full"; gap?: "none" | "small" | "medium"; rounded?: "none" | "small" | "medium" | "large" | "full"; // Put additional variants here, then define them in the CSS as .color-XXX variant?: | "default" | "light" | "light-opaque" | "dark" | "dark-opaque" | "blue"; }; export default function ButtonGroupB({ buttons, className, size = "medium", width = "fit", gap = "medium", rounded = "medium", variant = "default", }: Props) { return ( <div className={[ styles["group"], styles[`s-${size}`], styles[`w-${width}`], styles[`g-${gap}`], styles[`r-${rounded}`], styles[`variant-${variant}`], className, ].join(" ")} > {buttons?.map((buttonItem, index) => { return ( <ButtonItem key={`button-${index}`} {...buttonItem} variant={buttonItem.variant || variant} /> ); })} </div> ); }

Design

Figma design file:

Documentation

Properties

Props of the component:

  • buttons (Array of ButtonItemType): Specifies the buttons of the group. A button item is a ButtonItemType (see below).

  • className (string): Specifies the CSS class of the component.

  • size ("x-small" | "small" | "medium" | "large"): Specifies the size of the buttons.

  • width ("fit" | "full"): Specifies the width of the button group. "full" will make the button occupy 100% of the width of the parent and "fit" will set the width of the button group to the width of the content.

  • gap ("none" | "small" | "medium"): Specifies the gap between buttons.

  • rounded ("none" | "small" | "medium" | "large" | "full"): Specifies the border radius of the frame.

  • variant ("default" | "light" | "dark" | "blue" or a customized value): Specifies the color or theme variant of the component. See the "Sample CSS customization" below for an example of usage.

ButtonItemType item arguments
  • className (string): Specifies the CSS class of the button.
  • style (CSSProperties): Specifies the CSS properties of the button.
  • type ("button" | "submit" | "reset" | "link" | "static"): Specifies the type of the button. "button", "submit" and "reset" will render a button HTML element, "link" will render a HTML element, and "static" will render it a span.
  • href (string): Specifies the url of the button if it is a link.
  • icon (ReactNode): Specifies the icon component.
  • content (string): Specifies the title text.
  • iconOnly (boolean): Show only the icon.
  • iconPosition ("before-text" | "after-text"): Specifies if the icon will be placed after of before the text content.
  • variant ("default" | "light" | "dark" | "blue" or a customized value): Specifies the color or theme variant of the component. See the "Sample CSS customization" below for an example of usage.
  • onClick (function): Fires when the button is clicked.
Sample CSS customization

Sample customization for color="blue" or button item color:"blue".

.btn-color-blue { --btn-fg-color: #567FEF; --btn-bg-color: transparent; --btn-hover-fg-color: #567FEF; --btn-hover-bg-color: rgba(86, 127, 239, 0.17); }