Skip to content

Commit 0d56e27

Browse files
authored
Merge pull request #41 from ymrl/a11y_check_practice_2024
👍 順番のおかしいフォームとダメツールチップ、バリデーションを追加
2 parents 102b2ef + 59194f3 commit 0d56e27

File tree

2 files changed

+157
-22
lines changed

2 files changed

+157
-22
lines changed

src/components/parts/CheckBox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const CheckBox = ({
1616
value?: string;
1717
id?: string;
1818
checked?: boolean;
19-
onChange?: React.ChangeEventHandler;
19+
onChange?: React.ChangeEventHandler<HTMLInputElement>;
2020
}): JSX.Element => (
2121
<CheckBoxWrapper>
2222
<input type="checkbox" {...props} />

src/pages/practice/index.tsx

Lines changed: 156 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,10 @@ import {
2323
MdDelete,
2424
MdEdit,
2525
MdRemove,
26+
MdHelp,
2627
} from 'react-icons/md';
2728
import { BadVisual } from '../../components/examples/link';
28-
import {
29-
ExampleContainer,
30-
FieldWithBadErrorMessage,
31-
} from '../../components/examples';
29+
import { ExampleContainer } from '../../components/examples';
3230
import { styled } from 'styled-components';
3331

3432
const SmallButton = styled.button`
@@ -62,6 +60,51 @@ const GrayText = styled.p`
6260
color: #999;
6361
`;
6462

63+
const ErrorMessage = styled(P)`
64+
color: #dc1e32;
65+
`;
66+
67+
const HelpIcon = styled.span`
68+
color: #8c8989;
69+
font-size: 1.5em;
70+
margin-left: 0.25em;
71+
cursor: pointer;
72+
position: relative;
73+
display: inline-block;
74+
`;
75+
const Help = styled.span`
76+
display: none;
77+
position: absolute;
78+
bottom: calc(100% + 0.5rem);
79+
color: #323232;
80+
left: -1.25rem;
81+
background-color: #fff;
82+
border: 1px solid #d7d2d2;
83+
padding: 0.5em;
84+
border-radius: 0.25em;
85+
box-shadow: 1px 2px 4px 0 rgba(0, 0, 0, 0.3);
86+
z-index: 1;
87+
width: 20rem;
88+
font-size: 0.75rem;
89+
font-weight: normal;
90+
&:before {
91+
content: '';
92+
position: absolute;
93+
top: 100%;
94+
left: calc(1.5rem - 2px);
95+
border: calc(0.5em + 2px) solid transparent;
96+
border-top-color: #d7d2d2;
97+
}
98+
&:after {
99+
content: '';
100+
position: absolute;
101+
top: 100%;
102+
left: 1.5rem;
103+
border: 0.5em solid transparent;
104+
border-top-color: #fff;
105+
}
106+
`;
107+
65108
const Practice = (): JSX.Element => {
66109
React.useEffect(() => {
67110
const html = document.getElementsByTagName('html')[0];
@@ -87,6 +130,11 @@ const Practice = (): JSX.Element => {
87130
| 'overseas'
88131
>();
89132
const [counter, setCounter] = React.useState(12345);
133+
const [postalCode, setPostalCode] = React.useState('');
134+
const postalCodeTouchedRef = React.useRef(false);
135+
const [postalCodeMessage, setPostalCodeMessage] = React.useState('');
136+
const [helpHover, setHelpHover] = React.useState(false);
137+
const [agree, setAgree] = React.useState(false);
90138

91139
return (
92140
<>
@@ -164,7 +212,24 @@ const Practice = (): JSX.Element => {
164212
as="span"
165213
/>
166214
</ExampleContainer>
167-
<H4>カウンター</H4>
215+
<H4>
216+
カウンター
217+
<HelpIcon>
218+
<MdHelp
219+
role="img"
220+
aria-label="ヘルプ"
221+
onMouseEnter={() => setHelpHover(true)}
222+
onMouseLeave={() => setHelpHover(false)}
223+
onFocus={() => setHelpHover(true)}
224+
onBlur={() => setHelpHover(false)}
225+
tabIndex={0}
226+
/>
227+
<Help style={{ display: helpHover ? 'block' : 'none' }}>
228+
カウンターの値を増減するボタンです。ボタンを押すとカウンターの値が増減します。
229+
詳しくは <TextLink href="http://example.com/">こちら</TextLink>
230+
</Help>
231+
</HelpIcon>
232+
</H4>
168233
<ExampleContainer>
169234
<SmallButton
170235
onClick={() => setCounter(counter + 1)}
@@ -381,25 +446,95 @@ const Practice = (): JSX.Element => {
381446
</fieldset>
382447
</FormItem>
383448
<FormItem>
384-
<CheckBox name="toc" value="agree">
385-
利用規約に同意する
386-
</CheckBox>
449+
<label htmlFor="postal_code">
450+
<FormLabel>郵便番号</FormLabel>
451+
</label>
452+
<TextField
453+
type="text"
454+
value={postalCode}
455+
onFocus={() => {
456+
postalCodeTouchedRef.current = true;
457+
setPostalCodeMessage(
458+
postalCodeTouchedRef.current &&
459+
!postalCode.match(/^[-]{3}-[-]{4}$/)
460+
? '入力形式が正しくありません'
461+
: ''
462+
);
463+
}}
464+
onChange={(e) => {
465+
const value = e.target.value;
466+
setPostalCode(value);
467+
setPostalCodeMessage(
468+
postalCodeTouchedRef.current &&
469+
!value.match(/^[-]{3}-[-]{4}$/)
470+
? '入力形式が正しくありません'
471+
: ''
472+
);
473+
}}
474+
placeholder="141-0032"
475+
aria-label="postal_code"
476+
id="postal_code"
477+
/>
478+
{postalCodeMessage && (
479+
<ErrorMessage>{postalCodeMessage}</ErrorMessage>
480+
)}
387481
</FormItem>
388-
</ExampleContainer>
389-
<ExampleContainer>
390-
<FieldWithBadErrorMessage fieldAriaLabel="postal-code" />
391-
</ExampleContainer>
392-
<div style={{ marginTop: '1rem' }}>
393-
<Button
394-
onMouseDown={() => {
395-
window.alert('送信しました');
482+
<div
483+
style={{
484+
display: 'flex',
485+
alignItems: 'start',
486+
flexDirection: 'column-reverse',
487+
marginBottom: '1rem',
488+
gap: '1rem'
396489
}}
397-
as="span"
398-
tabIndex={0}
399490
>
400-
送信
401-
</Button>
402-
</div>
491+
<FormItem>
492+
<label htmlFor="address">
493+
<FormLabel>住所</FormLabel>
494+
</label>
495+
<TextField type="text" id="address" />
496+
</FormItem>
497+
<FormItem>
498+
<label htmlFor="city">
499+
<FormLabel>市区町村</FormLabel>
500+
</label>
501+
<TextField type="text" id="city" />
502+
</FormItem>
503+
<FormItem>
504+
<label htmlFor="prefecture">
505+
<FormLabel>都道府県</FormLabel>
506+
</label>
507+
<TextField type="text" id="prefecture" />
508+
</FormItem>
509+
</div>
510+
<FormItem>
511+
<Button
512+
onMouseDown={() => {
513+
window.alert(
514+
postalCodeMessage
515+
? '送信できません。入力内容を確認してください':
516+
!agree || !postalCode ? '入力が不正です'
517+
: '送信しました'
518+
);
519+
}}
520+
as="span"
521+
tabIndex={0}
522+
>
523+
送信
524+
</Button>
525+
526+
<div style={{ display: 'inline-block', marginLeft: '1rem'}}>
527+
<CheckBox
528+
name="tos"
529+
value="agree"
530+
checked={agree}
531+
onChange={(e) => setAgree(e.target.checked)}
532+
>
533+
利用規約に同意する
534+
</CheckBox>
535+
</div>
536+
</FormItem>
537+
</ExampleContainer>
403538
</>
404539
);
405540
};

0 commit comments

Comments
 (0)