cnc-nav-horizontal
A horizontal menu bar whose groups open as hover dropdowns, nested to any depth. The whole bar
is a projection of one root tree — there is no per-item markup.
Quick start
Give it a root tree and handle navigate. The widget does NOT follow
links itself — it swallows the click and hands you the destination.
nothing clicked yet
<cnc-nav-horizontal
active-id="widgets"
@navigate="router.go($event.detail.href)"
$root='{
"id": "root",
"children": [
{ "id": "home", "label": "Home", "href": "/home" },
{ "id": "products", "label": "Products", "children": [
{ "id": "widgets", "label": "Widgets", "href": "/products/widgets" }
]}
]
}'
></cnc-nav-horizontal>
Node fields
Every item in the tree, at any depth, takes the same four fields.
| Field | Purpose |
|---|---|
| id |
The node's identity. Used by active-id and carried in the events, so it
must be unique across the whole tree rather than among its siblings.
|
| label | The text shown for the item. |
| children | An array of the same shape, nested to any depth. A node WITH children is a group; a node without is a destination. |
| href |
The destination. Note that the widget calls preventDefault() on it and
emits its event instead, so this is data for your handler rather than a working link.
|
Usage guidance
Navigation is the HOST's job. Every one of these widgets swallows the click on an
href
and emits an event carrying it instead of letting the browser follow the link, so a nav with no
handler renders correctly and goes nowhere. Route from the event.
Hover is the only way in, so this bar is a DESKTOP shape. Pair it with
cnc-nav-mobile
or cnc-nav-mobile-drop behind a breakpoint rather than letting it degrade — a
touch user cannot hover, and a group whose own entry has no
href
is unreachable for them.
Keep it to two levels where you can. A third opens a submenu of a submenu, each held open only
while the pointer stays inside it, which is a long thin path to steer along. Deep trees read
better in cnc-nav-vertical, and a wide shallow one in
cnc-nav-horizontal2, whose panel shows a whole level at once.
Ids must be unique across the WHOLE tree, not just among siblings —
active-id
and the event both address items by id alone.