Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

웹 접근성 개선 #693

Merged
merged 5 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function BackArrowButton(props: BackArrowButtonProps) {
const { ...rest } = props;

return (
<button {...rest} css={S.button}>
<button {...rest} css={S.button} aria-label="뒤로가기">
<BackArrowIcon />
</button>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useTheme } from '@emotion/react';
import { HTMLAttributes, PropsWithChildren } from 'react';

interface FunnelInputErrorMessageProps
extends HTMLAttributes<HTMLSpanElement> {}

export default function FunnelInputErrorMessage(
props: PropsWithChildren<FunnelInputErrorMessageProps>,
) {
const { children, ...rest } = props;

const theme = useTheme();

return (
<span css={[theme.typography.b3]} {...rest}>
{children}
</span>
);
}
10 changes: 6 additions & 4 deletions frontend/src/components/Funnel/FunnelQuestion/FunnelQuestion.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { PropsWithChildren } from 'react';
import { LabelHTMLAttributes, PropsWithChildren } from 'react';
import FunnelQuestionHighlight from './FunnelQuestionHighlight/FunnelQuestionHighlight';
import FunnelTextQuestionText from './FunnelQuestionText/FunnelQuestionText';

function FunnelQuestion(props: PropsWithChildren) {
const { children } = props;
interface FunnelQuestionProps extends LabelHTMLAttributes<HTMLLabelElement> {}

return <h5>{children}</h5>;
function FunnelQuestion(props: PropsWithChildren<FunnelQuestionProps>) {
const { children, ...rest } = props;

return <label {...rest}>{children}</label>;
}

FunnelQuestion.Text = FunnelTextQuestionText;
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/HighlightSpan/HighlightSpan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface HighlightSpanProps extends PropsWithChildren {
normalColor?: SerializedStyles | string;
font?: SerializedStyles | string;
isCenterAlign?: boolean;
ariaLabel?: string;
}

interface HighlightSpanContext {
Expand All @@ -24,14 +25,18 @@ function HighlightSpan(props: HighlightSpanProps) {
normalColor = theme.colorPalette.black[100],
font = theme.typography.h5,
isCenterAlign = false,
ariaLabel,
children,
} = props;

return (
<HighlightSpanContext.Provider
value={{ highlightColor, normalColor, font }}
>
<span css={S.text({ color: normalColor, font, isCenterAlign })}>
<span
aria-label={ariaLabel}
css={S.text({ color: normalColor, font, isCenterAlign })}
>
{children}
</span>
</HighlightSpanContext.Provider>
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="en">
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand All @@ -12,7 +12,7 @@
<meta property="og:title" content="모우다" />
<meta property="og:type" content="website" />
<meta property="og:image" content="/preview-image.png" />
<meta property="og:description" content="모여봐요 우리들의 다락방으로" />
<meta property="og:description" content="모여봐요 우리의 다락방" />
<meta property="og:site_name" content="모우다" />

<meta name="apple-mobile-web-app-title" content="모우다" />
Expand All @@ -25,7 +25,5 @@
</head>
<body>
<div id="root"></div>

</body>

</html>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export const container = (keyboardHeight: number) => css`

display: flex;
flex-direction: column;
gap: 20px;
gap: 12px;
align-items: center;

width: 100%;
max-width: ${DISPLAY_MAX_WIDTH};
Expand Down
15 changes: 12 additions & 3 deletions frontend/src/layouts/FunnelLayout/FunnelFooter/FunnelFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { PropsWithChildren, useEffect, useState } from 'react';
import * as S from './FunnelFooter.style';

export default function FunnelFooter(props: PropsWithChildren) {
const { children } = props;
interface FunnelFooterProps {
isResize?: boolean;
}

export default function FunnelFooter(
props: PropsWithChildren<FunnelFooterProps>,
) {
const { children, isResize = true } = props;
const [keyboardHeight, setKeyboardHeight] = useState(0);

useEffect(() => {
if (!isResize) return;

const handleResize = () => {
if (window.visualViewport) {
const keyboardHeight =
window.innerHeight - window.visualViewport.height;
setKeyboardHeight(Math.max(0, keyboardHeight));
console.log(Math.max(0, keyboardHeight));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console.log 지워줘요잉~~~

}
};

window.visualViewport?.addEventListener('resize', handleResize);
return () =>
window.visualViewport?.removeEventListener('resize', handleResize);
}, []);
}, [isResize]);

return <div css={S.container(keyboardHeight)}>{children}</div>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ export default function DarakbangCreationModalContent(
const theme = useTheme();
return (
<div css={S.content({ theme })}>
<HighlightSpan font={theme.typography.s1}>
<HighlightSpan
font={theme.typography.s1}
ariaLabel={`다락방 이름으로 ${darakbangName}, 닉네임으로 ${nickname}을(를) 선택하셨습니다. 한 번 선택한 다락방 이름은 바꿀 수 없습니다. 진행하시겠습니까?`}
>
{'다락방 이름으로 '}
<HighlightSpan.Highlight>{darakbangName}</HighlightSpan.Highlight>
{',\n닉네임으로 '}
<HighlightSpan.Highlight>{nickname}</HighlightSpan.Highlight>
{
'을(를) 선택하셨습니다.\n\n한 번 선택한 다락방 이름과 닉네임은 바꿀 수 없습니다.\n진행하시겠습니까?'
'을(를) 선택하셨습니다.\n\n한 번 선택한 다락방 이름은 바꿀 수 없습니다. 진행하시겠습니까?'
}
</HighlightSpan>
<div css={S.buttonContainer}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import HighlightSpan from '@_components/HighlightSpan/HighlightSpan';
import Modal from '@_components/Modal/Modal';
import POLICES from '@_constants/poclies';
import SelectLayout from '@_layouts/SelectLayout/SelectLayout';
import SolidArrow from '@_components/Icons/SolidArrow';
import { setLastDarakbangId } from '@_common/lastDarakbangManager';
import useCreateDarakbang from '@_hooks/mutaions/useCreateDarakbang';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import BackArrowButton from '@_components/Button/BackArrowButton/BackArrowButton';

export default function DarakbangCreationPage() {
const theme = useTheme();
Expand All @@ -34,8 +34,7 @@ export default function DarakbangCreationPage() {
<SelectLayout>
<SelectLayout.Header>
<SelectLayout.Header.Left>
<SolidArrow
direction="left"
<BackArrowButton
onClick={() => {
navigate(-1);
}}
Expand All @@ -47,23 +46,22 @@ export default function DarakbangCreationPage() {
</SelectLayout.Header>
<SelectLayout.ContentContainer>
<div css={S.labeledInput}>
<HighlightSpan>
{'다락방의 '}
<HighlightSpan.Highlight>이름</HighlightSpan.Highlight>은
<HighlightSpan ariaLabel="다락방의 이름은 무엇인가요?">
다락방의 <HighlightSpan.Highlight>이름</HighlightSpan.Highlight>은
무엇인가요?
</HighlightSpan>

<ErrorControlledInput
errorMessage=""
placeholder="다락방의 이름을 입력해주세요"
placeholder="다락방의 이름을 입력해주세요."
onChange={(e: ChangeEvent<HTMLInputElement>) => {
setDarakbangName(e.target.value);
}}
maxLength={POLICES.maxDarakbangName}
/>
</div>
<div css={S.labeledInput}>
<HighlightSpan>
<HighlightSpan ariaLabel="닉네임을 입력해주세요.최대 12글자까지 가능해요.">
<HighlightSpan.Highlight>닉네임</HighlightSpan.Highlight>을
입력해주세요{'\n최대 '}
<HighlightSpan.Highlight>{`${POLICES.maxNicknameLength}글자`}</HighlightSpan.Highlight>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import ErrorControlledInput from '@_components/ErrorControlledInput/ErrorControl
import POLICES from '@_constants/poclies';
import ROUTES from '@_constants/routes';
import SelectLayout from '@_layouts/SelectLayout/SelectLayout';
import SolidArrow from '@_components/Icons/SolidArrow';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import BackArrowButton from '@_components/Button/BackArrowButton/BackArrowButton';

export default function DarakbangEntrancePage() {
const theme = useTheme();
Expand All @@ -17,8 +17,7 @@ export default function DarakbangEntrancePage() {
<SelectLayout>
<SelectLayout.Header>
<SelectLayout.Header.Left>
<SolidArrow
direction="left"
<BackArrowButton
onClick={() => {
navigate(-1);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ export default function DarakbangLandingPage() {
</CompleteLayout.Header.Center>
</CompleteLayout.Header>
<CompleteLayout.ContentContainer>
<HighlightSpan isCenterAlign>
<HighlightSpan
isCenterAlign
ariaLabel={`${myInfo?.nickname}님 반가워요~! 이제 모임을 확인해볼까요?`}
>
<HighlightSpan.Highlight>{myInfo?.nickname}</HighlightSpan.Highlight>
{`님 반가워요~!\n이제 `}
<HighlightSpan.Highlight>모임</HighlightSpan.Highlight>을
확인해볼까요?
</HighlightSpan>{' '}
</HighlightSpan>
<CompleteLayout.BottomButtonWrapper>
<Button
shape="bar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function DarakbangSelectOptionPage() {
</SelectLayout.Header.Center>
</SelectLayout.Header>
<SelectLayout.ContentContainer>
<HighlightSpan>
<HighlightSpan ariaLabel="다락방에 참여해보세요">
<HighlightSpan.Highlight>다락방</HighlightSpan.Highlight>에
참여해보세요
</HighlightSpan>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import HighlightSpan from '@_components/HighlightSpan/HighlightSpan';
import MissingFallback from '@_components/MissingFallback/MissingFallback';
import ROUTES from '@_constants/routes';
import SelectLayout from '@_layouts/SelectLayout/SelectLayout';
import SolidArrow from '@_components/Icons/SolidArrow';
import { common } from '@_common/common.style';
import { setLastDarakbangId } from '@_common/lastDarakbangManager';
import useMyDarakbangs from '@_hooks/queries/useMyDarakbang';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import SelectBar from '../components/SelectBar/SelectBar';
import BackArrowButton from '@_components/Button/BackArrowButton/BackArrowButton';

export default function DarakbangSelectPage() {
const theme = useTheme();
Expand All @@ -22,8 +22,7 @@ export default function DarakbangSelectPage() {
<SelectLayout>
<SelectLayout.Header>
<SelectLayout.Header.Left>
<SolidArrow
direction="left"
<BackArrowButton
onClick={() => {
navigate(-1);
}}
Expand All @@ -34,9 +33,8 @@ export default function DarakbangSelectPage() {
</SelectLayout.Header.Center>
</SelectLayout.Header>
<SelectLayout.ContentContainer>
<HighlightSpan>
{'어느 '}
<HighlightSpan.Highlight>다락방</HighlightSpan.Highlight>에
<HighlightSpan ariaLabel="어느 다락방에 들어갈까요?">
어느 <HighlightSpan.Highlight>다락방</HighlightSpan.Highlight>에
들어갈까요?
</HighlightSpan>
{isLoading && <>loading...</>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import useStatePersist from '@_hooks/useStatePersist';
import { MoimInputInfo } from '@_types/index';
import {
isApprochedByUrl,
isToday,
validateDate,
validateMaxPeople,
validatePlace,
Expand Down Expand Up @@ -80,7 +81,7 @@ const useMoimCreationForm = (currentStep: MoimCreationStep) => {
title: validateTitle(title),
place: validatePlace(place),
date: date === '' || validateDate(date),
time: time === '' || validateTime(time),
time: time === '' || (isToday(date) ? validateTime(time) : true),
maxPeople: validateMaxPeople(maxPeople),
});
}, [formData]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export const validateDate = (date: string) => {
return date >= nowDateYyyymmdd && POLICIES.yyyymmddDashRegex.test(date);
};

export const isToday = (date: string) => {
const nowDate = new Date();
const nowDateYyyymmdd = `${nowDate.getFullYear()}-${(nowDate.getMonth() + 1).toString().padStart(2, '00')}-${nowDate.getDate().toString().padStart(2, '00')}`;
return date === nowDateYyyymmdd;
};

export const validateTime = (time: string) => {
if (time === '') {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import FunnelButton from '@_components/Funnel/FunnelButton/FunnelButton';
import FunnelInput from '@_components/Funnel/FunnelInput/FunnelInput';
import FunnelInputErrorMessage from '@_components/Funnel/FunnelInputErrorMessage/FunnelInputErrorMessage';
import FunnelQuestion from '@_components/Funnel/FunnelQuestion/FunnelQuestion';
import FunnelLayout from '@_layouts/FunnelLayout/FunnelLayout';

Expand Down Expand Up @@ -48,23 +49,28 @@ export default function DateAndTimeStep(props: DateAndTimeStepProps) {
</FunnelLayout.Main>

<FunnelLayout.Footer>
{isValidDate && isValidTime ? null : (
<FunnelInputErrorMessage>
{!isValidDate && !isValidTime
? '날짜와 시간을 다시 확인해주세요'
: !isValidDate
? '날짜를 다시 확인해주세요'
: !isValidTime
? '시간을 다시 확인해주세요'
: null}
</FunnelInputErrorMessage>
)}
<FunnelButton
disabled={!isValidDate || !isValidTime}
onClick={onButtonClick}
>
{!isValidDate && !isValidTime
? '날짜와 시간을 다시 확인해주세요'
: !isValidDate
? '날짜를 다시 확인해주세요'
: !isValidTime
? '시간을 다시 확인해주세요'
: date === '' && time === ''
? '스킵하고 채팅에서 정할게요!'
: date === ''
? '날짜는 채팅에서 정할게요!'
: time === ''
? '시간은 채팅에서 정할게요!'
: '다음으로'}
{date === '' && time === ''
? '스킵하고 채팅에서 정할게요!'
: date === ''
? '날짜는 채팅에서 정할게요!'
: time === ''
? '시간은 채팅에서 정할게요!'
: '다음으로'}
</FunnelButton>
</FunnelLayout.Footer>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function DescriptionStep(props: DescriptionStepProps) {
/>
</FunnelLayout.Main>

<FunnelLayout.Footer>
<FunnelLayout.Footer isResize={false}>
<FunnelButton disabled={!isValid} onClick={onButtonClick}>
모임 만들기 완료!
</FunnelButton>
Expand Down
Loading
Loading