スイッチ
スイッチは、2つの状態間で値を切り替えるための快適なインターフェースであり、ネイティブのチェックボックス要素と同じセマンティクスとキーボードナビゲーションを提供します。
開始するには、npm 経由で Headless UI をインストールします。
npm install @headlessui/react
スイッチは、`Switch` コンポーネントを使用して構築されています。コンポーネントを直接クリックするか、フォーカスされている間にスペースバーを押して、スイッチを切り替えることができます。
スイッチを切り替えると、`checked` 値の反転バージョンを使用して `onChange` 関数が呼び出されます。
import { Switch } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<Switch
checked={enabled}
onChange={setEnabled}
className="group inline-flex h-6 w-11 items-center rounded-full bg-gray-200 transition data-[checked]:bg-blue-600"
>
<span className="size-4 translate-x-1 rounded-full bg-white transition group-data-[checked]:translate-x-6" />
</Switch>
)
}
Headless UI は、スイッチがオンかどうか、ポップオーバーが開いているか閉じているか、キーボードで現在フォーカスされているメニューのアイテムなどが、各コンポーネントに関する多くの状態を追跡します。
しかし、コンポーネントはヘッドレスであり、すぐに使える状態では完全にスタイルが適用されていないため、自分で各状態に望ましいスタイルを提供するまで、UIでこの情報を確認できません。
Headless UI コンポーネントのさまざまな状態をスタイリングする最も簡単な方法は、各コンポーネントが公開する `data-*` 属性を使用することです。
たとえば、`Switch` コンポーネントは `data-checked` 属性(スイッチが現在オンかどうかを示す)と `data-disabled` 属性(スイッチが現在無効かどうかを示す)を公開します。
<!-- Rendered `Switch` -->
<button data-checked data-disabled>
<!-- ... -->
</button>
これらのデータ属性の存在に基づいて条件付きでスタイルを適用するには、CSS 属性セレクター を使用します。Tailwind CSS を使用している場合は、データ属性修飾子 を使用すると簡単です。
import { Switch } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<Switch
checked={enabled}
onChange={setEnabled}
className="group inline-flex h-6 w-11 items-center rounded-full bg-gray-200 data-[checked]:bg-blue-600 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50" >
<span className="size-4 translate-x-1 rounded-full bg-white transition group-data-[checked]:translate-x-6" /> </Switch>
)
}
使用可能なすべてのデータ属性のリストについては、コンポーネントAPI を参照してください。
各コンポーネントは、レンダープロップス を介して現在の状態に関する情報を公開しており、これを使用して条件付きで異なるスタイルを適用したり、異なるコンテンツをレンダリングしたりできます。
たとえば、`Switch` コンポーネントは `checked` 状態(スイッチが現在オンかどうかを示す)と `disabled` 状態(スイッチが現在無効かどうかを示す)を公開します。
import { Switch } from '@headlessui/react'
import clsx from 'clsx'
import { Fragment, useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<Switch checked={enabled} onChange={setEnabled} as={Fragment}>
{({ checked, disabled }) => ( <button
className={clsx(
'group inline-flex h-6 w-11 items-center rounded-full',
checked ? 'bg-blue-600' : 'bg-gray-200', disabled && 'cursor-not-allowed opacity-50' )}
>
<span className="sr-only">Enable notifications</span>
<span
className={clsx('size-4 rounded-full bg-white transition', checked ? 'translate-x-6' : 'translate-x-1')} />
</button>
)} </Switch>
)
}
使用可能なすべてのレンダープロップスのリストについては、コンポーネントAPI を参照してください。
`Label` と `Switch` を `Field` コンポーネントでラップして、生成された ID を使用して自動的に関連付けます。
import { Field, Label, Switch } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<Field> <Label>Enable notifications</Label> <Switch
checked={enabled}
onChange={setEnabled}
className="group inline-flex h-6 w-11 items-center rounded-full bg-gray-200 transition data-[checked]:bg-blue-600"
>
<span className="size-4 translate-x-1 rounded-full bg-white transition group-data-[checked]:translate-x-6" />
</Switch>
</Field> )
}
デフォルトでは、`Label` をクリックすると `Switch` が切り替わり、ネイティブのHTMLチェックボックスのラベルと同じように動作します。`Label` をクリック不可にする場合は、`Label` コンポーネントに `passive` プロップを追加できます。
<Label passive>Enable beta features</Label>
`aria-describedby` 属性を使用して `Switch` と自動的に関連付けるには、`Field` 内に `Description` コンポーネントを使用します。
import { Description, Field, Label, Switch } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<Field> <Label>Enable notifications</Label>
<Description>Get notified about important changes in your projects.</Description> <Switch
checked={enabled}
onChange={setEnabled}
className="group inline-flex h-6 w-11 items-center rounded-full bg-gray-200 transition data-[checked]:bg-blue-600"
>
<span className="size-4 translate-x-1 rounded-full bg-white transition group-data-[checked]:translate-x-6" />
</Switch>
</Field> )
}
`Switch` と関連付けられた `Label` と `Description` を無効にするには、`Field` コンポーネントに `disabled` プロップを追加します。
import { Description, Field, Label, Switch } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<Field disabled> <Label className="data-[disabled]:opacity-50">Enable notifications</Label>
<Description className="data-[disabled]:opacity-50">
Get notified about important changes in your projects.
</Description>
<Switch
checked={enabled}
onChange={setEnabled}
className="group inline-flex h-6 w-11 items-center rounded-full bg-gray-200 transition data-[checked]:bg-blue-600 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50"
>
<span className="size-4 translate-x-1 rounded-full bg-white transition group-data-[checked]:translate-x-6" />
</Switch>
</Field>
)
}
`Switch` 自体に `disabled` プロップを追加することで、`Field` の外でもスイッチを無効化できます。
`Switch` に `name` プロップを追加すると、非表示の `input` 要素がレンダリングされ、スイッチの状態と同期されます。
import { Switch } from '@headlessui/react'
import { useState } from 'react'
function Example() {
const [enabled, setEnabled] = useState(false)
return (
<form action="/accounts" method="post">
<Switch
checked={enabled}
onChange={setEnabled}
name="terms-of-service" className="group inline-flex h-6 w-11 items-center rounded-full bg-gray-200 transition data-[checked]:bg-blue-600"
>
<span className="size-4 translate-x-1 rounded-full bg-white transition group-data-[checked]:translate-x-6" />
</Switch>
<button>Submit</button>
</form>
)
}
これにより、ネイティブのHTML `
コマンド | 説明 |
スペース`Switch` がフォーカスされているとき | スイッチを切り替えます。 |
Enterフォーム内にあるとき | フォームを送信します。 |
プロップ | デフォルト | 説明 |
as | button | 文字列 | コンポーネント スイッチがレンダリングされる要素またはコンポーネント。スイッチとしてレンダリングする必要があります。 |
checked | — | ブール値 スイッチがオンかどうか。 |
defaultChecked | — | T 非制御コンポーネントとして使用する場合のデフォルトのオン値。 |
onChange | — | (value: Boolean) => void スイッチが切り替えられたときに呼び出す関数。 |
name | — | 文字列 フォーム内で使用する場合の名前。スイッチフォーム内 |
form | — | 文字列 所属するフォームのID。スイッチに属します。 `name` が指定されているが `form` が指定されていない場合、スイッチ自身の状態を最も近い祖先である |
値 | — | 文字列 このコンポーネントをフォーム内で使用する場合、チェックされているときの値。 |
データ属性 | レンダープロップ | 説明 |
data-checked | checked |
〜かどうかスイッチチェックされています。 |
data-無効化 | 無効化 |
〜かどうかスイッチ無効化されています。 |
data-フォーカス | フォーカス |
〜かどうかスイッチフォーカスされています。 |
data-ホバー | ホバー |
〜かどうかスイッチホバーされています。 |
data-アクティブ | アクティブ |
〜かどうかスイッチアクティブまたは押された状態です。 |
data-自動フォーカス | 自動フォーカス |
|
data-変更中 | 変更中 |
チェック状態が現在変更中かどうか。
|
Label
、Description
、およびフォームコントロールをグループ化します。
プロップ | デフォルト | 説明 |
as | div | 文字列 | コンポーネント スイッチがレンダリングされる要素またはコンポーネント。フィールドとしてレンダリングする必要があります。 |
無効化 | false | ブール値 フィールドが無効化されているかどうか。 |
データ属性 | レンダープロップ | 説明 |
data-無効化 | 無効化 |
フィールドが無効化されているかどうか。 |
Label
コンポーネントはフォームコントロールにラベルを付けます。
プロップ | デフォルト | 説明 |
as | label | 文字列 | コンポーネント スイッチがレンダリングされる要素またはコンポーネント。labelとしてレンダリングする必要があります。 |
パッシブ | false | ブール値 trueの場合、ラベルをクリックしても関連付けられたフォームコントロールにフォーカスされません。 |
データ属性 | レンダープロップ | 説明 |
data-無効化 | 無効化 |
親 |
Description
コンポーネントはフォームコントロールを説明します。
プロップ | デフォルト | 説明 |
as | p | 文字列 | コンポーネント スイッチがレンダリングされる要素またはコンポーネント。説明としてレンダリングする必要があります。 |
データ属性 | レンダープロップ | 説明 |
data-無効化 | 無効化 |
親 |
事前にデザインされたTailwind CSS トグルとスイッチの例(Headless UI を使用)に興味がある場合、Tailwind UIをご覧ください。これは、私たちが作成した美しくデザインされ、専門的に作られたコンポーネントのコレクションです。
これは、このようなオープンソースプロジェクトへの私たちの取り組みを支援する素晴らしい方法であり、それらを改善し、適切に維持することを可能にします。