React overriding child element styles - reactjs

I have the following structure
<button>
<OtherComponent />
</button>
OtherComponent just gives a < span /> with an icon, with its own styles.
I want to pass a style to button to override OtherComponent's styles, eg. set the margin to 0. I've tried (doesn't work)
<button style={{ 'span': { margin: 0 }}}>
<OtherComponent />
</button>

Inline style only affects the current element that you are applying to
If you want to style a child element then you should select it from a CSS file.
So in your parent component you would do:
import React from "react";
import { OtherComponent } from "./components/OtherComponent";
import "./styles.css";
export default function App() {
return (
<div className="App">
<OtherComponent />
</div>
);
}
And then in styles.css file:
.App span {
margin: 0;
}
Complete Example

A simple way is to add div/Button in backend and override style like style={{ marginLeft: "100px" }} with double curle braces.
Parent Component
import "./styles.css";
import OtherComponent from "./OtherComponent";
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<button style={{ marginLeft: "100px" }}>
<OtherComponent />
</button>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
Child Component
import React from "react";
import "./buttonStyle.css";
class OtherComponent extends React.Component {
render() {
return <button className="button">Style Button</button>;
}
}
export default OtherComponent;
CodeSandBox Live Demo

Related

Unable to toggle expanded nav menu

I want to create an expandable side menu which is toggled by clicking the hamburger menu inside "MobileNav". I'm having issues selecting the elements since they're inside seperate documents. How would I go about doing this?
The idea is to add and remove the "hidden" class to hide and show the expanded menu.
App
import React from "react";
import ExpandedNav from "./components/ExpandedNav";
import MobileNav from "./components/MobileNav";
import Navbar from "./components/Navbar";
import "./styles/styles.css";
function App() {
return (
<div className="app-wrapper">
{/* Mobile Nav */}
<MobileNav />
<ExpandedNav />
{/* Main Nav */}
<Navbar />
{/* Routing */}
</div>
);
}
export default App;
Expanded Nav
import React from "react";
function ExpandedNav() {
return <div className="expanded-nav" id="expanded-nav"></div>;
}
export default ExpandedNav;
Mobile Nav
import React from "react";
import { AiOutlineMenu } from "react-icons/ai";
function MobileNav() {
return (
<div className="app-mobile-nav">
<div className="mobile-nav-brand">
<span>Chicken</span>
<div className="mobile-nav-divider" />
<span>Little</span>
</div>
<AiOutlineMenu className="nav-icon" id="mobile-hb-nav" />
</div>
);
}
export default MobileNav;
Expanded Nav SCSS
.expanded-nav {
display: flex;
position: absolute;
top: 0;
right: 0;
bottom: 0;
margin: 15px 20px 15px 0px;
width: 300px;
border-radius: $border-radius;
box-shadow: $box-shadow;
border: $thin-light-border;
background-color: $block-color;
}
.hidden {
display: none; /* responds to click event */
}
There is a better way then toggling CSS classes. Add state in the App file and then forward function for changing state via props to the MobileNav component. Based on the state show or hide expanded component. Something like this:
import React from "react";
import ExpandedNav from "./components/ExpandedNav";
import MobileNav from "./components/MobileNav";
import Navbar from "./components/Navbar";
import "./styles/styles.css";
function App() {
const [isVisible, setIsVisible] = useState(false);
return (
<div className="app-wrapper">
{/* Mobile Nav */}
<MobileNav toggleNav={() => setIsVisible(!visible)}/>
{isVisible && <ExpandedNav />}
{/* Main Nav */}
<Navbar />
{/* Routing */}
</div>
);
}
export default App;
import React from "react";
import { AiOutlineMenu } from "react-icons/ai";
function MobileNav({toggleNav}) {
return (
// Add onClick function to the element that you need, this is only
// for example
<div className="app-mobile-nav" onClick={toggleNav}>
<div className="mobile-nav-brand">
<span>Chicken</span>
<div className="mobile-nav-divider" />
<span>Little</span>
</div>
<AiOutlineMenu className="nav-icon" id="mobile-hb-nav" />
</div>
);
}
export default MobileNav;

How to Change footer value in antd layout when i click on button inside route based component in reactjs [duplicate]

This question already exists:
How to Change footer value inside antd layout when i click on button inside any route based component in reactjs
Closed 1 year ago.
I have used antd Layout with footer for Reactjs application. How to change value of footer when I click on button inside numbers component. I have used antd layout like this
https://ant.design/components/layout/
Code For Above Functionality Like:
When i click on button how to display Input value on Footer Label.
Mainly Two component Like :
WebSiteLayout.js (Footer inside them)
NumberList.js (Button and Input value inside them)
How to pass value from NumberList.js component to WebSiteLayout.js
WebSiteLayout.js
import React from "react";
import { withRouter, Switch, Link } from "react-router-dom";
import NumbersList from "../pages/Numbers/NumbersList";
import AuthenticatedRoute from '../../AuthenticatedRoute';
import './WebLayout.css';
import '../../../../assets/css/app.css';
import { Layout, Button, Menu, Popover, Spin, Select, Checkbox, Row, Col, Form, notification } from 'antd';
const { Header, Sider, Content, Footer } = Layout;
const { SubMenu } = Menu;
import {
PhoneOutlined,
} from '#ant-design/icons';
const WebSiteLayout = ({ location, row }) => {
return (
<Layout>
<Sider trigger={null} collapsible collapsed={collapsed}>
<div className="topbar1">
<div className="topbar-left">
</div>
</div>
<Menu theme="dark" mode="inline">
<Menu.Item key="/numbers" icon={<PhoneOutlined style={{ fontSize: '18px' }} />} title="Numbers" >
<span>Numbers</span>
<Link to="/numbers" />
</Menu.Item>
</Menu>
</Sider>
<Layout className="site-layout" hasSider={true} style={{ height: "100vh" }}>
<Content
className="site-layout-background"
style={{
padding: 24,
height: '80px',
minHeight: 280,
}}
>
<Switch>
<AuthenticatedRoute path='/numbers' component={NumbersList} />
</Switch>
<Footer style={{ position: "fixed", bottom: "0px", right: "0px", background: "#c2c2c2", padding: "15px 25px" }}>
Display Numbers Field Value
</Footer>
</Content>
</Layout>
</Layout>
);
};
export default withRouter(WebSiteLayout)
NumberList.js
import React, {Component} from 'react';
import 'antd/dist/antd.css';
import { withRouter } from "react-router";
import { Button, Input } from 'antd';
class NumbersList extends Component {
constructor(props) {
super(props);
this.state = {
value:''
}
}
sendValueToFooter = () => {
console.log(this.state.value);
}
render() {
return (
<div class="container-fluid">
<h4 class="page-title float-left">Numbers</h4>
<Input placeholder="Basic usage" value={this.state.value} onChange={(e)=>{this.setState({value : e.target.value})}}/>
<br></br>
<Button type="primary" onClick={this.sendValueToFooter}>
Click Here To Send Value On Footer
</Button>
</div>
)
}
}
export default withRouter(NumbersList)
When I click on button how to display Input value on Footer Label.

How to Use ClassName for import the style of the Element react-js

this is my component code
import React from 'react';
import Aux from '../../hoc/Aux';
import classes from './Layout.css';
const layout = (props) => (
<Aux>
<div>toolbar, sideshow, backdrop</div>
<main className = {classes.Content}>
{props.children}
</main>
</Aux>
);
export default layout;
in this {props.children} just the <p> Hi </p> and this is my css file
.Content{
margin: 2% auto;
}
thi
why the style of the classes.Content not working?

React 16 - unable to make a modal render using createPortal

I'm trying to render a loading notification modal while a POST is processing.
It seems like it should be very simple using createPortal but the modal never displays.
I added a div in index with an id of modal:
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<div id="modal"></div>
</body>
Here is the react component. When the test button is clicked the state of showModal is set to true:
import React, { Component, Header } from 'react';
import { render } from "react-dom";
import { Row, Col, Button } from 'reactstrap'
import 'bootstrap/dist/css/bootstrap.css';
import ProcessingModal from '../Modals/ProcessingModal';
export class TestModal extends React.Component {
constructor(props) {
this.state = {
showModal: false,
}
this.handleShowModal = this.handleShowModal.bind(this);
}
handleShowModal() {
this.setState({ showModal: true });
}
render() {
return (
<div>
<div className='container-fluid'>
<h2 style={{ textAlign: 'center', border: 'none' }}>
Header Text
</h2>
<br />
{this.state.showModal ? <ProcessingModal /> : null }
<Row>
<Col md={6}>
<Button onClick={this.handleShowModal} type="button">test</Button>
</Col>
</Row>
</div>
</div>
);
}
This is the ProcessingModal js:
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
const ModalContent = (
<div className='modal text-center'>
<div className="spinner-border text-success"><br />
Loading...
</div>
</div>
);
function ProcessingModal(props) {
return ReactDOM.createPortal(ModalContent, document.querySelector("#modal"));
}
export default ProcessingModal;
Where am i going wrong?
I think first argument of createPortal expect a React Element, not React Component.
In ProcessingModal.js, wrap ModalContent into JSX Element:
return ReactDOM.createPortal(<ModalContent/>, document.querySelector("#modal"))
Styling was my issue. The modal style had display: none;
Once that was removed it worked.

Parent component that can get different components

I have a <Panel/> component that has to get different changing components.
For example one time- the <Panel/> needs to contain a <Dropdown/> component, a second time a <TextInput/> and in the third time a <Checkbox/>.
How can I make this <Panel/> component to get different components?
The <Panel/> component:
import React from "react";
import { css } from "emotion";
import colors from '../../styles/colors';
import PanelHeader from "./PanelHeader";
export default function Panel({ active, panelHeader}) {
const styles = css({
borderRadius: 4,
backgroundColor: "white",
border: `1px solid ${ active ? colors.blue : colors.grayLight }`,
width: 540,
padding: 32,
});
return (
<div className={styles}>
{panelHeader && <PanelHeader headerType={panelHeader} />}
</div>
);
}
The Panel story:
import React from "react";
import { storiesOf } from "#storybook/react";
import Panel from "../components/Panel";
import colors from '../styles/colors';
import PanelHeader from "../components/Panel/PanelHeader";
storiesOf("Panel", module)
.add("Default", () => (
<Panel></Panel>
))
.add("Active", () => (
<Panel active></Panel>
))
storiesOf("Panel/PanelHeader", module)
.add("Default", () => (
<PanelHeader headerType="Identity document" color={colors.gray}>1</PanelHeader>
))
.add("Active", () => (
<PanelHeader headerType="Identity document" color={colors.blue}>1</PanelHeader>
))
You can change Panel to accept children prop, pass it where you Render <Panel> and pass in the corresponding component.
For example:
// PropType for children is `PropTypes.node`
export default function Panel({ active, panelHeader, children}) {
// ...
return (
<div className={styles}>
{children}
</div>
);
}
// ...
<Panel><Dropdown /></Panel>
// or
<Panel><TextInput /></Panel>
Or, you could pass in a component class/function and render it inside:
export default function Panel({ active, panelHeader, ChildComponent}) {
// ...
return (
<div className={styles}>
{/* This is like any other component,
you can pass in props as usual. */}
{/* It's important for the name to start with an uppercase letter,
otherwise the JSX compiler will turn this in a string! */}
<ChildComponent />
</div>
);
}
// ...
<Panel ChildComponent={Dropdown}></Panel>
// or
<Panel ChildComponent={TextInput}></Panel>
This pattern is called component composition. You can read more in React docs: https://reactjs.org/docs/composition-vs-inheritance.html

Resources