דילוג לתוכן
uiify

Header

כותרת אתר מובנית עם שיפור גלילה אופציונלי.

דפדפנים
Chrome 123+Firefox 121+Safari 17.5+
שכבה
0
גודל חבילה דחוסה
141 B
מגבלת פריסה כפויה
0 ms
מגבלת Axe
0
תואם SSR
כן
חוזה מפורסם
סביבת בדיקות

מגרש ניסויים

Team workspace

A shared view of what you are working on.

12Active projects
4Awaiting review

Workspace overview

Keep your team's projects and recent updates in one place.

Projects

Website refresh · In progress. Design library · Ready for review.

Recent activity

The team updated the roadmap and shared a new design proposal.

Create a project

Start with a name, invite your team, and plan your next milestone.

Workspace help

Find guides for organizing projects and collaborating with your team.

Scroll inside the panel. Enable Hide on scroll to hide down and reveal up.

Team workspace

A shared view of what you are working on.

12Active projects
4Awaiting review

Workspace overview

Keep your team's projects and recent updates in one place.

Projects

Website refresh · In progress. Design library · Ready for review.

Recent activity

The team updated the roadmap and shared a new design proposal.

Create a project

Start with a name, invite your team, and plan your next milestone.

Workspace help

Find guides for organizing projects and collaborating with your team.

import { Breadcrumb, Button, Header } from "@gunkin/uiify";
import { HeaderClient } from "@gunkin/uiify/components/header/client";
import {
  ModalBody,
  ModalClose,
  ModalContent,
  ModalHeader,
  ModalTitle,
  ModalTrigger,
} from "@gunkin/uiify/components/modal";

// Native by default. Replace Header.Root with HeaderClient to hide on scroll.
// HeaderClient defaults to sticky + hideOnScroll. For a panel, pass its scrollport id.
export default function Example() {
  return (
    <>
      <Header.Root placement="sticky" className="">
        <a href="/">Logo</a>
        <nav aria-label="Workspace">
          <a href="/overview" aria-current="page">
            Overview
          </a>
          <a href="/projects">Projects</a>
          <a href="/activity">Activity</a>
        </nav>
        <ModalTrigger target="logo-navigation" className="">
          Menu
        </ModalTrigger>
        <ModalContent className="" id="logo-navigation" size="full" aria-labelledby="logo-navigation-title">
          <ModalHeader>
            <ModalTitle id="logo-navigation-title">Logo navigation</ModalTitle>
            <ModalClose target="logo-navigation" aria-label="Close navigation">
              ×
            </ModalClose>
          </ModalHeader>
          <ModalBody>
            <nav aria-label="Mobile workspace">
              <a href="/overview" aria-current="page">
                Overview
              </a>
              <a href="/projects">Projects</a>
              <a href="/activity">Activity</a>
              <a href="/help">Help</a>
              <Button as="a" href="/projects/new" variant="link" className="">
                New project
              </Button>
            </nav>
          </ModalBody>
        </ModalContent>
      </Header.Root>
      <Breadcrumb.Root className="">
        <Breadcrumb.List
          items={[
            { key: "workspace", label: "Workspace", href: "/" },
            { key: "overview", label: "Overview", current: true },
          ]}
          className=""
          slotProps={{
            item: { className: "" },
            link: { className: "" },
          }}
          separator={<Breadcrumb.Separator className="" />}
        />
      </Breadcrumb.Root>
    </>
  );
}

// Optional client entry; SSR remains visible and scroll behavior attaches after hydration.
export function ScrollHeader() {
  return (
    <HeaderClient className="">
      <a href="/">Logo</a>
      <nav aria-label="Workspace">
        <a href="/overview" aria-current="page">
          Overview
        </a>
        <a href="/projects">Projects</a>
        <a href="/activity">Activity</a>
      </nav>
    </HeaderClient>
  );
}
/* ---- Header demo (homepage card + detail playground) ---- */
.docs-header-demo {
  inline-size: 100%;
  color: var(--foreground);
  font-size: 0.82rem;
}

.docs-header-demo--playground {
  display: flex;
  flex-direction: column;
  gap: calc(var(--docs-space-unit) * 2.5);
  block-size: 100%;
  min-block-size: 0;
}

.docs-header-demo__scroll-hint {
  margin: 0;
  color: var(--muted-foreground);
  font-size: var(--docs-text-xs);
  line-height: var(--docs-leading-snug);
}

.docs-header-demo__viewport {
  container: header-demo / size;
  flex: 1;
  min-block-size: 0;
  block-size: 22rem;
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--background);
}

.docs-header-demo__viewport--mobile {
  inline-size: min(100%, 24rem);
  margin-inline: auto;
}

.docs-header-demo__viewport--desktop {
  inline-size: 100%;
}

.docs-playground__stage--header {
  display: flex;
  flex-direction: column;
  min-block-size: 26rem;
  block-size: 26rem;
  padding: calc(var(--docs-space-unit) * 4);
  overflow: hidden;
  align-items: stretch;
}

.docs-header-demo [data-uiify-header] {
  z-index: 2;
  background: var(--card);
  color: var(--card-foreground);
  border-block-end: 1px solid var(--border);
}

.docs-header-demo__bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: calc(var(--docs-space-unit) * 3);
  min-block-size: 4rem;
  padding-inline: calc(var(--docs-space-unit) * 4);
}

.docs-header-demo__brand {
  color: inherit;
  font-size: var(--docs-text-base);
  font-weight: var(--docs-weight-bold);
  text-decoration: none;
  white-space: nowrap;
}

.docs-header-demo__desktop-actions,
.docs-header-demo__nav {
  display: none;
}

.docs-header-demo__menu {
  gap: 0;
  padding: 0;
  background: var(--card);
  color: var(--card-foreground);
}

.docs-header-demo__menu-header {
  display: grid;
  grid-template-columns: 2.5rem 1fr 2.5rem;
  align-items: center;
  min-block-size: 4rem;
  padding-block: env(safe-area-inset-top) 0;
  padding-inline: env(safe-area-inset-left) env(safe-area-inset-right);
  border-block-end: 1px solid var(--border);
}

.docs-header-demo__menu-title {
  grid-column: 2;
  margin: 0;
  font-size: var(--docs-text-base);
  font-weight: var(--docs-weight-bold);
}

.docs-header-demo__menu-header .docs-header-demo__close {
  position: static;
  grid-column: 3;
  display: grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  color: inherit;
  cursor: pointer;
  font-size: var(--docs-text-2xl);
}

.docs-header-demo__actions {
  display: flex;
  align-items: center;
  gap: calc(var(--docs-space-unit) * 2);
}

.docs-header-demo__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: 2.5rem;
  padding-inline: calc(var(--docs-space-unit) * 3);
  border: 1px solid var(--primary);
  border-radius: var(--radius-md);
  background: var(--primary);
  color: var(--primary-foreground);
  font: inherit;
  font-weight: var(--docs-weight-semibold);
  gap: calc(var(--docs-space-unit) * 1.5);
  text-decoration: none;
}

.docs-header-demo__toggle {
  margin-inline-start: auto;
  background: var(--card);
  color: inherit;
  font: inherit;
  display: flex;
  align-items: center;
  gap: calc(var(--docs-space-unit) * 2.5);
  min-block-size: 2.5rem;
  padding-inline: calc(var(--docs-space-unit) * 3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  list-style: none;
}

.docs-header-demo__card-navigation {
  margin-inline-start: auto;
}

.docs-header-demo__card-menu {
  position: absolute;
  inset-block-start: 100%;
  inset-inline: 0;
  display: grid;
  gap: calc(var(--docs-space-unit) * 2);

  /* Reserve the header bar within the card viewport's 240px minimum height. */
  max-block-size: calc(240px - 4rem);
  overflow: auto;
  overscroll-behavior: contain;
  padding: calc(var(--docs-space-unit) * 2);
  border-block-end: 1px solid var(--border);
  background: var(--card);
  color: var(--card-foreground);
}

.docs-header-demo__card-menu .docs-header-demo__mobile-nav a {
  min-block-size: 2.25rem;
}

.docs-header-demo__mobile-content {
  display: flex;
  flex-direction: column;
  gap: calc(var(--docs-space-unit) * 4);
  padding-block: calc(var(--docs-space-unit) * 4)
    max(calc(var(--docs-space-unit) * 4), env(safe-area-inset-bottom));
  padding-inline: max(calc(var(--docs-space-unit) * 4), env(safe-area-inset-left))
    max(calc(var(--docs-space-unit) * 4), env(safe-area-inset-right));
}

.docs-header-demo__mobile-nav {
  display: flex;
  flex-direction: column;
}

.docs-header-demo__mobile-nav a,
.docs-header-demo__nav a,
.docs-header-demo__help {
  display: inline-flex;
  align-items: center;
  min-block-size: 2.5rem;
  padding-inline: calc(var(--docs-space-unit) * 2);
  color: inherit;
  text-decoration: none;
}

.docs-header-demo__mobile-nav [aria-current="page"],
.docs-header-demo__nav [aria-current="page"] {
  background: var(--accent);
  color: var(--accent-foreground);
  border-radius: var(--radius-sm);
  font-weight: var(--docs-weight-semibold);
}

.docs-header-demo a {
  text-decoration: none;
}

.docs-header-demo a:not(.docs-header-demo__cta):hover {
  color: var(--primary);
}

.docs-header-demo__toggle:hover {
  border-color: var(--ring);
}

.docs-header-demo :focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 3px;
}

.docs-header-demo__breadcrumb {
  padding-block: calc(var(--docs-space-unit) * 3);
  padding-inline: calc(var(--docs-space-unit) * 4);
  font-size: var(--docs-text-xs);
}

.docs-header-demo__breadcrumb ol {
  display: flex;
  gap: calc(var(--docs-space-unit) * 2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.docs-header-demo__breadcrumb li {
  display: flex;
  gap: calc(var(--docs-space-unit) * 2);
}

.docs-header-demo__breadcrumb a {
  color: var(--muted-foreground);
}

.docs-header-demo__workspace {
  padding-inline: calc(var(--docs-space-unit) * 4);
  padding-block-end: calc(var(--docs-space-unit) * 5);
}

.docs-header-demo__workspace h3 {
  line-height: var(--docs-leading-tight);
  margin-block: calc(var(--docs-space-unit) * 2);
  font-size: var(--docs-text-lg);
  font-weight: var(--docs-weight-semibold);
}

.docs-header-demo__workspace p {
  margin: 0;
  color: var(--muted-foreground);
}

.docs-header-demo__metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(var(--docs-space-unit) * 3);
  margin-block-start: calc(var(--docs-space-unit) * 4);
}

.docs-header-demo__metrics div {
  display: grid;
  gap: calc(var(--docs-space-unit) * 1);
  padding: calc(var(--docs-space-unit) * 3);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--card);
}

.docs-header-demo__metrics strong {
  font-size: var(--docs-text-xl);
  font-variant-numeric: tabular-nums;
}

.docs-header-demo__metrics span {
  color: var(--muted-foreground);
  font-size: var(--docs-text-xs);
}

.docs-header-demo__scroll-body {
  display: grid;
  gap: calc(var(--docs-space-unit) * 3);
  padding-block-end: calc(var(--docs-space-unit) * 4);
  padding-inline: calc(var(--docs-space-unit) * 4);
}

.docs-header-demo__scroll-section {
  min-block-size: 8rem;
  padding: calc(var(--docs-space-unit) * 4);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  color: var(--card-foreground);
  scroll-margin-block-start: calc(var(--docs-space-unit) * 20);
}

.docs-header-demo__scroll-section h3 {
  line-height: var(--docs-leading-tight);
  margin-block: 0 calc(var(--docs-space-unit) * 1.5);
  font-size: var(--docs-text-base);
}

.docs-header-demo__scroll-section p {
  margin: 0;
  color: var(--muted-foreground);
  line-height: var(--docs-leading-normal);
}

.docs-header-demo--card .docs-header-demo__viewport {
  inline-size: 100%;
  block-size: 100%;
  min-block-size: 240px;
  border: none;
  border-radius: 0;
}

@container header-demo (min-width: 40rem) {
  .docs-header-demo__brand {
    position: static;
    translate: none;
  }

  .docs-header-demo__desktop-actions {
    display: flex;
    align-items: center;
    gap: calc(var(--docs-space-unit) * 4);
    margin-inline-start: auto;
  }

  .docs-header-demo__toggle,
  .docs-header-demo__card-navigation {
    display: none;
  }

  .docs-header-demo__nav {
    display: flex;
    gap: calc(var(--docs-space-unit) * 0.5);
  }
}
import { Breadcrumb, Button, Header } from "@gunkin/uiify";
import { HeaderClient } from "@gunkin/uiify/components/header/client";
import {
  ModalBody,
  ModalClose,
  ModalContent,
  ModalHeader,
  ModalTitle,
  ModalTrigger,
} from "@gunkin/uiify/components/modal";

// Native by default. Replace Header.Root with HeaderClient to hide on scroll.
// HeaderClient defaults to sticky + hideOnScroll. For a panel, pass its scrollport id.
export default function Example() {
  return (
    <>
      <Header.Root
        placement="sticky"
        className="
          grid gap-md w-max max-w-[min(28rem,calc(100vw_-_2_*_var(--space-lg)))] p-6 border border-border rounded-xl
          bg-card text-card-foreground shadow-popover [&[popover]:not(:popover-open)]:hidden
          motion-safe:[&[popover]]:[transition:var(--transition-presence)]
          motion-safe:[&[popover]:not(:popover-open)]:opacity-0
          motion-safe:[&[popover]:not(:popover-open)]:[scale:var(--presence-scale)]
          motion-safe:starting:[&[popover]:popover-open]:opacity-0
          motion-safe:starting:[&[popover]:popover-open]:[scale:var(--presence-scale)]
        "
      >
        <a href="/">Logo</a>
        <nav aria-label="Workspace">
          <a href="/overview" aria-current="page">
            Overview
          </a>
          <a href="/projects">Projects</a>
          <a href="/activity">Activity</a>
        </nav>
        <ModalTrigger
          target="logo-navigation"
          className={
            "relative isolate inline-flex items-center justify-center gap-1.5 min-h-10 min-w-10 px-5 py-px border-[l" +
            "ength:var(--border-width)] border-solid border-transparent rounded-full bg-clip-padding text-base font-" +
            "medium leading-6 no-underline cursor-pointer [transition:var(--transition-colors)] focus-visible:[outli" +
            "ne:none] focus-visible:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_20%,_transpa" +
            "rent)] disabled:opacity-50 disabled:cursor-not-allowed data-[disabled]:opacity-50 data-[disabled]:curso" +
            "r-not-allowed [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-button-rim:rgb(2" +
            "55_255_255_/_20%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-button-wash" +
            ":rgb(255_255_255_/_15%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:border-transpa" +
            "rent [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:bg-primary [&:is([data-selected],[" +
            "aria-pressed=true],[aria-current=page])]:text-primary-foreground [:checked+&]:[--uiify-button-rim:rgb(2" +
            "55_255_255_/_20%)] [:checked+&]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [:checked+&]:border-transp" +
            "arent [:checked+&]:bg-primary [:checked+&]:text-primary-foreground [@media_(any-hover:_hover)_and_(any-" +
            "pointer:_fine)]:[&:is([data-selected],[aria-pressed=true],[aria-current=page]):hover:not(:disabled,[dat" +
            "a-disabled])]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [@m" +
            "edia_(any-hover:_hover)_and_(any-pointer:_fine)]:[:checked:not(:disabled)+&:hover]:[background-color:co" +
            "lor-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] bg-transparent text-foreground before" +
            ":content-none after:content-none hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(i" +
            "n_oklch,_var(--foreground)_10%,_transparent)] active:[&:not(:disabled,[data-disabled])]:[background-col" +
            "or:color-mix(in_oklch,_var(--foreground)_16%,_transparent)]"
          }
        >
          Menu
        </ModalTrigger>
        <ModalContent
          className={
            "[&[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)] [&_[data-positioning=native]]:[--u" +
            "iify-anchor-offset:var(--space-sm)] [&[popover]:popover-open:not([data-positioning=native])]:[margin:re" +
            "vert] [&_[popover]:popover-open:not([data-positioning=native])]:[margin:revert] [&[data-part=content]]:" +
            "m-auto [&[data-part=content]]:[inline-size:min(28rem,_calc(100vw_-_2_*_var(--space-lg)))] [&[data-part=" +
            "content]]:p-xl [&[data-part=content]]:border-[length:var(--border-width)] [&[data-part=content]]:border" +
            "-solid [&[data-part=content]]:border-border [&[data-part=content]]:rounded-xl [&[data-part=content]]:bg" +
            "-popover [&[data-part=content]]:text-popover-foreground [&[data-part=content]]:shadow-modal [&[data-par" +
            "t=content]::backdrop]:[background-color:rgb(0_0_0_/_45%)] motion-safe:[&[data-part=content]]:[transitio" +
            "n:var(--transition-presence)] motion-safe:[&[data-part=content]::backdrop]:[transition:var(--transition" +
            "-presence)] motion-safe:[&[data-part=content]:not([open])]:opacity-0 motion-safe:[&[data-part=content]:" +
            "not([open])]:[scale:var(--presence-scale)] motion-safe:[&[data-part=content]:not([open])::backdrop]:opa" +
            "city-0 motion-safe:starting:[&[data-part=content][open]]:opacity-0 motion-safe:starting:[&[data-part=co" +
            "ntent][open]]:[scale:var(--presence-scale)] motion-safe:starting:[&[data-part=content][open]::backdrop]" +
            ":opacity-0 data-[part=content]:[--uiify-modal-inline-size:28rem] data-[part=content]:flex-col data-[par" +
            "t=content]:gap-md data-[part=content]:[inline-size:min(var(--uiify-modal-inline-size),_calc(100vw_-_2_*" +
            "_var(--space-lg)))] data-[part=content]:[max-block-size:calc(100dvh_-_2_*_var(--space-lg))] data-[part=" +
            "content]:[&[open]]:flex data-[part=content]:data-[size=sm]:[--uiify-modal-inline-size:24rem] data-[part" +
            "=content]:data-[size=lg]:[--uiify-modal-inline-size:40rem] data-[part=content]:data-[size=full]:inset-0" +
            " data-[part=content]:data-[size=full]:m-0 data-[part=content]:data-[size=full]:[inline-size:100%] data-" +
            "[part=content]:data-[size=full]:[block-size:100%] data-[part=content]:data-[size=full]:[max-inline-size" +
            ":none] data-[part=content]:data-[size=full]:[max-block-size:none] data-[part=content]:data-[size=full]:" +
            "[padding-block:max(var(--space-xl),_env(safe-area-inset-top))_max(var(--space-xl),_env(safe-area-inset-" +
            "bottom))] data-[part=content]:data-[size=full]:[padding-inline:max(var(--space-xl),_env(safe-area-inset" +
            "-left))_max(var(--space-xl),_env(safe-area-inset-right))] data-[part=content]:data-[size=full]:border-0" +
            " data-[part=content]:data-[size=full]:border-current data-[part=content]:data-[size=full]:border-none d" +
            "ata-[part=content]:data-[size=full]:rounded-none [@media_(width_>=_40rem)]:data-[part=content]:data-[al" +
            "ign=start]:[&:not([data-size=full])]:[margin-block:var(--space-xl)_auto] [@media_(width_<_40rem)]:data-" +
            "[part=content]:[&:not([data-size=full])]:[inline-size:100%] [@media_(width_<_40rem)]:data-[part=content" +
            "]:[&:not([data-size=full])]:[max-inline-size:100%] [@media_(width_<_40rem)]:data-[part=content]:[&:not(" +
            "[data-size=full])]:[min-block-size:50dvh] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-siz" +
            "e=full])]:[max-block-size:80dvh] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-size=full])]" +
            ":[margin-block:auto_0] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-size=full])]:[margin-i" +
            "nline:0] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-size=full])]:[padding-block-end:calc" +
            "(var(--space-xl)_+_env(safe-area-inset-bottom))] [@media_(width_<_40rem)]:data-[part=content]:[&:not([d" +
            "ata-size=full])]:[border-block-end-width:0] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-s" +
            "ize=full])]:[border-end-start-radius:0] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-size=" +
            "full])]:[border-end-end-radius:0] [@media_(width_<_40rem)]:data-[part=content]:[&:not([data-size=full])" +
            ":has(>[data-uiify-modal][data-part=body])]:[touch-action:none] [@media_(width_<_40rem)]:data-[part=cont" +
            "ent]:[&:not([data-size=full])_[data-uiify-modal][data-part=header]]:[touch-action:none] [@media_(width_" +
            "<_40rem)]:data-[part=content]:[&:not([data-size=full])>[data-part=grabber]]:block [@media_(width_<_40re" +
            "m)_and_(prefers-reduced-motion:_no-preference)]:data-[part=content]:[&:not([data-size=full])]:[transiti" +
            "on:translate_var(--duration-fast)_var(--ease-out),_opacity_var(--duration-fast)_var(--ease-out),_displa" +
            "y_var(--duration-fast)_allow-discrete,_overlay_var(--duration-fast)_allow-discrete] [@media_(width_<_40" +
            "rem)_and_(prefers-reduced-motion:_no-preference)]:data-[part=content]:[&:not([data-size=full],[open])]:" +
            "[translate:0_100%] [@media_(width_<_40rem)_and_(prefers-reduced-motion:_no-preference)]:data-[part=cont" +
            "ent]:[&:not([data-size=full],[open])]:[scale:1] [@media_(width_<_40rem)_and_(prefers-reduced-motion:_no" +
            "-preference)]:starting:data-[part=content]:[&:not([data-size=full])[open]]:[translate:0_100%] [@media_(" +
            "width_<_40rem)_and_(prefers-reduced-motion:_no-preference)]:starting:data-[part=content]:[&:not([data-s" +
            "ize=full])[open]]:[scale:1] data-[part=content]:data-[dragging]:[&[open]:not([data-size=full])]:[transi" +
            "tion:none] data-[part=content]:data-[dragging]:[&[open]:not([data-size=full])]:[translate:0_var(--uiify" +
            "-sheet-offset,_0)] data-[part=content]:data-[backdrop=blur]:backdrop:[backdrop-filter:blur(4px)] data-[" +
            "part=content]:data-[backdrop=none]:backdrop:bg-transparent [&[data-part=content]_[data-uiify-modal][dat" +
            "a-part=content]::backdrop]:bg-transparent [&[data-part=content]_[data-uiify-modal][data-part=content]::" +
            "backdrop]:[backdrop-filter:none] data-[part=content]:[&:has([data-uiify-modal][data-part=content]:modal" +
            ")]:[filter:brightness(0.9)] [@media_(width_>=_40rem)]:data-[part=content]:[&:has([data-uiify-modal][dat" +
            "a-part=content]:modal)]:[scale:0.97]"
          }
          id="logo-navigation"
          size="full"
          aria-labelledby="logo-navigation-title"
        >
          <ModalHeader>
            <ModalTitle id="logo-navigation-title">Logo navigation</ModalTitle>
            <ModalClose target="logo-navigation" aria-label="Close navigation">
              ×
            </ModalClose>
          </ModalHeader>
          <ModalBody>
            <nav aria-label="Mobile workspace">
              <a href="/overview" aria-current="page">
                Overview
              </a>
              <a href="/projects">Projects</a>
              <a href="/activity">Activity</a>
              <a href="/help">Help</a>
              <Button
                as="a"
                href="/projects/new"
                variant="link"
                className={
                  "relative isolate inline-flex items-center justify-center gap-1.5 min-h-10 py-px border-transparen" +
                  "t bg-clip-padding text-base font-medium leading-6 cursor-pointer [transition:var(--transition-col" +
                  "ors)] focus-visible:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_20%,_tran" +
                  "sparent)] disabled:opacity-50 disabled:cursor-not-allowed data-[disabled]:opacity-50 data-[disabl" +
                  "ed]:cursor-not-allowed [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-b" +
                  "utton-rim:rgb(255_255_255_/_20%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]" +
                  ":[--uiify-button-wash:rgb(255_255_255_/_15%)] [&:is([data-selected],[aria-pressed=true],[aria-cur" +
                  "rent=page])]:border-transparent [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:b" +
                  "g-primary [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:text-primary-foreground" +
                  " [:checked+&]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [:checked+&]:[--uiify-button-wash:rgb(2" +
                  "55_255_255_/_15%)] [:checked+&]:border-transparent [:checked+&]:bg-primary [:checked+&]:text-prim" +
                  "ary-foreground [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[&:is([data-selected],[aria-pr" +
                  "essed=true],[aria-current=page]):hover:not(:disabled,[data-disabled])]:[background-color:color-mi" +
                  "x(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [@media_(any-hover:_hover)_and_(any-p" +
                  "ointer:_fine)]:[:checked:not(:disabled)+&:hover]:[background-color:color-mix(in_oklch,_var(--prim" +
                  "ary)_88%,_var(--primary-foreground))] min-w-0 px-0 border-0 border-none rounded-none bg-transpare" +
                  "nt text-primary underline [text-underline-offset:0.2em] before:content-none after:content-none [&" +
                  ":is(a)]:underline-offset-4 hover:bg-transparent focus-visible:[outline:2px_solid_var(--ring)] foc" +
                  "us-visible:[outline-offset:3px]"
                }
              >
                New project
              </Button>
            </nav>
          </ModalBody>
        </ModalContent>
      </Header.Root>
      <Breadcrumb.Root className="">
        <Breadcrumb.List
          items={[
            { key: "workspace", label: "Workspace", href: "/" },
            { key: "overview", label: "Overview", current: true },
          ]}
          className="flex flex-wrap items-center [gap:0.5rem] list-none p-0 m-0"
          slotProps={{
            item: { className: "flex items-center [gap:0.5rem]" },
            link: {
              className:
                "text-primary no-underline hover:underline data-[current]:text-foreground " +
                "data-[current]:font-semibold",
            },
          }}
          separator={<Breadcrumb.Separator className="text-muted-foreground" />}
        />
      </Breadcrumb.Root>
    </>
  );
}

// Optional client entry; SSR remains visible and scroll behavior attaches after hydration.
export function ScrollHeader() {
  return (
    <HeaderClient
      className="
        grid gap-md w-max max-w-[min(28rem,calc(100vw_-_2_*_var(--space-lg)))] p-6 border border-border rounded-xl
        bg-card text-card-foreground shadow-popover [&[popover]:not(:popover-open)]:hidden
        motion-safe:[&[popover]]:[transition:var(--transition-presence)]
        motion-safe:[&[popover]:not(:popover-open)]:opacity-0
        motion-safe:[&[popover]:not(:popover-open)]:[scale:var(--presence-scale)]
        motion-safe:starting:[&[popover]:popover-open]:opacity-0
        motion-safe:starting:[&[popover]:popover-open]:[scale:var(--presence-scale)]
      "
    >
      <a href="/">Logo</a>
      <nav aria-label="Workspace">
        <a href="/overview" aria-current="page">
          Overview
        </a>
        <a href="/projects">Projects</a>
        <a href="/activity">Activity</a>
      </nav>
    </HeaderClient>
  );
}

API

Header.Root

מאפייןטיפוסברירת מחדלתיאור
placement"static" | "sticky""static"מיקום מובנה של הכותרת העליונה הסמנטית. מיקום נצמד נשאר בתוך מכל הגלילה הקרוב ביותר.
refRef<HTMLElement>—ה-ref המועבר לאלמנט הכותרת העליונה המובנה.

HeaderClient

מאפייןטיפוסברירת מחדלתיאור
placement"static" | "sticky""sticky"מיקום סטטי משבית הסתרה. ברירת המחדל של Root המובנה היא static.
hideOnScrollbooleantrueהסתרה לאחר גלילה ממושכת מטה מעבר לגובה Header; חשיפה בגלילה מעלה או בראש העמוד.
scrollTargetstring—מזהה אלמנט אזור הגלילה. כשהוא מושמט, נעשה שימוש בחלון שאליו הוא שייך. יעד שאינו נמצא משאיר את Header גלוי ללא מעבר לחלון כחלופה.
refRef<HTMLElement>—ה-ref המועבר לאותה כותרת עליונה מובנית; המאפיינים המובנים, className, style והאירועים נשמרים.

מקלדת

מקשפעולה
Tabמעבר בין קישורים לפעולות; מיקוד בתוך HeaderClient חושף אותו
Enter / Spaceפתיחת Modal המובנה שהורכב, באמצעות המפעיל שלו
Escapeסגירת Modal של הניווט והחזרת המיקוד למפעיל שלו

נגישות

Header.Root מרנדר <header> סמנטי ללא JavaScript בצד הלקוח; HeaderClient מוסיף הסתרה בגלילה. שניהם גלויים לפני הידרציה. מיקוד פנימי, או רכיב צאצא פתוח מסוג מודאל, חלונית קופצת או אזור חשיפה, משאירים אותו גלוי; תנועה מופחתת מסירה את ההחלקה. בנו ניווט לנייד מחלקי Modal עם מזהים ייחודיים. תנו תוויות לאלמנטי nav, סמנו את הקישור הנוכחי ב-aria-current וסגרו את תיבת הדו-שיח לפני ניווט למקטע.

נקודות חיבור לעיצוב

data-uiify-headerdata-placement="static|sticky"data-state="top|visible|hidden" (HeaderClient only)
דף זה תורגם אוטומטית וטרם נבדק.