トランジション
CSSクラスを使用して、ネストされた子トランジションを含む、条件付きでレンダリングされた要素のトランジションスタイルを制御します。
はじめに、npm経由でHeadless UIをインストールします
npm install @headlessui/react
条件付きでレンダリングされた要素をトランジションするには、それをTransition
コンポーネントでラップし、show
プロップを使用して開いているか閉じているかを示します。
次に、ネイティブのCSSトランジションスタイルを使用してアニメーションを適用し、Transition
コンポーネントが公開するdata-closed
属性をターゲットにすることで、要素の閉じたスタイルを指定します。
import { Transition } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [open, setOpen] = useState(false)
return (
<>
<button onClick={() => setOpen((open) => !open)}>Toggle</button>
<Transition show={open}>
<div className="transition duration-300 ease-in data-[closed]:opacity-0">I will fade in and out</div>
</Transition>
</>
)
}
data-closed
属性で定義されたスタイルは、トランジションインするときの開始点と、トランジションアウトするときの終了点として使用されます。
より複雑なトランジションの場合、data-enter
、data-leave
、およびdata-transition
属性を使用して、トランジションの異なる段階でスタイルを適用することもできます。
進入時と退出時に異なるトランジションスタイルを適用するには、data-enter
属性とdata-leave
属性を使用します
import { Transition } from '@headlessui/react'
import clsx from 'clsx'
import { useState } from 'react'
function Example() {
const [open, setOpen] = useState(false)
return (
<div className="relative">
<button onClick={() => setOpen((open) => !open)}>Toggle</button>
<Transition show={open}>
<div
className={clsx([
// Base styles
'absolute w-48 border transition ease-in-out',
// Shared closed styles
'data-[closed]:opacity-0',
// Entering styles
'data-[enter]:duration-100 data-[enter]:data-[closed]:-translate-x-full',
// Leaving styles
'data-[leave]:duration-300 data-[leave]:data-[closed]:translate-x-full',
])}
>
I will enter from the left and leave to the right
</div>
</Transition>
</div>
)
}
この例では、data-enter
属性とdata-closed
属性を組み合わせて進入トランジションの開始点を指定し、data-leave
属性とdata-closed
属性を組み合わせて退出トランジションの終了点を指定します。
また、data-enter
属性とdata-leave
属性を使用して、異なる進入と退出の期間を指定します。
異なるアニメーションで複数の要素をトランジションする必要がある場合がありますが、すべて同じ状態に基づいています。たとえば、ユーザーがボタンをクリックして画面上にスライドするサイドバーを開き、同時に背景をフェードインする必要があるとします。
これを行うには、関連する要素を親のTransition
コンポーネントでラップし、独自のトランジションスタイルが必要な各子をTransitionChild
コンポーネントでラップします。これは自動的に親のTransition
と通信し、親のopen
状態を継承します。
import { Transition, TransitionChild } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [open, setOpen] = useState(false)
return (
<>
<button onClick={() => setOpen(true)}>Open</button>
{/* The `show` prop controls all nested `TransitionChild` components. */}
<Transition show={open}> {/* Backdrop */}
<TransitionChild> <div
className="fixed inset-0 bg-black/30 transition duration-300 data-[closed]:opacity-0"
onClick={() => setOpen(false)}
/>
</TransitionChild>
{/* Slide-in sidebar */}
<TransitionChild> <div className="fixed inset-y-0 left-0 w-64 bg-white transition duration-300 data-[closed]:-translate-x-full">
{/* ... */}
</div> </TransitionChild> </Transition>
</>
)
}
TransitionChild
コンポーネントは、Transition
コンポーネントとまったく同じAPIを持っていますが、show
値は親によって制御されるため、show
プロップはありません。
親のTransition
コンポーネントは、常にすべての子がトランジションを終了するまで自動的に待機してからアンマウントされるため、タイミングを自分で管理する必要はありません。
要素が最初にレンダリングされたときにトランジションさせる場合は、appear
プロップをtrue
に設定します。
これは、初期ページの読み込み時、または親が条件付きでレンダリングされたときに何かをトランジションインさせたい場合に便利です。
import { Transition } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [open, setOpen] = useState(true)
return (
<>
<button onClick={() => setOpen((open) => !open)}>Toggle</button>
<Transition show={open} appear={true}> <div className="transition duration-300 ease-in data-[closed]:opacity-0">I will fade in on initial render</div>
</Transition>
</>
)
}
プロパティ | デフォルト | 説明 |
as | フラグメント | 文字列 | コンポーネント トランジションがレンダリングされる要素またはコンポーネント。としてレンダリングする必要があります。 |
show | — | ブール値 子を表示するか非表示にするか。 |
appear | false | ブール値 初期マウント時にトランジションを実行するかどうか。 |
unmount | true | ブール値 表示状態に基づいて要素をアンマウントするか非表示にするか。 |
beforeEnter | — | () => void 進入トランジションを開始する前に呼び出されるコールバック。 |
afterEnter | — | () => void 進入トランジションの完了後に呼び出されるコールバック。 |
beforeLeave | — | () => void 退出トランジションを開始する前に呼び出されるコールバック。 |
afterLeave | — | () => void 退出トランジションの完了後に呼び出されるコールバック。 |
プロパティ | デフォルト | 説明 |
as | フラグメント | 文字列 | コンポーネント トランジションがレンダリングされるトランジションの子としてレンダリングする必要があります。 |
appear | false | ブール値 初期マウント時にトランジションを実行するかどうか。 |
unmount | true | ブール値 表示状態に基づいて要素をアンマウントするか非表示にするか。 |
beforeEnter | — | () => void 進入トランジションを開始する前に呼び出されるコールバック。 |
afterEnter | — | () => void 進入トランジションの完了後に呼び出されるコールバック。 |
beforeLeave | — | () => void 退出トランジションを開始する前に呼び出されるコールバック。 |
afterLeave | — | () => void 退出トランジションの完了後に呼び出されるコールバック。 |
属性 | 説明 |
data-closed | トランジションインする前、およびトランジションアウトするときに存在します。 |
data-enter | トランジションインするときに存在します。 |
data-leave | トランジションアウトするときに存在します。 |
data-transition | トランジションインまたはアウトするときに存在します。 |
Headless UIを使用した、事前にデザインされたTailwind CSSコンポーネントの例に興味がある場合は、Tailwind UIをご覧ください。これは、私たちが構築した美しくデザインされ、巧みに作られたコンポーネントのコレクションです。
これは、このようなオープンソースプロジェクトでの私たちの仕事をサポートするのに最適な方法であり、私たちがそれらを改善し、適切に維持することを可能にします。