diff --git a/apps/public/package.json b/apps/public/package.json index 077752df..67dfa62b 100644 --- a/apps/public/package.json +++ b/apps/public/package.json @@ -38,6 +38,7 @@ "react-animate-height": "^3.2.3", "react-dom": "18.2.0", "react-syntax-highlighter": "^15.5.0", + "react-type-animation": "^3.2.0", "tailwind-merge": "^1.14.0", "tailwindcss-animate": "^1.0.7", "zod": "^3.22.4" diff --git a/apps/public/src/app/animated-text.tsx b/apps/public/src/app/animated-text.tsx new file mode 100644 index 00000000..db38de13 --- /dev/null +++ b/apps/public/src/app/animated-text.tsx @@ -0,0 +1,46 @@ +'use client'; + +import { useMemo, useState } from 'react'; +import { TypeAnimation } from 'react-type-animation'; + +type Props = { + className?: string; + texts: { text: string; color: string }[]; +}; + +const AnimatedText = ({ texts }: Props) => { + const [currIndex, setCurrIndex] = useState(0); + const sequence = useMemo(() => { + return texts.reduce((acc, { text }, index) => { + return [ + ...acc, + () => setCurrIndex(index), + text, + index === 0 ? 3000 : 2000, + ]; + }, [] as any[]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + + + ); +}; + +export default AnimatedText; diff --git a/apps/public/src/app/hero.tsx b/apps/public/src/app/hero.tsx index 6281969c..2ebe5ca7 100644 --- a/apps/public/src/app/hero.tsx +++ b/apps/public/src/app/hero.tsx @@ -2,6 +2,7 @@ import { ALink } from '@/components/ui/button'; import { chQuery } from '@openpanel/db'; +import AnimatedText from './animated-text'; import { Heading1, Lead2 } from './copy'; function shortNumber(num: number) { @@ -31,7 +32,23 @@ export async function Hero() { An open-source
- alternative to Mixpanel + alternative to{' '} +
The power of Mixpanel, the ease of Plausible and nothing from Google @@ -47,7 +64,7 @@ export async function Hero() { Get started -
+
Collected events @@ -66,7 +83,7 @@ export async function Hero() {
-
+