Docs
Swap Text
A component that swaps text on click or hover.
requires interactionhoverclick
Installation
Update tailwind.config.js
theme: {
extend: {
colors: {
foreground: "hsl(var(--foreground))",
},
transitionTimingFunction: {
slow: "cubic-bezier(.405, 0, .025, 1)",
"minor-spring": "cubic-bezier(0.18,0.89,0.82,1.04)",
}
},
},
Run the following command
It will create a new file called swap-text.tsx
inside the components/animata/text
directory.
touch components/animata/text/swap-text.tsx
Paste the code
Open the newly created file and paste the following code:
import { useState } from "react";
import { cn } from "@/lib/utils";
interface SwapTextProps extends React.ComponentPropsWithoutRef<"div"> {
/**
* The initial text to display.
*/
initialText: string;
/**
* The final text to display.
*/
finalText: string;
/**
* Whether the component should toggle on hover as well as click.
*/
supportsHover?: boolean;
/**
* The class name for the text.
*/
textClassName?: string;
/**
* The class name for the initial text.
*/
initialTextClassName?: string;
/**
* The class name for the final text.
*/
finalTextClassName?: string;
/**
* Whether to disable the click interaction.
*/
disableClick?: boolean;
}
export default function SwapText({
initialText,
finalText,
className,
supportsHover = true,
textClassName,
initialTextClassName,
finalTextClassName,
disableClick,
// The rest of the props are passed to the container div.
...props
}: SwapTextProps) {
const [active, setActive] = useState(false);
const common = "block transition-all duration-1000 ease-slow";
const longWord = finalText.length > initialText.length ? finalText : null;
return (
<div {...props} className={cn("relative overflow-hidden text-foreground", className)}>
<div
className={cn("group cursor-pointer select-none text-3xl font-bold", textClassName)}
onClick={() => !disableClick && setActive((current) => !current)}
>
<span
className={cn(common, initialTextClassName, {
"flex flex-col": true,
"-translate-y-full": active,
"group-hover:-translate-y-full": supportsHover,
})}
>
{initialText}
{
/* Trick to make sure it can always fit all available words after transition as the second word is set to absolute*/
Boolean(longWord?.length) && <span className="invisible h-0">{longWord}</span>
}
</span>
<span
className={cn(`${common} absolute top-full`, finalTextClassName, {
"-translate-y-full": active,
"group-hover:-translate-y-full": supportsHover,
})}
>
{finalText}
</span>
</div>
</div>
);
}
Credits
Built by hari