layer5io / layer5io/sistent

Create a base `Icon` to derive from when creating icons

Open
#589 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind/enhancement
Dominant language
TypeScript
Stars
137
Forks
239
Avg merge
4d 14h
Merged PRs (30d)
5

Description

Current Behavior

We have multiple icons that needs to be refactored to reduce duplication on variables and constants, and rather rely on one icon to use from.

Desired Behavior
  • Create base SistentIcon
  • Widen the IconProps to include sx props as an optional field to be used with MUI
  • Add size field in IconProps to provide the default sizes for xsmall, small, medium, large, and xlarge
Implementation

The below describes the SistentIcon that will wraps the svg path or else with Box, doesn't have to be box, it can be a div.

The children was changed to allow child elements within the div or Box

export type IconSize = "xsmall" | "small" | "medium" | "large";

export type IconProps = {
  children?: React.ReactNode;
  color?: string;
  title?: string;
  width?: number | string;
  height?: number | string;
  size?: IconSize;
  sx?: SxProps<Theme>;
} & Omit<BoxProps, "sx"> &
  React.SVGProps<SVGSVGElement>;

const iconSizes: Record<IconSize, { width: number; height: number }> = {
  xsmall: { width: 16, height: 16 },
  small: { width: 24, height: 24 },
  medium: { width: 32, height: 32 },
  large: { width: 40, height: 40 },
};

export default function SistentIcon({
  color,
  title,
  size = "medium",
  fill = CHARCOAL_FILL,
  viewBox,
  sx,
  children,
  ...rest
}: IconProps) {
  const { width, height } = iconSizes[size];

  return (
    <Box
      component={"svg"}
      xmlns="http://www.w3.org/2000/svg"
      width={width}
      height={height}
      viewBox={viewBox}
      fill={fill || color}
      sx={sx}
      {...rest}
    >
      {title && <title>{title}</title>}
      {children}
    </Box>
  );
}

The fill will be a default color, in this case charcoal. This can be changed inline in project specific. You can also use sx props from MUI in order to use the theme inline.

            <IconButton
              aria-label="close"
              onClick={onClose}
              sx={(theme) => ({
                "&:hover": {
                  "& svg": {
                    fill: theme.palette.keppelGreen,
                  },
                },
              })}
              disableRipple
            >
              <CloseIcon
                sx={(theme) => ({
                  fill: theme.palette.charcoal,
                })}
              />
            </IconButton>
Acceptance Tests
Mockups

Contributor Guide

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the existing IconProps and icon components in the Sistent frontend, then compare their shared variables and constants with the proposed SistentIcon implementation. Done means a reusable base icon supports children, MUI sx props, color, title, and the defined size presets, with the duplicated icons refactored to use it.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
design, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.