Display
Resizable panels
Panels side by side or stacked, sized by dragging the line between them, or from the keyboard.
Installation
npx sinaui add resizableCopy src/lib/ui/resizable/ and tokens.css. No dependencies.
Examples
Side by side
Drag a line, or focus it and use the arrow keys. The catalog collapses when dragged small, or with Enter; double-click a line to reset. The layout is remembered.
Catalog
- Book of Optics
- The Canon of Medicine
- Al-Jabr
- Tabula Rogeriana
Book of Optics
Ibn al-Haytham argued that we see because light travels from objects into the eye, and tested it by experiment: light in a dark room, through a small hole.
Notes
Compare with the Latin translation, De aspectibus.
<script lang="ts">
import * as Resizable from '#lib/ui/resizable/index.js';
</script>
<div class="frame">
<Resizable.Group persist="sinaui-reading-room">
<Resizable.Panel defaultSize={24} minSize={16} collapsible label="Catalog">
<div class="pane">
<h4>Catalog</h4>
<ul>
<li>Book of Optics</li>
<li>The Canon of Medicine</li>
<li>Al-Jabr</li>
<li>Tabula Rogeriana</li>
</ul>
</div>
</Resizable.Panel>
<Resizable.Handle label="Resize the catalog" />
<Resizable.Panel minSize={30} label="Manuscript">
<div class="pane">
<h4>Book of Optics</h4>
<p>
Ibn al-Haytham argued that we see because light travels from objects into the eye, and
tested it by experiment: light in a dark room, through a small hole.
</p>
</div>
</Resizable.Panel>
<Resizable.Handle label="Resize the notes" />
<Resizable.Panel defaultSize={26} minSize={18} label="Notes">
<div class="pane">
<h4>Notes</h4>
<p>Compare with the Latin translation, <i>De aspectibus</i>.</p>
</div>
</Resizable.Panel>
</Resizable.Group>
</div>
<style>
.frame {
inline-size: 100%;
block-size: 16rem;
border-radius: calc(var(--ui-radius) * 1.5);
background: var(--ui-surface);
box-shadow: 0 1px 3px rgb(0 0 0 / 0.06);
overflow: hidden;
}
.pane {
padding: 1rem;
font-size: 0.875rem;
line-height: 1.55;
}
h4 {
margin: 0 0 0.5rem;
font-size: 0.9375rem;
}
p,
ul {
margin: 0;
color: var(--ui-muted);
}
ul {
display: grid;
gap: 0.375rem;
padding-inline-start: 1.1rem;
}
</style>Stacked
The Compendious Book on Calculation by Completion and Balancing, written by al-Khwarizmi in Baghdad around 820, gave algebra its name.
“Completion” is al-jabr: moving a subtracted term to the other side of the equation.
<script lang="ts">
import * as Resizable from '#lib/ui/resizable/index.js';
</script>
<div class="frame">
<Resizable.Group orientation="vertical">
<Resizable.Panel minSize={25} label="Text">
<div class="pane">
<p>
The Compendious Book on Calculation by Completion and Balancing, written by al-Khwarizmi
in Baghdad around 820, gave algebra its name.
</p>
</div>
</Resizable.Panel>
<Resizable.Handle label="Resize the text" />
<Resizable.Panel minSize={25} label="Commentary">
<div class="pane">
<p>“Completion” is al-jabr: moving a subtracted term to the other side of the equation.</p>
</div>
</Resizable.Panel>
</Resizable.Group>
</div>
<style>
.frame {
inline-size: 100%;
block-size: 14rem;
border-radius: calc(var(--ui-radius) * 1.5);
background: var(--ui-surface);
box-shadow: 0 1px 3px rgb(0 0 0 / 0.06);
overflow: hidden;
}
.pane {
padding: 1rem;
font-size: 0.9375rem;
line-height: 1.7;
}
p {
margin: 0;
}
</style>Props
Resizable.Group
| Prop | Type | Default |
|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' |
persist | string: a storage key |
Resizable.Panel
| Prop | Type | Default |
|---|---|---|
defaultSize | number: percent | an equal share |
minSize, maxSize | number: percent | 10, 100 |
collapsible | boolean | false |
label | string |
Resizable.Handle
| Prop | Type | Default |
|---|---|---|
label | string (required): what it resizes |
Keyboard
| Key | Does |
|---|---|
| Arrow keys | Move the line by 5% (10% with Shift) |
| Home / End | The panel before it at its smallest or largest |
| Enter | Collapse a collapsible panel, or bring it back |
Accessibility
- Each line is a focusable separator: screen readers hear its name and the size of the panel it controls.
- A collapsed panel is taken out of the page, so Tab never lands inside it.
- The grab area is wider than the line it draws, and wider still on touch screens.