How to toggle dark mode in Angular - css

I am trying to toggle the dark mode when a user toggles the switch, which is in the header component. See image below:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link active" href="/">Home <span class="sr-only">(current)</span></a>
<a class="nav-item nav-link" href="/about">About</a>
<a class="nav-item nav-link" href="/contact">Contact</a>
<a class="nav-item nav-link" href="/resume">Resume</a>
</div>
</div>
<div class="custom-control custom-switch">
<input (change)="onChangeToggle()" type="checkbox" class="custom-control-input" id="toggleTheme">
<label class="custom-control-label" for="toggleTheme">Dark Mode</label>
</div>
</nav>
My header component ts file holds a boolean value called setDark which is triggered in an event emitter through the Output decorator :
// header.component.ts
import { Component, OnInit , Output, EventEmitter} from '#angular/core';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
#Output() mode = new EventEmitter<boolean>();
setDark = false;
constructor() { }
ngOnInit(): void {
}
onChangeToggle() {
this.setDark = !this.setDark;
this.mode.emit(this.setDark);
console.log(this.setDark);
}
}
Then in the app.comoonent.html receive boolean
<app-header (mode)="receiveMode($event)"></app-header>
<router-outlet></router-outlet>
// app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
setMode = false;
receiveMode($event) {
this.setMode = $event;
console.log("MODEEEE", this.setMode);
}
title = 'about-me';
}
I have tried to wrap the div around the app-header and router-outlet like so:
<app-header (mode)="receiveMode($event)"></app-header>
<div class="darkTheme">
<router-outlet></router-outlet>
and using ngClass:
<div [ngClass]="{
darkTheme: setMode
}">
</div>
But it doesn't work. I did check to see whether or not the boolean is being logged into the console when toggling the switch. It is.

Have a look at this stackblitz: https://stackblitz.com/edit/angular-rubaka?file=src/app/toolbar-multirow-example.html
it toggles the class "dark-theme" on the #container:ElementRef:
<div #container style="padding: 4rem;" class="mat-typography dark-theme">
The styles.scss defines two different theme's on line 28 (default theme)...
// Include the default theme styles.
#include angular-material-theme($candy-app-theme);
and on line 39 (dark theme)...
.dark-theme {
#include angular-material-theme($dark-theme)
};
Hope this helps.

Related

React Bulma mobile nav bar is not working as expected

When I click the button to toggle the mobile nav bar it's not working. I am using Bulma css framework with react. Here is the React nav bar component:
onst Header = (props) => {
const dispatch = useDispatch()
const { loginUser, isAuthenticated, history, errors } = props;
const dropdownRef = useRef(null);
const [isActive, setIsActive] = useDetectOutsideClick(dropdownRef, false);
const [isMobileActive, setisMobileActive] = useState(false);
const onClick = () => setIsActive(!isActive);
const onLogout = () => {
dispatch(logout())
}
return (
<nav className="navbar" role="navigation" aria-label="main navigation">
<div className="navbar-brand">
<a className="navbar-item" href="https://bulma.io">
<img
src="https://bulma.io/images/bulma-logo.png"
width="112"
height="28"
/>
</a>
<a
onClick={() => {
setisMobileActive(!isMobileActive)
}}
role="button"
className={`navbar-burger burger ${isActive ? "is-active" : ""}`}
aria-label="menu"
aria-expanded="false"
data-target="navbarBasicExample"
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" className="navbar-menu">
<div className="navbar-end">
<a className="navbar-item">Dashboard</a>
<div
onClick={onClick}
ref={dropdownRef}
className={`navbar-item has-dropdown ${
isActive ? "is-active" : ""
}`}
>
<a className="navbar-link">Account</a>
<div className="navbar-dropdown is-right">
<a className="navbar-item">Account settings</a>
<a className="navbar-item">Set Job filters</a>
<a className="navbar-item">Report an issue</a>
<a className="navbar-item" onClick={onLogout}>Log out</a>
</div>
</div>
</div>
</div>
</nav>
);
};
The most bottom part with dropdown is for desktop nav bar. What is missing for mobile toggle menu. How can I fix it? Who I click the toggle button nothing happens.
I‘m not familiar with React, but on the bulma side you need to toggle the class is-active on both the navbar-burger and the targeted navbar-menu.
There are implementation examples in Bulma navbar documentation, personally I'm using the jQuery implementation which works perfectly :
$(document).ready(function() {
// Check for click events on the navbar burger icon
$(".navbar-burger").click(function() {
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
$(".navbar-burger").toggleClass("is-active");
$(".navbar-menu").toggleClass("is-active");
});
});
but there's also a Vanilla Javascript implementation in the docs if you want.

How do I show link text when sidebar is collapsed in Angular 9?

I know if i put title="link name" into the anchor tag, the description or title shows up. But I only want it to show, when the navbar is collapsed.
In the html file I have a lot more links but to save space I opted to show the rest.
.html template
<nav class="navbar-default navbar-static-side" role="navigation">
<div class="sidebar-collapse">
<ul class="nav nav-sb metismenu" id="side-menu">
<li class="nav-header" style="padding-top: 0px; padding-bottom: 0px;">
<div (click)="handleClick($event)">
<div class="profile-element" style="text-align: center;">
<img alt="image" style="max-width: 100%; max-height: 60px; text-align: center;" src="assets/images/nieto.jpg">
</div>
<div class="logo-element" style="text-align: center; color: #384C65">
SMS
</div>
</div>
</li>
<li class="nav-item mt-3" [ngClass]="{active: activeRoute('ReleaseNotes')}">
<a class="nav-link" title="ReleaseNotes" [routerLink]="['/ReleaseNotes']" style="color:#faec4c;">
<fa-icon style="padding-right: 5px;" [icon]="faExclamationTriangle"></fa-icon><span class="nav-label"> Release notes</span>
</a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Dashboard')}">
<a class="nav-link" [routerLink]="['/Dashboard']" style="color:greenyellow;">
<fa-icon style="padding-right: 5px;" [icon]="faChartLine"></fa-icon><span class="nav-label"> Dashboard</span>
</a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Agreements')}" *ngIf="globals.userHasAgreementAccess()">
<a class="nav-link" [routerLink]="['/Agreements']"><fa-icon [icon]="faFileSignature"></fa-icon><span class="nav-label"> Agreements</span></a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Appointments')}">
<a class="nav-link" [routerLink]="['/Appointments']"><fa-icon [icon]="faUsersCog"></fa-icon><span class="nav-label"> Appointments</span></a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Attachments')}">
<a class="nav-link" [routerLink]="['/Attachments']"><fa-icon [icon]="faPaperclip"></fa-icon><span class="nav-label"> Attachments</span></a>
</li>
I also shortened the ts file by a couple of lines to save space to show relevant info.
.ts file
import { Component } from '#angular/core';
import {Router} from '#angular/router';
import { GlobalsService } from 'src/app/app.globals.service';
import { faUsersCog, faUser, faCalendarCheck, faChartLine, faAlignJustify,faToolbox, faFileInvoiceDollar, faFileSignature, faPaperclip, faShoppingCart, faExclamationTriangle, faBug} from '#fortawesome/free-solid-svg-icons';
declare var jQuery:any;
#Component({
selector: 'navigation',
templateUrl: 'navigation.template.html',
})
export class NavigationComponent {
faUsersCog=faUsersCog; faUser=faUser;faCalendarCheck=faCalendarCheck;faChartLine=faChartLine;faAlignJustify=faAlignJustify;faToolbox=faToolbox; faShoppingCart=faShoppingCart;
faFileInvoiceDollar=faFileInvoiceDollar;faFileSignature=faFileSignature; faPaperclip=faPaperclip; faExclamationTriangle=faExclamationTriangle; faBug=faBug;
constructor(public globals: GlobalsService,private router: Router) {}
ngAfterViewInit() {
jQuery('#side-menu').metisMenu();
if (jQuery("body").hasClass('fixed-sidebar')) {
jQuery('.sidebar-collapse').slimscroll({
height: '100%'
})
}
}
}
You can conditionally add attributes in Angular, so you could only add the title attribute when the sidebar is collapsed.
<a class="nav-link" [attr.title]="isSidebarCollapsed ? 'Release Notes' : null">
Release notes
</a>
isSidebarCollapsed is a variable that you'll need to create in the NavigationComponent that you will need to set to true when the sidebar is collapsed, and false otherwise.

Navbar collapse button does not show items for bootstrap 4.5.0 and Nextjs 9.4.4

I am trying to create a very simple nextjs demo project using bootstrap for styling.
I am able to use the basic styling very easily by first installing bootstrap using npm and then including it in my app.js
import 'bootstrap/dist/css/bootstrap.min.css'
I created a navbar and it worked fine but when I tried to make it collapse when my screen size shrinks does not seem to work.
I tried to find my way through it and came to know that it requires popperjs and jquery in particular order, here, and I did the same. I included the 2 in my app.js file. My import is the below.
import 'jquery/dist/jquery.min.js'
import '#popperjs/core/dist/umd/popper.min.js'
import 'bootstrap/dist/css/bootstrap.min.css'
But still my toggle button does not pop the navbar items when clicked. I can see not errors on my browser console and the dev console from where I run my project.
Here is a section of dependencies from my package.json
"dependencies": {
"#popperjs/core": "^2.4.2",
"bootstrap": "^4.5.0",
"jquery": "^3.5.1",
"next": "9.4.4",
"react": "16.13.1",
"react-bootstrap": "^1.0.1",
"react-dom": "16.13.1"
}
I can see similar questions on SO but all of them are for older bootstrap version with different class names for bootstrap components.
Here is my component
/**
* className to create the navbar using bootstrap, TODO, intial version
*/
export default class NavBar extends Component {
render() {
return (
<div id="rootdiv">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarTogglerDemo01"
aria-controls="navbarTogglerDemo01"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<a class="navbar-brand" href="#">
Hidden brand
</a>
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
<li class="nav-item active">
<a class="nav-link" href="#">
Home <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
Link
</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">
Disabled
</a>
</li>
</ul>
</div>
</nav>
</div>
);
}
}```
I don't know why it did not work with native bootstrap but I was able to get it to work after switching to react-bootstrap. I hope this will help some one in future.
Also there is no need to manually import popper and jquery in the app.js file.
I only imported the bootstrap min file.
import 'bootstrap/dist/css/bootstrap.min.css'
import Navbar from "react-bootstrap/Navbar";
import Nav from "react-bootstrap/Nav";
import React from "react";
const RBNavBar = () => {
return (
<Navbar bg="light" expand="lg" id="myNavbar">
<Navbar.Brand href="#home"><img src="/logo_lpb_small.png"></img></Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="ml-auto" id="myNavItem">
<Nav.Link href="/" id="myNavItem">Home</Nav.Link>
<Nav.Link href="contact" id= "myNavItem">Contact</Nav.Link>
<Nav.Link href="about" id= "myNavItem">About Us</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
);
};
export default RBNavBar;

How I can add bulma.css toggle navbar in Next.js?

I have added bulma.css in my Next.js project and all runs well, but navbar toggle doesn't work because need add some pure javascript code and React doesn't provide pure DOM events
Just add React Lifecycle event and put your code.
ORIGINAL example:
import React from "react";
class NavBar extends React.Component {
componentDidMount() {
const $navbarBurgers = Array.prototype.slice.call(
document.querySelectorAll(".navbar-burger"),
0
);
if ($navbarBurgers.length > 0) {
// Add a click event on each of them
$navbarBurgers.forEach(el => {
el.addEventListener("click", () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle("is-active");
$target.classList.toggle("is-active");
});
});
}
}
render() {
return (
<nav className="navbar" role="navigation" aria-label="main navigation">
<div className="navbar-brand">
<a className="navbar-item" href="https://bulma.io">
<img
src="https://bulma.io/images/bulma-logo.png"
width="112"
height="28"
/>
</a>
<a
role="button"
className="navbar-burger burger"
aria-label="menu"
aria-expanded="false"
data-target="navbarBasicExample"
>
<span aria-hidden="true" />
<span aria-hidden="true" />
<span aria-hidden="true" />
</a>
</div>
<div id="navbarBasicExample" className="navbar-menu">
<div className="navbar-start">
<a className="navbar-item">Home</a>
<a className="navbar-item">Documentation</a>
<div className="navbar-item has-dropdown is-hoverable">
<a className="navbar-link">More</a>
<div className="navbar-dropdown">
<a className="navbar-item">About</a>
<a className="navbar-item">Jobs</a>
<a className="navbar-item">Contact</a>
<hr className="navbar-divider" />
<a className="navbar-item">Report an issue</a>
</div>
</div>
</div>
<div className="navbar-end">
<div className="navbar-item">
<div className="buttons">
<a className="button is-primary">
<strong>Sign up</strong>
</a>
<a className="button is-light">Log in</a>
</div>
</div>
</div>
</div>
</nav>
);
}
}
export default NavBar;
I had the same issue and in my case I can resolve it adding in the _app component this line
import 'bulma/css/bulma.css

Bootstrap 4 Navbar doesnt collapse in Angular4

I'm working with Bootstrap 4 and Ng-Bootstrap in an Angular 4 Project,
i have linked the que bootstrap.css in my angular-cli.json this way
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.css",
"styles.css"
],
and imported the NgbModule in my app.module that looks like this
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
NgbModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
i made a Navbar copying the documentation from the bootstrap website and added the toggle component from ng-bootstrap (it works well) the code looks like this
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-
target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li>
<div ngbDropdown class="d-inline-block">
<div class="nav-link" id="dropdownBasic1" ngbDropdownToggle>Toggle
dropdown</div>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<button class="dropdown-item">Action - 1</button>
<button class="dropdown-item">Another Action</button>
<button class="dropdown-item">Something else is here</button>
</div>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search"
aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0"
type="submit">Search</button>
</form>
</div>
</nav>
the problem starts when i scale down the window and the toggle does its work, when i press the button for collapsing the navbar it doesn't work.
i tried installing and linking the js files of jquery and popper and the bootstrap one, but it still doesn't work, the actual angular-cli.json looks like this
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.css",
"styles.css"
],
"scripts": [
"../node_modules/popper.js/dist/umd/popper.min.js",
"../node_modules/jquery/jquery.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js"
],
what am i doing wrong?
To work with angular you need this fix
first define this in your class public navbarCollapsed = true;
then chnage your button
<button class="navbar-toggler" type="button" (click)="navbarCollapsed = !navbarCollapsed" [attr.aria-expanded]="!navbarCollapsed" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
also you need to add this to your collapsing div
<div class="collapse navbar-collapse" [ngbCollapse]="navbarCollapsed" id="navbarSupportedContent">
now you don't need jquery, popper or bootstrap.js
you can find more info about this issue here.
also check ng-bootstraps working demo page code link.
I had the same problem, I used normal bootstrap 4 rather then ng-bootstrap and this way I don't need to any module in app.module file as well. it works. Below is the script add into angular.json (angular v6) and bootstrap 4+:
"scripts": ["../node_modules/jquery/dist/jquery.js",
"../node_modules/popper.js/dist/umd/popper.js",
"../node_modules/bootstrap/dist/js/bootstrap.js"]
For CSS I prefer to use Scss version so it goes like this.
"styles": [
"src/styles.scss",
"../node_modules/font-awesome/scss/font-awesome.scss"
],
and i import bootstrap into style.scss file
#import "~bootstrap/scss/bootstrap.scss";
Cheers!
JK
Look for the compiled classes, maybe you get the wrong version. I had a similar issue with the class col-sm-offset-#, the problem was that this classes doesn't exist in that version. Maybe could be the same issue
This is the route ..\node_modules\bootstrap\dist\js here we have two file
bootstrap.js and bootstrap.min.js
find into bootstrap.js the nav classes. if you could not found it, look for another Bootstrap repository.
Good luck.
this works fine for me
I installed
npm i --save #ng-bootstrap/ng-bootstrap ng add #angular/localize
app.module.ts
import {NgbModule} from '#ng-bootstrap/ng-bootstrap';
imports:[NgbModule]
NgbModule.forRoot() not working
angular.json
"styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css" ], "scripts": ["node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.js]`
Hope this helps, even just alittle bit

Resources