components icon indicating copy to clipboard operation
components copied to clipboard

Make a ColorFrame component

Open ghost opened this issue 2 years ago • 2 comments

Goal

Our callouts always have an icon.

We want to let users make a frame without an icon.

You can use the Callout Template code and pass different props to it.

Schema

<ColorFrame borderColor={hexcode} backgroundColor={hexcode} />

ghost avatar Mar 07 '23 17:03 ghost

Can I work on this issue?

juank1809 avatar Mar 23 '23 18:03 juank1809

Hey! Just recently discovered Mintlify and would love to contribute. Here's a loom of the feature, let me know what you all think!

Design decisions

  • I opted to go for a single color input to control the component because as a developer, that's the experience I'd prefer - simply give the component a color and it handles border, background color, text color and opacity.
  • I added a dark mode control because in order to use tailwind's built in system dynamically, I'd need to change tailwind.config.js to include all the colors. Plus this wouldn't give the flexibility I'd personally expect from a component like this.
  • To make the color dynamics match the existing callouts, I used tinycolor2, a small NPM package that handles color manipulation.

Code

I'm unable to push to a separate branch, so here's the code for the component to inspect. Would love feedback!

type ColorFrameProps = {
  children: ReactNode;
  frameColor: string; // Will handle broder, background and text color.
  darkMode: boolean;
};

// mintlify: 2ab673
// sieve: 7240ff
function frameColorStyles(frameColor: string, darkMode: boolean) {
  const baseColor = tinycolor(frameColor);
  const brightness = baseColor.getBrightness();
  const lighteningAmount = 30 + (100 - brightness) * 0.25;
  const darkeningAmount = 50 - brightness * 0.25;

  const lightModeStyles = {
    borderColor: baseColor.clone().setAlpha(0.3).toRgbString(),
    backgroundColor: baseColor.clone().lighten(lighteningAmount).setAlpha(0.5).toRgbString(),
    textColor: baseColor.clone().darken(darkeningAmount).toRgbString(),
  };

  const darkModeStyles = {
    borderColor: baseColor.clone().setAlpha(0.4).toRgbString(),
    backgroundColor: baseColor.clone().setAlpha(0.1).toRgbString(),
    textColor: baseColor.clone().lighten(30).toRgbString(),
  };

  return darkMode ? darkModeStyles : lightModeStyles;
}

export function ColorFrame({ children, frameColor, darkMode }: ColorFrameProps) {
  const { borderColor, backgroundColor, textColor } = frameColorStyles(frameColor, darkMode);

  return (
    <CalloutTemplate
      className="border"
      style={{
        borderColor,
        backgroundColor,
      }}
      childrenStyle={{
        color: textColor,
      }}
      childrenClassName=""
    >
      {children}
    </CalloutTemplate>
  );
}

albTian avatar May 01 '23 16:05 albTian