轉場
轉場元件可讓您將進入/離開的轉場加入有條件渲染的元素中,使用 CSS 類別來控制不同轉場階段的實際轉場樣式。
入門:透過 npm 安裝 Headless UI
npm install @headlessui/react
轉場
接受一個 顯示
prop,用於控制子項目應顯示或隱藏,以及一系列生命週期 props(例如 enterFrom
和 leaveTo
),讓您可以在轉場的特定階段加入 CSS 類別。
import { Transition } from '@headlessui/react' import { useState } from 'react' function MyComponent() { const [isShowing, setIsShowing] = useState(false) return ( <> <button onClick={() => setIsShowing((isShowing) => !isShowing)}> Toggle </button> <Transition show={isShowing} enter="transition-opacity duration-75" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity duration-150" leaveFrom="opacity-100" leaveTo="opacity-0" > I will fade in and out </Transition> </> ) }
將應有條件渲染的內容包覆在 <轉場>
元件中,並使用 顯示
prop 來控制內容應為可見或隱藏狀態。
import { Transition } from '@headlessui/react' import { useState } from 'react' function MyComponent() { const [isShowing, setIsShowing] = useState(false) return ( <> <button onClick={() => setIsShowing((isShowing) => !isShowing)}>
Toggle</button> <Transition show={isShowing}>I will appear and disappear.</Transition> </> ) }
預設情況下,轉場元件會渲染為 div
元素。
使用 as
prop 可以渲染一個元件為不同元素或自訂元件,但請確認自訂元件已 轉譯 ref
,以便 Headless UI 能正確連接所有事物。
import { forwardRef, useState, Fragment } from 'react' import { Dialog, Transition } from '@headlessui/react'
let MyDialogPanel = forwardRef(function (props, ref) {return <Dialog.Panel className="…" ref={ref} {...props} />})function MyDialog() { let [isOpen, setIsOpen] = useState(true) return ( <Transitionas={Dialog}show={isOpen} onClose={() => setIsOpen(false)} > <Transition.Childas={MyDialogPanel}enter="ease-out duration-300" enterFrom="opacity-0 scale-95" enterTo="opacity-100 scale-100" leave="ease-in duration-200" leaveFrom="opacity-100 scale-100" leaveTo="opacity-0 scale-95" > <Dialog.Title>Deactivate account</Dialog.Title> {/* ... */} </Transition.Child> </Transition> ) }
預設情況下,轉場
會立即進入與離開,如果您要使用這個元件,可能不是您所需要的功能。
若要為您的進入/離開轉場加入動畫,請使用這些 prop 加入提供每個轉場階段造型的類別。
- 進入:當元素進入時持續套用。通常會在此定義要套用轉場的持續時間與屬性,例如
transition-opacity duration-75
。 - enterFrom:從指定起點進入,例如
opacity-0
,表示要淡入元素。 - enterTo:進入終點,例如淡入後為
opacity-100
。 - leave:在元素離開的整個時間中套用。通常在此定義持續時間和想要轉換的屬性,例如
transition-opacity duration-75
。 - leaveFrom:離開起點,例如在淡出時為
opacity-100
。 - leaveTo:離開終點,例如淡出後為
opacity-0
。
以下是一個範例
import { Transition } from '@headlessui/react' import { useState } from 'react' function MyComponent() { const [isShowing, setIsShowing] = useState(false) return ( <> <button onClick={() => setIsShowing((isShowing) => !isShowing)}> Toggle </button>
<Transitionshow={isShowing}enter="transition-opacity duration-75"enterFrom="opacity-0"enterTo="opacity-100"leave="transition-opacity duration-150"leaveFrom="opacity-100" leaveTo="opacity-0" > I will fade in and out </Transition> </> ) }
在此範例中,此轉換元素將花費 75 毫秒進入(這是 duration-75
類別),並在此期間轉換不透明度屬性(這是 transition-opacity
)。
它將在進入前完全透明(這是 enterFrom
階段中的 opacity-0
),並在結束時淡入為完全不透明(opacity-100
)(這是 enterTo
階段)。
當元素被移除(leave
階段),它將轉換不透明度屬性,並花費 150 毫秒執行此動作(transition-opacity duration-150
)。
它將開始為完全不透明(leaveFrom
階段中的 opacity-100
),並結束為完全透明(leaveTo
階段中的 opacity-0
)。
所有這些 props 都是選用的,如果未設定會預設為空字串。
有時你需要使用不同的動畫轉換多個元素,但所有這些轉換都根據相同的狀態。例如,假設使用者按下按鈕以開啟滑過螢幕的側邊欄,同時你也需要同時淡入背景疊層。
你可以透過將相關元素包覆在父層級 Transition
組件內,並將需要有自己轉換樣式的每個子層級包覆在 Transition.Child
組件內來執行此動作,這會自動與父層級 Transition
進行通訊,並繼承父層級的 show
狀態。
import { Transition } from '@headlessui/react' function Sidebar({ isShowing }) { return ( /* The `show` prop controls all nested `Transition.Child` components. */ <Transition show={isShowing}> {/* Background overlay */} <Transition.Child enter="transition-opacity ease-linear duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity ease-linear duration-300" leaveFrom="opacity-100" leaveTo="opacity-0" > {/* ... */} </Transition.Child> {/* Sliding sidebar */} <Transition.Child enter="transition ease-in-out duration-300 transform" enterFrom="-translate-x-full" enterTo="translate-x-0" leave="transition ease-in-out duration-300 transform" leaveFrom="translate-x-0" leaveTo="-translate-x-full" > {/* ... */} </Transition.Child> </Transition> ) }
Transition.Child
組件的 API 與 Transition
組件完全相同,但沒有 show
props,這是因為 show
值是由父層級控制的。
父層級 Transition
組件會在全部子層級完成轉換前自動等待它們,然後才會解除掛載,因此你不需要自己管理這些時間。
如果你想要讓元素在第一次渲染時轉換,請將 appear
props 設定為 true
。
如果你想要讓某些東西在初始網頁載入時,或是在其父層級有條件渲染時轉換,這會很有用。
import { Transition } from '@headlessui/react' function MyComponent({ isShowing }) { return ( <Transition
appear={true}show={isShowing} enter="transition-opacity duration-75" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity duration-150" leaveFrom="opacity-100" leaveTo="opacity-0" > {/* Your content goes here*/} </Transition> ) }
道具 | 預設值 | 說明 |
show | — | 布林值 子代是否應顯示或隱藏。 |
as | div | 字串 | 組件 用於在轉場本身的位置顯示的元素或組件。 |
appear | false | 布林值 轉場是否應在初始掛載時執行。 |
unmount | true | 布林值 元素是否應基於顯示狀態取消掛載或隱藏。 |
enter | — | 字串 在整個輸入階段要新增至轉換元素的類別。 |
enterFrom | — | 字串 在輸入階段開始前要新增至轉換元素的類別。 |
enterTo | — | 字串 在輸入階段開始後立即要新增至轉換元素的類別。 |
entered | — | 字串 轉場完成後要新增至轉換元素的類別。這些類別將在之後持續存在,直到離開時間點。 |
leave | — | 字串 在整個離開階段要新增至轉換元素的類別。 |
leaveFrom | — | 字串 在離開階段開始前要新增至轉換元素的類別。 |
leaveTo | — | 字串 在離開階段開始後立即要新增至轉換元素的類別。 |
beforeEnter | — | () => void 在我們開始進行輸入轉場前呼叫的回呼函式。 |
afterEnter | — | () => void 在我們完成輸入轉場後呼叫的回呼函式。 |
beforeLeave | — | () => void 在我們開始進行離開轉場前呼叫的回呼函式。 |
afterLeave | — | () => void 在我們完成離開轉場後呼叫的回呼函式。 |
道具 | 預設值 | 說明 |
as | div | 字串 | 組件 用於在轉場本身的位置顯示的元素或組件。 |
appear | false | 布林值 轉場是否應在初始掛載時執行。 |
unmount | true | 布林值 元素是否應基於顯示狀態取消掛載或隱藏。 |
enter | — | 字串 在整個輸入階段要新增至轉換元素的類別。 |
enterFrom | — | 字串 在輸入階段開始前要新增至轉換元素的類別。 |
enterTo | — | 字串 在輸入階段開始後立即要新增至轉換元素的類別。 |
entered | — | 字串 轉場完成後要新增至轉換元素的類別。這些類別將在之後持續存在,直到離開時間點。 |
leave | — | 字串 在整個離開階段要新增至轉換元素的類別。 |
leaveFrom | — | 字串 在離開階段開始前要新增至轉換元素的類別。 |
leaveTo | — | 字串 在離開階段開始後立即要新增至轉換元素的類別。 |
beforeEnter | — | () => void 在我們開始進行輸入轉場前呼叫的回呼函式。 |
afterEnter | — | () => void 在我們完成輸入轉場後呼叫的回呼函式。 |
beforeLeave | — | () => void 在我們開始進行離開轉場前呼叫的回呼函式。 |
afterLeave | — | () => void 在我們完成離開轉場後呼叫的回呼函式。 |