feat(ui): add typed navbar menu items
Quality / quality (ubuntu-latest) (push) Failing after 11m12s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-24 21:36:46 +05:30
parent fc1eea3939
commit 9d64ec60c4
9 changed files with 396 additions and 27 deletions
+51
View File
@@ -0,0 +1,51 @@
import { expect, test } from "bun:test";
import type { NavbarItem } from "../src/navigation";
const items = [
{ type: "link", label: "Pricing", href: "/pricing" },
{
type: "dropdown",
label: "Company",
items: [{ label: "About", href: "/about" }],
},
{
type: "mega",
label: "Products",
mega: {
variant: "icon-grid",
density: "compact",
panelWidth: "2xl",
panelAlign: "center",
columnCount: 3,
fullWidth: true,
rail: [{ label: "All products", href: "/products", icon: "icon-products" }],
columns: [
{
heading: "Work",
items: [
{
label: "Projects",
href: "/projects",
icon: "icon-projects",
description: "Plan and deliver work",
badge: "New",
},
],
},
],
featured: {
title: "What's new",
image: "/new.png",
actionLabel: "Explore",
actionHref: "/new",
},
footer: "One connected platform",
actionLabel: "View all products",
actionHref: "/products",
},
},
] satisfies NavbarItem[];
test("navbar item contract covers links, dropdowns, and complete mega menus", () => {
expect(items.map((item) => item.type)).toEqual(["link", "dropdown", "mega"]);
});
+20 -12
View File
@@ -239,7 +239,9 @@ test("navbar supports brands, nested menus, actions, utility slots, and public e
expect(defaults.get("openOnHover")).toBe("false");
expect(defaults.get("maxWidth")).toBe('"full"');
expect(source).toContain("item.children");
expect(source).toContain("child.children");
expect(source).toContain("dropdownGroupItems(child)");
expect(source).toContain('itemType(item) === "mega"');
expect(source).toContain("megaData(item).featured");
expect(source).toContain("wrn-navbar__dropdown--{item.type || 'dropdown'}");
const outputs = new Set(contract.outputs.map((output) => output.name));
for (const event of ["toggle", "open", "close", "select", "action"]) {
@@ -304,13 +306,19 @@ test("navbar renders a brand, nested dropdowns, mega groups, and actions", async
{
label: "Safety",
type: "mega",
columns: 2,
children: [
{
label: "Resources",
children: [{ label: "Guidance", href: "/guidance" }],
},
],
mega: {
variant: "icon-grid",
columnCount: 2,
rail: [{ label: "Overview", href: "/safety" }],
columns: [
{
heading: "Resources",
items: [{ label: "Guidance", href: "/guidance", badge: "New" }],
},
],
featured: { title: "Safety report", actionLabel: "Read report" },
actionLabel: "All safety resources",
},
},
],
actions: [{ label: "Sign in", href: "/login", variant: "primary" }],
@@ -320,7 +328,9 @@ test("navbar renders a brand, nested dropdowns, mega groups, and actions", async
expect(html).toContain("Public portal");
expect(html).toContain("Reports");
expect(html).toContain("Guidance");
expect(html).toContain("wrn-navbar__dropdown--mega");
expect(html).toContain("wrn-navbar__mega");
expect(html).toContain("Safety report");
expect(html).toContain("All safety resources");
expect(html).toContain("data-wrn-navbar");
expect(html).toContain('name="wrn-navbar-menu"');
expect(html).toContain("Sign in");
@@ -2951,9 +2961,7 @@ test("mega menu supports rails, icons, badges, media, featured content and foote
heading: "Products",
description: "Choose a workspace",
image: "/products.png",
items: [
{ label: "CRM", description: "Customer records", icon: "icon-crm", badge: "New" },
],
items: [{ label: "CRM", description: "Customer records", icon: "icon-crm", badge: "New" }],
actionLabel: "All products",
},
],