I'm still a beginner with the ui-material. And I would like to custom my own Button Component with styled-component.
The problem is to override the css according to the button variations, for example if it is primary or secondary:
Here's my code into codesandbox.io
import React from "react";
import PropTypes from "prop-types";
import { CButton } from "./styles";
const CustomButton = ({ children, color }) => {
return (
<div>
<CButton variant="contained" color={color}>
{children}
</CButton>
</div>
);
};
CustomButton.propTypes = {
children: PropTypes.node,
color: PropTypes.oneOf(["primary", "secondary"])
};
export default CustomButton;
import styled, { css } from "styled-components";
import Button from "#material-ui/core/Button";
export const CButton = styled(Button)`
height: 80px;
${({ color }) =>
color === "primary"
? css`
background-color: green;
`
: color === "secondary" &&
css`
background-color: yellow;
`}
`;
import React from "react";
import CustomButton from "./CustomButton";
const App = () => {
return (
<div>
<div
style={{
marginBottom: "10px"
}}
>
<CustomButton color="primary">Primary</CustomButton>
</div>
<div>
<CustomButton color="secondary">Secondary</CustomButton>
</div>
</div>
);
};
export default App;
Could you tell me how I can get my styling to override the ui-material?
Thank you in advance.
It looks like there's a nice example on how to do this in the material-ui docs: https://material-ui.com/guides/interoperability/#styled-components
One thing you seem to be missing is the StylesProvider, which allows your styles to override the default material styles. This seems to work... I don't deal with the conditional in your example, but I don't think that's part of your problem here.
const MyStyledButton = styled(Button)`
background-color: red;
color: white;
`;
export default function App() {
return (
<StylesProvider injectFirst>
<div className="App">
<MyStyledButton color="primary">Foo</MyStyledButton>
</div>
</StylesProvider>
);
}
Here's a codesandbox: https://codesandbox.io/s/infallible-khorana-gnejy
Related
I want to pass var form parent component to child component (--my-custom) that will set color for child component , but when i write like this it gives me error , if you see i use my custom variable in MyButton.css in this manner it will adjust my button to any color i want.
// my jsx file
import React from "react";
import "./styles/MyButton.css";
const MyButton = ({ title, handelClick, color }) => {
return (
<div class="parentbutton">
<a class="mybutton" onClick={() => handelClick()} style={{ --my-custom: color }}>
<span>{title}</span>
<i></i>
</a>
</div>
);
};
export default MyButton;
//MyButton.css
a.mybutton:hover {
letter-spacing: 0.25em;
background-color: var(--my-custom);
box-shadow: 0 0 2.5em var(--my-custom);
color: var(--my-custom);
}
You can replace your style like this, it might works!
<div style={{ "--my-css-var": 10 } as React.CSSProperties} />
Just use the inline styling without a .css file
import React from "react";
const MyButton = ({ title, handelClick, color }) => {
return (
<div className="parentbutton">
<a className="mybutton" onClick={() => handelClick()} style={{
backgroundColor: color,
boxShadow: `0 0 2.5em ${color}`,
color: color
}}>
<span>{title}</span>
<i></i>
</a>
</div >
);
};
export default MyButton;
When the button inside the Post clicked, Popup will render with createPortal method outside from root element's tree.
With this code that popup renders twice.
I want to render it only once.
Here's the parent Post component.
import { useState } from 'react';
import PopupModal from './PopupModal/PopupModal';
import './Post.css';
const Post = (props) => {
const postData = props;
const [isOpen, setIsOpen] = useState(false);
return (
<div className="post-container">
<div className="post-img-container">
<img className="post-img" src={props.img} alt="Travels" />
</div>
<div className="post-text-container">
<h4 className="post-heading">{props.title}</h4>
<p className="post-para">{props.description}</p>
<h1 className="post-price">{props.price}</h1>
<div className="post-btn-container">
<button onClick={() => setIsOpen(true)} className="post-btn">
Check Availability
</button>
<PopupModal dataData={postData} open={isOpen} onClose={() => setIsOpen(false)}>
Button123
</PopupModal>
</div>
</div>
</div>
);
};
export default Post;
And here's the popupModal
import React from 'react';
import ReactDOM from 'react-dom';
import '../PopupModal/popupModal.css'
const MODAL_STYLES = {
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%,-50%)',
background: '#fff',
width: '40vw',
height: '90vh',
padding: '50px',
zIndex: 1000,
};
const PopupModal = ({ open, children, onClose ,dataData }) => {
if (!open) return null;
console.log('xxx');
console.log(dataData);
return ReactDOM.createPortal(
<>
<div className='modal-overlay' ></div>
<div className='modal-container'>
<button onClick={onClose}> Popup Close</button>
{children}
</div>
</>,
document.getElementById('portal')
);
};
export default PopupModal;
Here's how I figured it rendered twice.
Here's the Popup with overlay around it which covers the background.
Thanks in advance!
Try following
{
isOpen && <PopupModal dataData={postData} open={isOpen} onClose={() => setIsOpen(false)}>
Button123
</PopupModal>
}
I am creating a div using styled component. I want to change the visibility of the div on button clicked,
const Category = () => {
const [showCategory, setShowCategory] = useState(false)
useEffect(() => {
setShowCategory(false)
}, [])
return (
<button onClick={() => { setShowCategory(true)}}>
New Category
</button>
<AdminInputStyle>
<form>
<form-group>
<label>Add Category</label>
<input type='text' />
</form-group>
<button>Submit</button>
</form>
</AdminInputStyle>
)
}
Here's the styled component
const AdminInputStyle = styled.div`
display: ${(d) => (d.showCategory ? 'show' : 'hidden')};
`
You can try something like this too, show when you need to show the add category when you press add category
return (
<>
<button
onClick={() => {
setShowCategory(true);
}}
>
New Category
</button>
{showCategory && (
<AdminInputStyle>
<form>
<form-group>
<label>Add Category</label>
<input type="text" />
</form-group>
<button>Submit</button>
</form>
</AdminInputStyle>
)}
</>
);
I have an example, but in the case we will use a Button. Clicking it will alter the visibility.
You must pass a property to the styled component if you want it to be visible based on that prop. In your example, you don't pass a prop to the styled component in this scenario, which is why the component cannot detect if it should be visible or not.
You will need to / can use the css function from the styled-components library. This can help you return styles based on the properties your styled-component will have. In this example, our property that we pass to the button will be called visible.
import React from 'react';
import PropTypes from 'prop-types';
import styled, { css } from 'styled-components/macro';
const StyledButton = styled.button`
border-radius: 3px;
color: white;
background-color: green;
cursor: pointer;
width: 100px;
height: 50px;
${({ visible }) => {
return css`
visibility: ${visible ? 'visible' : 'hidden'};
`;
}}
`;
export default function Button({ children, visible, onClick }) {
return (
<StyledButton visible={visible} onClick={onClick}>
{children}
</StyledButton>
);
}
Button.propTypes = {
children: PropTypes.node,
visible: PropTypes.bool,
onClick: PropTypes.func,
};
You can see that passing the visible prop will enable the button to alter its' styles based on whether that property is true or false. We utilize a function within the component that returns the css function and this will control the visibility css property.
Here is how we utilize the button and pass props to it from another component; in this example just the App.js file:
import React, { useState } from 'react';
import './App.css';
import Button from './components/Button';
function App() {
const [visible, setVisible] = useState(true);
function handleClick() {
setVisible(!visible);
}
return (
<div className="App">
<Button visible={visible} onClick={handleClick}>
Click
</Button>
</div>
);
}
export default App;
FYI: For the css; you don't want display: hidden;. hidden is an invalid value for the display prop. You'd want display: none; if you don't want the element to be in the DOM. visibility: hidden; will add the element to the DOM, but it won't be visible. You can use whichever works best for your case 👍🏿
I'm experimenting with react-resizable, but this extremely basic example will simply display the text XYZ in the browser, but will otherwise be blank with no error messages. I am expecting a resizable box.
import { ResizableBox } from 'react-resizable';
import 'react-resizable/css/styles.css';
ReactDOM.render(
<div>
<ResizableBox className="box" width={200} height={200} axis="y">
<span className="text">XYZ</span>
</ResizableBox>
</div>,
document.getElementById("root")
);
I derived this test case from the longer example here.
EDIT: And here is the codesandbox: https://codesandbox.io/s/suspicious-bogdan-08f01?file=/src/App.js
You can apply CSS styles with the className property. Here is a working example:
import React from "react";
import { ResizableBox } from "react-resizable";
import "react-resizable/css/styles.css";
import "./style.css";
const Box = () => {
return (
<ResizableBox
className="box borderBlack"
width={200}
height={200}
axis="y"
>
<span className="text">XYZ!!</span>
</ResizableBox>
);
};
export default Box;
style.css file:
.borderBlack {
border: 1px solid black;
}
I have a Styled Component called StyledButton and a React component called AddToCart. I want to apply the styled from StyledButton to AddToCart.
I have already tried the following:
import styled from "styled-components";
import AddToCart from "./AddToCart";
import StyledButton from "./styles/StyledButton";
const StyledAddToCart = styled(AddToCart)`
${StyledButton}
`;
What I want to do is already in the documentation at https://www.styled-components.com/docs/basics#styling-any-components but this applies new styles to the component. The problem is that I want to use existing styled from a Styled Component (StyledButton)
From the documentation:
// This could be react-router-dom's Link for example
const Link = ({ className, children }) => (
<a className={className}>
{children}
</a>
);
const StyledLink = styled(Link)`
color: palevioletred;
font-weight: bold;
`;
render(
<div>
<Link>Unstyled, boring Link</Link>
<br />
<StyledLink>Styled, exciting Link</StyledLink>
</div>
);
I would really like to have the styles from StyledButton applied to StyledAddToCart without copying the styles manually.
You can share styling with the css util:
// import styled, {css} from 'styled-components'
const {css} = styled;
const Link = (props) => <a {...props} />
const sharedBtnStyle = css`
color: green;
border: 1px solid #333;
margin: 10px;
padding: 5px;
`;
const StyledButton = styled.button`
${sharedBtnStyle}
`;
const AddToCartBtn = styled(Link)`
${sharedBtnStyle}
color: red;
`;
function App() {
return (
<div>
<StyledButton>styled button</StyledButton>
<div />
<AddToCartBtn>styled link</AddToCartBtn>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="root"/>