Apply CSS Style inside ng-content - css

in an Angular application I have a component with <ng-content></ng-content>. I added the scss rules for content that will be put inside the ng-content, but they are ignored. I tried to solve using :host, but it doesn't work.
https://stackblitz.com/edit/angular-ewqhzj
Wrapper component:
<app-embed>
<p>Hello world!</p><h1 class="toBeColored">toBeColored</h1>
</app-embed>
Styles in embed component:
:host {
border: 5px solid red;
padding: 15px;
display: block;
.toBeColored {
color: pink;
}
}
The problem is that the pink color of 'toBeColored' string is not set

Try this
:host ::ng-deep{
border: 5px solid red;
padding: 15px;
display: block;
.toBeColored {
color: pink !important;
}
}
and remove encapsulation statement and try ti build
encapsulation: ViewEncapsulation.Native

Try adding encapsulation: ViewEncapsulation.Native to your embed component like
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'app-embed',
templateUrl: './embed.component.html',
styleUrls: ['./embed.component.scss'],
encapsulation: ViewEncapsulation.Native
})
export class EmbedComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}

You can't achieve that with a clean way.
A workaround would be to create global css :
:host {
...;
::ng-deep .toBeColored {
color: pink;
}
}
But it will be deprecated. See this issue
::ng-deep is going to hold the web record for long-lived deprecated API.

You should be able to apply the styles in the parent component that projects the content into the ng-content tag. The angular styles isolation appears to consider the content to be part of the component where the HTML is declared.
https://stackblitz.com/edit/angular-ivy-q9dn68

Related

CSS modules composes rule not working in create-react-app

I have two components, each with a CSS module:
src/_components/ProfileImage.tsx
import styles form './ProfileImage.module.scss';
function ProfileImage () {
return (
<img className={styles.profileImage} />
)
}
export default ProfileImage;
src/_components/ProfileImage.module.scss
.profileImage {
height: 50px;
width: 50px;
}
and
src/ProfilePage/Profile.tsx
import styles form './ProfilePage.module.scss';
function ProfilePage () {
return (
<ProfileImage className={styles.profileImage}
)
}
export default ProfilePage;
src/ProfilePage/Profile.module.scss
.profileImage {
composes: profileImage from '_components/ProfileImage.module.scss';
outline: 1px solid red;
}
This doesn't seem to work, not even when I use relative paths.
SCSS doens't recognise the property composes.
Is there a better way to compose modules than this? I am switching from CSS-in-JS to CSS modules, but I really miss how easy it was to compose components with emotion or styled-components.
in src/ProfilePage/Profile.module.scss
#import '/ProfileImage.module.scss' /* your ProfileImage scss file path */
.profileImage {
#extend .profileImage;
outline: 1px solid red;
}
this will work

How do we use the input:focus selector in angular 2+ component?

I have a form that contains something like the following:
<div class="form-field">
<input-component [tabIndex]="tabData.tabEnable"></input-component>
</div>
<div class="form-field">
<input [tabIndex]="tabData.tabEnable" matInput cgiPrecision type="number"/>
</div>
In the css I have this:
input:focus {
border: $border-width solid $darkblue
}
but the border only shows on the input element and not the input-component component which has an input wrapped inside of it. How can I get the input:focus to work for the custom angular component as well?
Your custom component should listen for the focus event, then focus the input.
#Component({
selector: 'custom-input',
template: `<input #myInput type="text" [(ngModel)]="innerValue">`,
styles: [`
input {border: 5px solid green; }
input:focus { border: 5px solid blue; }
`]
})
export class CustomInputComponent implements ControlValueAccessor {
#ViewChild('myInput', {static: false}) inputCtrl;
//...functions to implement ControlValueAccessor
#HostListener('focus')
focusHandler() {
this.inputCtrl.nativeElement.focus();
}
}
Here's a stackblitz demonstrating.
scss files are limited to their angular component. If you want to use css globally, use the style.scss.
Another option is, integrate the scss into your child component with the style-urls array:
#Component({
selector: 'input-component',
templateUrl: '/input-component.html',
styleUrls: [
'./input-component.scss', // own scss file
'./../path-to-other-compontent.scss' // <--- here
]
})
export class InputComponent {
[...]
}

ng-select Angular2 panel transparent

I have some problem with ng-select css, my dropdown panel color is transparent (normally default color is white) on Chrome and Firefox.
html
<ng-select class="custom"[items]="mesurePoints2"
bindLabel="name"
bindValue="name"
[ngModel]="actualMesurePoint.name"
name="name"
(ngModelChange)="mesurePointSelection($event)"
>
</ng-select>
css
.ng-select.custom {
border:1px solid rgba(0, 0, 0, 0.15);
height: 38px;
border-radius: 0.25rem;
background-color: white;
font-size: 1rem;
padding: 0.5rem 0.75rem;
font-family: sans-serif;
}
.ng-select.custom .ng-option {
background-color: red;
}
component
#Component({
selector: 'app-traffic-data',
templateUrl: './traffic-data.component.html',
styleUrls: ['./traffic-data.component.scss', '../../../app.disabled.scss',
'../../../../../node_modules/#ng-select/ng-select/themes/default.theme.css'],
You need to use encapsulation in order to override children component's css:
#Component({
selector: 'app-traffic-data',
templateUrl: './traffic-data.component.html',
styleUrls: ['./traffic-data.component.scss', '../../../app.disabled.scss',
'../../../../../node_modules/#ng-select/ng-select/themes/default.theme.css'],
encapsulation: ViewEncapsulation.None
})
Example stackbiltz here.
The encapsulation solution did not work for me. But using adding the appendTo="body" attribute to the ng-select worked like magic for me.
You can refer to this issue thread on ng-select library for more details.

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 fix when angular 2 component take full width of the page?

My angular 2 components are taking full width of the page.
When I limit the component width, its margin is stretched to full width.
So I cannot bring other components beside this. How can I limit the width of components?
I tried display: inline, but no use.Still the component takes full width allowing nothing to come beside this.
import { Component } from '#angular/core';
import { Item } from './../item';
import { ItemComponent } from './ItemComponent';
#Component({
selector: 'Item-Set',
directives: [ItemComponent],
template: '<div class="singleItem" *ngFor="let eachItem of itemList"><Item></Item></div>'
})
export class ItemSet{
itemList: Item[];
constructor(){
this.itemList=ItemList;
}
}
In style sheet
.singleItem{
width:300px;
}
You need to add the CSS to set the width at the correct place. In your example would that be the styles parameter of ItemSet or Item like
Plunker example
Either on the ItemComponent with the :host selector (self):
#Component({
selector: 'Item',
template: '<div>Item</div>',
styles: [':host {display: block; border: solid 1px red; width: 300px;}']
})
export class ItemComponent{}
or the parent component with .singleItem as selector
#Component({
selector: 'Item-Set',
directives: [ItemComponent],
styles: [`
.singleItem{width:300px;}
:host {display: block; border: solid 1px green;}`
]
template: '<div class="singleItem" *ngFor="let eachItem of itemList"><Item></Item></div>'
})
export class ItemSet{
itemList = ['a', 'b', 'c', 'd'];
})

Resources