Sass extending isn't working with simple example - css

below is both simple sass code,an Angular 2 component accessing the sass code, and the rendered HTML. In my last span element, blueBig is not working as it should. I'm new to sass and I'm not sure why this simple example is not extending properly. Can anyone shed some light on this issue for me? Thank you!
Angular2 Component
#Component({
selector: 'test',
template: `
<h1> testing sass</h1>
<span [ngClass]="{blue : true}">This should be blue</span>
<br>
<span [ngClass]="{big: true}">This should be big</span>
<br>
<span [ngClass]="{blue : true, big: true }">This should be big and blue</span>
<br>
<span [ngClass]="{blueBig : true}"> this should be big and blue as well</span>
`,
styleUrls: ['assets/scss/testing-component.scss']
})
Sass
.blue{
color:blue;
}
.big{
font-size: 200%;
}
.blueBig{
#extend .blue;
#extend .big;
}
HTML
Rendered HTML

I compiled your Sass locally and it appears to be authored correctly.
Without being able to see the rendered HTML, my guess is that Angular is converting camelcase blueBig into kebab-case blue-big. Try putting quotes around the classname, i.e.
<span [ngClass]="{'blueBig' : true}">

Related

How to set a SCSS variable using angular

i am trying to change a css variable using a component but for some reason it doesn't work, any help ?
//work but i dont want to use the property background
<div class="planete" [ngStyle]="{'background': planete.planeteBackgroundColor }"></div>
/* this is what i'd like to do :
.SCSS
$my-var
/*...*/
background: $my-var;
HTLM:
// does not work
<div class="planete" [ngStyle]="{'$my-var': planete.planeteBackgroundColor }">
// second option:
.SCSS
--my-var
/*...*/
background: var(--my-var)
HTLM:
// does not work
<div class="planete" [ngStyle]="{'--my-var': planete.planeteBackgroundColor }">
Thanks for the reply
Have you tried?
<div class="planete" [ngStyle]="{'background': var(planeteBackgroundColor) }">
.SCSS
planeteBackgroundColor='FFFFFF'
But the easieast way to build dynamic theme should be:
<div class="planete" [ngStyle]="{'background': planeteBackgroundColor }">
and define variable in your component ts file:
planeteBackgroundColor='FFFFFF'

Angular HTML class.otherclass explanation

I have seen this HTML line in an Angular project:
<div id="player" class="player" [class.voted]="booleanvar">
The CSS contains a defintion of .player.voted
I'm not really sure what this part means: [class.voted]="booleanvar"
This is one way of dynamically applying a class to an HTML element in Angular.
If booleanvar equates to true then the css class voted will be applied, so long as its defined correctly in CSS file. If it equates to false, then the class will not be applied.
<div id="player" class="player" [class.voted]="booleanvar">
I hope you help it
[class.voted]="booleanvar" this means the element add a class "voted" when "booleanvar" poperty or a variable value is true.
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
template:`
<div id="player" class="player" [class.voted]="booleanvar">
`
})
export class AppComponent {
booleanvar:boolean = true;
}
when booleanvar = false then the render element like '<div id="player" class="player">'
Otherwise it's render <div id="player" class="player voted">

How to open and hide ng-bootstrap datepicker on custom actions?

Currently I am using:
ng-bootstrap 1.0.0-alpha.24
angular/core 4.0.0
bootstrap 4.0.0-alpha.6
I wanted to ask if someone knows how to autoclose the datepicker
when the focus is lost or another datepicker is opened.
Also i wanted to now if it is possible to close the datepicker in the component code with typescript.
It would be nice if someone could provide a working plunker or a code snippet.
My actual implementation:
<div class="input-group">
<input class="rect-border full-width"
placeholder="YYMMDD"
[(ngModel)]="selectedDate"
ngbDatepicker
#datePickerInput="ngbDatepicker"
(keydown.arrowup)="incrementDate()"
(keydown.arrowdown)="decrementDate()"
(ngModelChange)="validate('modelChanged')"
(blur)="validate(null)"
[disabled]="disabled"
[ngClass]="{'input-required': required, 'normal-color': valid, 'picker-disabled': disabled}">
<div class="input-group-addon rect-border"
(click)="disabled ? true : datePickerInput.toggle()"
[ngClass]="{'picker-button-disabled': disabled}">
<img src="assets/img/calendar-icon.svg" class="datpickerToggle"/>
</div>
</div>
Plunker: ng-bootstrap team demo
I have searched a long time and I am also pretty new to angular and these things.
Thank you for your help!
Update:
Possible solution:
There were a lot of good solutions provided.
I also found out by myself that I could use the class NgbInputDatepicker
to close the datePicker (I always used NgbDatepicker, so it didn't work).
#ViewChild('datePickerInput') datePicker: NgbInputDatepicker;
this.datePicker.close();
you can open and close your datepicker from your html itself
for eg:
<div class="input-group">
<input class="rect-border full-width"
placeholder="YYMMDD"
[(ngModel)]="selectedDate"
ngbDatepicker
#datePickerInput="ngbDatepicker"
(keydown.arrowup)="incrementDate()"
(keydown.arrowdown)="decrementDate()"
(ngModelChange)="validate('modelChanged')"
(blur)="validate(null)"
[disabled]="disabled"
[ngClass]="{'input-required': required, 'normal-color': valid, 'picker-disabled': disabled}">
<div class="input-group-addon rect-border"
(click)="disabled ? true : datePickerInput.toggle()"
[ngClass]="{'picker-button-disabled': disabled}">
<img src="assets/img/calendar-icon.svg" class="datpickerToggle"/>
</div>
</div>
<div (click)="datePickerInput.open()"></div>
<span (click)="datePickerInput.close()"></span>
and also there are many functions which you can use in your html. some are close(), isOpen(), manualDateChange(), open(), toggle(), validate() etc. You can refer it in this plunkr http://plnkr.co/edit/G1b6fFrtVZwEz4lsou8n?p=preview
In typescript you can simply define a variable datepickerVisibility and then in your template use *ngIf to show or hide your datepicker component. Here is a demo code:
Template: <datepicker *ngIf="datepickerVisibility" [ngModel]="date"> </datepicker>
Component: private datepickerVisibility: boolean = false;
// Show the datepicker
showDatepicker() {
this.datepickerVisibility = true;
}
Edit:
Therefore you could use jQuery. Add the jQuery js into your index.html and in your typescript component use jQuery as follows:
declare let jQuery: any;
#Component({
moduleId: module.id,
selector: 'test',
templateUrl: 'template.html',
styleUrls: ['test.css'],
})
export class TestComponent {
constructor() {}
public toggleDatepicker() {
jQuery("#datepicker01").toggle();
}
}
And in your template file just add the id datepicker01 to your datepicker div
<div id="datepicker01" ...>
I was looking for a solution to this issue, but in a scenario where the datepicker is wrapped in a custom component and has to expose a function a parent component can call to toggle the datepicker. The answers provided are great and will work for most use case, but not mine, as I didn't want to add a jQuery dependency and calling toggle from the HTML isn't an option.
Here's how I solved it.
I added a ViewChild reference to the datepicker input in the *.component.ts file
#ViewChild('d', {static: true}) d;
that matches the datepicker identifier in the HTML file
<input (dateSelect)="dateSelected($event)" class="form-control" (focus)='d.toggle()' placeholder="yyyy-mm-dd" name="d"
[ngModelOptions]="{standalone: true}" [(ngModel)]="date" ngbDatepicker #d="ngbDatepicker">
and called the toggle function within a method exposed by the component
toggle() {
this.d.toggle();
}
That way, another component can call the toggle() function exposed by this component to toggle the datepicker like so:
In HTML
<app-custom-datepicker #date></app-custom-date-picker>
In .ts file
#ViewChild('date', {static: true}) date;
.
.
.
this.date.toggle();

Angular 2 + Semantic UI , component encapsulation breaks style

I'm using Angular2 with Semantic UI as a css library. I have this piece of code:
<div class="ui three stakable cards">
<a class="ui card"> ... </a>
<a class="ui card"> ... </a>
<a class="ui card"> ... </a>
</div>
the cards are rendered nicely with a space between and such.
like this: refer to cards section in the link
since the cards represent some kind of view I thought of making a component out of it, so now the code is:
<div class="ui three stakable cards">
<my-card-component></my-card-component>
<my-card-component></my-card-component>
<my-card-component></my-card-component>
</div>
but now the style is broken, there is no space between them anymore.
Is there any nice way of fixing this ?
the first thing I thought of doing is this:
my-card-component OLD template:
<a class="ui card">
[some junk]
</a>
|||
VVV
my-card-component NEW template:
[some junk]
and instantiating like:
<my-card-component class="ui card"></my-card-component>
or like:
<a href="?" my-card-component></a>
but this is not satisfactory since I want to be able to pass in an object and the component would automatically set the [href]=obj.link.
in AngularJS 1.0 there was a replace: true property which does excatly what i need, is there a similar thing in Angular2 ?
There is no replace=true in Angular2. It is considered a bad solution and deprecated in Angular 1.x as well.
See also Why is replace deprecated in AngularJS?
Use an attribute-selector instead of a tag-selector in your component or directive.
Just change
#Directive({ ..., selector: "my-card-component"})
to
#Directive({ ..., selector: "a[my-card-component]"})
and use it like
<a my-card-component class="ui card"> ... </a>
You might also adjust the encapsulation strategy http://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html but I think the default emulated should be fine in your case.
Solved it using #GünterZöchbauer Answer together with #HostBinding('href')
so now the code is:
template:
---------
[some junk]
component:
----------
#Component({
selector: 'a[my-card-component].ui.card',
templateUrl: 'urlOfSomeJunk.html',
directives: []
})
export class ProblemCardComponent {
#Input()
obj: MyObject;
#HostBinding('attr.href') get link { return this.obj.link; }
}
instantiating:
--------------
<a class="ui card" my-card-component [obj]="someBindingHere"></a>
that way the href is automatically bound to obj.link and I can rest in piece.

Angular2 Bind Attribute Value

Similar to Angular2 two-way data binding, I have a parent and a child component. In the parent I change the value that is passed to the child component via property. The property of the child is named percentage.
https://gist.github.com/ideadapt/59c96d01bacbf3222096
I want to bind the property value to a html attribute value. Like: <div style="width: {{percentage}}%">. I didn't find any syntax that worked. So I ended up using a change listener that does some manual DOM update:
this.progressElement = DOM.querySelector(element.nativeElement, '.progress');
DOM.setAttribute(this.progressElement, "style", `width: ${this.percentage}%`);
Is there a more elegant way to accomplish this?
You can use percentage binding for CSS properties: [style.width.%]
import {Component, Input} from 'angular2/core';
#Component({
selector: 'progress-bar',
template: `
<div class="progress-bar">
<div [style.width.%]="value"> {{ value }}% </div>
</div>
`,
})
export class ProgressBar {
#Input() private value: number;
}
Use NgStyle, which works similar to Angular 1. Since alpha-30, NgStyle is available in angular2/directives:
import {NgStyle} from 'angular2/directives';
Then include NgStyle in the directives list, this should work (here are some examples):
#View({
directives: [NgStyle]
template: `
<div class="all">
<div class="progress" [ng-style]="{'width': percentage + '%'}"></div>
<span class="label">{{percentage}}</span>
</div>
`
})
Alternatively and without using NgStyle, this would work well too:
<div class="progress" [style.width]="percentage + '%'"></div>

Resources