Web Component API
Complete API reference for the <sliced-areas> Web Component.
Element
<sliced-areas>
Custom HTML element for managing resizable and splittable areas.
<sliced-areas style="width: 100%; height: 100vh;"></sliced-areas>Tag Name: sliced-areas
Class: SlicedAreasElement
Properties
layout
Get or set the current layout.
- Type:
AreasLayout | null - Default:
null - Reactive: Yes (triggers re-render)
// Get current layout
const layout = element.layout
// Set new layout
element.layout = {
areas: [
{ tag: 'editor', rect: { left: 0, right: 1, top: 1, bottom: 0 } }
]
}
// Clear layout
element.layout = nulloperations
Enable or disable interactive operations.
- Type:
SlicedAreasOperationsConfig | null - Default:
null(all operations enabled) - Reactive: Yes (triggers re-render)
Available operations:
resizesplitjoinreplaceswapmovemaximizerestore
// Disable resize and swap
element.operations = {
disable: ['resize', 'swap']
}
// Allow only split and join
element.operations = {
enable: ['split', 'join']
}graph Read-only
Access the internal planar graph representation.
- Type:
AreasGraph | null - Read-only: Yes
- Advanced: For debugging and advanced use cases
const graph = element.graph
if (graph) {
console.log('Vertices:', graph.verts)
console.log('Edges:', graph.edges)
console.log('Areas:', graph.areas)
}Methods
setResolver()
Set the content resolver function.
setResolver(resolver: AreaResolver | null): voidParameters:
resolver: Function that creates content for each area tag (and area id), ornullto clear
Example:
element.setResolver((tag, areaId) => {
const div = document.createElement('div')
div.textContent = `Area: ${tag}`
return {
element: div,
cleanup: () => console.log(`Cleanup ${areaId}`)
}
})
// Clear resolver
element.setResolver(null)split()
Split an area into two parts.
split(
sourceAreaId: AreaId,
zone?: string,
clientX?: number,
clientY?: number
): voidParameters:
sourceAreaId: ID of the area to splitzone(optional): Drop zone identifier'split-vertical'- Split left/right'split-horizontal'- Split top/bottom
clientX(optional): X coordinate for split positionclientY(optional): Y coordinate for split position
Example:
// Split area vertically (left/right)
element.split(areaId, 'split-vertical')
// Split area horizontally (top/bottom)
element.split(areaId, 'split-horizontal')
// Split with default behavior
element.split(areaId)Emits: sliced-areas:layoutchange
join()
Merge two adjacent areas into one.
join(sourceAreaId: AreaId, targetAreaId: AreaId): voidParameters:
sourceAreaId: ID of the area to merge fromtargetAreaId: ID of the area to merge into
Example:
element.join(areaId1, areaId2)Emits: sliced-areas:layoutchange
Note: Areas must be adjacent (share an edge).
replace()
Replace the content tag of a target area.
replace(sourceAreaId: AreaId, targetAreaId: AreaId): voidParameters:
sourceAreaId: ID of the area whose content to copytargetAreaId: ID of the area to replace
Example:
// Replace target's content with source's content
element.replace(sourceId, targetId)Emits: sliced-areas:layoutchange
swap()
Swap the positions and content of two areas.
swap(sourceAreaId: AreaId, targetAreaId: AreaId): voidParameters:
sourceAreaId: ID of the first areatargetAreaId: ID of the second area
Example:
element.swap(areaId1, areaId2)Emits: sliced-areas:layoutchange
close()
Close an area and redistribute its space.
close(areaId: AreaId): voidParameters:
areaId: ID of the area to close
Example:
element.close(areaId)Emits: sliced-areas:layoutchange
Note: Cannot close the last remaining area.
retag()
Change the content tag of an area.
retag(areaId: AreaId, tag: AreaTag): voidParameters:
areaId: ID of the area to retagtag: New tag string
Example:
// Change area content from 'editor' to 'viewer'
element.retag(areaId, 'viewer')Emits: sliced-areas:layoutchange
maximize()
Maximize an area to full screen, hiding all others.
maximize(areaId: AreaId): voidParameters:
areaId: ID of the area to maximize
Example:
element.maximize(areaId)Emits: sliced-areas:layoutchange
Note: Stores the current layout for later restoration.
restore()
Restore the layout after maximizing.
restore(): voidExample:
element.restore()Emits: sliced-areas:layoutchange
Note: Only works if a layout was previously maximized.
Events
sliced-areas:layoutchange
Fired when the layout changes.
Event Type: CustomEvent<{ layout: AreasLayout }>
Detail:
{
layout: AreasLayout // The new layout
}Example:
element.addEventListener('sliced-areas:layoutchange', (event) => {
const layout = event.detail.layout
console.log('Layout changed:', layout)
// Save to localStorage
localStorage.setItem('layout', JSON.stringify(layout))
})Triggered by:
- Setting
layoutproperty - Calling
split(),join(),replace(),swap() - Calling
close(),retag() - Calling
maximize(),restore() - User dragging splitters
- User drag-and-drop operations
Note: Not emitted on the initial render or ResizeObserver-driven redraws.
sliced-areas:area-added
Fired when a new area appears in the layout.
Event Type: CustomEvent<AreaAddedDetail>
Example:
element.addEventListener('sliced-areas:area-added', (event) => {
const { areaId, tag, rect } = event.detail
console.log('Area added:', areaId, tag, rect)
})sliced-areas:area-removed
Fired when an area is removed from the layout.
Event Type: CustomEvent<AreaRemovedDetail>
Example:
element.addEventListener('sliced-areas:area-removed', (event) => {
const { areaId, tag } = event.detail
console.log('Area removed:', areaId, tag)
})sliced-areas:area-updated
Fired when an area changes geometry or tag.
Event Type: CustomEvent<AreaUpdatedDetail>
Example:
element.addEventListener('sliced-areas:area-updated', (event) => {
const { areaId, tag, oldRect, newRect } = event.detail
console.log('Area updated:', areaId, tag, oldRect, newRect)
})sliced-areas:cornerclick
Fired when an area corner is clicked.
Event Type: CustomEvent<CornerClickDetail>
Detail:
{
areaId: AreaId, // ID of the clicked area
corner: CornerId, // Which corner was clicked
clientX: number, // X coordinate
clientY: number // Y coordinate
}Corner Values:
'top-left''top-right''bottom-left''bottom-right'
Example:
element.addEventListener('sliced-areas:cornerclick', (event) => {
const { areaId, corner, clientX, clientY } = event.detail
// Show context menu
showContextMenu({
x: clientX,
y: clientY,
items: [
{ label: 'Close Area', onClick: () => element.close(areaId) },
{ label: 'Maximize', onClick: () => element.maximize(areaId) }
]
})
})Lifecycle Hooks
connectedCallback()
Called when the element is added to the DOM.
Automatic: Yes (standard Web Component lifecycle)
What it does:
- Creates root and stash containers
- Sets up ResizeObserver
- Renders the current layout
disconnectedCallback()
Called when the element is removed from the DOM.
Automatic: Yes (standard Web Component lifecycle)
What it does:
- Cleans up ResizeObserver
- Removes event listeners
- Clears drag state
TypeScript
Import types for better type safety:
import type {
SlicedAreasElement,
AreasLayout,
AreasGraph,
AreaResolver,
AreaResolverResult,
AreaId,
AreaTag,
AreaRect,
CornerId,
CornerClickDetail
} from 'sliced-areas'
// Use types
const el = document.querySelector('sliced-areas') as SlicedAreasElement
const layout: AreasLayout = {
areas: [
{ tag: 'main', rect: { left: 0, right: 1, top: 1, bottom: 0 } }
]
}
const resolver: AreaResolver = (tag: AreaTag, areaId: AreaId): AreaResolverResult => {
const div = document.createElement('div')
div.textContent = tag
return { element: div, cleanup: () => console.log(`Cleanup ${areaId}`) }
}
el.layout = layout
el.setResolver(resolver)
el.addEventListener('sliced-areas:layoutchange', (e: CustomEvent<{ layout: AreasLayout }>) => {
console.log(e.detail.layout)
})
el.addEventListener('sliced-areas:cornerclick', (e: CustomEvent<CornerClickDetail>) => {
const { areaId, corner, clientX, clientY } = e.detail
console.log(`Corner ${corner} of area ${areaId} clicked at (${clientX}, ${clientY})`)
})Advanced Usage
Accessing Internal State
// Get current graph
const graph = element.graph
// Access vertices
Object.values(graph.verts).forEach(vert => {
console.log(`Vertex ${vert.id} at (${vert.x}, ${vert.y})`)
})
// Access edges
Object.values(graph.edges).forEach(edge => {
console.log(`Edge ${edge.id}: ${edge.v1} -> ${edge.v2}, border: ${edge.border}`)
})
// Access areas
Object.entries(graph.areas).forEach(([id, area]) => {
console.log(`Area ${id}: vertices ${area.v1}, ${area.v2}, ${area.v3}, ${area.v4}`)
})Manual Area Operations
// Get area IDs from the graph
const areaIds = Object.keys(element.graph.areas)
// Perform operations
element.split(areaIds[0], 'split-vertical')
element.join(areaIds[0], areaIds[1])
element.maximize(areaIds[0])
element.restore()See Also
- TypeScript Types - Full type reference
- Web Components Guide - Usage guide with examples
- Core Concepts - Understanding the layout model