import { memo, useId } from "react";
import { Pressable, View } from "react-native";
import Svg, { Circle, Defs, RadialGradient, Stop } from "react-native-svg";
import { mixThemePreviewBase, THEME_PREVIEW_RENDER_SPECS } from "@t3tools/shared/themePreview";
import { SymbolView } from "../../../../components/AppSymbol";
import { AppText as Text } from "../../../../components/AppText";
import {
getMobileThemeVariables,
getMobileThemePreviewColors,
MOBILE_THEME_OPTIONS,
type MobileThemeAppearance,
type MobileThemeId,
type MobileThemeIds,
type MobileThemeMode,
type MobileThemeVariables,
} from "../../../../lib/mobileTheme";
import { useThemeColor } from "../../../../lib/useThemeColor";
import { useAppearancePreferences } from "../AppearancePreferencesProvider";
const APPEARANCE_MODES: ReadonlyArray<{
readonly id: MobileThemeMode;
readonly label: string;
}> = [
{ id: "system", label: "System" },
{ id: "light", label: "Light" },
{ id: "dark", label: "Dark" },
];
const PreviewOrb = memo(function PreviewOrb(props: {
readonly appearance: MobileThemeAppearance;
readonly compact?: boolean;
readonly themeId: MobileThemeId;
}) {
const idPrefix = useId().replaceAll(":", "");
const accentGradientId = `${idPrefix}-accent-glow`;
const actionGradientId = `${idPrefix}-action-glow`;
const colors = getMobileThemePreviewColors(props.themeId, props.appearance);
const spec = THEME_PREVIEW_RENDER_SPECS[props.appearance];
const accentRadius = Math.hypot(
Math.max(spec.accent.center[0], 1 - spec.accent.center[0]),
Math.max(spec.accent.center[1], 1 - spec.accent.center[1]),
);
const actionRadius = Math.hypot(
Math.max(spec.action.center[0], 1 - spec.action.center[0]),
Math.max(spec.action.center[1], 1 - spec.action.center[1]),
);
const position = (value: number) => `${value * 100}%`;
const radius = (value: number) => `${value * 100}%`;
return (
);
});
function ThemeCard(props: {
readonly disabled: boolean;
readonly darkSelected: boolean;
readonly label: string;
readonly lightSelected: boolean;
readonly onSelectBoth: () => void;
readonly onSelect: (appearance: MobileThemeAppearance) => void;
readonly themeId: MobileThemeId;
}) {
const badgeBackground = useThemeColor("--color-card");
const badgeIcon = useThemeColor("--color-icon");
const choice = (appearance: MobileThemeAppearance, selected: boolean) => (
props.onSelect(appearance)}
>
{selected ? (
) : null}
);
return (
{choice("light", props.lightSelected)}
{choice("dark", props.darkSelected)}
{props.label}
);
}
function PreviewPane(props: { readonly colors: MobileThemeVariables; readonly compact?: boolean }) {
return (
);
}
function ModePreview(props: { readonly mode: MobileThemeMode; readonly themeIds: MobileThemeIds }) {
const light = getMobileThemeVariables(props.themeIds.light, "light");
const dark = getMobileThemeVariables(props.themeIds.dark, "dark");
const currentBorder = useThemeColor("--color-border");
const currentFrame = useThemeColor("--color-drawer");
const currentIndicator = useThemeColor("--color-foreground-muted");
const frameColor =
props.mode === "light"
? light["--color-border"]
: props.mode === "dark"
? dark["--color-border"]
: currentBorder;
const frameBackground =
props.mode === "light"
? light["--color-drawer"]
: props.mode === "dark"
? dark["--color-drawer"]
: currentFrame;
const indicatorColor =
props.mode === "light"
? light["--color-foreground-muted"]
: props.mode === "dark"
? dark["--color-foreground-muted"]
: currentIndicator;
return (
{props.mode === "system" ? (
<>
>
) : (
)}
);
}
function ModeCard(props: {
readonly disabled: boolean;
readonly label: string;
readonly mode: MobileThemeMode;
readonly onPress: () => void;
readonly selected: boolean;
readonly themeIds: MobileThemeIds;
}) {
return (
{props.label}
);
}
function SectionLabel({ children }: { readonly children: string }) {
return {children};
}
export function ThemeAppearanceSection() {
const {
isReady,
setThemeIdForAppearance,
setThemeIdForBothAppearances,
setThemeMode,
themeIds,
themeMode,
} = useAppearancePreferences();
return (
Color scheme
{APPEARANCE_MODES.map((mode) => (
setThemeMode(mode.id)}
selected={mode.id === themeMode}
themeIds={themeIds}
/>
))}
Themes
{MOBILE_THEME_OPTIONS.map((theme) => (
setThemeIdForAppearance(appearance, theme.id)}
onSelectBoth={() => setThemeIdForBothAppearances(theme.id)}
themeId={theme.id}
/>
))}
);
}