Popover
トリガーにアンカーされたフローティングパネル。コンテンツに合わせてなめらかにサイズが変わり、トリガーの方向に従います。
pnpm dlx shadcn@latest add https://hextaui.com/r/popover.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @base-ui/react cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/popover.tsx インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
サイズが変わるコンテンツ
コンテンツが増減すると、ポップアップはジャンプせず高さをアニメーションさせます。入力のような連続的な変化は、遅れが出ないようコンテンツに直接追従します。
制御
自前の状態で制御するには、open と onOpenChange を渡します。第2引数は、trigger-press、outside-press、escape-key のように、変化した理由を伝えます。
配置
side と align は希望する位置を設定します。空間がない場合、ポップアップは反対側に反転し、画面内に収まるようにずれて、端から8pxを保ちます。
ホバーで開く
プレビューカードにするには、トリガーに openOnHover を設定します。delay と closeDelay により、ポインターが通り過ぎるときのちらつきを防ぎます。
分離したトリガー
createPopoverHandle でハンドルを作ると、ツリー内のどこにある複数のトリガー間でも1つの popover を共有できます。各トリガーは payload を渡し、ポップアップは関数の子要素を通じてそれを描画します。
カレンダー付き
独自のパディングを持つコンテンツに合わせるには、className="w-auto p-0" を使います。ポップアップは、月が変わるたびにカレンダーに追従します。
入れ子
別の popover や sheet の内側にある popover は、親の上に重なります。子の内側でのクリックでは親は開いたままで、Escape は最上位のレイヤーだけを閉じます。
長いコンテンツ
区切りのないテキストはポップアップ内で折り返されます。コンテンツが利用可能な空間より高い場合は、画面からはみ出さず、ポップアップ内でスクロールします。
モーダル
modal を指定すると、ページのスクロールがロックされ、外側のクリックは popover を閉じるだけになります。フォーカスをトラップでき、タッチ操作のスクリーンリーダーが抜け出せるよう、内側に <PopoverClose /> を描画してください。
無効
disabled のトリガーは popover を開きません。
右から左
ポップアップはポータルに描画されても、開いたトリガーの方向を引き継ぎます。inline-end のような論理的な側も一緒に反転します。
| キー | アクション |
|---|---|
| EnterSpace | トリガー上では popover を開閉します。フォーカスはポップアップ内に移ります。 |
| Tab | ポップアップの内容の中を移動します。モーダルでない popover からタブで外へ出ると閉じます。 |
| Esc | popover を閉じ、トリガーにフォーカスを戻します。 |
<PopoverTitle />と<PopoverDescription />は、スクリーンリーダー向けにポップアップのラベルと説明を提供します。ポップアップに1文より長い内容が入る場合は、必ずタイトルを含めてください。- 開くと最初のフォーカス可能な要素にフォーカスが移り、閉じるとトリガーに戻ります。これは
initialFocusとfinalFocusで変更できます。 - 視差効果の軽減が有効な場合、ポップアップは拡大せずにフェードします。
Base UI の popover 上に構築されています。すべてのパーツは、ラップしているプリミティブの props を受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
defaultOpen | boolean | false |
open | boolean | – |
onOpenChangedetails.reason は、変更の原因を示します。 | (open: boolean, details) => void | – |
onOpenChangeComplete開閉アニメーションの終了後に呼ばれます。 | (open: boolean) => void | – |
modaltrue はページのスクロールと外部操作をロックします。trap-focus はフォーカスのトラップだけを行います。 | boolean | "trap-focus" | false |
handle分離したトリガーを接続します。 | PopoverHandle<Payload> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
openOnHover | boolean | false |
delayホバーしてから開くまでのミリ秒。 | number | 300 |
closeDelayホバーが終わってから閉じるまでのミリ秒。 | number | 0 |
handle | PopoverHandle<Payload> | – |
payloadこのトリガーが開いたときに、ポップアップへ渡されます。 | Payload | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="popover-trigger" | CSSでトリガーを指定します。 |
data-popup-open | その popover が開いている間付きます。 |
data-pressed | トリガーが押されている間存在します。 |
data-disabled | トリガーが無効なときに付与されます。 |
ポータル、ポジショナー、ポップアップを1つのパーツで描画します。
| プロパティ | 型 | デフォルト |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end" | "bottom" |
align | "start" | "center" | "end" | "center" |
sideOffsetトリガーとポップアップの間隔。 | number | (data) => number | 6 |
alignOffset | number | (data) => number | 0 |
collisionPaddingビューポートの端から保つ余白。 | number | Rect | 8 |
collisionAvoidance空間が足りないときに、反転するか、ずらすか、どちらもしないか。 | CollisionAvoidance | – |
collisionBoundary | Boundary | – |
anchorトリガー以外のものを基準に配置します。 | Element | RefObject | VirtualElement | () => Element | – |
sticky | boolean | false |
positionMethod | "absolute" | "fixed" | "absolute" |
initialFocuspopover が開いたときにフォーカスが移る先。 | boolean | RefObject | (type) => HTMLElement | boolean | – |
finalFocuspopover が閉じたときにフォーカスが移る先。 | boolean | RefObject | (type) => HTMLElement | boolean | – |
portalPropscontainer など、ポータル用の props。 | PortalProps | – |
classNameポップアップはデフォルトで w-72 です。 | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| 属性 | 説明 |
|---|---|
data-slot="popover-content" | ポップアップ。 |
data-slot="popover-positioner" | ポップアップの位置を決める要素。 |
data-open | popover が開いている間付きます。 |
data-starting-style | ポップアップが表示アニメーション中に付きます。 |
data-ending-style | ポップアップが非表示アニメーション中に付きます。 |
data-side | ポップアップが最終的に配置された側。 |
data-align | ポップアップが最終的に取ったアラインメント。 |
data-instant | 変化をアニメーションさせないときに付きます。 |
--transform-origin | ポップアップがトリガーの位置から拡大する基点。 |
--available-width | トリガーとビューポートの端との間隔。 |
--available-height | トリガーとビューポートの端との間隔。ポップアップの最大の高さ。 |
--anchor-width | トリガーの幅。 |
--anchor-height | トリガーの高さ。 |
タイトルと説明を縦に並べるだけの <div>。
| 属性 | 説明 |
|---|---|
data-slot="popover-header" | CSSでヘッダーを指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| 属性 | 説明 |
|---|---|
data-slot="popover-title" | ポップアップにラベルを付けます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <p> |
| 属性 | 説明 |
|---|---|
data-slot="popover-description" | ポップアップを説明します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="popover-close" | 押すと popover を閉じます。 |
createPopoverHandle<Payload>() は、別の場所にレンダリングされたトリガーと <Popover /> をつなぐハンドルを返します。コンポーネントの外で一度だけ作成してください。
- Alert dialog破壊的または重要な操作のための確認ダイアログです。非同期処理を待ち、スマートフォンではボトムシートになります。
- Commandインラインまたは⌘Kパレットとして使える、検索可能な操作リストです。ページ、ショートカット、一致箇所のハイライトに対応します。
- Context menu右クリックまたは長押しで開く操作メニューです。サブメニュー、チェックボックス項目、ラジオ項目に対応し、タッチでは長押しのフィードバックを返します。
- Dialogフォームや集中して行う作業のための、ページ上のウィンドウです。固定のヘッダーとフッター、入れ子に対応し、スマートフォンではスワイプできるボトムシートになります。
- Drawer任意の端からスライドインし、指に追従するパネルです。スナップポイント、実際に使えるハンドル、重なっていく入れ子のドロワーに対応します。
- Dropdown menuボタンの背後に、操作とオプションをまとめたメニューです。グループ、サブメニュー、チェックボックス項目、ラジオ項目、ショートカットに対応します。
使用しているブロック
Popover の上に構築されるブロック。
- Prompt Input最初は静かな1行で、入力に合わせてカードへ広がり、会話が始まると下へ移動するチャット入力欄です。Enterで送信でき、日本語や中国語の入力でも安全です。ファイルは貼り付け、ドロップ、選択でき、プレビュー、進捗、再試行に対応します。@でファイルを追加し、/でコマンドをカーソル位置のメニューから実行できます。数字キーで選べるモデルピッカー、Maxで動き出す推論量スライダー、コンテキストリング、リアルタイム波形つきの音声入力、ツールチップ、返信のストリーミング中に入力したメッセージのキュー、再読み込みしても残る下書きを備えています。
- Agent Todosエージェントの作業中のプランを表示します。すべてのステップはバックログからToDo、進行中、完了へと移り、リアルタイムの所要時間、失敗、その裏にあるツール呼び出しも確認できます。コンポーザーの上に置くステータスピル、目に見えるプランの変更、実行前にプランを編集できるレビューステップを備えています。
- Diff Reviewエージェントによる編集を、反映される前にファイルをまたいで確認します。件数つきのファイルツリー、変更ごと、ファイルごと、またはすべてに対する承認と却下、任意の行や範囲に付けてエージェントへ返せるコメント、ユニファイドビューとスプリットビュー、単語単位のハイライト、取り消し、ストリーミングされる編集、チャット向けの「Edited 4 files」サマリーを備えています。
- Voice Modeアシスタントと話せます。曇り空やフェロフルイドの塊から、ディザリングされたピクセル、ASCII、CRTの惑星、ハーフトーンのドット、1つのリング、やわらかなオーラまで、音に反応する8つのスタイルと、4つのリアクティブなドットを備えています。ミュート、割り込み、字幕に対応した全画面セッション、チャット内の音声ピル、音声ピッカー、聞き取り、話し終えるのを待って返答するブラウザーエンジンも含みます。