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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 105x 855x 855x 465x 105x 4x 4x 1x 3x 3x 3x 3x 1x 2x 2x 4x 2x 2x 105x 4x 864x 105x | import { ChevronRight } from "lucide-react";
import { type ReactNode } from "react";
import { Link } from "react-router";
import { sendGAEvent } from "@/utils/ReactGA/SendGAEvent";
type BreadCrumbsProps = {
options: BreadCrumbConfig[];
};
export type BreadCrumbConfig = {
default?: boolean;
order: number;
to: string;
displayText: string;
};
export const BreadCrumbs = ({ options }: BreadCrumbsProps) => {
const defaultBreadCrumb = options.find((option) => option.default);
return (
<BreadCrumbBar>
{defaultBreadCrumb && (
<BreadCrumb to={defaultBreadCrumb.to} showSeparator={false}>
{defaultBreadCrumb.displayText}
</BreadCrumb>
)}
{/* After this we map over the config and check to see if the breadcrumb needs to be displayed. Proper route paths are important here. It should be hierarchical */}
{options
.filter((option) => !option.default)
.toSorted((option, prevOption) => option.order - prevOption.order)
.map(({ displayText, to }, index, optionsArray) => {
return (
<BreadCrumb key={displayText} to={to} active={index !== optionsArray.length - 1}>
{displayText}
</BreadCrumb>
);
})}
</BreadCrumbBar>
);
};
type BreadCrumbProps = {
to: string;
active?: boolean;
showSeparator?: boolean;
separator?: ReactNode;
children?: string;
};
const triggerGAEvent = (children: string | undefined) => {
const pathName = window.location.pathname;
let submissionType;
if (pathName.includes("chip")) {
submissionType = "chip";
} else Iif (pathName.includes("medicaid")) {
submissionType = "medicaid";
} else Iif (pathName.includes("temporary-extensions")) {
submissionType = "temporary-extension";
} else Iif (pathName.includes("/waiver/b/b4/initial")) {
submissionType = "1915b_waiver_initial";
} else if (pathName.includes("/waiver/b/b4/renewal/")) {
submissionType = "1915b_waiver_renewal";
} else Iif (pathName.includes("/waiver/b/b4/amendment/")) {
submissionType = "1915b_waiver_ammendment";
} else Iif (pathName.includes("/waiver/app-k")) {
submissionType = "app-k";
}
if (submissionType) {
sendGAEvent("submit_breadcrumb_click", {
crumb_name: typeof children === "string" ? children : undefined,
submission_type: submissionType,
});
} else {
sendGAEvent("breadcrumb_click", {
breadcrumb_text: typeof children === "string" ? children : undefined,
});
}
};
export const BreadCrumb = ({
to,
separator = <BreadCrumbSeparator />,
showSeparator = true,
active = true,
children,
}: React.PropsWithChildren<BreadCrumbProps>) => {
return (
<li className="flex items-center text-sm">
{showSeparator && <span>{separator}</span>}
{active && (
<Link
to={to}
className="underline text-sky-700 hover:text-sky-800"
onClick={() => {
triggerGAEvent(children);
}}
>
{children}
</Link>
)}
{!active && (
<span className="whitespace-nowrap" aria-disabled>
{children}
</span>
)}
</li>
);
};
export const BreadCrumbSeparator = () => <ChevronRight className="w-5 h-5" />;
export const BreadCrumbBar = ({ children }: React.PropsWithChildren) => {
return (
<nav role="navigation" aria-label="breadcrumbs for spa or waiver choices" className="my-4">
<ul className="flex flex-wrap gap-1">{children}</ul>
</nav>
);
};
|