Initial independent version of CrAPP

This commit is contained in:
Ivan Cacciari
2026-08-06 08:36:47 +02:00
commit 330669176d
167 changed files with 24096 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
import { cn } from "@/lib/utils";
import { useRiempimento } from "@/lib/motion";
/** Barra di avanzamento che si riempie in ~700 ms all'apertura. */
export function Barra({
percentuale,
className,
trackClassName,
altezza = "h-2",
}: {
percentuale: number;
className?: string;
trackClassName?: string;
altezza?: string;
}) {
const larghezza = useRiempimento(Math.max(0, Math.min(100, Math.round(percentuale))));
return (
<div className={cn("overflow-hidden rounded-full bg-secondary", altezza, trackClassName)}>
<div
className={cn("anim-barra h-full rounded-full bg-accent-grad", className)}
style={{ width: `${larghezza}%` }}
/>
</div>
);
}
+20
View File
@@ -0,0 +1,20 @@
import { useConteggio } from "@/lib/motion";
/** Contatore animato per statistiche e percentuali. */
export function Numero({
valore,
durata = 700,
suffisso = "",
}: {
valore: number;
durata?: number;
suffisso?: string;
}) {
const n = useConteggio(valore, durata);
return (
<span className="tabular-nums">
{n}
{suffisso}
</span>
);
}
+29
View File
@@ -0,0 +1,29 @@
import type { CSSProperties, ReactNode } from "react";
import { cn } from "@/lib/utils";
/**
* Comparsa graduale con leggero slide dal basso (~300 ms).
* `indice` sfalsa l'animazione tra elementi vicini.
*/
export function Reveal({
children,
indice = 0,
className,
style,
as: Tag = "div",
}: {
children: ReactNode;
indice?: number;
className?: string;
style?: CSSProperties;
as?: "div" | "section" | "li" | "article";
}) {
return (
<Tag
className={cn("anim-reveal", className)}
style={{ animationDelay: `${Math.min(indice, 8) * 60}ms`, ...style }}
>
{children}
</Tag>
);
}