SplitPane
Resize adjacent regions by pointer and keyboard while respecting minimum task requirements.
Use the web element directly without the semantic runtime.
A registered presentation adapter can bind this component to host-owned meaning and state.
The standard recipe resolver does not select this component automatically.
Import and live example#
Two labelled panes with a keyboard-resizable divider.
Interactive preview requires JavaScript.
View the complete example source
import {registerAeliqoElements} from "@varendo/web";
import {
AeliqoAvatarElement,
AeliqoBadgeElement,
AeliqoButtonElement,
AeliqoGridElement,
AeliqoHeadingElement,
AeliqoIconButtonElement,
AeliqoLinkElement,
AeliqoScrollAreaElement,
AeliqoSeparatorElement,
AeliqoSplitPaneElement,
AeliqoStackElement,
AeliqoSurfaceElement,
AeliqoTextElement,
} from "@varendo/web/foundation";
registerAeliqoElements();
const host = document.querySelector<HTMLElement>("#aeliqo-example") ?? (() => {
const created = document.createElement("div");
created.id = "aeliqo-example";
(document.body ?? document.documentElement).append(created);
return created;
})();
function createCatalogRoot(container: HTMLElement): HTMLElement {
const root = document.createElement("div");
root.dataset.catalogSourceRoot = "true";
root.style.display = "grid";
root.style.gap = "12px";
container.append(root);
return root;
}
function createCatalogElement<T extends HTMLElement>(tagName: string, container: HTMLElement): T {
const element = document.createElement(tagName) as T;
element.setAttribute("data-aeliqo-theme", "light");
container.append(element);
return element;
}
function appendSlottedText(root: HTMLElement, slot: string, textContent: string): void {
const content = document.createElement("span");
content.slot = slot;
content.textContent = textContent;
root.append(content);
}
const root = createCatalogRoot(host);
(((root) => {
const element = createCatalogElement<AeliqoSplitPaneElement>("aeliqo-split-pane", root);
element.defaultPosition = 42;
element.min = 20;
element.max = 80;
element.primaryLabel = "Primary panel";
element.secondaryLabel = "Secondary panel";
appendSlottedText(element, "start", "Primary panel");
appendSlottedText(element, "end", "Secondary panel");
}))(root);
Purpose#
Two panes around a divider that users resize by pointer or keyboard. min, max, and step bound the range; changes emit a position request.
When to use it#
- A sidebar and detail view the user rebalances.
- Two regions that must stay usable within set limits.
- Layouts where keyboard users need the same resize control.
When to use a different component#
- Use Grid for a fixed responsive layout users can't resize.
- Use ScrollArea when one region needs bounded overflow scrolling.
Properties and defaults#
Use position for controlled layout and defaultPosition for initial uncontrolled state.
| Property | Use and ownership | Declared type | Initial value |
|---|---|---|---|
orientation | Sets the horizontal or vertical orientation and associated keyboard behavior. | AeliqoSplitOrientation | 'horizontal' |
position | Controls the current split position within the declared minimum and maximum. | number | undefined | undefined |
defaultPosition | Provides the initial uncontrolled position. Later updates come from component interaction. | number | 50 |
min | Sets the lower bound for min. | number | 20 |
max | Sets the upper bound for max. | number | 80 |
step | Sets the permitted numeric or split-position increment. | number | 5 |
disabled | Prevents user interaction while keeping the control and its current value visible. | boolean | false |
primaryLabel | Provides the visible text for the primary control or section. | string | 'Primary pane' |
secondaryLabel | Provides the visible text for the secondary control or section. | string | 'Secondary pane' |
separatorLabel | Provides the visible text for the separator control or section. | string | 'Resize panes' |
Events#
| Event | Payload | Emitted | Application responsibility |
|---|---|---|---|
aeliqo-split-change | {source, orientation, position} | While the user moves the separator. | Clamp and persist the accepted position, then update controlled position. |
Events cross the component boundary as user proposals. Validate their detail and current authority before applying a business effect.
Listen for aeliqo-split-change
const element = document.querySelector('aeliqo-split-pane');<p>element?.addEventListener('aeliqo-split-change', (event) => {
const proposal = (event as CustomEvent<unknown>).detail;
// Validate the proposal, update host state, then assign controlled properties.
applyProposal(proposal);
});States and failure handling#
Relevant states:
- ready
- disabled
Expected result: The divider exposes its range and emits a typed position proposal when adjusted.
Keyboard, focus, and accessibility#
Keyboard behavior:
- Tab
- Arrow keys
- Home
- End
Exposed semantics:
- aria-controls
- aria-disabled
- aria-label
- aria-orientation
- aria-valuemax
- aria-valuemin
- aria-valuenow
- aria-valuetext
- role
Responsive behavior#
position is the primary pane’s percentage of the available pane area, excluding the resize handle. The handle reserves its own space and is at least 44 CSS pixels wide (horizontal layout) or tall (vertical layout) for coarse pointers, including compact density. Ordinary text wraps within each pane; children can override wrapping for preformatted or intentionally scrollable content. Set pane limits so each side stays useful. On phones, use vertical orientation if two side-by-side panes become too narrow.
Style hooks#
- Shadow parts:
end,split,splitter,start - Varendo design tokens referenced:
--aeliqo-color-border,--aeliqo-color-focus,--aeliqo-control-border-width,--aeliqo-focus-width,--aeliqo-split-position
Related components#
Generated TypeScript declaration#
View generated declaration
export declare class AeliqoSplitPaneElement extends AeliqoFoundationElement {
static readonly properties: {
orientation: {
type: StringConstructor;
};
position: {
type: NumberConstructor;
};
defaultPosition: {
attribute: string;
type: NumberConstructor;
};
min: {
type: NumberConstructor;
};
max: {
type: NumberConstructor;
};
step: {
type: NumberConstructor;
};
disabled: {
type: BooleanConstructor;
reflect: boolean;
};
primaryLabel: {
attribute: string;
type: StringConstructor;
};
secondaryLabel: {
attribute: string;
type: StringConstructor;
};
separatorLabel: {
attribute: string;
type: StringConstructor;
};
};
orientation: AeliqoSplitOrientation;
position: number | undefined;
defaultPosition: number;
min: number;
max: number;
step: number;
disabled: boolean;
primaryLabel: string;
secondaryLabel: string;
separatorLabel: string;
private internalPosition;
private activePointer;
protected willUpdate(changed: Map<PropertyKey, unknown>): void;
protected render(): import("lit").TemplateResult<1>;
disconnectedCallback(): void;
private effectivePosition;
private positionBounds;
private clamped;
private readonly handlePointerDown;
private readonly handlePointerMove;
private readonly handlePointerUp;
private readonly handleKeyDown;
private commitPosition;
static readonly styles: import("lit").CSSResult[];
}Version#
This page documents the Varendo 0.6 component contract.
