05customization

Toolbar & chrome

Kloq.Toolbar, Kloq.Nav, Kloq.Reset and useKloq() — the app bar as opt-in composable parts.

<Kloq> renders no app bar of its own — the chrome is opt-in parts you compose as children. It used to render its own header, wordmark and all; that made it an app, not a component. Now naming the product is the host's business.

The parts

<div className="h-dvh">
  <Kloq>
    <Kloq.Toolbar>
      <h1>My calendar</h1>
      <div className="flex items-center gap-2">
        <Kloq.Nav />
        <Kloq.Reset />
      </div>
    </Kloq.Toolbar>
  </Kloq>
</div>
PartTypeNotes
Kloq.ToolbarKloqToolbarPropsA bordered app-bar row above the surface. Pure layout — holds no state. With no children it renders the built-in arrangement: nav left, Reset right, no wordmark.
Kloq.Nav{ className? }‹ › Today, the range title (with its month/year picker), and the view switcher.
Kloq.Reset{ className? }Restore the sample events — through the store, so it hits onCommit and persistence like any other change.

The same components are importable by name — KloqToolbar, KloqNav, KloqReset — the statics are a convenience. The toolbar's responsiveness is flex-wrap: below ~640px the nav and your controls stack instead of the view switcher being squeezed to nothing.

Why children, not siblings

The parts read useKloq() — the same view, anchor date and store the grid is using — so they have to be inside the provider. Rendering them as children of <Kloq> buys three things a sibling layout would have to re-solve: the keyboard layer's ownership test sees a click on Today as landing inside the calendar, so t / / keep working; design mode's scope and hover-inspect cover the toolbar; and a host never has to prop-drill view / onViewChange to reproduce the built-in bar.

useKloq()

The calendar's live view state and navigation actions, as one object — KloqChrome. Only valid inside <Kloq>: outside it there is no calendar to describe, and it throws rather than returning a plausible-looking default that would hide the mistake until a button silently did nothing.

view?
ViewDescriptor

The resolved EFFECTIVE view: columns, dates, today's index — after any responsive collapse.

viewSetting?
KloqView

The effective view *setting* ("week", 3, …), not the shape.

intentView?
KloqView | undefined

What the consumer asked for, when a narrow box is overriding it. undefined when the two agree.

collapsed?
boolean | undefined

True while the box is overriding the view (three days, a day, or a month).

narrow?
boolean | undefined

True below the narrow breakpoint — the nav uses a short title.

fits?
(view: KloqView) => boolean

Whether a view fits the box at its current width; the switcher disables the ones that don't.

date?
Date

The anchor date the view is resolved around.

atToday?
boolean

True when today is inside the visible range.

lastStep?
StepDirection | null

Direction of the last range step, for directional animation.

step(dir)?
(dir) => void

Step the range by one of the current view's units.

goToday()?
() => void

Move the range back onto today.

switchView(view)?
(view: KloqView) => void

Request a view change — reports through onViewChange.

jumpToDay(date)?
(date: Date) => void

Move the anchor and switch to the day view.

goToDate(date)?
(date: Date) => void

Move the anchor, leaving the view alone.

reset()?
() => void

Restore the sample events.

openCommand() / openShortcuts()?
() => void

Open ⌘K / the ? shortcuts overlay.

keymap?
Keymap | undefined

The host's keymap overrides, so chrome that advertises a key shows the real binding.

Composing your own bar

my-toolbar.tsx
import { Kloq, useKloq } from "@/components/kloq";

function SaveIndicator() {
  const k = useKloq();
  return (
    <span className="text-xs text-muted-foreground">
      {k.atToday ? "Today" : k.date.toLocaleDateString()}
    </span>
  );
}

<Kloq>
  <Kloq.Toolbar>
    <MyLogo />
    <div className="flex items-center gap-2">
      <SaveIndicator />
      <Kloq.Nav />
      <MyAccountMenu />
    </div>
  </Kloq.Toolbar>
</Kloq>

Anything inside the toolbar can call useKloq() — your components and the built-ins read the same context, so a custom Today button is onClick={k.goToday} and nothing more. Note the distinction the shape encodes: view is what is drawn, viewSetting is the current setting, and intentView remembers what you asked for while a narrow box overrides it — chrome that steps the range or highlights the active view should read the effective one, or ‹ › would step by a week while showing a day.

on this page