揭露

用於建立自訂 UI 的一個簡單、簡易存取基礎,可以顯示和隱藏內容,像是可切換的手風琴面板。

要開始使用,請透過 npm 安裝無頭 UI。

請注意,此程式庫僅支援 Vue 3

npm install @headlessui/vue

揭露是使用 DisclosureDisclosureButtonDisclosurePanel 元件建置的。

按鈕會自動在點選時開啟/關閉面板,而所有元件都會接收適當的 aria-* 相關屬性,例如 aria-expandedaria-controls

<template> <Disclosure> <DisclosureButton class="py-2"> Is team pricing available? </DisclosureButton> <DisclosurePanel class="text-gray-500"> Yes! You can purchase a license that you can share with your entire team. </DisclosurePanel> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' </script>

無頭 UI 會追蹤每個元件的很多狀態,例如哪個列表方塊選項目前已選取、提示框是開啟還是關閉,或者揭露中哪個項目目前正在透過鍵盤使用。

但是因為元件是無頭的,而且完全未在方塊外設定樣式,所以直到您自行提供您想要每個狀態的樣式前,您在 UI 中看不到此資訊。

每個元件會公開其目前狀態的資訊,這是透過 插槽道具,您可以使用插槽道具有條件地套用不同樣式或呈現不同內容。

例如,Disclosure 元件會公開一個 open 狀態,這個狀態可以告訴您揭露目前是否已開啟。

<template>
<Disclosure v-slot="{ open }">
<!-- Use the `open` state to conditionally change the direction of an icon. --> <DisclosureButton class="py-2"> <span>Do you offer technical support?</span>
<ChevronRightIcon :class="open && 'rotate-90 transform'" />
</DisclosureButton> <DisclosurePanel>No</DisclosurePanel> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' import { ChevronRightIcon } from '@heroicons/vue/20/solid' </script>

關於可用插槽道具的完整清單,請參閱 元件 API 文件

每個元件都透過你可以用來有條件套用不同樣式的 `data-headlessui-state` 屬性公開其目前狀態的資訊。

`插槽屬性 API` 中的其中一個狀態為 `true` 時,它們會以空格分隔字串的方式列在這個屬性中,因此你可以用 `[attr~=value]` 格式的 `CSS 屬性選擇器` 來指定目標。

例如,以下是在揭露元件開啟時呈現的內容:

<!-- Rendered `Disclosure` --> <div data-headlessui-state="open"> <button data-headlessui-state="open">Do you offer technical support?</button> <div data-headlessui-state="open">No</div> </div>

如果你正在使用 `Tailwind CSS`,你可以使用 `@headlessui/tailwindcss` 外掛程式以 `ui-open:*` 類型的修改器指定這個屬性的目標。

<template> <Disclosure> <DisclosureButton class="py-2"> <span>Do you offer technical support?</span>
<ChevronRightIcon class="ui-open:rotate-90 ui-open:transform" />
</DisclosureButton> <DisclosurePanel>No</DisclosurePanel> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' import { ChevronRightIcon } from '@heroicons/vue/20/solid' </script>

預設情況下,你的 `DisclosurePanel` 會根據 `Disclosure` 元件本身中追蹤的內部開啟狀態自動顯示/隱藏。

<template> <Disclosure> <DisclosureButton>Is team pricing available?</DisclosureButton> <!-- By default, the `DisclosurePanel` will automatically show/hide when the `DisclosureButton` is pressed. --> <DisclosurePanel> Yes! You can purchase a license that you can share with your entire team. </DisclosurePanel> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' </script>

如果你想自己處理這件事(可能是因為某種原因需要新增額外的包裝元素),你可以傳送 `static` 屬性給 `DisclosurePanel` 以指示它總是呈現,然後使用 `open` 插槽屬性自己控制何時顯示/隱藏面板。

<template>
<Disclosure v-slot="{ open }">
<DisclosureButton>Is team pricing available?</DisclosureButton>
<div v-show="open">
<!-- Using the `static` prop, the `DisclosurePanel` is always rendered and the `open` state is ignored. -->
<DisclosurePanel static>
Yes! You can purchase a license that you can share with your entire team. </DisclosurePanel> </div> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' </script>

若要手動關閉揭露,請在點選其面板的子項時將該子項呈現為 `DisclosureButton`。你可以使用 `:as` 屬性自訂要呈現的元素。

<template> <Disclosure> <DisclosureButton>Open mobile menu</DisclosureButton> <DisclosurePanel>
<DisclosureButton :as="MyLink" href="/home">Home</DisclosureButton>
<!-- ... --> </DisclosurePanel> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' import MyLink from './MyLink' </script>

在將揭露用於包含連結的行動裝置功能表等內容時,這項功能特別有用,因為你希望在導覽到下一頁時關閉揭露。

另外,`Disclosure` 和 `DisclosurePanel` 公開一個你可以用來強制關閉面板的 `close()` 插槽屬性,例如在執行非同步動作之後。

<template> <Disclosure> <DisclosureButton>Terms</DisclosureButton>
<DisclosurePanel v-slot="{ close }">
<button @click="accept(close)">Read and accept</button>
</DisclosurePanel>
</Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue'
async function accept(close) {
await fetch('/accept-terms', { method: 'POST' })
close()
}
</script>

預設情況下,`DisclosureButton` 會在呼叫 `close()` 之後獲得焦點,但你可以透過傳送參考給 `close(ref)` 來變更這項設定。

若要為你的揭露面板開啟/關閉動畫,你可以使用 Vue 內建的 `<transition>` 元件。你只需要將你的 `DisclosurePanel` 包在 `<transition>` 之中,就會自動套用過場動畫。

<template> <Disclosure> <DisclosureButton>Is team pricing available?</DisclosureButton> <!-- Use the built-in `transition` component to add transitions. -->
<transition
enter-active-class="transition duration-100 ease-out"
enter-from-class="transform scale-95 opacity-0"
enter-to-class="transform scale-100 opacity-100"
leave-active-class="transition duration-75 ease-out"
leave-from-class="transform scale-100 opacity-100"
leave-to-class="transform scale-95 opacity-0"
>
<DisclosurePanel> Yes! You can purchase a license that you can share with your entire team. </DisclosurePanel> </transition> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' </script>

如果你想協調你的揭露中不同子項的過場動畫,請查看 `Headless UI 中提供的 Transition 元件`。

Disclosure 和它的子元件,それぞれがそのコンポーネントにとって道理にかなったデフォルトの要素を作成する: Button<button> を作成し、Panel<div> を作成します。対照的に、ルート Disclosure コンポーネントは 要素を作成しません、そして代わりに、デフォルトでは、直接子要素を作成します。

これは、すべてのコンポーネントに搭載されている as プロップを使用して、簡単に変更できます。

<template> <!-- Render a `div` for the root `Disclosure` component -->
<Disclosure as="div">
<!-- Don't render any element (only children) for the `DisclosureButton` component -->
<DisclosureButton as="template">
<button>What languages do you support?</button> </DisclosureButton> <!-- Render a `ul` for the `DisclosurePanel` component -->
<DisclosurePanel as="ul">
<li>HTML</li> <li>CSS</li> <li>JavaScript</li> </DisclosurePanel> </Disclosure> </template> <script setup> import { Disclosure, DisclosureButton, DisclosurePanel, } from '@headlessui/vue' </script>

DisclosureButton をクリックすると、Disclosure のパネルが開閉します。

コマンド説明

Enter or Space which DisclosureButton がフォーカスされた時。

パネルをトグルする

関連するすべての ARIA 属性は、自動で管理されます。

メインの Disclosure コンポーネントです。

プロップデフォルト説明
astemplate
文字列 | コンポーネント

Disclosure によってレンダリングされる要素またはコンポーネント。

defaultOpenfalse
ブール値

Disclosure コンポーネントをデフォルトで開くかどうかを示します。

スロットプロップ説明
open

ブール値

開示が開いているかどうかを表します。

close

(ref?: ref | HTMLElement) => void

開示を閉じ、DisclosureButton にフォーカスを戻します。その代わりに ref または HTMLElement を渡して、その要素にフォーカスを当てます。

Disclosure をトグルするトリガコンポーネントです。

プロップデフォルト説明
asbutton
文字列 | コンポーネント

DisclosureButton 應呈現為的元素或組件。

スロットプロップ説明
open

ブール値

開示が開いているかどうかを表します。

此組件包含揭露的內容。

プロップデフォルト説明
asdiv
文字列 | コンポーネント

DisclosurePanel 應呈現為的元素或組件。

staticfalse
ブール値

若元素應忽略內部管理的開啟/關閉狀態。

請注意:不可以同時使用 staticunmount。如果您這樣做,會收到 TypeScript 錯誤訊息。

unmounttrue
ブール値

元素是否應根據開啟/關閉的狀態卸載或隱藏。

請注意:不可以同時使用 staticunmount。如果您這樣做,會收到 TypeScript 錯誤訊息。

スロットプロップ説明
open

ブール値

開示が開いているかどうかを表します。

close

(ref?: ref | HTMLElement) => void

開示を閉じ、DisclosureButton にフォーカスを戻します。その代わりに ref または HTMLElement を渡して、その要素にフォーカスを当てます。

如果您有興趣取得使用 Headless UI 和 Tailwind CSS 的預先設計組件範例,請檢閱Tailwind UI — 我們建立的一系列精心設計且精湛製作的組件。

支持我們對於此類型開放原始碼專案的工作,讓我們得以改進專案並持續維護,這是一個很棒的方式。