Dynamically add colors into component - css

I have 2 components. The first component sets colors that I then use in my second component however I have to set every color individually which I do not want to do. I am trying to possibly add an array that I can add the colors inside instead of adding individual colors.
Here is my code
component 1 html
<div [ngClass]="{'brand-error-image-banner': data?.redImageBanner, 'graphite-grey-image-banner': data?.greyImageBanner, 'graphite-orange-image-banner': data?.orangeDarkImageBanner}</div>
component 1 scss
.brand-error-image-banner {
background-color: $brand-error;
height: 164px;
margin: -24px -24px 24px;
}
.graphite-grey-image-banner {
background-color: $graphite-3;
height: 164px;
margin: -24px -24px 24px;
}
.graphite-orange-image-banner {
background-color: $brand-orange-light;
height: 164px;
margin: -24px -24px 24px;
}
component 1 modal
export class component1{
public redImageBanner: boolean = false;
public greyImageBanner: boolean = false;
public orangeDarkImageBanner: boolean = false;
constructor(args) {
this.redImageBanner = args.redImageBanner;
this.greyImageBanner = args.greyImageBanner;
this.orangeDarkImageBanner = args.orangeDarkImageBanner;
}
}
component 2 html
<component1 [data]="{orangeDarkImageBanner: false, redImageBanner: true, greyImageBanner: false}"></component1>
So basically I do not want to have to add each color individually eg. In the above code I am adding red, grey and orange and if I want to add a new color then I will have to make a new entry. How can I just keep it generic and then add the color like this for example?
<component1 [data]="{color: graphite-orange-image-banner}"></component1>

You can use HostBinding. Example (try me):
Parent:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `<hello [data]="{ color: selectedColor }"></hello>
<label for="colors">I am parent color chooser:</label>
<select name="colors" id="colors" [(ngModel)]="selectedColor">
<option value="red">red</option>
<option value="blue">blue</option>
<option value="green">green</option>
<option value="orange">orange</option>
</select>`,
})
export class AppComponent {
selectedColor = 'red';
}
Child
import { Component, HostBinding, Input } from '#angular/core';
#Component({
selector: 'hello',
template: `<h1>I am the child component!</h1>`,
})
export class HelloComponent {
#HostBinding('style.color') // can also bind class names for example
color: string;
#Input()
set data({ color }) {
this.color = color; // you could map your strings to colors here
}
}

Related

Change styling of nested dom element of a custom react library UI component

I am using react-phone-input-2 library in my code-base. This component is used in conjuction with react-hook-forms and yup for field validation. Using their material.css file for styling and adding some custom CSS I have been able to modify its default look. For custom CSS I am using .css file like so:
phone-input.css
.react-tel-input .special-label {
background-color: transparent !important;
color: #009378 !important;
position: absolute;
top: 6px !important;
font-size: 12px !important;
left: 10px !important;
}
When the field validation fails, I have to toggle color of this ".special-label" classes color. I am not sure how to do that. I could not find an API which they expose for this special-label classes style. Github repo of phone-input.
Here is my phone-input code:
import React from 'react';
import PhoneInput from 'react-phone-input-2';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faPhone } from '#fortawesome/free-solid-svg-icons';
import { Controller } from 'react-hook-form';
import FormIcon from './FormIcon';
import 'react-phone-input-2/lib/material.css';
import './phone-input.css';
export default function FormPhoneInput({ error, validation }) {
return (
<div className={`relative inline-block ${error ? 'pb-4' : ''}`}>
<Controller
name="phone"
render={({ field }) => (
<PhoneInput
country="in"
placeholder="Phone"
name="phone"
countryCodeEditable={false}
defaultErrorMessage={error}
isValid={() => {
return error ? false : true;
}}
inputProps={{
required: true,
}}
inputStyle={{
width: '100%',
color: '#F2FBF7',
...(error
? { background: '#4D3230' }
: { background: '#004246' }),
border: 'none',
outline: 'none',
}}
{...field}
/>
)}
></Controller>
<FormIcon
icon={<FontAwesomeIcon icon={faPhone} />}
error={error}
validated={validation}
/>
</div>
);
}
Rendered DOM look like this: (react-tel-input wraps the whole component and special label is a child div)
Current UI looks like this, when validation is failed:

Change initial color of an Angular 9 mat-input

I have a standard matInput field inside a standard mat-form-field, which is in a standard [formGroup] div. The background of the parent area is dark and the default color of the input is dark. That doesn't work well. Here's a sample of the HTML..
<div [formGroup]="myInfo">
Year:
<mat-form-field>
<input class="myClass" style="color: white" matInput (keypress)="numericOnly($event)" placeholder='YYYY'
formControlName="yearControl">
</mat-form-field>
</div>
Looking online and based on answers here, I see how to change things in the .scss like:
.childClass {
input { color: #fff !important; }
label.mat-input-placeholder { color: #fff !important; }
::ng-deep .mat-form-field-label { color: #fff !important; }
::ng-deep .mat-form-field-ripple { color: #fff !important; }
::ng-deep .mat-form-field-underline { color: #fff !important; }
}
This finally changed the placeholder text and entered text to be white, but the underline is still black. Thanks for your ongoing suggestions.
It's doesn't work becouse yours selector
::ng-deep .mat-focused .mat-form-field-label
contains
.mat-focused
And it works only when you focused on field
Just change the selector
::ng-deep .mat-form-field-label and placeholder color
label.mat-input-placeholder
i changed input color to a brighter color with a dark background like this:
i build my own input component switched-input.component
html:
// switched-input.component.html
<mat-form-field>
<input matInput placeholder="{{placeholder}}" [formControl]="inputControl"/>
</mat-form-field>
scss:
// switched-input.component.scss
mat-form-field {
width: 100%;
}
// color of the text typed by the user when input is selected
input {
color: #fff !important;
}
ts:
// switched-input.component.ts
import { FormHelper } from './../../../helper/form.helper';
import { Component, OnInit, Input, ViewEncapsulation } from '#angular/core';
import { FormControl } from '#angular/forms';
import { TranslateService } from '#ngx-translate/core';
#Component({
selector: 'switched-input',
templateUrl: './switched-input.component.html',
styleUrls: ['./switched-input.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class SwitchedInputComponent implements OnInit {
inputControl: FormControl;
#Input() placeholder: string;
#Input() set control(controlObj: FormControl) {
this.inputControl = controlObj;
if (this.placeholder && this.placeholder !== '') {
this.placeholder = this.translateService.instant(this.placeholder);
}
}
get control(): FormControl {
return this.inputControl;
}
constructor(private translateService: TranslateService) {}
ngOnInit() {
}
}
additionally to change the underline color aswell as the label color of the input fields i had to use the following styles in my apps main styles.scss file
// styles.scss
// underline color of mat input fields
.mat-form-field-underline {
background-color: #fff !important;
}
// label color of mat input fields
.mat-form-field-appearance-legacy .mat-form-field-label {
color: #fff;
}

Align text to center inside Snackbar (Angular Material)

Hey how can I align text inside SnackBar to be center?
this is my code and it doesn't work:
import { Injectable } from '#angular/core';
import { MatSnackBar, MatSnackBarConfig } from '#angular/material';
#Injectable({
providedIn: 'root'
})
export class MaterialService {
constructor(public snackBar: MatSnackBar) { }
openSnackBar(message:string){
let config = new MatSnackBarConfig();
config.panelClass = 'text-align:center';
this.snackBar.open(message);
}
}
thanks you :)
Simply add this in your style.css (or any global css, in my case I put it in my app.component.scss)
margin:auto; will center the span tag inside the snackBar
text-align:center; will center the text inside the span
simple-snack-bar span {
margin:auto;
text-align: center;
}
Settings like this will apply to all your SnackBars.
For angular 7 w/material, I use this in global style.css:
.mat-simple-snackbar span {
margin: auto;
text-align: center;
}
The panelClass property of MatSnackBarConfig accepts a CSS class which you can define in your main app's styles.css:
openSnackBar(message: string) {
let config = new MatSnackBarConfig();
config.panelClass = 'center-snackbar';
this.snackBar.open(message);
}
Just make sure you use the !important selector as well!
.center-snackbar {
text-align: center !important;
}
For on demand centred text.
SASS:
snack-bar-container.text-center {
span {
margin-left: auto;
margin-right: auto;
text-align: center;
}
}
Then you add "text-center" to your panelClass
let config = new MatSnackBarConfig();
config.panelClass = "text-center";
this.snackBar.open(message);
That way you can have standard appearance if the Snackbar comes with an action.
Try this
import { Injectable } from '#angular/core';
import { MatSnackBar, MatSnackBarConfig } from '#angular/material';
#Injectable({
providedIn: 'root'
})
export class MaterialService {
horizontalPosition: MatSnackBarHorizontalPosition = 'center';
verticalPosition: MatSnackBarVerticalPosition = 'top';
constructor(public snackBar: MatSnackBar) { }
openSnackBar(message:string){
let config = new MatSnackBarConfig();
config.verticalPosition = this.verticalPosition;
config.horizontalPosition = this.horizontalPosition;
this.snackBar.open(message);
}
Ref:https://material.angular.io/components/snack-bar/api
Example:https://stackblitz.com/edit/angular-snackbar
Although this question is quite old, I thought posting my solution might be helpful to someone out there.
After lots of research and some trial and error, the below code is all I needed to get my snackbar working with centered text. (hint: I'm using the most stable Angular version as at today).
// extract from my-notification-service.ts file
// Note that I created the above service file, imported "MatSnackBar"
// & "MatSnackBarConfig" from #angular/material/snack-bar,
// and added a property of type "MatSnackBar" into the constructor.
// After that, I created the below object and function.
// The function will be called by any submit button in the project.
mySnackBarConfig: MatSnackBarConfig = {
duration: 3000,
horizontalPosition: 'center',
verticalPosition: 'bottom'
}
displayMessage(msg: string) {
this.mySnackBarConfig['panelClass'] = ['notification','success'];
this.snackBar.open(msg, '', this.mySnackBarConfig);
}
The following code was added to the global styles.css file
// extract from styles.css (global)
snack-bar-container.success {
background-color: rgb(31, 121, 39);
color: rgb(255, 255, 255);
}
snack-bar-container.notification simple-snack-bar {
font-size: 18px !important;
}
// this part is all I did to center the text.
// Take note of the css declaration, not just the style inside.
simple-snack-bar > span {
margin: 0 auto;
text-align:center !important;
}

How to css style angular2's Ng2-completer plugin input box and dropdown color?

I am using angular2/4's Ng2-Completer plugin and am having trouble with styling of the component. I want to change the background dropdown to "red" and the input box to be blue.
The following is my plunkr:
https://plnkr.co/edit/sVnfpBiEb5jBdtul4ls9?p=preview
I tried to include the following CSS, but it does not appear to impact anything:
.completer-row {
display: inherit;
background:blue;
}
.completer-selected-row {
background-color: lightblue;
color: yellow;
}
.completer-row p {
position: relative;
top: 50%;
transform: translateY(50%);
}
.completer-dropdown-holder {
position: absolute;
background: red;
}
.customid {
background:blue;
}
My component:
import { Component } from '#angular/core';
import { CompleterService, CompleterData } from 'ng2-completer';
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';
#Component({
selector: 'my-app',
styleUrls: [
'./app.component.css'
],
template: `<h1>Search color</h1>
<ng2-completer id="customid" [(ngModel)]="searchStr" [datasource]="searchData" [minSearchLength]="0" [clearSelected]="true" (selected)="onSelected($event)"></ng2-completer>
<p>Selected: {{selectedColor}}</p>
`
})
export class AppComponent {
protected searchStr: string;
protected dataService: CompleterData;
protected selectedColor: string;
protected searchData = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black'];
protected onSelected(item: CompleterItem) {
this.selectedColor = item? item.title: "";
}
}
You can use inputClass propery of ng2-completer.
For example with bootstrap:
<ng2-completer [inputClass]="'form-control form-control-inline'" ...></ng2-completer>
You can style the angular ng2 completer like this:
::ng-deep .completer-row{
}
Angular 2 have a safety feature where CSS only work on HTML files of their respected component. Or css have to go in the global styles.css file for global use. However you can force CSS to apply by adding hots: >>> .class-name this method will force the css to apply to a child component.
More info on this thread Angular 2: How to style host element of the component?
https://alligator.io/angular/styles-between-components-angular/

How to dynamically change CSS in :host in angular 2?

How do I dynamically change CSS properties of a component host?
I have a component and in it's CSS I have given it a stlye:
:host {
overflow-x: hidden
}
On a button click from child component, I need to add overflow-y: hidden to the host component.
How do I achieve this behavior?
Here is a working example.
Use the following HostBinding:
#HostBinding('style.overflow-y') overflowY = 'scroll';
This would give the following component:
#Component({
selector: 'my-app',
template: `
<div>
<button (click)="addStyle()">Add Style</button>
<h2>Hello</h2>
</div>`, styles: [
`
:host {
overflow-x: hidden;
height: 50px;
width: 200px;
display: block;
}
`,
],
})
export class App {
name: string;
#HostBinding('style.overflow-y')
overflowY = 'scroll';
constructor() {
}
addStyle() {
this.overflowY = 'hidden';
}
}

Resources