diff --git a/src/components/buttons/buttons.module.css b/src/components/buttons/buttons.module.css index fb30169..a52e6ec 100644 --- a/src/components/buttons/buttons.module.css +++ b/src/components/buttons/buttons.module.css @@ -3,82 +3,9 @@ z-index: 10; top: 30px; display: flex; + width: max-content; align-items: center; justify-content: center; + margin: 0 auto; column-gap: 10px; - - & .playButton { - display: flex; - width: 150px; - height: 45px; - align-items: center; - justify-content: center; - border: none; - border-radius: 100px; - border-top: 2px solid #818cf8; - border-bottom: 3px solid #4f46e5; - background-color: #6366f1; - color: var(--color-foreground); - cursor: pointer; - font-family: var(--font-heading); - font-size: var(--font-base); - line-height: 0; - outline: none; - - &:disabled, - &.disabled { - cursor: not-allowed; - } - - & span { - font-size: var(--font-lg); - } - } - - & .smallButton { - display: flex; - width: 45px; - height: 45px; - align-items: center; - justify-content: center; - border: none; - border-radius: 100px; - border-top: 2px solid var(--color-neutral-950); - border-bottom: 3px solid var(--color-neutral-600); - background-color: var(--color-neutral-800); - color: var(--color-neutral-200); - cursor: pointer; - font-family: var(--font-heading); - font-size: var(--font-md); - line-height: 0; - outline: none; - transition: 0.2s; - - &:disabled, - &.disabled { - cursor: not-allowed; - } - - &.restore { - border-top-color: #34d399; - border-bottom-color: #047857; - background-color: #10b981; - color: var(--color-foreground); - } - - &.delete { - border-top-color: #fb7185; - border-bottom-color: #be123c; - background-color: #f43f5e; - 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 322f5c8..69ac8ac 100644 --- a/src/components/buttons/buttons.tsx +++ b/src/components/buttons/buttons.tsx @@ -1,134 +1,13 @@ -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 { AnimatePresence, motion } from 'framer-motion'; - -import { useSoundStore } from '@/store'; -import { usePlay } from '@/contexts/play'; -import { cn } from '@/helpers/styles'; +import { PlayButton } from './play'; +import { UnselectButton } from './unselect'; 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); - const hasHistory = useSoundStore(state => !!state.history); - const unselectAll = useSoundStore(state => state.unselectAll); - - const handleClick = () => { - if (noSelected) return pause(); - - toggle(); - }; - - useEffect(() => { - if (isPlaying && noSelected) pause(); - }, [isPlaying, pause, noSelected]); - return (
- - {isPlaying ? ( - <> - - - {' '} - Pause - - ) : ( - <> - - - {' '} - Play - - )} - - - - {(!noSelected || hasHistory) && ( - - - - )} - - - {isTooltipOpen && ( -
- {hasHistory ? 'Restore unselected sounds.' : 'Unselect all sounds.'} -
- )} + +
); } diff --git a/src/components/buttons/play/index.ts b/src/components/buttons/play/index.ts new file mode 100644 index 0000000..4b1ed52 --- /dev/null +++ b/src/components/buttons/play/index.ts @@ -0,0 +1 @@ +export { PlayButton } from './play'; diff --git a/src/components/buttons/play/play.module.css b/src/components/buttons/play/play.module.css new file mode 100644 index 0000000..aa15934 --- /dev/null +++ b/src/components/buttons/play/play.module.css @@ -0,0 +1,27 @@ +.playButton { + display: flex; + width: 150px; + height: 45px; + align-items: center; + justify-content: center; + border: none; + border-radius: 100px; + border-top: 2px solid #818cf8; + border-bottom: 3px solid #4f46e5; + background-color: #6366f1; + color: var(--color-foreground); + cursor: pointer; + font-family: var(--font-heading); + font-size: var(--font-base); + line-height: 0; + outline: none; + + &:disabled, + &.disabled { + cursor: not-allowed; + } + + & span { + font-size: var(--font-lg); + } +} diff --git a/src/components/buttons/play/play.tsx b/src/components/buttons/play/play.tsx new file mode 100644 index 0000000..f21af07 --- /dev/null +++ b/src/components/buttons/play/play.tsx @@ -0,0 +1,49 @@ +import { useEffect } from 'react'; +import { BiPause, BiPlay } from 'react-icons/bi/index'; +import { motion } from 'framer-motion'; + +import { useSoundStore } from '@/store'; +import { usePlay } from '@/contexts/play'; +import { cn } from '@/helpers/styles'; + +import styles from './play.module.css'; + +export function PlayButton() { + const { isPlaying, pause, toggle } = usePlay(); + const noSelected = useSoundStore(state => state.noSelected()); + + const handleClick = () => { + if (noSelected) return pause(); + + toggle(); + }; + + useEffect(() => { + if (isPlaying && noSelected) pause(); + }, [isPlaying, pause, noSelected]); + + return ( + + {isPlaying ? ( + <> + + + {' '} + Pause + + ) : ( + <> + + + {' '} + Play + + )} + + ); +} diff --git a/src/components/buttons/unselect/index.ts b/src/components/buttons/unselect/index.ts new file mode 100644 index 0000000..0df02c7 --- /dev/null +++ b/src/components/buttons/unselect/index.ts @@ -0,0 +1 @@ +export { UnselectButton } from './unselect'; diff --git a/src/components/buttons/unselect/unselect.module.css b/src/components/buttons/unselect/unselect.module.css new file mode 100644 index 0000000..9b1c43d --- /dev/null +++ b/src/components/buttons/unselect/unselect.module.css @@ -0,0 +1,39 @@ +.unselectButton { + display: flex; + width: 45px; + height: 45px; + align-items: center; + justify-content: center; + border: none; + border-radius: 100px; + border-top: 2px solid #fb7185; + border-bottom: 3px solid #be123c; + background-color: #f43f5e; + color: var(--color-foreground); + cursor: pointer; + font-family: var(--font-heading); + font-size: var(--font-md); + line-height: 0; + outline: none; + transition: 0.2s; + + &:disabled, + &.disabled { + cursor: not-allowed; + } + + &.restore { + border-top-color: #34d399; + border-bottom-color: #047857; + background-color: #10b981; + 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/unselect/unselect.tsx b/src/components/buttons/unselect/unselect.tsx new file mode 100644 index 0000000..6f8cf8a --- /dev/null +++ b/src/components/buttons/unselect/unselect.tsx @@ -0,0 +1,93 @@ +import { useState } from 'react'; +import { BiUndo, BiTrash } from 'react-icons/bi/index'; +import { + useFloating, + autoUpdate, + offset, + flip, + shift, + useHover, + useFocus, + useDismiss, + useRole, + useInteractions, +} from '@floating-ui/react'; +import { AnimatePresence, motion } from 'framer-motion'; + +import { useSoundStore } from '@/store'; +import { cn } from '@/helpers/styles'; + +import styles from './unselect.module.css'; + +export function UnselectButton() { + 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, + ]); + + const noSelected = useSoundStore(state => state.noSelected()); + const restoreHistory = useSoundStore(state => state.restoreHistory); + const hasHistory = useSoundStore(state => !!state.history); + const unselectAll = useSoundStore(state => state.unselectAll); + + return ( + <> + + {(!noSelected || hasHistory) && ( + + + + )} + + + {isTooltipOpen && ( +
+ {hasHistory ? 'Restore unselected sounds.' : 'Unselect all sounds.'} +
+ )} + + ); +}