-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(add-breadcrumbs): Add Bread Crumbs to the Mako Web Application (#…
…162) * initial markup for the breadcrumb component * add unit tests * add initial breadcrumbs with light styles * rough draft breadcrumbs * update typescript in ui service * remove tsdoc support. nice to have, but doesn't belong in this effort * remove state from router. this isn't needed currently * remove breadcrumbs from welcome page (this was for testing before) * fix tests * add a comment as a reminder * add breadcrumbs to the various landing pages * change config to address verbiage issues * add breadcrumbs to package detail pages * fix deploy error with typescript * fix breadcrumb verbiage to match titles for landing pages
- Loading branch information
1 parent
f6f4174
commit d57f2df
Showing
11 changed files
with
1,394 additions
and
1,133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/services/ui/src/components/BreadCrumb/BreadCrumb.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { describe, test, expect, beforeAll, beforeEach } from "vitest"; | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { BreadCrumb, BreadCrumbBar } from "./BreadCrumb"; | ||
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom"; | ||
|
||
export const LocationDisplay = () => { | ||
const location = useLocation(); | ||
|
||
return <div data-testid="location-display">{location.pathname}</div>; | ||
}; | ||
|
||
describe("Bread Crumb Tests", () => { | ||
describe("Bread Crumb Routing", () => { | ||
test("Sucessfully navigate using breadcrumbs", async () => { | ||
render( | ||
<> | ||
<Routes> | ||
<Route path="/" /> | ||
<Route path="/test" /> | ||
<Route path="/test/:id" /> | ||
</Routes> | ||
<BreadCrumbBar> | ||
<BreadCrumb to="/test">Click Me</BreadCrumb> | ||
</BreadCrumbBar> | ||
<LocationDisplay /> | ||
</>, | ||
{ wrapper: BrowserRouter } | ||
); | ||
|
||
const user = userEvent.setup(); | ||
|
||
await user.click(screen.getByText(/click me/i)); | ||
expect(screen.getByText("/test")).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
describe("Bread Crumb Interations", async () => { | ||
beforeEach(() => { | ||
render( | ||
<BreadCrumbBar> | ||
<BreadCrumb data-testid="home" to="/"> | ||
Home | ||
</BreadCrumb> | ||
<BreadCrumb data-testid="dashboard" to="/test"> | ||
Test Dashboard | ||
</BreadCrumb> | ||
<BreadCrumb data-testid="item" to="/test/:id" active={false}> | ||
Test Item | ||
</BreadCrumb> | ||
</BreadCrumbBar>, | ||
{ | ||
wrapper: BrowserRouter, | ||
} | ||
); | ||
}); | ||
|
||
test("active element is styled different", async () => { | ||
const homeBreadCrumb = screen.getByText("Home"); | ||
const dashboardBreadCrumb = screen.getByText("Test Dashboard"); | ||
const itemBreadCrumb = screen.getByText("Test Item"); | ||
|
||
expect(homeBreadCrumb.classList.contains("underline")).toBeTruthy(); | ||
expect(dashboardBreadCrumb.classList.contains("underline")).toBeTruthy(); | ||
expect(itemBreadCrumb.classList.contains("underline")).toBeFalsy(); | ||
}); | ||
}); | ||
|
||
// TODO: Write a test to test the functionality of the BreadCrumbs component with a test config passed in | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { Link } from "react-router-dom"; | ||
import { type ReactNode } from "react"; | ||
import { ChevronRight } from "lucide-react"; | ||
import { BreadCrumbConfig } from "./bread-crumb-config"; | ||
|
||
type BreadCrumbsProps = { | ||
options: BreadCrumbConfig[]; | ||
}; | ||
|
||
export const BreadCrumbs = ({ options }: BreadCrumbsProps) => { | ||
const defaultBreadCrumb = options.find((option) => option.default); | ||
|
||
return ( | ||
<BreadCrumbBar> | ||
{defaultBreadCrumb && ( | ||
<BreadCrumb to={defaultBreadCrumb.to} showSeperator={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) | ||
.filter((option) => window.location.href.includes(option.to)) | ||
.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; | ||
showSeperator?: boolean; | ||
seperator?: ReactNode; | ||
}; | ||
|
||
export const BreadCrumb = ({ | ||
to, | ||
seperator = <BreadCrumbSeperator />, | ||
showSeperator = true, | ||
active = true, | ||
children, | ||
}: React.PropsWithChildren<BreadCrumbProps>) => { | ||
return ( | ||
<li className="flex items-center"> | ||
{showSeperator && <span>{seperator}</span>} | ||
|
||
{active && ( | ||
<Link to={to} className="underline text-sky-600 hover:text-sky-800"> | ||
{children} | ||
</Link> | ||
)} | ||
{!active && <span aria-disabled>{children}</span>} | ||
</li> | ||
); | ||
}; | ||
|
||
export const BreadCrumbSeperator = () => <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="mt-4" | ||
> | ||
<ul className="flex gap-1">{children}</ul> | ||
</nav> | ||
); | ||
}; |
90 changes: 90 additions & 0 deletions
90
src/services/ui/src/components/BreadCrumb/bread-crumb-config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { ROUTES } from "@/routes"; | ||
|
||
export type BreadCrumbConfig = { | ||
default?: boolean; | ||
order: number; | ||
to: string; | ||
displayText: string; | ||
}; | ||
|
||
export const BREAD_CRUMB_CONFIG_NEW_SUBMISSION: BreadCrumbConfig[] = [ | ||
{ | ||
default: true, | ||
displayText: "Dashboard", | ||
to: ROUTES.DASHBOARD, | ||
order: 1, | ||
}, | ||
{ | ||
displayText: "Submission Type", | ||
to: ROUTES.NEW_SUBMISSION_OPTIONS, | ||
order: 2, | ||
}, | ||
{ | ||
displayText: "SPA Type", | ||
to: ROUTES.SPA_SUBMISSION_OPTIONS, | ||
order: 3, | ||
}, | ||
{ | ||
displayText: "Waiver Type", | ||
to: ROUTES.WAIVER_SUBMISSION_OPTIONS, | ||
order: 3, | ||
}, | ||
{ | ||
displayText: "1915(b) Waiver Type", | ||
to: ROUTES.B_WAIVER_SUBMISSION_OPTIONS, | ||
order: 4, | ||
}, | ||
{ | ||
displayText: "Medicaid SPA Type", | ||
to: ROUTES.MEDICAID_SPA_SUB_OPTIONS, | ||
order: 4, | ||
}, | ||
{ | ||
displayText: "CHIP SPA Type", | ||
to: ROUTES.CHIP_SPA_SUB_OPTIONS, | ||
order: 4, | ||
}, | ||
{ | ||
displayText: "CHIP Eligibility SPAs", | ||
to: ROUTES.CHIP_ELIGIBILITY_LANDING, | ||
order: 5, | ||
}, | ||
{ | ||
displayText: | ||
"Medicaid Alternative Benefits Plans (ABP), and Medicaid Premiums and Cost Sharing", | ||
to: ROUTES.MEDICAID_ABP_LANDING, | ||
order: 5, | ||
}, | ||
{ | ||
displayText: | ||
"Medicaid Eligibility, Enrollment, Administration, and Health Homes", | ||
to: ROUTES.MEDICAID_ELIGIBILITY_LANDING, | ||
order: 5, | ||
}, | ||
{ | ||
displayText: "1915(b)(4) FFS Selective Contracting Waiver Types", | ||
to: ROUTES.B4_WAIVER_OPTIONS, | ||
order: 5, | ||
}, | ||
{ | ||
displayText: "1915(b) Comprehensive (Capitated) Waiver Authority Types", | ||
to: ROUTES.BCAP_WAIVER_OPTIONS, | ||
order: 5, | ||
}, | ||
]; | ||
|
||
export const BREAD_CRUMB_CONFIG_PACKAGE_DETAILS = (data: { | ||
id: string; | ||
}): BreadCrumbConfig[] => [ | ||
{ | ||
displayText: "Dashboard", | ||
order: 1, | ||
default: true, | ||
to: ROUTES.DASHBOARD, | ||
}, | ||
{ | ||
displayText: `${data.id}`, | ||
order: 2, | ||
to: ROUTES.DETAILS, | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./BreadCrumb"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.