Files
calendar/packages/config/theme/generateColor.ts
T
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
357c2882ad refactor: apply biome formatting to several packages (#27439)
* refactor: apply biome formatting to Phase 1 packages

Packages formatted:
- packages/app-store-cli
- packages/config
- packages/dayjs
- packages/debugging
- packages/embeds/embed-react
- packages/embeds/embed-snippet
- packages/kysely
- packages/platform/constants
- packages/platform/utils
- packages/testing
- packages/tsconfig

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore non-null assertions in embed-snippet to fix type error

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: remove ESM import from CommonJS config file

Biome incorrectly added 'import process from node:process' to a CommonJS
file that uses require(). This breaks Jest which expects CommonJS syntax.
The process global is already available in Node.js without explicit import.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: exclude packages/embeds from Phase 1 formatting

Per user request, reverting all biome formatting changes in packages/embeds
to handle separately.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore const enum for BookingLocations

Biome changed 'const enum' to 'enum' which is a semantic change.
Reverting to keep the PR purely formatting-only.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 07:24:34 -03:00

86 lines
2.2 KiB
TypeScript

import type { Color, HSL, Shade } from "./interfaces";
// Yeah i stole this...
const hexToHSL = (hex: string): HSL => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) || [];
try {
let r = parseInt(result[1], 16);
let g = parseInt(result[2], 16);
let b = parseInt(result[3], 16);
(r /= 255), (g /= 255), (b /= 255);
const max = Math.max(r, g, b),
min = Math.min(r, g, b);
let h = 0,
s,
// eslint-disable-next-line prefer-const
l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
const HSL: HSL = { h: 0, s: 0, l: 0 };
HSL.h = Math.round(h * 360);
HSL.s = Math.round(s * 100);
HSL.l = Math.round(l * 100);
return HSL;
} catch (_error) {
console.log(hex);
return { h: 0, s: 0, l: 0 };
}
};
const hslToHex = ({ h, s, l }: HSL): string => {
l /= 100;
const a = (s * Math.min(l, 1 - l)) / 100;
const f = (n: number) => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color)
.toString(16)
.padStart(2, "0"); // convert to Hex and prefix "0" if needed
};
return `#${f(0)}${f(8)}${f(4)}`;
};
const HSL_SHADES: Shade[] = [
{ name: "50", lightness: 98 },
{ name: "100", lightness: 95 },
{ name: "200", lightness: 90 },
{ name: "300", lightness: 82 },
{ name: "400", lightness: 64 },
{ name: "500", lightness: 46 },
{ name: "600", lightness: 33 },
{ name: "700", lightness: 24 },
{ name: "800", lightness: 14 },
{ name: "900", lightness: 7 },
];
const generateColor = ({ hex }: { hex: string }): Color => {
const colorHSL = hexToHSL(hex);
const obj: Color = {};
HSL_SHADES.forEach(({ name, lightness }: Shade) => {
const { h, s } = colorHSL;
const hsl: HSL = { h, s, l: lightness };
const hex = hslToHex(hsl);
obj[name] = hex;
});
return obj;
};
export { generateColor };