# All files / src/components/layout PageHeader.tsx

0% Statements 0/2
0% Branches 0/18
0% Functions 0/1
0% Lines 0/2

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79

     /**
     * PageHeader — standardized breadcrumb row with optional back-navigation and actions.
     *
     * @module
     */

    import type { JSX, ReactNode } from "react";
    import { ArrowLeft } from "lucide-react";
    import { Link } from "react-router";
    import { Breadcrumbs } from "../display/Breadcrumbs.js";
    import type { BreadcrumbSegment } from "../../utils/breadcrumbs.js";
    import { ICON_SM } from "../../utils/iconSize.js";
    import styles from "./PageHeader.module.scss";

    /** Props for {@link PageHeader}. */
    export interface PageHeaderProps {
      /** Breadcrumb segments to render. */
      segments: BreadcrumbSegment[];
      /** Optional back-navigation label (e.g., "Home"). Renders ArrowLeft + label. */
      backLabel?: string;
      /** URL to navigate to when the back button is clicked. */
      backUrl?: string;
      /** Optional callback for back navigation (overrides backUrl if provided). */
      onNavigateBack?: () => void;
      /** Optional actions to render in the right slot. */
      actions?: ReactNode;
    }

    /** Standardized page header with breadcrumbs, optional back-navigation, and actions. */
    export function PageHeader({
      segments,
      backLabel,
      backUrl,
      onNavigateBack,
      actions,
    }: PageHeaderProps): JSX.Element {
      const showBack = Boolean(backUrl || onNavigateBack);

      return (
        <header className={styles.pageHeader} data-testid="page-header">
          {showBack && (
            <>
              {onNavigateBack ? (
                <button
                  type="button"
                  className={styles.backButton}
                  onClick={onNavigateBack}
                  aria-label={backLabel ? `Back to ${backLabel}` : "Back"}
                  data-testid="page-header-back"
                >
                  <ArrowLeft size={ICON_SM} />
                  {backLabel && <span className={styles.backLabel}>{backLabel}</span>}
                </button>
              ) : backUrl ? (
                <Link
                  to={backUrl}
                  className={styles.backButton}
                  aria-label={backLabel ? `Back to ${backLabel}` : "Back"}
                  data-testid="page-header-back"
                >
                  <ArrowLeft size={ICON_SM} />
                  {backLabel && <span className={styles.backLabel}>{backLabel}</span>}
                </Link>
              ) : null}
              <span className={styles.backSeparator} aria-hidden="true">
                /
              </span>
            </>
          )}
          <Breadcrumbs segments={segments} />
          {actions && (
            <div className={styles.actions} data-testid="page-header-actions">
              {actions}
            </div>
          )}
        </header>
      );
    }