feat(ui): add in-flow floating navbar
Quality / quality (windows-latest) (push) Waiting to run
Quality / quality (ubuntu-latest) (push) Failing after 9m54s

This commit is contained in:
2026-08-24 19:47:47 +05:30
parent f9e285b182
commit 270040fb5f
7 changed files with 43 additions and 6 deletions
+1 -1
View File
@@ -688,7 +688,7 @@
}, },
"packages/ui": { "packages/ui": {
"name": "@wrnexus/ui", "name": "@wrnexus/ui",
"version": "0.8.26", "version": "0.8.27",
"dependencies": { "dependencies": {
"@wrnexus/core": "workspace:*", "@wrnexus/core": "workspace:*",
}, },
+1 -1
View File
@@ -60,7 +60,7 @@
"packages/ui/components/MetricGrid.wrn": "1fcebf51dcbe8520fe16bda904c1ef206c25c3900438d53877492c64ea21a1a5", "packages/ui/components/MetricGrid.wrn": "1fcebf51dcbe8520fe16bda904c1ef206c25c3900438d53877492c64ea21a1a5",
"packages/ui/components/Modal.wrn": "7fa4b877772736f29f690e24d8742922b310397ef3083f0b78acb67a9f0d14b2", "packages/ui/components/Modal.wrn": "7fa4b877772736f29f690e24d8742922b310397ef3083f0b78acb67a9f0d14b2",
"packages/ui/components/Nav.wrn": "c45b0ecb42250f4b3ede33c8932a025f789dda9ef48dbf332459ae458163e69a", "packages/ui/components/Nav.wrn": "c45b0ecb42250f4b3ede33c8932a025f789dda9ef48dbf332459ae458163e69a",
"packages/ui/components/Navbar.wrn": "9095876ad737e9d85c6ba38963b777c29b54c095f024c4e7f4325067039fe07f", "packages/ui/components/Navbar.wrn": "ce33334b98a363ea2c3e4ba111077ff2f3dc875f87e839729cce365789de6f65",
"packages/ui/components/PageHeader.wrn": "321cde36ce8d521a57901033d46e8b437f42e558cca27f49ca26f7172aff1d54", "packages/ui/components/PageHeader.wrn": "321cde36ce8d521a57901033d46e8b437f42e558cca27f49ca26f7172aff1d54",
"packages/ui/components/Pagination.wrn": "d54226705d4556f76ee5f0d6ae82d101ca6d006397756d547a9aa5954415ba39", "packages/ui/components/Pagination.wrn": "d54226705d4556f76ee5f0d6ae82d101ca6d006397756d547a9aa5954415ba39",
"packages/ui/components/PinInput.wrn": "4dc398456f6392d7925db941debb484c7cb0358ecef527f696fe5ec4800a7602", "packages/ui/components/PinInput.wrn": "4dc398456f6392d7925db941debb484c7cb0358ecef527f696fe5ec4800a7602",
+1 -1
View File
@@ -826,7 +826,7 @@ Theme-aware, responsive nav component.
Theme-aware, responsive navbar component. Theme-aware, responsive navbar component.
- Mount: `data-component="Navbar"` - Mount: `data-component="Navbar"`
- Props: `size: string = "default"`, `color: string = "primary"`, `label: string = "Primary navigation"`, `topbarLabel: string = "Utility navigation"`, `brand: Record<string, unknown> = {}`, `items: unknown[] = []`, `actions: unknown[] = []`, `active: string = ""`, `sticky: boolean = false`, `openOnHover: boolean = false`, `maxWidth: string = "full"`, `mobileLabel: string = "Toggle navigation"`, `collapseAt: string = "900px"`, `mobilePanel: string = "content"`, `mobileUtilitiesPosition: string = "header"`, `gutter: string = "md"`, `contentGutter: string = "md"`, `flushMobile: boolean = false`, `translationPrefix: string = ""`, `class: string = ""` - Props: `size: string = "default"`, `color: string = "primary"`, `label: string = "Primary navigation"`, `topbarLabel: string = "Utility navigation"`, `brand: Record<string, unknown> = {}`, `items: unknown[] = []`, `actions: unknown[] = []`, `active: string = ""`, `sticky: boolean = false`, `floating: boolean = false`, `startFloating: string = "0px"`, `openOnHover: boolean = false`, `maxWidth: string = "full"`, `mobileLabel: string = "Toggle navigation"`, `collapseAt: string = "900px"`, `mobilePanel: string = "content"`, `mobileUtilitiesPosition: string = "header"`, `gutter: string = "md"`, `contentGutter: string = "md"`, `flushMobile: boolean = false`, `translationPrefix: string = ""`, `class: string = ""`
- Slots: `topbar`, `actions`, `utilities` - Slots: `topbar`, `actions`, `utilities`
- Outputs: `toggle({ open: boolean })`, `open({ sourceEvent?: Event; [key: string]: string | number | boolean | null | object })`, `close({ sourceEvent?: Event; [key: string]: string | number | boolean | null | object })`, `select({ item: string | number | boolean | null | object; value: string | number | boolean; level: string })`, `action({ item: string | number | boolean | null | object; value: string | number | boolean })` - Outputs: `toggle({ open: boolean })`, `open({ sourceEvent?: Event; [key: string]: string | number | boolean | null | object })`, `close({ sourceEvent?: Event; [key: string]: string | number | boolean | null | object })`, `select({ item: string | number | boolean | null | object; value: string | number | boolean; level: string })`, `action({ item: string | number | boolean | null | object; value: string | number | boolean })`
+14
View File
@@ -9095,6 +9095,20 @@
"default": "false", "default": "false",
"options": [] "options": []
}, },
{
"name": "floating",
"type": "boolean",
"required": false,
"default": "false",
"options": []
},
{
"name": "startFloating",
"type": "string",
"required": false,
"default": "\"0px\"",
"options": []
},
{ {
"name": "openOnHover", "name": "openOnHover",
"type": "boolean", "type": "boolean",
+13 -2
View File
@@ -17,6 +17,8 @@ size: string = "default"
actions: unknown[] = [] actions: unknown[] = []
active: string = "" active: string = ""
sticky: boolean = false sticky: boolean = false
floating: boolean = false
startFloating: string = "0px"
openOnHover: boolean = false openOnHover: boolean = false
maxWidth: string = "full" maxWidth: string = "full"
mobileLabel: string = "Toggle navigation" mobileLabel: string = "Toggle navigation"
@@ -76,7 +78,7 @@ size: string = "default"
} }
view { view {
<header class="wrn-navbar wrn-navbar--width-{maxWidth} wrn-component--color-{color} wrn-component--size-{size} {sticky ? 'wrn-navbar--sticky' : ''} {class}" data-wrn-navbar data-open-on-hover="{openOnHover}" data-collapse-at="{collapseAt}" data-mobile-panel="{mobilePanel}" data-mobile-utilities-position="{mobileUtilitiesPosition}" data-gutter="{gutter}" data-content-gutter="{contentGutter}" data-flush-mobile="{flushMobile ? 'true' : 'false'}"> <header class="wrn-navbar wrn-navbar--width-{maxWidth} wrn-component--color-{color} wrn-component--size-{size} {sticky ? 'wrn-navbar--sticky' : ''} {floating ? 'wrn-navbar--floating' : ''} {class}" style="--wrn-navbar-floating-start: {startFloating};" data-wrn-navbar data-open-on-hover="{openOnHover}" data-floating="{floating ? 'true' : 'false'}" data-collapse-at="{collapseAt}" data-mobile-panel="{mobilePanel}" data-mobile-utilities-position="{mobileUtilitiesPosition}" data-gutter="{gutter}" data-content-gutter="{contentGutter}" data-flush-mobile="{flushMobile ? 'true' : 'false'}">
<div class="wrn-navbar__topbar" aria-label="{topbarLabel}"> <div class="wrn-navbar__topbar" aria-label="{topbarLabel}">
<slot name="topbar" /> <slot name="topbar" />
</div> </div>
@@ -165,7 +167,7 @@ size: string = "default"
/* Full application navigation */ /* Full application navigation */
.wrn-navbar { .wrn-navbar {
position: relative; position: relative;
z-index: 40; z-index: 1000;
width: 100%; width: 100%;
color: var(--wrn-color-text); color: var(--wrn-color-text);
background: color-mix(in srgb, var(--wrn-color-surface) 96%, transparent); background: color-mix(in srgb, var(--wrn-color-surface) 96%, transparent);
@@ -178,6 +180,14 @@ size: string = "default"
backdrop-filter: blur(16px); backdrop-filter: blur(16px);
} }
.wrn-navbar--floating {
position: sticky;
z-index: 1000;
top: var(--wrn-navbar-floating-start, 0px);
box-shadow: 0 10px 30px rgb(15 23 42 / 0.08);
backdrop-filter: blur(16px);
}
.wrn-navbar__topbar:not(:has(> *)) { .wrn-navbar__topbar:not(:has(> *)) {
display: none; display: none;
} }
@@ -369,6 +379,7 @@ size: string = "default"
.wrn-navbar__panel { .wrn-navbar__panel {
position: absolute; position: absolute;
z-index: 1100;
top: calc(100% + 0.55rem); top: calc(100% + 0.55rem);
left: 50%; left: 50%;
display: grid; display: grid;
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@wrnexus/ui", "name": "@wrnexus/ui",
"version": "0.8.26", "version": "0.8.27",
"private": true, "private": true,
"type": "module", "type": "module",
"main": "src/index.ts", "main": "src/index.ts",
@@ -126,6 +126,18 @@ describe("@wrnexus/ui redesign component pack", () => {
expect(source).not.toContain(".wrn-navbar__topbar:not(:empty)"); expect(source).not.toContain(".wrn-navbar__topbar:not(:empty)");
}); });
test("Navbar supports in-flow floating and elevated menu panels", async () => {
const source = await readFile(join(componentsDir, "Navbar.wrn"), "utf8");
const ast = parse(source);
const defaults = new Map(ast.props.map((prop) => [prop.name, prop.default]));
expect(defaults.get("floating")).toBe("false");
expect(defaults.get("startFloating")).toBe('"0px"');
expect(source).toContain("wrn-navbar--floating");
expect(source).toContain("--wrn-navbar-floating-start");
expect(source).toContain("z-index: 1100");
});
test("CTASection exposes responsive section spacing", async () => { test("CTASection exposes responsive section spacing", async () => {
const source = await readFile(join(componentsDir, "CTASection.wrn"), "utf8"); const source = await readFile(join(componentsDir, "CTASection.wrn"), "utf8");
const ast = parse(source); const ast = parse(source);