Files
fotospiel-app/resources/js/guest-v2/lib/brandingTheme.tsx
2026-02-03 15:18:44 +01:00

67 lines
2.1 KiB
TypeScript

import { Theme } from '@tamagui/core';
import React from 'react';
import type { Appearance } from '@/hooks/use-appearance';
import { useAppearance } from '@/hooks/use-appearance';
import { useEventBranding } from '@/guest/context/EventBrandingContext';
import { relativeLuminance } from '@/guest/lib/color';
import type { EventBranding } from '@/guest/types/event-branding';
const LIGHT_LUMINANCE_THRESHOLD = 0.65;
const DARK_LUMINANCE_THRESHOLD = 0.35;
type ThemeVariant = 'light' | 'dark';
function resolveThemeVariant(
mode: EventBranding['mode'],
backgroundColor: string,
appearanceOverride: 'light' | 'dark' | null
): ThemeVariant {
const prefersDark =
typeof window !== 'undefined' && typeof window.matchMedia === 'function'
? window.matchMedia('(prefers-color-scheme: dark)').matches
: false;
const backgroundLuminance = relativeLuminance(backgroundColor);
const backgroundPrefers =
backgroundLuminance >= LIGHT_LUMINANCE_THRESHOLD
? 'light'
: backgroundLuminance <= DARK_LUMINANCE_THRESHOLD
? 'dark'
: null;
if (appearanceOverride) {
return appearanceOverride;
}
if (mode === 'dark') {
return 'dark';
}
if (mode === 'light') {
return 'light';
}
if (backgroundPrefers) {
return backgroundPrefers;
}
return prefersDark ? 'dark' : 'light';
}
export function resolveGuestThemeName(
branding: EventBranding,
appearance: Appearance
): 'guestLight' | 'guestNight' {
const appearanceOverride = appearance === 'light' || appearance === 'dark' ? appearance : null;
const background = branding.backgroundColor || branding.palette?.background || '#ffffff';
const variant = resolveThemeVariant(branding.mode ?? 'auto', background, appearanceOverride);
return variant === 'dark' ? 'guestNight' : 'guestLight';
}
export function BrandingTheme({ children }: { children: React.ReactNode }) {
const { branding } = useEventBranding();
const { appearance } = useAppearance();
const themeName = resolveGuestThemeName(branding, appearance);
return <Theme name={themeName}>{children}</Theme>;
}