diff --git a/src/components/sound/sound.tsx b/src/components/sound/sound.tsx
index 02acc50..a435ba2 100644
--- a/src/components/sound/sound.tsx
+++ b/src/components/sound/sound.tsx
@@ -1,20 +1,31 @@
import { useState, useEffect } from 'react';
+import { useSound } from '@/hooks/use-sound';
import { cn } from '@/helpers/styles';
import styles from './sound.module.css';
interface SoundProps {
- sound: { label: string; src: string };
+ label: string;
+ src: string;
}
-export function Sound({ sound }: SoundProps) {
+export function Sound({ label, src }: SoundProps) {
const [isSelected, setIsSelected] = useState(false);
const [volume, setVolume] = useState(0.5);
+ const sound = useSound(src, { loop: true, volume });
+
useEffect(() => {
- if (!isSelected) setVolume(0.5);
- }, [isSelected]);
+ if (!isSelected) {
+ sound?.pause();
+ setVolume(0.5);
+ }
+
+ if (isSelected) {
+ sound?.play();
+ }
+ }, [isSelected, sound]);
return (
setIsSelected(prev => !prev)}
onKeyDown={() => setIsSelected(prev => !prev)}
>
-
{sound.label}
+ {label}
{sounds.map(sound => (
-
+
))}
);
diff --git a/src/hooks/use-sound.ts b/src/hooks/use-sound.ts
new file mode 100644
index 0000000..3ebe467
--- /dev/null
+++ b/src/hooks/use-sound.ts
@@ -0,0 +1,32 @@
+import { useMemo, useEffect } from 'react';
+
+import { useSSR } from './use-ssr';
+
+export function useSound(
+ src: string,
+ options: { volume?: number; loop?: boolean } = {},
+): HTMLAudioElement | null {
+ const { isBrowser } = useSSR();
+ const sound = useMemo(() => {
+ let sound: HTMLAudioElement | null = null;
+
+ if (isBrowser) {
+ sound = new Audio(src);
+ sound.preload = 'none';
+ }
+
+ return sound;
+ }, [src, isBrowser]);
+
+ useEffect(() => {
+ if (sound)
+ sound.loop = typeof options.loop === 'boolean' ? options.loop : false;
+ }, [sound, options.loop]);
+
+ useEffect(() => {
+ if (sound)
+ sound.volume = typeof options.volume === 'number' ? options.volume : 0.5;
+ }, [sound, options.volume]);
+
+ return sound;
+}
diff --git a/src/hooks/use-ssr.ts b/src/hooks/use-ssr.ts
new file mode 100644
index 0000000..ef2f8c1
--- /dev/null
+++ b/src/hooks/use-ssr.ts
@@ -0,0 +1,11 @@
+export function useSSR() {
+ const isDOM =
+ typeof window !== 'undefined' &&
+ window.document &&
+ window.document.documentElement;
+
+ return {
+ isBrowser: isDOM,
+ isServer: !isDOM,
+ };
+}