diff --git a/animata/fabs/share-sheet.stories.tsx b/animata/fabs/share-sheet.stories.tsx new file mode 100644 index 00000000..4b5109dc --- /dev/null +++ b/animata/fabs/share-sheet.stories.tsx @@ -0,0 +1,94 @@ +import React from "react"; + +import ShareSheet from "@/animata/fabs/share-sheet"; +import { Meta, StoryObj } from "@storybook/react"; + +const meta = { + title: "Fabs/Share Sheet", + component: ShareSheet, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], + argTypes: { + platforms: { + description: + "Array of platforms available to share through. Each platform should have an image, label, action function, and color.", + table: { + type: { summary: "Array of objects" }, + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const platforms = [ + { + image: ( + Smiley + ), + label: "Smiley Emoji", + key: "smiley", + action: () => console.log("Smiley Share clicked"), + }, + { + image: ( + Rocket + ), + label: "Rocket Emoji", + key: "rocket", + action: () => console.log("Rocket Share clicked"), + }, + { + image: ( + Pizza + ), + label: "Pizza Emoji", + key: "pizza", + action: () => console.log("Pizza Share clicked"), + }, + { + image: ( + Heart + ), + label: "Heart Emoji", + key: "heart", + action: () => console.log("Heart Share clicked"), + }, + { + image: ( + Star + ), + label: "Star Emoji", + key: "star", + action: () => console.log("Star Share clicked"), + }, +]; + +export const Primary: Story = { + args: { + platforms: platforms, + }, +}; diff --git a/animata/fabs/share-sheet.tsx b/animata/fabs/share-sheet.tsx new file mode 100644 index 00000000..204dc849 --- /dev/null +++ b/animata/fabs/share-sheet.tsx @@ -0,0 +1,129 @@ +import React, { useEffect, useState } from "react"; +import { Share } from "lucide-react"; + +interface ShareSheetProps { + platforms: Array<{ + image: React.ReactNode; + label: string; + key: string; + action: () => void; + }>; +} + +interface TooltipProps { + text: string; + children: React.ReactNode; +} + +const Tooltip: React.FC = ({ text, children }) => { + const [visible, setVisible] = useState(false); + + return ( +
setVisible(true)} + onMouseLeave={() => setVisible(false)} + className="relative inline-block" + > + {children} + {visible && ( +
+ {text} +
+ )} +
+ ); +}; + +export default function ShareSheet({ platforms }: ShareSheetProps) { + const [isOpen, setIsOpen] = useState(false); + const [selectedPlatform, setSelectedPlatform] = useState(null); + const [animationProgress, setAnimationProgress] = useState(0); + const [isExitAnimationActive, setIsExitAnimationActive] = useState(false); + + const toggleShareSheet = () => setIsOpen((prev) => !prev); + + useEffect(() => { + let animationFrame: number; + if (selectedPlatform && !isExitAnimationActive) { + const animate = () => { + setAnimationProgress((prev) => { + if (prev < 100) { + animationFrame = requestAnimationFrame(animate); + return prev + 0.5; // Slower animation + } + return 100; + }); + }; + animationFrame = requestAnimationFrame(animate); + } + return () => cancelAnimationFrame(animationFrame); + }, [selectedPlatform, isExitAnimationActive]); + + useEffect(() => { + if (animationProgress === 100) { + setIsExitAnimationActive(true); + const timer = setTimeout(() => { + setSelectedPlatform(null); + setAnimationProgress(0); + setIsExitAnimationActive(false); + }, 800); // Adjust timing as needed + return () => clearTimeout(timer); + } + }, [animationProgress]); + + return ( +
+
+ + {selectedPlatform && ( +
+ {React.cloneElement(selectedPlatform.image as React.ReactElement, { + className: "w-10 h-10 rounded-full", + })} +
+ )} +
+ +
+
+ {platforms.map((platform, index) => ( + + + + ))} +
+
+
+ ); +} diff --git a/content/docs/fabs/share-sheet.mdx b/content/docs/fabs/share-sheet.mdx new file mode 100644 index 00000000..dfe7ef7b --- /dev/null +++ b/content/docs/fabs/share-sheet.mdx @@ -0,0 +1,38 @@ +--- +title: Share Sheet +description: Share Sheet +author: Asmit Kumar Rai +--- + + + +## Installation + + +Install dependencies + +```bash +npm install lucide-react +``` + +Run the following command + +It will create a new file `share-sheet.tsx` inside the `components/animata/fabs` directory. + +```bash +mkdir -p components/animata/fabs && touch components/animata/fabs/share-sheet.tsx +``` + +Paste the code{" "} + +Open the newly created file and paste the following code: + +```jsx file=/animata/fabs/share-sheet.tsx + +``` + + + +## Credits + +Built by [Asmit Kumar Rai](https://github.com/asmit27rai)