Splitter follows the W3C ARIA window splitter pattern. The splitter creates one internal gutter between each pair of adjacent panes, so you never write gutters yourself.

splitter.ts
import { KuiSplitter, KuiSplitterPane } from '@kikita-labs/ui';

Give the splitter a container with a height and project kui-splitter-pane elements. size is only the initial share: the splitter owns the live size, and drag and keyboard both write into it.

Files
Editor

Sizes: 30 / 70

<div class="splitter-example">
  <kui-splitter (sizesChange)="onResize($event)">
    <kui-splitter-pane [size]="30" [minSize]="15" [collapsible]="true">
      <div class="splitter-example__pane">Files</div>
    </kui-splitter-pane>
    <kui-splitter-pane [size]="70" [minSize]="30">
      <div class="splitter-example__pane">Editor</div>
    </kui-splitter-pane>
  </kui-splitter>
</div>
<p>Sizes: {{ sizes().join(' / ') }}</p>
  • Pane sizes are percentages of the splitter's own container, computed with calc() against the fixed gutter width, so panes and gutters always add up to 100%.
  • minSize (default 10) is a percentage floor that stops an accidental drag or keyboard step from collapsing a pane to nothing.
  • A collapsible first or last pane gets a one-touch button on its gutter that toggles it between its minSize and its size before collapsing; Enter on the gutter does the same. A middle pane's flag is ignored.

orientation vertical stacks the panes top to bottom. A splitter inside a pane needs no special API, since each splitter measures only its own container.

Tree
Editor
Terminal
<div class="splitter-example">
  <kui-splitter orientation="vertical">
    <kui-splitter-pane>
      <kui-splitter orientation="horizontal">
        <kui-splitter-pane [size]="25">
          <div class="splitter-example__pane">Tree</div>
        </kui-splitter-pane>
        <kui-splitter-pane [size]="75">
          <div class="splitter-example__pane">Editor</div>
        </kui-splitter-pane>
      </kui-splitter>
    </kui-splitter-pane>
    <kui-splitter-pane [size]="30" [minSize]="10" [collapsible]="true">
      <div class="splitter-example__pane">Terminal</div>
    </kui-splitter-pane>
  </kui-splitter>
</div>

Any number of panes works, with one gutter between each adjacent pair. A gutter only resizes the two panes touching it, each clamped by its own minSize. disabled removes every gutter from the tab order and ignores input.

One
Two
Three
Locked one
Locked two
<div class="splitter-example">
  <kui-splitter>
    <kui-splitter-pane [size]="20">
      <div class="splitter-example__pane">One</div>
    </kui-splitter-pane>
    <kui-splitter-pane>
      <div class="splitter-example__pane">Two</div>
    </kui-splitter-pane>
    <kui-splitter-pane>
      <div class="splitter-example__pane">Three</div>
    </kui-splitter-pane>
  </kui-splitter>
</div>
<div class="splitter-example">
  <kui-splitter [disabled]="true">
    <kui-splitter-pane>
      <div class="splitter-example__pane">Locked one</div>
    </kui-splitter-pane>
    <kui-splitter-pane>
      <div class="splitter-example__pane">Locked two</div>
    </kui-splitter-pane>
  </kui-splitter>
</div>

Set defaults.splitter once for the application or for a subtree. Each option resolves as local input > defaults.splitter.<option> > built-in default.

import { provideKikitaUi } from '@kikita-labs/ui';

export const appConfig: ApplicationConfig = {
  providers: [
    provideKikitaUi({
      defaults: {
        splitter: {
          /* options below */
        },
      },
    }),
  ],
};
NameTypeDefaultDescription
orientation'horizontal' | 'vertical' — Panel layout direction.
minSizenumber — Minimum share of a pane, as a percentage from 0 to 100.

Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.

NameTypeDefaultDescription
--kui-splitter-gutter-thumb-radiusCSS custom property--kui-radius-fullGutter thumb corner radius
--kui-splitter-gutter-thumb-btn-radiusCSS custom property--kui-radius-fullGutter thumb btn corner radius

Every text the component owns (accessible names, visible words, announcements) is a typed message with an English default. Override it for the application with provideKikitaUi({ messages }), or for a subtree with provideKuiMessages.

NameTypeDefaultDescription
collapsePanestring — Collapse button. Default Collapse pane.
expandPanestring — Expand button. Default Expand pane.

Inputs verified against @kikita-labs/ui v2.0.0 public typings.

NameTypeDefaultDescription
kui-splitter orientation'horizontal' | 'vertical' | undefinedundefinedPane layout direction (defaults.splitter.orientation, then horizontal). Horizontal puts the panes side by side with a vertical gutter line.
kui-splitter disabledbooleanfalseDisables every gutter: aria-disabled, tabindex -1, and no drag or keyboard resize. Pane content stays interactive.
(sizesChange)readonly number[]-Emitted with the full sizes array, in percent, on every drag or keyboard resize.
kui-splitter-pane sizenumber | undefinedundefinedInitial or requested share in percent. The splitter owns the live size afterwards. Panes without a size split the remaining space evenly.
kui-splitter-pane minSizenumber | undefinedundefinedMinimum share in percent, clamped to 0-100 (defaults.splitter.minSize, then 10). Drag and keyboard resizing clamp to it; invalid static values use 10.
kui-splitter-pane collapsiblebooleanfalseAdds a one-touch collapse button to the adjacent gutter. Only meaningful on the first or last pane; the flag of a middle pane is ignored.
currentSizeSignal<number>-Live share of a pane in percent, reflecting drag and keyboard changes.
collapsedSignal<boolean>-True while the pane is collapsed to its minSize.
toggleCollapse()() => void-Toggles the collapse state. A no-op when collapsible is false or the pane is in the middle.
--kui-splitter-pane-bg / -pane-border / -radiusCSS custom properties-Container background, border and corner radius.
--kui-splitter-gutter-sizeCSS custom property--kui-space-2Width or height of the interactive gutter strip.
--kui-splitter-gutter-line / -line-hover / -line-active / -line-disabledCSS custom properties-Gutter line colour by state.
--kui-splitter-thumb-bg / -thumb-bg-hover / -thumb-bg-activeCSS custom properties-Default grip colour by state.
--kui-splitter-collapse-btn-bg / -collapse-btn-fg / -focus-ringCSS custom properties-One-touch collapse button colours and the focus-visible ring of a gutter.
KuiSplitterOptionsinterface-Shape of defaults.splitter: orientation and minSize.

Each gutter holds a focusable separator, following the window splitter pattern.

  • The gutter renders an inner role="separator", focusable unless disabled. The kui-splitter-gutter host has no role, and the collapse button is a sibling of the separator because a focusable separator must not contain an interactive control.
  • aria-orientation describes the gutter line: horizontal panes have a vertical line, and vice versa.
  • aria-valuenow, aria-valuemin and aria-valuemax track the pane before the gutter from the same value that drives the visual size, and aria-controls points at that pane's generated id, which replaces any id set in a template.
  • The collapse button is named by the splitter.collapsePane and splitter.expandPane messages and stays out of the tab order; its keyboard equivalent is Enter on the separator.
  • Tab focuses each gutter. The arrow keys along the layout axis resize the before pane by 2%, or 10% with Shift. Home collapses it to its minSize and End expands it to the maximum the after pane allows. Escape cancels an active drag and restores the earlier sizes.

Documented limits of the installed package.

  • There is no custom thumb projection; only the default grip and the chevron button exist.
  • Sizes are not persisted between sessions.
  • The gutter strip is 8px, below the 44px touch-target guidance, as a desktop cursor-driven control.
  • A formal assistive-technology review has not been run.