Drawer
Drawers support persistent navigation or supplementary content pinned to the left or right edge of the screen.
Overview
Drawers are panels that provide supplementary content alongside the main application interface. They can appear on the left or right side of the screen and serve various purposes including navigation, filtering, and displaying detailed information. Drawers help organize content hierarchically while maintaining focus on the primary interface.
The drawer component supports multiple interaction patterns—from persistent navigation panels on desktop to modal overlays on mobile—making them versatile for both primary navigation and contextual content display. They maintain consistent positioning and elevation relationships with the main content while providing smooth transitions and appropriate accessibility features.
Usage
forge-drawer pins persistent navigation or supplementary content to an edge through open and direction, and slots into a forge-scaffold’s side slots. Use a plain drawer when it should stay visible and dismissible by choice, forge-mini-drawer when it should collapse to a narrow icon rail, and forge-modal-drawer when it should overlay the page with a backdrop instead of sharing space with it. For apps with fewer than five primary destinations, use tabs instead of a navigation drawer.
Rules
Basic usage
A plain drawer sits in a scaffold’s side slot alongside the main content, toggled open and closed by a menu button in the app bar.
A dismissible drawer with navigation links, inside a scaffold.
<forge-scaffold>
<forge-app-bar slot="header" title-text="Drawer Demo" elevation="raised">
<forge-app-bar-menu-button slot="start" id="menu-button">
</forge-app-bar-menu-button>
</forge-app-bar>
<forge-drawer id="drawer" slot="body-left" open direction="left">
<aside>
<forge-list navlist>
<forge-list-item selected>
<forge-icon slot="start" name="inbox">
</forge-icon>
<a href="javascript: void(0)">
Inbox
</a>
</forge-list-item>
<forge-list-item>
<forge-icon slot="start" name="send">
</forge-icon>
<a href="javascript: void(0)">
Outgoing
</a>
</forge-list-item>
<forge-list-item>
<forge-icon slot="start" name="drafts">
</forge-icon>
<a href="javascript: void(0)">
Drafts
</a>
</forge-list-item>
<forge-list-item>
<forge-icon slot="start" name="send">
</forge-icon>
<a href="javascript: void(0)">
Sent
</a>
</forge-list-item>
</forge-list>
</aside>
</forge-drawer>
<main slot="body" style="padding: 16px; background-color: var(--forge-theme-surface-dim)">
<forge-card>
Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</forge-card>
</main>
</forge-scaffold>
<script type="module">
import { IconRegistry } from "@tylertech/forge/icon";
import { tylIconDrafts, tylIconInbox, tylIconMenu, tylIconSend } from "@tylertech/tyler-icons";
IconRegistry.define([tylIconDrafts, tylIconInbox, tylIconMenu, tylIconSend]);
const menuButton = document.getElementById("menu-button");
const drawer = document.getElementById("drawer");
menuButton?.addEventListener("click", () => {
drawer.open = !drawer.open;
});
</script>Mini drawer
forge-mini-drawer collapses to a narrow icon rail and optionally expands to full width on pointer hover — use it on desktop when the main content needs the extra width a full drawer would take. Hover-to-expand is a pointer-only affordance and isn’t available on touch devices.
A mini drawer collapsed to an icon rail, with tooltips labeling each item.
<forge-scaffold>
<forge-app-bar slot="header" title-text="Drawer Demo" elevation="raised">
<forge-app-bar-menu-button slot="start" id="menu-button">
</forge-app-bar-menu-button>
</forge-app-bar>
<forge-mini-drawer id="mini-drawer" slot="body-left" open direction="left">
<aside>
<forge-list navlist>
<forge-list-item selected id="tooltip-host-1">
<forge-tooltip anchor="tooltip-host-1" aria-hidden>
Inbox
</forge-tooltip>
<forge-icon slot="start" name="inbox">
</forge-icon>
<a href="javascript: void(0)">
Inbox
</a>
</forge-list-item>
<forge-list-item id="tooltip-host-2">
<forge-tooltip anchor="tooltip-host-2" aria-hidden>
Sent
</forge-tooltip>
<forge-icon slot="start" name="send">
</forge-icon>
<a href="javascript: void(0)">
Sent
</a>
</forge-list-item>
<forge-list-item id="tooltip-host-3">
<forge-tooltip anchor="tooltip-host-3" aria-hidden>
Drafts
</forge-tooltip>
<forge-icon slot="start" name="drafts">
</forge-icon>
<a href="javascript: void(0)">
Drafts
</a>
</forge-list-item>
</forge-list>
</aside>
</forge-mini-drawer>
<main slot="body" style="padding: 16px; background-color: var(--forge-theme-surface-dim)">
<forge-card>
Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</forge-card>
</main>
</forge-scaffold>
<script type="module">
import { IconRegistry } from "@tylertech/forge/icon";
import { tylIconDrafts, tylIconInbox, tylIconMenu, tylIconSend } from "@tylertech/tyler-icons";
IconRegistry.define([tylIconDrafts, tylIconInbox, tylIconMenu, tylIconSend]);
const menuButton = document.getElementById("menu-button");
const drawer = document.getElementById("mini-drawer");
menuButton?.addEventListener("click", () => {
drawer.open = !drawer.open;
});
</script>Modal drawer
forge-modal-drawer slides in over the page with a backdrop instead of sharing space with the content — typically used at tablet and mobile widths in place of a dismissible drawer.
A modal drawer overlaying the page with a backdrop.
<forge-scaffold>
<forge-app-bar slot="header" title-text="Modal Drawer Demo" elevation="raised">
<forge-app-bar-menu-button slot="start" id="menu-button">
</forge-app-bar-menu-button>
</forge-app-bar>
<forge-modal-drawer id="modal-drawer" slot="left" direction="left">
<aside>
<forge-list navlist>
<forge-list-item selected>
<forge-icon slot="start" name="inbox">
</forge-icon>
<a href="javascript: void(0)">
Inbox
</a>
</forge-list-item>
<forge-list-item>
<forge-icon slot="start" name="send">
</forge-icon>
<a href="javascript: void(0)">
Outgoing
</a>
</forge-list-item>
<forge-list-item indented>
<a href="javascript: void(0)">
Pending
</a>
</forge-list-item>
<forge-list-item>
<forge-icon slot="start" name="drafts">
</forge-icon>
<a href="javascript: void(0)">
Drafts
</a>
</forge-list-item>
<forge-list-item>
<forge-icon slot="start" name="send">
</forge-icon>
<a href="javascript: void(0)">
Sent
</a>
</forge-list-item>
</forge-list>
</aside>
</forge-modal-drawer>
<main slot="body" class="p-medium">
<forge-card>
Lorem ipsum dolor sit amet, consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</forge-card>
</main>
</forge-scaffold>
<script type="module">
import { IconRegistry } from "@tylertech/forge/icon";
import { tylIconDrafts, tylIconInbox, tylIconMenu, tylIconSend } from "@tylertech/tyler-icons";
IconRegistry.define([tylIconDrafts, tylIconInbox, tylIconMenu, tylIconSend]);
const menuButton = document.getElementById("menu-button");
const drawer = document.getElementById("modal-drawer");
menuButton?.addEventListener("click", () => {
drawer.open = !drawer.open;
});
</script>A persistent side navigation drawer component that provides the ability to dismiss and open the drawer with smooth animations. Use for navigation or to display additional content alongside the main application content.
import "@tylertech/forge/drawer";| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
open | open | boolean | false | Toggles whether the drawer is visible or not. |
direction | direction | DrawerDirection | "left" | Controls the layout and animation direction of the drawer for positioning on the left vs. right side of the screen when toggling the `open` attribute. |
| Name | Type | Description |
|---|---|---|
forge-drawer-after-open | CustomEvent<void> | Dispatched after the drawer has opened. |
forge-drawer-after-close | CustomEvent<void> | Dispatched after the drawer has closed. |
| Name | Description |
|---|---|
(default) | The content to display in the scrollable content container. |
header | The header content above the main content. |
footer | The footer content below the main content. |
| Name | Description |
|---|---|
::part(root) | The component's root element. |
::part(content) | The content container element. |
| Name | Description |
|---|---|
--forge-drawer-width | The width of the drawer. |
--forge-drawer-background | The background color of the drawer. |
--forge-drawer-border-color | The border of the drawer. |
--forge-drawer-border-width | The border width of the drawer. |
--forge-drawer-transition-duration | The transition duration of the drawer. |
--forge-drawer-transition-easing | The transition timing function of the drawer. |
--forge-drawer-duration-close | The duration of the drawer closing animation. |
Screen reader behavior
forge-drawer does not provide any semantics by default, in any of its variants (permanent, dismissible, or mini). Provide your own <aside> element when the drawer holds navigation, or the appropriate ARIA role for whatever else it contains — the component won’t infer this for you.