I have an angular expansion panel as shown below.
But I want to change the the design of the arrow to something like this:
Not expanded:
Expanded:
How? or is it possible for me to do so in angular material?
Code below:
HTML:
<md-expansion-panel>
<md-expansion-panel-header>
<md-panel-title>
Personal data
</md-panel-title>
<md-panel-description>
Type your name and age
</md-panel-description>
</md-expansion-panel-header>
<md-form-field>
<input mdInput placeholder="First name">
</md-form-field>
<md-form-field>
<input mdInput placeholder="Age">
</md-form-field>
</md-expansion-panel>
TS:
import {Component} from '#angular/core';
/**
* #title Basic expansion panel
*/
#Component({
selector: 'expansion-overview-example',
templateUrl: 'expansion-overview-example.html',
})
export class ExpansionOverviewExample {}
Yes it is possible. Give your expansion panel a reference id e.g. example and set the hideToggle property as true.
In the <md-panel-description>, you can place your icons and use the expanded property of the panel to show or hide the relevant icons.
<md-expansion-panel class="custom-header" hideToggle="true" #example>
<md-expansion-panel-header>
<md-panel-title>
Personal data
</md-panel-title>
<md-panel-description>
Type your name and age
<md-icon *ngIf="!example.expanded">play_arrow</md-icon>
<md-icon *ngIf="example.expanded">arrow_drop_down</md-icon>
</md-panel-description>
</md-expansion-panel-header>
<md-form-field>
<input mdInput placeholder="First name">
</md-form-field>
<md-form-field>
<input mdInput placeholder="Age">
</md-form-field>
</md-expansion-panel>
To provide space between the icon and panel description, add the following classes in your component.css:
.custom-header .mat-expansion-panel-header-title,
.custom-header .mat-expansion-panel-header-description {
flex-basis: 0;
}
.custom-header .mat-expansion-panel-header-description {
justify-content: space-between;
align-items: center;
}
I have used material icons. You can place your custom icons if you want. Here is a link to stackblitz demo.
extended the answer from #Faisal and as per the latest version of angular material, we will use mat prefix instead of md for the Material components.
Angular Material 8.1.4
<mat-expansion-panel class="mb-15px" hideToggle="true" #xyz>
<mat-expansion-panel-header>
<mat-panel-title class="font-weight-bold font-small">
Info
</mat-panel-title>
<mat-panel-description>
<mat-icon *ngIf="!xyz.expanded">play_arrow</mat-icon>
<mat-icon *ngIf="xyz.expanded">arrow_drop_down</mat-icon>
</mat-panel-description>
</mat-expansion-panel-header>
<mat-expansion-panel class="mb-15px" hideToggle="true" #xyz>
Stackblitz Demo
Another pretty solution .. just add a span with fxFlex
<mat-panel-description>
<span fxFlex></span>
<img src="">
</mat-panel-description>
Don't forget to add hideToggle to the mat-expansion-panel
<mat-expansion-panel hideToggle>
Related
I use a CSS framework (Bulma). However, I would like to design my input field a little differently. For example, it should have a red border.
I use scss. However, it does not work. When I import my class, the border is not displayed in red.
How can I adapt my input field in addition to the CSS framework, e.g. so that I have a red border?
import React from 'react'
import './style/General.scss'
function General() {
return (
<div>
<div className="field">
<p className="control has-icons-left has-icons-right">
<input className="input section-changing-input" type="text" value="Hello" />
<span className="icon is-small is-left">
<i className="fas fa-futbol"></i>
</span>
</p>
</div>
</div>
</div>
)
}
export default General
General.scss
section-changing-input {
input {
border-color: crimson !important;
}
}
Make sure you have imported the Bulma CSS library before your custom CSS. Otherwise, the custom CSS changes you make will not be applied.
Bulma's input borders are set with the $input-border-color variable. If you're compiling Bulma in with your own scss files, then simply declare that as red before importing Bulma.
I have below code
<span className="item-toggle" onClick={toggleChecked}>
<Checkbox toggle checked={checked} data-togglecolor={toggleColor}/>
</span>
That renders to
<span class="item-toggle">
<div class="ui checked fitted toggle checkbox" data-togglecolor="#9cd3dd">
<input class="hidden" readonly="" tabindex="0" type="checkbox" value="" checked="">
<label></label>
</div>
</span>
The Checkbox component is part of the Semantic UI React. I would like to use the value of the data-togglecolor to style my input :
.ui.toggle.checkbox input:checked ~ label:before {
background-color: XXX;
}
I could ofcourse hardcode it like below in my CSS
.ui.toggle.checkbox[data-togglecolor="#9cd3dd"] input:checked ~ label:before {
background-color: #9cd3dd;
}
But I was wondering how I could achieve this dynamically.
Thanks !
Do you use styled-components ?
If so, you could override the Checkbox component to pass the background-colour to its child, just like this :
const Checkbox = styled(ImportedCheckbox)`
input {
background-color: ${p => p['data-togglecolor']};
}
`
You can't access props in your CSS files unless you used something like styled-components or something related, what you can do is add a style attribute to your checkbox
<div class="ui checked fitted toggle checkbox" style={{backgroundColor: this.props.yourcolorprophere}}></div>
select in an mat-expansion-panel. I am trying to get both of my ng-selects side by side, but even when I change the width. I can't seem to get them side by side. I went to some of documention and in one of the demos. They seem to use two ng-selects side by side. However, I think they are using boostrap to get that done. Does ngselect use boostrap as default or how can I get this down in material?
This is an example of what I am trying to achieve.
https://ng-select.github.io/ng-select#/forms
I tried changing the width this way:
.ng-select.AdditionalRecipientFormcustom ::ng-deep .ng-select-container {
width:30%;
}
<mat-expansion-panel [(expanded)]="xpandStatus" #formDirectiveTwo="ngForm" [formGroup]="AdditionalRecipientForm">
<mat-expansion-panel-header [collapsedHeight]="customCollapsedHeight" [expandedHeight]="customExpandedHeight" >
<mat-panel-title>
Add Recipients To The Report
</mat-panel-title>
</mat-expansion-panel-header>
<button mat-raised-button (click)="externalLogin()" color="primary" >Create Recipient</button>
<br>
<ng-select class="AdditionalRecipientFormcustom"
[items]="recipients"
[hideSelected]="true"
#select
loadingText="Loading..."
[selectOnTab] = "true"
dropdownPosition="auto"
bindLabel="Email"
placeholder="Select Recipient"
formControlName="UserRecipientsDto">
<ng-template ng-option-tmp let-item="item" let-search="searchTerm">
<div><span [ngOptionHighlight]="search">Email: {{item.Email}} </span><span>, </span><span [ngOptionHighlight]="search">Name: {{item.FirstAndLast }}</span></div>
</ng-template>
</ng-select>
<mat-form-field class="add-addtional-recipients-form-field">
<mat-label>Contact Name</mat-label>
<input matInput placeholder="User Email Address" formControlName="FirstAndLast">
</mat-form-field>
<ng-select class="AdditionalRecipientFormcustom"
[items]="recipientTypes"
[hideSelected]="true"
#select
loadingText="Loading..."
[selectOnTab] = "true"
dropdownPosition="auto"
bindLabel="typerecipient"
placeholder="Select Type Of Recipient"
formControlName="TaskRecipientTypeDto">
<ng-template ng-option-tmp let-item="item" let-search="searchTerm">
<div><span [ngOptionHighlight]="search">{{item.typerecipient}}</span></div>
</ng-template>
</ng-select>
<br>
<button mat-raised-button class="btnUpdate" (click)="resetFieldsForAdditionalForm()" [disabled]="!AdditionalRecipientForm.valid" color="primary"><b>Reset</b></button>
<button mat-raised-button class="btnReset" (click)="createNewRecipientUser(); this.getLogins(); " color="primary"><b>Update</b></button>
<br>
</mat-expansion-panel>
The problem is not specific to ng-select or material. I think you are not fully understanding the display property in css. The ng-select components end up on different lines because of the default display: block; styling. You can either give the ng-selects and the mat-form-field display: inline-block; or solve it with flexbox:
// apply this class to the parent element of the form controls (ng-select, ...)
.example-wrapper {
display: flex;
flex-direction: row;
justify-content: space-between;
}
// give ng-select a fixed width, because it isn't limited by the viewport width now
ng-select {
width: 200px;
}
For more detailed information on flexbox, see this link. Also, see a stackblitz example of what I've explained so far.
I'm unable to set the icon colors
I have a mat-horizontal-stepper with five mat-steps (e.g. named Part A, Part B ... Part E). Each part (mat-step) may have different colors depending some business rules.
I know how to change the "selected" mat-step or how to change the color for ALL the mat-steps (with the same color) but can't figure out how to change it dynamically so each Part may have different icon background colors.
Using Angular v7
The following is a style to set the third mat-step icon green. Id does work but I don't how to change the color dynamically at run-time from the component (typescript).
::ng-deep .mat-step-header:nth-of-type(3) .mat-step-icon {
background-color: green!important;
}
Also I tried using [ngClass] but it is ignored when used as a mat-step attribute. It only works if I enclose the step label within and use it there but that is not the requirement (I need to change the background color of the icon... not the labels).
Expected result:
Able to set each each step with different columns depending the level of completion for each step. (mat-steps could be a combination of yellow, red, green and black),
Actual result:
Unable to change icon colors based on component variable settings
The question is really about controlling CSS variables via TS - i got help from this post here;
CSS: we assign the 3 variables to the 3 icons which we needed to color
HTML: We created 2 divs firstClass & secondClass in addition to the <body>, to which we can assign the uniquely named variables color1, color2 and color3;
Since we are using 'mat-table' we can't use [ngStyle] or [ngClass] because the material elements are created at run time and we can only operate on any of them AfterViewInit event, so it is here that we assign values to our 2 divs & <body> tag;
relevant CSS:
::ng-deep .mat-step-header:nth-of-type(1) .mat-step-icon {
background-color: var(--my-var1);
}
::ng-deep .mat-step-header:nth-of-type(2) .mat-step-icon {
background-color: var(--my-var2);
}
::ng-deep .mat-step-header:nth-of-type(3) .mat-step-icon {
background-color: var(--my-var3);
}
relevant HTML:
<div class='firstClass'>
<div class=' secondClass'>
<mat-horizontal-stepper labelPosition="bottom" #stepper>
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Fill out your name</ng-template>
<mat-form-field>
<input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step [stepControl]="secondFormGroup" optional>
<form [formGroup]="secondFormGroup">
<ng-template matStepLabel>Fill out your address</ng-template>
<mat-form-field>
<input matInput placeholder="Address" formControlName="secondCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Done</ng-template>
You are now done.
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button (click)="stepper.reset()">Reset</button>
</div>
</mat-step>
</mat-horizontal-stepper>
<div>
<div>
relevant TS:
import {Component, OnInit,AfterViewInit } from '#angular/core';
import {FormBuilder, FormGroup, Validators} from '#angular/forms';
#Component({
selector: 'stepper-label-position-bottom-example',
templateUrl: 'stepper-label-position-bottom-example.html',
styleUrls: ['stepper-label-position-bottom-example.css'],
})
export class StepperLabelPositionBottomExample implements OnInit, AfterViewInit {
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
color1:string = 'green';
color2:string = 'yellow';
color3:string = 'red';
constructor(private _formBuilder: FormBuilder) {}
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
firstCtrl: ['', Validators.required]
});
this.secondFormGroup = this._formBuilder.group({
secondCtrl: ['', Validators.required]
});
}
ngAfterViewInit(){
document.querySelector("body").style.cssText = "--my-var1: "+this.color1;
(<HTMLElement>document.querySelector('.secondClass')).style.cssText = "--my-var2: "+this.color2;
(<HTMLElement>document.querySelector('.firstClass')).style.cssText = "--my-var3: "+this.color3;
}
}
complete working stacblitz here
Hello,
I use Angular 5 and material for my project, i'm trying to change the width of the autocomplete panel, with the exemple, i can now display the options corretly, but i cannot see all the informations for the options, then i modified the css file of the new component, but it doesn't work for the material component, can someone tell me how to do it, please?
This is the html of the component:
<mat-expansion-panel [expanded]="panelOpenState === true">
<mat-expansion-panel-header>
<mat-panel-title>
Critère de recherche
</mat-panel-title>
<mat-panel-description>
Saisir un numéro de procédure
</mat-panel-description>
</mat-expansion-panel-header>
<mat-form-field>
<input id="autocomplete" type="text" matInput placeholder="number" [ngControl]="inputControl"
[(ngModel)]="searchValue" [matAutocomplete]="auto" (keyup)="onChange()">
<mat-autocomplete #auto="matAutocomplete" class="class1">
<mat-option *ngFor="let procedure of filteredProcedures | async" [value]="procedure.procedureId">
<span>{{procedure.procedureId}} | </span>
<small>{{procedure.firstName}} </small>
<small>{{procedure.lastName}}</small>
<small>{{procedure.userId}}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>
<button class="pull-right btn btn-info" (click)="search()">
<span matTooltip="Chercher une procédure">
<i class="fa fa-search"></i> Chercher </span>
</button>
</mat-expansion-panel>
And the css file:
.mat-button {
color: white
}
#autocomplete {
width: 400px, !important;
}
.class1 {
width: 400px, !important;
}
.cdk-overlay-pane {
width: 400px;
}
I have tried also to use :host, but it doesn't work.
:host ::ng-deep mat-autocomplete-panel(class1) {
width : 400px;
}
Can you tell me where is the error, please?
I want to display all/more informations of the options.
In fact, with the css file, the button style is applied correctly. but it doesn't work for the autocomplete panel, why?
Thank you.
Remove the commas from your css (then the width works) and you can't use :host as a pseudo since it's not a pseudo element. Pseudos list here: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
#autocomplete {
width: 400px !important;
}
.class1 {
width: 400px !important;
}