Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
51dc3f8
refactor: refactoring navbars
jderochervlk Feb 8, 2026
be70e99
making progress on the nav
jderochervlk Feb 8, 2026
0808cbc
scrolling works again
jderochervlk Feb 10, 2026
949389f
refactoring
jderochervlk Feb 10, 2026
bd7b348
mobile overlay works
jderochervlk Feb 15, 2026
482b405
tests are passing
jderochervlk Feb 15, 2026
80b836d
done with mobile overlay
jderochervlk Feb 16, 2026
3eb6f20
screenshots
jderochervlk Feb 16, 2026
53682b0
removing top padding
jderochervlk Feb 16, 2026
876486a
fix playground
jderochervlk Feb 16, 2026
57dae95
remove unused open
jderochervlk Feb 16, 2026
b7de7a6
fix issue with homepage reloading nonstop
jderochervlk Feb 16, 2026
86f806b
restor mdx route
jderochervlk Feb 16, 2026
09e42d4
remove dummy page
jderochervlk Feb 16, 2026
f642c1c
fixing docs
jderochervlk Feb 16, 2026
6e0bc9d
fix syntax lookup
jderochervlk Feb 16, 2026
c671d16
remove build errors and warnings
jderochervlk Feb 16, 2026
e0bf40d
commit screenshot changes
jderochervlk Feb 16, 2026
21a333c
chore: update vitest screenshots [skip ci]
jderochervlk Feb 16, 2026
f4ec369
remove unused values
jderochervlk Feb 16, 2026
f66a9f1
remove unused file
jderochervlk Feb 16, 2026
5e5c0e1
tidying up
jderochervlk Feb 16, 2026
76414e8
fix version dropdown
jderochervlk Feb 17, 2026
95b07eb
Update src/components/Search.res
jderochervlk Feb 18, 2026
a15986e
Update src/components/BreadCrumbs.res
jderochervlk Feb 18, 2026
588fc92
Fix mobile overlay not closing on navigation link clicks (#1198)
Copilot Feb 21, 2026
0f26f30
PR feedback.
jderochervlk Feb 21, 2026
17f7d42
PR feedback
jderochervlk Feb 21, 2026
2605d2a
cleanup
jderochervlk Feb 21, 2026
04ba370
Fix sidebar scrolling when it shouldn't
jderochervlk Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ jobs:
run: yarn playwright install --with-deps
- name: Vitest
run: yarn ci:test
- name: Commit and Push changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update vitest screenshots [skip ci]"
file_pattern: "**/__screenshots__/**/*.png"
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ __tests__/**/*.jsx
_scripts

# Local env files
.env.local
.env.local

# Vitest screenshots
!__tests__/__screenshots__/**/*
.vitest-attachments
28 changes: 0 additions & 28 deletions __tests__/Example.test.res

This file was deleted.

101 changes: 101 additions & 0 deletions __tests__/NavbarPrimary_.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
open ReactRouter
open Vitest

test("desktop has everything visible", async () => {
await viewport(1440, 500)

let screen = await render(
<BrowserRouter>
<NavbarPrimary />
</BrowserRouter>,
)

let leftContent = await screen->getByTestId("navbar-primary-left-content")

await element(await leftContent->getByText("Docs"))->toBeVisible
await element(await leftContent->getByText("Playground"))->toBeVisible
await element(await leftContent->getByText("Blog"))->toBeVisible
await element(await leftContent->getByText("Community"))->toBeVisible

let rightContent = await screen->getByTestId("navbar-primary-right-content")

await element(await rightContent->getByLabelText("GitHub"))->toBeVisible
await element(await rightContent->getByLabelText("X (formerly Twitter)"))->toBeVisible
await element(await rightContent->getByLabelText("Bluesky"))->toBeVisible
await element(await rightContent->getByLabelText("Forum"))->toBeVisible

let navbar = await screen->getByTestId("navbar-primary")

await element(navbar)->toMatchScreenshot("desktop-navbar-primary")
})

test("tablet has everything visible", async () => {
await viewport(900, 500)

let screen = await render(
<BrowserRouter>
<NavbarPrimary />
</BrowserRouter>,
)

let leftContent = await screen->getByTestId("navbar-primary-left-content")

await element(await leftContent->getByText("Docs"))->toBeVisible
await element(await leftContent->getByText("Playground"))->toBeVisible
await element(await leftContent->getByText("Blog"))->toBeVisible
await element(await leftContent->getByText("Community"))->toBeVisible

let rightContent = await screen->getByTestId("navbar-primary-right-content")

await element(await rightContent->getByLabelText("GitHub"))->toBeVisible
await element(await rightContent->getByLabelText("X (formerly Twitter)"))->toBeVisible
await element(await rightContent->getByLabelText("Bluesky"))->toBeVisible
await element(await rightContent->getByLabelText("Forum"))->toBeVisible

let navbar = await screen->getByTestId("navbar-primary")

await element(navbar)->toMatchScreenshot("tablet-navbar-primary")
})

test("phone has some things hidden and a mobile nav that can be toggled", async () => {
await viewport(600, 1200)

let screen = await render(
<BrowserRouter>
<NavbarPrimary />
</BrowserRouter>,
)

let leftContent = await screen->getByTestId("navbar-primary-left-content")

await element(await leftContent->getByText("Docs"))->toBeVisible
await element(await leftContent->getByText("Playground"))->notToBeVisible
await element(await leftContent->getByText("Blog"))->notToBeVisible
await element(await leftContent->getByText("Community"))->notToBeVisible

let rightContent = await screen->getByTestId("navbar-primary-right-content")

await element(await rightContent->getByLabelText("GitHub"))->notToBeVisible
await element(await rightContent->getByLabelText("X (formerly Twitter)"))->notToBeVisible
await element(await rightContent->getByLabelText("Bluesky"))->notToBeVisible
await element(await rightContent->getByLabelText("Forum"))->notToBeVisible

let mobileNav = await screen->getByTestId("mobile-nav")
await element(mobileNav)->notToBeVisible

let button = await screen->getByTestId("toggle-mobile-overlay")

await element(button)->toBeVisible

await button->click

let mobileNavAfterOpen = await screen->getByTestId("mobile-nav")

await element(mobileNavAfterOpen)->toBeVisible

let navbar = await screen->getByTestId("navbar-primary")

await element(navbar)->toMatchScreenshot("mobile-navbar-primary")

await element(mobileNavAfterOpen)->toMatchScreenshot("mobile-overlay-navbar-primary")
})
93 changes: 93 additions & 0 deletions __tests__/NavbarTertiary_.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
open ReactRouter
open Vitest

let sidebarContent =
<aside>
<div dataTestId="sidebar-version-select"> {React.string("v12 (latest)")} </div>
<div dataTestId="sidebar-categories">
<div> {React.string("OVERVIEW")} </div>
<div> {React.string("Introduction")} </div>
</div>
</aside>

let breadcrumbs =
<span dataTestId="breadcrumbs"> {React.string("Docs / Language Manual / Installation")} </span>

let editLink = <a dataTestId="edit-link" href="#"> {React.string("Edit")} </a>

test("desktop shows breadcrumbs and edit link", async () => {
await viewport(1440, 500)

let screen = await render(
<BrowserRouter>
<NavbarTertiary sidebar=sidebarContent>
breadcrumbs
editLink
</NavbarTertiary>
</BrowserRouter>,
)

let navbar = await screen->getByTestId("navbar-tertiary")

await element(navbar)->toBeVisible

let crumbs = await screen->getByTestId("breadcrumbs")
await element(crumbs)->toBeVisible

let edit = await screen->getByTestId("edit-link")
await element(edit)->toBeVisible

await element(navbar)->toMatchScreenshot("desktop-navbar-tertiary")
})

test("mobile shows breadcrumbs and drawer button", async () => {
await viewport(600, 1200)

let screen = await render(
<BrowserRouter>
<NavbarTertiary sidebar=sidebarContent>
breadcrumbs
editLink
</NavbarTertiary>
</BrowserRouter>,
)

let navbar = await screen->getByTestId("navbar-tertiary")
await element(navbar)->toBeVisible

let crumbs = await screen->getByTestId("breadcrumbs")
await element(crumbs)->toBeVisible

let edit = await screen->getByTestId("edit-link")
await element(edit)->toBeVisible

await element(navbar)->toMatchScreenshot("mobile-navbar-tertiary")
})

test("mobile drawer can be toggled open", async () => {
await viewport(600, 1200)

let screen = await render(
<BrowserRouter>
<NavbarTertiary sidebar=sidebarContent>
breadcrumbs
editLink
</NavbarTertiary>
</BrowserRouter>,
)

// Sidebar dialog should not be visible initially
let sidebar = await screen->getByTestId("sidebar-categories")
await element(sidebar)->notToBeVisible

// Click the drawer toggle button
let drawerButton = await screen->getByRole(#button)
await drawerButton->click

// Sidebar content should now be visible
let sidebarAfter = await screen->getByTestId("sidebar-categories")
await element(sidebarAfter)->toBeVisible

let versionSelect = await screen->getByTestId("sidebar-version-select")
await element(versionSelect)->toBeVisible
})
80 changes: 80 additions & 0 deletions __tests__/VersionSelect_.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
open Vitest

test("renders current version label", async () => {
let screen = await render(<VersionSelect />)

let el = await screen->getByTestId("version-select")
await element(el)->toBeVisible

let label = await screen->getByText("v12 (latest)")
await element(label)->toBeVisible
})

test("clicking button shows older versions", async () => {
let screen = await render(<VersionSelect />)

// Menu should be hidden initially
let v11 = await screen->getByText("v11")
await element(v11)->notToBeVisible

// Click the trigger button
let button = await screen->getByRole(#button)
await button->click

// Older versions should now be visible
let v11After = await screen->getByText("v11")
await element(v11After)->toBeVisible

let v9 = await screen->getByText("v9.1 - v10.1")
await element(v9)->toBeVisible

let v8 = await screen->getByText("v8.2 - v9.0")
await element(v8)->toBeVisible

let v6 = await screen->getByText("v6.0 - v8.1")
await element(v6)->toBeVisible
})

test("clicking button again closes older versions", async () => {
let screen = await render(<VersionSelect />)

let button = await screen->getByRole(#button)

// Open
await button->click
let v11 = await screen->getByText("v11")
await element(v11)->toBeVisible

// Close
await button->click
let v11After = await screen->getByText("v11")
await element(v11After)->notToBeVisible
})

test("multiple instances have unique popover IDs", async () => {
let screen = await render(
<div>
<div dataTestId="first">
<VersionSelect />
</div>
<div dataTestId="second">
<VersionSelect />
</div>
</div>,
)

let first = await screen->getByTestId("first")
let second = await screen->getByTestId("second")

// Click the button in the first instance
let firstButton = await first->getByRole(#button)
await firstButton->click

// First instance menu should be visible
let firstV11 = await first->getByText("v11")
await element(firstV11)->toBeVisible

// Second instance menu should remain hidden
let secondV11 = await second->getByText("v11")
await element(secondV11)->notToBeVisible
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 5 additions & 20 deletions app/root.res
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,6 @@ open ReactRouter

@react.component
let default = () => {
let {pathname} = ReactRouter.useLocation()
let (isOverlayOpen, setOverlayOpen) = React.useState(_ => false)
let (isScrollLockEnabled, setIsScrollLockEnabled) = React.useState(_ => false)

React.useEffect(() => {
// When the path changes close the sidebar and disable scroll lock
setOverlayOpen(_ => false)
setIsScrollLockEnabled(_ => false)
None
}, [pathname])

<html lang="en">
<head>
<style> {React.string("html {opacity:0;}")} </style>
Expand All @@ -65,15 +54,11 @@ let default = () => {
/>
<meta charSet="UTF-8" />
</head>
<body className={isScrollLockEnabled ? "overflow-hidden" : ""}>
<ScrollLockContext.Provider lockState=(isScrollLockEnabled, setIsScrollLockEnabled)>
<EnableCollapsibleNavbar isEnabled={!isOverlayOpen}>
<Navigation isOverlayOpen setOverlayOpen />
<Outlet />
<ScrollRestoration />
<Scripts />
</EnableCollapsibleNavbar>
</ScrollLockContext.Provider>
<body>
<NavbarPrimary />
<Outlet />
<ScrollRestoration />
<Scripts />
</body>
</html>
}
4 changes: 3 additions & 1 deletion app/routes.res
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ let stdlibRoutes =
let beltRoutes =
beltPaths->Array.map(path => route(path, "./routes/ApiRoute.jsx", ~options={id: path}))

let mdxRoutes = mdxRoutes("./routes/MdxRoute.jsx")

let default = [
index("./routes/LandingPageRoute.jsx"),
route("packages", "./routes/PackagesRoute.jsx"),
Expand All @@ -42,6 +44,6 @@ let default = [
route("docs/manual/api/dom", "./routes/ApiRoute.jsx", ~options={id: "api-dom"}),
...stdlibRoutes,
...beltRoutes,
...mdxRoutes("./routes/MdxRoute.jsx"),
...mdxRoutes,
route("*", "./routes/NotFoundRoute.jsx"),
]
Loading