Display

IconCircle

Circular container for icons

Preview

size
icon
weight

Code

import css from "./IconCircle.module.css";

import type { Icon, IconWeight } from "@phosphor-icons/react";

type Size = "xs" | "sm" | "md" | "lg";

interface ResponsiveSize {
  base: Size;
  mobile?: Size;
  tablet?: Size;
  desktop?: Size;
  wide?: Size;
}

interface IconCircleProps {
  size?: Size | ResponsiveSize;
  customSize?: string;
  customBorder?: string;
  weight: IconWeight;
  icon: Icon;
}

function getSizeClasses(size: Size | ResponsiveSize): string {
  if (typeof size === "string") {
    return css[size];
  }

  const classes = [css[`${size.base}_base`]];

  if (size.mobile) classes.push(css[`${size.mobile}_mobile`]);
  if (size.tablet) classes.push(css[`${size.tablet}_tablet`]);
  if (size.desktop) classes.push(css[`${size.desktop}_desktop`]);
  if (size.wide) classes.push(css[`${size.wide}_wide`]);

  return classes.join(" ");
}

export default function IconCircle({
  size,
  customSize,
  customBorder,
  weight,
  icon: IconComponent,
}: IconCircleProps) {
  const customStyle =
    customSize || customBorder
      ? { width: customSize, height: customSize, borderWidth: customBorder }
      : undefined;

  return (
    <div
      className={`${css.circle} ${size ? getSizeClasses(size) : ""}`}
      style={customStyle}
      aria-hidden="true"
    >
      <IconComponent weight={weight} />
    </div>
  );
}

Props

PropTypeRequiredDescription
iconIconrequiredPhosphor icon component to render. Decorative, hidden from screen readers.
weightIconWeightrequiredIcon stroke weight.
size"xs" | "sm" | "md" | "lg" | ResponsiveSize—Circle diameter and border width. Omit it only if you pass customSize. Fixed or responsive.
customSizestring—Custom diameter (any CSS unit); replaces size.
customBorderstring—Custom border width (any CSS unit).