Files
simple-react-app-kit/packages/appearance/src/display.ts
T

78 lines
2.0 KiB
TypeScript
Raw Normal View History

import type { ThemeScheme } from "./internal/themes"
export type Brightness = "dim" | "normal" | "bright"
export type MotionMode = "system" | "reduce" | "full"
export type ResolvedMotionMode = Exclude<MotionMode, "system">
export type TextScale = "100" | "125" | "150" | "200"
export const brightnessModes = [
"dim",
"normal",
"bright",
] as const satisfies readonly Brightness[]
export const motionModes = [
"system",
"reduce",
"full",
] as const satisfies readonly MotionMode[]
export const textScales = [
"100",
"125",
"150",
"200",
] as const satisfies readonly TextScale[]
export const BRIGHTNESS_ATTRIBUTE = "data-ui-brightness"
export const MOTION_ATTRIBUTE = "data-ui-motion"
export const TEXT_SCALE_ATTRIBUTE = "data-ui-text-scale"
const surfaceVariableNames = [
"background",
"card",
"popover",
"secondary",
"muted",
"highlight",
"sidebar",
] as const
export function isBrightness(value: unknown): value is Brightness {
return brightnessModes.some((mode) => mode === value)
}
export function isMotionMode(value: unknown): value is MotionMode {
return motionModes.some((mode) => mode === value)
}
export function isTextScale(value: unknown): value is TextScale {
return textScales.some((scale) => scale === value)
}
/**
* Adjusts interface surfaces without filtering media, illustrations, or brand
* colors. Foreground colors are preserved so dimming does not reduce contrast.
*/
export function applyBrightnessToTheme(
variables: Record<string, string>,
brightness: Brightness,
scheme: ThemeScheme
): Record<string, string> {
if (brightness === "normal") return variables
const target = brightness === "dim" ? "black" : "white"
const amount = {
bright: scheme === "light" ? 12 : 8,
dim: scheme === "light" ? 5 : 12,
}[brightness]
const adjusted = { ...variables }
for (const name of surfaceVariableNames) {
const value = variables[name]
if (value) {
adjusted[name] = `color-mix(in oklch,${value},${target} ${amount}%)`
}
}
return adjusted
}