{
  "$schema": "https://pdfx.akashpise.dev/schema/registry-item.json",
  "name": "page-footer",
  "type": "registry:ui",
  "title": "PageFooter",
  "description": "Fixed or inline page footer with 6 layout variants and contact info support",
  "files": [
    {
      "path": "components/pdfx/page-footer/pdfx-page-footer.tsx",
      "content": "import { Text as PDFText, StyleSheet, View } from '@react-pdf/renderer';\nimport type { Style } from '@react-pdf/types';\nimport { usePdfxTheme, useSafeMemo } from '../lib/pdfx-theme-context';\ntype PdfxTheme = ReturnType<typeof usePdfxTheme>;\n\nexport type PageFooterVariant =\n  | 'simple'\n  | 'centered'\n  | 'branded'\n  | 'minimal'\n  | 'three-column'\n  | 'detailed';\n\n/**\n * Footer row with layout variants, optional sticky or fixed positioning, and contact info support.\n * Props - `leftText` | `rightText` | `centerText` | `variant` | `background` | `textColor` | `marginTop` | `address` | `phone` | `email` | `website` | `fixed` | `sticky` | `pagePadding` | `noWrap` | `style`\n * @see {@link PageFooterProps}\n */\nexport interface PageFooterProps {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  leftText?: string;\n  rightText?: string;\n  centerText?: string;\n  /**\n   * @default 'simple'\n   */\n  variant?: PageFooterVariant;\n  background?: string;\n  textColor?: string;\n  marginTop?: number;\n  address?: string;\n  phone?: string;\n  email?: string;\n  website?: string;\n  /**\n   * @default false\n   */\n  fixed?: boolean;\n  /**\n   * @default false\n   */\n  sticky?: boolean;\n  /**\n   * @default 0\n   */\n  pagePadding?: number;\n  /**\n   * @default true\n   */\n  noWrap?: boolean;\n}\n\nconst THEME_COLOR_KEYS = ['foreground','muted','mutedForeground','primary','primaryForeground','accent','destructive','success','warning','info'] as const;\nfunction resolveColor(value: string, colors: Record<string, string>): string {\n  return THEME_COLOR_KEYS.includes(value as (typeof THEME_COLOR_KEYS)[number]) ? colors[value] : value;\n}\nfunction createPageFooterStyles(t: PdfxTheme) {\n  const { spacing, fontWeights } = t.primitives;\n  const c = t.colors;\n  const { body } = t.typography;\n\n  const textBase = {\n    fontFamily: body.fontFamily,\n    fontSize: t.primitives.typography.xs,\n    color: c.mutedForeground,\n    lineHeight: body.lineHeight,\n  };\n\n  return StyleSheet.create({\n    simpleContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'center',\n      justifyContent: 'space-between',\n      paddingTop: spacing[3],\n      borderTopWidth: spacing[0.5],\n      borderTopColor: c.border,\n      borderTopStyle: 'solid',\n    },\n\n    centeredContainer: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      paddingTop: spacing[3],\n      borderTopWidth: spacing[0.5],\n      borderTopColor: c.border,\n      borderTopStyle: 'solid',\n    },\n\n    minimalContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'center',\n      justifyContent: 'space-between',\n      paddingTop: spacing[1],\n      paddingBottom: spacing[1],\n    },\n\n    brandedContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'center',\n      justifyContent: 'space-between',\n      backgroundColor: c.primary,\n      paddingHorizontal: spacing[4],\n      paddingVertical: spacing[3],\n    },\n\n    textLeft: {\n      ...textBase,\n      flex: 1,\n    },\n    textCenter: {\n      ...textBase,\n      textAlign: 'center',\n      flex: 1,\n    },\n    textRight: {\n      ...textBase,\n      textAlign: 'right',\n    },\n    textCenteredVariant: {\n      ...textBase,\n      textAlign: 'center',\n      marginBottom: spacing[1],\n    },\n    textBranded: {\n      ...textBase,\n      color: c.primaryForeground,\n      fontWeight: fontWeights.medium,\n    },\n    textBrandedRight: {\n      ...textBase,\n      color: c.primaryForeground,\n      textAlign: 'right',\n    },\n\n    threeColumnContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'flex-start',\n      justifyContent: 'space-between',\n      paddingTop: spacing[3],\n      borderTopWidth: spacing[0.5],\n      borderTopColor: c.border,\n      borderTopStyle: 'solid',\n    },\n    threeColumnLeft: {\n      display: 'flex',\n      flexDirection: 'column',\n      flex: 1,\n    },\n    threeColumnCenter: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      flex: 1,\n    },\n    threeColumnRight: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'flex-end',\n      flex: 1,\n    },\n    companyName: {\n      ...textBase,\n      fontWeight: fontWeights.medium,\n      color: c.foreground,\n    },\n    contactInfoCenter: {\n      ...textBase,\n      textAlign: 'center',\n      fontSize: t.primitives.typography.xs - 1,\n      marginTop: spacing[0.5],\n    },\n\n    detailedContainer: {\n      display: 'flex',\n      flexDirection: 'column',\n      paddingTop: spacing[3],\n      borderTopWidth: spacing[1],\n      borderTopColor: c.border,\n      borderTopStyle: 'solid',\n    },\n    detailedTopRow: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'flex-start',\n      justifyContent: 'space-between',\n      marginBottom: spacing[2],\n    },\n    detailedLeft: {\n      display: 'flex',\n      flexDirection: 'column',\n      flex: 1,\n    },\n    detailedRight: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'flex-end',\n    },\n    companyBold: {\n      ...textBase,\n      fontWeight: fontWeights.bold,\n      color: c.foreground,\n    },\n    detailedPageNumber: {\n      ...textBase,\n      textAlign: 'center',\n      paddingTop: spacing[2],\n      borderTopWidth: spacing[0.5],\n      borderTopColor: c.border,\n      borderTopStyle: 'solid',\n    },\n  });\n}\n\nexport function PageFooter({\n  leftText,\n  rightText,\n  centerText,\n  variant = 'simple',\n  background,\n  textColor,\n  marginTop,\n  address,\n  phone,\n  email,\n  website,\n  fixed = false,\n  sticky = false,\n  pagePadding = 0,\n  noWrap = true,\n  style,\n}: PageFooterProps) {\n  const theme = usePdfxTheme();\n  const styles = useSafeMemo(() => createPageFooterStyles(theme), [theme]);\n  // sticky implies fixed; marginTop is irrelevant with absolute positioning\n  const isFixed = fixed || sticky;\n  const mt = sticky ? 0 : (marginTop ?? theme.spacing.sectionGap);\n  const resolvedTextColor = textColor ? resolveColor(textColor, theme.colors) : undefined;\n  const stickyStyle: Style = sticky\n    ? { position: 'absolute', bottom: pagePadding, left: pagePadding, right: pagePadding }\n    : {};\n\n  function applyOverrides(base: Style[]): Style[] {\n    if (background) base.push({ backgroundColor: resolveColor(background, theme.colors) });\n    if (style) base.push(style);\n    if (sticky) base.push(stickyStyle);\n    return base;\n  }\n\n  if (variant === 'branded') {\n    const containerStyles = applyOverrides([styles.brandedContainer, { marginTop: mt }]);\n\n    const lStyle: Style[] = [styles.textBranded];\n    const rStyle: Style[] = [styles.textBrandedRight];\n    if (resolvedTextColor) {\n      lStyle.push({ color: resolvedTextColor });\n      rStyle.push({ color: resolvedTextColor });\n    }\n\n    return (\n      <View wrap={!noWrap} fixed={isFixed} style={containerStyles}>\n        {leftText && <PDFText style={lStyle}>{leftText}</PDFText>}\n        {rightText && <PDFText style={rStyle}>{rightText}</PDFText>}\n      </View>\n    );\n  }\n\n  if (variant === 'centered') {\n    const containerStyles = applyOverrides([styles.centeredContainer, { marginTop: mt }]);\n\n    const tStyle: Style[] = [styles.textCenteredVariant];\n    if (resolvedTextColor) tStyle.push({ color: resolvedTextColor });\n\n    return (\n      <View wrap={!noWrap} fixed={isFixed} style={containerStyles}>\n        {leftText && <PDFText style={tStyle}>{leftText}</PDFText>}\n        {rightText && <PDFText style={tStyle}>{rightText}</PDFText>}\n      </View>\n    );\n  }\n\n  if (variant === 'three-column') {\n    const containerStyles = applyOverrides([styles.threeColumnContainer, { marginTop: mt }]);\n\n    const leftStyle: Style[] = [styles.companyName];\n    const centerStyle: Style[] = [styles.contactInfoCenter];\n    const rightStyle: Style[] = [styles.textRight];\n    if (resolvedTextColor) {\n      leftStyle.push({ color: resolvedTextColor });\n      centerStyle.push({ color: resolvedTextColor });\n      rightStyle.push({ color: resolvedTextColor });\n    }\n\n    return (\n      <View wrap={!noWrap} fixed={isFixed} style={containerStyles}>\n        <View style={styles.threeColumnLeft}>\n          {leftText && <PDFText style={leftStyle}>{leftText}</PDFText>}\n          {address && <PDFText style={styles.textLeft}>{address}</PDFText>}\n        </View>\n        <View style={styles.threeColumnCenter}>\n          {phone && <PDFText style={centerStyle}>{phone}</PDFText>}\n          {email && <PDFText style={centerStyle}>{email}</PDFText>}\n          {website && <PDFText style={centerStyle}>{website}</PDFText>}\n        </View>\n        <View style={styles.threeColumnRight}>\n          {rightText && <PDFText style={rightStyle}>{rightText}</PDFText>}\n        </View>\n      </View>\n    );\n  }\n\n  if (variant === 'detailed') {\n    const containerStyles = applyOverrides([styles.detailedContainer, { marginTop: mt }]);\n\n    const companyStyle: Style[] = [styles.companyBold];\n    const addrStyle: Style[] = [styles.textLeft];\n    const contactStyle: Style[] = [styles.textRight];\n    const pageNumStyle: Style[] = [styles.detailedPageNumber];\n    if (resolvedTextColor) {\n      companyStyle.push({ color: resolvedTextColor });\n      addrStyle.push({ color: resolvedTextColor });\n      contactStyle.push({ color: resolvedTextColor });\n      pageNumStyle.push({ color: resolvedTextColor });\n    }\n\n    return (\n      <View wrap={!noWrap} fixed={isFixed} style={containerStyles}>\n        <View style={styles.detailedTopRow}>\n          <View style={styles.detailedLeft}>\n            {leftText && <PDFText style={companyStyle}>{leftText}</PDFText>}\n            {address && <PDFText style={addrStyle}>{address}</PDFText>}\n          </View>\n          <View style={styles.detailedRight}>\n            {phone && <PDFText style={contactStyle}>{`Phone: ${phone}`}</PDFText>}\n            {email && <PDFText style={contactStyle}>{`Email: ${email}`}</PDFText>}\n            {website && <PDFText style={contactStyle}>{`Web: ${website}`}</PDFText>}\n          </View>\n        </View>\n        {rightText && <PDFText style={pageNumStyle}>{rightText}</PDFText>}\n      </View>\n    );\n  }\n\n  if (variant === 'minimal') {\n    const containerStyles = applyOverrides([styles.minimalContainer, { marginTop: mt }]);\n\n    const lStyle: Style[] = [styles.textLeft];\n    const rStyle: Style[] = [styles.textRight];\n    if (resolvedTextColor) {\n      lStyle.push({ color: resolvedTextColor });\n      rStyle.push({ color: resolvedTextColor });\n    }\n\n    return (\n      <View wrap={!noWrap} fixed={isFixed} style={containerStyles}>\n        {leftText && <PDFText style={lStyle}>{leftText}</PDFText>}\n        {rightText && <PDFText style={rStyle}>{rightText}</PDFText>}\n      </View>\n    );\n  }\n\n  const containerStyles = applyOverrides([styles.simpleContainer, { marginTop: mt }]);\n\n  const lStyle: Style[] = [styles.textLeft];\n  const cStyle: Style[] = [styles.textCenter];\n  const rStyle: Style[] = [styles.textRight];\n  if (resolvedTextColor) {\n    lStyle.push({ color: resolvedTextColor });\n    cStyle.push({ color: resolvedTextColor });\n    rStyle.push({ color: resolvedTextColor });\n  }\n\n  return (\n    <View wrap={!noWrap} fixed={isFixed} style={containerStyles}>\n      {leftText && <PDFText style={lStyle}>{leftText}</PDFText>}\n      {centerText && <PDFText style={cStyle}>{centerText}</PDFText>}\n      {rightText && <PDFText style={rStyle}>{rightText}</PDFText>}\n    </View>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "dependencies": [
    "@react-pdf/renderer"
  ],
  "registryDependencies": [
    "theme"
  ]
}