65 lines
2.2 KiB
TypeScript
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)}
|
|
/>
|
|
);
|
|
};
|