mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-08-09 10:35:46 +00:00
253 lines
6.6 KiB
TypeScript
253 lines
6.6 KiB
TypeScript
import colors from 'tailwindcss/colors';
|
|
import plugin from 'tailwindcss/plugin';
|
|
import { colord } from 'colord';
|
|
|
|
type Color = string;
|
|
|
|
type Colors = {
|
|
primary: Color;
|
|
primaryFocus?: Color;
|
|
primaryContent?: Color;
|
|
|
|
secondary: Color;
|
|
secondaryFocus?: Color;
|
|
secondaryContent?: Color;
|
|
|
|
accent: Color;
|
|
accentFocus?: Color;
|
|
accentContent?: Color;
|
|
|
|
neutral: Color;
|
|
neutralFocus?: Color;
|
|
neutralContent?: Color;
|
|
|
|
base100: Color;
|
|
base200?: Color;
|
|
base300?: Color;
|
|
base400?: Color;
|
|
baseContent?: Color;
|
|
|
|
info: Color;
|
|
infoFocus?: Color;
|
|
infoContent?: Color;
|
|
|
|
success: Color;
|
|
successFocus?: Color;
|
|
successContent?: Color;
|
|
|
|
warning: Color;
|
|
warningFocus?: Color;
|
|
warningContent?: Color;
|
|
|
|
error: Color;
|
|
errorFocus?: Color;
|
|
errorContent?: Color;
|
|
|
|
link: Color;
|
|
linkVisited: Color;
|
|
};
|
|
|
|
type ThemeOpts = {
|
|
name: string;
|
|
scheme: 'light' | 'dark';
|
|
colors: Colors;
|
|
};
|
|
|
|
export const theme = (opts: ThemeOpts) => {
|
|
// const foreground = (c: string) => (colord(c).isDark() ? '255 255 255' : '0 0 0');
|
|
const foreground = (c: string) =>
|
|
colord(c).isDark() ? colord(c).lighten(0.9).toHex() : colord(c).darken(0.9).toHex();
|
|
const focus = (c: string) =>
|
|
opts.scheme == 'light' ? colord(c).darken().toHex() : colord(c).lighten().toHex();
|
|
|
|
const colors: Required<Colors> = {
|
|
...opts.colors,
|
|
primaryFocus: opts.colors?.primaryFocus ?? focus(opts.colors.primary),
|
|
primaryContent: opts.colors?.primaryContent ?? foreground(opts.colors.primary),
|
|
secondaryFocus: opts.colors?.secondaryFocus ?? focus(opts.colors.secondary),
|
|
secondaryContent: opts.colors?.secondaryContent ?? foreground(opts.colors.secondary),
|
|
accentFocus: opts.colors?.accentFocus ?? focus(opts.colors.accent),
|
|
accentContent: opts.colors?.accentContent ?? foreground(opts.colors.accent),
|
|
neutralFocus: opts.colors?.neutralFocus ?? focus(opts.colors.neutral),
|
|
neutralContent: opts.colors?.neutralContent ?? foreground(opts.colors.neutral),
|
|
base200: opts.colors?.base200 ?? focus(opts.colors.base100),
|
|
base300: opts.colors?.base300 ?? focus(focus(opts.colors.base100)),
|
|
base400: opts.colors?.base400 ?? focus(focus(focus(opts.colors.base100))),
|
|
baseContent: opts.colors?.baseContent ?? foreground(opts.colors.base100),
|
|
infoFocus: opts.colors?.infoFocus ?? focus(opts.colors.info),
|
|
infoContent: opts.colors?.infoContent ?? foreground(opts.colors.info),
|
|
successFocus: opts.colors?.successFocus ?? focus(opts.colors.success),
|
|
successContent: opts.colors?.successContent ?? foreground(opts.colors.success),
|
|
warningFocus: opts.colors?.warningFocus ?? focus(opts.colors.warning),
|
|
warningContent: opts.colors?.warningContent ?? foreground(opts.colors.warning),
|
|
errorFocus: opts.colors?.errorFocus ?? focus(opts.colors.error),
|
|
errorContent: opts.colors?.errorContent ?? foreground(opts.colors.error),
|
|
};
|
|
|
|
return plugin(({ addComponents }) => {
|
|
const toKebabCase = (s: string) => s.replaceAll(/([A-Z0-9]+)/g, (x) => `-${x.toLowerCase()}`);
|
|
|
|
addComponents({
|
|
[`.theme-${opts.name}`]: Object.fromEntries(
|
|
Object.entries(colors).map(([shade, color]) => [`--${toKebabCase(shade)}`, hex2rgb(color)]),
|
|
),
|
|
});
|
|
});
|
|
};
|
|
|
|
export const hex2rgb = (hex: string) => {
|
|
hex = colord(hex).toHex();
|
|
const pick = (n: number) => parseInt(hex.slice(n, n + 2), 16);
|
|
return hex.startsWith('#') ? `${pick(1)} ${pick(3)} ${pick(5)}` : hex;
|
|
};
|
|
|
|
export const base = {
|
|
...colors,
|
|
// https://tailwind.ink?p=10.f4f9fadcf1fbb5dff785bfec539adc3f77cd345cb92a45961e2e6c121c45f7f9fbe4f0fdc7d8fb9fb5f37c8deb6568e4534bd74039b82c278a181857f9fafbefeffbded3f8c1adedad83e1955ed67c42c45d32a0402271241643fdfcfbfbeff1f7cbe4ee9ec7ec6ea5e14a89cc3168a6254c7a1a314b111afdfcfafbf0ebf8cfd7eea2b0ea7286dd4e64c635469f2833721c22461113fcfbf8faf0d8f5d7aee6ae7bd9814dc35e2ea6441d80331859231238160cfbfaf4f9f0bcf1dd80dbb94eba8f2a9b70157d560d60400c412c0b2b1b08faf9f3f7f0b9ede07bd2bd4aa69526847712695e0c51460b37300a251d08f1f6f3dbf0eaade6d072cca230ac722191491d7b351a5e2c1440220e271bf0f6f6d3f0f6a0e5eb68c9d12ea9b0218c8e1d73741a585a143c420d252e
|
|
navy: {
|
|
50: '#f4f9fa',
|
|
100: '#dcf1fb',
|
|
200: '#b5dff7',
|
|
300: '#85bfec',
|
|
400: '#539adc',
|
|
500: '#3f77cd',
|
|
600: '#345cb9',
|
|
700: '#2a4596',
|
|
800: '#1e2e6c',
|
|
900: '#121c45',
|
|
},
|
|
indigo: {
|
|
50: '#f9fafb',
|
|
100: '#efeffb',
|
|
200: '#ded3f8',
|
|
300: '#c1aded',
|
|
400: '#ad83e1',
|
|
500: '#955ed6',
|
|
600: '#7c42c4',
|
|
700: '#5d32a0',
|
|
800: '#402271',
|
|
900: '#241643',
|
|
},
|
|
cerise: {
|
|
50: '#fdfcfb',
|
|
100: '#fbeff1',
|
|
200: '#f7cbe4',
|
|
300: '#ee9ec7',
|
|
400: '#ec6ea5',
|
|
500: '#e14a89',
|
|
600: '#cc3168',
|
|
700: '#a6254c',
|
|
800: '#7a1a31',
|
|
900: '#4b111a',
|
|
},
|
|
cerise2: {
|
|
50: '#fdfcfa',
|
|
100: '#fbf0eb',
|
|
200: '#f8cfd7',
|
|
300: '#eea2b0',
|
|
400: '#ea7286',
|
|
500: '#dd4e64',
|
|
600: '#c63546',
|
|
700: '#9f2833',
|
|
800: '#721c22',
|
|
900: '#461113',
|
|
},
|
|
cocoa: {
|
|
50: '#fcfbf8',
|
|
100: '#faf0d8',
|
|
200: '#f5d7ae',
|
|
300: '#e6ae7b',
|
|
400: '#d9814d',
|
|
500: '#c35e2e',
|
|
600: '#a6441d',
|
|
700: '#803318',
|
|
800: '#592312',
|
|
900: '#38160c',
|
|
},
|
|
gold: {
|
|
50: '#fbfaf4',
|
|
100: '#f9f0bc',
|
|
200: '#f1dd80',
|
|
300: '#dbb94e',
|
|
400: '#ba8f2a',
|
|
500: '#9b7015',
|
|
600: '#7d560d',
|
|
700: '#60400c',
|
|
800: '#412c0b',
|
|
900: '#2b1b08',
|
|
},
|
|
lemon: {
|
|
50: '#faf9f3',
|
|
100: '#f7f0b9',
|
|
200: '#ede07b',
|
|
300: '#d2bd4a',
|
|
400: '#a69526',
|
|
500: '#847712',
|
|
600: '#695e0c',
|
|
700: '#51460b',
|
|
800: '#37300a',
|
|
900: '#251d08',
|
|
},
|
|
green: {
|
|
50: '#f1f6f3',
|
|
100: '#dbf0ea',
|
|
200: '#ade6d0',
|
|
300: '#72cca2',
|
|
400: '#30ac72',
|
|
500: '#219149',
|
|
600: '#1d7b35',
|
|
700: '#1a5e2c',
|
|
800: '#144022',
|
|
900: '#0e271b',
|
|
},
|
|
island: {
|
|
50: '#f0f6f6',
|
|
100: '#d3f0f6',
|
|
200: '#a0e5eb',
|
|
300: '#68c9d1',
|
|
400: '#2ea9b0',
|
|
500: '#218c8e',
|
|
600: '#1d7374',
|
|
700: '#1a585a',
|
|
800: '#143c42',
|
|
900: '#0d252e',
|
|
},
|
|
zinc: {
|
|
50: '#FAFAFA',
|
|
100: '#F4F4F5',
|
|
200: '#E4E4E7',
|
|
300: '#D4D4D8',
|
|
400: '#A1A1AA',
|
|
500: '#71717A',
|
|
600: '#52525B',
|
|
700: '#3F3F46',
|
|
800: '#27272A',
|
|
850: '#1F1F22',
|
|
900: '#18181B',
|
|
},
|
|
gray: {
|
|
50: '#F9FAFB',
|
|
100: '#F3F4F6',
|
|
200: '#E5E7EB',
|
|
300: '#D1D5DB',
|
|
400: '#9CA3AF',
|
|
500: '#6B7280',
|
|
600: '#4B5563',
|
|
700: '#374151',
|
|
800: '#1F2937',
|
|
900: '#111827',
|
|
950: '#0D131E',
|
|
},
|
|
neutral: {
|
|
50: '#FAFAFA',
|
|
100: '#F5F5F5',
|
|
200: '#E5E5E5',
|
|
300: '#D4D4D4',
|
|
400: '#A3A3A3',
|
|
500: '#737373',
|
|
600: '#525252',
|
|
700: '#404040',
|
|
800: '#262626',
|
|
900: '#171717',
|
|
},
|
|
} as const;
|