// Copyright (c) Meta Platforms, Inc. and affiliates. 'use client'; /** * @file LayoutHeader.tsx * @input Uses React StyleX * @output Exports LayoutHeader component and LayoutHeaderProps * @position Top bar / header area for Layout. Use for page titles, app bars, * toolbar areas, or any fixed-height content at the top of a layout. * * SYNC: When modified, update these files to stay in sync: * - /packages/core/src/Layout/Layout.doc.mjs * - /packages/core/src/Layout/LayoutHeader.doc.mjs * - /apps/storybook/stories/Layout.stories.tsx * - /packages/cli/assets/templates/blocks/components/Layout/ (showcase blocks) */ import type { AriaRole, ReactNode } from 'react'; import type { BaseProps } from "../BaseProps.js"; import { use } from 'react'; import * as stylex from "../style-runtime.js"; import { LayoutDividerContext } from "./LayoutDividerContext.js"; import "../theme/tokens.stylex.js"; import { colorVars, spacingVars } from "../theme/tokens.stylex.js"; import { mergeProps } from "../utils/index.js"; import type { SizeValue, SpacingStep } from "../utils/types.js"; import { themeProps } from "../utils/themeProps.js"; import { paddingStyles, paddingBlockEndStyles, containerPaddingInlineVarStyles, containerPaddingBlockStartVarStyles, containerPaddingBlockEndVarStyles } from "./padding.stylex.js"; const styles = { header: { kmuXW: "x2lah0s", $$css: true as const }, inner: { kB7OPa: "x9f619", ks0D6T: "xjl2t3p", kUOVxO: "xvueqy4", kZCmMZ: "x139j0dd", kwRFfy: "xpc6k2p", kLKAdn: "x81pis9", kGO01o: "xg476vw", "--container-padding-inline-start": "xdvaxxn", "--container-padding-inline-end": "xqpvj4r", "--container-padding-block-start": "xzz8v79", "--container-padding-block-end": "xi9ns85", $$css: true as const }, fullBleed: { kZCmMZ: "x1c1uobl", kwRFfy: "xyri2b", kLKAdn: "xexx8yu", kGO01o: "x18d9i69", "--container-padding-inline-start": "xrhngw9", "--container-padding-inline-end": "xjsfl84", "--container-padding-block-start": "x1047aw6", "--container-padding-block-end": "xax9j7h", $$css: true as const }, divider: { kt9PQ7: "xso031l", kfdmCh: "x1q0q8m5", kL6WhQ: "xw8gpjh", $$css: true as const } }; // Dynamic styles for sizing props const dynamicStyles = { sizing: (height: SizeValue | null) => [{ kZKoxP: height != null ? "x16ye13r" : height, $$css: true as const }, { "--x-height": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(height) }] }; export interface LayoutHeaderProps extends BaseProps { ref?: React.Ref; /** * Content to render inside the header. */ children?: ReactNode; /** * Adds a themed border at the bottom edge. * When false, spacing collapse is applied automatically for seamless visual flow. * When not set, falls back to the parent Layout's `defaultHasDividers`, then `false`. * @default false */ hasDivider?: boolean; /** * Height of the header. * Numbers are treated as pixels, strings are used as-is. */ height?: SizeValue; /** * Internal padding of the header using the spacing scale. * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10. * Overrides the default padding from the layout container. */ padding?: SpacingStep; /** * Block-end (bottom) padding override. Takes precedence over `padding` on * that edge only; the block-start edge and both inline edges are left alone. * `paddingBlockEnd={0}` docks the last child on the header's bottom edge, so * a tab strip's underline meets `hasDivider` with no hand-written margin. * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10. */ paddingBlockEnd?: SpacingStep; /** * Accessible label for the landmark. * Required when role is set and multiple landmarks of the same type exist. */ label?: string; /** * ARIA landmark role for accessibility. * Use 'banner' only for site-wide headers (not in nested layouts). */ role?: AriaRole; } /** * Top bar / header for Layout. Use for page titles, app bars, or toolbars. * Renders in the header slot with optional divider and padding control. * * Already provides its own padding — don't add padding to children. * Use `padding={0}` if your content manages its own padding (e.g. TopNav). * * @example * ``` * * Page Title} * content={...} * /> * * ``` */ export function LayoutHeader({ children, hasDivider, height, label, padding, paddingBlockEnd, role, xstyle, className, style, ref, ...props }: LayoutHeaderProps) { const dividerCtx = use(LayoutDividerContext); const resolvedHasDivider = hasDivider ?? dividerCtx?.defaultHasDividers ?? false; const isZeroPadding = padding === 0; return
{children}
; } LayoutHeader.displayName = 'LayoutHeader';