design-system icon indicating copy to clipboard operation
design-system copied to clipboard

[RFC]: Support common theme colors for CTB icons in the Icon component

Open markkaylor opened this issue 2 years ago • 0 comments

Context

CTB icons behave differently than other icons. They maintain a consistent color between themes. We provide some icons intended for custom field developers to use as CTB icons, but if they use them directly with <Icon> the color does not remain consistent between themes and therefore seem out of place within the design system.

https://user-images.githubusercontent.com/26598053/208102172-b0ce57fd-f334-48f8-856c-047dee5da438.mov

This means custom field developers have to do something like this to hard code the values to get the desired behavior.

const IconBox = styled(Flex)`
  /* Hard code color values */
  /* to stay consistent between themes */
  background-color: #f0f0ff; /* primary100 */
  border: 1px solid #d9d8ff; /* primary200 */

  svg > path {
    fill: #4945ff; /* primary600 */
  }
`;

const ColorPickerIcon = () => {
  return (
    <IconBox justifyContent="center" alignItems="center" width={7} height={6} hasRadius aria-hidden>
      <Icon as={Paint} />
    </IconBox>
  );
};

https://user-images.githubusercontent.com/26598053/208102244-d4219365-d048-4811-9d88-eb8eb8d1e939.mov

Proposal

The design system could provide a way to access a color dictionary that does not change between themes.

The Icon component could then accept a boolean prop like isConsistent or isCtbIcon and handle whether or not to use the common colors or the theme colors.

const getColorDictionary = (isConsistent, theme) => {
  if (isConsistent) {
    return theme.commonColors;
  }

  return theme.colors;
};

const IconWrapper = styled(Flex)`
  path {
    fill: ${({ isConsistent, theme, color }) => getColorDictionary(isConsistent, theme)[color]};
  }
  background-color: ${({ background, isConsistent, theme }) => getColorDictionary(isConsistent, theme)[background]};
  border-color: ${({ borderColor, isConsistent, theme }) => getColorDictionary(isConsistent, theme)[borderColor]};
  ${({ theme, colors }) => colors(theme)}
`;

export const Icon = React.forwardRef(({ as, ...props }, ref) => {
  return (
    <IconWrapper {...props} ref={ref}>
      <Box as={as} />
    </IconWrapper>
  );
});

Reasons

CTB icons use the same colors between themes according to the Figma UI kit. To my knowledge this is not possible with Icon component.

CTB icon color rules:

color: {themeColor}600
backgroundColor: {themeColor}200
borderColor: {themeColor}100

markkaylor avatar Dec 16 '22 13:12 markkaylor