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?
Related
I have a component with a button. It has a default class and a class passed to its from the props. But sometimes the default class overwrites the class from the props. Is it possible to increase the specificity of the class from the props or lower the specificity of the default class?
Do not suggest using !important
Do not suggest to prescribe default styles for the button tag, I do not want to apply them to all buttons in the project
Assigning an id for each button is also not an option
In the props, it is the class name that needs to be passed, not the style
import React from 'react'
import styles from './Button.module.scss'
import classNames from 'classnames'
const Button = ({ children, className, ...props }) => {
return (
<button {...props} className={classNames(styles.btn, className)}>
{children}
</button>
)
}
I can't find a beautiful and convenient solution. Now I'm adding !imortant in a class of props.
I just hope there's some css or js trick I'm not aware of.
Any additional selector will be increase priority of passed classname
component.module.scss:
button.passed-class-name {
color: red;
}
button.module.scss:
.btn {
color: green
}
Component.js
import styles from './component.module.scss'
import { Button } from 'components/Button'
const Component = () => {
<Button className={styles.passedClassName} />
}
The ideal solution could not be found. I decided not to reinvent the wheel and write a UI kit for the project, like everyone else.
UI kit styles are connected earlier, so styles from parents will rewrite them without !important and without increasing specificity.
I want to change CSS of element <div class="myClass1">"I am content"</div> in react. Basically, I just want to add "display: none;" Problem is that that element is created by one library on click so I cant really set style or class to state or variable or something. In jQuery there is a lot of ways but how to do this in react?
Here is my handler
// Handling change
const handleChange = () => {
// Here should be code to change css of myClass1
};
You can use conditional class name for that. In your handleChange set a boolean state and in your className use this state to change className. Then in this new className you can apply display: none .
<div class={`${clicked ? "myClass1" : "myClass2"}`}>"I am content"</div>
In this case clicked would be your state that you can change with handleChange function
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.
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
I have these routes:
.account /:email
.account.home /:email
.account.personal /:email/personal
.account.settings /:email/settings
.account is an abstract state and .account.home is the default state that it would go onto.
Now if I have this link, with an ui-sref-active to add a class when it is navigated, I would do something like
<a ui-sref-active='active' ui-sref='.account.home({email: account.email})'></a>
the right element is set with an active class when it is clicked (which is was expected), but if I then clicked on .account.personal it is removed since it is not a child of .account.home but a child of .account
How can I set the ui-sref-active to remain active to the <a></a> above even I selected a different route under it? But I cannot link it to the abstract state since we cannot navigate to an abstract state?
you have to use ui-sref-active like ng-class
<a
ui-sref-active='{"active": ".account({email: account.email})" }'
ui-sref='.account.home({email: account.email})'
>
the important part is this:
{"active": ".account({email: account.email})" }
which tells ui-router to set the active class when the current state is .account({email: account.email}) so it is now looking at the abstract state .account and not .account.home