Reporch
문제
랭킹
포럼
챌린지
소개
IDE
로그인
회원가입
실전 UI 컴포넌트 | Reporch
목록
학습 경로
실전 UI 컴포넌트
네이티브 HTML, CSS, DOM과 접근성을 조합해 실제 서비스에서 사용하는 인터페이스를 완성합니다.
0 / 16
0%
01
동작에 맞는 HTML 요소 선택하기
5
## 이번 단계에서 배울 내용 링크는 다른 위치로 이동하고, 버튼은 현재 화면에서 동작을 실행하며, 체크박스는 켜짐과 꺼짐을 저장합니다. 모양이 비슷해도 목적에 맞는 네이티브 요소를 선택해야 키보드와 보조 기술이 기본 동작을 제공합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <a href="/guide">가이드</a> <button type="button">설명 열기</button> <label><input type="checkbox"> 알림 받기</label> ``` ## 해야 할 일 문서 링크, 설명 열기 버튼, 알림 체크박스를 각각 목적에 맞는 HTML 요소로 바꾸고 설명 버튼이 패널을 열도록 완성하세요. ## 완성 조건 - 문서 이동은 링크, 설명 열기는 button, 알림 설정은 checkbox를 사용합니다. - 설명 버튼을 누르면 도움말 패널이 표시됩니다. - 알림 체크박스는 키보드와 마우스로 선택할 수 있습니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
50.00%
02
닫을 수 있는 상태 알림 만들기
5
## 이번 단계에서 배울 내용 상태 알림은 사용자의 작업 결과를 짧고 명확하게 전달합니다. 알림을 닫을 수 있다면 닫기 버튼에는 무엇을 닫는지 알 수 있는 이름이 필요합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <section role="status"> 저장되었습니다. <button type="button" aria-label="알림 닫기">×</button> </section> ``` ## 해야 할 일 저장 완료 알림의 닫기 버튼을 연결해 알림을 제거하고, 닫은 뒤 저장 버튼으로 포커스가 돌아가게 하세요. ## 완성 조건 - 알림은 상태 메시지로 인식됩니다. - 닫기 버튼을 누르면 알림이 사라집니다. - 알림을 닫으면 저장 버튼이 다시 포커스를 받습니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
50.00%
03
Disclosure로 상세 내용 펼치기
5
## 이번 단계에서 배울 내용 Disclosure는 버튼 하나로 관련 콘텐츠를 펼치고 접는 패턴입니다. 버튼의 `aria-expanded` 값과 패널의 표시 상태는 항상 함께 바뀌어야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <button aria-expanded="false" aria-controls="details">자세히</button> <div id="details" hidden>상세 내용</div> ``` ## 해야 할 일 수강 안내 버튼을 누를 때마다 안내 패널을 펼치거나 접고 버튼의 상태를 동기화하세요. ## 완성 조건 - 처음에는 패널이 접혀 있습니다. - 버튼을 누르면 패널과 aria-expanded가 함께 변경됩니다. - Space 또는 Enter로도 같은 동작을 실행할 수 있습니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
50.00%
04
키보드로 이동하는 탭 만들기
5
## 이번 단계에서 배울 내용 탭은 하나의 패널만 보여 주며, 좌우 방향키로 탭 사이의 포커스를 이동합니다. 선택된 탭, 포커스 가능한 탭, 표시되는 패널이 같은 상태를 나타내야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <div role="tablist"> <button role="tab" aria-selected="true">개요</button> <button role="tab" aria-selected="false" tabindex="-1">진도</button> </div> ``` ## 해야 할 일 개요와 진도 탭을 클릭하거나 방향키로 전환할 수 있도록 완성하세요. ## 완성 조건 - 항상 탭 하나만 선택됩니다. - 좌우 방향키로 포커스와 선택 상태가 이동합니다. - 선택된 탭에 연결된 패널만 표시됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
05
액션 메뉴 버튼 만들기
5
## 이번 단계에서 배울 내용 액션 메뉴는 값을 선택하는 폼 컨트롤이 아니라 여러 명령을 제공하는 메뉴입니다. 메뉴를 열면 첫 항목으로 포커스를 옮기고, Escape로 닫으면 실행 버튼으로 돌아가야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <button aria-haspopup="menu" aria-expanded="false">작업</button> <div role="menu"><button role="menuitem">복제</button></div> ``` ## 해야 할 일 작업 버튼으로 메뉴를 열고 방향키로 항목을 이동하며 Escape로 닫을 수 있게 하세요. ## 완성 조건 - 메뉴를 열면 첫 번째 메뉴 항목이 포커스를 받습니다. - ArrowDown과 ArrowUp으로 메뉴 항목을 이동합니다. - Escape로 닫으면 작업 버튼으로 포커스가 돌아갑니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
06
자동완성 Combobox 만들기
5
## 이번 단계에서 배울 내용 Combobox는 입력창과 추천 목록을 연결합니다. 사용자는 입력으로 결과를 좁히고, 방향키로 후보를 이동한 뒤 Enter로 선택할 수 있어야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <input role="combobox" aria-autocomplete="list" aria-controls="language-list" aria-expanded="false"> ``` ## 해야 할 일 언어 검색창에 입력하면 추천 목록을 필터링하고 키보드로 항목을 선택할 수 있게 하세요. ## 완성 조건 - 입력값에 맞는 언어만 추천 목록에 표시됩니다. - ArrowDown으로 첫 추천 항목에 포커스를 옮길 수 있습니다. - Enter로 선택하면 입력값이 바뀌고 추천 목록이 닫힙니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
07
포커스를 관리하는 모달 만들기
5
## 이번 단계에서 배울 내용 모달이 열리면 배경 대신 모달 내부에서 작업을 시작해야 합니다. 닫힌 뒤에는 모달을 연 요소로 포커스가 돌아가야 사용자가 위치를 잃지 않습니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <dialog aria-labelledby="dialog-title"> <h2 id="dialog-title">삭제 확인</h2> <button type="button">취소</button> </dialog> ``` ## 해야 할 일 삭제 확인 모달을 열고 취소 버튼에 포커스를 둔 뒤 Escape나 취소 버튼으로 닫히게 하세요. ## 완성 조건 - 열기 버튼을 누르면 모달이 표시되고 취소 버튼이 포커스를 받습니다. - Escape와 취소 버튼으로 모달을 닫을 수 있습니다. - 닫은 뒤 삭제 버튼으로 포커스가 돌아갑니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
3
50.00%
08
마우스와 키보드를 지원하는 Tooltip 만들기
5
## 이번 단계에서 배울 내용 Tooltip은 짧은 보조 설명이며 클릭해야 하는 콘텐츠를 넣지 않습니다. 마우스를 올렸을 때뿐 아니라 키보드 포커스에서도 나타나야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <button aria-describedby="shortcut-tip">저장</button> <div id="shortcut-tip" role="tooltip" hidden>단축키 Ctrl+S</div> ``` ## 해야 할 일 저장 버튼의 Tooltip을 hover와 focus에서 표시하고, blur와 Escape에서 숨기세요. ## 완성 조건 - 버튼은 Tooltip과 aria-describedby로 연결됩니다. - hover 또는 focus에서 Tooltip이 표시됩니다. - blur 또는 Escape에서 Tooltip이 숨겨집니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
09
현재 위치를 알려 주는 캐러셀 만들기
5
## 이번 단계에서 배울 내용 캐러셀은 여러 항목 중 하나를 보여 주는 컴포넌트입니다. 현재 슬라이드와 전체 개수를 알려 주고, 이전·다음 버튼의 경계 동작을 명확히 해야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <section aria-roledescription="carousel"> <p aria-live="polite">1 / 3</p> <button type="button">다음</button> </section> ``` ## 해야 할 일 세 개의 학습 카드 사이를 이전·다음 버튼으로 이동하고 현재 위치를 표시하세요. ## 완성 조건 - 한 번에 슬라이드 하나만 표시됩니다. - 현재 위치가 1 / 3 형식으로 갱신됩니다. - 첫 슬라이드에서 이전, 마지막에서 다음 버튼은 비활성화됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
10
반응형 내비게이션 메뉴 만들기
5
## 이번 단계에서 배울 내용 작은 화면에서는 내비게이션 링크를 메뉴 버튼으로 제어할 수 있습니다. 화면 크기가 달라져도 링크 구조와 키보드 접근이 유지되어야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <button aria-expanded="false" aria-controls="site-nav">메뉴</button> <nav id="site-nav" hidden>...</nav> ``` ## 해야 할 일 모바일 메뉴 버튼으로 내비게이션을 열고 닫으며 Escape로 닫을 수 있게 하세요. ## 완성 조건 - 메뉴 버튼과 내비게이션이 aria-controls로 연결됩니다. - 버튼을 누르면 메뉴와 aria-expanded가 함께 변경됩니다. - Escape로 닫으면 메뉴 버튼이 포커스를 받습니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
1
33.33%
11
검색 가능한 강의 목록 만들기
5
## 이번 단계에서 배울 내용 검색 UI는 입력값을 정규화하고 일치하는 항목만 보여 줍니다. 결과 개수와 빈 결과를 함께 제공하면 사용자가 현재 상태를 이해하기 쉽습니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html const query = input.value.trim().toLowerCase(); const matches = items.filter((item) => item.name.toLowerCase().includes(query)); ``` ## 해야 할 일 강의 목록을 대소문자와 앞뒤 공백에 관계없이 검색하고 결과 수와 빈 상태를 표시하세요. ## 완성 조건 - 검색어가 포함된 강의만 표시됩니다. - 표시된 결과 개수가 입력할 때마다 갱신됩니다. - 결과가 없으면 빈 결과 안내가 표시됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
12
정렬과 필터를 지원하는 표 만들기
5
## 이번 단계에서 배울 내용 데이터 표는 원본 데이터를 기준으로 필터한 뒤 정렬하고 다시 렌더링합니다. 화면에 보이는 순서와 정렬 버튼의 상태를 함께 갱신해야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html const visible = rows .filter((row) => row.status === selectedStatus) .sort((a, b) => a.score - b.score); ``` ## 해야 할 일 학습자 표를 상태로 필터하고 점수 버튼으로 오름차순·내림차순 정렬하세요. ## 완성 조건 - 상태 선택에 맞는 행만 표시됩니다. - 점수 버튼을 누를 때마다 정렬 방향이 전환됩니다. - 정렬 방향이 aria-sort로 표시됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
2
66.67%
13
목록 페이지네이션 만들기
5
## 이번 단계에서 배울 내용 클라이언트 페이지네이션은 전체 배열에서 현재 페이지에 해당하는 구간만 잘라 보여 줍니다. 첫 페이지와 마지막 페이지에서는 이동할 수 없는 버튼을 비활성화합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html const start = (page - 1) * pageSize; const pageItems = items.slice(start, start + pageSize); ``` ## 해야 할 일 다섯 개 강의를 두 개씩 나누어 표시하고 이전·다음 버튼과 현재 페이지를 갱신하세요. ## 완성 조건 - 한 페이지에는 최대 두 개 항목이 표시됩니다. - 현재 페이지와 전체 페이지가 표시됩니다. - 첫 페이지의 이전 버튼과 마지막 페이지의 다음 버튼이 비활성화됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
1
50.00%
14
오류를 설명하는 가입 폼 만들기
5
## 이번 단계에서 배울 내용 좋은 폼 검증은 단순히 제출을 막는 데서 끝나지 않습니다. 어떤 필드가 왜 잘못되었는지 설명하고, 사용자가 오류를 수정하면 안내도 갱신해야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <input id="email" type="email" required aria-describedby="email-error"> <p id="email-error" aria-live="polite"></p> ``` ## 해야 할 일 이름과 이메일을 검사해 필드별 오류를 표시하고 유효할 때만 가입 완료 메시지를 보여 주세요. ## 완성 조건 - 빈 이름과 잘못된 이메일에 각각 명확한 오류를 표시합니다. - 오류가 있는 입력은 aria-invalid=true가 됩니다. - 모든 값이 유효하면 가입 완료 메시지가 표시됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
1
50.00%
15
입력값을 유지하는 여러 단계 폼 만들기
5
## 이번 단계에서 배울 내용 긴 폼은 논리적인 단계로 나누면 이해하기 쉬워집니다. 현재 단계를 알려 주고, 각 단계를 검증하며, 이전 단계로 돌아가도 입력값을 유지해야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html <p aria-live="polite">1 / 2 단계</p> <section data-step="1">...</section> ``` ## 해야 할 일 이름 입력과 관심 분야 선택을 두 단계로 나누고 마지막에 입력 내용을 확인해 제출하세요. ## 완성 조건 - 이름이 비어 있으면 다음 단계로 이동하지 않습니다. - 이전 단계로 돌아와도 입력한 이름이 유지됩니다. - 마지막 제출 후 이름과 관심 분야가 요약됩니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
1
50.00%
16
학습 관리 대시보드 완성하기
5
## 이번 단계에서 배울 내용 실전 화면은 검색, 필터, 상태 변경, 모달 같은 여러 컴포넌트가 하나의 데이터 상태를 공유합니다. 각 기능을 따로 구현한 뒤 하나의 렌더링 흐름으로 연결해야 합니다. ### 먼저 예시를 살펴보세요 아래 코드는 문법을 이해하기 위한 작은 예시이며, 문제의 정답과는 다릅니다. ```html function render() { const visible = filterCourses(courses, state); renderCards(visible); renderSummary(visible); } ``` ## 해야 할 일 강의를 검색·상태 필터링하고 카드에서 완료 처리하며 상세 모달을 열 수 있는 대시보드를 완성하세요. ## 완성 조건 - 검색어와 상태 필터가 동시에 적용됩니다. - 완료 버튼을 누르면 카드 상태와 완료 개수가 함께 바뀝니다. - 상세 버튼으로 모달을 열고 닫은 뒤 포커스가 복귀합니다. ## 작업 방법 1. 에디터에서 `script.js`을 엽니다. 2. `TODO` 주석 주변의 코드를 한 단계씩 수정합니다. 3. 미리보기에서 화면과 동작을 직접 확인합니다. 4. 완성 조건을 다시 읽고 제출합니다.
1
50.00%