There are 4 steps there:
1.) Click on category
2.) Show filtered products
3.) Select filtered products
4.) Display selected products in most right part of screen /3rd child component/
What I would like to achieve is next:
When I click on product (3rd step), product is added to 'right' component, and there I would like to change a font size of quantity so it might look like animation, like make font bigger for example 28 and make it small again for example 18.
Products are added to the 3rd component by using service which is shared between child components. This is how it looks :
Thanks guys
Cheers
First of all, add a new rule to the order-quantity-number class:
transition: font-size 1s;
then define another selector in css:
.order-quantity-number.selected {
font-size: 48px;
}
then basically you just need to add this 'selected' class to the span element and the font-size will be animated. After 1s (anim is completed), you need to remove the class from the element and the text will shrink. I hope it answers the question :)
EDIT: Implementation details
Template:
Add reference to the span element so that it is accessible from code
<span class="order-quantity-number" #ref>{{receiptItem.quantity}}</span>
ts:
Add the following line to the class to use 'ref' from the template.
#ViewChild('ref') elRef: ElementRef;
Add setTimeout() call to the click handler that triggers the animation to remove selected class after 1s:
onClick() {
...
// 1. add 'selected' class to the span element
this.elRef.nativeElement.classList.add('selected');
// 2. remove it after 1s
setTimeout(() => {
this.elRef.nativeElement.classList.remove('selected');
}, 1000);
}
You can write simple #Directive that implements AfterViewInit interface in which you will add a class with bigger font-size and then watch for event transitionend and remove class.
something like this
#Directive({
selector: `[fontAnimation]`
})
export class FontAnimationDirective implements AfterViewInit {
constructor(
private hostElement: ElementRef
) { }
ngAfterViewInit() {
const el = this.hostElement.nativeElement as HTMLElement;
el.classList.add('animate-font-size');
el.addEventListener('animationend', (ev: TransitionEvent) => {
if (ev.propertyName == 'font-size') {
el.classList.remove('animation-font-size');
}
})
}
}
Warning: transitionend will trigger event for every property that has transition, so we need to check if propertyName is equal to font-size.
All you need to do is create proper css class. Don't forget to import it to proper NgModule
Related
I wanted to add an "i" element as a child element to HTMLDivElement
but styles are not applied to the newly inserted "i" element.
How can I make sure to apply the same styles to newly added "i" element?
I want to apply the the styles that I have set in the scss file for the new element.
(when I am inserting the new element in the .ts file, I can set the same styles using JS(TS), but I intend to use the scss/css styles, is there any way to use the scss/css styles for the newly added elements?)
accommodation-view-data.html
<div class="star-rating" #starRating>
<i class="bi bi-star-fill"></i> <!-- styles are applied to this element successfully -->
</div>
accommodation-view-data.component.scss
i{
font-size: 1.6rem;
padding: 0 0.25rem ;
color: #ffbe0f;
}
accommodation-view-data.component.ts
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '#angular/core';
#Component({
selector: 'app-accommodation-view-data',
templateUrl: './accommodation-view-data.component.html',
styleUrls: ['./accommodation-view-data.component.scss']
})
export class AccommodationViewDataComponent implements OnInit, AfterViewInit {
#ViewChild('starRating')
starRatingElem!: ElementRef;
constructor() { }
ngOnInit(): void {
}
ngAfterViewInit(): void {
/* When I append the the new element to the DOM,
* the styles that I have set in the scss file, are not applied for the new element */
const starIconElement = document.createElement('i');
starIconElement.classList.add('bi');
starIconElement.classList.add('bi-star-fill');
(this.starRatingElem.nativeElement as HTMLDivElement).append(starIconElement);
}
}
This is a normal behavior, When you write style that is integrated in the styleUrls, every single class is reworked to be specific to the component, it's the style scope (note the i[ng-content-lep-c52]in the screenshot below).
So adding an element in the dom like you do is not recommended, instead prefer toggling it thanks to a ngIf or here for stars with a ngFor or else you'll have hard times trying to make it dynamic and bind values with the component model.
Like you can see in this screenshot, the first element is properly matched with the scoped style while the new element isn't.
NOT RECOMMENDED AND DEPRECATED: To bypass this you can use the ::ng-deep pseudo class to make a style global, and therefor getting overrided by scoped style as you can see in this screenshot comming from this stackblitz.
You can find more information about styles in angular here
Ok, so, i have a component that takes a className as a prop, but the component itself comes with an default style.
className={`${
props.classNameStyle ? `${styles.defaultButtonStyle} ${props.classNameStyle}` : styles.defaultButtonStyle
}
If className prop exists, it should put as classes both the default class and the class passed as prop, and otherwise, to put just the default class. It works, but, i want the class passed as prop to have a bigger CSS specifity than the default button, because, let's say that we have :
.defaultButtonStyle { background-color:red }
and
.classNameStyle { background-color:blue } (this is the class from props)
it should make the background color blue, but in the browser's console, the classNameStyle it's cut, and the background-color is set to the default button style. I don't want to use !important, because that's gonna be annoying for the user. Any ideas?
I need to add class to an element on an individual element scroll. I created a slackblitz example. I know how to add a class on whole body scroll. But, I need to add on particular element scroll.
In this example I need to add class on scrolling the div#paragraph.
Thanks in advance.
https://stackblitz.com/edit/angular-changeclassonelementscroll
You can create a directive that listens to its host scroll event. Something like would work:
#Directive({
selector: '[appScroll]'
})
export class ScrollDirective {
#Input() scrollClass: string;
constructor(private el: ElementRef, private renderer: Renderer2) { }
#HostListener("scroll", [])
onScroll() {
if (this.el.nativeElement.scrollTop > 20) {
this.renderer.addClass(this.el.nativeElement, this.scrollClass)
}
}
}
I forked your code example here
PS: try to avoid accessing the DOM directly using document.getElementById. Always use Angular utilities for that.
You could try adding an event to the paragraph element in your template:
<div id="paragraph" (scroll)="onDivScroll()">
and then add a function in your component that gets called
onDivScroll(){
this.document.getElementById('paragraph').classList.add('green');
}
you'll have to add your additional logic as needed, but you should be able to turn the individual element text green this way.
In my Angular app, I have a component that triggers an event when I click on it. I can get the elementRef from this event, but I want to test whether that element has a certain class applied to it. So my code looks like this:
<component1 [class.class1]="this.condition">
and
#HostListener('document:mousedown', ['$event'])
onMouseDown(event: MouseEvent): void {
let elementRef = this.elementRef;
// I want to know if 'elementRef' has class 'class1' applied to it.
}
I want to do something like elementRef.class1. Does anyone know how to approach this?
You need to get nativeElement (via elementRef’s nativeElement property) and then use standard classlist.contains approach:
elementRef.nativeElement.classList.contains(class);
Not entirely sure of your use case, but if you want to "control" which class is enabled for your component you can leverage ngClass and bind each class to a condition in your ts:
<component1 [ngClass]="{ 'class1': isCondition1, 'class2': isCondition2 }"></component1>
So if your isCondition1 property results in 'true' then component1 will have class1 added to it etc
I am trying to apply styling to a child of a custom component.
Selector:
<custom-component-example></custom-component-example>
Inside custom-component-example.html:
<button>
<ng-content></ng-content>
</button>
If I were to use style like this:
<custom-component-example style="color: green">some text</custom-component-example>
Or like this:
<custom-component-example [ngStyle]="{'color': green}">some text</custom-component-example>
The button text will not get green. The styling could be anything (for example font-weight or size or anything really).
I have also tried the solution to this topic:
Best way to pass styling to a component
But that also does not apply to the child element (button in the example above).
How do I pass any given styling and apply it to the child element, in the case of the example, how would I pass styling (through the custom-component-example selector) and apply it to the button and the button's text?
Thanks in advance.
You should never alter the child style from the parent, instead here is what you should do :
Apply a class to the parent (let's say green-button).
In the child's css you need to check that does my parent has a class green-button, if yes then it should change it's color.
In the child's css file ->
:host-context(.green-button) button{
color : green
}
You should not transfer styles from parent to child essentialy because it spoils the ViewEncapsulation goodness that Angular is proud of.
Here is some refrence . : Link
Also, the child component should be responsible for how does it button looks. The parent should be concerned about itself. In the future, if you will have two children to your parent, it will be difficult to manage what style to pass to what child.
Using this method, altering style is not only easy but also manageable.
Upvote and mark as solved if I was able to help.Cheers.
You need to pass the style property to the child component using the #Input() like
Your child component HTML code should look like
<div [className]="tableCss">
</div>
Your child component ts file code shoule look like
#Input() tableCss: string;
Your Parent component should look like
<app-list [tableCss]="'table-responsive table-borderless table-grid mt-4 border-top border-primary'"></app-list>
Try to change styles into [styles]
custom-component-example.html
<button [ngStyle]="styles">
<ng-content></ng-content>
</button>
custom-component-example.ts
#Input() styles: any = {};
Use,
<custom-component-example [styles]="{color: green}">some text</custom-component-example>
If you would like to use input and styles without deep selectecting of css like that:
a > b > c {
color: green;
}
Change this class to this:
class CustomComponentExample {
#Input() styles;
}
Set styles for this input:
<custom-component-example [styles]="{'color': green}">some text</custom-component-example>
Use this property in your component:
<button [ngStyle]="styles">
<ng-content></ng-content>
</button>
Try this:
Add a class on that component into your template file like this example bellow. (class='toggle-button').
<custom-component-example class="toggle-button"> Button name </custom-component-example>
Use ::ng-deep to your scss file for styling this class and add !important to that parameter.
::ng-deep .toggle-button { .switch-btn {
width: 80px !important;
height: 40px !important;}}
*"switch-btn" class is a class into the parent component.