Skip to content
Source
Sign inSign up

projectIdentity.ts

41 lines1.3 KB

1import { PROJECT_ICON_COLORS } from "./projectIconColors";
2import type { ProjectIconColor } from "@t3tools/contracts";
3​
4export interface ProjectIdentity {
5 readonly monogram: string;
6 readonly color: ProjectIconColor;
7}
8​
9function normalizeProjectName(projectName: string): string {
10 return projectName.normalize("NFKC").trim();
12​
13function projectMonogram(projectName: string): string {
14 const words = normalizeProjectName(projectName).match(/[\p{L}\p{N}]+/gu) ?? [];
15 const firstWord = words[0];
16 if (!firstWord) return "PR";
17​
18 const glyphs = Array.from(firstWord);
19 const first = glyphs[0] ?? "P";
20 const second =
21 glyphs.slice(1).find((glyph) => /\p{N}/u.test(glyph)) ??
22 (words.length > 1 ? Array.from(words.at(-1) ?? "")[0] : glyphs.at(-1)) ??
23 first;
24 return Array.from(`${first}${second}`.toUpperCase()).slice(0, 2).join("");
26​
27function projectColor(projectName: string): ProjectIconColor {
28 const seed = normalizeProjectName(projectName).toLocaleLowerCase("en-US") || "project";
29 let index = 0;
30 for (const glyph of seed) {
31 index = (index * 31 + (glyph.codePointAt(0) ?? 0)) % PROJECT_ICON_COLORS.length;
32 }
33 return PROJECT_ICON_COLORS[index]?.value ?? "blue";
35​
36export function deriveProjectIdentity(projectName: string): ProjectIdentity {
37 return {
38 monogram: projectMonogram(projectName),
39 color: projectColor(projectName),
40 };