@shaman-apprentice/page-skeleton
v1.0.1
Published
A custom element web component providing slots for header, sidebar and content.
Readme
page-skeleton
A custom element web component providing slots for header, sidebar and content. Works with any framework (Angular, React, Vue, etc.) or vanilla JavaScript.

Installation
npm install @shaman-apprentice/page-skeletonNote: Make sure your CSS reset sets body { margin: 0; } for the component to display correctly. Most modern CSS resets include this anyway.
Usage
With Angular
import { Component, signal, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@shaman-apprentice/page-skeleton';
@Component({
selector: 'app-root',
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<page-skeleton
[attr.sidebar-open]="isSidebarOpen() ? '' : null"
[attr.sidebar-width-in-px]="sidebarWidth()"
(sidebar-width-changed)="onSidebarWidthChanged($event)"
animated
>
<header slot="header">
<button (click)="isSidebarOpen.set(!isSidebarOpen())">Toggle</button>
My App
</header>
<aside slot="sidebar">Sidebar content</aside>
<section slot="sidebar-border"></section>
<main slot="content">Main content</main>
</page-skeleton>
`
})
export class AppComponent {
isSidebarOpen = signal(true);
sidebarWidth = signal(320);
onSidebarWidthChanged(event: CustomEvent<{ width: number }>) {
this.sidebarWidth.set(event.detail.width);
}
}API
Slots
| Slot Name | Description |
| --- | --- |
| header | Fixed header at the top |
| sidebar | Collapsible sidebar on the left |
| sidebar-border | Draggable border between sidebar and content |
| content | Main content area |
Attributes
| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| sidebar-width-in-px | number | 320 | Current sidebar width in pixels |
| sidebar-min-width-in-px | number | 240 | Minimum sidebar width in pixels |
| sidebar-open | boolean | false | Whether sidebar is open |
| disable-dragging | boolean | false | Disable sidebar resize dragging |
| animated | boolean | false | Enable slide animation for sidebar |
Properties (JavaScript)
Access via JavaScript:
const skeleton = document.querySelector('page-skeleton');
skeleton.sidebarWidthInPx = 400;
skeleton.sidebarOpen = true;Events
| Event | Detail | Description |
| --- | --- | --- |
| sidebar-width-changed | { width: number } | Fired when sidebar is resized by dragging |
CSS Variables
| Variable | Default | Description |
| --- | --- | --- |
| --page-skeleton_header-height | 48px | Header height |
| --page-skeleton_sidebar_border-width | 1px | Border width |
| --page-skeleton_transition-duration | 0.3s | Animation duration |
| --page-skeleton_transition-timing-function | ease-in-out | Animation easing |
CSS Parts
You can style each internal layout containers using the ::part() selector:
| Part Name | Description |
| --- | --- |
| header | Header container |
| sidebar | Sidebar container |
| content | Content container |
| sidebar_border | Sidebar border/resize handle |
Example:
page-skeleton::part(header) {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}Migration from @shaman-apprentice/ngx-page-skeleton
If you're upgrading from @shaman-apprentice/ngx-page-skeleton, see this migration guide.
