81901: Single link in sidebar menu entries

+ improved focus ring styling
This commit is contained in:
Yura Bondarenko
2021-08-06 13:27:32 +02:00
parent d095c98b13
commit 2265de8d44
5 changed files with 115 additions and 51 deletions

View File

@@ -1,10 +1,19 @@
<div class="sidebar-section"> <div class="sidebar-section">
<a href="javascript:void(0);" class="nav-item nav-link shortcut-icon" attr.aria-labelledby="sidebarName-{{section.id}}" [title]="('menu.section.icon.' + section.id) | translate" [routerLink]="itemModel.link"> <a class="nav-item nav-link d-flex flex-row flex-nowrap"
attr.aria-labelledby="sidebarName-{{section.id}}"
[title]="('menu.section.icon.' + section.id) | translate"
[routerLink]="itemModel.link"
href="javascript:void(0);"
>
<div class="shortcut-icon">
<i class="fas fa-{{section.icon}} fa-fw"></i> <i class="fas fa-{{section.icon}} fa-fw"></i>
</a> </div>
<div class="sidebar-collapsible"> <div class="sidebar-collapsible">
<div class="toggle">
<span id="sidebarName-{{section.id}}" class="section-header-text"> <span id="sidebarName-{{section.id}}" class="section-header-text">
<a class="nav-item nav-link" tabindex="-1" [routerLink]="itemModel.link">{{itemModel.text | translate}}</a> {{itemModel.text | translate}}
</span> </span>
</div> </div>
</div> </div>
</a>
</div>

View File

@@ -9,17 +9,18 @@
role="navigation" [attr.aria-label]="'menu.header.admin.description' |translate"> role="navigation" [attr.aria-label]="'menu.header.admin.description' |translate">
<div class="sidebar-top-level-items"> <div class="sidebar-top-level-items">
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="admin-menu-header sidebar-section"> <li class="admin-menu-header">
<a class="shortcut-icon navbar-brand mr-0" href="javascript:void(0);"> <div class="sidebar-section">
<span class="logo-wrapper"> <a href="javascript:void(0);" class="nav-item d-flex flex-row flex-nowrap py-0">
<div class="shortcut-icon navbar-brand logo-wrapper">
<img class="admin-logo" src="assets/images/dspace-logo-mini.svg" <img class="admin-logo" src="assets/images/dspace-logo-mini.svg"
[alt]="('menu.header.image.logo') | translate"> [alt]="('menu.header.image.logo') | translate">
</span> </div>
</a> <div class="sidebar-collapsible navbar-brand">
<div class="sidebar-collapsible"> <div class="mr-0">
<a class="navbar-brand mr-0" href="javascript:void(0);"> <h4 class="section-header-text mb-0">{{ 'menu.header.admin' | translate }}</h4>
<h4 class="section-header-text mb-0">{{'menu.header.admin' | </div>
translate}}</h4> </div>
</a> </a>
</div> </div>
</li> </li>
@@ -32,22 +33,20 @@
</div> </div>
<div class="navbar-nav"> <div class="navbar-nav">
<div class="sidebar-section" id="sidebar-collapse-toggle"> <div class="sidebar-section" id="sidebar-collapse-toggle">
<a class="nav-item nav-link shortcut-icon" <a class="nav-item nav-link sidebar-section d-flex flex-row flex-nowrap"
href="javascript:void(0);" href="javascript:void(0);"
(click)="toggle($event)"> (click)="toggle($event)">
<div class="shortcut-icon">
<i *ngIf="(menuCollapsed | async)" class="fas fa-fw fa-angle-double-right" <i *ngIf="(menuCollapsed | async)" class="fas fa-fw fa-angle-double-right"
[title]="'menu.section.icon.pin' | translate"></i> [title]="'menu.section.icon.pin' | translate"></i>
<i *ngIf="!(menuCollapsed | async)" class="fas fa-fw fa-angle-double-left" <i *ngIf="!(menuCollapsed | async)" class="fas fa-fw fa-angle-double-left"
[title]="'menu.section.icon.unpin' | translate"></i> [title]="'menu.section.icon.unpin' | translate"></i>
</a> </div>
<div class="sidebar-collapsible"> <div class="sidebar-collapsible">
<a class="nav-item nav-link sidebar-section"
href="javascript:void(0);"
(click)="toggle($event)">
<span *ngIf="menuCollapsed | async" class="section-header-text">{{'menu.section.pin' | translate }}</span> <span *ngIf="menuCollapsed | async" class="section-header-text">{{'menu.section.pin' | translate }}</span>
<span *ngIf="!(menuCollapsed | async)" class="section-header-text">{{'menu.section.unpin' | translate }}</span> <span *ngIf="!(menuCollapsed | async)" class="section-header-text">{{'menu.section.unpin' | translate }}</span>
</a>
</div> </div>
</a>
</div> </div>
</div> </div>
</nav> </nav>

View File

@@ -25,6 +25,11 @@
.navbar-nav { .navbar-nav {
.admin-menu-header { .admin-menu-header {
background-color: var(--ds-admin-sidebar-header-bg); background-color: var(--ds-admin-sidebar-header-bg);
.sidebar-section {
background-color: inherit;
}
.logo-wrapper { .logo-wrapper {
img { img {
height: 20px; height: 20px;
@@ -34,6 +39,10 @@
line-height: 1.5; line-height: 1.5;
} }
.navbar-brand {
margin-right: 0;
}
} }
} }
@@ -44,26 +53,67 @@
display: flex; display: flex;
align-content: stretch; align-content: stretch;
background-color: var(--ds-admin-sidebar-bg); background-color: var(--ds-admin-sidebar-bg);
overflow-x: visible;
.nav-item { .nav-item {
padding-top: var(--bs-spacer); padding-top: var(--bs-spacer);
padding-bottom: var(--bs-spacer); padding-bottom: var(--bs-spacer);
} background-color: inherit;
&:focus-visible {
// since links fill the whole sidebar, we _inset_ the outline
outline-offset: -4px;
// replace padding with margins so it doesn't extend over the :focus-visible outline
// → can't remove the padding altogether; the icon needs to fill out
// the collapsed width of the sidebar for the slide animation to look decent.
.shortcut-icon { .shortcut-icon {
padding-left: 0;
padding-right: 0;
margin-left: var(--ds-icon-padding);
margin-right: var(--ds-icon-padding);
}
.logo-wrapper {
margin-right: var(--bs-navbar-padding-x) !important;
}
.navbar-brand {
padding-top: 0;
padding-bottom: 0;
margin-top: var(--bs-navbar-brand-padding-y);
margin-bottom: var(--bs-navbar-brand-padding-y);
}
}
}
.shortcut-icon {
background-color: inherit;
padding-left: var(--ds-icon-padding); padding-left: var(--ds-icon-padding);
padding-right: var(--ds-icon-padding); padding-right: var(--ds-icon-padding);
}
.shortcut-icon, .icon-wrapper {
background-color: inherit;
z-index: var(--ds-icon-z-index); z-index: var(--ds-icon-z-index);
align-self: baseline;
} }
.sidebar-collapsible { .sidebar-collapsible {
padding-left: 0;
padding-right: var(--bs-spacer);
width: var(--ds-sidebar-items-width); width: var(--ds-sidebar-items-width);
position: relative; position: relative;
a { .toggle {
padding-right: var(--bs-spacer);
width: 100%; width: 100%;
} }
ul {
padding-top: var(--bs-spacer);
// move nested elements over to the left and pad so their :focus-visible outline
// doesn't get cut off by the parent section's icon
margin-left: calc(-1 * var(--bs-spacer));
li a {
padding-left: var(--bs-spacer);
} }
}
}
&.active > .sidebar-collapsible > .nav-link { &.active > .sidebar-collapsible > .nav-link {
color: var(--bs-navbar-dark-active-color); color: var(--bs-navbar-dark-active-color);
} }

View File

@@ -2,21 +2,26 @@
[@bgColor]="{ [@bgColor]="{
value: ((expanded | async) ? 'endBackground' : 'startBackground'), value: ((expanded | async) ? 'endBackground' : 'startBackground'),
params: {endColor: (sidebarActiveBg | async)}}"> params: {endColor: (sidebarActiveBg | async)}}">
<div class="icon-wrapper"> <a class="nav-item nav-link d-flex flex-row flex-nowrap"
<a class="nav-item nav-link shortcut-icon" attr.aria.labelledby="sidebarName-{{section.id}}" [title]="('menu.section.icon.' + section.id) | translate" (click)="toggleSection($event)" href="javascript:void(0);"> attr.aria.labelledby="sidebarName-{{section.id}}"
[title]="('menu.section.icon.' + section.id) | translate"
(click)="toggleSection($event)"
href="javascript:void(0);"
>
<div class="shortcut-icon">
<i class="fas fa-{{section.icon}} fa-fw"></i> <i class="fas fa-{{section.icon}} fa-fw"></i>
</a>
</div> </div>
<div class="sidebar-collapsible"> <div class="sidebar-collapsible">
<a class="nav-item nav-link" href="javascript:void(0);" tabindex="-1" <div class="toggle">
(click)="toggleSection($event)">
<span id="sidebarName-{{section.id}}" class="section-header-text"> <span id="sidebarName-{{section.id}}" class="section-header-text">
<ng-container <ng-container
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container> *ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
</span> </span>
<i class="fas fa-chevron-right fa-pull-right" <i class="fas fa-chevron-right fa-pull-right"
[@rotate]="(expanded | async) ? 'expanded' : 'collapsed'" [title]="('menu.section.toggle.' + section.id) | translate"></i> [@rotate]="(expanded | async) ? 'expanded' : 'collapsed'"
</a> [title]="('menu.section.toggle.' + section.id) | translate"
></i>
</div>
<ul class="sidebar-sub-level-items list-unstyled" @slide *ngIf="(expanded | async)"> <ul class="sidebar-sub-level-items list-unstyled" @slide *ngIf="(expanded | async)">
<li *ngFor="let subSection of (subSections$ | async)"> <li *ngFor="let subSection of (subSections$ | async)">
<ng-container <ng-container
@@ -24,4 +29,5 @@
</li> </li>
</ul> </ul>
</div> </div>
</a>
</div> </div>

View File

@@ -9,7 +9,7 @@
list-style: disc; list-style: disc;
color: var(--bs-navbar-dark-color); color: var(--bs-navbar-dark-color);
overflow: hidden; overflow: hidden;
margin-bottom: calc(-1 * var(--bs-spacer)); // the bottom-most nav-item is padded, no need for double spacing
} }
.sidebar-collapsible { .sidebar-collapsible {