One-way: layout-change → signal
The split-group emits layout-change; Datastar copies
evt.detail.layout into $s1Layout.
view code
<body data-signals="{s1Layout: []}">
<schism-group
direction="horizontal"
data-on:layout-change="$s1Layout = evt.detail.layout"
>
<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>
<span data-text="JSON.stringify($s1Layout)"></span>
</body>
Two-way: signal ⇄ layout (animated)
data-effect calls el.setLayout($s2Layout)
whenever the signal changes; the buttons just write to the signal.
animate tweens between layouts.
view code
<body data-signals="{s2Layout: []}">
<schism-group
direction="horizontal"
animate
data-on:layout-change="$s2Layout = evt.detail.layout"
data-effect="el.setLayout && $s2Layout.length === 3
&& el.setLayout($s2Layout)"
>
<schism-pane default-size="20">A</schism-pane>
<schism-resizer></schism-resizer>
<schism-pane default-size="60">B</schism-pane>
<schism-resizer></schism-resizer>
<schism-pane default-size="20">C</schism-pane>
</schism-group>
<button data-on:click="$s2Layout = [20, 60, 20]">20 / 60 / 20</button>
<button data-on:click="$s2Layout = [50, 25, 25]">50 / 25 / 25</button>
</body>
<!-- inside data-effect, `el` is the <schism-group>.
length===3 guard avoids running before the WC has scanned. -->
Collapsible sidebar — events drive a signal (animated)
data-on:collapse and data-on:expand on the
pane keep $sidebarCollapsed in sync; the button calls
the imperative API. animate smooths the collapse.
Forest signature surface
Workspace
view code
<body data-signals="{sidebarCollapsed: false}">
<schism-group direction="horizontal" animate>
<schism-pane
min-size="120px" collapsible default-size="25"
data-on:collapse="$sidebarCollapsed = true"
data-on:expand="$sidebarCollapsed = false"
>sidebar</schism-pane>
<schism-resizer></schism-resizer>
<schism-pane>main</schism-pane>
</schism-group>
<button
data-on:click="
const pane = el.closest('.demo').querySelector('schism-pane');
$sidebarCollapsed ? pane.expand() : pane.collapse();
"
data-text="$sidebarCollapsed ? 'Expand sidebar' : 'Collapse sidebar'"
></button>
</body>
Persisted via save-id
Persistence is independent of any signal. The signal here is just an observer.
Drag — refresh — sizes restore
Independent of any signal
view code
<body data-signals="{s4Layout: []}">
<schism-group
direction="vertical"
save-id="datastar-demo"
data-on:layout-change="$s4Layout = evt.detail.layout"
>
<schism-pane>top</schism-pane>
<schism-resizer></schism-resizer>
<schism-pane>bottom</schism-pane>
</schism-group>
</body>
<!-- save-id is independent of any signal.
localStorage["schism:datastar-demo"] is updated on drag,
debounced 100 ms, and re-read on next mount. -->