Skip to content
BigBang

Popular

    ↑↓Navigate↵OpenEscClose
    TR

    Templates

    AppShell template

    The signed-in page layout; navigation, top bar, page header and content width.

    This template sets up the AppShell component at page level: navigation groups, top bar, PageHeader and a content container. The dashboard, list, settings and account blocks sit inside it.

    The brand and mode switches in the page header restyle the preview too. Collapse the sidebar to icons with its button; in a narrow window the menu becomes a slide-in panel.

    Live example, StorybookOpen in Storybook
    Live example, StorybookOpen in Storybook
    Live example, StorybookOpen in Storybook
    Region Element Note
    Skip link AppShell The first tab stop; moves to main.
    Sidebar nav “General” and a collapsible “Administration” group; the current page has aria-current="page".
    Top bar header A search button, the Notification centre, the Account menu and, on narrow screens, the menu button.
    Page header PageHeader The single h1, description, optional breadcrumbs and page actions.
    Content Container width="lg" for dashboards and lists, md for forms and settings.

    The document <title> reads Page · Product name.

    Width Layout
    Below 1024 px Sidebar hidden; the top bar button opens a panel that slides in from the start edge (motion.drawer).
    1024 px and up A 256 px sidebar; 48 px when collapsed, labels kept for screen readers.
    1440 px and up Content is limited by Container, so line length stays readable.
    • Landmarks: a named nav, header and main; the skip link moves focus to main.
    • On a page change, focus goes to the new page’s h1; the routing layer does this.
    • The collapse button has aria-expanded and aria-controls.
    • The narrow-screen menu traps focus, closes with Escape and returns focus to the menu button.
    import { AppShell, Button, Container, Icon, NavGroup, NavItem, PageHeader, Stack } from '@bigbang/ui';
    import type { BreadcrumbItem, IconName } from '@bigbang/ui';
    import type { ReactNode } from 'react';
    import { AccountMenu } from '../../blocks/account-menu/AccountMenu';
    import { NotificationsCentre } from '../../blocks/notifications-centre/NotificationsCentre';
    import { type Lang, LangProvider } from '../../patterns/lang';
    const copy = {
    tr: {
    product: 'Ürün adı',
    general: 'Genel',
    admin: 'Yönetim',
    search: 'Ara',
    pages: { home: 'Ana sayfa', projects: 'Projeler', records: 'Kayıtlar', reports: 'Raporlar', team: 'Ekip', account: 'Hesap', settings: 'Ayarlar' },
    },
    en: {
    product: 'Product name',
    general: 'General',
    admin: 'Administration',
    search: 'Search',
    pages: { home: 'Home', projects: 'Projects', records: 'Records', reports: 'Reports', team: 'Team', account: 'Account', settings: 'Settings' },
    },
    };
    export type AppPage = keyof (typeof copy)['tr']['pages'];
    const general: { id: AppPage; icon: IconName; badge?: number }[] = [
    { id: 'home', icon: 'home' },
    { id: 'projects', icon: 'layout-grid' },
    { id: 'records', icon: 'list', badge: 3 },
    { id: 'reports', icon: 'file' },
    ];
    const admin: { id: AppPage; icon: IconName }[] = [
    { id: 'team', icon: 'user' },
    { id: 'account', icon: 'user' },
    { id: 'settings', icon: 'settings' },
    ];
    export type AppShellTemplateProps = {
    /** The current page: marks the navigation item and names the page. */
    current: AppPage;
    /** Page title (h1); defaults to the navigation label of `current`. */
    title?: string;
    description?: string;
    breadcrumbs?: readonly BreadcrumbItem[];
    /** Page-level actions at the end of the header. */
    actions?: ReactNode;
    /** Shows the header skeleton while the page loads. */
    loading?: boolean;
    /** Content width: `lg` for dashboards and lists, `md` for forms and settings. */
    width?: 'md' | 'lg' | 'full';
    children: ReactNode;
    defaultCollapsed?: boolean;
    /** Opens the notifications panel or the account menu of the header on first render. */
    headerOpen?: 'notifications' | 'account';
    /** `empty` starts the notifications centre with no notifications. */
    notifications?: 'some' | 'empty';
    lang?: Lang;
    };
    /**
    * The signed-in page template: AppShell navigation and a top bar with search, notifications and the
    * account menu, a PageHeader with the page's h1,
    * and the content in a Container. Blocks fill `children`.
    */
    export function AppShellTemplate({ current, title, description, breadcrumbs, actions, loading, width = 'lg', children, defaultCollapsed, headerOpen, notifications = 'some', lang = 'tr' }: AppShellTemplateProps) {
    const t = copy[lang];
    const mainId = `main-${current}-${lang}`;
    return (
    <LangProvider lang={lang}>
    <AppShell
    mainId={mainId}
    className="min-h-[44rem]"
    {...(defaultCollapsed === undefined ? {} : { defaultCollapsed })}
    brand={<strong className="type-label-md text-fg-default">{t.product}</strong>}
    header={
    <div className="ms-auto flex items-center gap-sm">
    <Button variant="secondary" size="sm" startIcon={<Icon name="search" />}>
    {t.search}
    </Button>
    <NotificationsCentre lang={lang} state={notifications} defaultOpen={headerOpen === 'notifications'} />
    <AccountMenu lang={lang} defaultOpen={headerOpen === 'account'} />
    </div>
    }
    nav={
    <>
    <NavGroup label={t.general}>
    {general.map((item) => (
    <NavItem key={item.id} href="#" label={t.pages[item.id]} icon={item.icon} current={item.id === current} {...(item.badge ? { badge: item.badge } : {})} />
    ))}
    </NavGroup>
    <NavGroup label={t.admin} collapsible>
    {admin.map((item) => (
    <NavItem key={item.id} href="#" label={t.pages[item.id]} icon={item.icon} current={item.id === current} />
    ))}
    </NavGroup>
    </>
    }
    >
    <Container size={width} className="py-2xl">
    <Stack gap="2xl">
    <PageHeader
    title={title ?? t.pages[current]}
    {...(description ? { description } : {})}
    {...(breadcrumbs ? { breadcrumbs } : {})}
    {...(actions ? { actions } : {})}
    {...(loading ? { loading } : {})}
    />
    {children}
    </Stack>
    </Container>
    </AppShell>
    </LangProvider>
    );
    }

    AppShell, PageHeader, Container, Button, Breadcrumbs. Blocks built on this template: Dashboard, Empty dashboard, List and filters, Settings, Account overview.