From 813e4db8759d7eb528e950ddfc3eade774dcf0fa Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Mon, 7 Apr 2025 21:33:54 +0530 Subject: [PATCH] feat: --- src/components/Flippable.tsx | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/components/Flippable.tsx diff --git a/src/components/Flippable.tsx b/src/components/Flippable.tsx new file mode 100644 index 0000000..f53f277 --- /dev/null +++ b/src/components/Flippable.tsx @@ -0,0 +1,79 @@ +import { css, cx } from "@emotion/css"; +import React, { useState, useRef } from "react"; + +export interface FlippableProps { + front: React.ReactNode; + back: React.ReactNode; + className?: string; + defaultSide?: "front" | "back"; +} + +export const Flippable: React.FC = ({ + front, + back, + className, + defaultSide, +}) => { + const ref = useRef(null); + const [isFlipped, setIsFlipped] = useState(defaultSide === "back"); + const mouseDownTime = useRef(0); + const DRAG_THRESHOLD = 250; // milliseconds + + const handleMouseDown = () => { + mouseDownTime.current = Date.now(); + }; + + const handleClick = () => { + if (Date.now() - mouseDownTime.current < DRAG_THRESHOLD) { + setIsFlipped(prev => !prev); + + ref.current?.animate( + [ + { transform: "scale(1)" }, + { transform: "scale(1.2)", offset: 0.4 }, + { transform: "scale(1.2)", offset: 0.6 }, + { transform: "scale(1)" }, + ], + { + duration: 600, + easing: "cubic-bezier(0.4, 0, 0.2, 1)", + }, + ); + } + }; + + return ( +
+
{front}
+
{back}
+
+ ); +};