diff --git a/apps/www/components/sections/testimonial-tweet-link.tsx b/apps/www/components/sections/testimonial-tweet-link.tsx new file mode 100644 index 000000000..e6b430a46 --- /dev/null +++ b/apps/www/components/sections/testimonial-tweet-link.tsx @@ -0,0 +1,83 @@ +"use client" + +import type { KeyboardEvent, MouseEvent, ReactNode } from "react" +import Link from "next/link" +import { ArrowUpRight } from "lucide-react" + +import { Button } from "@/components/ui/button" + +interface TestimonialTweetLinkProps { + children: ReactNode + tweetUrl: string +} + +const interactiveSelector = + 'a, button, input, select, textarea, summary, [role="button"], [role="link"]' + +const isInteractiveTarget = ( + target: EventTarget | null, + container: Element +) => { + if (!(target instanceof Element)) { + return false + } + + const interactiveElement = target.closest(interactiveSelector) + + return interactiveElement !== null && interactiveElement !== container +} + +export function TestimonialTweetLink({ + children, + tweetUrl, +}: TestimonialTweetLinkProps) { + const navigateToTweet = () => { + window.location.assign(tweetUrl) + } + + const handleClick = (event: MouseEvent) => { + if (isInteractiveTarget(event.target, event.currentTarget)) { + return + } + + navigateToTweet() + } + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.target !== event.currentTarget) { + return + } + + if (event.key !== "Enter" && event.key !== " ") { + return + } + + event.preventDefault() + navigateToTweet() + } + + return ( +
+ {children} +
+ +
+
+ ) +} diff --git a/apps/www/components/sections/testimonials.tsx b/apps/www/components/sections/testimonials.tsx index ec6227505..d4823016f 100644 --- a/apps/www/components/sections/testimonials.tsx +++ b/apps/www/components/sections/testimonials.tsx @@ -1,8 +1,5 @@ -import Link from "next/link" -import { ArrowUpRight } from "lucide-react" - -import { Button } from "@/components/ui/button" import { ExpandableMasonarySection } from "@/components/sections/expandable-masonary-section" +import { TestimonialTweetLink } from "@/components/sections/testimonial-tweet-link" import { TweetCard } from "@/registry/magicui/tweet-card" const allTweets = [ @@ -64,26 +61,15 @@ export function Testimonials() { {allTweets.map((id) => ( - -
- -
- + ))}