Second class of multiple classes can't override style - reactjs

button.module.css
.general_button {
width: 100%;
}
button.js
import React from 'react';
import styles from './button.module.css';
const GeneralButton = ({ text, className}) => {
return (
<button className={`${styles.general_button} ${className}`}>
<p className={styles.text}>{text}</p>
</button>
);
};
export { GeneralButton };
app.module.css
.next_btn {
width: 35%;
}
app.js
import React from 'react';
import classes from './app.module.css';
import { GeneralButton } from './components/Buttons';
const App = () => {
return (
<div>
<GeneralButton className={classes.next_btn} text='next' />
</div>
)
}
export default App;
When I used button component from app, button component is working with 'width:100%'. I would like to be button component is with 'width: 35%'.
This is when I inspect browser.
This is when I inspect browser.

Since both classes are equally specific, your app chooses whichever comes later in the stylesheet. Unfortunately you have much control over this order since it is likely generated by webpack (or whatever bundler you happen to be using).
One of the main benefits of using modular css is to avoid having to fight specificity battles such as this, so I would suggest reworking the button component slightly - something like this might work:
const GeneralButton = ({ text, variant }) => {
let buttonClass = styles.general_button;
if (variant === "next") {
buttonClass = styles.next_button;
}
return (
<button className={buttonClass}>
<p className={styles.text}>{text}</p>
</button>
);
};
The advantage here is that the button lays out the options for how to present it and the parent component just selects the type it needs. This makes it safer to re-work the button component in the future since it encapsulates all of it's states.

Related

Styled-Components Not Loading Until Page Refreshed

I'm facing an issue where the css from my styled-components aren't loading until we refresh. I pared down a specific file until there is just a button. I kept the file flow, but stripped out practically everything but the button and the green background color.
I would expect that on the first load, the button has a green background. Instead, it has a transparent background. But it does have the green background after refresh.
If additional context helps, we are using material themes at the moment but are transitioning to styled components. This specific page doesn't reference the MUI themes in any way I can tell. That said, I also am getting the multiple #mui/styles warning in the console. (My package.json doesn't directly use #mui/styles, so I am assuming it's a dependency)
I'm currently stumped and would happily take any suggestions on what to check.
It looks like there are several instances of `#material-ui/styles` initialized in this application.
This may cause theme propagation issues, broken class names, specificity issues, and makes your application bigger without a good reason.
See https://material-ui.com/r/styles-instance-warning for more info.
index.tsx
import PrimaryButton from "components/Shared/Button/PrimaryButton";
export default function ReviewPurchaseOrderPage() {
return (
<PrimaryButton
text={"Approve"}
onClick={() => console.log("test for SO question")}
/>
);
}
PrimaryButton.tsx
import ActionButton from "components/Shared/Button/ActionButton";
interface Props {
text: string;
onClick: () => void;
}
export default function PrimaryButton({
text,
onClick,
}: Props) {
return (
<ActionButton
text={text}
onClick={onClick}
/>
);
}
ActionButton.tsx
import { Button } from "#material-ui/core";
import styled from "styled-components";
const StyledActionButton = styled(Button)`
background-color: #769362;
`;
interface Props {
text: string;
onClick: () => void;
}
export default function ActionButton({
text,
onClick,
}: Props) {
return (
<StyledActionButton
onClick={onClick}
>
{text}
</StyledActionButton>
);
}

How do you use Pseudo-classes in React using css modules?

The example I worked on is the following:
I have a button component that receives the background color as props. The received color will be the background that the button must have when hovering.
Second question:
The only way to use props in css, using css modules, is to apply the inline style in the js file where you declare the component?
Below I insert a code base (in the example the background color is applied by default):
import Button from "./Button";
export default function App() {
return <Button hoverColor={"red"} />;
}
...
export default function Button({ hoverColor }) {
const buttonStyle = {
backgroundColor: hoverColor
};
return <button style={buttonStyle}>click me!</button>;
}
Thanks
You may use React useState Hook to achieve the desired functionality: (Your Button component should look like this)
import React, { useState } from "react";
export default function Button({ hoverColor }) {
const [color, setColor] = useState("");
const buttonStyle = {
backgroundColor: color
};
return (
<button
style={buttonStyle}
onMouseOver={() => setColor(hoverColor)} //set the color when user hovers over the button
onMouseOut={() => setColor("")} //set color to an empty string otherwise
>
click me!
</button>
);
}

Customize layout of AmplifySignOut

I'm currently working on a react app that integrates AWS Amplify. A great tool so far but I find it hard to customize components. Especially I would like to style the AmplifySignOut-component.
According to the documentation (see last paragraph on page) passing a theme to the withAuthenticator-component does not work like this anymore.
I can't figure out how to pass a theme to the AmplifySignOut-component that overwrites the default layout for the button that is created. So far, I think that this is the default layout but I'm not 100% sure.
It would be great, if someone could point me in the right direction here :)
Im using the component like this (not working):
import React from 'react'
import { NavLink } from "react-router-dom";
import './Navbar.css'
import { AmplifySignOut } from '#aws-amplify/ui-react';
function Navbar(props) {
const MyTheme = {
NavButton: { 'fontWeight': '10' },
}
return (
<div className="navbar">
<NavLink exact to="/">Home</NavLink>
<NavLink to="/pdservice">Drucker & Netzwerk</NavLink>
<AmplifySignOut theme={MyTheme}/>
</div>
)
}
export default Navbar;
Best Regards
In my case, i just ended up writing a completely custom button which calls the amplify function. you can style this one then completely as you want. maybe this code helps?
import React from 'react'
import {Auth} from "aws-amplify";
function CustomSignoutButton() {
const signOut = (e) => {
e.preventDefault();
Auth.signOut();
window.location.reload() <!-- it also works without, but just to really kick the user out.-->
}
return (
<button onClick={signOut}>
Sign out
</button>
)
}
export default CustomSignoutButton;
Create new component (in my case it is "src\components\SignOut.js")
import React from 'react'
import {Auth} from "aws-amplify";
function SignOutButton() {
const signOut = (e) => {
e.preventDefault();
Auth.signOut().then(()=>{
window.location.reload(false);
});
}
return (
<button onClick={signOut}>
Sign out
</button>
)
}
export default SignOutButton;
Import it in your app (remember to replace path with correct one if it differs with mine)
import SignOutButton from './components/SignOut';
Then you can use it anywhere you want
<SignOutButton />

Ag-grid custom tooltip with functional component

I am looking at ag-Grid's example on creating a custom tooltip.
import React, {Component} from 'react';
export default class CustomTooltip extends Component {
getReactContainerClasses() {
return ['custom-tooltip'];
}
render() {
const data = this.props.api.getDisplayedRowAtIndex(this.props.rowIndex).data;
return (
<div className="custom-tooltip" style={{backgroundColor: this.props.color || 'white'}}>
<p><span>{data.athlete}</span></p>
<p><span>Country: </span> {data.country}</p>
<p><span>Total: </span> {data.total}</p>
</div>
);
}
}
According to ag-Grid's react component page, "If you wish to override the style of this div you can either provide an implementation of the ag-react-container class, or via the getReactContainerStyle or getReactContainerClasses callbacks on the React component:"
How would I go about creating a custom tooltip using a functional component? I am not sure how I would provide an implementation of the getReactContainerClasses callback.
You won't be able to have the public function getReactContainerClasses in a functional component, you'd need to write a class component. If you want to write a functional component, just set the CSS class directly on the container DOM element, similarly to their vanilla JS example. Below is a functional tooltip example which sets the class custom-tooltip.
import React, {Component} from 'react';
export const FunctionalCustomTooltip = (props) => {
props.reactContainer.classList.add('custom-tooltip');
const data = props.api.getDisplayedRowAtIndex(props.rowIndex).data;
return (
<div className="custom-tooltip" style={{backgroundColor: props.color || 'white'}}>
<p><span>{data.athlete}</span></p>
<p><span>Country: </span> {data.country}</p>
<p><span>Total: </span> {data.total}</p>
</div>
);
};
Fully working example:
https://plnkr.co/edit/WHEgtw0YVia1BVP4SVO8?p=preview
You can have public function using React Hooks with useImperativeHandle hook.
export const Component = forwardRef((props: ComponentParams, ref: any) => {
useImperativeHandle(ref, () => {
return {
getReactContainerClasses() {
return ['grid-container'];
},
};
});
}

Locate a component in React project

I wrote a Logout button component in my React app for which I wish to locate at the top right corner of the screen.
render() {
<LogoutButtonComponent height: , backgroudColor: />
}
It wouldn't let me assign any values for height and etc.
This is the Logout component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class LogOutButton extends Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.props.onLogout();
};
render() {
return <button type="button" onClick={this.handleClick}>Logout</button>;
}
}
Should I locate it by < col /> ?
To add inline styles, you should defined a style object as prop, and pass it values, like doniyor2109 mentioned. There are a few caveats to using this, however.
style={{ height: 100, height: '100px', height: '100%', minHeight: '100px'}}.
Not every value should be passed as integer, some need to be passed as a string
Not every css attribute gets passed as you would expect them to, the css min-height actually gets passed as minHeight, so replace all hyphens with lower camel case style
Inline styles get insanely difficult to manage. I suggest you at the very least create an object outside the component, and pass it in like:
const DivStyle = { minHeight: '100px' }
and then:
<LogoutButtonComponent style={DivStyle} />
You can prefix that DivStyle with an export if you want to import {DivStyle} from './somefile' in other places
I suggest you check out a library like styled-components as it makes styling much easier!
I suggest you check out this article which outlines your options
You don't really add styles to your component like that. It's better to add those styles in the source for the actual component. So how exactly do you want it displayed? I will provide a template kind of and you can change it to what you want.
Go to your source for your Logout Button Component. In the return of your render method try adding a div call it container. Then add styling in a css file to that div or if you are using react-bootstrap or reactstrap or #material/ui/core you can adjust the style according to their documentation.
You can add your css for the className .container to make it appear the way you would like.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class LogOutButton extends Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.props.onLogout();
};
render() {
return (
<div className="container">
{* notice the className here *}
<button type="button" onClick={this.handleClick}>Logout</button>
</div>
)
}
}
Hope this helps.

Resources