Skip to content

Commit a619011

Browse files
committed
Add sound state on Header using Recoil
1 parent 6e07b11 commit a619011

File tree

4 files changed

+86
-58
lines changed

4 files changed

+86
-58
lines changed

src/App.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import React from 'react';
2-
import './App.css';
3-
// import { HashRouter as Router, Route, Routes } from "react-router-dom";
4-
import Header from './Layout/Header/Header';
1+
import React from "react";
2+
import { RecoilRoot } from "recoil";
3+
import Header from "./Layout/Header/Header";
54

65
function App() {
7-
return (
8-
<Header />
9-
);
6+
return (
7+
<RecoilRoot>
8+
<Header />
9+
</RecoilRoot>
10+
);
1011
}
1112

1213
export default App;

src/Layout/Header/Header.tsx

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
import { Link } from 'react-router-dom';
2+
import React, { useState } from 'react';
3+
import { useRecoilState } from 'recoil';
4+
import { soundState } from '../../recoil/state/soundState';
25
import styles from './Header.module.scss'; // 스타일 시트 임포트
36

47
const Header = () => {
8+
const [isVolumeOn, setVolumeOn] = useState(soundState);
9+
10+
// 음성 토글 함수
11+
const toggleVolume = () => {
12+
setVolumeOn(!isVolumeOn);
13+
};
14+
15+
// TTS 처리 함수
16+
const handleTTS = (text) => {
17+
if (isVolumeOn) {
18+
const speech = new SpeechSynthesisUtterance(text);
19+
window.speechSynthesis.speak(speech);
20+
}
21+
};
22+
523
return (
624
<>
725
<header className={styles.header}>
@@ -80,21 +98,42 @@ const Header = () => {
8098
</div>
8199
</Link>
82100
<div className={styles.icons}>
83-
<button className={styles.volumeUpIcon}>
84-
<svg
85-
width="45"
86-
height="40"
87-
viewBox="0 0 45 40"
88-
fill="none"
89-
xmlns="http://www.w3.org/2000/svg"
90-
>
91-
<path
92-
d="M24.3947 8.33366V31.667C24.3947 32.5875 23.5544 33.3337 22.5177 33.3337H21.4103C20.9179 33.3318 20.446 33.1582 20.0964 32.8503L12.9076 26.467C11.8527 25.529 10.4214 25.0015 8.92847 25.0003C7.10401 25.0003 5.625 23.687 5.625 22.067V17.9337C5.625 16.3136 7.10401 15.0003 8.92847 15.0003C10.4214 14.9992 11.8527 14.4716 12.9076 13.5337L20.0964 7.15033C20.446 6.84242 20.9179 6.66883 21.4103 6.66699H22.5177C23.5544 6.66699 24.3947 7.41318 24.3947 8.33366ZM35.6565 11.217C35.476 11.0547 35.2366 10.9544 34.9808 10.9337C34.7203 10.9277 34.4687 11.0183 34.2863 11.1837L32.9537 12.367C32.6199 12.6866 32.6199 13.1807 32.9537 13.5003C36.5585 17.2426 36.5585 22.7581 32.9537 26.5003C32.6199 26.82 32.6199 27.314 32.9537 27.6337L34.2863 28.817C34.4687 28.9823 34.7203 29.0729 34.9808 29.067C35.2375 29.0492 35.478 28.9484 35.6565 28.7837C40.6145 23.7556 40.6145 16.2451 35.6565 11.217ZM29.7253 15.667C29.453 15.6578 29.1884 15.7482 28.9933 15.917L27.6606 17.117C27.3407 17.3945 27.2857 17.8339 27.5292 18.167C28.3543 19.2794 28.3543 20.7212 27.5292 21.8337C27.2857 22.1667 27.3407 22.6062 27.6606 22.8837L28.9933 24.0837C29.1903 24.2481 29.4554 24.3326 29.7253 24.317C29.9963 24.3018 30.248 24.1871 30.4198 24.0003C32.4219 21.63 32.4219 18.3707 30.4198 16.0003C30.2446 15.8147 29.9962 15.6954 29.7253 15.667Z"
93-
fill="#FD841F"
94-
/>
95-
</svg>
101+
<button
102+
className={styles.volumeUpIcon}
103+
onMouseEnter={() => handleTTS('소리 버튼')}
104+
onClick={toggleVolume}
105+
>
106+
{isVolumeOn ? (
107+
<svg
108+
width="45"
109+
height="40"
110+
viewBox="0 0 45 40"
111+
fill="none"
112+
xmlns="http://www.w3.org/2000/svg"
113+
>
114+
<path
115+
d="M24.3947 8.33366V31.667C24.3947 32.5875 23.5544 33.3337 22.5177 33.3337H21.4103C20.9179 33.3318 20.446 33.1582 20.0964 32.8503L12.9076 26.467C11.8527 25.529 10.4214 25.0015 8.92847 25.0003C7.10401 25.0003 5.625 23.687 5.625 22.067V17.9337C5.625 16.3136 7.10401 15.0003 8.92847 15.0003C10.4214 14.9992 11.8527 14.4716 12.9076 13.5337L20.0964 7.15033C20.446 6.84242 20.9179 6.66883 21.4103 6.66699H22.5177C23.5544 6.66699 24.3947 7.41318 24.3947 8.33366ZM35.6565 11.217C35.476 11.0547 35.2366 10.9544 34.9808 10.9337C34.7203 10.9277 34.4687 11.0183 34.2863 11.1837L32.9537 12.367C32.6199 12.6866 32.6199 13.1807 32.9537 13.5003C36.5585 17.2426 36.5585 22.7581 32.9537 26.5003C32.6199 26.82 32.6199 27.314 32.9537 27.6337L34.2863 28.817C34.4687 28.9823 34.7203 29.0729 34.9808 29.067C35.2375 29.0492 35.478 28.9484 35.6565 28.7837C40.6145 23.7556 40.6145 16.2451 35.6565 11.217ZM29.7253 15.667C29.453 15.6578 29.1884 15.7482 28.9933 15.917L27.6606 17.117C27.3407 17.3945 27.2857 17.8339 27.5292 18.167C28.3543 19.2794 28.3543 20.7212 27.5292 21.8337C27.2857 22.1667 27.3407 22.6062 27.6606 22.8837L28.9933 24.0837C29.1903 24.2481 29.4554 24.3326 29.7253 24.317C29.9963 24.3018 30.248 24.1871 30.4198 24.0003C32.4219 21.63 32.4219 18.3707 30.4198 16.0003C30.2446 15.8147 29.9962 15.6954 29.7253 15.667Z"
116+
fill="#FD841F"
117+
/>
118+
</svg>
119+
) : (
120+
<svg
121+
width="34"
122+
height="26"
123+
viewBox="0 0 34 26"
124+
fill="none"
125+
xmlns="http://www.w3.org/2000/svg"
126+
>
127+
<path
128+
fill-rule="evenodd"
129+
clip-rule="evenodd"
130+
d="M25.6606 9.30264C25.8831 9.0974 26.1847 8.98211 26.4991 8.98211C26.8135 8.98211 27.1151 9.0974 27.3376 9.30264L29.6632 11.4508L31.9888 9.30264C32.2137 9.10904 32.5112 9.00364 32.8186 9.00865C33.126 9.01366 33.4193 9.12869 33.6367 9.3295C33.854 9.53031 33.9786 9.80123 33.984 10.0852C33.9894 10.3691 33.8753 10.6439 33.6657 10.8517L31.3417 12.9999L33.6673 15.1481C33.8833 15.3549 34.0028 15.6318 33.9999 15.9192C33.9971 16.2066 33.8722 16.4814 33.6521 16.6845C33.432 16.8876 33.1343 17.0028 32.8232 17.0051C32.5121 17.0075 32.2124 16.8969 31.9888 16.6971L29.6632 14.5489L27.3376 16.6971C27.1127 16.8907 26.8152 16.9961 26.5078 16.9911C26.2004 16.9861 25.9071 16.8711 25.6897 16.6703C25.4723 16.4695 25.3478 16.1986 25.3424 15.9146C25.3369 15.6307 25.451 15.3559 25.6606 15.1481L27.9862 12.9999L25.6606 10.8517C25.4384 10.6462 25.3136 10.3676 25.3136 10.0772C25.3136 9.78672 25.4384 9.50815 25.6606 9.30264ZM18.6475 0.426331C20.4874 -0.694534 22.9395 0.525704 22.9395 2.56138V23.4384C22.9395 25.4755 20.4874 26.6943 18.6475 25.5734L9.15524 19.7938C9.09103 19.7542 9.01569 19.7329 8.9385 19.7324H4.3506C3.19675 19.7324 2.09016 19.309 1.27426 18.5553C0.458365 17.8017 0 16.7795 0 15.7136V10.2861C0 9.2203 0.458365 8.19812 1.27426 7.44446C2.09016 6.6908 3.19675 6.26739 4.3506 6.26739H8.9385C9.01606 6.26763 9.09199 6.24679 9.15682 6.20748L18.6475 0.426331Z"
131+
fill="#FD841F"
132+
/>
133+
</svg>
134+
)}
96135
</button>
97-
<button className={styles.plusIcon}>
136+
<button onMouseEnter={() => handleTTS('화면 크게하기')} className={styles.plusIcon}>
98137
<svg
99138
width="30"
100139
height="30"
@@ -120,7 +159,7 @@ const Header = () => {
120159
</svg>
121160
</button>
122161

123-
<button className={styles.minusIcon}>
162+
<button onMouseEnter={() => handleTTS('화면 작게하기')} className={styles.minusIcon}>
124163
<svg
125164
width="30"
126165
height="30"
@@ -138,7 +177,7 @@ const Header = () => {
138177
<circle cx="8" cy="8" r="7" stroke="white" strokeWidth="2" />
139178
</svg>
140179
</button>
141-
<button className={styles.clientIcon}>
180+
<button onMouseEnter={() => handleTTS('사용자 정보')} className={styles.clientIcon}>
142181
<svg
143182
width="35"
144183
height="34"
@@ -164,22 +203,34 @@ const Header = () => {
164203

165204
<div className={styles.menu}>
166205
<div>
167-
<Link to="/home" className={styles.menuItem}>
206+
<Link to="/home" onMouseEnter={() => handleTTS('홈')} className={styles.menuItem}>
168207
169208
</Link>
170-
<Link to="/algorithm" className={styles.menuItem}>
209+
<Link
210+
to="/algorithm"
211+
onMouseEnter={() => handleTTS('알고리즘')}
212+
className={styles.menuItem}
213+
>
171214
알고리즘
172215
</Link>
173-
<Link to="/theme" className={styles.menuItem}>
216+
<Link
217+
to="/theme"
218+
onMouseEnter={() => handleTTS('테마 선택하기')}
219+
className={styles.menuItem}
220+
>
174221
테마
175222
</Link>
176223
</div>
177224
<div className={styles.userSection}>
178225
<p className={styles.greeting}>안녕하세요, 게스트님</p>
179-
<Link to="/login" className={styles.loginLink}>
226+
<Link to="/login" onMouseEnter={() => handleTTS('로그인')} className={styles.loginLink}>
180227
로그인
181228
</Link>
182-
<Link to="/register" className={styles.registerLink}>
229+
<Link
230+
to="/register"
231+
onMouseEnter={() => handleTTS('회원가입')}
232+
className={styles.registerLink}
233+
>
183234
회원가입
184235
</Link>
185236
</div>

src/recoil/README.md

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/recoil/state/soundState.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { atom } from "recoil";
2+
3+
export const soundState = atom({
4+
key: "soundState", // 고유 키값
5+
default: true, // 기본값 (볼륨 켜짐)
6+
});

0 commit comments

Comments
 (0)