33 lines
1.4 KiB
TypeScript
33 lines
1.4 KiB
TypeScript
export const DEFAULT_PORTAL_COLOR = "#69c350"
|
|
|
|
export function normalizePortalColor(value: unknown): string | null {
|
|
if (typeof value !== "string") return null
|
|
const color = value.trim().toLowerCase()
|
|
return /^#[0-9a-f]{6}$/.test(color) ? color : null
|
|
}
|
|
|
|
export function getPortalColor(config: any): string {
|
|
// Older tenant records contain the misspelled key from the original schema.
|
|
return normalizePortalColor(config?.primaryColor)
|
|
|| normalizePortalColor(config?.primayColor)
|
|
|| DEFAULT_PORTAL_COLOR
|
|
}
|
|
|
|
export function portalThemeStyle(value: unknown): Record<string, string> {
|
|
const color = normalizePortalColor(value) || DEFAULT_PORTAL_COLOR
|
|
const rgb = [1, 3, 5].map(offset => parseInt(color.slice(offset, offset + 2), 16) / 255)
|
|
const linear = rgb.map(channel => channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4)
|
|
const luminance = linear[0] * 0.2126 + linear[1] * 0.7152 + linear[2] * 0.0722
|
|
const style: Record<string, string> = {
|
|
"--ui-primary": color,
|
|
"--portal-accent-contrast": luminance > 0.179 ? "#000000" : "#ffffff",
|
|
}
|
|
const shades = { 50: 5, 100: 10, 200: 25, 300: 45, 400: 70, 500: 100, 600: 80, 700: 65, 800: 50, 900: 35, 950: 20 }
|
|
for (const [shade, percent] of Object.entries(shades)) {
|
|
style[`--ui-color-primary-${shade}`] = Number(shade) === 500
|
|
? color
|
|
: `color-mix(in srgb, ${color} ${percent}%, ${Number(shade) < 500 ? "white" : "black"})`
|
|
}
|
|
return style
|
|
}
|