Skip to content

Components

Reference

Import from @kasane/design/react. Every class a component emits exists in the CSS. The check runs on every commit.

Page

Covers the root, bands, column, and chrome

Kasane

The root. Scopes every style and paints the page ground. One per page, in the root layout.

<Kasane>
  <ToastProvider>{children}</ToastProvider>
</Kasane>
PropTypeNote
langstringdefault 'en'
classNamestring
Band

A full-bleed band. Content goes in a Col.

<Band tone="deep" id="notes" labelledBy="notes-title">
  <Col>
    <Head title="Notes" id="notes-title" />
  </Col>
</Band>
PropTypeNote
tone'hero' | 'tone' | 'deep' | 'beni'omit for the page ground
asElementTypedefault 'section'
labelledBystringid of the heading inside
Col

The 1200px column.

PropTypeNote
classNamestring
Panel

A surface block. On the deep band in the light theme it takes the light theme.

A panel.

PropTypeNote
asElementTypedefault 'div'
classNamestring
Main

The main landmark.

PropTypeNote
idstringdefault 'main'
Bar

The fixed pill bar holds the brand, section links, and children at the end. Put a ThemeSwitch there.

<Bar brand={{ name: 'Kasane', href: '/' }} items={items} link={Link}>
  <ThemeSwitch />
</Bar>
PropTypeNote
brand{ name, domain?, href }
itemsNavItem[]{ href, label, current? }
labelstringnav label, default 'Primary'
linkLinkComponent | 'a'next/link or a plain anchor
ThemeSwitch

One button that says the theme and flips it. useTheme() gives [theme, setTheme]. themeScript is the head snippet.

PropTypeNote
classNamestringdefault 'kb-bar__theme'
Invert

A block in the opposite theme of the page.

Healthy
PropTypeNote
classNamestring

Blocks

Covers the hero, tiles, stats, and long-form blocks

Hero

The opening band. Renders its own Band.

PropTypeNote
titleReactNode
nameReactNode
introReactNode
idstringheading id, default 'hero-title'
Tile

A whole-tile link, inside Tiles.

PropTypeNote
hrefstring
kindReactNode
yearReactNode
titleReactNode
levelHeadingLeveldefault 3
smallboolean
linkLinkComponent | 'a'next/link or a plain anchor
childrenReactNodethe description
Stat

A big number, inside Stats. direction draws the arrow. sentiment colours it.

3.76MRequestsUp 12.4%
1Failed deploysUp 1 since yesterday
99.97%Uptime30d
PropTypeNote
valueReactNode
labelReactNode
deltaReactNode
direction'up' | 'down'
sentiment'good' | 'bad' | 'neutral'default 'neutral'
Cta

The beni band. Renders its own Band.

PropTypeNote
titleReactNode
textReactNode
actionsReactNode
idstringheading id, default 'cta-title'
Prose

Long-form headings, lists, figures, tables, and code get their margins back. Article puts a Prose and a Toc side by side.

On margins

The unit is 8px.

Every gap, padding and control height is a multiple of it. --kb-space-8

Rules

  • Controls on one row share one height.
  • Muted text clears 4.5:1 or becomes ink.
PropTypeNote
asElementTypedefault 'article'
classNamestring
Toc

On this page, as a panel.

PropTypeNote
items{ href, label }[]
labelstringdefault 'On this page'
linkLinkComponent | 'a'next/link or a plain anchor
Callout

A note in a box. err is an alert.

NeutralMaintenance on Sunday 02:00 JST.
NoticeA new version is available.
SavedChanges are live.
Certificate expires in 6 daysRenewal is automatic.
PropTypeNote
kind'neutral' | 'notice' | 'ok' | 'warn' | 'err'default 'neutral'
titleReactNode
Empty

An empty state.

No deployments yet. Push to main to create one.

Sheet

Rows of surface, one per family, each with a caps label. SheetRow takes label and id.

Controls

Covers buttons, words, identity, and layout

Button

Passes every button attribute through. ButtonLink is the same look on an anchor. LinkButton is a button drawn as a link.

Link as button
PropTypeNote
variant'secondary' | 'primary' | 'accent' | 'danger'default 'secondary'
size'sm' | 'md' | 'lg'32, 40, 48px
iconbooleana square button holding one icon, needs aria-label
tipstringtooltip on hover and focus
pushbooleanmargin-left: auto
Tray

A pill holding a segmented set. Buttons inside carry aria-pressed.

PropTypeNote
labelstring
role'group' | 'tablist'default 'group'
Status

A word in its colour.

HealthyDegradedFailedBuilding
PropTypeNote
kind'neutral' | 'ok' | 'warn' | 'err'default 'neutral'
Kbd, Code, Pre

Keys, inline code, a code block.

CtrlK--kb-space-8: 8px
.card {
  border-radius: var(--kb-radius-block);
}
Avatar

Initials in a circle. With a name it is an image. Without one it is hidden, because the control around it carries the name. AvatarStack overlaps them.

JBKBJBTS+3
PropTypeNote
initialsReactNode
namestring
size'md' | 'lg'
Crumbs

Breadcrumb. The last entry has no href and is the page.

  1. auth
  2. Deployments
  3. storage
PropTypeNote
trail{ href?, label }[]
linkLinkComponent | 'a'next/link or a plain anchor
Pages

Page numbers. A null entry is a gap.

PropTypeNote
pages({ href, label, current? } | null)[]
prevstring
nextstring
labelstringdefault 'Pagination'
pushboolean
linkLinkComponent | 'a'next/link or a plain anchor
Progress

A progressbar. Skeleton is one shimmering line.

Build, 25%
Upload, 70%
Loading
PropTypeNote
valuenumber
maxnumberdefault 100
labelstring
Cluster, Stack, Row, Split, Divider

Cluster is a wrapping row. Stack is a column. Row puts fields side by side, 2 or 3 columns. Split makes two halves. Divider is a hairline.

PropTypeNote
Cluster gap'tight' | 'wide'
Cluster pushboolean
Cluster asElementType
Stack tightboolean
Row cols2 | 3default 2

Forms

Covers field wiring, inputs, choices, and the dropdown

Field

Hands the control its id, aria-describedby and aria-invalid through a render prop. Form and Fieldset wrap. FormActions is the button row.

Identity
Shown in the index.
Enter a full address.
PropTypeNote
idstringgenerated when omitted
labelReactNode
hintReactNode
errorReactNodemarks the field invalid
requiredboolean
widebooleanspans the row
children(wiring) => ReactNode
Input, Textarea

Native inputs with the system's look. Every attribute passes through.

PropTypeNote
size'sm' | 'md'Input only, 32 or 40px
Group

An input with a fixed word before or after it, in one pill.

.kurobeni.jp
https://
PropTypeNote
beforeReactNode
afterReactNode
size'sm' | 'md'
Select

A native select for forms and a button plus listbox drawn by the system. Arrows, Home, End, typeahead, Escape. Flips up when there is no room below.

Selected: osaka
PropTypeNote
options{ value, label, disabled? }[]
valuestringcontrolled
defaultValuestring
onChange(value: string) => void
size'sm' | 'md'
namestring
disabledboolean
Choice, Switch

Checkbox, radio and switch, drawn by the CSS. The switch says On or Off.

Visibility
Features
PropTypeNote
type'checkbox' | 'radio'Choice only
labelReactNode
descriptionReactNodesmall type under the label
on, offstringSwitch words, default 'On' / 'Off'
Toolbar, HiddenLabel

A row of small controls above a table. HiddenLabel names a control the layout already explains.

Data

Tables and tabs

Table

TableWrap scrolls sideways inside its block and shows a hint only when columns are hidden. Th and Td take a priority. Columns drop as the block narrows, low then mid then narrow. RowTitle folds the status word under the name when the status column has gone.

ProjectEnvironmentStatusRequestsp95UpdatedActions
apiHealthyproductionHealthy1,204,553182 ms2 min ago
webDegradedstagingDegraded48,210640 ms14 min ago
storageFailedproductionFailed03 h ago
1 selected, showing 1–3 of 3
PropTypeNote
TableWrap labelstringnames the scroll region
TableWrap hintReactNode
TableWrap prosebooleaninside long-form
Th, Td priority'low' | 'mid' | 'narrow'
Th, Td numbooleanright-aligned, tabular digits
Td mutedboolean
RowTitle status{ kind?, label }
Tabs

ARIA tabs. Arrows, Home and End move and select. The list is a tray. The selected tab is a filled pill.

All eight deployments.

PropTypeNote
labelstring
items{ id?, label, count?, children }[]
initialnumberdefault 0
onChange(index: number) => void

Feedback

Dialogs and toasts

Dialog

Native dialog. Open it with ref.current.showModal(). The cross and any button with data-kb-close close it. useTypedConfirm(word) gives inputProps and confirmed for a destructive dialog.

Edit deployment

Delete storage?

This removes the project, its deployments and its subdomain.

PropTypeNote
idstring
titleReactNode
actionsReactNodethe foot
refRef<HTMLDialogElement>
closeLabelstringdefault 'Close'
ToastProvider, useToast

ToastProvider renders the list at the viewport corner. useToast() returns toast(message, kind?). At most three, five seconds each, paused while hovered.

PropTypeNote
kind'ok' | 'err'optional

Whole page

All of the above, combined on one page.