feat: enable TS strict mode (#168)

* feat: enable TS strict mode

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: colors bug with default

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: text type errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors - add definite assignment assertion

* fix: strict TS errors - add definite assignment assertion

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix(ESLint): error on no-explicit-any

* fix: type annotations for any types

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors (and remove packages)

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* fix: strict TS errors

* feat: enable React.StrictMode

* fix: strict TS errors (done!)

* fix: build error

* fix: replace no-explicit-any assertions

* refactor: cleanup

* refactor: more cleanup

* style: prettier

---------

Co-authored-by: Lukas Zenick <lukas@utexas.edu>
Co-authored-by: Razboy20 <razboy20@gmail.com>
This commit is contained in:
doprz
2024-03-21 13:19:40 -05:00
committed by GitHub
parent 0c76052478
commit efed1c0edb
61 changed files with 562 additions and 1309 deletions

View File

@@ -4,7 +4,7 @@ import { theme } from 'unocss/preset-mini';
import type { HexColor, Lab, RGB, sRGB } from '../types/Color';
import { isHexColor } from '../types/Color';
import type { Course } from '../types/Course';
import type { CourseColors, TWColorway } from '../types/ThemeColors';
import type { CourseColors, TWColorway, TWIndex } from '../types/ThemeColors';
import { colorwayIndexes } from '../types/ThemeColors';
import type { UserSchedule } from '../types/UserSchedule';
@@ -14,18 +14,21 @@ import type { UserSchedule } from '../types/UserSchedule';
* @param hex - The hexadecimal color value.
* @returns An array containing the RGB values.
*/
export function hexToRGB(hex: HexColor): RGB {
export function hexToRGB(hex: HexColor): RGB | undefined {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
let shorthandRegex: RegExp = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const parsedHex: string = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);
let shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
const parsedHex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);
let result: RegExpExecArray = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(parsedHex);
return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : null;
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(parsedHex);
if (!result || !(result.length > 3)) return undefined;
return [parseInt(result[1]!, 16), parseInt(result[2]!, 16), parseInt(result[3]!, 16)];
}
export const useableColorways = Object.keys(theme.colors)
// check that the color is a colorway (is an object)
.filter(color => typeof theme.colors[color] === 'object')
.filter(color => typeof theme.colors[color as keyof typeof theme.colors] === 'object')
.slice(0, 17) as TWColorway[];
/**
@@ -33,12 +36,16 @@ export const useableColorways = Object.keys(theme.colors)
* @param bgColor the hex color of the background
*/
export function pickFontColor(bgColor: HexColor): 'text-white' | 'text-black' | 'text-theme-black' {
const coefficients = [0.2126729, 0.7151522, 0.072175];
const coefficients = [0.2126729, 0.7151522, 0.072175] as const;
const flipYs = 0.342; // based on APCA™ 0.98G middle contrast BG color
const trc = 2.4; // 2.4 exponent for emulating actual monitor perception
let Ys = hexToRGB(bgColor).reduce((acc, c, i) => acc + (c / 255.0) ** trc * coefficients[i], 0);
const rgb = hexToRGB(bgColor);
if (!rgb) throw new Error('bgColor: Invalid hex.');
// coefficients and rgb are both 3 elements long, so this is safe
let Ys = rgb.reduce((acc, c, i) => acc + (c / 255.0) ** trc * coefficients[i]!, 0);
if (Ys < flipYs) {
return 'text-white';
@@ -54,13 +61,13 @@ export function pickFontColor(bgColor: HexColor): 'text-white' | 'text-black' |
export function getCourseColors(colorway: TWColorway, index?: number, offset: number = 300): CourseColors {
if (index === undefined) {
// eslint-disable-next-line no-param-reassign
index = colorway in colorwayIndexes ? colorwayIndexes[colorway] : 500;
index = colorway in colorwayIndexes ? colorwayIndexes[colorway as keyof typeof colorwayIndexes] : 500;
}
return {
primaryColor: theme.colors[colorway][index],
secondaryColor: theme.colors[colorway][index + offset],
} satisfies CourseColors;
primaryColor: theme.colors[colorway][index as TWIndex] as HexColor,
secondaryColor: theme.colors[colorway][(index + offset) as TWIndex] as HexColor,
};
}
/**
@@ -87,7 +94,12 @@ export function getColorwayFromColor(color: HexColor): TWColorway {
continue;
}
const distance = oklabDistance(rgbToOKlab(hexToRGB(shadeColor)), rgbToOKlab(hexToRGB(color)));
const shadeColorRGB = hexToRGB(shadeColor);
if (!shadeColorRGB) {
continue;
}
const distance = oklabDistance(rgbToOKlab(shadeColorRGB), rgbToOKlab(shadeColorRGB));
if (distance < closestDistance) {
closestDistance = distance;
closestColor = shade;
@@ -148,7 +160,8 @@ export function getUnusedColor(
if (sameDepartment.length > 0) {
// check to see if any adjacent colorways are available
const centerCourse = sameDepartment[Math.floor(Math.random() * sameDepartment.length)];
const centerCourse = sameDepartment[Math.floor(Math.random() * sameDepartment.length)]!;
let nextColorway = getNextColorway(centerCourse.colorway);
let prevColorway = getPreviousColorway(centerCourse.colorway);
@@ -175,11 +188,18 @@ export function getUnusedColor(
if (shortenedColorways.size > 0) {
// TODO: make this go by 3's to leave future spaces open
const randomColorway = Array.from(shortenedColorways)[Math.floor(Math.random() * shortenedColorways.size)];
const randomColorway = Array.from(shortenedColorways)[Math.floor(Math.random() * shortenedColorways.size)]!;
return getCourseColors(randomColorway, index, offset);
}
// no colorways are at least 2 indexes away from any used colors, just get a random colorway
const randomColorway = Array.from(availableColorways)[Math.floor(Math.random() * availableColorways.size)];
const randomColorway: TWColorway | undefined =
Array.from(availableColorways)[Math.floor(Math.random() * availableColorways.size)];
if (!randomColorway) {
throw new Error('randomColorway is undefined');
}
return getCourseColors(randomColorway, index, offset);
}
// TODO: get just a random color idk