Sidebar with submenus as dropdowns
A sidebar with submenus as dropdowns.
Preview
Built with
The components this screen renders, through their own templates. Changing one of them, or a token they read, changes this screen.
Design system gaps
What the design system lacks to render the original as it is. The screen fills each gap with native HTML on semantic tokens until a component or a token covers it.
- Collapsing the sidebar (off canvas or to an icon rail) has no pattern without script yet.
- The sidebar navigation (groups, items, sub-items, current item) is native HTML on semantic tokens: there is no Navigation component yet.
- Each submenu is a Dropdown whose trigger is a Button sized to its label, ending with the Dropdown's expand icon: it cannot span the sidebar row or show the "More" icon at its end.
- The Dropdown menu always opens below its trigger: it has no placement option to open to the right of the sidebar as the original does.
- The Card has no content part: the opt-in form is placed inside the Card root after its title and description.
Changes from the original
- The sidebar does not collapse (that needs script, and so does the trigger button): it is always expanded on wide screens and stacks above the content on narrow ones. The sidebar trigger and its separator are dropped.
- The rail that resizes the sidebar is dropped.
- The email field of the opt-in form shows its "Email" label (the original only has a placeholder), and the browser requires a value before subscribing.
- Rebuilt as static HTML with the design system's component templates; every color, type style, radius, border and spacing comes from its tokens.
- The original visual design (Tailwind classes, the Geist font) is not reused.
- Lucide and Tabler icons are remapped to Material Symbols; brand logos (Apple, Google, GitHub, Meta) are dropped, the buttons keep their text.
- Placeholder images are drawn with semantic tokens.
- No script: behaviour that needs JavaScript (collapsing the sidebar, toasts, drag and drop, client-side tables) is dropped or simplified, and each screen says so.
Code
The HTML the screen renders, from apps/docs/screens/shadcn-ui/sidebar-06.screen.mjs, with the stylesheets of @quantum-ds/tokens, the reference implementation (packages/components/src/) and apps/docs/screens/screens.css.
HTML
<div class="scr-viewport">
<div class="scr-screen">
<div class="scr-shell" data-variant="sidebar" data-side="left">
<nav class="scr-sidebar" aria-label="Documentation">
<div class="scr-sidebar__header">
<a class="scr-identity scr-home" href="#">
<span class="scr-tile-mark">
<span
class="ds-icon"
data-size="small"
data-color="current"
aria-hidden="true"
>view_agenda</span>
</span>
<span class="scr-identity__text">
<span class="scr-identity__title">Documentation</span>
<span class="scr-identity__subtitle">v1.0.0</span>
</span>
</a>
</div>
<div class="scr-sidebar__content">
<div class="scr-nav-group">
<ul class="scr-nav">
<li class="scr-nav__item">
<div class="ds-dropdown">
<button
type="button"
class="ds-button ds-dropdown__trigger"
data-emphasis="ghost"
data-intent="neutral"
data-size="small"
data-part="trigger"
id="sidebar-06-menu-0-trigger"
popovertarget="sidebar-06-menu-0"
>
<span
class="ds-button__label"
data-part="label"
>Getting Started</span>
<span
class="ds-button__icon"
data-part="icon"
data-position="end"
aria-hidden="true"
>expand_more</span>
</button>
<div
class="ds-dropdown__menu"
data-part="menu"
id="sidebar-06-menu-0"
popover
aria-labelledby="sidebar-06-menu-0-trigger"
>
<ul class="ds-dropdown__group" data-part="group">
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Installation</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Project Structure</span>
</a>
</li>
</ul>
</div>
</div>
</li>
<li class="scr-nav__item">
<div class="ds-dropdown">
<button
type="button"
class="ds-button ds-dropdown__trigger"
data-emphasis="ghost"
data-intent="neutral"
data-size="small"
data-part="trigger"
id="sidebar-06-menu-1-trigger"
popovertarget="sidebar-06-menu-1"
>
<span
class="ds-button__label"
data-part="label"
>Build Your Application</span>
<span
class="ds-button__icon"
data-part="icon"
data-position="end"
aria-hidden="true"
>expand_more</span>
</button>
<div
class="ds-dropdown__menu"
data-part="menu"
id="sidebar-06-menu-1"
popover
aria-labelledby="sidebar-06-menu-1-trigger"
>
<ul class="ds-dropdown__group" data-part="group">
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Routing</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Data Fetching</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Rendering</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Caching</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Styling</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Optimizing</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Configuring</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Testing</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Authentication</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Deploying</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Upgrading</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Examples</span>
</a>
</li>
</ul>
</div>
</div>
</li>
<li class="scr-nav__item">
<div class="ds-dropdown">
<button
type="button"
class="ds-button ds-dropdown__trigger"
data-emphasis="ghost"
data-intent="neutral"
data-size="small"
data-part="trigger"
id="sidebar-06-menu-2-trigger"
popovertarget="sidebar-06-menu-2"
>
<span
class="ds-button__label"
data-part="label"
>API Reference</span>
<span
class="ds-button__icon"
data-part="icon"
data-position="end"
aria-hidden="true"
>expand_more</span>
</button>
<div
class="ds-dropdown__menu"
data-part="menu"
id="sidebar-06-menu-2"
popover
aria-labelledby="sidebar-06-menu-2-trigger"
>
<ul class="ds-dropdown__group" data-part="group">
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Components</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>File Conventions</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Functions</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>next.config.js Options</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>CLI</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Edge Runtime</span>
</a>
</li>
</ul>
</div>
</div>
</li>
<li class="scr-nav__item">
<div class="ds-dropdown">
<button
type="button"
class="ds-button ds-dropdown__trigger"
data-emphasis="ghost"
data-intent="neutral"
data-size="small"
data-part="trigger"
id="sidebar-06-menu-3-trigger"
popovertarget="sidebar-06-menu-3"
>
<span
class="ds-button__label"
data-part="label"
>Architecture</span>
<span
class="ds-button__icon"
data-part="icon"
data-position="end"
aria-hidden="true"
>expand_more</span>
</button>
<div
class="ds-dropdown__menu"
data-part="menu"
id="sidebar-06-menu-3"
popover
aria-labelledby="sidebar-06-menu-3-trigger"
>
<ul class="ds-dropdown__group" data-part="group">
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Accessibility</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Fast Refresh</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Next.js Compiler</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Supported Browsers</span>
</a>
</li>
<li>
<a
class="ds-dropdown__item"
data-part="item"
data-intent="neutral"
href="#"
>
<span
class="ds-dropdown__item-label"
data-part="item-label"
>Turbopack</span>
</a>
</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="scr-sidebar__footer">
<div class="ds-card" data-surface="level-1">
<h2
class="ds-card__title"
data-part="title"
>Subscribe to our newsletter</h2>
<p
class="ds-card__description"
data-part="description"
>Opt-in to receive updates and news about the sidebar.</p>
<form class="scr-form" action="#" method="post">
<div class="scr-stack">
<div class="ds-text-field" data-size="small">
<label
class="ds-text-field__label"
data-part="label"
for="sidebar-06-email"
>Email</label>
<input
type="text"
class="ds-text-field__control"
data-part="control"
id="sidebar-06-email"
name="email"
placeholder="Email"
required
autocomplete="email"
inputmode="email"
>
</div>
<button
type="submit"
class="ds-button"
data-emphasis="accent"
data-intent="neutral"
data-size="small"
>
<span
class="ds-button__label"
data-part="label"
>Subscribe</span>
</button>
</div>
</form>
</div>
</div>
</nav>
<div class="scr-main">
<header class="scr-header">
<nav
class="ds-breadcrumb"
aria-label="Breadcrumb"
data-size="small"
>
<ol class="ds-breadcrumb__list" data-part="list">
<li class="ds-breadcrumb__item" data-part="item">
<a
class="ds-breadcrumb__link"
data-part="link"
href="#"
>Build Your Application</a>
<span
class="ds-breadcrumb__separator"
data-part="separator"
aria-hidden="true"
>chevron_right</span>
</li>
<li class="ds-breadcrumb__item" data-part="item">
<span
class="ds-breadcrumb__link"
data-part="link"
aria-current="page"
>Data Fetching</span>
</li>
</ol>
</nav>
</header>
<main class="scr-content">
<h1 class="scr-sr">Data Fetching</h1>
<div class="scr-stack" aria-hidden="true">
<div class="scr-tiles">
<div class="scr-tile"></div>
<div class="scr-tile"></div>
<div class="scr-tile"></div>
</div>
<div class="scr-tile" data-size="large"></div>
</div>
</main>
</div>
</div>
</div>
</div>