|
|
5 months ago | |
|---|---|---|
| .. | ||
| README.md | 5 months ago | |
| index.ts | 5 months ago | |
| splitter-panel.svelte | 5 months ago | |
| splitter-resize-trigger.svelte | 5 months ago | |
| splitter.css | 5 months ago | |
| splitter.svelte | 5 months ago | |
| types.ts | 5 months ago | |
README.md
Eidos Splitter
Two-or-more resizable panels separated by draggable handles. The
headless Soma layer owns the resize math (panel sizes as
percentages, min / max clamping, collapsed state, keyboard arrow
steps); the morfo declares a single semantic event,
commit-resize, fired on drag-end (mouse-up). Eidos paints chrome:
panels, the handle, its hover / drag affordance, and the center
grip.
Superficie
<Splitter orientation="horizontal">
<Splitter.Panel panelId="a" defaultSize={50} minSize={20}>
Left panel
</Splitter.Panel>
<Splitter.ResizeTrigger panelBefore="a" panelAfter="b" />
<Splitter.Panel panelId="b" defaultSize={50} minSize={20}>
Right panel
</Splitter.Panel>
</Splitter>
<!-- Vertical with collapsible top panel -->
<Splitter orientation="vertical">
<Splitter.Panel panelId="header" defaultSize={30} collapsible collapsedSize={0}>
Header
</Splitter.Panel>
<Splitter.ResizeTrigger panelBefore="header" panelAfter="body" />
<Splitter.Panel panelId="body" defaultSize={70}>
Body
</Splitter.Panel>
</Splitter>
Baseline
Origin: air/components/layout/splitter (branch morfo-runtime),
which wrapped the legacy Terra splitter implementation.
Adjustments applied during the port:
- Drop the
air-splitter-*class namespace. Eidos targets[data-splitter]/[data-splitter-panel]/[data-splitter-resize-trigger]via the markers emitted by the morfo runtime. - Replace the
--air-splitter-*token namespace with bare--splitter-*names per the eidos naming convention. The identifiers map to canonical UIX primitives:--splitter-bg→--color-surface-default--splitter-border-color→--color-border-default--splitter-handle-bg→--color-border-subtle--splitter-handle-bg-active→--color-primary-solid--splitter-handle-size→--space-2--splitter-grip-bg→--color-content-muted
- Wire the
commit-resizesema event in the recipe: when the morfo's signal hold stampsdata-event='commit-resize'on the resize trigger, the handle paints in the active color until the hold expires. Air had no equivalent because air predates the sema visual channel. - Soma is the source of state. The eidos wrappers are pure
pass-through; min / max / collapsible / collapsedSize / keyboard
step all live on
<Splitter.Panel>props (PanelProps) or<Splitter>props (disabled,orientation,keyboardStep).
Comparativa
| Capability | UIX (eidos) | Radix Themes Splitter | Ark UI Splitter | react-resizable-panels |
|---|---|---|---|---|
| Compound API (Panel / ResizeTrigger) | Yes | Yes | Yes | Yes |
orientation prop (horizontal / vertical) |
Yes (responsive via soma dir) |
Yes | Yes | Yes |
defaultSize per panel (%) |
Yes | Yes | Yes | Yes |
minSize / maxSize per panel |
Yes | Yes | Yes | Yes |
collapsible + collapsedSize |
Yes | No | Yes | Yes |
onResize callback (live during drag) |
Yes (onResize) |
No (only commit) | Yes | Yes |
onResizeEnd callback (drag commit) |
Yes — also raised as sema commit-resize |
Yes | Yes | Yes |
| Keyboard arrow resize | Yes (configurable step via keyboardStep) |
Yes | Yes | Yes |
| Home / End jump to min / max | Yes | Yes | Yes | No |
| Enter to toggle collapse | Yes | No | Yes | No |
| Sema event surface | Yes (commit-resize in commit family) |
No | No | No |
| Drag affordance (center grip) | Yes (eidos pseudo) | Yes | Yes | n/a (consumer styles) |
Decisiones
- Soma is the source of state and ARIA. Eidos adds no
evaluative props — no
size, novariant, nointent. Panel sizing belongs to the morfo'spropRef('size')mapping, the active drag belongs todata-dragging, keyboard belongs to the morfo's keyboard table. - Single sema event:
commit-resize. Live drag (every pixel movement) is NOT a sema event — it would saturate the perceptual channels with high-frequency noise. Only the drag commit (mouse up, key release after arrow resize) fires the sema verb. This matches thefeedback_per_event_intent_intrinsicprinciple: per-event intent reflects the act's own evaluative load — a resize commit iscommit.setwithneutralintent (the user set a new value; the result is geometric, neither affirm nor threat). - Eidos pulses the handle on
commit-resize. The recipe selector[data-splitter-resize-trigger][data-event='commit-resize']paints the handle in the active color during the signal hold, giving the user visual confirmation that the drag was committed. The pulse fades automatically when the hold expires. Indicatoris not implemented as a separate part. The morfo listsProvider/Panel/ResizeTrigger; the brief mentioned an optionalIndicatorpart for the grip / handle visualisation, but the grip is owned by the recipe's::beforepseudo — promoting it to a part would manufacture a DOM element the consumer never needs to override. The decision is documented here so a future port can revisit.
Eventos Sema
| Name | Family | Verb | Sequence | Intent | Target |
|---|---|---|---|---|---|
commit-resize |
commit |
set |
post |
neutral |
resize-trigger |
The event fires on drag-end (mouse-up) and on keyboard arrow-key
release. The signal hold is short (brief band from
SEMA_DURATIONS) so the visual pulse on the handle disappears
quickly. Sound and haptic channels project a low-intensity feedback
suitable for a layout adjustment.
Gaps
| Gap | Disposition | Detail |
|---|---|---|
Splitter.Indicator as a separately stylable part |
diferir | The grip is rendered by ::before today. Promote when ≥2 consumers want to override the grip independently (e.g. custom icon). |
Sema event on panel-collapse / panel-expand |
diferir | When a Panel toggles its collapsed state via Enter, an emerge family event would be natural. Out of scope for the layout-primitive sweep. |
nested mode for splitter-in-splitter ergonomics |
diferir | Today the consumer manually nests <Splitter>s. A nested flag could hide the outer border to avoid double-borders. |
| 3+ panel keyboard parity check (Tab through handles) | implementar | Manual test pending — the soma test covers two-panel only; need a multi-panel keyboard walk. |
variant="ghost" for borderless splitter |
descartar | Token override (--splitter-border-color: transparent;) is enough. Variant would manufacture a typed surface. |
Referencias
- Radix Themes Splitter: https://www.radix-ui.com/themes/docs/components/splitter
- Ark UI Splitter: https://ark-ui.com/docs/components/splitter
- react-resizable-panels: https://github.com/bvaughn/react-resizable-panels
- allotment: https://github.com/johnwalley/allotment
- WAI-ARIA
separatorrole witharia-valuenow: https://www.w3.org/TR/wai-aria-1.2/#separator