lunaDOM Docs
lunaDOM Docs

lunaDOM is a collection of lightweight, accessible shadowdom based web components built with JavaScript.

v0.0.25

The <luna-split-panel> component creates resizable split panels with snapping, nesting, and custom divider styling.

Paths

/lunadom/components/split-panel/split-panel.js REQUIRED

Horizontal Split

Left Panel

Drag the divider to resize. The left panel maintains its size while the right fills remaining space.

Right Panel

This panel flexes to fill the available space. Try resizing the browser window.

Vertical Split

Top Panel

Drag horizontally to resize vertically stacked panels.

Bottom Panel

Bottom panel flexes to fill remaining height.

With Snap Points

Snap at 25%, 50%, 75%

Drag the divider near these points to feel the snap effect. Higher threshold (40px) makes it easier to snap.

The divider will magnetically snap to the defined positions when you get close.

Snap with repeat() Notation

Grid Snapping

repeat(5, 20%) creates snap points at 20%, 40%, 60%, 80%, 100%

Useful for creating evenly-spaced layouts like column grids.

Fixed Header with Label

Fixed Header (60px)

The header maintains a fixed 60px height while this content area fills the remaining space.

Scrollable content below...

Primary Panel (Fixed Sidebar)

Liquid Panel

This panel expands/contracts to fill available space.

Fixed Sidebar (200px)

This panel maintains 200px width while the left panel flexes.

Custom Divider Styling

Thick Green Divider

Custom 8px wide divider with green hover color and larger grip handle.

Hover over the divider to see the custom green highlight.

Scrollable Content

Scrollable Left

Each panel has automatic scrolling when content overflows. The scrollbars are hidden but you can still scroll with mouse wheel or touch.

Tall content area that triggers scrolling...

Scrollable Right

This panel also scrolls independently. Try scrolling each side separately.

Even taller content to demonstrate independent scrolling...

Nested Split Panels

Sidebar

Top Content Area

Bottom Content Area

Customization

Slots
start - Content for the first (left or top) panel.
end - Content for the second (right or bottom) panel.
divider - Optional custom content rendered inside the divider bar.

Attributes
position - Initial split position (% or px). Defaults to '50%'.
vertical - Stack panels top/bottom instead of left/right.
primary - Which panel keeps explicit size (start, end).
snap - Space-separated snap positions (e.g., '25% 50% 75%'). Supports repeat() notation.
snap-threshold - Pixel distance for snap activation. Defaults to 30.
min-size - Minimum size of either panel. Defaults to '50px'.
disabled - Prevents resizing.

CSS Variables
--luna-sp-divider-width - Width (or height if vertical) of divider bar. Defaults to 4px.
--luna-sp-divider-hit-area - Invisible pointer target around bar. Defaults to 16px.
--luna-sp-divider-color - Resting bar color. Defaults to var(--luna-border, #222).
--luna-sp-divider-color-hover - Bar color on hover/drag. Defaults to var(--luna-accent, #2563eb).
--luna-sp-handle-size - Length of grip handle. Defaults to 28px.
--luna-sp-handle-color - Grip dot color. Defaults to #555.
--luna-sp-handle-color-hover - Grip dot color on hover/drag. Defaults to #aaa.
--luna-sp-panel-bg - Background applied to both panels. Defaults to transparent.

Events
luna-reposition - Fired while dragging. detail: { position: string, value: number }

Example Code

<!-- Horizontal Split --> <luna-split-panel position="50%"> <div slot="start">Left Panel</div> <div slot="end">Right Panel</div> </luna-split-panel> <!-- Vertical Split --> <luna-split-panel vertical position="40%"> <div slot="start">Top Panel</div> <div slot="end">Bottom Panel</div> </luna-split-panel> <!-- With Snap Points --> <luna-split-panel position="50%" snap="25% 50% 75%" snap-threshold="40"> <div slot="start">Snaps at 25%, 50%, 75%</div> <div slot="end">Right Panel</div> </luna-split-panel> <!-- Scrollable Content (automatic) --> <luna-split-panel position="50%"> <div slot="start"> <div style="height: 1000px;">Tall content scrolls automatically</div> </div> <div slot="end"> <div style="height: 1500px;">Independent scrolling</div> </div> </luna-split-panel> <!-- Fixed Header with Label --> <luna-split-panel vertical position="60px" primary="start"> <div slot="start">Fixed Header (60px)</div> <div slot="end">Scrollable content area</div> </luna-split-panel> <!-- Snap with repeat() Notation --> <luna-split-panel position="50%" snap="repeat(5, 20%)" snap-threshold="35"> <div slot="start">Snaps every 20%: 20%, 40%, 60%, 80%, 100%</div> <div slot="end">Right Panel</div> </luna-split-panel> <!-- Primary Panel (Fixed Size) --> <luna-split-panel position="200px" primary="end"> <div slot="start">Liquid Panel (expands/contracts)</div> <div slot="end">Fixed Sidebar (200px)</div> </luna-split-panel> <!-- Custom Divider Styling --> <luna-split-panel position="60%" style=" --luna-sp-divider-width: 8px; --luna-sp-divider-color: #2a2a2a; --luna-sp-divider-color-hover: #22c55e; --luna-sp-handle-size: 40px; --luna-sp-handle-color: #555; --luna-sp-handle-color-hover: #22c55e; "> <div slot="start">Thick Green Divider</div> <div slot="end">Right Panel</div> </luna-split-panel> <!-- Nested Split Panels --> <luna-split-panel position="200px" primary="start"> <div slot="start">Sidebar</div> <luna-split-panel slot="end" vertical position="50%"> <div slot="start">Top Content Area</div> <div slot="end">Bottom Content Area</div> </luna-split-panel> </luna-split-panel> <!-- Listening to reposition events --> <script> const splitPanel = document.querySelector('luna-split-panel'); splitPanel.addEventListener('luna-reposition', (e) => { console.log('New position:', e.detail.position); console.log('Value:', e.detail.value); }); </script>