Skip to content

Commit 7718d7f

Browse files
committed
Close usermenu on user icon click - Fix velopert#37
1 parent 1d5f0eb commit 7718d7f

File tree

4 files changed

+33
-10
lines changed

4 files changed

+33
-10
lines changed

src/components/base/Header.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as React from 'react';
1+
import React, { useRef, useCallback } from 'react';
22
import styled, { css } from 'styled-components';
33
import RoundButton from '../common/RoundButton';
44
import { CurrentUser } from '../../lib/graphql/user';
@@ -95,8 +95,6 @@ interface HeaderProps {
9595
isSearch: boolean;
9696
}
9797

98-
const { useCallback } = React;
99-
10098
const Header: React.FC<HeaderProps> = ({
10199
floating,
102100
floatingMargin,
@@ -108,6 +106,7 @@ const Header: React.FC<HeaderProps> = ({
108106
isSearch,
109107
}) => {
110108
const [userMenu, toggleUserMenu] = useToggle(false);
109+
const ref = useRef<HTMLDivElement>(null);
111110

112111
const onLogout = useCallback(async () => {
113112
try {
@@ -116,6 +115,16 @@ const Header: React.FC<HeaderProps> = ({
116115
storage.removeItem('CURRENT_USER');
117116
window.location.href = '/';
118117
}, []);
118+
119+
const onOutsideClick = useCallback(
120+
(e: React.MouseEvent) => {
121+
if (!ref.current) return;
122+
if (ref.current.contains(e.target as any)) return;
123+
toggleUserMenu();
124+
},
125+
[toggleUserMenu],
126+
);
127+
119128
return (
120129
<>
121130
<HeaderBlock
@@ -162,9 +171,11 @@ const Header: React.FC<HeaderProps> = ({
162171
>
163172
새 글 작성
164173
</RoundButton>
165-
<HeaderUserIcon user={user} onClick={toggleUserMenu} />
174+
<div ref={ref}>
175+
<HeaderUserIcon user={user} onClick={toggleUserMenu} />
176+
</div>
166177
<HeaderUserMenu
167-
onClose={toggleUserMenu}
178+
onClose={onOutsideClick}
168179
username={user.username}
169180
onLogout={onLogout}
170181
visible={userMenu}

src/components/base/HeaderUserIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const HeaderUserIconBlock = styled.div`
3838

3939
export interface HeaderUserIconProps {
4040
user: CurrentUser;
41-
onClick: () => void;
41+
onClick: (e: React.MouseEvent) => void;
4242
}
4343

4444
// TODO: show user thumbnail

src/components/base/HeaderUserMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const HeaderUserMenuBlock = styled.div`
2626
`;
2727

2828
interface HeaderUserMenuProps {
29-
onClose: () => void;
29+
onClose: (e: React.MouseEvent) => void;
3030
onLogout: () => void;
3131
username: string;
3232
visible: boolean;

src/components/main/MainHeader.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useRef, useCallback } from 'react';
22
import styled from 'styled-components';
33
import { Logo, SearchIcon2 } from '../../static/svg';
44
import RoundButton from '../common/RoundButton';
@@ -15,6 +15,16 @@ export type MainHeaderProps = {};
1515
function MainHeader(props: MainHeaderProps) {
1616
const { user, onLoginClick, onLogout } = useHeader();
1717
const [userMenu, toggleUserMenu] = useToggle(false);
18+
const ref = useRef<HTMLDivElement>(null);
19+
20+
const onOutsideClick = useCallback(
21+
(e: React.MouseEvent) => {
22+
if (!ref.current) return;
23+
if (ref.current.contains(e.target as any)) return;
24+
toggleUserMenu();
25+
},
26+
[toggleUserMenu],
27+
);
1828

1929
return (
2030
<Block>
@@ -37,9 +47,11 @@ function MainHeader(props: MainHeaderProps) {
3747
새 글 작성
3848
</RoundButton>
3949

40-
<HeaderUserIcon user={user} onClick={toggleUserMenu} />
50+
<div ref={ref}>
51+
<HeaderUserIcon user={user} onClick={toggleUserMenu} />
52+
</div>
4153
<HeaderUserMenu
42-
onClose={toggleUserMenu}
54+
onClose={onOutsideClick}
4355
onLogout={onLogout}
4456
username={user.username}
4557
visible={userMenu}

0 commit comments

Comments
 (0)