Skip to content
BigBang

Popular

    ↑↓Navigate↵OpenEscClose
    TR

    Templates

    PrintShell

    An A4-proportioned shell for printable documents and statements; a page on screen, plain black and white on paper.

    PrintShell shows an A4-proportioned page on screen and leaves only the document when printed. Receipts, statements and summaries sit in this shell.

    The brand and mode switches in the page header restyle the preview too. In the browser’s print preview the action buttons, shadow and border disappear.

    Live example, StorybookOpen in Storybook
    Live example, StorybookOpen in Storybook
    Region Element Note
    Actions actions Print and download buttons; a named toolbar, hidden on paper with print:hidden.
    Sheet article Named by its h1; at most 832 px wide (A4 ratio).
    Header header Brand on the left; title, document number and date on the right.
    Body children Facts in a DescriptionList, figures in a Table.
    Footer footer Page note and verification code.
    Medium Layout
    Screen, below 640 px The sheet takes the full width; the header stacks.
    Screen, 640 px and up A centred sheet on a grey surface with space.3xl padding.
    Paper Surface, shadow, border and padding go away; the app’s print CSS (@page) sets A4 size and 12 mm margins. The docs CSP forbids inline <style> blocks, so @page lives in the app, not in the shell.
    • The document has one article and one h1; sections start at h2.
    • Figures sit in table cells matched to header cells (th); the total row has a row header too.
    • Status is read from the StatusBadge text, not colour alone, so it survives black and white printing.
    • Masked values (•••• 1234) stay masked on screen and on paper.
    • The action buttons are grouped in a “Document actions” toolbar for screen readers.
    import { Heading, Inline, Stack, Text } from '@bigbang/ui';
    import type { ReactNode } from 'react';
    import { type Lang, LangProvider } from '../../patterns/lang';
    const copy = {
    tr: { product: 'Ürün adı', actions: 'Belge işlemleri' },
    en: { product: 'Product name', actions: 'Document actions' },
    };
    export type PrintShellProps = {
    /** The document's h1, such as "İşlem özeti". */
    title: string;
    /** Document number, date and similar facts under the title. */
    meta?: ReactNode;
    /** Print and download buttons; they are hidden on paper. */
    actions?: ReactNode;
    /** The document body. */
    children: ReactNode;
    /** Page note and verification code at the bottom of the sheet. */
    footer?: ReactNode;
    /** Logo or product name in the header. */
    brand?: ReactNode;
    lang?: Lang;
    };
    /**
    * Template for printable documents: an A4-proportioned sheet on screen, plain black on white on paper.
    * Screen-only parts carry `print:hidden`; the app's print CSS sets `@page` size and margins.
    */
    export function PrintShell({ title, meta, actions, children, footer, brand, lang = 'tr' }: PrintShellProps) {
    const t = copy[lang];
    return (
    <LangProvider lang={lang}>
    <div className="flex w-full flex-col items-center gap-lg bg-surface-sunken px-lg py-2xl print:block print:bg-transparent print:p-0" data-template="print-shell">
    {actions ? (
    <div className="flex w-full max-w-[52rem] justify-end print:hidden" role="toolbar" aria-label={t.actions} data-part="actions">
    <Inline gap="sm">{actions}</Inline>
    </div>
    ) : null}
    <article
    className="w-full max-w-[52rem] rounded-md border border-line-subtle bg-surface-raised p-3xl shadow-raised print:max-w-none print:rounded-none print:border-0 print:p-0 print:shadow-none"
    aria-labelledby={`print-title-${lang}`}
    data-part="sheet"
    >
    <Stack gap="2xl">
    <header className="flex flex-wrap items-start justify-between gap-lg border-b border-line-default pb-lg">
    <div>
    {brand ?? <Text weight="medium">{t.product}</Text>}
    </div>
    <Stack gap="xs" align="end">
    <Heading level={1} size="lg" id={`print-title-${lang}`}>
    {title}
    </Heading>
    {meta ? (
    <Text size="sm" tone="subtle">
    {meta}
    </Text>
    ) : null}
    </Stack>
    </header>
    <div data-part="body">{children}</div>
    {footer ? (
    <footer className="border-t border-line-subtle pt-lg">
    <Text size="sm" tone="subtle">
    {footer}
    </Text>
    </footer>
    ) : null}
    </Stack>
    </article>
    </div>
    </LangProvider>
    );
    }

    Heading, Text, Stack, Inline. Block built on this shell: Receipt and statement.