diff --git a/package.json b/package.json index 92cc3ce..8233543 100644 --- a/package.json +++ b/package.json @@ -107,5 +107,8 @@ "url": "https://github.com/storybookjs/addon-onboarding/issues" }, "readme": "ERROR: No README data found!", - "homepage": "https://github.com/storybookjs/addon-onboarding#readme" + "homepage": "https://github.com/storybookjs/addon-onboarding#readme", + "dependencies": { + "react-confetti": "^6.1.0" + } } diff --git a/src/components/confetti/Confetti.stories.tsx b/src/components/confetti/Confetti.stories.tsx new file mode 100644 index 0000000..ab8eec5 --- /dev/null +++ b/src/components/confetti/Confetti.stories.tsx @@ -0,0 +1,33 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { Confetti } from "./Confetti"; +import React from "react"; + +const meta: Meta = { + component: Confetti, + parameters: { + chromatic: { disableSnapshot: true }, + }, + decorators: [ + (StoryFn) => ( +
+ + +
+ ), + ], +}; + +export default meta; + +type Story = StoryObj; + +export const FullWidth: Story = {}; + +export const Positioned: Story = { + args: { + top: 100, + left: 300, + width: 300, + height: 250, + }, +}; diff --git a/src/components/confetti/Confetti.tsx b/src/components/confetti/Confetti.tsx new file mode 100644 index 0000000..dc94f8e --- /dev/null +++ b/src/components/confetti/Confetti.tsx @@ -0,0 +1,61 @@ +import ReactConfetti from "react-confetti"; +import React, { useEffect, useRef } from "react"; +import { styled } from "@storybook/theming"; +import { createPortal } from "react-dom"; +import { useState } from "react"; + +interface ConfettiProps + extends Omit, "drawShape"> { + top: number; + left: number; + width: number; + height: number; +} + +const Wrapper = styled.div<{ + width: number; + height: number; + top: number; + left: number; +}>(({ width, height, left, top }) => ({ + width: `${width}px`, + height: `${height}px`, + left: `${left}px`, + top: `${top}px`, + position: "relative", + overflow: "hidden", +})); + +export function Confetti({ + top = 0, + left = 0, + width = window.innerWidth, + height = window.innerHeight, + ...confettiProps +}: ConfettiProps) { + const [confettiContainer] = useState(() => { + const container = document.createElement("div"); + container.setAttribute("id", "confetti-container"); + container.setAttribute( + "style", + "position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999;" + ); + + return container; + }); + + useEffect(() => { + document.body.appendChild(confettiContainer); + + return () => { + document.body.removeChild(confettiContainer); + }; + }, []); + + return createPortal( + + + , + confettiContainer + ); +} diff --git a/yarn.lock b/yarn.lock index a8c179e..2ec2b04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7112,6 +7112,13 @@ react-colorful@^5.1.2: resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== +react-confetti@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-confetti/-/react-confetti-6.1.0.tgz#03dc4340d955acd10b174dbf301f374a06e29ce6" + integrity sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw== + dependencies: + tween-functions "^1.2.0" + react-docgen-typescript@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" @@ -8197,6 +8204,11 @@ tunnel@^0.0.6: resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== +tween-functions@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" + integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA== + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"