{"version":3,"file":"AppBar.cjs","names":[],"sources":["../../../src/components/AppBar/AppBar.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — a top bar is a slot layout: leading (leading,\n * showBack, onBack, backLabel, backIcon, brand), centre (title, centered) and\n * trailing (actions), plus the chrome it sits in (sticky, tone, bordered, safeArea).\n * Every one of those is a real decision an app makes per screen, and the alternative\n * to accepting them is the app rebuilding the bar around the parts it wanted to\n * change.\n */\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { cn } from \"@/utils/cn\";\nimport { useStickyBodyWarning } from \"./use-sticky-body-warning\";\nimport styles from \"./AppBar.module.css\";\n\nexport type AppBarTone = \"surface\" | \"primary\" | \"transparent\";\n\nexport interface AppBarProps extends Omit<HTMLAttributes<HTMLElement>, \"title\"> {\n    /** Page title — string or any node. Rendered as the bar's `<h1>`. */\n    title?: ReactNode;\n    /**\n     * Replace the whole left slot. When set, the auto back button and `brand`\n     * are ignored — you own the leading content.\n     */\n    leading?: ReactNode;\n    /** Show a back button in the left slot. Ignored when `leading` is set. */\n    showBack?: boolean;\n    /**\n     * Back-button handler. Defaults to `window.history.back()`. With a router,\n     * pass `onBack={() => navigate(-1)}`.\n     */\n    onBack?: () => void;\n    /** Accessible label for the back button. Default `\"Go back\"`. */\n    backLabel?: string;\n    /** Custom back icon. Default a left arrow. */\n    backIcon?: ReactNode;\n    /** Brand / logo node shown in the left slot (after the back button). */\n    brand?: ReactNode;\n    /** Right slot — action buttons / menu. One node or many. */\n    actions?: ReactNode;\n    /** Center the title (three-column grid). Default `false` (left-aligned). */\n    centered?: boolean;\n    /**\n     * Stick to the top of the scroll container. Default `true`.\n     *\n     * The page has to leave the body out of the scrolling: `body { overflow-x:\n     * hidden }` makes the body a scroll container and the bar scrolls away with\n     * the content. Use `overflow-x: clip` on `html` and `body` instead — in\n     * development the bar says so in the console when it detects it.\n     */\n    sticky?: boolean;\n    /** Visual tone. Default `\"surface\"`. */\n    tone?: AppBarTone;\n    /** Thin bottom border. Default `true`. */\n    bordered?: boolean;\n    /** Add `env(safe-area-inset-top)` padding (iOS notch / PWA). Default `true`. */\n    safeArea?: boolean;\n}\n\n/**\n * Mobile-first top app bar for PWAs — leading (back / brand) + title +\n * trailing actions, sticky with safe-area padding out of the box.\n *\n * Consumers customise via tokens (`--tempest-*`) and slots; the SDK ships the\n * layout, sticky/safe-area behaviour, and accessible back button so apps don't\n * hand-roll one per screen. For a desktop three-slot nav use [[Navbar]].\n *\n * @example\n * // Detail screen with back + a trailing action\n * <AppBar\n *     title=\"Profile\"\n *     showBack\n *     onBack={() => navigate(-1)}\n *     actions={<IconButton icon={<Settings />} onClick={openSettings} />}\n * />\n *\n * @example\n * // Home screen — brand left, centered title disabled\n * <AppBar brand={<Logo />} actions={<UserMenu />} />\n */\nexport function AppBar({\n    title,\n    leading,\n    showBack = false,\n    onBack,\n    backLabel = \"Go back\",\n    backIcon,\n    brand,\n    actions,\n    centered = false,\n    sticky = true,\n    tone = \"surface\",\n    bordered = true,\n    safeArea = true,\n    className,\n    ...props\n}: AppBarProps) {\n    useStickyBodyWarning(sticky);\n\n    const handleBack = onBack ?? (() => window.history.back());\n\n    const leadingContent = leading ?? (\n        <>\n            {showBack && (\n                <button\n                    type=\"button\"\n                    className={styles.iconBtn}\n                    onClick={handleBack}\n                    aria-label={backLabel}\n                >\n                    {backIcon ?? <ArrowLeft size={22} aria-hidden=\"true\" />}\n                </button>\n            )}\n            {brand && <span className={styles.brand}>{brand}</span>}\n        </>\n    );\n\n    return (\n        <header\n            className={cn(\n                styles.bar,\n                styles[tone],\n                centered && styles.centered,\n                sticky && styles.sticky,\n                bordered && styles.bordered,\n                safeArea && styles.safeArea,\n                className,\n            )}\n            {...props}\n        >\n            <div className={styles.leading}>{leadingContent}</div>\n            {title != null && title !== \"\" && (\n                <h1 className={styles.title} aria-live=\"polite\">\n                    {title}\n                </h1>\n            )}\n            <div className={styles.actions}>{actions}</div>\n        </header>\n    );\n}\n"],"mappings":"+KA+EA,SAAgB,EAAO,CACnB,QACA,UACA,WAAW,GACX,SACA,YAAY,UACZ,WACA,QACA,UACA,WAAW,GACX,SAAS,GACT,OAAO,UACP,WAAW,GACX,WAAW,GACX,YACA,GAAG,GACS,CACZ,EAAA,qBAAqB,CAAM,EAE3B,IAAM,EAAa,QAAiB,OAAO,QAAQ,KAAK,GAElD,EAAiB,IACnB,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,CACK,IACG,EAAA,EAAA,IAAA,CAAC,SAAD,CACI,KAAK,SACL,UAAW,EAAA,QAAO,QAClB,QAAS,EACT,aAAY,EAEX,SAAA,IAAY,EAAA,EAAA,IAAA,CAAC,EAAA,UAAD,CAAW,KAAM,GAAI,cAAY,MAAQ,CAAA,CAClD,CAAA,EAEX,IAAS,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,MAAQ,SAAA,CAAY,CAAA,CACxD,CAAA,CAAA,EAGN,OACI,EAAA,EAAA,KAAA,CAAC,SAAD,CACI,UAAW,EAAA,GACP,EAAA,QAAO,IACP,EAAA,QAAO,GACP,GAAY,EAAA,QAAO,SACnB,GAAU,EAAA,QAAO,OACjB,GAAY,EAAA,QAAO,SACnB,GAAY,EAAA,QAAO,SACnB,CACJ,EACA,GAAI,EAVR,SAAA,EAYI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,QAAU,SAAA,CAAoB,CAAA,EACpD,GAAS,MAAQ,IAAU,KACxB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAA,QAAO,MAAO,YAAU,SAClC,SAAA,CACD,CAAA,GAER,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,QAAO,QAAU,SAAA,CAAa,CAAA,CAC1C,GAEhB"}