import tinycolor from "tinycolor2"; interface RGBColor { r: number; g: number; b: number; a?: number; } interface HSLColor { h: number; s: number; l: number; } interface HSVColor { h: number; s: number; v: number; } /** * Takes in a color value (see https://www.npmjs.com/package/tinycolor2 * for accepted input formats) and returns a new color in rgb format * that is 30% transparent, but results in the same perceived color * as the input when layered on a white background. This is used so that * when you place an element in a container that uses linear-gradient * background images to create shadows indicating that the container * can be scrolled to reveal more content, those elements can appear * as though they are under the shadows even though they are, in fact, * on top of them. */ export function transparentEquivalentColor(color: string | RGBColor | HSLColor | HSVColor): string { const { r, g, b } = tinycolor(color).toRgb(); const newRGB = [ r, g, b, ].map((c: number): number => Math.round((c - 255 + (255 * 0.3)) / 0.3)) .join(", "); return `rgb(${newRGB}, 0.3)`; }