새로운 개인 웹사이트 템플릿 + Heroicons v2.0, Headless UI v1.7, 그리고 더 많은 것들
- Date
- Adam Wathan
지난주는 여러 프로젝트를 마무리하느라 바빴지만, 이제 모든 것이 마무리되어 업데이트를 공유하기 좋은 시기라고 생각합니다.
지난 포스트 이후로 226개의 GitHub 이슈와 풀 리퀘스트를 처리했고, 조직 전체에서 열려 있는 이슈/PR이 50개 미만으로 줄어 처음으로 이정도로 줄었습니다. 그러니 이제 버그 찾는 건 그만하고, 잠시 Tailwind CSS로 아름다운 것들을 디자인하고 만들고 싶습니다.
아름다운 것들에 대해 말하자면, 지난 몇 주 동안 출시된 것들을 소개합니다!
스포트라이트: 여러분의 새로운 개인 웹사이트
며칠 전, 우리는 Tailwind UI를 위해 디자인한 멋진 새로운 개인 웹사이트 템플릿인 스포트라이트를 출시했습니다.
다른 템플릿들과 마찬가지로, 이 템플릿은 Next.js로 구축되었으며, 이번에는 블로그 섹션과 같은 마크다운 기반 콘텐츠를 위해 MDX를 사용했습니다.
이 템플릿을 디자인하는 것은 꽤 재미있고 흥미로운 도전이었습니다. 우리는 정말 아름답고 영감을 주는 무언가를 만들고 싶었지만, 동시에 거의 모든 사람에게 적합할 만큼 중립적인 디자인을 원했습니다. 결국 회전된 이미지, 링크에 약간의 색상, 그리고 상단 네비게이션과 같은 곳에서 그림자와 레이어링으로 인한 미묘한 깊이감을 더한 미니멀리즘 디자인으로 결정했습니다.
항상 그렇듯이, 라이브 미리보기를 확인해 보시길 추천합니다. 특히 홈페이지에서 스크롤할 때 아바타와 네비게이션이 어떻게 작동하는지 주의 깊게 살펴보세요. 실제 사이트에서 경험하면 정말 _*완벽하다*_는 느낌을 받을 수 있습니다.
우리는 이 사이트를 우리 자신의 개인 사이트를 구조화하는 방식으로 설계하려고 노력했습니다. 그래서 전용 블로그, 여러분이 작업한 프로젝트를 나열할 수 있는 페이지, 여러분이 진행한 컨퍼런스 발표와 같은 것들을 링크할 수 있는 영역, 그리고 여러분이 좋아하는 도구와 장비를 나열할 수 있는 “사용하는 도구” 페이지를 포함했습니다.
만약 여러분이 Tailwind UI 올액세스 라이선스를 가지고 있다면, 이미 이 템플릿에 접근할 수 있습니다! 아직 라이선스가 없다면, Tailwind CSS, Headless UI, Heroicons와 같은 오픈소스 프로젝트를 지원하는 가장 좋은 방법이니 고려해 보세요.
Heroicons v2.0
작년에 우리는 Heroicons v1.0을 출시했습니다. 그리고 지난 주에 Heroicons v2.0을 출시했는데, 이는 스티브가 약 1년 동안 작업한 완전히 새로운 아이콘 세트입니다.
이번 버전에는 세 가지 독특한 스타일로 그려진 280개의 아이콘이 포함되어 있습니다:
- Outline — 1.5px 두께의 선으로 그려진 아이콘으로, 24px 뷰 박스 안에 그려졌습니다.
- Solid — 채워진 형태의 솔리드 아이콘으로, 24px 뷰 박스 안에 그려졌습니다.
- Mini — 채워진 형태의 솔리드 아이콘으로, 20px 뷰 박스 안에 그려졌습니다.
v1과 가장 큰 차이점은 아웃라인 세트가 더 얇은 선을 사용한다는 점입니다. 이는 최근 트렌드에 맞게 더 현대적이고 세련된 느낌을 주며, 시각적으로도 조금 더 유쾌한 스타일을 가지고 있습니다.
이 아이콘 세트는 이름에 “v2”가 붙어 있지만, OpenSSL 2보다는 터미네이터 2에 더 가깝다고 생각하는 것이 좋습니다. 우리는 이 아이콘 세트가 우리의 최고 작품이라고 생각하지만, 이는 기존 아이콘 세트의 단순한 업그레이드가 아니라 완전히 새로운 아이콘 세트입니다. 실제 애플리케이션 의존성처럼 기존 프로젝트를 업그레이드해야 한다는 압박을 느낄 필요는 없지만, 마이그레이션을 원한다면 릴리스 노트를 확인하여 필요한 모든 정보를 얻을 수 있습니다.
새로운 아이콘 세트를 탐색하려면, 새로 출시된 완전히 리디자인된 Heroicons 웹사이트를 방문해 보세요.
Headless UI v1.7
이번 주 초, 우리는 스타일이 적용되지 않은 UI 컴포넌트를 제공하는 React와 Vue 라이브러리인 Headless UI의 새 버전을 출시했습니다.
Headless UI v1.7에는 평소처럼 여러 버그 수정과 개선 사항이 포함되어 있으며, 특히 유용한 새로운 기능들도 추가되었습니다!
객체 비교를 제어하기 위한 “by” prop 추가
Listbox
, Combobox
, RadioGroup
컴포넌트에 새로운 by
prop을 추가했습니다. 이 prop은 폼 값으로 객체를 바인딩할 때 훨씬 간편하게 사용할 수 있도록 도와줍니다.
by
prop을 사용하면 객체의 어떤 속성을 비교에 사용할지 지정할 수 있습니다. 이렇게 하면 바인딩된 값과 잠재적 값 목록에 있는 해당 값이 정확히 동일한 객체 인스턴스일 필요가 없어집니다:
import { Listbox } from '@headlessui/react'
const departments = [
{ id: 1, name: 'Marketing', contact: 'Durward Reynolds' },
{ id: 2, name: 'HR', contact: 'Kenton Towne' },
{ id: 3, name: 'Sales', contact: 'Therese Wunsch' },
{ id: 4, name: 'Finance', contact: 'Benedict Kessler' },
{ id: 5, name: 'Customer service', contact: 'Katelyn Rohan' },
]
function DepartmentPicker({ selectedDepartment, onChange }) {
return (
<Listbox value={selectedDepartment} by="id" onChange={onChange}>
<Listbox.Button>{selectedDepartment.name}</Listbox.Button>
<Listbox.Options>
{departments.map((department) => (
<Listbox.Option key={department.id} value={department}>
{department.name}
</Listbox.Option>
))}
</Listbox.Options>
</Listbox>
)
}
이 기능을 사용하면 값이 컴포넌트 외부에서 오는 경우에도 훨씬 쉽게 처리할 수 있으며, id
와 같은 값만 바인딩한 후 필요할 때마다 전체 객체를 찾기 위해 여러 번 조회해야 하는 번거로움을 덜어줍니다.
더 자세한 내용은 각 컴포넌트의 “객체를 값으로 바인딩하기” 문서를 참고하세요.
폼 컨트롤을 비제어 컴포넌트로 사용하기
Listbox
, Combobox
, RadioGroup
컴포넌트는 이제 value
대신 defaultValue
를 선택적으로 전달할 수 있게 되어, 비제어 컴포넌트로 사용할 수 있습니다.
import { Listbox } from '@headlessui/react'
const people = [
{ id: 1, name: 'Durward Reynolds' },
{ id: 2, name: 'Kenton Towne' },
{ id: 3, name: 'Therese Wunsch' },
{ id: 4, name: 'Benedict Kessler' },
{ id: 5, name: 'Katelyn Rohan' },
]
function Example() {
return (
<form action="/projects/1/assignee" method="post">
<Listbox name="assignee" defaultValue={people[0]}>
<Listbox.Button>{({ value }) => value.name}</Listbox.Button>
<Listbox.Options>
{people.map((person) => (
<Listbox.Option key={person.id} value={person}>
{person.name}
</Listbox.Option>
))}
</Listbox.Options>
</Listbox>
<button>Submit</button>
</form>
)
}
이 기능은 전통적인 HTML 폼이나 FormData
를 사용하여 상태를 수집하는 폼 API를 사용할 때 코드를 단순화할 수 있습니다.
각 컴포넌트의 “비제어 컴포넌트로 사용하기” 문서에서 더 많은 예제를 확인할 수 있습니다.
CSS만으로 상태 스타일링을 위한 데이터 속성
기존에는 Headless UI 컴포넌트의 다양한 상태를 스타일링하기 위해 렌더링 prop을 통해 전달된 인자를 검사하고, 적절한 클래스나 콘텐츠를 조건부로 렌더링해야 했습니다. 이는 단순히 배경색을 조정하거나 CSS만으로 변경하려는 경우에도 상당히 많은 보일러플레이트 코드가 필요했습니다.
Headless UI v1.7에서는 렌더링된 HTML에 data-headlessui-state
속성을 추가하여 현재 상태에 대한 정보를 포함시켰습니다. 이제 CSS만으로도 해당 상태를 타겟팅할 수 있습니다.
또한 새로운 @headlessui/tailwindcss 플러그인을 출시했습니다. 이 플러그인은 이러한 상태에 대한 변형을 제공하므로 Tailwind CSS 클래스만으로도 쉽게 스타일링할 수 있습니다:
<Listbox.Option
key={person.id}
value={person}
className="ui-active:bg-blue-500 ui-active:text-white ui-not-active:bg-white ui-not-active:text-black"
>
<CheckIcon className="hidden ui-selected:block" />
{person.name}
</Listbox.Option>
더 자세한 내용은 데이터 속성을 사용한 스타일링에 대한 새로운 문서를 확인해 보세요.
Tailwind Play에서의 Insiders 지원
많은 사람들이 모르고 있지만, 우리는 Tailwind CSS의 insiders
빌드를 npm에 배포합니다. 이 빌드는 저장소에 새로운 커밋이 올라올 때마다 자동으로 빌드되고 배포됩니다. 이를 통해 정식 릴리스 전에 새로운 기능과 수정 사항을 쉽게 테스트할 수 있습니다.
이제 Tailwind Play에서도 insiders 빌드에 접근할 수 있게 되었습니다. 프로젝트를 설정하지 않고도 최신 기능을 사용해 볼 수 있습니다:
Play에서는 최신 insiders 빌드만 유지합니다. 따라서 insiders 빌드를 사용하여 데모를 만들 경우, 다음 insiders 빌드에서 사용 중인 미출시 기능이 변경되면 문제가 발생할 수 있습니다. 중요한 작업을 여기에 올려서는 안 됩니다. 프로답게 행동합시다.
Tailwind CSS + Phoenix v1.7
얼마 전 Phoenix 팀과 이야기를 나누기 시작했습니다. 그들은 향후 릴리스에서 Tailwind CSS를 기본으로 제공하고 싶어 했습니다. 저는 이 아이디어가 매우 흥미로웠고, 기본 제공되는 경험을 정말 멋지게 만들기 위해 그들과 협력하고 싶었습니다.
우리는 새로운 스플래시 스크린과 생성기 시스템에 필요한 모든 기본 구조를 설계했고, 이는 Phoenix v1.7의 일부로 제공될 예정입니다.
Phoenix의 창시자인 Chris McCord는 지난주에 멋진 발표를 통해 Tailwind CSS와 관련된 모든 내용을 소개했습니다. 더 알고 싶다면 한번 시청해 보세요.
이것이 지난 몇 주 동안 우리가 작업한 가장 멋진 내용들입니다!
다음 달에는 우리가 디자인한 새로운 Tailwind UI 컴포넌트를 만들고, Tailwind CSS의 새로운 기능 아이디어를 탐구하며, Tailwind + Next.js를 기반으로 한 애플리케이션 스타터 키트 템플릿을 만드는 R&D를 시작할 예정입니다. 잘 해낸다면 꽤 멋진 결과물이 나올 것 같습니다.
다음 업데이트에서 뵙겠습니다!