Skip to content

Commit

Permalink
Merge pull request #705 from woowacourse-teams/feature/#703
Browse files Browse the repository at this point in the history
모임 목록 페이지 접근성 개선
  • Loading branch information
ss0526100 authored Oct 23, 2024
2 parents 56fc3d1 + 4f3e64a commit a9b635b
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 36 deletions.
4 changes: 2 additions & 2 deletions frontend/src/components/NavigationBar/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export default function NavigationBar() {
};

return (
<nav css={S.navigationBarContainer({ theme })}>
<ul css={[S.navigationBarList]}>
<nav id="bottom-nav" css={S.navigationBarContainer({ theme })}>
<ul css={[S.navigationBarList]} role="menu">
{Object.keys(tabRoutes).map((tab) => (
<NavigationBarItem
key={tab}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ export default function NavigationBarItem(props: NavigationBarItemProps) {

return (
<li
role="menuitem"
aria-label={tab}
css={S.navigationBarItem({ theme, isActive })}
onClick={() => onClick(tab)}
tabIndex={0}
>
{tabIcon}
<span css={[theme.typography.c2, common.nonDrag]}>{tab}</span>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/PlusButton/PlusButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function PlusButton(props: PlusButtonProps) {
const { onClick } = props;

return (
<button onClick={onClick} css={S.plusButton}>
<button onClick={onClick} css={S.plusButton} aria-label="모임 생성">
<PlusIcon />
</button>
);
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/RefreshButton/RefreshButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default function RefreshButton() {
queryKey: [QUERY_KEYS.darakbang, getLastDarakbangId()],
})
}
aria-label="새로고침"
>
<Refresh />
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import * as S from './ListContent.style';
export default function ListContent(props: PropsWithChildren) {
const { children } = props;

return <div css={S.ListSection}>{children}</div>;
return <ul css={S.ListSection}>{children}</ul>;
}
17 changes: 17 additions & 0 deletions frontend/src/pages/Moim/MainPage/MainPage.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,20 @@ export const ModalContent = (props: { theme: Theme }) => css`
margin-bottom: 4rem;
padding-right: 60px;
`;

export const skipLink = () => css`
position: absolute;
z-index: 100;
top: -40px;
left: 0;
padding: 8px;
color: #fff;
background: #000;
&:focus {
top: 0;
}
`;
32 changes: 23 additions & 9 deletions frontend/src/pages/Moim/MainPage/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,28 +148,44 @@ export default function MainPage() {
}, [darakbangMenuOption]);
return (
<Fragment>
<a href="#bottom-nav" css={S.skipLink}>
하단 메뉴 바로가기
</a>
<DefaultPageLayout>
<DefaultPageLayout.DoubleTriHeader>
<DefaultPageLayout.DoubleTriHeader.Top>
<DefaultPageLayout.DoubleTriHeader.Top.Left>
<div
css={[S.headerLeft, common.cursorPointer, common.nonDrag]}
<button
css={[
S.headerLeft,
common.cursorPointer,
common.nonDrag,
{
background: 'none',
border: 'none',
},
]}
onClick={(e) => {
e.stopPropagation();
setIsDarakbangMenuOpened(!isDarakbangMenuOpened);
}}
aria-label="다락방"
>
<DarakbangNameWrapper>{darakbangName}</DarakbangNameWrapper>
<SolidArrow
direction={isDarakbangMenuOpened ? 'up' : 'down'}
width="15"
height="15"
/>
</div>
</button>
</DefaultPageLayout.DoubleTriHeader.Top.Left>

<DefaultPageLayout.DoubleTriHeader.Top.Right>
<button css={S.headerButton} onClick={handleNotification}>
<button
css={S.headerButton}
onClick={handleNotification}
aria-label="알림센터"
>
<Notification />
</button>
<RefreshButton />
Expand All @@ -178,16 +194,14 @@ export default function MainPage() {
{isDarakbangMenuOpened && darakbangMenu}
<MoimTabBar currentTab={currentTab} onTabClick={handleTabClick} />
</DefaultPageLayout.DoubleTriHeader>

<DefaultPageLayout.Main>
<HomeMainContent currentTab={currentTab} />
</DefaultPageLayout.Main>

<DefaultPageLayout.ListPageFixedButtonWrapper>
<PlusButton
onClick={() => navigate(GET_ROUTES.nowDarakbang.addMoim())}
/>
</DefaultPageLayout.ListPageFixedButtonWrapper>
<DefaultPageLayout.Main>
<HomeMainContent currentTab={currentTab} />
</DefaultPageLayout.Main>
</DefaultPageLayout>

<NavigationBarWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import * as S from './MoimCard.style';

import { formatHhmmToKorean, formatYyyymmddToKorean } from '@_utils/formatters';

import { HTMLProps } from 'react';
import HeartIcon from '@_components/Icons/HeartIcon';
import { MoimInfo } from '@_types/index';
import useChangeZzim from '@_hooks/mutaions/useChangeZzim';
import { useTheme } from '@emotion/react';

interface MoimCardProps extends HTMLProps<HTMLDivElement> {
interface MoimCardProps extends HTMLProps<HTMLLIElement> {
moimInfo: MoimInfo;
}

Expand All @@ -28,29 +26,59 @@ export default function MoimCard(props: MoimCardProps) {
} = props;

const theme = useTheme();

const { mutate: changeZzim } = useChangeZzim();
const { onClick, ...restArgs } = args;

const handleHeartButtonClick = (e: React.MouseEvent<HTMLButtonElement>) => {
const handleKeyDown = (e: React.KeyboardEvent<HTMLLIElement>) => {
if (e.currentTarget !== e.target) {
return;
}
if (onClick && (e.key === 'Enter' || e.key === ' ')) {
e.preventDefault();
onClick(e as unknown as React.MouseEvent<HTMLLIElement>);
}
};
const handleZzimButtonClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
changeZzim(moimId);
};

// 카드 전체 정보를 aria-describedby로 제공
const cardInfoId = `moim-info-${moimId}`;
const titleId = `moim-title-${moimId}`;

return (
<div css={S.cardBox} {...args}>
<li
css={S.cardBox}
aria-labelledby={titleId}
aria-describedby={cardInfoId}
tabIndex={0}
onClick={onClick}
onKeyDown={handleKeyDown}
{...restArgs}
>
<div css={S.titleBox}>
<h2 css={S.cardTitle({ theme })}>{title}</h2>
<button css={S.heartButton} onClick={handleHeartButtonClick}>
{/* 제목을 스크린 리더에 읽히도록 id를 부여 */}
<h2 id={titleId} css={S.cardTitle({ theme })}>
{title}
</h2>
<button
css={S.heartButton}
onClick={handleZzimButtonClick}
aria-label={isZzimed ? '찜 취소' : '찜하기'}
tabIndex={0}
role="button"
>
<HeartIcon isFilled={isZzimed} />
</button>
</div>

<div css={S.detailInfo({ theme })}>
<div id={cardInfoId} css={S.detailInfo({ theme })} aria-hidden="true">
{(date || time) && (
<div css={S.subjectBox}>
<span
css={S.subjectTag({ theme })}
>{`${date ? '날짜' : ''}${date && time ? ' 및 ' : ''}${time ? '시간' : ''}`}</span>
<span css={S.subjectTag({ theme })}>
{`${date ? '날짜' : ''}${date && time ? ' 및 ' : ''}${time ? '시간' : ''}`}
</span>
<span css={S.subjectInfo({ theme })}>
{`${date ? formatYyyymmddToKorean(date) + ' ' : ''}${time ? formatHhmmToKorean(time) : ''}`}
</span>
Expand All @@ -71,6 +99,6 @@ export default function MoimCard(props: MoimCardProps) {
</span>
</div>
</div>
</div>
</li>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ export const tabItemStyle = (props: { theme: Theme; isTurnedOn: boolean }) => {
return css`
${theme.typography.s1}
margin: 0 0 0 1rem;
color: ${isTurnedOn ? theme.semantic.primary : theme.semantic.disabled};
background: none;
border: none;
border-bottom: ${isTurnedOn
? `2px solid ${theme.semantic.primary}`
: 'none'};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as S from './MoimTabBar.style';

import { common } from '@_common/common.style';
import { useTheme } from '@emotion/react';

Expand All @@ -14,22 +13,24 @@ interface MoimTabBarProps {

export default function MoimTabBar(props: MoimTabBarProps) {
const { currentTab, onTabClick } = props;

const theme = useTheme();

return (
<nav css={S.tabStyle}>
<nav css={S.tabStyle} role="tablist" aria-label="Moim tabs">
{tabs.map((tab, index) => (
<p
<button
key={index}
role="tab"
aria-selected={currentTab === tab}
tabIndex={0}
css={[
S.tabItemStyle({ theme, isTurnedOn: currentTab === tab }),
common.nonDrag,
]}
onClick={() => onTabClick(tab)}
>
{tab}
</p>
</button>
))}
</nav>
);
Expand Down
9 changes: 4 additions & 5 deletions frontend/src/pages/Moim/MoimDetailPage/MoimDetailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { useNavigate, useParams } from 'react-router-dom';

import BackLogo from '@_common/assets/back.svg';
import Button from '@_components/Button/Button';
import CommentList from './components/CommentList/CommentList';
import CommentListSkeleton from './components/CommentList/CommentListSkeleton';
Expand Down Expand Up @@ -30,6 +28,7 @@ import useOpenChat from '@_hooks/mutaions/useOpenChat';
import useReopenMoim from '@_hooks/mutaions/useReopenMoim';
import { useTheme } from '@emotion/react';
import useZzimMine from '@_hooks/queries/useZzimMine';
import BackArrowButton from '@_components/Button/BackArrowButton/BackArrowButton';

export default function MoimDetailPage() {
const navigate = useNavigate();
Expand Down Expand Up @@ -185,9 +184,9 @@ export default function MoimDetailPage() {
<InformationLayout>
<InformationLayout.Header>
<InformationLayout.Header.Left>
<div onClick={() => navigate(GET_ROUTES.nowDarakbang.main())}>
<BackLogo />
</div>
<BackArrowButton
onClick={() => navigate(GET_ROUTES.nowDarakbang.main())}
/>
</InformationLayout.Header.Left>
<InformationLayout.Header.Right>
{isZzimMineLoading && (
Expand Down

0 comments on commit a9b635b

Please sign in to comment.