Skip to content
Nizivo UI

Split

A main column and an aside, side by side while there is room and stacked below that, by the Split's own width, with no breakpoint and no script.

Server component, no client JS

Import

import { Split } from '@nizivo/react/split';

// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/split.css';

Static or interactive

Server. It ships no client JavaScript when a Server Component renders it, in every Next.js build mode; its code is bundled only when a client component (a 'use client' file) imports it. How to choose.

In a client app (a Vite or React Router single-page app, or a 'use client' file) it is an ordinary React component: event handlers, refs and state work as usual. In a client app.

Layout

08's pages draw "Columns" frames: a main column and an aside, the grid's gutter apart (24 px on desktop). Split.Aside asks for its width, 360 px (aside="wide", the Overview's 8 + 4 split) or 232 px (aside="narrow", Settings' section nav), and Split.Main takes the rest. When the main column would get less than 60 % of the row, the two stack, in source order: put the aside after the main column for a side panel, or first for a section nav. It follows the Split's own width, so it works the same in a dashboard, a dialog or a narrow card. Give the aside a landmark through render, for example render={<aside aria-label="Goals" />} or render={<nav aria-label="…" />}.

Hooks: --nz-split-gap, --nz-split-aside-width, --nz-split-main-min.

Examples

Basic

08's Overview: the main column and a 360 px aside; they stack when the row is narrow.

Revenue

The main column takes the rest of the row.

import type { JSX } from 'react';
import { Card } from '@nizivo/react/card';
import { Text } from '@nizivo/react/text';
import { Split } from '@nizivo/react/split';

export function SplitExample(): JSX.Element {
  return (
    <Split.Root>
      <Split.Main>
        <Card.Root>
          <Card.Header>
            <Card.Title>Revenue</Card.Title>
          </Card.Header>
          <Card.Body>
            <Text>The main column takes the rest of the row.</Text>
          </Card.Body>
        </Card.Root>
      </Split.Main>
      <Split.Aside render={<aside aria-label="Goals" />}>
        <Card.Root>
          <Card.Header>
            <Card.Title>Goals</Card.Title>
          </Card.Header>
          <Card.Body>
            <Text>The aside is 360 px wide beside it.</Text>
          </Card.Body>
        </Card.Root>
      </Split.Aside>
    </Split.Root>
  );
}

Narrow

Settings: a 232 px section nav first, then the content.

Store details

The content column.

import type { JSX } from 'react';
import { Card } from '@nizivo/react/card';
import { Text } from '@nizivo/react/text';
import { Split } from '@nizivo/react/split';

export function SplitNarrowExample(): JSX.Element {
  return (
    <Split.Root aside="narrow">
      <Split.Aside render={<nav aria-label="Settings sections" />}>
        <Text>Store details · Payments · Shipping</Text>
      </Split.Aside>
      <Split.Main>
        <Card.Root>
          <Card.Header>
            <Card.Title>Store details</Card.Title>
          </Card.Header>
          <Card.Body>
            <Text>The content column.</Text>
          </Card.Body>
        </Card.Root>
      </Split.Main>
    </Split.Root>
  );
}

Parts

Use the parts through the namespace (Split.Root) or by their flat names (SplitRoot); both work from Server Components.

Split.Root

The row. Put Split.Main and Split.Aside in reading order: the aside after the main column (an Overview's side panel), or first (a Settings page's section nav). They stack in that order.

Server component Renders data-slot="split" with the class nz-split. Props: SplitRootProps. Source: src/split/split.tsx.

NameTypeDefaultDescription
asideSplitAsideWidth
"narrow""wide"
'wide'

The aside's width while the columns sit side by side.

renderRenderProp<Empty>–
  • Also takes every attribute of <div>. (ComponentPropsWithRef<"div">)

render takes an element, or, in client code, a function of the props and no state.

Split.Main

The main column: it takes the rest of the row.

Server component Renders data-slot="split-main" with the class nz-split-main. Props: SplitMainProps. Source: src/split/split.tsx.

NameTypeDefaultDescription
renderRenderProp<Empty>–
  • Also takes every attribute of <div>. (ComponentPropsWithRef<"div">)

render takes an element, or, in client code, a function of the props and no state.

Split.Aside

The side column, aside wide; pass render={<aside />} for complementary content.

Server component Renders data-slot="split-aside" with the class nz-split-aside. Props: SplitAsideProps. Source: src/split/split.tsx.

NameTypeDefaultDescription
renderRenderProp<Empty>–
  • Also takes every attribute of <div>. (ComponentPropsWithRef<"div">)

render takes an element, or, in client code, a function of the props and no state.

Other exports

SplitAsideProps type

import type { SplitAsideProps } from '@nizivo/react/split'

The props of Split.Aside, listed above.

SplitAsideWidth type

import type { SplitAsideWidth } from '@nizivo/react/split'

wide is 08's 360 px aside (the 8 + 4 split); narrow its 232 px Settings nav column.

type SplitAsideWidth = "narrow" | "wide"

SplitMainProps type

import type { SplitMainProps } from '@nizivo/react/split'

The props of Split.Main, listed above.

SplitRootProps type

import type { SplitRootProps } from '@nizivo/react/split'

The props of Split.Root, listed above.

Data attributes and slots

Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.

SlotRendered byData attributes
split
.nz-split
Split.Root
root (takes render)
  • data-aside: "narrow""wide" ← aside
    The aside's width while the columns sit side by side
split-aside
.nz-split-aside
Split.Aside
root (takes render)
none
split-main
.nz-split-main
Split.Main
root (takes render)
none

CSS hooks

Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.

HookDefaultRead as
--nz-split-aside-width
  • default: 22.5rem
  • data-aside="narrow": 14.5rem
  • flex on .nz-split-aside
--nz-split-gap--nz-grid-gutter
  • gap on .nz-split
--nz-split-main-min60%
  • min-inline-size on .nz-split-main

Layers: nz.components. Classes: .nz-split, .nz-split-aside, .nz-split-main.

Tokens this stylesheet reads (1)

--nz-grid-gutter

Accessibility

Nothing in this component takes focus or keyboard input.

Keyboard

None.

Figma

Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.

  • Canonical: none
  • Ghost masters: none

On this page