標籤頁
輕鬆建立具無障礙功能、可完全自訂的標籤頁介面,並支援強大的焦點管理和鍵盤導覽。
要開始使用,請透過 npm 安裝無頭 UI
npm install @headlessui/react
標籤頁是用 Tab.Group
、Tab.List
、Tab
、Tab.Panels
和 Tab.Panel
元件建置的。預設會選取第一個標籤頁,並按一下任意標籤頁或用鍵盤選取,將會啟用對應的面板。
import { Tab } from '@headlessui/react' function MyTabs() { return ( <Tab.Group> <Tab.List> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> <Tab.Panel>Content 2</Tab.Panel> <Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
無頭 UI 會追蹤每個元件的許多狀態,例如目前已勾選哪個標籤頁選項、浮動式視窗是開啟還是關閉,或選單中哪個項目目前已使用鍵盤啟用。
但是由於這些元件在未調整樣式之前是無頭的且完全未調整樣式,因此在您自己為每個狀態提供所需的樣式之前,無法在使用者介面中看見這些資訊。
每個元件都會透過 渲染 Props 公開其目前狀態的資訊,您可以使用該資訊來有條件地套用不同的樣式或渲染不同的內容。
例如,Tab
元件會公開一個 selected
狀態,告訴您標籤頁是否目前已選取。
import { Fragment } from 'react' import { Tab } from '@headlessui/react' function MyTabs() { return ( <Tab.Group> <Tab.List> <Tab as={Fragment}>
{({ selected }) => (/* Use the `selected` state to conditionally style the selected tab. */ <button className={selected ? 'bg-blue-500 text-white' : 'bg-white text-black'} > Tab 1 </button> )} </Tab> {/* ... */} </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> {/* ... */} </Tab.Panels> </Tab.Group> ) }
若要查看每個元件的完整渲染 Props API,請參閱 元件 API 文件。
每個元件還透過 data-headlessui-state
屬性公開其目前狀態的資訊,您可以使用該資訊來有條件地套用不同的樣式。
當 傳遞 props API 中的任一狀態為「true
」時,這些狀態將會以空白分隔字串的形式列在這個屬性中,因此你可以使用 CSS 屬性選取器(例如 [attr~=value]
)來設定目標。
舉例,以下是具有多個子項 Tab
元件的 Tab.Group
元件,而第二個索引標籤為「selected
」時呈現的畫面
<!-- Rendered `Tab.Group` --> <div> <button data-headlessui-state="">Tab 1</button> <button data-headlessui-state="selected">Tab 2</button> <button data-headlessui-state="">Tab 3</button> </div> <div> <div data-headlessui-state="">Content 1</div> <div data-headlessui-state="selected">Content 2</div> <div data-headlessui-state="">Content 3</div> </div>
如果你使用的是 Tailwind CSS,可以使用 @headlessui/tailwindcss 外掛來設定對應屬性的目標,例如 ui-open:*
import { Tab } from '@headlessui/react' function MyTabs() { return ( <Tab.Group> <Tab.List>
<Tab className="ui-selected:bg-blue-500 ui-selected:text-white ui-not-selected:bg-white ui-not-selected:text-black">Tab 1 </Tab> {/* ... */} </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> {/* ... */} </Tab.Panels> </Tab.Group> ) }
若要停用某個索引標籤,請在 Tab
元件上使用 disabled
屬性。停用的索引標籤無法使用滑鼠選取,且在使用鍵盤瀏覽索引標籤清單時也會跳過該索引標籤。
import { Tab } from '@headlessui/react' function MyTabs() { return ( <Tab.Group> <Tab.List> <Tab>Tab 1</Tab>
<Tab disabled>Tab 2</Tab><Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> <Tab.Panel>Content 2</Tab.Panel> <Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
預設情況下,當使用者使用箭頭鍵瀏覽時,會自動選取索引標籤。
如果你希望在使用者按下「Enter
」或「Space
」之前,不要變更目前的索引標籤,請在 Tab.Group
元件上使用 manual
屬性。當選取索引標籤會執行成本高昂的操作,而你希望避免不必要執行時,這項設定可能很有幫助。
import { Tab } from '@headlessui/react' function MyTabs() { return (
<Tab.Group manual><Tab.List> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> <Tab.Panel>Content 2</Tab.Panel> <Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
manual
屬性並不會影響滑鼠互動—索引標籤仍會在你按一下後立即被選取。
如果你已將 Tab.List
設定成垂直顯示,請使用 vertical
屬性改為使用上下箭頭鍵(而不是左右箭頭鍵)瀏覽,並更新輔助技術的 aria-orientation
屬性。
import { Tab } from '@headlessui/react' function MyTabs() { return (
<Tab.Group vertical><Tab.List> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> <Tab.Panel>Content 2</Tab.Panel> <Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
若要變更預設選取的索引標籤,請在 Tab.Group
元件上使用 defaultIndex={number}
屬性。
import { Tab } from '@headlessui/react' function MyTabs() { return (
<Tab.Group defaultIndex={1}><Tab.List> <Tab>Tab 1</Tab>{/* Selects this tab by default */}<Tab>Tab 2</Tab><Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel>{/* Displays this panel by default */}<Tab.Panel>Content 2</Tab.Panel><Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
如果你提供的索引超出了範圍,則會在初始呈現時選取最後一個未停用的索引標籤。(例如,在上方的範例中,<Tab.Group defaultIndex={5}
會將第三個面板呈現為已選取狀態。)
若要選定的索引標籤分頁變更時執行函式,請在 Tab.Group
元件上使用 onChange
屬性。
import { Tab } from '@headlessui/react' function MyTabs() { return ( <Tab.Group
onChange={(index) => {console.log('Changed selected tab to:', index)}}> <Tab.List> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> <Tab.Panel>Content 2</Tab.Panel> <Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
索引標籤分頁元件也可以當作受控制的元件。為達到此目的,請提供 selectedIndex
並自己管理狀態。
import { useState } from 'react' import { Tab } from '@headlessui/react' function MyTabs() {
const [selectedIndex, setSelectedIndex] = useState(0)return (<Tab.Group selectedIndex={selectedIndex} onChange={setSelectedIndex}><Tab.List> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </Tab.List> <Tab.Panels> <Tab.Panel>Content 1</Tab.Panel> <Tab.Panel>Content 2</Tab.Panel> <Tab.Panel>Content 3</Tab.Panel> </Tab.Panels> </Tab.Group> ) }
按一下 Tab
會選取索引標籤分頁,並顯示對應的 Tab.Panel
。
當 Tab
元件取得焦點時,所有互動都會套用。
指令 | 說明 |
向左箭頭和向右箭頭 | 選取上一個/下一個非停用的索引標籤分頁。 |
向上箭頭和向下箭頭在設定 | 選取上一個/下一個非停用的索引標籤分頁。 |
Home或PageUp | 選取第一個非停用的索引標籤分頁。 |
End或PageDown | 選取最後一個非停用的索引標籤分頁。 |
Enter 或 Space 當 | 啟用所選索引標籤。 |
屬性 | 預設 | 說明 |
as | 區段 | 字串 | 元件
|
defaultIndex | 0 | Number 預設選取索引 |
selectedIndex | — | 數字 如果您想使用 Tabs 元件做為受控元件,則為選取索引。 |
onChange | — | (index: number) => void 當目前選取的索引標籤變更時呼叫的函式。 |
vertical | false | 布林 當為 true 時, |
manual | false | 布林 當為 true 時,使用者只能透過鍵盤先使用箭頭鍵瀏覽面板,再按 |
渲染屬性 | 說明 |
selectedIndex |
目前選取的索引。 |
屬性 | 預設 | 說明 |
as | div | 字串 | 元件
|
渲染屬性 | 說明 |
selectedIndex |
目前選取的索引。 |
屬性 | 預設 | 說明 |
as | 按鈕 | 字串 | 元件
|
disabled | false | 布林
|
渲染屬性 | 說明 |
selected |
|
屬性 | 預設 | 說明 |
as | div | 字串 | 元件
|
渲染屬性 | 說明 |
selectedIndex |
目前選取的索引。 |
屬性 | 預設 | 說明 |
as | div | 字串 | 元件
|
static | false | 布林 元素是否應忽略所選索引。 注意: |
unmount | true | 布林 元素是否應根據所選索引取消掛載或隱藏。 注意: |
渲染屬性 | 說明 |
selected |
|