Qure UI
Components

Header Bar

Something to go back with, a title, and the actions for the whole thing.

CT chest — ACC-482913

'use client'import { ArrowLeftIcon, MoreHorizontalIcon, PencilIcon, SearchIcon } from 'lucide-react'import { Button } from '@/registry/qure/ui/button'import { HeaderBar, HeaderBarActions, HeaderBarTitle } from '@/registry/qure/ui/header-bar'export default function HeaderBarDemo() {  return (    <HeaderBar divider className="max-w-xl rounded-md border">      <Button variant="tertiary" size="md">        <ArrowLeftIcon />        Back      </Button>      <HeaderBarTitle>CT chest — ACC-482913</HeaderBarTitle>      <HeaderBarActions>        <Button variant="tertiary" size="icon-md" aria-label="Search this study">          <SearchIcon />        </Button>        <Button variant="tertiary" size="icon-md" aria-label="Edit report">          <PencilIcon />        </Button>        <Button variant="tertiary" size="icon-md" aria-label="More actions">          <MoreHorizontalIcon />        </Button>      </HeaderBarActions>    </HeaderBar>  )}

Installation

npx shadcn@latest add https://qure-ui.qure.ai/r/header-bar.json

Usage

import {
  HeaderBar, HeaderBarActions, HeaderBarContent,
  HeaderBarDescription, HeaderBarTitle,
} from '@/components/ui/header-bar'
<HeaderBar divider>
  <Button variant="tertiary"><ArrowLeftIcon />Back</Button>
  <HeaderBarTitle>CT chest — ACC-482913</HeaderBarTitle>
  <HeaderBarActions>
    <Button variant="tertiary" size="icon-md" aria-label="More actions">
      <MoreHorizontalIcon />
    </Button>
  </HeaderBarActions>
</HeaderBar>

This is one of the components with no shadcn equivalent. It comes from the Qure design system.

Figma's axis has four values — large, medium, dialogue, notification — but only two of them are a different bar. dialogue and notification are the medium bar in a modal; they say where it is used, not what it is. So the prop here is size, and the modal frames become compositions rather than variants.

Composition

<HeaderBar>              {/* owns size, background and the optional divider */}
  {/* leading — a back button, a close, or nothing */}
  <HeaderBarContent>     {/* only needed when there is a description */}
    <HeaderBarTitle>
    <HeaderBarDescription>
  </HeaderBarContent>
  <HeaderBarActions>     {/* trailing icon buttons */}
</HeaderBar>

The leading slot is deliberately not a component. What goes there is a back button, a close button, an avatar or nothing at all, and wrapping that in a HeaderBarLeading would only add a name for a <div> you did not need.

Size

lg

Reporting queue

md

Reporting queue

'use client'import { ArrowLeftIcon, MoreHorizontalIcon } from 'lucide-react'import { Button } from '@/registry/qure/ui/button'import { HeaderBar, HeaderBarActions, HeaderBarTitle } from '@/registry/qure/ui/header-bar'export default function HeaderBarSize() {  return (    <div className="flex w-full max-w-xl flex-col gap-5">      {(['lg', 'md'] as const).map(size => (        <div key={size} className="flex flex-col gap-1">          <code className="text-label-base text-muted-foreground">{size}</code>          <HeaderBar size={size} divider className="rounded-md border">            <Button variant="tertiary" size={size === 'lg' ? 'md' : 'sm'}>              <ArrowLeftIcon />              Back            </Button>            <HeaderBarTitle>Reporting queue</HeaderBarTitle>            <HeaderBarActions>              <Button                variant="tertiary"                size={size === 'lg' ? 'icon-md' : 'icon-sm'}                aria-label="More actions"              >                <MoreHorizontalIcon />              </Button>            </HeaderBarActions>          </HeaderBar>        </div>      ))}    </div>  )}

lg is a whole page or the top of a drawer, with the title in Heading. md is a panel, a section or a modal, with the title in Subheading. Match the button sizes to the bar — md buttons in the large bar, sm in the medium one.

With a description

Kaur, Rupinder

PT-40192 · 61F · 4 studies, 2 unread

'use client'import { XIcon } from 'lucide-react'import { Button } from '@/registry/qure/ui/button'import {  HeaderBar, HeaderBarActions, HeaderBarContent, HeaderBarDescription, HeaderBarTitle,} from '@/registry/qure/ui/header-bar'/** * A second line, for the thing the title cannot fit. `HeaderBarContent` is * what stacks them and keeps them sharing the flexible width, so a long title * truncates instead of shoving the actions off the end. */export default function HeaderBarDescription_() {  return (    <HeaderBar size="md" divider className="max-w-xl rounded-md border">      <HeaderBarContent>        <HeaderBarTitle>Kaur, Rupinder</HeaderBarTitle>        <HeaderBarDescription>PT-40192 · 61F · 4 studies, 2 unread</HeaderBarDescription>      </HeaderBarContent>      <HeaderBarActions>        <Button variant="tertiary" size="icon-sm" aria-label="Close">          <XIcon />        </Button>      </HeaderBarActions>    </HeaderBar>  )}

HeaderBarContent stacks the title and its second line and keeps them sharing the flexible width, so a long title truncates rather than shoving the actions off the end. Without a description you do not need it — put HeaderBarTitle straight in the bar.

Heading level

Worklist

Priors

'use client'import { HeaderBar, HeaderBarTitle } from '@/registry/qure/ui/header-bar'/** * The title is an `h2` by default, because a bar is rarely the top of the * document. `render` moves it to wherever it belongs in the outline — a page * header wants `h1`, a panel nested in one may want `h3`. */export default function HeaderBarHeading() {  return (    <div className="flex w-full max-w-xl flex-col gap-4">      <HeaderBar divider className="rounded-md border">        <HeaderBarTitle render={<h1 />}>Worklist</HeaderBarTitle>      </HeaderBar>      <HeaderBar size="md" divider className="rounded-md border">        <HeaderBarTitle render={<h3 />}>Priors</HeaderBarTitle>      </HeaderBar>    </div>  )}

The title renders an <h2>, because a bar is rarely the top of the document. render moves it:

<HeaderBarTitle render={<h1 />}>Worklist</HeaderBarTitle>

Get this right rather than leaving it. A screen reader user navigates by heading, and a page whose outline starts at h2 and then skips to h4 is a page they have to read in full to understand the shape of.

Building a modal

The Figma "Modal — Dialogue / Notification / Interactive" frames are not components. Each is a header bar, a body and an Action Bar at one of four widths:

FrameWidthSurface
Dialogue360pxbase-secondary
Notification480pxbase-default
Interactive520pxbase-secondary
Navigation840×560a rail beside a panel

There is a worked example of each: the first three on the Action Bar page, and Navigation on the Dialog page.

Size a Dialog with max-w-* on DialogContent and compose the bars inside it. There is a worked example on the Action Bar page.

API Reference

HeaderBar

Renders a <header>.

PropTypeDefaultDescription
size"lg" | "md""lg"Page or drawer, versus panel or modal.
dividerbooleanfalseA 0.5px hairline along the bottom edge.

HeaderBarTitle

PropTypeDefaultDescription
renderReactElement<h2 />Change the heading level to fit the outline.

HeaderBarContent and HeaderBarActions render <div>s, HeaderBarDescription a <p>.

On this page