ドロワーは、オーバーレイとして表示されるコンテナコンポーネントです。
import Drawer from 'primevue/drawer';
ドロワーはコンテナとして使用され、可視性は *visible* へのバインディングによって制御されます。
<div class="card flex justify-center">
<Drawer v-model:visible="visible" header="Drawer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
<Button icon="pi pi-arrow-right" @click="visible = true" />
</div>
ドロワーの位置は、有効な値として *left*、*right*、*top*、*bottom* を取ることができる *position* プロパティで設定されます。
<div class="flex gap-2 justify-center">
<Button icon="pi pi-arrow-right" @click="visibleLeft = true" />
<Button icon="pi pi-arrow-left" @click="visibleRight = true" />
<Button icon="pi pi-arrow-down" @click="visibleTop = true" />
<Button icon="pi pi-arrow-up" @click="visibleBottom = true" />
</div>
<Drawer v-model:visible="visibleLeft" header="Left Drawer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
<Drawer v-model:visible="visibleRight" header="Right Drawer" position="right">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
<Drawer v-model:visible="visibleTop" header="Top Drawer" position="top" style="height: auto">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
<Drawer v-model:visible="visibleBottom" header="Bottom Drawer" position="bottom" style="height: auto">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
ドロワーの寸法は、*style* または *class* プロパティで定義できます。このレスポンシブな例では、Tailwindを使用しています。
<div class="card flex justify-center">
<Drawer v-model:visible="visible" header="Drawer" class="!w-full md:!w-80 lg:!w-[30rem]">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
<Button icon="pi pi-arrow-right" @click="visible = true" />
</div>
*position* プロパティが *full* に設定されている場合、ページ全体が覆われます。
<div class="card flex justify-center">
<Drawer v-model:visible="visible" header="Drawer" position="full">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</Drawer>
<Button icon="pi pi-window-maximize" @click="visible = true" />
</div>
ヘッダーとフッターセクションのカスタムコンテンツは、テンプレートを使用して表示されます。
<Drawer v-model:visible="visible">
<template #header>
<div class="flex items-center gap-2">
<Avatar image="/images/avatar/amyelsner.png" shape="circle" />
<span class="font-bold">Amy Elsner</span>
</div>
</template>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<template #footer>
<div class="flex items-center gap-2">
<Button label="Account" icon="pi pi-user" class="flex-auto" outlined></Button>
<Button label="Logout" icon="pi pi-sign-out" class="flex-auto" severity="danger" text></Button>
</div>
</template>
</Drawer>
<Button icon="pi pi-plus" @click="visible = true" />
ヘッドレスモードは、デフォルト要素の代わりにUI全体を実装できる *container* スロットを定義することで有効になります。
<Drawer v-model:visible="visible">
<template #container="{ closeCallback }">
<div class="flex flex-col h-full">
<div class="flex items-center justify-between px-6 pt-4 shrink-0">
<span class="inline-flex items-center gap-2">
<svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="..." fill="var(--p-primary-color)" />
<path d="..." fill="var(--p-text-color)" />
</svg>
<span class="font-semibold text-2xl text-primary">Your Logo</span>
</span>
<span>
<Button type="button" @click="closeCallback" icon="pi pi-times" rounded outlined></Button>
</span>
</div>
<div class="overflow-y-auto">
<ul class="list-none p-4 m-0">
<li>
<div
v-ripple
v-styleclass="{
selector: '@next',
enterFromClass: 'hidden',
enterActiveClass: 'animate-slidedown',
leaveToClass: 'hidden',
leaveActiveClass: 'animate-slideup'
}"
class="p-4 flex items-center justify-between text-surface-500 dark:text-surface-400 cursor-pointer p-ripple"
>
<span class="font-medium">FAVORITES</span>
<i class="pi pi-chevron-down"></i>
</div>
<ul class="list-none p-0 m-0 overflow-hidden">
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-home mr-2"></i>
<span class="font-medium">Dashboard</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-bookmark mr-2"></i>
<span class="font-medium">Bookmarks</span>
</a>
</li>
<li>
<a
v-ripple
v-styleclass="{
selector: '@next',
enterFromClass: 'hidden',
enterActiveClass: 'animate-slidedown',
leaveToClass: 'hidden',
leaveActiveClass: 'animate-slideup'
}"
class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple"
>
<i class="pi pi-chart-line mr-2"></i>
<span class="font-medium">Reports</span>
<i class="pi pi-chevron-down ml-auto"></i>
</a>
<ul class="list-none py-0 pl-4 pr-0 m-0 hidden overflow-y-hidden transition-all duration-[400ms] ease-in-out">
<li>
<a
v-ripple
v-styleclass="{
selector: '@next',
enterFromClass: 'hidden',
enterActiveClass: 'animate-slidedown',
leaveToClass: 'hidden',
leaveActiveClass: 'animate-slideup'
}"
class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple"
>
<i class="pi pi-chart-line mr-2"></i>
<span class="font-medium">Revenue</span>
<i class="pi pi-chevron-down ml-auto"></i>
</a>
<ul class="list-none py-0 pl-4 pr-0 m-0 hidden overflow-y-hidden transition-all duration-[400ms] ease-in-out">
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-table mr-2"></i>
<span class="font-medium">View</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-search mr-2"></i>
<span class="font-medium">Search</span>
</a>
</li>
</ul>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-chart-line mr-2"></i>
<span class="font-medium">Expenses</span>
</a>
</li>
</ul>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-users mr-2"></i>
<span class="font-medium">Team</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-comments mr-2"></i>
<span class="font-medium">Messages</span>
<span class="inline-flex items-center justify-center ml-auto bg-primary text-primary-contrast rounded-full" style="min-width: 1.5rem; height: 1.5rem">3</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-calendar mr-2"></i>
<span class="font-medium">Calendar</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-cog mr-2"></i>
<span class="font-medium">Settings</span>
</a>
</li>
</ul>
</li>
</ul>
<ul class="list-none p-4 m-0">
<li>
<div
v-ripple
v-styleclass="{
selector: '@next',
enterFromClass: 'hidden',
enterActiveClass: 'animate-slidedown',
leaveToClass: 'hidden',
leaveActiveClass: 'animate-slideup'
}"
class="p-4 flex items-center justify-between text-surface-500 dark:text-surface-400 cursor-pointer p-ripple"
>
<span class="font-medium">APPLICATION</span>
<i class="pi pi-chevron-down"></i>
</div>
<ul class="list-none p-0 m-0 overflow-hidden">
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-folder mr-2"></i>
<span class="font-medium">Projects</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-chart-bar mr-2"></i>
<span class="font-medium">Performance</span>
</a>
</li>
<li>
<a v-ripple class="flex items-center cursor-pointer p-4 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<i class="pi pi-cog mr-2"></i>
<span class="font-medium">Settings</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="mt-auto">
<hr class="mb-4 mx-4 border-t border-0 border-surface-200 dark:border-surface-700" />
<a v-ripple class="m-4 flex items-center cursor-pointer p-4 gap-2 rounded text-surface-700 hover:bg-surface-100 dark:text-surface-0 dark:hover:bg-surface-800 duration-150 transition-colors p-ripple">
<Avatar image="/images/avatar/amyelsner.png" shape="circle" />
<span class="font-bold">Amy Elsner</span>
</a>
</div>
</div>
</template>
</Drawer>
<Button icon="pi pi-bars" @click="visible = true" />
ドロワーコンポーネントは、デフォルトで *complementary* ロールを使用します。属性がルート要素に渡されるため、ariaロールはユースケースに応じて変更でき、*aria-labelledby* などの追加属性を追加できます。さらに、開いたときにフォーカスがドロワー内に保持されるため、*aria-modal* が追加されます。
トリガー要素では、*aria-expanded* と *aria-controls* を明示的に処理する必要があります。
<Button label="Show" icon="pi pi-external-link" @click="visible = true" :aria-controls="visible ? 'sbar' : null" :aria-expanded="visible"/>
<Drawer id="sbar" v-model:visible="visible" role="region" >
<p>Content</p>
</Drawer>
キー | 機能 |
---|---|
tab | ドロワー内の次のフォーカス可能な要素にフォーカスを移動します。 |
*shift* + *tab* | ドロワー内の前のフォーカス可能な要素にフォーカスを移動します。 |
escape | ダイアログを閉じます。 |
キー | 機能 |
---|---|
enter | ドロワーを閉じます。 |
space | ドロワーを閉じます。 |