Side Nav UX Changes (#3345)

Co-authored-by: Christopher <39032787+MrRobotjs@users.noreply.github.com>
Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
Joe Milazzo 2024-11-07 17:21:14 -06:00 committed by GitHub
parent aa939edf6d
commit 3a0c796c08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 1193 additions and 664 deletions

View file

@ -1,4 +1,5 @@
@import '../theme/variables';
.content-wrapper {
padding: 0 0 0 10px;
height: calc(var(--vh)* 100 - var(--nav-offset));
@ -14,6 +15,7 @@
scrollbar-width: thin;
mask-image: linear-gradient(to bottom, transparent, black 0%, black 95%, transparent 100%);
-webkit-mask-image: linear-gradient(to bottom, transparent, black 0%, black 95%, transparent 100%);
//margin-top: 7px;
// For firefox
@supports (-moz-appearance:none) {
@ -55,7 +57,7 @@
}
.companion-bar-content {
margin-left: 190px;
margin-left: var(--side-nav-width);
}
@media (max-width: $grid-breakpoints-lg) {
@ -82,7 +84,6 @@
margin-left: 0;
padding-left: 0;
width: 100%;
padding: 10px 0 0;
height: calc(var(--vh) * 100 - var(--nav-mobile-offset));
scrollbar-color: rgba(255,255,255,0.3) rgba(0, 0, 0, 0.1);
scrollbar-width: thin;

View file

@ -1,8 +1,8 @@
<ng-container *transloco="let t; read: 'bulk-operations'">
@if (bulkSelectionService.selections$ | async; as selectionCount) {
@if (selectionCount > 0) {
<div class="bulk-select-container">
<div class="bulk-select mb-3 {{modalMode ? '' : 'fixed-top'}}" [ngStyle]="{'margin-top': topOffset + 'px'}">
<div class="bulk-select-container" [ngStyle]="{'margin-left': marginLeft + 'px', 'margin-right': marginRight + 'px'}">
<div class="bulk-select">
<div class="d-flex justify-content-around align-items-center">
<span class="highlight">

View file

@ -1,6 +1,7 @@
.bulk-select-container {
position: absolute;
width: 100%;
z-index: 1;
top: 0;
position: sticky;
.bulk-select {
background-color: var(--bulk-selection-bg-color);

View file

@ -37,7 +37,14 @@ export class BulkOperationsComponent implements OnInit {
* Modal mode means don't fix to the top
*/
@Input() modalMode = false;
@Input() topOffset: number = 75;
/**
* On Series Detail this should be 12
*/
@Input() marginLeft: number = 0;
/**
* On Series Detail this should be 12
*/
@Input() marginRight: number = 8;
hasMarkAsRead: boolean = false;
hasMarkAsUnread: boolean = false;
actions: Array<ActionItem<any>> = [];

View file

@ -65,7 +65,7 @@
@if (accountService.isAdmin$ | async) {
<div class="col-auto ms-2">
<button class="btn btn-secondary-outline" id="edit-btn--komf" (click)="openEditModal()" [ngbTooltip]="t('edit-series-alt')">
<button class="btn btn-actions" id="edit-btn--komf" (click)="openEditModal()" [ngbTooltip]="t('edit-series-alt')">
<span><i class="fa fa-pen" aria-hidden="true"></i></span>
</button>
</div>
@ -73,7 +73,7 @@
<div class="col-auto ms-2 d-none d-md-block">
<div class="card-actions" [ngbTooltip]="t('more-alt')">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="chapterActions" [labelBy]="series.name + ' ' + chapter.minNumber" iconClass="fa-ellipsis-h" btnClass="btn-secondary-outline btn"></app-card-actionables>
<app-card-actionables (actionHandler)="performAction($event)" [actions]="chapterActions" [labelBy]="series.name + ' ' + chapter.minNumber" iconClass="fa-ellipsis-h" btnClass="btn-actions btn"></app-card-actionables>
</div>
</div>

View file

@ -1 +1,5 @@
@use '../../series-detail-common';
:host ::ng-deep .card-actions .btn.btn-actions {
padding: 0.375rem 0.75rem;
}

View file

@ -265,6 +265,14 @@ export class LibraryDetailComponent implements OnInit {
case(Action.GenerateColorScape):
await this.actionService.refreshLibraryMetadata(library, undefined, false);
break;
case (Action.Delete):
await this.actionService.deleteLibrary(library, () => {
this.loadPageSource.next(true);
});
break;
case (Action.AnalyzeFiles):
await this.actionService.analyzeFiles(library);
break;
case(Action.Edit):
this.actionService.editLibrary(library);
break;

View file

@ -20,7 +20,7 @@
.widget-button--indicator {
position: absolute;
top: 30px;
top: 24px;
color: var(--event-widget-activity-bg-color);
&.error {
@ -79,6 +79,7 @@
.dark-menu-item {
&.update-available {
cursor: pointer;
opacity: 1;
i.fa {
color: var(--primary-color) !important;

View file

@ -72,8 +72,6 @@ export class EventsWidgetComponent implements OnInit, OnDestroy {
*/
updateAvailable: boolean = false;
debugMode: boolean = false;
protected readonly EVENTS = EVENTS;

View file

@ -1,8 +1,3 @@
form {
max-height: 38px;
}
.search-result img {
width: 100% !important;
}
@ -16,75 +11,89 @@ form {
.typeahead-input {
border: 1px solid transparent;
border-radius: 4px;
padding: 0px 6px;
display: inline-block;
overflow: hidden;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
position: relative;
z-index: 1;
box-sizing: border-box;
box-shadow: none;
cursor: text;
background-color: var(--searchbar-bg-color);
color: var(--body-text-color);
min-height: 32px;
transition-property: all;
transition-duration: 0.3s;
display: block;
width: 50%;
.search {
display: flex;
position: relative;
z-index: 1;
box-sizing: border-box;
box-shadow: none;
cursor: text;
background-color: var(--input-bg-color);
color: var(--body-text-color);
min-height: 38px;
min-height: 32px;
.btn-close {
position: unset;
margin-top: unset;
align-self: center;
margin: 0 8px;
}
}
input {
width: 100%;
padding: 0px 6px;
outline: 0 !important;
border-radius: .28571429rem;
margin: 0px !important;
text-indent: 0 !important;
line-height: inherit !important;
box-shadow: none !important;
transition-property: all;
transition-duration: 0.3s;
display: block;
opacity: 1;
position: relative;
left: 4px;
border: none;
background-color: transparent;
.search {
display: flex;
position: relative;
&:focus-visible {
width: 100%;
}
}
&.focused {
width: 100%;
border-color: var(--primary-color);
input {
outline: 0 !important;
border-radius: .28571429rem;
padding: 0px !important;
min-height: 0px !important;
max-width: 100% !important;
margin: 0px !important;
text-indent: 0 !important;
line-height: inherit !important;
box-shadow: none !important;
width: 300px;
transition-property: all;
transition-duration: 0.3s;
display: block;
opacity: 1;
position: relative;
left: 4px;
border: none;
&:focus-visible {
width: calc(100vw - 180px);
}
&:empty {
padding-top: 6px !important;
}
color: #fff;
}
&.focused {
width: 98.5%;
border-color: var(--input-focused-border-color);
}
}
}
@media only screen and (max-width: 980px) {
.typeahead-input {
width: 65%;
}
}
/* small devices (phones, 650px and down) */
@media only screen and (max-width:650px) {
input {
width: 100%
.typeahead-input {
width: 75%;
margin: 0 auto;
}
}
input:focus-visible {
width: 100% !important;
}
@media only screen and (max-width: 500px) {
.typeahead-input {
width: 100%;
}
}
@ -160,10 +169,10 @@ ul ul {
}
.overlay {
position: absolute;
position: fixed;
top: 0;
left: 0;
background: rgba(0,0,0,0.4);
width: 100%;
height: 100dvh;
}
width: 100vw;
height: 100vh;
}

View file

@ -9,12 +9,14 @@
}
<a class="navbar-brand dark-exempt" routerLink="/home" routerLinkActive="active">
<app-image width="28px" height="28px" imageUrl="assets/images/logo-32.png" classes="logo" />
<span class="d-none d-md-inline logo"> Kavita</span>
<app-image width="24px" height="24px" imageUrl="assets/images/logo-32.png" classes="logo-icon" />
<div class="d-none d-md-inline logo">
<span>Kavita</span>
</div>
</a>
<ul class="navbar-nav col me-auto">
@if (accountService.currentUser$ | async; as user) {
<div class="nav-item">
<div class="nav-item search">
<label for="nav-search" class="form-label visually-hidden">{{t('search-series-alt')}}</label>
<div class="ng-autocomplete">
<app-grouped-typeahead
@ -161,8 +163,6 @@
}
</ul>
@if (!searchFocused) {
@if((breakpoint$ | async)! > Breakpoint.Tablet) {
@if (backToTopNeeded) {
<div class="back-to-top">
@ -206,7 +206,7 @@
</div>
}
}
}
</div>
</nav>

View file

@ -1,91 +1,140 @@
.btn:focus, .btn:hover {
.btn:focus {
box-shadow: 0 0 0 0.1rem var(--navbar-btn-hover-outline-color);
}
.navbar {
background-color: var(--navbar-bg-color);
background-color: var(--navbar-bg-color);
.side-nav-toggle {
cursor: pointer;
margin-left: 13px;
font-size: 1.2rem;
i {
color: var(--navbar-fa-icon-color);
}
.navbar-nav {
.nav-item {
&.search {
width: 100%;
}
}
}
.side-nav-toggle {
cursor: pointer;
margin-left: 0.8125rem;
font-size: 1.2rem;
i {
color: var(--navbar-fa-icon-color);
opacity: 0.8;
}
&:hover {
i {
opacity: 1;
}
}
}
.nav-item:not(.search) {
display: unset;
opacity: 0.8;
&:hover {
opacity: 1;
}
}
}
// On Really small screens, hide the server settings wheel and show it in nav
// TODO: Look into doing this with bootstrap 5 (and moving to _utilities.scss)
.xs-only {
display: none;
}
.not-xs-only {
display: inherit;
}
@media only screen and (max-width:300px) {
.xs-only {
display: inherit;
}
.not-xs-only {
display: none;
}
}
.nav-item.dropdown {
position: unset;
}
.navbar-brand {
font-family: var(--brand-font-family);
font-weight: bold;
margin: 0 2rem;
display: flex;
align-items: center;
&:hover {
text-decoration: none;
}
.logo-icon {
align-items: center;
align-self: center;
display: flex;
flex-direction: column;
height: 1.5rem;
width: 1.5rem;
margin-right: 0.5rem;
}
.logo {
vertical-align: text-top;
max-height: 1.75rem;
line-height: 2.0625rem;
margin-left: 0.3125rem;
}
.phone-hidden {
vertical-align: middle;
}
}
.focus-visible:focus {
visibility: visible;
color: var(--nav-header-text-color);
}
.ng-autocomplete {
margin-bottom: 0px;
}
.primary-text {
color: var(--nav-header-text-color);
border: none;
}
.search-result {
width: 1.5rem;
margin-top: 0.3125rem;
}
.scroll-to-top:hover {
animation: MoveUpDown 1s linear infinite;
}
.text-light {
color: var(--search-result-text-lite-color) !important;
}
/* small devices (phones, 650px and down) */
@media only screen and (max-width:650px) {
.navbar-nav {
width: 0;
.navbar-nav {
width: 0;
}
.navbar-brand {
margin: 0 1rem 0 1rem;
.logo-icon {
margin: unset;
}
}
// On Really small screens, hide the server settings wheel and show it in nav
// TODO: Look into doing this with bootstrap 5 (and moving to _utilities.scss)
.xs-only {
display: none;
}
.not-xs-only {
display: inherit;
}
@media only screen and (max-width:300px) {
.xs-only {
display: inherit;
}
.not-xs-only {
display: none;
}
}
.nav-item.dropdown {
position: unset;
}
.navbar-brand {
font-family: var(--brand-font-family);
font-weight: bold;
margin: 0 1rem;
&:hover {
text-decoration: none;
}
.logo {
max-height: 28px;
vertical-align: text-top;
}
.phone-hidden {
vertical-align: middle;
}
}
.focus-visible:focus {
visibility: visible;
color: var(--nav-header-text-color);
}
.ng-autocomplete {
margin-bottom: 0px;
}
.primary-text {
color: var(--nav-header-text-color);
border: none;
}
.search-result {
width: 24px;
margin-top: 5px;
}
.scroll-to-top:hover {
animation: MoveUpDown 1s linear infinite;
}
.text-light {
color: var(--search-result-text-lite-color) !important;
}
}

View file

@ -1,7 +1,7 @@
<ng-container *transloco="let t; read: 'download-button'">
@if (canDownload$ | async) {
@if (download$ | async; as download) {
<button class="btn btn-secondary-outline" (click)="downloadClicked()" [ngbTooltip]="t('download-tooltip')" [disabled]="download !== null">
<button class="btn btn-actions" (click)="downloadClicked()" [ngbTooltip]="t('download-tooltip')" [disabled]="download !== null">
@if (download) {
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
<span class="visually-hidden">{{t('downloading-status')}}</span>
@ -10,7 +10,7 @@
}
</button>
} @else {
<button class="btn btn-secondary-outline" (click)="downloadClicked()" [ngbTooltip]="t('download-tooltip')">
<button class="btn btn-actions" (click)="downloadClicked()" [ngbTooltip]="t('download-tooltip')">
<i class="fa fa-arrow-alt-circle-down" aria-hidden="true"></i>
</button>
}

View file

@ -1,5 +1,5 @@
<ng-container *transloco="let t; read: 'series-detail'">
<app-bulk-operations [actionCallback]="bulkActionCallback" [topOffset]="56"></app-bulk-operations>
<app-bulk-operations [actionCallback]="bulkActionCallback" [marginLeft]="12" [marginRight]="0"></app-bulk-operations>
@if (series && seriesMetadata && libraryType !== null) {
<div [ngStyle]="{'height': ScrollingBlockHeight}" class="main-container container-fluid" #scrollingBlock>
@ -48,7 +48,7 @@
</div>
<div class="mt-3 mb-3">
<div class="row g-0">
<div class="row g-0" style="align-items: center;">
<div class="col-auto">
<div class="btn-group">
<button type="button" class="btn btn-primary-outline" (click)="read()">
@ -72,7 +72,7 @@
</div>
<div class="col-auto ms-2">
<button class="btn btn-secondary-outline" (click)="toggleWantToRead()" ngbTooltip="{{isWantToRead ? t('remove-from-want-to-read') : t('add-to-want-to-read')}}">
<button class="btn btn-actions" (click)="toggleWantToRead()" ngbTooltip="{{isWantToRead ? t('remove-from-want-to-read') : t('add-to-want-to-read')}}">
<span>
<i class="{{isWantToRead ? 'fa-solid' : 'fa-regular'}} fa-star" aria-hidden="true"></i>
</span>
@ -81,7 +81,7 @@
@if (isAdmin) {
<div class="col-auto ms-2">
<button class="btn btn-secondary-outline" id="edit-btn--komf" (click)="openEditSeriesModal()" [ngbTooltip]="t('edit-series-alt')">
<button class="btn btn-actions" id="edit-btn--komf" (click)="openEditSeriesModal()" [ngbTooltip]="t('edit-series-alt')">
<span><i class="fa fa-pen" aria-hidden="true"></i></span>
</button>
</div>
@ -89,19 +89,19 @@
@if ((accountService.hasValidLicense$ | async) && libraryAllowsScrobbling) {
<div class="col-auto ms-2">
<button class="btn btn-secondary-outline" (click)="toggleScrobbling($event)" [ngbTooltip]="t('scrobbling-tooltip')">
<button class="btn btn-actions" (click)="toggleScrobbling($event)" [ngbTooltip]="t('scrobbling-tooltip')">
<i class="fa-solid fa-tower-{{(isScrobbling) ? 'broadcast' : 'observation'}}" aria-hidden="true"></i>
</button>
</div>
}
<div class="col-auto ms-2 d-none d-md-block">
<div class="card-actions mt-2" [ngbTooltip]="t('more-alt')">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="seriesActions" [labelBy]="series.name" iconClass="fa-ellipsis-h" btnClass="btn-secondary-outline btn"></app-card-actionables>
<div class="card-actions btn-actions" [ngbTooltip]="t('more-alt')">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="seriesActions" [labelBy]="series.name" iconClass="fa-ellipsis-h" btnClass="btn"></app-card-actionables>
</div>
</div>
<div class="col-auto ms-2 d-none d-md-block">
<div class="col-auto ms-2 d-none d-md-block btn-actions">
<app-download-button [download$]="download$" [entity]="series" entityType="series"></app-download-button>
</div>

View file

@ -27,4 +27,6 @@
}
}
:host ::ng-deep .card-actions.btn-actions .btn {
padding: 0.375rem 0.75rem;
}

View file

@ -1,7 +1,7 @@
<ng-container *transloco="let t;">
<div class="container-fluid">
<div class="row g-0">
<div class="col-10">
<div class="settings-row g-0 row">
<div class="col-10 setting-title">
<h6 class="section-title">
@if (labelId) {
<label class="reset-label" [for]="labelId">{{title}}</label>
@ -15,9 +15,9 @@
</div>
<div class="col-2 text-end align-self-end justify-content-end">
@if (showEdit) {
<button type="button" class="btn btn-text btn-sm" (click)="toggleEditMode()" [disabled]="!canEdit">
{{isEditMode ? t('common.close') : (editLabel || t('common.edit'))}}
</button>
<button type="button" class="btn btn-text btn-sm" (click)="toggleEditMode()" [disabled]="!canEdit">
{{isEditMode ? t('common.close') : (editLabel || t('common.edit'))}}
</button>
}
@if (titleActionsRef) {
<ng-container [ngTemplateOutlet]="titleActionsRef"></ng-container>
@ -25,7 +25,6 @@
</div>
</div>
@if (isEditMode) {
<ng-container [ngTemplateOutlet]="valueEditRef"></ng-container>
} @else {
@ -34,7 +33,6 @@
</span>
}
@if (subtitle) {
<div class="text-muted mt-2" [innerHTML]="subtitle | safeHtml"></div>
}

View file

@ -1,21 +1,19 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject} from '@angular/core';
import {CommonModule, NgOptimizedImage} from '@angular/common';
import {NgOptimizedImage} from '@angular/common';
import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
import {NgbCollapse, NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
import {translate, TranslocoDirective} from "@jsverse/transloco";
import {AccountService} from "../../../_services/account.service";
import {ToastrService} from "ngx-toastr";
import {EditExternalSourceItemComponent} from "../edit-external-source-item/edit-external-source-item.component";
import {ExternalSource} from "../../../_models/sidenav/external-source";
import {ExternalSourceService} from "../../../_services/external-source.service";
import {FilterPipe} from "../../../_pipes/filter.pipe";
import {SmartFilter} from "../../../_models/metadata/v2/smart-filter";
import {WikiLink} from "../../../_models/wiki";
@Component({
selector: 'app-manage-external-sources',
standalone: true,
imports: [CommonModule, FormsModule, NgOptimizedImage, NgbTooltip, ReactiveFormsModule, TranslocoDirective, NgbCollapse, EditExternalSourceItemComponent, FilterPipe],
imports: [FormsModule, NgOptimizedImage, NgbTooltip, ReactiveFormsModule, TranslocoDirective, NgbCollapse, EditExternalSourceItemComponent, FilterPipe],
templateUrl: './manage-external-sources.component.html',
styleUrls: ['./manage-external-sources.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush

View file

@ -1,5 +1,5 @@
<ng-container *transloco="let t; read: 'side-nav-companion-bar'">
<div class="mt-0 ms-1 d-flex justify-content-between align-items-center">
<div class="mt-0 d-flex justify-content-between align-items-center">
<div>
<ng-content select="[title]"></ng-content>
<ng-content select="[subtitle]"></ng-content>

View file

@ -1,152 +1,33 @@
@import '../../../../theme/variables';
::ng-deep .side-nav.closed {
::ng-deep .side-nav app-side-nav-item:first-child {
.active-highlight {
border-top-left-radius: 3px;
}
}
::ng-deep .side-nav app-side-nav-item:first-child {
.side-nav-item {
.side-nav-text {
opacity: 0 !important;
}
.card-actions {
opacity: 0 !important;
}
&.active {
color: var(--side-nav-item-active-color);
background-color: unset !important;
}
border-top-left-radius: 3px;
}
}
.side-nav-item {
position: relative;
align-items: center;
display: flex;
justify-content: space-between;
padding: 0 0 0 10px;
width: 100%;
height: auto;
min-height: 40px;
overflow: hidden;
cursor: pointer;
font-size: 0.9rem;
.side-nav-text {
opacity: 1;
min-width: 100px;
word-break: break-all;
-webkit-line-clamp: 1;
text-overflow: ellipsis;
display: -webkit-box !important;
-webkit-box-orient: vertical;
overflow: hidden;
div {
min-width: 102px;
width: 100%
@media (max-width: $grid-breakpoints-lg) {
::ng-deep .side-nav app-side-nav-item:first-child {
.side-nav-item {
border-top-left-radius: 0px;
}
}
span {
display:flex;
&:last-child {
flex-grow: 1;
justify-content: end;
}
div {
align-items: center;
height: 100%;
justify-content: inherit;
min-width: 30px;
width: 100%;
padding-left: 5px;
i {
font-size: 18px;
}
::ng-deep .side-nav app-side-nav-item:last-child {
.side-nav-item {
border-bottom-left-radius: 0px;
}
}
&.closed {
.side-nav-text {
opacity: 0;
}
.card-actions {
opacity: 0;
}
&.active {
color: var(--side-nav-item-active-color);
background-color: unset;
}
i {
color: var(--side-nav-item-closed-color);
}
&:hover {
color: var(--side-nav-hover-text-color);
background-color: var(--side-nav-hover-bg-color);
i {
color: var(--side-nav-item-closed-hover-color);
}
}
}
&:hover {
color: var(--side-nav-hover-text-color);
background-color: var(--side-nav-hover-bg-color);
.card-actions i.fa {
// TODO: The override to white does not work, please fix for light themes
color: var(--side-nav-hover-text-color) !important;
}
}
&.active {
color: var(--side-nav-item-active-color);
background-color: var(--side-nav-active-bg-color);
.active-highlight {
background-color: var(--side-nav-item-active-color);
width: 5px;
height: 100%;
position: absolute;
left: 0;
}
.side-nav-text, i {
color: var(--side-nav-item-active-text-color) !important;
}
&:hover {
color: var(--side-nav-hover-text-color);
background-color: var(--side-nav-hover-bg-color);
.card-actions i.fa {
// TODO: The override to white does not work, please fix for light themes
color: var(--side-nav-hover-text-color) !important;
}
}
}
}
a {
text-decoration: none;
color: var(--side-nav-text-color);
}
@media (max-width: $grid-breakpoints-lg) {
.side-nav-item {
align-items: center;
padding: 0 10px;
height: 55px;
font-size: 1rem;
.side-nav-text {
width: 100%;
@ -155,12 +36,5 @@ a {
span:last-child {
flex-grow: 0;
}
&.closed {
.card-actions {
font-size: inherit;
}
}
}
}

View file

@ -9,7 +9,7 @@
@for(section of sections; track section.title + section.children.length; let idx = $index;) {
@if (hasAnyChildren(user, section)) {
<h5 class="side-nav-header mt-3 mb-2 ms-3" [ngClass]="{'mt-4': idx > 0}">{{t(section.title)}}</h5>
<h5 class="side-nav-header mb-2 ms-3" [ngClass]="{'mt-4': idx > 0}">{{t(section.title)}}</h5>
@for(item of section.children; track item.fragment) {
@if (accountService.hasAnyRole(user, item.roles)) {
<app-side-nav-item [id]="'nav-item-' + item.fragment" [noIcon]="true" link="/settings" [fragment]="item.fragment" [title]="item.fragment | settingFragment" [badgeCount]="item.badgeCount$ | async"></app-side-nav-item>

View file

@ -1,84 +1,36 @@
@import '../../../theme/variables';
// TODO: Move this to a common file so it applies both ways
.side-nav {
padding-bottom: 10px;
width: 190px;
background-color: var(--side-nav-bg-color);
height: calc((var(--vh)*100) - 75px);
position: fixed;
margin: 0;
left: 10px;
top: 73px;
overflow-y: hidden;
overflow-x: hidden;
border-radius: var(--side-nav-border-radius);
transition: width var(--side-nav-openclose-transition), background-color var(--side-nav-bg-color-transition), border-color var(--side-nav-border-transition);
border: var(--side-nav-border);
scrollbar-gutter: stable both-edges;
scrollbar-width: thin;
// For firefox
@supports (-moz-appearance:none) {
scrollbar-color: transparent transparent;
scrollbar-width: thin;
scrollbar-color: transparent transparent;
scrollbar-width: thin;
}
&::-webkit-scrollbar {
background-color: transparent; /*make scrollbar space invisible */
width: inherit;
display: none;
visibility: hidden;
background: transparent;
background-color: transparent; /*make scrollbar space invisible */
width: inherit;
display: none;
visibility: hidden;
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: transparent; /*makes it invisible when not hovering*/
background: transparent; /*makes it invisible when not hovering*/
}
&:hover {
scrollbar-width: thin;
overflow-y: auto;
// For firefox
@supports (-moz-appearance:none) {
scrollbar-color: rgba(255,255,255,0.3) rgba(0, 0, 0, 0);
}
&::-webkit-scrollbar-thumb {
visibility: visible;
background-color: rgba(255,255,255,0.3); /*On hover, it will turn grey*/
}
}
&.no-donate {
height: calc((var(--vh)*100) - 82px);
}
&.hidden {
display: none;
opacity: 0;
}
&.closed {
width: 50px;
overflow-x: hidden;
scrollbar-width: thin;
overflow-y: auto;
background-color: var(--side-nav-closed-bg-color);
border: var(--side-nav-border-closed);
}
// For firefox
@supports (-moz-appearance:none) {
scrollbar-color: rgba(255,255,255,0.3) rgba(0, 0, 0, 0);
}
.side-nav-item:first {
border-top-left-radius: var(--side-nav-border-radius);
border-top-right-radius: var(--side-nav-border-radius);
}
}
::ng-deep .side-nav-text {
div {
display: flex;
}
span {
font-size: 0.6rem;
&::-webkit-scrollbar-thumb {
visibility: visible;
background-color: rgba(255,255,255,0.3); /*On hover, it will turn grey*/
}
}
}
@ -112,21 +64,6 @@
height: calc((var(--vh)*100) - var(--nav-mobile-offset));
}
}
.side-nav-overlay {
background-color: var(--side-nav-overlay-color);
width: 100vw;
height: calc((var(--vh)*100) - var(--nav-offset));
position: absolute;
left: 0;
z-index: 998;
&.closed {
display: none;
}
}
}
.side-nav-header {
@ -134,12 +71,3 @@
font-weight: bold;
margin-left: 5px;
}
.side-nav-header:first-of-type {
margin-top: 0.5rem !important;
}
// Overrides for this component
::ng-deep .side-nav-item {
padding: 0 0 0 20px !important;
}

View file

@ -1,6 +1,6 @@
<ng-container *transloco="let t; read: 'series-detail'">
<app-bulk-operations [actionCallback]="bulkActionCallback" [topOffset]="55"></app-bulk-operations>
<app-bulk-operations [actionCallback]="bulkActionCallback" [marginLeft]="12" [marginRight]="0"></app-bulk-operations>
<div [ngStyle]="{'height': ScrollingBlockHeight}" class="main-container container-fluid" #scrollingBlock>