Basic Dropdown
A menu button with the full keyboard model - arrows, Home/End, Escape, focus restore.
6 個のフレームワーク中級
A menu that lays its items into balanced columns for scanning, on one wrapping ring.
<!--
Two columns of plain menuitems. Columns are for the eye; the arrow-key ring is
still the items flattened in reading order and wrapping. Below sm the grid
collapses to one column and the panel is capped at calc(100vw-2rem), so it
never overflows a phone.
-->
<div class="relative inline-block">
<button type="button" aria-haspopup="menu" aria-expanded="true" aria-controls="mc-menu" class="inline-flex items-center gap-1.5 rounded-lg border border-gray-300 bg-white px-3.5 py-2 text-sm font-semibold text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-900">
View
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="m6 9 6 6 6-6" /></svg>
</button>
<div id="mc-menu" role="menu" aria-label="View" class="absolute left-0 top-[calc(100%+0.375rem)] z-20 w-[min(28rem,calc(100vw-2rem))] max-w-[calc(100vw-2rem)] rounded-xl border border-gray-200 bg-white p-2 shadow-lg dark:border-gray-700 dark:bg-gray-900">
<div class="grid grid-cols-1 gap-x-2 sm:grid-cols-2">
<div role="group" aria-label="Sort by" class="min-w-0">
<p class="px-2 pb-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Sort by</p>
<button type="button" role="menuitem" class="block w-full truncate rounded-md px-2 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus-visible:bg-gray-100 focus-visible:text-gray-900 focus-visible:outline-none dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-gray-100 dark:focus-visible:bg-gray-800 dark:focus-visible:text-gray-100">Newest</button>
<button type="button" role="menuitem" class="block w-full truncate rounded-md px-2 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus-visible:bg-gray-100 focus-visible:text-gray-900 focus-visible:outline-none dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-gray-100 dark:focus-visible:bg-gray-800 dark:focus-visible:text-gray-100">Oldest</button>
</div>
<div role="group" aria-label="Filter" class="min-w-0">
<p class="px-2 pb-1 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">Filter</p>
<button type="button" role="menuitem" class="block w-full truncate rounded-md px-2 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus-visible:bg-gray-100 focus-visible:text-gray-900 focus-visible:outline-none dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-gray-100 dark:focus-visible:bg-gray-800 dark:focus-visible:text-gray-100">Active</button>
<button type="button" role="menuitem" class="block w-full truncate rounded-md px-2 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus-visible:bg-gray-100 focus-visible:text-gray-900 focus-visible:outline-none dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-gray-100 dark:focus-visible:bg-gray-800 dark:focus-visible:text-gray-100">Archived</button>
</div>
</div>
</div>
</div>| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
label必須 | string | - | 読み込み中に読み上げられるアクセシブルなラベル。 |
columns必須 | ColumnGroup[] | - | レンダリングする項目の配列。 |
onSelect | (item: string) => void | - | ユーザーが選択したメニュー項目を引数に呼ばれます。 |
The columns are for scanning; the arrow-key ring is still the items flattened in reading order and wrapping, so the keyboard behaves exactly like a single-column menu. Each column is a labelled `role="group"`. Below `sm` the grid collapses to one column and the panel is capped at `calc(100vw-2rem)`, so a long list never pushes off a phone screen.