{
  "$schema": "https://pdfx.akashpise.dev/schema/registry-item.json",
  "name": "page-header",
  "type": "registry:ui",
  "title": "PageHeader",
  "description": "Fixed or inline page header with 7 layout variants including logo support",
  "files": [
    {
      "path": "components/pdfx/page-header/pdfx-page-header.tsx",
      "content": "import { Text as PDFText, StyleSheet, View } from '@react-pdf/renderer';\nimport type { Style } from '@react-pdf/types';\nimport type { ReactNode } from 'react';\nimport { usePdfxTheme, useSafeMemo } from '../lib/pdfx-theme-context';\ntype PdfxTheme = ReturnType<typeof usePdfxTheme>;\n\nexport type PageHeaderVariant =\n  | 'simple'\n  | 'centered'\n  | 'minimal'\n  | 'branded'\n  | 'logo-left'\n  | 'logo-right'\n  | 'two-column';\n\n/**\n * Header row with layout variants, logo support, and optional fixed positioning.\n * Props - `title` | `subtitle` | `rightText` | `rightSubText` | `variant` | `background` | `titleColor` | `marginBottom` | `address` | `phone` | `email` | `logo` | `fixed` | `noWrap` | `style`\n * @see {@link PageHeaderProps}\n */\nexport interface PageHeaderProps {\n  /** Custom styles to merge with component defaults */\n  style?: Style;\n  title: string;\n  subtitle?: string;\n  rightText?: string;\n  rightSubText?: string;\n  /**\n   * @default 'simple'\n   */\n  variant?: PageHeaderVariant;\n  background?: string;\n  titleColor?: string;\n  marginBottom?: number;\n  address?: string;\n  phone?: string;\n  email?: string;\n  logo?: ReactNode;\n  /**\n   * @default false\n   */\n  fixed?: boolean;\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 createPageHeaderStyles(t: PdfxTheme) {\n  const { spacing, borderRadius, fontWeights } = t.primitives;\n  const c = t.colors;\n  const { heading, body } = t.typography;\n\n  return StyleSheet.create({\n    simpleContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'flex-start',\n      justifyContent: 'space-between',\n      paddingBottom: spacing[4],\n      borderBottomWidth: spacing[0.5],\n      borderBottomColor: c.border,\n      borderBottomStyle: 'solid',\n    },\n    simpleLeft: {\n      display: 'flex',\n      flexDirection: 'column',\n      flex: 1,\n    },\n    simpleRight: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'flex-end',\n    },\n\n    centeredContainer: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      paddingBottom: spacing[4],\n      borderBottomWidth: spacing[0.5],\n      borderBottomColor: c.border,\n      borderBottomStyle: 'solid',\n    },\n\n    minimalContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'center',\n      justifyContent: 'space-between',\n      borderBottomWidth: spacing[1],\n      borderBottomColor: c.primary,\n      borderBottomStyle: 'solid',\n      paddingBottom: spacing[3],\n    },\n    minimalLeft: {\n      flex: 1,\n    },\n    minimalRight: {\n      alignItems: 'flex-end',\n    },\n\n    brandedContainer: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      backgroundColor: c.primary,\n      padding: spacing[6],\n      borderRadius: borderRadius.sm,\n    },\n\n    title: {\n      fontFamily: heading.fontFamily,\n      fontSize: heading.fontSize.h3,\n      fontWeight: fontWeights.bold,\n      color: c.foreground,\n      lineHeight: heading.lineHeight,\n      marginBottom: 0,\n    },\n    titleCentered: {\n      textAlign: 'center',\n    },\n    titleBranded: {\n      color: c.primaryForeground,\n    },\n    titleMinimal: {\n      fontSize: heading.fontSize.h3,\n      fontWeight: fontWeights.bold,\n    },\n\n    subtitle: {\n      fontFamily: body.fontFamily,\n      fontSize: body.fontSize,\n      color: c.mutedForeground,\n      marginTop: spacing[1],\n      lineHeight: body.lineHeight,\n    },\n    subtitleCentered: {\n      textAlign: 'center',\n    },\n    subtitleBranded: {\n      color: c.primaryForeground,\n      marginTop: spacing[1],\n    },\n\n    rightText: {\n      fontFamily: body.fontFamily,\n      fontSize: body.fontSize,\n      color: c.foreground,\n      fontWeight: fontWeights.medium,\n      textAlign: 'right',\n    },\n    rightSubText: {\n      fontFamily: body.fontFamily,\n      fontSize: t.primitives.typography.xs,\n      color: c.mutedForeground,\n      textAlign: 'right',\n      marginTop: spacing[1],\n    },\n\n    logoLeftContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'center',\n      paddingBottom: spacing[4],\n      borderBottomWidth: spacing[0.5],\n      borderBottomColor: c.border,\n      borderBottomStyle: 'solid',\n    },\n    logoContainer: {\n      marginRight: spacing[4],\n      width: 48,\n      height: 48,\n    },\n    logoContent: {\n      flex: 1,\n      display: 'flex',\n      flexDirection: 'column',\n    },\n\n    logoRightContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'center',\n      justifyContent: 'space-between',\n      paddingBottom: spacing[4],\n      borderBottomWidth: spacing[0.5],\n      borderBottomColor: c.border,\n      borderBottomStyle: 'solid',\n    },\n    logoRightContent: {\n      flex: 1,\n      display: 'flex',\n      flexDirection: 'column',\n    },\n    logoRightLogoContainer: {\n      marginLeft: spacing[4],\n      width: 48,\n      height: 48,\n    },\n\n    twoColumnContainer: {\n      display: 'flex',\n      flexDirection: 'row',\n      alignItems: 'flex-start',\n      justifyContent: 'space-between',\n      paddingBottom: spacing[4],\n      borderBottomWidth: spacing[0.5],\n      borderBottomColor: c.border,\n      borderBottomStyle: 'solid',\n    },\n    twoColumnLeft: {\n      display: 'flex',\n      flexDirection: 'column',\n      flex: 1,\n    },\n    twoColumnRight: {\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'flex-end',\n    },\n    contactInfo: {\n      fontFamily: body.fontFamily,\n      fontSize: t.primitives.typography.xs,\n      color: c.mutedForeground,\n      textAlign: 'right',\n      marginTop: spacing[0.5],\n    },\n  });\n}\n\nexport function PageHeader({\n  title,\n  subtitle,\n  rightText,\n  rightSubText,\n  variant = 'simple',\n  background,\n  titleColor,\n  marginBottom,\n  logo,\n  address,\n  phone,\n  email,\n  fixed = false,\n  noWrap = true,\n  style,\n}: PageHeaderProps) {\n  const theme = usePdfxTheme();\n  const styles = useSafeMemo(() => createPageHeaderStyles(theme), [theme]);\n  const mb = marginBottom ?? theme.spacing.sectionGap;\n\n  if (variant === 'branded') {\n    const containerStyles: Style[] = [styles.brandedContainer, { marginBottom: mb }];\n    if (background) {\n      containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n    }\n    if (style) containerStyles.push(style);\n\n    const titleStyles: Style[] = [styles.title, styles.titleBranded, styles.titleCentered];\n    if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n    return (\n      <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n        <PDFText style={titleStyles}>{title}</PDFText>\n        {subtitle && (\n          <PDFText style={[styles.subtitle, styles.subtitleBranded]}>{subtitle}</PDFText>\n        )}\n      </View>\n    );\n  }\n\n  if (variant === 'centered') {\n    const containerStyles: Style[] = [styles.centeredContainer, { marginBottom: mb }];\n    if (background) {\n      containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n    }\n    if (style) containerStyles.push(style);\n\n    const titleStyles: Style[] = [styles.title, styles.titleCentered];\n    if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n    return (\n      <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n        <PDFText style={titleStyles}>{title}</PDFText>\n        {subtitle && (\n          <PDFText style={[styles.subtitle, styles.subtitleCentered]}>{subtitle}</PDFText>\n        )}\n      </View>\n    );\n  }\n\n  if (variant === 'logo-right') {\n    const containerStyles: Style[] = [styles.logoRightContainer, { marginBottom: mb }];\n    if (background) {\n      containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n    }\n    if (style) containerStyles.push(style);\n\n    const titleStyles: Style[] = [styles.title];\n    if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n    return (\n      <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n        <View style={styles.logoRightContent}>\n          <PDFText style={titleStyles}>{title}</PDFText>\n          {subtitle && <PDFText style={styles.subtitle}>{subtitle}</PDFText>}\n        </View>\n        {logo && <View style={styles.logoRightLogoContainer}>{logo}</View>}\n      </View>\n    );\n  }\n\n  if (variant === 'logo-left') {\n    const containerStyles: Style[] = [styles.logoLeftContainer, { marginBottom: mb }];\n    if (background) {\n      containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n    }\n    if (style) containerStyles.push(style);\n\n    const titleStyles: Style[] = [styles.title];\n    if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n    return (\n      <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n        {logo && <View style={styles.logoContainer}>{logo}</View>}\n        <View style={styles.logoContent}>\n          <PDFText style={titleStyles}>{title}</PDFText>\n          {subtitle && <PDFText style={styles.subtitle}>{subtitle}</PDFText>}\n        </View>\n        {(rightText || rightSubText) && (\n          <View style={styles.simpleRight}>\n            {rightText && <PDFText style={styles.rightText}>{rightText}</PDFText>}\n            {rightSubText && <PDFText style={styles.rightSubText}>{rightSubText}</PDFText>}\n          </View>\n        )}\n      </View>\n    );\n  }\n\n  if (variant === 'two-column') {\n    const containerStyles: Style[] = [styles.twoColumnContainer, { marginBottom: mb }];\n    if (background) {\n      containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n    }\n    if (style) containerStyles.push(style);\n\n    const titleStyles: Style[] = [styles.title];\n    if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n    return (\n      <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n        <View style={styles.twoColumnLeft}>\n          <PDFText style={titleStyles}>{title}</PDFText>\n          {subtitle && <PDFText style={styles.subtitle}>{subtitle}</PDFText>}\n        </View>\n        {(address || phone || email) && (\n          <View style={styles.twoColumnRight}>\n            {address && <PDFText style={styles.contactInfo}>{address}</PDFText>}\n            {phone && <PDFText style={styles.contactInfo}>{phone}</PDFText>}\n            {email && <PDFText style={styles.contactInfo}>{email}</PDFText>}\n          </View>\n        )}\n      </View>\n    );\n  }\n\n  if (variant === 'minimal') {\n    const containerStyles: Style[] = [styles.minimalContainer, { marginBottom: mb }];\n    if (background) {\n      containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n    }\n    if (style) containerStyles.push(style);\n\n    const titleStyles: Style[] = [styles.title, styles.titleMinimal];\n    if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n    return (\n      <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n        <View style={styles.minimalLeft}>\n          <PDFText style={titleStyles}>{title}</PDFText>\n          {subtitle && <PDFText style={styles.subtitle}>{subtitle}</PDFText>}\n        </View>\n        {(rightText || rightSubText) && (\n          <View style={styles.minimalRight}>\n            {rightText && <PDFText style={styles.rightText}>{rightText}</PDFText>}\n            {rightSubText && <PDFText style={styles.rightSubText}>{rightSubText}</PDFText>}\n          </View>\n        )}\n      </View>\n    );\n  }\n\n  const containerStyles: Style[] = [styles.simpleContainer, { marginBottom: mb }];\n  if (background) {\n    containerStyles.push({ backgroundColor: resolveColor(background, theme.colors) });\n  }\n  if (style) containerStyles.push(style);\n\n  const titleStyles: Style[] = [styles.title];\n  if (titleColor) titleStyles.push({ color: resolveColor(titleColor, theme.colors) });\n\n  return (\n    <View wrap={!noWrap} fixed={fixed} style={containerStyles}>\n      <View style={styles.simpleLeft}>\n        <PDFText style={titleStyles}>{title}</PDFText>\n        {subtitle && <PDFText style={styles.subtitle}>{subtitle}</PDFText>}\n      </View>\n      {(rightText || rightSubText) && (\n        <View style={styles.simpleRight}>\n          {rightText && <PDFText style={styles.rightText}>{rightText}</PDFText>}\n          {rightSubText && <PDFText style={styles.rightSubText}>{rightSubText}</PDFText>}\n        </View>\n      )}\n    </View>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "dependencies": [
    "@react-pdf/renderer"
  ],
  "registryDependencies": [
    "theme"
  ]
}