diff --git a/package-lock.json b/package-lock.json index 4a8560a..71617f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "dependencies": { "@astrojs/react": "^3.0.3", + "@floating-ui/react": "0.26.0", "@types/react": "^18.2.25", "@types/react-dom": "^18.2.10", "astro": "^3.2.3", @@ -1780,6 +1781,54 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", + "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.0.tgz", + "integrity": "sha512-W70xgicegogSoy+8Hfmpd/NWEuL26vsatIHkpVydmigJ84YYhs5/GlBCkLcETWajCjD9XKwlHUv6ezwbLLiung==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.2", + "@floating-ui/utils": "^0.1.5", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -14415,6 +14464,11 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", diff --git a/package.json b/package.json index b1b9a8f..06ac69f 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@astrojs/react": "^3.0.3", + "@floating-ui/react": "0.26.0", "@types/react": "^18.2.25", "@types/react-dom": "^18.2.10", "astro": "^3.2.3", diff --git a/src/components/buttons/buttons.module.css b/src/components/buttons/buttons.module.css index 596bff5..fb30169 100644 --- a/src/components/buttons/buttons.module.css +++ b/src/components/buttons/buttons.module.css @@ -73,4 +73,12 @@ color: var(--color-foreground); } } + + & .tooltip { + padding: 6px 12px; + border: 1px solid var(--color-neutral-200); + border-radius: 100px; + background-color: var(--color-neutral-100); + font-size: var(--font-xsm); + } } diff --git a/src/components/buttons/buttons.tsx b/src/components/buttons/buttons.tsx index 720b18e..e04c36c 100644 --- a/src/components/buttons/buttons.tsx +++ b/src/components/buttons/buttons.tsx @@ -1,5 +1,17 @@ -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { BiPause, BiPlay, BiUndo, BiTrash } from 'react-icons/bi/index'; +import { + useFloating, + autoUpdate, + offset, + flip, + shift, + useHover, + useFocus, + useDismiss, + useRole, + useInteractions, +} from '@floating-ui/react'; import { useSoundStore } from '@/store'; import { usePlay } from '@/contexts/play'; @@ -8,6 +20,34 @@ import { cn } from '@/helpers/styles'; import styles from './buttons.module.css'; export function Buttons() { + /** + * Tooltip Start + */ + const [isTooltipOpen, setIsTooltipOpen] = useState(false); + + const { context, floatingStyles, refs } = useFloating({ + middleware: [offset(15), flip(), shift()], + onOpenChange: setIsTooltipOpen, + open: isTooltipOpen, + placement: 'top', + whileElementsMounted: autoUpdate, + }); + + const hover = useHover(context, { move: false }); + const focus = useFocus(context); + const dismiss = useDismiss(context); + const role = useRole(context, { role: 'tooltip' }); + + const { getFloatingProps, getReferenceProps } = useInteractions([ + hover, + focus, + dismiss, + role, + ]); + /** + * Tooltip End + */ + const { isPlaying, pause, toggle } = usePlay(); const noSelected = useSoundStore(state => state.noSelected()); const restoreHistory = useSoundStore(state => state.restoreHistory); @@ -50,6 +90,8 @@ export function Buttons() { + + {isTooltipOpen && ( +