Headless UI v2.1: 간소화된 트랜지션 API와 개선된 다중 다이얼로그 지원

Adam Wathan
Jonathan Reinink
Headless UI v2.1

React용 Headless UI v2.1을 출시했습니다. 이번 버전에서는 트랜지션 API가 크게 간소화되었고, 여러 다이얼로그를 형제 엘리먼트로 렌더링하는 기능이 추가되었습니다.


간소화된 트랜지션 API

v2.1에서는 트랜지션을 적용할 수 있는 모든 내장 컴포넌트에 새로운 transition prop을 추가하고, 각 트랜지션 단계에 대한 데이터 속성(data attributes)을 도입했습니다. 이제 타겟 엘리먼트에 클래스를 추가하는 것만으로도 트랜지션 스타일을 쉽게 적용할 수 있습니다:

import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";function Example() {  return (    <Menu>      <MenuButton>My account</MenuButton>      <MenuItems        transition        className={`          transition ease-out          data-[closed]:scale-95 data-[closed]:opacity-0          data-[enter]:duration-200 data-[leave]:duration-300        `}      >        {/* Menu items… */}      </MenuItems>    </Menu>  );}

트랜지션의 각 단계를 타겟팅하기 위해 사용할 수 있는 네 가지 데이터 속성이 있습니다:

  • data-closed: 엘리먼트가 진입할 때와 떠날 때 적용될 스타일
  • data-enter: 엘리먼트가 진입하는 동안 적용될 스타일 (예: 지속 시간이나 이징 곡선)
  • data-leave: 엘리먼트가 떠나는 동안 적용될 스타일 (예: 지속 시간이나 이징 곡선)
  • data-transition: 엘리먼트가 진입하거나 떠날 때 적용될 스타일 (두 단계 간 공유할 값에 유용)

이러한 속성을 조합하여 진입과 떠날 때 서로 다른 closed 스타일을 사용할 수도 있습니다. 예를 들어, 이 다이얼로그는 왼쪽에서 슬라이드되지만 오른쪽으로 슬라이드됩니다:

import { Dialog } from "@headlessui/react";import { useState } from "react";function Example() {  let [isOpen, setIsOpen] = useState(false);  return (    <>      <button onClick={() => setIsOpen(true)}>Open dialog</button>      <Dialog        open={isOpen}        onClose={() => setIsOpen(false)}        transition        className={`          transition duration-300 ease-out          data-[closed]:opacity-0          data-[closed]:data-[enter]:-translate-x-8          data-[closed]:data-[leave]:translate-x-8        `}      >        {/* Dialog content… */}      </Dialog>    </>  );}

일반 HTML 엘리먼트나 다른 컴포넌트에 트랜지션을 적용하려면, 새로운 데이터 속성 API와 함께 <Transition> 컴포넌트를 사용할 수 있습니다:

import { Transition } from "@headlessui/react";import { useState } from "react";function Example() {  const [isShowing, setIsShowing] = useState(false);  return (    <>      <button onClick={() => setIsShowing((isShowing) => !isShowing)}>Toggle</button>      <Transition show={isShowing}>        <div className="transition duration-300 data-[closed]:opacity-0">I will fade in and out</div>      </Transition>    </>  );}

이 새로운 트랜지션 API를 사용하도록 Tailwind UI를 모두 업데이트했으며, 코드가 훨씬 간결하고 가벼워졌습니다. Modal Dialog, Dropdown, Slide-over, Flyout Menu, 또는 Select Menu 컴포넌트에서 더 많은 예제를 확인할 수 있습니다.

기존 API는 하위 호환성을 위해 계속 작동하지만, 앞으로는 이 새로운 접근 방식을 권장할 예정입니다.

업데이트된 Transition 컴포넌트 문서에서 더 많은 정보를 확인하세요.


여러 다이얼로그를 형제로 렌더링하기

Headless UI v2.1에서는 이제 여러 다이얼로그를 서로 중첩하지 않고 동시에 렌더링할 수 있습니다.

이 기능은 애플리케이션의 두 개의 관련 없는 부분이 동시에 다이얼로그를 표시해야 할 때 매우 유용합니다. 예를 들어, 이미 어떤 확인 다이얼로그가 열려 있는 상태에서 다른 부분에서 네트워크 연결이 끊겼거나 세션이 만료되었다는 것을 감지하고 새로운 다이얼로그를 표시해야 하는 경우가 있습니다.

최근 작업 중인 애플리케이션 UI 키트인 Catalyst를 사용한 예시는 다음과 같습니다:

각 다이얼로그가 열린 순서를 추적하며, 가장 마지막에 열린 다이얼로그가 ESC 키를 누르거나 다이얼로그 외부를 클릭했을 때 닫힙니다.


이 기능을 사용하려면 최신 버전의 Headless UI를 설치하세요:

npm i @headlessui/react@latest

문제가 발생하면 GitHub에서 알려주세요!

모든 업데이트를 직접 받아 볼 수 있습니다.
뉴스레터에 가입하세요.