@nextrap/nte-nav 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,65 @@
1
+ # @nextrap/nte-nav
2
+
3
+ Draft replacement for the navigation portion of `@nextrap/nte-nav`. Do not remove or change the legacy package and do not add navbar concerns here.
4
+
5
+ ## First reference
6
+
7
+ Read the demo files before changing the API:
8
+
9
+ - `demo/01-overview.md` explains the component model.
10
+ - `demo/02-horizontal.html` demonstrates links, icons and nested submenus.
11
+ - `demo/03-vertical.html` demonstrates the same markup under the vertical mixin.
12
+ - `demo/04-responsive-order.html` demonstrates responsive orientation and Flexbox order.
13
+ - `demo/05-variations.html` demonstrates sizes, visual variants and linked/non-linked parent items.
14
+ - `demo/main.scss` is the authoritative example for binding public mixins to semantic contexts.
15
+
16
+ ## Markup
17
+
18
+ ```html
19
+ <nte-nav aria-label="Hauptnavigation">
20
+ <nte-nav-item submenu-popover>
21
+ <svg slot="icon" aria-hidden="true"><!-- icon --></svg>
22
+ Leistungen
23
+ <nte-nav-item href="/leistungen/beratung">Beratung</nte-nav-item>
24
+ </nte-nav-item>
25
+ <nte-nav-item href="/ueber-uns" current="page">Über uns</nte-nav-item>
26
+ </nte-nav>
27
+ ```
28
+
29
+ - Consumers never author a `ul/li/ul` tree.
30
+ - Direct nested items are automatically assigned to the parent item's `submenu` slot by the label slot-change handler.
31
+ - Anchors and submenu controls stay inside each item's Shadow DOM.
32
+ - Horizontal submenus use manual declarative Popover: add `submenu-popover` to the parent `nte-nav-item`; it renders `popover="auto"` and `popovertarget="submenu"` internally.
33
+ - Vertical submenus must not use `submenu-popover`; they render native `details`/`summary` and stay inline.
34
+ - A parent item should normally omit `href`, making its complete visible label the disclosure control.
35
+ - An item with both `href` and children must keep link and disclosure as separate controls.
36
+ - Do not add `menu`, `menubar` or `menuitem` roles for ordinary site navigation.
37
+ - Horizontal orientation positions the Popover submenu with CSS Anchor Positioning; vertical orientation keeps it static and inline below its parent.
38
+ - Orientation mixins do not add/remove attributes. For nested responsive submenus, the integration must manually add/remove `submenu-popover` or choose one authored variant.
39
+ - Keep `nextrap_element({ slotVisibility: true })` and use `.slot-empty` for optional slots instead of component-authored icon state.
40
+
41
+ ## Styling
42
+
43
+ ```scss
44
+ @use '@nextrap/nte-nav' as nav;
45
+
46
+ .site-header nte-nav.style-default {
47
+ @include nav.default-style();
48
+ @include nav.responsive(48rem);
49
+ }
50
+ ```
51
+
52
+ - Keep Shadow DOM CSS functional only.
53
+ - Visual styling belongs in the exported mixins and reaches internal markup through parts.
54
+ - Orientation is a mixin/CSS-custom-property concern, not a component attribute.
55
+ - Examples do not explicitly add `style-default`; `SetDefaultStyleMixin` adds it.
56
+ - A non-default `style-*` variant must include its full visual baseline.
57
+ - Feature classes, if introduced, start with `with-*`.
58
+
59
+ ## Accessibility checks
60
+
61
+ - Give each `nte-nav` an `aria-label` when the page has multiple nav landmarks.
62
+ - Preserve native link behavior and forward `current` to the anchor's `aria-current`.
63
+ - Keep visible focus indicators on links and disclosure buttons.
64
+ - Test Tab, Shift+Tab, Enter, Space, touch input and reduced motion.
65
+ - Flex `order` changes only visual order; avoid it when that would make focus order confusing.
@@ -0,0 +1,155 @@
1
+ # NTE Nav 2 architecture
2
+
3
+ ## Native Popover only
4
+
5
+ Die horizontale Submenu-Variante basiert vollständig auf dem nativen HTML
6
+ Popover-Mechanismus.
7
+
8
+ Ein `nte-nav-item` mit `submenu-popover` rendert intern ausschließlich
9
+ deklaratives Popover-Markup:
10
+
11
+ ```html
12
+ <button popovertarget="submenu">...</button>
13
+ <div id="submenu" popover="auto">...</div>
14
+ ```
15
+
16
+ Die Popover-Logik muss vom Browser kommen. `nte-nav` / `nte-nav-item` dürfen
17
+ keine JavaScript-Popover-Logik implementieren:
18
+
19
+ - kein `showPopover()`;
20
+ - kein `hidePopover()`;
21
+ - keine JS-Synchronisierung zwischen CSS-Orientation und Popover;
22
+ - keine Resize-/Media-Query-Logik für Popover.
23
+
24
+ Popover wird manuell durch das öffentliche `submenu-popover` Attribut am
25
+ betroffenen `nte-nav-item` aktiviert oder durch Entfernen dieses Attributs
26
+ deaktiviert.
27
+
28
+ ## Vertikale Navigation
29
+
30
+ Die vertikale Variante darf kein Popover verwenden. Ein vertikales Submenu wird
31
+ korrekt gerendert, indem am betroffenen `nte-nav-item` **kein**
32
+ `submenu-popover` Attribut gesetzt wird.
33
+
34
+ Dann rendert `nte-nav-item` intern native Disclosure-Struktur:
35
+
36
+ ```html
37
+ <details id="details" part="details">
38
+ <summary id="disclosure" part="disclosure">...</summary>
39
+ <div id="submenu" part="submenu" role="list">...</div>
40
+ </details>
41
+ ```
42
+
43
+ Bei einem Elternpunkt mit eigenem `href` bleiben Link und Disclosure getrennt:
44
+
45
+ ```html
46
+ <a id="link" part="link" href="...">...</a>
47
+ <details id="details" part="details">
48
+ <summary id="toggle" part="toggle">...</summary>
49
+ <div id="submenu" part="submenu" role="list">...</div>
50
+ </details>
51
+ ```
52
+
53
+ Die vertikale Darstellung entsteht durch die `vertical()` SCSS-Variante. Sie
54
+ setzt die Navigationsrichtung auf Spalte und die Submenu-Position auf normalen
55
+ Dokumentfluss:
56
+
57
+ - `--nte-nav-flow: column`;
58
+ - `--nte-nav-submenu-position: static`;
59
+ - `--nte-nav-submenu-inline-size: 100%`;
60
+ - transparente Submenu-Fläche ohne Popover-Box, Border oder Shadow;
61
+ - optionaler Einzug über `--nte-nav-inline-submenu-indent`.
62
+
63
+ Das Submenu öffnet ausschließlich über den nativen `details[open]` Zustand. Die
64
+ CSS-Regel für `#details[open] #submenu` macht den Inhalt sichtbar und klappt die
65
+ Grid-Zeile von `0fr` auf `1fr` auf. Dadurch bleibt das Submenu inline unter dem
66
+ Elterneintrag und erweitert die Navigation vertikal, statt als Overlay aus dem
67
+ Layout herauszuspringen.
68
+
69
+ Wichtig: Für vertikale Navigation darf weder das öffentliche
70
+ `submenu-popover` Attribut noch intern `popover` oder `popovertarget` vorhanden
71
+ sein.
72
+
73
+ ## CSS-Block- und Mixin-Dokumentation
74
+
75
+ Vor jedem zusammengehörigen CSS-Block und vor jedem SCSS-Mixin muss ein kurzer
76
+ Kommentar stehen, der seinen Zweck beschreibt. Der Kommentar muss erklären,
77
+ welches Verhalten der Block beziehungsweise das Mixin steuert und — falls
78
+ relevant — in welchem Zustand oder für welche Variante es gilt.
79
+
80
+ Ein Block umfasst dabei alle direkt zusammengehörigen Regeln eines Elements,
81
+ Parts oder Zustands. Einzelne CSS-Regeln innerhalb eines solchen Blocks
82
+ benötigen keinen eigenen Kommentar. Reine technische Folge- oder Reset-Regeln
83
+ können mit dem Kommentar des übergeordneten Blocks gruppiert werden.
84
+
85
+ Die Regel gilt insbesondere für:
86
+
87
+ - `:host`- und Komponentenblöcke;
88
+ - `::part(...)`-Blöcke;
89
+ - `:has(...)`-, Zustands- und Selektorblöcke;
90
+ - responsive beziehungsweise über `tj-responsive` gesetzte Zustände;
91
+ - jedes öffentliche SCSS-Mixin unter `src/scss/`.
92
+
93
+ Kommentare dürfen nicht nur den Selektor wiederholen. Sie müssen den
94
+ funktionalen Zweck des jeweiligen Blocks dokumentieren. Neue oder geänderte
95
+ zweckorientierte CSS-Blöcke und Mixins ohne Zweckkommentar sind nicht zulässig.
96
+
97
+ ## Responsive Verhalten
98
+
99
+ Responsive Änderungen werden nicht über CSS-Media-Queries in SCSS umgesetzt.
100
+ Breakpoint-abhängige Zustände müssen über `tj-responsive` beziehungsweise
101
+ `@trunkjs/responsive`-Klassen und Attribute gesteuert werden. Das gilt sowohl
102
+ für die Umschaltung zwischen horizontaler und vertikaler Navigation als auch
103
+ für responsive Sichtbarkeit, Reihenfolge und Layout-Eigenschaften.
104
+
105
+ SCSS-Varianten dürfen ausschließlich die jeweils gesetzten Zustände stylen;
106
+ eine eigene `@media`-Regel oder eine parallele Breakpoint-Logik innerhalb von
107
+ `nte-nav` ist nicht zulässig.
108
+
109
+ ## Styling und Style-Varianten
110
+
111
+ Das Shadow DOM enthält ausschließlich betriebsnotwendige Layout-, Disclosure-
112
+ und Popover-Regeln. Visuelle Defaults und Varianten werden außerhalb des Shadow
113
+ DOM über die öffentlichen Parts gestylt.
114
+
115
+ Die Default-Baseline wird im Mixin `default-style()` definiert. Neue visuelle
116
+ Varianten müssen dieses Mixin erweitern und unter `src/scss/styles/` angelegt
117
+ werden. Beispiel:
118
+
119
+ ```scss
120
+ @use '../default-style' as default;
121
+
122
+ @mixin bordered-style() {
123
+ @include default.default-style();
124
+
125
+ & nte-nav-item::part(link),
126
+ & nte-nav-item::part(disclosure) {
127
+ border: var(--nt-border-width) solid var(--nt-border);
128
+ }
129
+ }
130
+ ```
131
+
132
+ Die Variante wird über eine eigene `style-*`-Klasse am Custom Element aktiviert
133
+ und muss die vollständige Default-Baseline über das Default-Mixin erben:
134
+
135
+ ```scss
136
+ nte-nav.style-bordered {
137
+ @include nav.bordered-style();
138
+ }
139
+ ```
140
+
141
+ Dabei gelten folgende Regeln:
142
+
143
+ - Visuelles Styling immer über `::part(...)`, niemals durch zusätzliche
144
+ visuelle Regeln im Shadow DOM.
145
+ - Globale Werte aus `@nextrap/style-base` über `--nt-*` Tokens beziehen.
146
+ - Komponentenvariablen nur für betriebsnotwendiges Verhalten verwenden, etwa
147
+ Orientierung, Submenu-Positionierung und Animation.
148
+ - Eine Style-Variante wird als eigenes Mixin unter `src/scss/styles/` angelegt
149
+ und in `index.scss` exportiert.
150
+ - Pro `nte-nav` darf nur eine `style-*`-Klasse gesetzt sein.
151
+ - Feature-Änderungen, die mit anderen Styles kombinierbar sein sollen, werden
152
+ als `with-*` Modifier und nicht als neue `style-*`-Variante umgesetzt.
153
+ - Das Default-Mixin setzt für die Hauptnavigation keine Hintergrundfarbe. Das
154
+ horizontale Dropdown erhält seine Hintergrundfarbe separat über
155
+ `::part(submenu)`.
package/README.md CHANGED
@@ -1,3 +1,112 @@
1
- # nte-nav
1
+ # @nextrap/nte-nav
2
2
 
3
- A navigation element.
3
+ Working draft for the future Nextrap navigation component. The existing `@nextrap/nte-nav` package remains unchanged; a future navbar is explicitly out of scope.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import '@nextrap/nte-nav';
9
+ ```
10
+
11
+ ```scss
12
+ @use '@nextrap/nte-nav' as nav;
13
+
14
+ header nte-nav.style-default {
15
+ @include nav.default-style();
16
+ @include nav.horizontal();
17
+ @include nav.size-medium();
18
+ }
19
+
20
+ aside nte-nav.style-default {
21
+ @include nav.sub-navigation();
22
+ @include nav.vertical();
23
+ }
24
+ ```
25
+
26
+ `SetDefaultStyleMixin` adds `style-default` when no other `style-*` class is present. The component's Shadow DOM only contains functional layout, disclosure, positioning and transition CSS. Visual styling is supplied by the public mixins.
27
+
28
+ ## Basic API
29
+
30
+ ```html
31
+ <nte-nav aria-label="Hauptnavigation">
32
+ <nte-nav-item submenu-popover>
33
+ <svg slot="icon" aria-hidden="true"><!-- … --></svg>
34
+ Leistungen
35
+
36
+ <nte-nav-item href="/leistungen/beratung">Beratung</nte-nav-item>
37
+ <nte-nav-item href="/leistungen/entwicklung">Entwicklung</nte-nav-item>
38
+ </nte-nav-item>
39
+
40
+ <nte-nav-item href="/ueber-uns" current="page">Über uns</nte-nav-item>
41
+ </nte-nav>
42
+ ```
43
+
44
+ Direct nested `nte-nav-item` children are automatically assigned to the private `submenu` slot. Consumer markup no longer contains a `ul/li/ul` tree. Each item owns its anchor, disclosure control, submenu container and CSS positioning inside its Shadow DOM.
45
+
46
+ Parents with children are non-linking disclosures by default: omit `href` and the complete visible label toggles the submenu. Add `href` only when the parent page is a real destination of its own; the component then keeps the link and disclosure as two separate keyboard-focusable controls.
47
+
48
+ ## Attributes
49
+
50
+ ### `nte-nav`
51
+
52
+ | Attribute | Type | Purpose |
53
+ |---|---|---|
54
+ | `aria-label` | string | Accessible name forwarded to the internal `nav` landmark. Recommended whenever multiple navigation landmarks exist. |
55
+
56
+ ### `nte-nav-item`
57
+
58
+ | Attribute | Type | Purpose |
59
+ |---|---|---|
60
+ | `href` | string | Renders the item's internal anchor. If omitted on an item with children, the label itself becomes the disclosure button. |
61
+ | `target` | string | Forwarded to the internal anchor. |
62
+ | `rel` | string | Forwarded to the internal anchor. |
63
+ | `download` | string | Forwarded to the internal anchor. |
64
+ | `current` | ARIA current token | Forwarded as `aria-current` to the internal anchor. |
65
+ | `--order` | CSS custom property | Sets the host's Flexbox `order`. Use sparingly because visual order does not change DOM or keyboard order. |
66
+ | `submenu-popover` | boolean attribute | Manually renders nested items as declarative Popover markup for horizontal navigation. Omit for vertical inline `details`/`summary`. |
67
+ | `submenu-label` | string | Prefix for the submenu disclosure's accessible name. Default: `Untermenü`. |
68
+
69
+ ## Slots
70
+
71
+ | Component | Slot | Purpose |
72
+ |---|---|---|
73
+ | `nte-nav` | default | Top-level `nte-nav-item` elements. |
74
+ | `nte-nav-item` | default | Visible rich-text label. |
75
+ | `nte-nav-item` | `icon` | Optional icon rendered in the dedicated `icon` part. Decorative SVGs should use `aria-hidden="true"`. |
76
+ | `nte-nav-item` | `submenu` | Internal target slot for nested items. Direct nested `nte-nav-item` elements are assigned automatically. |
77
+
78
+ ## Parts
79
+
80
+ - `nte-nav`: `nav`, `list`
81
+ - `nte-nav-item`: `item`, `details`, `link`, `text`, `disclosure`, `toggle`, `icon`, `label`, `indicator`, `submenu`, `submenu-inner`
82
+
83
+ ## Public mixins
84
+
85
+ - `default-style()` – full default visual baseline
86
+ - `main-navigation()` – complete, large main-navigation variant
87
+ - `sub-navigation()` – complete, compact sub-navigation variant
88
+ - `horizontal($justify, $gap)` – horizontal functional orientation
89
+ - `vertical($gap)` – vertical functional orientation
90
+ - `responsive($breakpoint, $horizontal-justify)` – vertical below and horizontal above a breakpoint
91
+ - `size-small()`, `size-medium()`, `size-large()` – size presets that only set component variables
92
+
93
+ ## Orientation and native disclosure
94
+
95
+ This is ordinary website navigation, not an application menu. It intentionally uses a `nav` landmark, list/listitem semantics, links and disclosure buttons rather than ARIA `menu`/`menubar` roles.
96
+
97
+ Submenus are selected manually per item. The Shadow DOM CSS consumes orientation variables from the mixins; the markup variant is controlled by the public `submenu-popover` attribute:
98
+
99
+ - For `horizontal()`, add `submenu-popover` to parent items with nested items. The component renders a native `<button popovertarget="submenu">` and `<div id="submenu" popover="auto">`, so the browser handles the Popover declaratively.
100
+ - For `vertical()`, omit `submenu-popover`. The component renders native `details` / `summary`; the submenu stays in normal document flow, animates downwards and is indented as part of the navigation path.
101
+ - `responsive()` changes only CSS orientation. With nested submenus and no JavaScript, the integration must manually add/remove `submenu-popover` or choose one authored variant.
102
+
103
+ The optional icon slot is observed by `nextrap_element({ slotVisibility: true })`. Empty icon slots receive `.slot-empty` and are hidden entirely by the component CSS.
104
+
105
+ ## Deliberately deferred
106
+
107
+ - Navbar, sticky header and brand layout
108
+ - Burger/offcanvas content transfer from the legacy package
109
+ - Optional arrow-key navigation beyond normal Tab/Shift+Tab behavior
110
+ - Public imperative `showSubmenu()` / `hideSubmenu()` methods
111
+ - SPA-router adapters and prefetch behavior
112
+ - Public imperative `showSubmenu()` / `hideSubmenu()` methods beyond the internal Popover synchronization
package/index.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- export * from './lib/nte-nav';
2
- export * from './lib/nte-navbar';
3
- export * from './lib/nte-navbar-line';
4
- export * from './components/nte-nav-brand-relocator/nte-nav-brand-relocator';
1
+ export * from './src/components/nte-nav/nte-nav';
2
+ export * from './src/components/nte-nav-item/nte-nav-item';