diff --git a/packages/components/src/components/main-navigation/docs/Angular.md b/packages/components/src/components/main-navigation/docs/Angular.md
index 0837e77cdd6..8fe3a3cb0a0 100644
--- a/packages/components/src/components/main-navigation/docs/Angular.md
+++ b/packages/components/src/components/main-navigation/docs/Angular.md
@@ -11,7 +11,10 @@ import { DBMainNavigation } from '@db-ui/ngx-components';
@Component({
// ...
standalone: true,
- imports: [..., DBMainNavigation],
+ imports: [
+ // ...,
+ DBMainNavigation
+ ],
// ...
})
```
@@ -61,3 +64,72 @@ import { DBMainNavigation } from '@db-ui/ngx-components';
```
+
+### Angular Router and active state handling
+
+You can set the property `active` to a boolean value as in the example above.
+It will cause the navigation item to render in active style and implicitly
+set `aria-current="page"` to the list element.
+
+The component will also check for child element set to `aria-current="page"`.
+Such elements are also displayed in active state.
+This makes the component [integration with the Angular Router](https://angular.dev/best-practices/a11y#active-links-identification) way more elegant
+compared to the first variant.
+
+The component first needs to import the `RouterLink` and `RouterLinkActive` directives.
+
+```ts app.component.ts
+// app.component.ts
+import { RouterLink, RouterLinkActive } from '@angular/router';
+import { DBMainNavigation } from '@db-ui/ngx-components';
+
+@Component({
+ // ...
+ standalone: true,
+ imports: [
+ // ...
+ RouterLink,
+ RouterLinkActive,
+ DBMainNavigation
+ ],
+ // ...
+})
+```
+
+Now you can use the Angular Routers `routerLink` directive to define your targets.
+The active style is automatically set once an item receives the `aria-current="page"` attribute.
+
+```html app.component.html
+
+
+
+
+
+
+ Home
+
+
+
+
+ Demo Pages
+
+
+
+
+ Demo Page 1
+
+
+
+
+ Demo Page 2
+
+
+
+
+
+
+```
diff --git a/packages/components/src/components/main-navigation/docs/Vue.md b/packages/components/src/components/main-navigation/docs/Vue.md
index 2d41c5c7bb3..3900e7f1d9a 100644
--- a/packages/components/src/components/main-navigation/docs/Vue.md
+++ b/packages/components/src/components/main-navigation/docs/Vue.md
@@ -41,3 +41,46 @@ import { DBMainNavigation, DBNavigationItem } from "@db-ui/v-components";
```
+
+### Vue Router and active state handling
+
+You can set the property `active` to a boolean value as in the example above.
+It will cause the navigation item to render in active style and implicitly
+set `aria-current="page"` to the list element.
+
+The component will also check for child element set to `aria-current="page"`.
+Such elements are also displayed in active state.
+This makes the component [integration with the Vue Router](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#ariaCurrentValue) way more elegant
+compared to the first variant.
+
+Now you can use Vue Routers `RouterLink` component to define your targets.
+The active style is automatically set once an item receives the `aria-current="page"` attribute.
+
+```vue App.vue
+
+
+
+
+
+
+ Home
+
+
+ Demo Pages
+
+
+
+ Demo Page 1
+
+
+
+ Demo Page 2
+
+
+
+
+
+
+```
diff --git a/packages/components/src/components/main-navigation/main-navigation.scss b/packages/components/src/components/main-navigation/main-navigation.scss
index 42980da28b1..398f9902787 100644
--- a/packages/components/src/components/main-navigation/main-navigation.scss
+++ b/packages/components/src/components/main-navigation/main-navigation.scss
@@ -1,8 +1,8 @@
@use "@db-ui/foundations/build/scss/variables";
@use "@db-ui/foundations/build/scss/screen-sizes";
@use "../../styles/component";
-@use "../../styles/db-puls";
@use "../../styles/form-components";
+@use "../../styles/db-puls";
.db-main-navigation {
-webkit-tap-highlight-color: transparent; /* for removing the highlight */
@@ -25,6 +25,8 @@
}
.db-navigation-item {
+ @extend %db-puls-auto;
+
.db-navigation-item-expand-button:is(button),
.db-navigation-item-expand-button > button {
// overwrite for main-navigation items
@@ -70,12 +72,14 @@
}
}
+ &:has([aria-current="page"]),
&[aria-current="page"] {
// add puls for main-navigation items
@extend %show-db-puls-auto;
menu {
// hide puls for non main-navigation items
+ :has([aria-current="page"]),
[aria-current="page"] {
&::after {
display: none;
diff --git a/packages/components/src/components/navigation-item/navigation-item.scss b/packages/components/src/components/navigation-item/navigation-item.scss
index 6ca041538ba..12d1e9088da 100644
--- a/packages/components/src/components/navigation-item/navigation-item.scss
+++ b/packages/components/src/components/navigation-item/navigation-item.scss
@@ -4,7 +4,6 @@
@use "@db-ui/foundations/build/scss/helpers";
@use "@db-ui/foundations/build/scss/animation";
@use "@db-ui/foundations/build/scss/icons";
-@use "../../styles/db-puls";
@use "../../styles/icon-passing";
@use "../../styles/component";
@@ -69,7 +68,6 @@
.db-navigation-item {
--db-has-before: 0;
- @extend %db-puls-auto;
@include icon-passing.icon-passing();
@@ -77,6 +75,16 @@
position: relative;
inline-size: 100%;
+ @include screen-sizes.screen("md", "max") {
+ &:not([data-width="full"]) {
+ .db-navigation-item-expand-button {
+ &::after {
+ --db-icon-margin-start: auto;
+ }
+ }
+ }
+ }
+
a {
@extend %navigation-item;
text-decoration: none;
@@ -104,13 +112,11 @@
}
}
+ &:has([aria-current="page"]),
&[aria-current="page"] {
- font-weight: 700;
- }
-
- &:not([aria-current="page"]) {
- // revert for sub-navigation
- font-weight: normal;
+ & > :is(a, button) {
+ font-weight: 700;
+ }
}
&:not([data-width="full"]) {
diff --git a/showcases/angular-showcase/src/app/nav-item/nav-item.component.html b/showcases/angular-showcase/src/app/nav-item/nav-item.component.html
index 1e379ec3aaf..c577ab0d91c 100644
--- a/showcases/angular-showcase/src/app/nav-item/nav-item.component.html
+++ b/showcases/angular-showcase/src/app/nav-item/nav-item.component.html
@@ -1,18 +1,21 @@
@if (navItem) {
-
+
@if (navItem.subNavigation) {
@for (item of navItem.subNavigation; track item.label) {
-
+
}
}
@if (navItem.component) {
-
+
{{ navItem.label }}
}
diff --git a/showcases/angular-showcase/src/app/nav-item/nav-item.component.ts b/showcases/angular-showcase/src/app/nav-item/nav-item.component.ts
index 028b841dd7e..f23d65b2883 100644
--- a/showcases/angular-showcase/src/app/nav-item/nav-item.component.ts
+++ b/showcases/angular-showcase/src/app/nav-item/nav-item.component.ts
@@ -1,4 +1,4 @@
-import { Router, RouterLink } from '@angular/router';
+import { RouterLink, RouterLinkActive } from '@angular/router';
import { Component, Input } from '@angular/core';
import { NavItem } from '../utils/navigation-item';
import { NavigationContentDirective } from '../../../../../output/angular/src/components/navigation-item/NavigationContent.directive';
@@ -7,17 +7,16 @@ import { DBNavigationItem } from '../../../../../output/angular/src/components/n
@Component({
selector: 'app-nav-item',
templateUrl: './nav-item.component.html',
- imports: [RouterLink, DBNavigationItem, NavigationContentDirective],
+ imports: [
+ RouterLink,
+ RouterLinkActive,
+ DBNavigationItem,
+ NavigationContentDirective
+ ],
standalone: true
})
export class NavItemComponent {
@Input({ required: true }) navItem!: NavItem;
- constructor(private readonly router: Router) {}
-
- isActive = () =>
- this.navItem.path === ''
- ? this.router.url === '/'
- : this.router.url.includes(this.navItem.path);
getBackButtonText = () => {
return `Back to ${this.navItem.label}`;
diff --git a/showcases/vue-showcase/src/NavItemComponent.vue b/showcases/vue-showcase/src/NavItemComponent.vue
index cc7e4a167a3..e8fd5949c02 100644
--- a/showcases/vue-showcase/src/NavItemComponent.vue
+++ b/showcases/vue-showcase/src/NavItemComponent.vue
@@ -1,34 +1,24 @@
-
+
-
+
{{ navItem.label }}
{{ navItem.label }}