feat(ui): add in-flow floating navbar
This commit is contained in:
@@ -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:*",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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 })`
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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,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);
|
||||||
|
|||||||
Reference in New Issue
Block a user