How to style Angular Material select drop down overlay - html

I have an angular component called currency-selector which has its own css file that looks like this:
.currency-select {
position: absolute;
top: 5px;
right: 80px;
z-index: 1000000;
color: #DD642A;
font-size: 17px;
padding-right: 16px;
width: 130px;
}
.mat-form-field {
display: block;
}
This works exactly as expected for the selector until it is clicked and the drop down happens. The html is as follows:
<div class="currency-select">
<mat-form-field *ngIf=loaded>
<mat-select [formControl]="currencyForm" placeholder="Select Currency">
<select-search (search)="filterCurrencyOptions($event)" #selectSearch (keydown)="$event.stopPropagation()" >
</select-search>
<mat-option *ngFor="let currency of filteredCurrencies" [value]="currency.counter_currency_code" (click)="updateCurrency()">
<flag-icon country="{{ (currency.counter_currency_iso_2 || '').toLowerCase() }}"></flag-icon> {{currency.counter_currency_code}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
When I click on the currency select, the drop down doesn't appear how I want it to appear and I can't seem to add anything in the currency-select.component.html file to alter it, instead it seems to take the styling from a different div tag, "cdk-overlay-container".
Can anyone advise as to how I can write the css for this in the currency-select css file? I've tried using !important but this isn't working eithher.

To style the drop down overlay add a class to it using the mat-select input panelClass.
<mat-select panelClass="myPanel">
Then use ::ng-deep:
::ng-deep .myPanel.mat-select-panel {
background-color: darkslategray;
}
Or disable ViewEncapsulation for the component:
#Component({
selector: 'select-panel-class-example',
templateUrl: 'select-panel-class-example.html',
styleUrls: ['select-panel-class-example.css'],
encapsulation: ViewEncapsulation.None,
})
.myPanel.mat-select-panel {
background-color: darkslategray;
}
https://stackblitz.com/edit/angular-k4pxc1

try using ng-deep
::ng-deep .your-class-name {
...
}
PS: ng-deep will get deprecated in further versions. W3C didn't defined a 'replacement' for it yet.
Answer Update (07-07-2021): If you don't want to use ng-deep (deprecated), then use ViewEncapsulation.None: angular.io/guide/component-styles#deprecated-deep--and-ng-deep

Related

Add CSS if host has (click)

I'm building a library and I have a <my-card> component. It's a component that will often have a (click) handler on it.
What I'm looking to do is to add cursor: pointer automatically when the component has (click) attached to it.
So for example, <my-card> would have the default cursor, and <my-card (click)="onClick()> would apply cursor: pointer to the component element.
Any clean way of doing this?
If you're able to change (click) to click then you could do this using CSS.
HTML:
<my-card>Look at me</my-card>
<my-card click="onClick()">Click me</my-card>
CSS:
my-card {
border-radius: 3px;
display: inline-block;
padding: 5px;
}
[click] {
background-color: red;
color: white;
cursor: pointer;
}
The [click] part in the CSS references an attribute of an element. So, this will target any element you use with the click attribute. If you only want to target any <my-card> element with the click attribute then you would change your CSS to my-card[click].
Here's a fiddle for you to reference: https://jsfiddle.net/8w9Lqxr4/1/
The Angular way to do this is to use a directive, take a look at this example:
import { HostBinding, Directive } from '#angular/core'
#Directive({
selector: '[myClick]'
})
class MyClickDirective {
#HostBinding('class.mousepointer') private isClick: boolean;
constructor(private el: ElementRef,
private renderer: Renderer) {
}
#HostListener('click') onMyElemClicked() {
this.isClick =!this.isClick;
}
}
I've not tested this example but this is the way you must investigate.

How to apply two different CSS on mat-form-field in separate pages?

I have mat-form-field on one page:-
<mat-form-field class="form-control-full-width">
<input type="text" matInput placeholder="First Name" formControlName="firstNameFC" required>
<mat-error *ngIf="hasNewUserError('firstNameFC', 'required') && isNewUserSubmitted">
First Name is required
</mat-error>
</mat-form-field>
Following CSS applied:-
.mat-form-field-label {
/*change color of label*/
color: white !important;
}
.mat-form-field-underline {
/*change color of underline*/
background-color: white !important;
}
.mat-form-field-ripple {
/*change color of underline when focused*/
background-color: white !important;;
}
.mat-input-element{
color: white !important;
}
CSS is reflecting as expected.
The problem is I have another mat-form-field on different page and want to apply different CSS(color: green, background-color: white) on the field.
Is it possible to apply different CSS on controls in different page?
Yes, you can add them in each component's css file like this:
:host ::ng-deep .mat-form-field-label {
color: white;
}
yes Its possible just create a separate file called like textfield.css
import it in your style.css like
#import 'globalcss/textfield.scss';
put that file in globalcss folder make that folder under src so
src=>globalcss=>textfield.scss
now you can take any matInput and just add style like small-text-field see the class added below
<mat-form-field class="small-text-field">
<input matInput placeholder="Username">
</mat-form-field>
and the contents in the textfield.css file goes like
.mat-form-field.smallTextfield .mat-form-field-wrapper{
font-size: 10px;
width: 125px;
}
so in whole application wherever you have matInput if you apply this class it will be added but just note that as of now ng::deep is deprecated use the below directive in the ts file as
encapsulation: ViewEncapsulation.None
this will be used inside
#Component({selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
encapsulation: ViewEncapsulation.None})
I hope this is far more better and clear explanation quite understandable as well..!!

Change font size for ion-searchbar input in Ionic 5

How do I change the font size of ion-searchbar input? Could anyone please help.
<ion-searchbar></ion-searchbar>
Here's what I tried but this does not work
.searchbar-input {
font-size: 10px;
}
Please refer to the working example which I created in Stackblitz
In Ionic 5
global.scss
ion-searchbar {
.searchbar-input-container {
input{
font-size: 14px !important;
}
}
}
Why do you have <style> tag within your home template file? Angular (what Ionic has underneath) template compiler doesn't allow it and will remove any <style> tag you add.
If you have a global .css or .scss file (e.g. index.scss) than you can simply put your .searchbar-input style there, and it should work.
Another way I can think of is, adding encapsulation: ViewEncapsulation.None to your HomePage component, which would be not ideal or could break some things, but still should work.
Check the demo: https://stackblitz.com/edit/ionic-ionsearchbar-styling-vda1eu
What I mean is this:
home.ts
#Component({
selector: 'page-home',
templateUrl: 'home.html',
styleUrls: ['./home.scss'], // added
encapsulation: ViewEncapsulation.None // added
})
export class HomePage { /*... */ }
home.scss
.searchbar-input {
font-size: 10px !important;
}
This my solution in Ionic 5:
Global.css
.searchbarinput {
input{
font-size: 20px !important;
}
}
In search page:
<ion-searchbar #searchbar (ionInput)="getProdForSearch($event)" class="searchbarinput" placeholder="Buscar produtos..." search-icon="search-sharp"></ion-searchbar>

Hover a div with NgClass

I am trying to make a hover effect on a div with a Angular ngClass directive. In the template file I have a div element with class "list-item-container' which contains a div with class "list-item" that is iterated with a *ngFor directive. Inside the "list-item" div element I have three divs with class "list-item-column" which are placed horizontally like a table row with inline display. in the div with "list-item" class I have placed a mouseenter and mouseleave event listeners which calls hoverListItem() in my .ts file. the hoverListItem() function changes the value of listItemHovered variable to true or false. In the "list-item" class I have a ngClass directive which triggers a css class 'list-item-highlight' based on the value of listItemHovered boolean value which then changes to background to a different color.
The problem I'm facing is that upon hovering mouse pointer on the "list-item" div all my "list-item" divs are affected instead of the one I am hovering over. How to solve this problem?
.html file
<div class="list-item-container">
<ng-container *ngFor="let opportunity of dealService.opportunities">
<div [ngClass]="{'list-item-highlight': listItemHovered}" class="list-item" (mouseenter)="hoverListItem()"
(mouseleave)="hoverListItem()"
(click)="selectOpportunity(opportunity)">
<div
class="list-item-column">{{opportunity.account?.name === null ? "N/A" : opportunity.account.name}}</div>
<div class="list-item-column">{{opportunity.requirementTitle}}</div>
<div class="list-item-column">{{opportunity.salesValue | number: '1.0-2'}}</div>
</div>
</ng-container>
</div>
.css file
.list-item-container{
overflow: auto;
width: 100%;
max-height: 500px;
}
.list-item{
font-size: 15px;
border-radius: 10px ;
margin-top: 5px;
height: 50px;
background: lightgray;
color: black;
}
.list-item-highlight{
background: #7e00cc;
color: white;
}
.list-item-column{
height: inherit;
vertical-align: center;
display: inline-block;
width: 33.33%;
padding-left: 40px;
}
.ts file
hoverListItem() {
this.listItemHovered = !this.listItemHovered;
}
Right now you're creating and modifying listItemHovered flag inside component context, rather you should maintain a flag for each item level, which could help to easily identify wheather component has been highlighted or not.
[ngClass]="{'list-item-highlight': opportunity.listItemHovered}"
(mouseenter)="hoverListItem(opportunity)"
(mouseleave)="hoverListItem(opportunity)"
Component
hoverListItem(opportunity) {
opportunity.listItemHovered = !opportunity.listItemHovered;
}
Though I'd recommend to use :hover pseudo class if requirement is just to highlight the element on hover. That can be easily doable by changing CSS rule. This way could save several change detection cycle to be ran.
.list-item:hover {
background: #7e00cc;
color: white;
}
I would suggest use a directive to listen to the hover event on the target element and attach the class:
#Directive({
selector: '[hoverDir]'
})
export class HoverOverDirective {
#HostListener('mouseenter') onMouseEnter() {
this.elementRef.nativeElement.class = 'list-item-highlight';
}
#HostListener('mouseleave') onMouseLeave() {
this.elementRef.nativeElement.class = 'list-item-not-highlight';
}
}
Or the easiest way is to make use of CSS pseudo property :hover and use it as below:
.list-item:hover {
background: #7e00cc;
color: white;
}

Not able to change tab's height, colour in Angular 6

I'm new Angular, CSS and Html.
I have used MatTabsModule(import { MatTabsModule } from '#angular/material/tabs';) to create tabs but I'm able to adjust/change height, background etc. In short I'm not able to override default properties of MatTabsModule's classes. Please help me.
Below is my CSS and Html code. I hope Typescript code is not needed.
HTML: -
<mat-card>
<mat-card-content>
<mat-tab-group class="tab-group" dynamicHeight>
<mat-tab *ngFor="let obj of tags">
<ng-template mat-tab-label>{{ obj.name }}</ng-template>
<div class="tab-content">
{{ obj.name }}
</div>
</mat-tab>
</mat-tab-group>
</mat-card-content>
CSS: -
.tab-group {
border: 1px solid #e8e8e8;
margin-bottom: 30px;
.unicorn-dark-theme & {
border-color: #464646;
}
}
.tab-content {
padding: 16px;
}
mat-card{
padding: 0px;
}
.mat-tab-label .mat-ripple {
min-width: 0;
height: 30px;
}
I'm not able to change height width background colour of these tabs.. :(
You cannot access the styles of child components from your css-file as the ViewEncapsulation.Emulated prevents styles from leaking to the rest of the app (as it should, don't change it).
If you use the ng-deep-selector like this: :host ::ng-deep mat-tab { ... } you can override default material styles that cannot be configured in any other way. I say that because making css leak from a component is considered a bad practice and if possible you should use #Input to pass on styles.
By the way, the :host is there so the styles leak only to this components children and not to the rest of the app
To override default style of angular material elements you need to prefix ::ng-deep in CSS style.
This is how you can control height and width of tabs
::ng-deep .mat-tab-label{
height: 27px !important;
min-height: 0px!important;
margin: 3px!important;
}