Using style from a NextJS module CSS stylesheet - css

I have a stylesheet for a button which is located at styles/Button.module.css and i am trying to use it in my NextJS project but can't seem to get it going.
In my component, i have imported the stylesheet normally, i.e;
import Button from '../styles/Button.module.css';
Then i am trying to add it to the return in a component, like so;
<button onClick={e => login(e)} className={"text-white bg-indigo-600 " + (loading ? "Button.btn-loading" : "")}>
Login
</button>
But the styles don't seem to be pulling through.
Any help would be greatly appreciated

"Button.btn-loading" is invalid. Button is an imported JS object, hence you need to remove the quotes to evaluate the JS object notation.
<button onClick={e => login(e)} className={"text-white bg-indigo-600 " + (loading ? Button['btn-loading'] : "")}>
Login
</button>
That's why CSS Modules recommends using camelCase class names, so that we can use dot notation instead of bracket notation to get the values.
I'd suggest using template literals for more cleaner syntax
<button onClick={e => login(e)} className={`text-white bg-indigo-600 ${loading ? Button['btn-loading']: ""}`}>
Login
</button>

Related

How can I remove a CSS class based on condition

Hi I am writing a react code for a button. Here is the code:
<Button
block={true}
className={`sc-pc-action-button ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>
There is a condition in which I dont need this sc-pc-action-button css.
Now this class sc-pc-action-button is hardcoded.
How can I write a CSS which tells me to ignore the contents of sc-pc-action-button and take fresh CSS I am giving.
I need a CSS solution to remove the properties. I don't need JS Solution
<Button
block={true}
className={`${someCondition ? "sc-pc-action-button" : ""} ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>

Link react-router-dom causes CSS to be lost

I have a react component looks like this:
<MenuSection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
<MenuContainer>
<MenuRow>
{categoryItems.map(categoryItem => (
<MenuItemCard key={categoryItem.Id}>
<Link to={categoryItem.CategoryUrl}>
<MenuItemCardImg src={categoryItem.ImageUrl} />
<MenuItemCardBody>
<MenuItemTitle>{categoryItem.CategoryName}</MenuItemTitle>
</MenuItemCardBody>
</Link>
</MenuItemCard >
))}
</MenuRow>
</MenuContainer>
</MenuSection>
When I click the Link, the route is correct and it takes me to the correct page. However all the CSS in that following page is not applied. If I reload the page that 'Link' took me to the CSS is applied correctly.
When I change the 'Link' and replace it with an < a > tag, when I click the link everything works the next page has the css applied correctly with out any problems.
<MenuSection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
<MenuContainer>
<MenuRow>
{categoryItems.map(categoryItem => (
<MenuItemCard key={categoryItem.Id}>
<a href={categoryItem.CategoryUrl}>
<MenuItemCardImg src={categoryItem.ImageUrl} />
<MenuItemCardBody>
<MenuItemTitle>{categoryItem.CategoryName}</MenuItemTitle>
</MenuItemCardBody>
</a>
</MenuItemCard >
))}
</MenuRow>
</MenuContainer>
</MenuSection>
I can't figure out why this is happening, this is the first React project I have done, so maybe I am missing something really obvious?
UPDATE:
When I use import {Nav} from "react-bootstrap"; (Nav.Link) - from react bootstrap, when I click the link the page navigates correctly and the CSS is applied correctly.
<MenuSection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
<MenuContainer>
<MenuRow>
{categoryItems.map(categoryItem => (
<MenuItemCard key={categoryItem.Id}>
<Nav.Link href={categoryItem.CategoryUrl}>
<MenuItemCardImg src={categoryItem.ImageUrl} />
<MenuItemCardBody>
<MenuItemTitle>{categoryItem.CategoryName}</MenuItemTitle>
</MenuItemCardBody>
</Nav.Link>
</MenuItemCard >
))}
</MenuRow>
</MenuContainer>
So it just seems when I use Link from react-router-dom I get this strange behaviour.
For now I have found a solution by using Nav.Link, but I would really like to know why when I use Link the navigation works but the CSS is not applied untill I reload the page.

How to put Bulma Buttons CSS for the React Components?

The following component is part of To Do List Application. I would like to create four Filter Buttons (All, Active, Completed, Important). May I please ask how to place Bulma CSS Rules for this react component?
Screenshot 1 -
Filter Buttons Component
import React from "react";
function FilterButton(props){
return (
<button
type="button"
className="buttons"
onClick={()=>props.setFilter(props.name)}
>
<span className="visually-hidden">Show</span>
<span>{props.name}</span>
<span className="visually-hidden">tasks</span>
</button>
);
}
export default FilterButton;
You can use button component like this.
<button
className={`button is-${props.name}`}
onClick={()=>props.setFilter(props.name)}
>

Dynamically and conditionaly changing css of a button in reactJs

In a react application how to dynamically change css of a button when a form input validation fails(There are lot of input fields which accept marks)
You can do it like this
<button style={{backgroundColor: this.state.error ? 'red' : 'green'}}>Save</button>
or change the class based on the error state and style in the css file like this
<button className={this.state.error && 'error'}>Save</button>
Hope this helps
PS this.state.error assumes you are using a class component
Also you can give className conditionally. If you don't want to set anything when condition is false, then just leave as empty string ''
<button className={ this.state.something ? 'first-class' : 'second-class' }>Clicker</button>
If you want to add a className attribute conditionally, then
<button { ...(booleanValue && { className: 'some-class' }) }>Clicker</button>

Displaying Play/Pause Button in angular

I want to implement the show/hide feature of the play and pause buttons on a list of tracks in angular 7. I originally got this feature partially working using angular animation, but my method would change the state of all buttons in my list instead of a single item. I've also tried using ngClass but couldn't seem to get it working right.
Below is my latest efforts. Please help me.
<mat-card class="track-box" *ngFor="let track of tracks" cdkDrag>
<div class="custom-placeholder" *cdkDragPlaceholder></div>
<span>
<mat-icon
class="play-button md-48"
[ngClass]="{'show' : track === selectedTrack}"
(click)="toggle(track)"
> play_circle_outline</mat-icon>
<mat-icon
class="pause-button md-48"
[class.selected2]="track === selectedTrack"
(click)="toggle(track)"
>pause_circle_outline</mat-icon>
</span>
I would have to disagree with #Tomato 's answer, as per my comment on his answer.
However, what I would recommend is using Angular's NgClass which is similar to ngIf. But here's the catch.
When it comes to ngIf, you're creating 2 components, hiding one and showing the other, and doing that operation over and over again. Which is not the best code practice.
However, in the case of ngClass, you're creating one component and 2 separate SCSS classes for the same component. Whenever a certain condition is satisfied, one SCSS Class gets applied, and so forth.
HTML File
<span>
<button
class="play-pause-button"
[ngClass]="toggle(track)"></button>
</span>
TS File
export class Component {
let isPlay = false;
public toggle(track: string) {
this.isPlay = !this.isPlay;
this.isPlay ? return 'play-button'; : return 'pause-button'
}
}
That way, the toggle() function will return a SCSS class name based on the current status of the button itself.
Using ngClass
You could change the shown button icon by using ngClass as following:
<mat-card class="track-box" *ngFor="let track of tracks" cdkDrag>
<div class="custom-placeholder" *cdkDragPlaceholder></div>
<span>
<mat-icon
class="md-48"
[ngClass]="{'play-button' : track != selectedTrack,
'pause-button' : track === selectedTrack}"
(click)="toggle(track)">Some output here</mat-icon>
</span>
</mat-card>
Using ngIf
You could maybe use an ngIf (docs) to show/hide the buttons, though as Chris pointed out, this creates two elements for every track in your list and could cause performance issues on a very huge list.
<mat-card class="track-box" *ngFor="let track of tracks" cdkDrag>
<div class="custom-placeholder" *cdkDragPlaceholder></div>
<span>
<mat-icon
class="play-button md-48"
*ngIf="track != selectedTrack"
(click)="toggle(track)">play_circle_outline</mat-icon>
<mat-icon
class="pause-button md-48"
*ngIf="track === selectedTrack"
(click)="toggle(track)">pause_circle_outline</mat-icon>
</span>
</mat-card>
When your selectedTrack does not equal the track, show the play-button, if it is the same track, show the pause-button.
You could also use the if-else-block for this (from the docs):
<div *ngIf="condition; else elseBlock">Content to render when condition is true.</div>
<ng-template #elseBlock>Content to render when condition is false.</ng-template>

Resources