* reconciles latest color variables from Figma * defines the primary colors and the color system in tailwind config. * refines how we generate utilities within the color system for `bg`, `fg` and `border`. * removes custom box shadows, instead leaning on direct definition in CSS and `theme()`. This change removes duplicate color information being defined as CSS variables in `index.css` and co-locates all style information with the component whilst retaining the ability to tie in to the color system when mapping styles from Figma.
299 lines
7.7 KiB
TypeScript
299 lines
7.7 KiB
TypeScript
import plugin from "tailwindcss/plugin";
|
|
// @ts-expect-error: lib of tailwind has no types
|
|
import { parseColor } from "tailwindcss/lib/util/color";
|
|
import { CSSRuleObject, RecursiveKeyValuePair } from "tailwindcss/types/config";
|
|
|
|
/* Converts HEX color to RGB */
|
|
const toRGB = (value: string) =>
|
|
"rgb(" + parseColor(value).color.join(" ") + ")";
|
|
|
|
const primaries = {
|
|
off: {
|
|
white: toRGB("#ffffff"),
|
|
black: toRGB("#000000"),
|
|
},
|
|
primary: {
|
|
50: toRGB("#f4f9f9"),
|
|
100: toRGB("#dbeceb"),
|
|
200: toRGB("#b6d9d6"),
|
|
300: toRGB("#8abebc"),
|
|
400: toRGB("#478585"),
|
|
500: toRGB("#526f6f"),
|
|
600: toRGB("#4b6767"),
|
|
700: toRGB("#345253"),
|
|
800: toRGB("#2e4a4b"),
|
|
900: toRGB("#203637"),
|
|
950: toRGB("#162324"),
|
|
},
|
|
secondary: {
|
|
50: toRGB("#f7f9fa"),
|
|
100: toRGB("#e7f2f4"),
|
|
200: toRGB("#d8e8eb"),
|
|
300: toRGB("#afc6ca"),
|
|
400: toRGB("#90b2b7"),
|
|
500: toRGB("#7b9b9f"),
|
|
600: toRGB("#4f747a"),
|
|
700: toRGB("#415e63"),
|
|
800: toRGB("#446065"),
|
|
900: toRGB("#2c4347"),
|
|
950: toRGB("#0d1416"),
|
|
},
|
|
error: {
|
|
50: toRGB("#fff0f4"),
|
|
100: toRGB("#ffe2ea"),
|
|
200: toRGB("#ffcadb"),
|
|
300: toRGB("#ff9fbd"),
|
|
400: toRGB("#ff699b"),
|
|
500: toRGB("#ff2c78"),
|
|
600: toRGB("#ed116b"),
|
|
700: toRGB("#c8085b"),
|
|
800: toRGB("#a80953"),
|
|
900: toRGB("#8f0c4d"),
|
|
950: toRGB("#500126"),
|
|
},
|
|
info: {
|
|
50: toRGB("#eff9ff"),
|
|
100: toRGB("#d6ebff"),
|
|
200: toRGB("#b5deff"),
|
|
300: toRGB("#83cbff"),
|
|
400: toRGB("#48adff"),
|
|
500: toRGB("#1e88ff"),
|
|
600: toRGB("#0666ff"),
|
|
700: toRGB("#0051ff"),
|
|
800: toRGB("#083fc5"),
|
|
900: toRGB("#0d3a9b"),
|
|
950: toRGB("#0e245d"),
|
|
},
|
|
success: {
|
|
50: toRGB("#eefff3"),
|
|
100: toRGB("#d7ffe4"),
|
|
200: toRGB("#b2ffcb"),
|
|
300: toRGB("#76ffa4"),
|
|
400: toRGB("#34f475"),
|
|
500: toRGB("#0ae856"),
|
|
600: toRGB("#01b83f"),
|
|
700: toRGB("#059035"),
|
|
800: toRGB("#0a712e"),
|
|
900: toRGB("#0b5c29"),
|
|
950: toRGB("#003414"),
|
|
},
|
|
warning: {
|
|
50: toRGB("#feffe4"),
|
|
100: toRGB("#faffc4"),
|
|
200: toRGB("#faffc4"),
|
|
300: toRGB("#e8ff50"),
|
|
400: toRGB("#d4ff00"),
|
|
500: toRGB("#b9e600"),
|
|
600: toRGB("#90b800"),
|
|
700: toRGB("#6c8b00"),
|
|
800: toRGB("#556d07"),
|
|
900: toRGB("#485c0b"),
|
|
950: toRGB("#253400"),
|
|
},
|
|
};
|
|
|
|
const colorSystem = {
|
|
bg: {
|
|
def: {
|
|
1: primaries.off.white,
|
|
2: primaries.secondary["50"],
|
|
3: primaries.secondary["100"],
|
|
4: primaries.secondary["200"],
|
|
acc: {
|
|
1: primaries.primary["50"],
|
|
2: primaries.secondary["100"],
|
|
3: primaries.secondary["200"],
|
|
4: primaries.secondary["300"],
|
|
},
|
|
},
|
|
semantic: {
|
|
error: {
|
|
1: primaries.error["50"],
|
|
2: primaries.error["100"],
|
|
3: primaries.error["200"],
|
|
4: primaries.error["300"],
|
|
},
|
|
info: {
|
|
1: primaries.info["50"],
|
|
2: primaries.info["100"],
|
|
3: primaries.info["200"],
|
|
4: primaries.info["300"],
|
|
},
|
|
success: {
|
|
1: primaries.success["50"],
|
|
2: primaries.success["100"],
|
|
3: primaries.success["200"],
|
|
4: primaries.success["300"],
|
|
},
|
|
warning: {
|
|
1: primaries.warning["50"],
|
|
2: primaries.warning["100"],
|
|
3: primaries.warning["200"],
|
|
4: primaries.warning["300"],
|
|
},
|
|
},
|
|
inv: {
|
|
1: primaries.primary["600"],
|
|
2: primaries.primary["700"],
|
|
3: primaries.primary["800"],
|
|
4: primaries.primary["900"],
|
|
acc: {
|
|
1: primaries.secondary["500"],
|
|
2: primaries.secondary["600"],
|
|
3: primaries.secondary["900"],
|
|
4: primaries.secondary["950"],
|
|
},
|
|
},
|
|
},
|
|
border: {
|
|
def: {
|
|
1: primaries.secondary["100"],
|
|
2: primaries.secondary["200"],
|
|
3: primaries.secondary["300"],
|
|
4: primaries.secondary["400"],
|
|
acc: {
|
|
1: primaries.secondary["500"],
|
|
2: primaries.secondary["900"],
|
|
3: primaries.secondary["900"],
|
|
4: primaries.secondary["950"],
|
|
},
|
|
},
|
|
semantic: {
|
|
error: {
|
|
1: primaries.error["100"],
|
|
2: primaries.error["200"],
|
|
3: primaries.error["300"],
|
|
4: primaries.error["400"],
|
|
},
|
|
info: {
|
|
1: primaries.info["100"],
|
|
2: primaries.info["200"],
|
|
3: primaries.info["300"],
|
|
4: primaries.info["400"],
|
|
},
|
|
success: {
|
|
1: primaries.success["100"],
|
|
2: primaries.success["200"],
|
|
3: primaries.success["300"],
|
|
4: primaries.success["400"],
|
|
},
|
|
warning: {
|
|
1: primaries.warning["100"],
|
|
2: primaries.warning["200"],
|
|
3: primaries.warning["300"],
|
|
4: primaries.warning["400"],
|
|
},
|
|
},
|
|
inv: {
|
|
1: primaries.secondary["700"],
|
|
2: primaries.secondary["800"],
|
|
3: primaries.secondary["900"],
|
|
4: primaries.secondary["950"],
|
|
acc: {
|
|
1: primaries.secondary["300"],
|
|
2: primaries.secondary["200"],
|
|
3: primaries.secondary["100"],
|
|
4: primaries.secondary["50"],
|
|
},
|
|
},
|
|
},
|
|
fg: {
|
|
def: {
|
|
1: primaries.secondary["950"],
|
|
2: primaries.secondary["900"],
|
|
3: primaries.secondary["700"],
|
|
4: primaries.secondary["400"],
|
|
},
|
|
inv: {
|
|
1: primaries.off.white,
|
|
2: primaries.secondary["100"],
|
|
3: primaries.secondary["300"],
|
|
4: primaries.secondary["400"],
|
|
},
|
|
semantic: {
|
|
error: {
|
|
1: primaries.error["500"],
|
|
2: primaries.error["600"],
|
|
3: primaries.error["700"],
|
|
4: primaries.error["800"],
|
|
},
|
|
info: {
|
|
1: primaries.info["500"],
|
|
2: primaries.info["600"],
|
|
3: primaries.info["700"],
|
|
4: primaries.info["800"],
|
|
},
|
|
success: {
|
|
1: primaries.success["500"],
|
|
2: primaries.success["600"],
|
|
3: primaries.success["700"],
|
|
4: primaries.success["800"],
|
|
},
|
|
warning: {
|
|
1: primaries.warning["500"],
|
|
2: primaries.warning["600"],
|
|
3: primaries.warning["700"],
|
|
4: primaries.warning["800"],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
function isString(value: unknown): value is string {
|
|
return typeof value === "string";
|
|
}
|
|
|
|
const mkColorUtil = (
|
|
path: string[],
|
|
property: string,
|
|
config: string | RecursiveKeyValuePair,
|
|
): CSSRuleObject => {
|
|
if (isString(config)) {
|
|
return {
|
|
[`.${path.join("-")}`]: {
|
|
[`${property}`]: config,
|
|
},
|
|
};
|
|
}
|
|
|
|
return Object.entries(config as RecursiveKeyValuePair)
|
|
.map(([subKey, subConfig]) =>
|
|
mkColorUtil([...path, subKey], property, subConfig),
|
|
)
|
|
.reduce((acc, curr) => ({ ...acc, ...curr }), {});
|
|
};
|
|
|
|
export default plugin.withOptions(
|
|
(_options = {}) =>
|
|
({ addUtilities, theme, addVariant, e }) => {
|
|
// @ts-expect-error: lib of tailwind has no types
|
|
addVariant("popover-open", ({ modifySelectors, separator }) => {
|
|
// @ts-expect-error: lib of tailwind has no types
|
|
modifySelectors(({ className }) => {
|
|
return `.${e(`popover-open${separator}${className}`)}:popover-open`;
|
|
});
|
|
});
|
|
|
|
const { bg, fg, border } = colorSystem;
|
|
|
|
addUtilities(mkColorUtil(["bg"], "backgroundColor", bg));
|
|
addUtilities(mkColorUtil(["fg"], "color", fg));
|
|
addUtilities(mkColorUtil(["border"], "borderColor", border));
|
|
addUtilities(mkColorUtil(["border-t"], "borderTop", border));
|
|
addUtilities(mkColorUtil(["border-r"], "borderRight", border));
|
|
addUtilities(mkColorUtil(["border-b"], "borderBottom", border));
|
|
addUtilities(mkColorUtil(["border-l"], "borderLeft", border));
|
|
},
|
|
// add configuration which is merged with the final config
|
|
() => ({
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
...primaries,
|
|
...colorSystem,
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
);
|