Skip to content

@gluonjs/core / packages/organisms/src / AdminShellProps

Interface: AdminShellProps ​

Properties ​

attributes? ​

readonly optional attributes?: AdminShellAttributes


readonly optional footer?: TemplateValue


footerAttributes? ​

readonly optional footerAttributes?: AdminShellRegionAttributes


readonly optional header?: TemplateValue


headerAttributes? ​

readonly optional headerAttributes?: AdminShellRegionAttributes


id ​

readonly id: string


main ​

readonly main: TemplateValue


mainAttributes? ​

readonly optional mainAttributes?: AdminShellRegionAttributes


readonly optional navigationAttributes?: AdminShellNavigationAttributes


readonly optional sidebar?: TemplateValue


sidebarAttributes? ​

readonly optional sidebarAttributes?: AdminShellRegionAttributes


sidebarLabel? ​

readonly optional sidebarLabel?: string

Example ​

Configure an AdminShell while routing, permissions, data loading, and tenant identity remain caller-owned:

ts
import { html } from '@gluonjs/core';
import { AdminShell, AppShell, AsyncState, ConfirmationDialog, MegaMenu, PageLayout, ProductCard, ProductGallery, ProductGrid, SiteFooter, SiteHeader, SplitPane, WorkflowTimeline, adminShellStyles, asyncStateStyles, confirmationDialogStyles, createConfirmationDialogController, megaMenuStyles, organismManifest, organismStyles, pageLayoutStyles, productCardStyles, productGalleryStyles, productGridStyles, siteFooterStyles, siteHeaderStyles, splitPaneStyles, workflowTimelineStyles, type AdminShellAttributes, type AdminShellNavigationAttributes, type AdminShellProps, type AdminShellRegionAttributes, type AppShellProps, type AsyncStateAttributes, type AsyncStateHeadingLevel, type AsyncStateMessages, type AsyncStateProps, type AsyncStateStatus, type ConfirmationDialogAttributes, type ConfirmationDialogController, type ConfirmationDialogControllerOptions, type ConfirmationDialogInitialFocus, type ConfirmationDialogProps, type MegaMenuAttributes, type MegaMenuGroup, type MegaMenuLink, type MegaMenuLinkAttributes, type MegaMenuOpenChangeEvent, type MegaMenuProps, type MegaMenuTriggerAttributes, type PageLayoutAttributes, type PageLayoutHeadingLevel, type PageLayoutProps, type PageLayoutRegionAttributes, type ProductCardAttributes, type ProductCardProduct, type ProductCardProps, type ProductGalleryAttributes, type ProductGalleryImage, type ProductGalleryImageAttributes, type ProductGalleryProps, type ProductGridAttributes, type ProductGridColumns, type ProductGridProps, type SiteFooterAttributes, type SiteFooterNavigationAttributes, type SiteFooterProps, type SiteFooterRegionAttributes, type SiteHeaderAttributes, type SiteHeaderNavigationAttributes, type SiteHeaderOpenChangeEvent, type SiteHeaderProps, type SiteHeaderRegionAttributes, type SiteHeaderTriggerAttributes, type SplitPaneAttributes, type SplitPaneOpenChangeEvent, type SplitPaneOrientation, type SplitPaneProps, type SplitPaneRegionAttributes, type WorkflowTimelineProps, type WorkflowTimelineStatus, type WorkflowTimelineOverallState, type WorkflowTimelineAttributes, type WorkflowTimelineStep, type WorkflowTimelineMessages } from '@gluonjs/organisms';

const shell = {
  header: html`<strong>GLUON GOODS</strong>`,
  navigation: html`<a href="/shop">Shop</a><a href="/bag">Bag</a>`,
  children: html`<h1>New arrivals</h1>`,
  footer: html`<small>Free shipping over €100</small>`,
} satisfies AppShellProps;
const adminAttributes: AdminShellAttributes = { class: 'catalog-admin-shell' };
const adminRegionAttributes: AdminShellRegionAttributes = { class: 'catalog-admin-region' };
const adminNavigationAttributes: AdminShellNavigationAttributes = { class: 'catalog-admin-navigation' };
const adminShell: AdminShellProps = { id: 'catalog-admin', header: html`<strong>Back office</strong>`, sidebar: html`<a href='/overview'>Overview</a><a href='/settings'>Settings</a>`, main: html`<h1>Workspace</h1>`, footer: html`<small>Tenant: Gluon Goods</small>`, attributes: adminAttributes, headerAttributes: adminRegionAttributes, sidebarAttributes: adminRegionAttributes, navigationAttributes: adminNavigationAttributes, mainAttributes: adminRegionAttributes, footerAttributes: adminRegionAttributes, sidebarLabel: 'Back office navigation' };
const asyncStatus: AsyncStateStatus = 'partial';
const asyncAttributes: AsyncStateAttributes = { class: 'recommendations-state' };
const asyncMessages: AsyncStateMessages = { partial: 'Recommendations are partially loaded.' };
const asyncState: AsyncStateProps = { id: 'recommendations', status: asyncStatus, heading: 'Recommendations', headingLevel: 2 satisfies AsyncStateHeadingLevel, partialContent: html`<p>Profile data is ready while recommendations refresh.</p>`, actions: html`<button type="button">Retry</button>`, messages: asyncMessages, attributes: asyncAttributes };
const product: ProductCardProduct = { id: 'orbit-lamp', title: 'Orbit lamp', description: 'Adjustable light for focused work.' };
const productCardAttributes: ProductCardAttributes = { class: 'catalog-product-card' };
const productCard: ProductCardProps = { product, href: '/products/orbit-lamp', media: html`<img src="/assets/orbit-lamp.webp" alt="" />`, price: '€128', availability: 'In stock', actions: html`<button type="button">Add to bag</button>`, attributes: productCardAttributes };
const productColumns: ProductGridColumns = 3;
const productGridAttributes: ProductGridAttributes = { class: 'catalog-product-grid' };
const productGrid: ProductGridProps = { items: [product], columns: productColumns, renderCard: (item) => ProductCard({ product: item, price: '€128' }), emptyContent: 'No products found.', attributes: productGridAttributes };
const galleryImage: ProductGalleryImage = { id: 'orbit-primary', src: '/assets/orbit-lamp.webp', alt: 'Orbit lamp', primary: true };
const galleryImageAttributes: ProductGalleryImageAttributes = { class: 'catalog-gallery-image', loading: 'lazy' };
const galleryAttributes: ProductGalleryAttributes = { class: 'catalog-product-gallery', style: { '--gluon-product-gallery-gap': '1rem' } };
const productGallery: ProductGalleryProps = { id: 'catalog-gallery', label: 'Orbit lamp gallery', images: [{ ...galleryImage, attributes: galleryImageAttributes }, { id: 'orbit-detail', src: '/assets/orbit-lamp.webp', alt: '' }], attributes: galleryAttributes };
const initialFocus: ConfirmationDialogInitialFocus = '[data-confirm-primary]';
const confirmationOptions = { initialFocus } satisfies ConfirmationDialogControllerOptions;
const confirmationController: ConfirmationDialogController = createConfirmationDialogController(confirmationOptions);
const confirmationAttributes = { '@close': () => console.log('closed') } satisfies ConfirmationDialogAttributes;
const confirmation = { id: 'archive-confirmation', title: 'Archive order?', description: 'The caller owns the archive mutation.', safeAction: 'Cancel', primaryAction: html`<button data-confirm-primary>Archive</button>`, dismissOnBackdrop: false, controller: confirmationController, attributes: confirmationAttributes } satisfies ConfirmationDialogProps;
const workflowStep: WorkflowTimelineStep = { id: 'review', label: 'Review', status: 'current' satisfies WorkflowTimelineStatus, role: 'Reviewer', evidence: 'Ticket 42' };
const workflowState: WorkflowTimelineOverallState = 'degraded';
const workflowAttributes: WorkflowTimelineAttributes = { 'aria-label': 'Order workflow' };
const workflowMessages: WorkflowTimelineMessages = { timeline: 'Ablauf', status: (status) => `Status: ${status}`, step: (position, total) => `${position} von ${total}`, evidence: 'Nachweis' };
const workflow: WorkflowTimelineProps = { id: 'order-workflow', steps: [workflowStep], state: workflowState, messages: workflowMessages, role: 'Operations', evidence: 'Import log 42', attributes: workflowAttributes };
const megaLink: MegaMenuLink = { id: 'orbit-lamp', label: 'Orbit lamp', href: '/products/orbit-lamp', description: 'Adjustable light for focused work.' };
const megaGroup: MegaMenuGroup = { id: 'lighting', label: 'Lighting', links: [megaLink] };
const megaAttributes: MegaMenuAttributes = { class: 'catalog-mega-menu' };
const megaTriggerAttributes: MegaMenuTriggerAttributes = { class: 'catalog-mega-trigger' };
const megaLinkAttributes: MegaMenuLinkAttributes = { class: 'catalog-mega-link' };
const megaOpenChangeEvent: MegaMenuOpenChangeEvent = new MouseEvent('open-change');
const megaMenu: MegaMenuProps = { id: 'shop-menu', label: 'Shop navigation', trigger: 'Shop', groups: [megaGroup], open: true, attributes: megaAttributes, triggerAttributes: megaTriggerAttributes, onOpenChange: (open, event) => console.log('shop menu', open, event.type) };
const headerAttributes: SiteHeaderAttributes = { class: 'catalog-site-header' };
const headerNavigationAttributes: SiteHeaderNavigationAttributes = { 'aria-label': 'Catalog navigation' };
const headerRegionAttributes: SiteHeaderRegionAttributes = { class: 'catalog-header-region' };
const headerTriggerAttributes: SiteHeaderTriggerAttributes = { class: 'catalog-header-trigger' };
const headerOpenChangeEvent: SiteHeaderOpenChangeEvent = new MouseEvent('mobile-open-change');
const header: SiteHeaderProps = { id: 'catalog-header', brand: html`<a href='/'>GLUON GOODS</a>`, navigation: html`<a href='/shop'>Shop</a>`, actions: html`<button type='button'>Search</button>`, mobileNavigation: html`<a href='/shop'>Shop</a>`, attributes: headerAttributes, navigationAttributes: headerNavigationAttributes, brandAttributes: headerRegionAttributes, triggerAttributes: headerTriggerAttributes, onMobileOpenChange: (open, event) => console.log('mobile header', open, event.type) };
const footerAttributes: SiteFooterAttributes = { class: 'catalog-site-footer' };
const footerNavigationAttributes: SiteFooterNavigationAttributes = { 'aria-label': 'Catalog footer navigation' };
const footerRegionAttributes: SiteFooterRegionAttributes = { class: 'catalog-footer-region' };
const footer: SiteFooterProps = { id: 'catalog-footer', brand: html`<a href='/'>GLUON GOODS</a>`, navigation: html`<a href='/shop'>Shop</a><a href='/journal'>Journal</a>`, legal: html`<a href='/privacy'>Privacy</a>`, meta: html`<small>© 2026 Gluon Goods</small>`, attributes: footerAttributes, navigationAttributes: footerNavigationAttributes, brandAttributes: footerRegionAttributes, legalAttributes: footerRegionAttributes, metaAttributes: footerRegionAttributes };
const pageLayoutAttributes: PageLayoutAttributes = { class: 'catalog-page-layout' };
const pageLayoutHeadingLevel: PageLayoutHeadingLevel = 1;
const pageLayout: PageLayoutProps = { id: 'catalog-page', title: 'Catalog', headingLevel: pageLayoutHeadingLevel, breadcrumbs: html`<a href='/'>Home</a> / Catalog`, actions: html`<button type='button'>Create</button>`, children: html`<p>Caller-owned page content.</p>`, aside: html`<p>Related filters.</p>`, footer: html`<small>Tenant-owned metadata.</small>`, attributes: pageLayoutAttributes };
const splitPaneAttributes: SplitPaneAttributes = { class: 'catalog-split-pane' };
const splitPaneOrientation: SplitPaneOrientation = 'horizontal';
const splitPaneOpenChangeEvent: SplitPaneOpenChangeEvent = new MouseEvent('collapse-change');
const splitPane: SplitPaneProps = { id: 'catalog-workspace', primary: html`<p>Caller-owned workspace.</p>`, secondary: html`<p>Caller-owned inspector.</p>`, orientation: splitPaneOrientation, secondaryLabel: 'Inspector', attributes: splitPaneAttributes, onSecondaryCollapsedChange: (collapsed, event) => console.log('inspector', collapsed, event.type) };
console.log(AdminShell(adminShell), AppShell(shell), AsyncState(asyncState), MegaMenu(megaMenu), PageLayout(pageLayout), ProductCard(productCard), ProductGallery(productGallery), ProductGrid(productGrid), SiteFooter(footer), SiteHeader(header), SplitPane(splitPane), ConfirmationDialog(confirmation), WorkflowTimeline(workflow), adminShellStyles, asyncStateStyles, confirmationDialogStyles, megaMenuStyles, organismStyles, pageLayoutStyles, productCardStyles, productGalleryStyles, productGridStyles, siteFooterStyles, splitPaneStyles, siteHeaderStyles, workflowTimelineStyles, organismManifest.entries, megaOpenChangeEvent, headerOpenChangeEvent, splitPaneOpenChangeEvent);

Version-matched documentation. Examples are checked against the public package contracts.