I wanted to make a toggle dark theme for my project which will work in every component
the resources i found was on angular material. but i dont wanna use that,
is there any way to do it?
please help!
In order to do that, on your toggle button add a click functionality and change properties and accordingly change colors too. Something like this:
// In your HTML
<div [class.dark-class]="isDark" [class.white-class]="!isDark">
<button (click)="isDark = !isDark">Toggle background</button>
</div>
// In your SCSS file, have 2 class, one called dark-class and the other white-class
.dark-class { background: black }
.white-class { backgrond: white }
// In your component.ts file, add a boolean value 'isDark' and set it to false initially
private isDark: boolean = false;
So here what happened is, initially since the boolean value is dark, the div will have a 'white-class' background since i added a '!isDark' condition on the [class.white-class] and when you click the button, i am changing 'isDark' to '!isDark' which means, the 'isDark' will now become true and then the background changes to a dark color.
This is one approach where you can follow.
For your other question: How to do this globally? you can do something like this:
// If you have a service which is being used across all the components, you can use it otherwise create a new one like this:
1) Create a file and name it a commonService
// Inside common service:
#Injectable({ provideIn: 'root' })
export class CommonService {
globalIsDark: boolean = false;
setGlobalDark(value: boolean) {
this.globalIsDark = value;
}
getGlobalDark(): boolean {
return this.globalIsDark;
}
}
// Now in your styles.scss file, add the dark and white classes
.dark-class { background: black }
.white-class { backgrond: white }
// In every component, wherever you want to use, do this:
constructor(private commonService: CommonService) {}
isComponentBGDark: boolean;
ngOnInit() {
// If you want to use what's there, do this
this.isComponentBGDark = this.commonService.getGlobalDark();
// If you want to set the theme to dark, do this:
this.commonService.setGlobalDark(true);
}
// In your component HTML
<div [class.dark-class]="isComponentBGDark"
[class.white-class]="!isComponentBGDark"
>
</div>
Related
I added new settings for user by inheriting "res.users" model:
calendar_scale_type = fields.Selection([
('day', 'Day'),
('week', 'Week'),
('month', 'Month'),
('year', 'Year')],
'Type of calendar scaling', default='week')
in calendar view i want to read this field and set scale_type when opening this form
here in calendar_model.js file i want to read this setting from current user
and also rewrite current user setting if he chooses diferent type of scale here
how can i do this? i tried to use rpc, but i do something wrong and it didn`t work.
You can override the session_info and add calendar_scale_type to use it later in the calendar model (You will need to override the setScale function).
Example:
Add calendar_scale_type to the session info:
class Http(models.AbstractModel):
_inherit = 'ir.http'
def session_info(self):
session_info = super(Http, self).session_info()
session_info['calendar_scale_type'] = self.env.user.calendar_scale_type
return session_info
Override setScale function:
/* #odoo-module */
import CalendarModel from '#calendar/js/calendar_model';
import { session } from "#web/session";
CalendarModel.include({
setScale: function (scale) {
if (!_.contains(this.scales, scale)) {
scale = session.calendar_scale_type;
}
this._super(scale);
},
});
I am developing an UI framework based on antd (I call it Yooooo UI)
The design is a little different with the default style of antd and I did something to set the different color, size, margin and blablabla with setting less variables - follow the official solution.
Also, there is something new, such as I extend the type of Buttons - add 'atype', 'btype', 'ctype' to Button Component. That means I can use it like
import { Button } from 'yooooo-ui';
<Button type="atype" />
The solution for supporting this is here below
import { ButtonType } from 'antd/lib/button';
import { BaseButtonProps } from 'antd/lib/button/button';
const ExtendedButtonTypes = tuple(
'atype',
'btype',
'ctype'
);
type ExtendButtonType = typeof ExtendedButtonTypes[number];
type MyButtonType = ButtonType | ExtendButtonType;
interface MyBaseButtonProps extends Omit<BaseButtonProps, 'type'> {
type?: MyButtonType;
}
// ...something else codes
But there is a condition that Modal component used the Button component with a relative path in antd.
// codes in antd
import { ButtonProps } from './button'
// ...something else
that means, if I do nothing in Yoooo UI and use the Modal component, the button type 'atype' is invalid since Modal component doesn't use my customized Button component
import { Modal } from 'yoooo-ui';
const buttonProps = {
type: 'atype' // <-- error happened
}
<Modal
okButtonProps={buttonProps}
/>
I wanna figure out a way to handle this condition with a commonly way.
I have an issue with [ngClass]. It doesn't add or remove the class if the Circles in the HTML aren't moving. If the circles are moving it works fine.. Does somebody know why? I dont find anything in the internet.
The isSidebarMenuOpen value is coming from a other component. I got every time the right value. This is why I think the issue is with adding the css class to the div.
If the sidebar opens, I just want to move the map to the right side with a css class
<div [ngClass]="{'open': isSidebarMenuOpen}">
....svg code (circles and other stuff)
</div>
Service.ts
isSidebarMenuOpenSubject = new Subject<any>();
isSidebarMenuOpen = this.isSidebarMenuOpenSubject.asObservable();
getIsSidebarMenuOpen(isSidebarMenuOpen: boolean) {
this.isSidebarMenuOpenSubject.next(isSidebarMenuOpen)
}
Sidebar-Component
toggleSidebarMenu() {
this.isSidebarMenuOpen = !this.isSidebarMenuOpen;
this.resizeService.getIsSidebarMenuOpen(this.isSidebarMenuOpen);
}
map-component
isSidebarMenuOpen = false;
ngOnInit(): void {
this.resizeService.isSidebarMenuOpen.subscribe(value =>{
this.isSidebarMenuOpen = value
});
For example I have:
<div class="btn-wrapper-bt1">
<button>AAA</button>
</div>
This button is on the 3rd party element that exists in node_modules/somebt
I would like to do some simple class change within Angular environment.
Is there a simple way to change it in ngOnInit? Or I need to fork the source and change it within the source?
Thanks in advance.
In the html, add a #ref reference to the element containing your 3rd party component
yourComponent.html
<div #ref >
<your-3rd-party-component></your-3rd-party-component>
</div>
Then, in your component, retrieve the children of the containing element
yourComponent.ts
import { Component,Renderer2, ViewChild,ElementRef } from '#angular/core';
export class YourParentComponent {
#ViewChild('ref') containerEltRef: ElementRef;
constructor(private renderer: Renderer2)
{
}
ngAfterViewInit()
{
// retrieves element by class
let elt = this.containerEltRef.nativeElement.querySelector('.btn-wrapper-bt1');
this.renderer.addClass(elt, 'newClass'); //Adds new class to element
}
}
Here is a stacklblitz demo
Note: If you just want to change the 3rd party component's appearance, you could just override the class in your own component
yourComponent.scss
:host ::ng-deep .btn-wrapper-bt1
{
color: red;
}
Add a reference :
<div #myRef class="btn-wrapper-bt1">
<button>AAA</button>
</div>
And in your TS :
#ViewChild('myRef') myElement: ElementRef;
myFunc(){
// do whatever you want with it AFTER you third party module finished its job (that's your call)
//this.myElement.nativeElement.querySelector()
//this.myElement.nativeElement.classList.remove('toto')
}
1 ISSUE
I am trying to implement the following:
I have a container component ContainerComponent and child components ChildComponent. I want to modify the rendering and overall behaviour of the child components via the controlling ContainerComponent.
2 TECHNOLOGIES USED
Angular2, HTML, CSS, Javascript, Typescript, ES6
3 CODE
ContainerComponent.ts
export class ContainerComponent {
children: Array<Child>;
constructor(
private _el: ElementRef,
private _dcl: DynamicComponentLoader,
private _childService: ChildService) {
}
ngOnInit() {
let index = 0; // index of child component in container
this._childService.getChildren().then( // get the children models
(children) => {
this.children = children;
this.children.forEach((child, index) => {
this._dcl.loadIntoLocation(ChildComponent, this._el, 'dynamicChild')
.then(function(el){
el.instance.child = child; // assign child model to child component
el.instance.index = index;
});
});
}
);
}
}
ChildComponent.ts
export class ChildComponent {
child: Child;
index: number;
constructor(private _renderer: Renderer, private _el: ElementRef) {
}
ngOnInit() {
let delay = (this.index + 1) * 0.5; // calculate animation delay
this._renderer.setElementStyle(this._el, '-webkit-animation-delay', delay + 's !important');
this._renderer.setElementStyle(this._el, 'animation-delay', delay + 's !important');
}
}
4 CODE EXPLANATION
In the above code, the ContainerComponent dynamically inserts ChildComponents (granted, this could be done without the DynamicContentLoader).
The ChildComponents should dynamically add css properties, in this case, the animation delay once it is displayed. So based on the index of the child, the animation delay increases.
However the modifications from the renderer do not take effect, the css properties are not there at runtime.
I tried to reproduce your problem. In fact, I have problem to add styles like -webkit-animation-delay and animation-delay.
If I try with another style like color, it works fine and the style is taken into account at runtime.
ngOnInit() {
this._renderer.setElementStyle(this._el, 'color', 'yellow');
}
So it seems to be linked to animation styles... I see these links that could interest you:
How to set CSS3 transition using javascript?
http://www.javascriptkit.com/javatutors/setcss3properties.shtml
Otherwise it seems that there is some support for animation in Angular2 but it's not really documented... See this file: https://github.com/angular/angular/blob/master/modules/angular2/src/animate/animation.ts.
Hope it helps you,
Thierry
This seems to be a bug in angular2 itself. Adding !important to a style will result in an illegal value to the style and it is not applied to the element. The correct way in plain js is to use another parameter which implies if the style is important.
So the correct answer is to use:
this._renderer.setElementStyle(this._el, 'animation-delay', delay + 's'); //sans !important
and if you want to add !important you have to use:
this._el.nativeElement.style.setProperty('animation-delay', delay + 's', 'important');
The -webkit- prefix gets added (or removed) if necessary, so there is no need to add that as well
From here:
https://angular.io/docs/ts/latest/api/core/ElementRef-class.html
You should only use ElementRef as an absolute last resource. The whole idea of Angular 2 is that you don't have to mess with the dom at all. What you are trying to do can be acomplished very easy using a template:
import {NgStyle} from 'angular2/common';
import {Component} from "angular2/core";
#Component({
selector: 'app',
template: `
<div *ngFor="#child of children; #i = index">
<div [ngStyle]="{ 'z-index': i * multiplier,
'-webkit-animation-delay': i * multiplier + 's',
'animation-delay': i * multiplier + 's' }"> {{i}} - {{child}} </div>
</div>
`,
directives: [NgStyle]
})
export class AppComponent{
public children:string[] = [ "Larry", "Moe", "Curly" ];
public multiplier:number = 2;
}
Depending on the browser you might see those css properties or not, that's why I added the z-index which is more common and old so you can see you can render the css value dynamically using the index variable from ngFor inside a template.
I hope this helps !