diff --git a/.gitignore b/.gitignore index 5205805..a5bac02 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +package-lock.json \ No newline at end of file diff --git a/src/pages/index.js b/src/pages/index.js index 587de8c..99484dd 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -1,7 +1,8 @@ -import { TbBrandTwitter, TbShare, TbDownload, TbCopy } from "react-icons/tb"; -import React, { useRef, useState, useEffect } from "react"; +import { TbBrandTwitter, TbShare, TbDownload, TbCopy, TbChevronDown } from "react-icons/tb"; +import React, { useRef, useState, useEffect, useCallback } from "react"; import { download, + downloadSVG, fetchData, downloadJSON, cleanUsername, @@ -19,6 +20,8 @@ const App = () => { const [theme, setTheme] = useState("standard"); const [data, setData] = useState(null); const [error, setError] = useState(null); + const [showDownloadMenu, setShowDownloadMenu] = useState(false); + const downloadMenuRef = useRef(); useEffect(() => { if (!data) { @@ -27,6 +30,17 @@ const App = () => { draw(); }, [data, theme]); + // Close dropdown when clicking outside + useEffect(() => { + const handler = (e) => { + if (downloadMenuRef.current && !downloadMenuRef.current.contains(e.target)) { + setShowDownloadMenu(false); + } + }; + document.addEventListener("mousedown", handler); + return () => document.removeEventListener("mousedown", handler); + }, []); + const handleSubmit = (e) => { e.preventDefault(); @@ -62,6 +76,18 @@ const App = () => { copyToClipboard(canvasRef.current); }; + const onDownloadSVG = (e) => { + e.preventDefault(); + if (data != null) { + downloadSVG( + data, + username, + theme, + "Made by @sallar & friends - github-contributions.vercel.app" + ); + } + }; + const onDownloadJson = (e) => { e.preventDefault(); if (data != null) { @@ -139,14 +165,35 @@ const App = () => { Copy - +
+ + {showDownloadMenu && ( +
+ + +
+ )} +
{global.navigator && "share" in navigator && (