Files
homarr/packages/onboarding/src/onboarding-wordmark.tsx
T

65 lines
2.2 KiB
TypeScript

"use client";
import type { CSSProperties, MouseEvent as ReactMouseEvent } from "react";
import { useState } from "react";
import { useComputedColorScheme } from "@mantine/core";
import confetti from "canvas-confetti";
import HomarrWordmarkLight from "./homarr-wordmark-light";
import classes from "./onboarding-studio.module.css";
import { useOnboardingSounds } from "./use-onboarding-sounds";
interface OnboardingWordmarkProps {
primaryColor?: string;
secondaryColor?: string;
large?: boolean;
}
export const OnboardingWordmark = ({ primaryColor, secondaryColor, large = false }: OnboardingWordmarkProps) => {
const [celebrating, setCelebrating] = useState(false);
const colorScheme = useComputedColorScheme("light");
const sounds = useOnboardingSounds();
const colors = {
"--homarr-wordmark-primary": primaryColor ?? "#F92424",
"--homarr-wordmark-secondary": secondaryColor ?? "#FA5252",
"--homarr-wordmark-foreground": colorScheme === "light" ? "#1A1B1E" : "#FEFDFD",
} as CSSProperties;
const celebrate = (event: ReactMouseEvent<SVGSVGElement>) => {
sounds.hover();
const logo = event.currentTarget.getBoundingClientRect();
const originY = (logo.top + logo.height / 2) / window.innerHeight;
const colors = primaryColor && secondaryColor ? [primaryColor, secondaryColor] : undefined;
if (!window.matchMedia("(prefers-reduced-motion: reduce)").matches) setCelebrating(true);
for (const { angle, originX } of [
{ angle: 165, originX: logo.left + logo.width * 0.12 },
{ angle: 15, originX: logo.right - logo.width * 0.12 },
]) {
void confetti({
particleCount: 28,
angle,
spread: 35,
startVelocity: 14,
gravity: 0.7,
ticks: 90,
scalar: 0.8,
origin: { x: originX / window.innerWidth, y: originY },
colors,
disableForReducedMotion: true,
});
}
};
return (
<HomarrWordmarkLight
role="img"
aria-label="Homarr"
style={colors}
className={`${classes.wordmark} ${classes.onboardingWordmark} ${large ? classes.welcomeWordmark : ""} ${celebrating ? classes.celebratingWordmark : ""}`}
onMouseEnter={celebrate}
onAnimationEnd={() => setCelebrating(false)}
/>
);
};