// Copyright (c) Meta Platforms, Inc. and affiliates. 'use client'; /** * @file LayoutFooter.tsx * @input Uses React StyleX * @output Exports LayoutFooter component and LayoutFooterProps * @position Bottom bar / footer area for Layout. Use for action bars, * pagination, status bars, or any fixed-height content at the bottom of a layout. * * SYNC: When modified, update these files to stay in sync: * - /packages/core/src/Layout/Layout.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, containerPaddingInlineVarStyles, containerPaddingBlockStartVarStyles, containerPaddingBlockEndVarStyles } from "./padding.stylex.js"; const styles = { footer: { kmuXW: "x2lah0s", $$css: true as const }, inner: { kB7OPa: "x9f619", ks0D6T: "xjl2t3p", kUOVxO: "xvueqy4", kZCmMZ: "x139j0dd", kwRFfy: "xpc6k2p", kLKAdn: "xqty4a", kGO01o: "xon7vh3", "--container-padding-inline-start": "xdvaxxn", "--container-padding-inline-end": "xqpvj4r", "--container-padding-block-start": "xjmgx01", "--container-padding-block-end": "x1xjq73n", $$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: { kEafiO: "x178xt8z", kPef9Z: "x13fuv20", kLZC3w: "x1pc3f07", $$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 LayoutFooterProps extends BaseProps { ref?: React.Ref; /** * Content to render inside the footer. */ children?: ReactNode; /** * Adds a themed border at the top 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 footer. * Numbers are treated as pixels, strings are used as-is. */ height?: SizeValue; /** * Internal padding of the footer 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; /** * 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 'contentinfo' only for site-wide footers (not in nested layouts). */ role?: AriaRole; } /** * Bottom bar / footer for Layout. Use for action bars, pagination, or status bars. * Renders in the footer 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. * * @example * ``` * * ...} * footer={Actions} * /> * * ``` */ export function LayoutFooter({ children, hasDivider, height, label, padding, role, xstyle, className, style, ref, ...props }: LayoutFooterProps) { const dividerCtx = use(LayoutDividerContext); const resolvedHasDivider = hasDivider ?? dividerCtx?.defaultHasDividers ?? false; const isZeroPadding = padding === 0; return
{children}
; } LayoutFooter.displayName = 'LayoutFooter';