Catalyst 소개: React를 위한 모던 UI 키트
- Date
- Adam Wathan
오늘은 바로 그 날입니다. 여러분의 휴가 코딩 세션에 딱 맞춰 Catalyst의 첫 개발 프리뷰를 공개했습니다.
Catalyst는 완전한 컴포넌트화와 기본 기능이 포함된 애플리케이션 UI 키트입니다. 실제 애플리케이션에서 사용하는 방식과 동일하게, 서로를 기반으로 구축된 신중하게 설계된 API를 가진 진짜 React 컴포넌트로 구성되어 있습니다.
라이브 데모를 확인하고, 문서를 읽어보세요. Tailwind UI All-Access 고객이라면 다운로드하여 새로운 프로젝트에서 바로 사용해 볼 수 있습니다.
Catalyst는 현재 개발 프리뷰 단계이며, 더 많은 기능이 추가될 예정입니다. 하지만 우리는 여러분이 바로 사용해 볼 수 있도록 오늘 공개했습니다. 새로운 컴포넌트를 계속 추가하고, 더 나은 경험을 제공할 방법을 찾아 나갈 것입니다.
여러분의 컴포넌트, 우리의 것이 아닙니다
Catalyst를 통해 우리는 내일의 Stripe나 Linear가 자신의 제품을 만들 때 사용하고 싶어할 UI 키트를 만들고자 했습니다. 디자인에 집착하는 팀들은 자신만의 UI 컴포넌트를 소유하고 싶어하며, 기성 라이브러리를 선택하지 않을 것입니다.
따라서 Catalyst는 설치하는 의존성이 아닙니다. 대신 소스 코드를 다운로드하고 컴포넌트를 여러분의 프로젝트에 복사하여 여러분만의 컴포넌트 시스템의 시작점으로 삼을 수 있습니다:
버튼의 테두리 반경을 변경하고 싶나요? 그냥 button.tsx
를 열고 클래스를 변경하면 됩니다. GitHub 이슈를 열어 새로운 설정 옵션을 추가해 달라고 설득할 필요가 없습니다.
Catalyst는 “사라지는 UI 키트”입니다. 설치한 지 6개월이 지나면, 원래 컴포넌트를 여러분이 직접 만들지 않았다는 사실을 거의 잊어버릴 정도로 자연스럽게 사용할 수 있습니다.
디자인은 디테일에 있다
이런 프로젝트에서 시각적 스타일을 제대로 잡는 것은 어려운 일입니다. 우리는 몇 가지 목표를 가지고 시작했습니다:
- 경쟁력 있게 — 오늘날 웹에서 가장 멋진 인터페이스들과 어깨를 나란히 할 수 있는 디자인을 만들고 싶었습니다.
- 시간을 초월하게 — 특정 트렌드에 너무 의존해서 6개월 후면 구식으로 보일 디자인을 만들고 싶지 않았습니다.
- 생산성 있게 — 우리가 디자인한 것이 Dribbble 샷에서만 멋져 보이는 것이 아니라 실제 사용자에게 빠르고 효율적으로 느껴져야 했습니다.
많은 노력과 균형을 맞추기 위한 많은 절충이 있었지만, 결국 우리가 도달한 결과에 정말 만족합니다:
경쟁력 있게 만들기 위해, 드롭다운 메뉴의 미묘한 배경 블러, 폼 컨트롤에서 그림자와 테두리가 서로 조화를 이루는 방식, 그리고 다이얼로그와 토글 스위치 같은 곳에서의 신중한 애니메이션 사용과 같은 많은 디테일에 투자했습니다.
시간을 초월하게 만들기 위해, 플랫 디자인과 스큐어모픽 디자인 사이의 적절한 균형을 맞추려고 노력했습니다. 트렌드가 어느 쪽으로든 조금 변하더라도 우리의 컴포넌트가 여전히 멋지게 보일 수 있도록 충분한 깊이감을 주었습니다.
또한 브라우저에서 영감을 받아, 곧 유행에 뒤처질 수 있는 디자인을 피하기 위해 중립적인 파란색 포커스 링을 사용했습니다.
생산성 있게 만들기 위해, 여전히 충분한 여백을 유지하면서도 화면에 많은 정보를 담을 수 있도록 UI를 충분히 조밀하게 만드는 데 신경 썼습니다.
또한 트랜지션과 애니메이션은 중요한 곳에만 제한적으로 사용했고, 그곳에서도 빠르게 유지하여 UI를 기다리는 느낌이 들지 않도록 했습니다.
Catalyst는 다크 모드를 완벽하게 지원합니다. Catalyst 컴포넌트로 만든 모든 것은 라이트 모드와 다크 모드 사이에서 자동으로 조정됩니다.
눈에 띄지 않지만, 다크 모드에서 최상의 모습을 보이기 위해 그림자를 조정하고, 외부 링을 내부 링으로 변경하여 조명 변화를 모방하는 등 수많은 작은 디테일을 변경해야 했습니다.
HTML을 모델로 삼다
우리는 컴포넌트 API를 설계하는 데 많은 시간을 투자했습니다. 유연성을 희생하지 않으면서도 쉽게 사용할 수 있도록 최대한 노력했습니다.
일반적으로 UI 라이브러리는 다음과 같은 API를 사용합니다:
function Example() {
return (
<TextField
name="product_name"
label="Product name"
description="Use the name you'd like people to see in their cart."
/>
)
}
하지만 모든 props가 하나의 컴포넌트에 몰려 있으면, <input>
엘리먼트 자체에만 클래스를 추가하는 것과 같은 작업이 어려워집니다.
이러한 문제로 인해 우리는 HTML과 유사한 API를 설계하게 되었습니다. 이 방식에서는 하나의 컴포넌트가 여러 엘리먼트를 렌더링하는 경우가 거의 없습니다.
Catalyst로 텍스트 필드를 만드는 방법은 다음과 같습니다:
import { Description, Field, Label } from '@/components/fieldset'
import { Input } from '@/components/input'
function Example() {
return (
<Field>
<Label>Product name</Label>
<Description>Use the name you'd like people to see in their cart.</Description>
<Input name="product_name" />
</Field>
)
}
이렇게 합성 가능한 구조를 유지하면, 다른 엘리먼트의 너비를 제한하지 않고도 입력 필드의 너비만 제한하는 것이 매우 쉬워집니다:
import { Description, Field, Label } from '@/components/fieldset'
import { Input } from '@/components/input'
function Example() {
return (
<Field>
<Label>Product name</Label>
<Description>Use the name you'd like people to see in their cart.</Description>
<Input name="product_name" />
<Input name="product_name" className="max-w-sm" />
</Field>
)
}
또한 설명을 입력 필드 위가 아니라 아래로 옮기는 것도 간단합니다:
import { Description, Field, Label } from '@/components/fieldset'
import { Input } from '@/components/input'
function Example() {
return (
<Field>
<Label>Product name</Label>
<Description>Use the name you'd like people to see in their cart.</Description>
<Input name="product_name" className="max-w-sm" />
<Description>Use the name you'd like people to see in their cart.</Description>
</Field>
)
}
이러한 API를 설계하는 데 많은 실험이 필요했습니다. 특히 레이아웃 스타일을 적절한 자식 엘리먼트에 추가하는 것과 같은 세부 사항을 고려하는 데 많은 노력이 들었습니다. 하지만 그만한 가치가 있었고, 이 컴포넌트들은 정말 사용하기 편리합니다.
차세대 Headless UI로 구동
2020년 여름에 Headless UI의 첫 번째 버전을 출시했지만, Tailwind CSS 작업에 집중하느라 마지막 주요 기능 업데이트 이후로 1년 이상이 지났습니다.
Catalyst는 Headless UI를 다시 손댈 수 있는 완벽한 기회였고, Catalyst 자체의 코드를 단순화하기 위해 프로젝트를 개선할 수 있는 다양한 방법을 빠르게 찾아냈습니다.
이제 Headless UI v2.0.0-alpha.1을 출시했으며, 여기에는 다음과 같은 새로운 기능들이 포함되어 있습니다:
- 내장 앵커 포지셔닝 — Floating UI를 사용하여
Menu
,Listbox
등의 컴포넌트가 트리거에 앵커링된 팝오버를 자동으로 위치시킬 수 있으며, 뷰포트 변경에 따라 적응합니다. - Headless 체크박스 컴포넌트 — 기존
RadioGroup
컴포넌트를 보완하기 위해 HeadlessCheckbox
컴포넌트를 추가했으며, 완전히 커스텀한 체크박스 컨트롤을 쉽게 만들 수 있습니다. - HTML 폼 컴포넌트 —
Input
,Select
,Textarea
,Label
,Description
,Fieldset
,Legend
컴포넌트를 추가했으며, 폼 필드를 연결하기 위해 필요한 ID 생성 및aria-*
속성 매핑을 모두 처리합니다. - 향상된 호버 및 포커스-가시성 감지 — React Aria 라이브러리의 훅을 사용하여, Headless UI는 이제 더 스마트한
data-hover
및data-focus
속성을 컨트롤에 추가하며, 이는 기본 의사 클래스보다 다양한 기기에서 더 일관된 동작을 보입니다. - Combobox 리스트 가상화 — Headless UI의 다음 버전은 이제 성능 문제 없이 거대한 Combobox 옵션 리스트를 처리할 수 있습니다.
이 외에도 데이트 피커, 툴팁 등 다양한 개선 사항이 예정되어 있습니다.
이러한 개선 사항은 현재 초기 알파 기간 동안 React 전용이지만, v2.0 출시 전에 Vue에도 모든 개선 사항을 적용할 계획입니다.
이에 대한 문서는 곧 출시될 예정이지만, 연휴 전에 Catalyst를 출시하고 싶어서 Headless UI 문서를 몇 일 늦게 출시하는 것도 마다하지 않았습니다.
직접 사용해 보세요
Catalyst는 모든 Tailwind UI All-Access 고객에게 무료로 제공되는 업데이트입니다. 여기서 다운로드하여 오늘 바로 첫 번째 릴리스를 사용해 볼 수 있습니다.
오늘 공개하는 모든 것을 완벽하게 만들기 위해 상상 이상의 노력이 들어갔지만, 여러분의 피드백과 개선점을 기대하고 있습니다. Catalyst로 무언가를 만들어 보고 의견을 알려주세요.
연말 휴가 동안 몇 주간 휴식을 취할 예정이지만, 새해가 되면 애플리케이션 레이아웃, 콤보박스, 커맨드 팔레트, 툴팁 등 새로운 컴포넌트 작업을 위해 Catalyst 개발에 다시 뛰어들 것입니다.