Add NativeFlipText component and update UI styles

Introduces NativeFlipText components for both BaseUI and ShadcnUI, along with a demo for BaseUI. Updates layout and responsive styles in detail task cards and home page content, including improved flex behavior and text sizing. Also updates the cash flow chart's heading size for better responsiveness and tweaks home page copy from 'copy' to 'install'.
This commit is contained in:
moumensoliman 2025-12-16 03:23:56 +02:00
parent 6de3c709eb
commit d9817c2bdb
10 changed files with 181 additions and 8 deletions

View file

@ -374,7 +374,7 @@ export function DetailTaskCardBaseUI() {
</div>
<div className="flex flex-col gap-4 rounded-2xl border border-border/40 bg-background/40 px-4 py-4 backdrop-blur md:flex-row md:items-center md:justify-between">
<div className="flex items-center gap-3">
<div className="md:flex items-center gap-3">
<motion.button
type="button"
role="switch"

View file

@ -366,7 +366,7 @@ export function DetailTaskCard() {
</div>
<div className="flex flex-col gap-4 rounded-2xl border border-border/40 bg-background/40 px-4 py-4 backdrop-blur md:flex-row md:items-center md:justify-between">
<div className="flex items-center gap-3">
<div className="md:flex space-y-2 md:space-y-0 items-center gap-3">
<motion.button
type="button"
role="switch"

View file

@ -205,7 +205,7 @@ export function CashFlowChart() {
initial={shouldAnimate ? { scale: 0.95 } : { scale: 1 }}
animate={{ scale: 1 }}
transition={shouldAnimate ? { duration: 0.4 } : { duration: 0 }}
className="text-5xl font-bold text-foreground"
className="text-3xl md:text-5xl font-bold text-foreground"
>
{formatCurrency(
displayData.reduce((total, datum) => total + datum.cashflow, 0)

View file

@ -56,7 +56,7 @@ export default function HomePageContent() {
initial={{ opacity: 0, y: 4 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.25 }}
className="text-xs font-medium uppercase tracking-[0.25em] text-muted-foreground text-center flex items-center justify-center gap-2"
className="text-xs font-medium uppercase tracking-[0.25em] text-muted-foreground text-center md:flex items-center justify-center gap-2"
>
When Framer Motion meets <HeroFlip />
</motion.p>
@ -66,7 +66,7 @@ export default function HomePageContent() {
transition={{ duration: 0.3, delay: 0.05 }}
className="text-center text-2xl font-semibold tracking-tight text-foreground sm:text-3xl"
>
Browse, copy, and ship
Browse, install, and ship
</motion.h1>
<motion.p
initial={{ opacity: 0, y: 6 }}

View file

@ -0,0 +1,47 @@
"use client";
import { NativeFlipText } from "@/components/native/baseui/native-flip-text-baseui";
export function NativeFlipTextDefault() {
return (
<div className="flex items-center justify-center p-8 bg-black/5 dark:bg-white/5 rounded-xl border border-black/10 dark:border-white/10">
<NativeFlipText
words={["Design", "Develop", "Ship", "Deploy"]}
className="text-2xl font-bold text-foreground"
/>
</div>
);
}
export function NativeFlipTextColored() {
return (
<div className="flex items-center justify-center p-8 bg-black/5 dark:bg-white/5 rounded-xl border border-black/10 dark:border-white/10">
<div className="text-xl font-medium text-muted-foreground flex items-center gap-2">
<span>We build</span>
<NativeFlipText
words={["beautiful", "modern", "fast", "accessible"]}
className="text-primary font-bold"
duration={1500}
/>
<span>user interfaces.</span>
</div>
</div>
);
}
export function NativeFlipTextDemo() {
return (
<div className="flex flex-col gap-8 w-full">
<div className="space-y-2">
<h3 className="font-semibold text-muted-foreground">Default</h3>
<NativeFlipTextDefault />
</div>
<div className="space-y-2">
<h3 className="font-semibold text-muted-foreground">
Inline with Text
</h3>
<NativeFlipTextColored />
</div>
</div>
);
}

View file

@ -0,0 +1,63 @@
"use client";
import { cn } from "@/lib/utils";
import { AnimatePresence, motion } from "framer-motion";
import { useEffect, useState } from "react";
interface NativeFlipTextProps {
/**
* Array of words to flip through.
*/
words: string[];
/**
* Duration of each word display in ms.
* Default: 2000
*/
duration?: number;
className?: string;
}
export function NativeFlipText({
words,
duration = 2000,
className,
}: NativeFlipTextProps) {
const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((prevIndex) => (prevIndex + 1) % words.length);
}, duration);
return () => clearInterval(interval);
}, [words.length, duration]);
return (
<div
className={cn(
"inline-flex items-center justify-center overflow-hidden",
className
)}
>
<AnimatePresence mode="wait">
<motion.div
key={words[index]}
initial={{ rotateX: -90, opacity: 0, filter: "blur(6px)" }}
animate={{ rotateX: 0, opacity: 1, filter: "blur(0px)" }}
exit={{ rotateX: 90, opacity: 0, filter: "blur(6px)" }}
transition={{
type: "spring",
stiffness: 100,
damping: 20,
opacity: { duration: 0.3 },
filter: { duration: 0.3 },
rotateX: { duration: 0.4 },
}}
className="text-center"
>
{words[index]}
</motion.div>
</AnimatePresence>
</div>
);
}

View file

@ -0,0 +1,63 @@
"use client";
import { cn } from "@/lib/utils";
import { AnimatePresence, motion } from "framer-motion";
import { useEffect, useState } from "react";
interface NativeFlipTextProps {
/**
* Array of words to flip through.
*/
words: string[];
/**
* Duration of each word display in ms.
* Default: 2000
*/
duration?: number;
className?: string;
}
export function NativeFlipText({
words,
duration = 2000,
className,
}: NativeFlipTextProps) {
const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((prevIndex) => (prevIndex + 1) % words.length);
}, duration);
return () => clearInterval(interval);
}, [words.length, duration]);
return (
<div
className={cn(
"inline-flex items-center justify-center overflow-hidden",
className
)}
>
<AnimatePresence mode="wait">
<motion.div
key={words[index]}
initial={{ rotateX: -90, opacity: 0, filter: "blur(6px)" }}
animate={{ rotateX: 0, opacity: 1, filter: "blur(0px)" }}
exit={{ rotateX: 90, opacity: 0, filter: "blur(6px)" }}
transition={{
type: "spring",
stiffness: 100,
damping: 20,
opacity: { duration: 0.3 },
filter: { duration: 0.3 },
rotateX: { duration: 0.4 },
}}
className="text-center"
>
{words[index]}
</motion.div>
</AnimatePresence>
</div>
);
}

View file

@ -2,7 +2,7 @@
> Production-ready UI components, blocks, and pages built on top of shadcn/ui and Framer Motion.
**Last Updated:** 2025-12-15T23:36:13.194Z
**Last Updated:** 2025-12-16T01:22:38.286Z
## Table of Contents

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long