라이브러리 선택
결정을 내리기 전에 product-ui §1(취향 저널 및 선례)과 §5(어느 스킬이 무엇을 담당하는지)를 적용하세요. 라이브러리 이름을 지정하는 저널 규칙이 우선합니다.
작업 없이 호출되면 한 줄로 작업을 요청하고 중단하세요.
결정 순서
위에서 아래로 진행하세요. 작업을 완전히 해결하는 첫 번째 단계에서 멈추세요.
- 이미 설치된 것은 무엇인가?
package.json을 읽으세요. 나열된 라이브러리나 경쟁 라이브러리가 이미 작업을 수행한다면 그것을 사용하세요. 더 나은 선택이 있다면 한 줄로 표시하고, 요청 없이 의존성을 교체하지 마세요. 이유: 동일한 작업을 위한 두 번째 라이브러리는 번들을 두 배로 늘리고 규칙도 두 배로 만듭니다. - 플랫폼이 완전히 해결하는가? 아래 표를 확인하세요. 이유: 플랫폼은 번들 비용, 업그레이드 경로 및 유지보수 중단 위험이 없습니다.
- 목록에 항목이 있는가? references/catalogue.md를 열고, 카테고리를 찾은 후 Default로 표시된 항목을 선택하세요. 메뉴가 아닌 하나의 라이브러리를 추천하세요.
- 그 항목이 유지보수되고 있는가? 상태 열을 확인하세요. Unmaintained라고 표시되면 절대 추천하지 말고, 항목에 명시된 대체 라이브러리를 사용하세요.
- 아무것도 맞지 않는가? "이 작업은 목록에 없습니다"라고 말한 후, 자신의 지식에서 선택하고 아래 검증을 실행하세요. 이유: 확인되지 않은 패키지는 일반적으로 유지보수되지 않는 코드가 유입되는 경로입니다.
"완전히 해결"이란 키보드, 포커스 및 스크린 리더 동작을 포함한 작업의 모든 요구 사항이 충족됨을 의미합니다. 하나의 요구 사항이라도 실패하면 3단계로 이동하세요.
플랫폼 우선
| 작업 | 플랫폼 답변 | 라이브러리로 전환해야 하는 경우 |
|---|---|---|
| 모달 | showModal()이 포함된 <dialog> | 지원하는 브라우저에서 애니메이트된 종료가 있는 중첩 대화상자가 필요하거나, 비모달 포커스 관리가 필요한 경우 |
| 팝오버, 드롭다운 패널, 툴팁 스타일 카드 | popover 속성, 지원되는 경우 CSS 앵커 포지셔닝 | 모든 곳에서 충돌 플립이 필요하거나, 로빙 포커스 메뉴가 필요한 경우 |
| 아코디언, 공개/비공개 | <details name> | 제어된 상태나 interpolate-size를 넘어서는 애니메이션 높이가 필요한 경우 |
| 토글 없는 다크 모드 | prefers-color-scheme, color-scheme, light-dark() | 사용자가 수동으로 테마를 선택하고 지속되어야 하는 경우 |
| 날짜, 시간, 월 입력 | <input type="date"> 및 관련 요소 | 범위, 사용자 정의 캘린더 또는 일관된 모양이 필요한 경우 |
| 숫자 서식, 상대 시간, 복수형, 목록 | Intl.NumberFormat, RelativeTimeFormat, PluralRules, ListFormat | 절대 안 됨. 항상 Intl 사용 |
| 일회성 코드, 단일 필드 | <input autocomplete="one-time-code" inputmode="numeric"> | 숫자당 하나의 상자가 필요한 경우 |
| 진입, 종료 및 레이아웃 모션 | CSS 전환, @starting-style, WAAPI, View Transitions | 스프링, 제스처 또는 중단 가능한 레이아웃 애니메이션이 필요한 경우 |
| 양식 유효성 검사 | 제약 조건 검증 (required, pattern, setCustomValidity) | 필드 간 또는 비동기 규칙, 또는 타입이 지정된 스키마가 필요한 경우 |
| 적은 옵션의 선택 | <select> | 검색, 다중 선택 또는 풍부한 행이 필요한 경우 |
| 고정 헤더, 스크롤 스냅, 느린 목록 | CSS position: sticky, scroll-snap, content-visibility: auto | 목록에 1,000개 이상의 행이 있는 경우 |
짝
| 잘못된 방법 | 올바른 방법 | 이유 |
|---|---|---|
수동으로 작성된 포커스 트랩이 있는 <div> 모달 | <dialog> 및 showModal() | 포커스 트랩, Esc 및 배경 비활성화가 무료로 제공됨 |
npm i react-beautiful-dnd | @dnd-kit/react | 첫 번째는 더 이상 사용되지 않고 유지보수되지 않음 |
서랍을 위해 npm i vaul | Base UI Drawer 또는 시트 스타일의 <dialog> | vaul의 자체 README에 유지보수되지 않는다고 명시됨 |
| 모달 라이브러리로 만든 토스트 | Base UI Toast | 스택, 호버 시 일시 중지 및 스와이프가 이미 해결됨 |
setInterval로 숫자 세기 | NumberFlow | 숫자가 올바른 레이아웃과 축소된 모션으로 굴러감 |
한 번에 5,000개의 <tr> 렌더링 | TanStack Table 아래의 TanStack Virtual 또는 목록용 Virtuoso | 렌더링 비용이 행 수에 따라 증가하며 뷰포트에 비례하지 않음 |
new Intl.NumberFormat을 통화 패키지로 대체 | Intl.NumberFormat | 로케일 규칙이 브라우저에 내장됨 |
추천 전 확인
목록에 있든 없든 모든 패키지에 대해 다음을 실행하세요. 카탈로그 상태는 세션보다 오래되었을 수 있습니다.
npm view <pkg> time.modified license version
- 유지보수 중: 마지막 게시일이 12개월 이내, 또는 게시된 릴리스가 포함된 6개월 이내의 저장소 푸시.
- 느림: 기능이 완료됨, 12-24개월 동안 게시되지 않음, 저장소에서 여전히 이슈에 응답 중. 사용 가능합니다. 느리다고 말하세요.
- 유지보수되지 않음: 보관됨, 그렇게 명시된 README, 또는 24개월 이상 게시되지 않았고 공개된 손상이 있음. 절대 추천하지 마세요.
- 라이선스를 읽으세요. MIT, ISC, BSD 또는 Apache-2.0이 아닌 경우 보고하세요(MPL-2.0 및 AGPL은 메모가 필요함).
- 피어 의존성을 프로젝트의 React 버전과 확인하세요.
답변 형식
메뉴 없는 하나의 블록:
Base UI Toast for toasts. 스택, 호버 시 일시 중지 및 스와이프 가능. 작업이 필요한 항목에는 사용하지 마세요. 그런 항목은 화면에 유지됩니다. MIT, 유지보수 중.
npm i @base-ui/react.
항상 다음을 제공하세요: 용도, 사용하지 말아야 할 경우, 라이선스, 확인한 날짜의 상태.
마치기 전에
package.json을 읽었으며 선택한 라이브러리가 설치된 라이브러리와 중복되지 않습니다.- 플랫폼 답변을 확인했으며, 건너뛴 경우 그 이유가 한 절입니다.
- 선택한 라이브러리에 대해
npm view를 실행했으며 답변의 상태는 카탈로그의 것이 아닌 오늘의 것입니다. - Unmaintained로 표시된 항목은 추천되지 않습니다.