Star skammer/schism on GitHub

Install

npm i @skammer/schism

Or load directly from jsDelivr — no build step:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@skammer/schism/dist/schism.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@skammer/schism/dist/schism.js"></script>

Horizontal — three panes

Default split: a leading 30%, a remainder, and a trailing 20%.

A

Files

30% by default. Pull the handle to resize.

B

Editor

Takes whatever's left.

C

Preview

20% by default.

view code
<schism-group direction="horizontal">
  <schism-pane default-size="30">A</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane>B</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane default-size="20">C</schism-pane>
</schism-group>

Vertical

Same model, stacked instead of side-by-side.

Top

A signature peach surface

Bottom

A signature mint surface

view code
<schism-group direction="vertical">
  <schism-pane>top</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane>bottom</schism-pane>
</schism-group>

Nested — IDE layout, px constraints, animated collapse

Sidebar: min-size="160px", max-size="40%", collapsible. The animate attribute smooths collapse/expand/reset; dragging stays 1:1.

src/ index.ts app.tsx utils/ fmt.ts Editor

main.ts

Drag the inner handle to resize the terminal.

Terminal

$ npm run build  ✓ schism.js 31 KB

Preview

Output

Live render area.

outer = inner =
view code
<schism-group direction="horizontal" id="ide" animate>
  <schism-pane min-size="160px" max-size="40%"
               default-size="22" collapsible>
    sidebar
  </schism-pane>
  <schism-resizer></schism-resizer>

  <schism-pane>
    <schism-group direction="vertical" id="ide-inner">
      <schism-pane default-size="70">editor</schism-pane>
      <schism-resizer></schism-resizer>
      <schism-pane min-size="60px">terminal</schism-pane>
    </schism-group>
  </schism-pane>

  <schism-resizer></schism-resizer>
  <schism-pane min-size="160px" default-size="22">preview</schism-pane>
</schism-group>

<script>
  const ide = document.getElementById("ide");
  const sidebar = ide.querySelector("schism-pane");

  sidebar.collapse();             // hide
  sidebar.expand();               // restore last expanded size
  ide.setLayout([22, 56, 22]);    // outer
  ideInner.setLayout([70, 30]);   // inner

  ide.addEventListener("layout-change",
    (e) => console.log(e.detail.layout));
</script>

Persisted — save-id="demo"

Layout is saved to localStorage on drag, restored on reload.

A

Drag, refresh.

B

Sizes restore.

C

Per shape and constraints.

view code
<schism-group direction="horizontal" save-id="demo">
  <schism-pane default-size="33">A</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane default-size="33">B</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane>C</schism-pane>
</schism-group>

<!-- saved at localStorage["schism:demo"], debounced 100 ms -->

Controlled — animated setLayout

group.setLayout([…]) validates against the panes' constraints; animate tweens between layouts. Tune duration/easing with --schism-animate-duration / --schism-animate-easing.

duration easing
A B C
layout =
view code
<schism-group id="ctl" direction="horizontal" animate
              style="--schism-animate-duration: 240ms;
                     --schism-animate-easing: cubic-bezier(.2,.9,.2,1.2);">
  <schism-pane>A</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane>B</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane>C</schism-pane>
</schism-group>

<button onclick="ctl.setLayout([20, 60, 20])">20 / 60 / 20</button>
<button onclick="ctl.setLayout([50, 25, 25])">50 / 25 / 25</button>

<!-- animate = transitions on flex-grow.
     Drag stays 1:1 (suppressed while [data-dragging]).
     Honors prefers-reduced-motion: reduce. -->

RTL — horizontal axis

Drag and arrow-key directions invert when dir="rtl" is in effect.

Start

Right side in RTL

End

Left side in RTL

view code
<!-- direction: rtl on the group, an ancestor, or the document -->
<schism-group direction="horizontal" style="direction: rtl">
  <schism-pane>start (right in RTL)</schism-pane>
  <schism-resizer></schism-resizer>
  <schism-pane>end (left in RTL)</schism-pane>
</schism-group>