108 lines · 5.9 KB · TypeScript
RawDownload
import { Hct, argbFromHex, hexFromArgb } from "@material/material-color-utilities"; import type { MobileThemeAppearance, MobileThemeVariables } from "./mobileTheme";import type { MaterialYouPalette } from "./materialYouPalette"; function withAlpha(color: string, alpha: number): string {  const match = /^#([\da-f]{6})(?:[\da-f]{2})?$/iu.exec(color);  if (!match?.[1]) return color;  const alphaByte = Math.round(Math.min(1, Math.max(0, alpha)) * 255)    .toString(16)    .padStart(2, "0")    .toUpperCase();  return `#${match[1]}${alphaByte}`;} function materialTone(color: string, tone: number): string {  const match = /^#([\da-f]{6})(?:[\da-f]{2})?$/iu.exec(color);  if (!match?.[1]) return color;   const source = Hct.fromInt(argbFromHex(match[1]));  return `${hexFromArgb(Hct.from(source.hue, source.chroma, tone).toInt()).toUpperCase()}FF`;} export function materialYouPaletteToMobileThemeVariables(  palette: MaterialYouPalette,  appearance: MobileThemeAppearance,  base: MobileThemeVariables,): MobileThemeVariables {  const dark = appearance === "dark";  const userBubble = dark ? materialTone(palette.inversePrimary, 30) : palette.primary;  const userBubbleForeground = dark ? materialTone(palette.inversePrimary, 90) : palette.onPrimary;   return {    ...base,    "--color-screen": palette.surface,    "--color-sheet": withAlpha(palette.surfaceContainerLow, 0.98),    "--color-sheet-solid": palette.surfaceContainerLow,    "--color-card": palette.surfaceContainer,    "--color-card-alt": palette.surfaceContainerHigh,    "--color-card-translucent": withAlpha(palette.surfaceContainer, 0.8),    "--color-thread-canvas": palette.surfaceContainerLow,    "--color-thread-selected": palette.surfaceContainer,    "--color-thread-selected-foreground": palette.onSurface,    "--color-thread-selected-foreground-muted": palette.onSurfaceVariant,    "--color-composer-panel": withAlpha(palette.surfaceContainerLow, dark ? 0.92 : 0.88),    "--color-composer-surface": withAlpha(palette.surfaceContainerHigh, dark ? 0.9 : 0.94),    "--color-composer-border": withAlpha(palette.outlineVariant, dark ? 0.34 : 0.46),    "--color-foreground": palette.onSurface,    "--color-foreground-secondary": palette.onSurfaceVariant,    "--color-foreground-muted": palette.onSurfaceVariant,    "--color-foreground-tertiary": withAlpha(palette.onSurfaceVariant, 0.58),    "--color-border": withAlpha(palette.outlineVariant, dark ? 0.5 : 0.65),    "--color-border-subtle": withAlpha(palette.outlineVariant, dark ? 0.34 : 0.46),    "--color-separator": withAlpha(palette.outlineVariant, dark ? 0.24 : 0.34),    "--color-subtle": withAlpha(palette.onSurface, 0.05),    "--color-subtle-strong": withAlpha(palette.onSurface, 0.1),    "--color-inline-skill-background": withAlpha(palette.tertiaryContainer, 0.52),    "--color-inline-skill-border": withAlpha(palette.tertiary, 0.38),    "--color-inline-skill-foreground": palette.onTertiaryContainer,    "--color-primary": palette.primary,    "--color-primary-foreground": palette.onPrimary,    "--color-primary-shadow": withAlpha(palette.scrim, dark ? 0.22 : 0.18),    "--color-secondary": palette.secondaryContainer,    "--color-secondary-foreground": palette.onSecondaryContainer,    "--color-secondary-border": withAlpha(palette.outlineVariant, dark ? 0.42 : 0.56),    "--color-switch-active-track": palette.primary,    "--color-switch-active-thumb": palette.onPrimary,    "--color-switch-inactive-track": palette.surfaceContainerHighest,    "--color-switch-inactive-thumb": palette.outline,    "--color-danger": palette.errorContainer,    "--color-danger-border": withAlpha(palette.onErrorContainer, dark ? 0.42 : 0.5),    "--color-danger-foreground": palette.onErrorContainer,    "--color-input": palette.surfaceContainerLowest,    "--color-input-border": withAlpha(palette.outline, dark ? 0.42 : 0.5),    "--color-sidebar-search": palette.surfaceContainerLowest,    "--color-placeholder": withAlpha(palette.onSurface, 0.62),    "--color-icon": palette.onSurface,    "--color-icon-muted": palette.onSurfaceVariant,    "--color-icon-subtle": withAlpha(palette.onSurfaceVariant, 0.68),    "--color-header": palette.surfaceContainerHigh,    "--color-header-border": withAlpha(palette.outlineVariant, dark ? 0.36 : 0.48),    "--color-glass-surface": withAlpha(palette.surfaceContainerHigh, dark ? 0.78 : 0.72),    "--color-glass-tint": withAlpha(palette.primaryContainer, dark ? 0.24 : 0.18),    "--color-status-bar": palette.surfaceContainerLow,    "--color-md-body": materialTone(palette.onSurfaceVariant, dark ? 90 : 10),    "--color-md-strong": materialTone(palette.onSurfaceVariant, dark ? 90 : 10),    "--color-md-link": palette.primary,    "--color-md-blockquote-border": withAlpha(palette.primary, dark ? 0.34 : 0.26),    "--color-md-blockquote-bg": withAlpha(palette.primaryContainer, dark ? 0.14 : 0.2),    "--color-md-code-bg": withAlpha(palette.onSurface, dark ? 0.08 : 0.06),    "--color-md-code-text": palette.onSurface,    "--color-md-user-code-bg": withAlpha(userBubbleForeground, dark ? 0.18 : 0.22),    "--color-md-user-code-text": userBubbleForeground,    "--color-md-user-fence-bg": withAlpha(userBubbleForeground, dark ? 0.14 : 0.18),    "--color-md-user-fence-text": userBubbleForeground,    "--color-md-hr": withAlpha(palette.outlineVariant, dark ? 0.48 : 0.6),    "--color-user-bubble": userBubble,    "--color-user-bubble-foreground": userBubbleForeground,    "--color-user-bubble-foreground-muted": withAlpha(userBubbleForeground, 0.78),    "--color-user-bubble-skill-foreground": userBubbleForeground,    "--color-backdrop": withAlpha(palette.scrim, dark ? 0.48 : 0.22),    "--color-drawer": palette.surface,    "--color-drawer-shadow": withAlpha(palette.scrim, dark ? 0.32 : 0.12),    "--color-dot-separator": withAlpha(palette.onSurface, 0.2),    "--color-wordmark": palette.onSurface,    "--color-chevron": withAlpha(palette.onSurface, 0.2),  };}