Goal:
When you press on the button 'ok', the id element named test2 should be display non and id element named test1 should be display block with support of css code.
And also please take account to the color of the text that is located in the css code.
Problem:
I don't know how to solve it.
What is needed to be changed in the source code in order to achieve the goal?
Stackblitz:
https://stackblitz.com/edit/react-modal-gdh4hp?
Info:
*I'm newbie in Reactjs
Thank you!
index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import { Modal } from './modal';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
modal: true
};
}
handleCloseModal = () => {
alert('ddd');
};
render() {
const { modal } = this.state;
const non = {
display: 'none',
color: 'yellow'
};
const block = {
display: 'block',
color: 'yellow'
};
return (
<div>
{modal ? (
<Modal
onClose={() => {
this.setState({ modal: false });
}}
>
<div id="test1" style={non}>Awesome1</div>
<div id="test2">Awesome2</div>
<button onClick={() => this.handleCloseModal()}>ok</button>
</Modal>
) : (
<button
onClick={() => {
this.setState({ modal: true });
}}
>
Show modal
</button>
)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
modal.js
import React from 'react';
export class Modal extends React.Component {
render() {
const { children, onClose } = this.props;
return (
<div style={{position: "absolute", top: 0, left: 0, width: "100%", height: "100%", background: "gray"}} onClick={ev => onClose()}>
<div
style={{margin: "auto", background: "white", border: "red", width: "500px", height: "300px"}}
onClick={ev => ev.stopPropagation()}>
{ children }
</div>
</div>
);
}
}
You can simply do that :
ok() => {
document.getElementById('test1').style.display = 'block'
document.getElementById('test2').style.display = 'none'
}
You can use state
class App extends Component {
constructor() {
super();
this.state = {
modal: true,
showBlock: "",
showNon: "",
color: ""
};
}
handleCloseModal = () => {
this.setState({showBlock: "block"});
this.setState({showNon: "none"});
this.setState({color: "yellow"});
alert('ddd');
};
render() {
const { modal } = this.state;
return (
<div>
{modal ? (
<Modal
onClose={() => {
this.setState({ modal: false });
}}
>
<div id="test1" style={{display: this.state.showBlock, color: this.state.color}}>Awesome1</div>
<div id="test2" style={{display: this.state.showNon, color: this.state.color}}>Awesome2</div>
<button onClick={() => this.handleCloseModal()}>ok</button>
</Modal>
) : (
<button
onClick={() => {
this.setState({ modal: true });
}}
>
Show modal
</button>
)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
React way to achieve that is to use useRef hook (or createRef for class approach):
Class approach:
constructor(props) {
this.testRef = React.createRef()
}
const toggleBlock = () => {
testRef.current.style.display = 'block'
testRef.current.style.color = 'yellow'
}
render() {
return (
<>
<div id="test1" ref={testRef}>Awesome1</div>
<button onclick={this.toggleBlock}>Ok</button>
</>
)
}
Hooks approach:
const testRef = useRef(null)
const toggleBlock = () => {
testRef.current.style.display = 'block'
testRef.current.style.color = 'yellow'
}
return (
<>
<div id="test1" ref={testRef}>Awesome1</div>
<button onclick={this.toggleBlock}>Ok</button>
</>
)
Related
I am trying to achieve an image/video carousel using https://jossmac.github.io/react-images/
and it should be like this including modal :
I following the code snippet given there but it's not working and I don't see any step by step guide to making that carousel.
class Gall extends Component {
state = { modalIsOpen: false }
toggleModal = () => {
this.setState(state => ({ modalIsOpen: !state.modalIsOpen }));
}
render() {
const { modalIsOpen } = this.state;
return (
<ModalGateway>
{modalIsOpen ? (
<Modal onClose={this.toggleModal}>
<Carousel views={images} />
</Modal>
) : null}
</ModalGateway>
);
}
}
export default Gall;
can anyone please help with a codesandbox?
Also is it possible to trigger the modal with the current active image?
Thanks in advance.
There is a link in their docs to the source
// #flow
// #jsx glam
import glam from 'glam';
import React, { Component, Fragment } from 'react';
import { type ProviderProps } from '../../ImageProvider';
import Carousel, { Modal, ModalGateway } from '../../../src/components';
import { FooterCaption } from '../components';
import { getAltText } from '../formatters';
type State = {
selectedIndex?: number,
lightboxIsOpen: boolean,
};
export default class Home extends Component<ProviderProps, State> {
state = {
selectedIndex: 0,
lightboxIsOpen: false,
};
toggleLightbox = (selectedIndex: number) => {
this.setState(state => ({
lightboxIsOpen: !state.lightboxIsOpen,
selectedIndex,
}));
};
render() {
const { images, isLoading } = this.props;
const { selectedIndex, lightboxIsOpen } = this.state;
return (
<Fragment>
{!isLoading ? (
<Gallery>
{images.map(({ author, caption, source }, j) => (
<Image onClick={() => this.toggleLightbox(j)} key={source.thumbnail}>
<img
alt={caption}
src={source.thumbnail}
css={{
cursor: 'pointer',
position: 'absolute',
maxWidth: '100%',
}}
/>
</Image>
))}
</Gallery>
) : null}
<ModalGateway>
{lightboxIsOpen && !isLoading ? (
<Modal onClose={this.toggleLightbox}>
<Carousel
components={{ FooterCaption }}
currentIndex={selectedIndex}
formatters={{ getAltText }}
frameProps={{ autoSize: 'height' }}
views={images}
/>
</Modal>
) : null}
</ModalGateway>
</Fragment>
);
}
}
const gutter = 2;
const Gallery = (props: any) => (
<div
css={{
overflow: 'hidden',
marginLeft: -gutter,
marginRight: -gutter,
}}
{...props}
/>
);
const Image = (props: any) => (
<div
css={{
backgroundColor: '#eee',
boxSizing: 'border-box',
float: 'left',
margin: gutter,
overflow: 'hidden',
paddingBottom: '16%',
position: 'relative',
width: `calc(25% - ${gutter * 2}px)`,
':hover': {
opacity: 0.9,
},
}}
{...props}
/>
);
tl;dr: I'm finding that consecutive elements on my page with position: relative are overlapping, and really don't understand why.
Details: I'm trying to write a re-usable React component SlidePair that allows you to toggle between two other components with a slide animation, passing data between them. I'm using react-reveal for the animation, and positioning the elements at the same place in the page, so the exit of one accompanies the entry of the other. To make the divs overlap I followed the approach of this SO question.
My code, in the context of an App.js file from create-react-app, is below. You see that in the main App component I want to stack two SlidePair elements, which turn out to overlap instead. Everything else are just some example components for me to plug in; I've only included them for the sake of anyone who just wants to copy and paste the whole thing to get it running.
import React, {Component} from 'react';
import Slide from 'react-reveal/Slide';
class RedBox extends Component {
constructor(props){
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
text: props.text
}
}
handleChange(event) {
this.setState({text: event.target.value});
}
render(){
const { toggleState, text, style} = this.props;
return(
<div style={style}
onClick={()=>{console.log('red clicked'); toggleState({text: this.state.text})}}>
<input onChange={this.handleChange}
type="text" value={this.state.text}
onClick={(event)=>{event.stopPropagation()}}
style={{zIndex: '999'}}
/>
{ text }
</div>
);
}
}
const BlueBox = ({toggleState, passedProps, style })=> {
return (
<div onClick={toggleState} style={style}>
{ passedProps.text }
</div>
);
};
class MouseTracker extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
const coords = {
x: event.clientX,
y: event.clientY
};
this.props.toggleState(coords);
}
render() {
return (
<div style={{ height: '100px' }} onClick={this.handleClick}>
<h1>Click me!</h1>
</div>
);
}
}
const MouseInformer = ({toggleState, passedProps}) => (
<div>
You clicked {passedProps.x}, {passedProps.y}!
<button onClick={toggleState}>Go Back</button>
</div>
);
class SlidePair extends Component {
constructor(props){
super(props);
this.state = { left: true, passedProps: {}};
this.toggleState = this.toggleState.bind(this);
}
toggleState(passedProps){
const left = !this.state.left;
console.log(`Toggling left to ${left}`);
this.setState({ left, passedProps });
}
render(){
const {left, passedProps } = this.state;
return(
<div style={{position: 'relative'}}>
<Slide left when={left} >
<div style={ {position: 'absolute', top: '0px', right: '0px', width: '100%', zIndex: left ? '998' : -1 }}>
{this.props.renderLeft(this.toggleState, passedProps)}
</div>
</Slide>
<Slide right when={!left}>
<div style={{position: 'absolute', top: '0px', right: '0px', width: '100%', zIndex: left ? -1 : 1}}>
{ this.props.renderRight(this.toggleState, passedProps) }
</div>
</Slide>
</div>
)
}
}
class App extends Component {
render(){
const redBox = (toggleState, passedProps)=>(
<RedBox toggleState={toggleState}
style={{width: '100%', border: '5px solid red', height: '100px'}}/>
);
const blueBox = (toggleState, passedProps) => (
<BlueBox
toggleState={toggleState}
passedProps={passedProps}
style={{width: '100%', border: '5px solid blue', height: '100px'}}
/>
);
const mouseTracker = (toggleState, passedProps) => (
<MouseTracker toggleState={toggleState} passedProps={passedProps} style={{top: '300px'}}/>
);
const mouseInformer = (toggleState, passedProps) => (
<MouseInformer toggleState={toggleState} passedProps={passedProps} style={{top: '300px'}}/>
);
return (
<div className="App">
<SlidePair renderLeft={redBox} renderRight={blueBox}/>
<br/>
<SlidePair renderLeft={mouseTracker} renderRight={mouseInformer} />
</div>
);
}
}
export default App;
Thanks in advance for any help.
I am new to Ant-design. Currently I am working on ReactJs project and I've used Steps in my project. I want to change the color of Steps but did not get idea how will it be possible . I will share ant-design (Steps) code. Please help me out
Thanks
You may see example of Steps in this codesandbox
Code
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Steps, Button, message } from 'antd';
const Step = Steps.Step;
const steps = [{
title: 'First',
content: 'First-content',
}, {
title: 'Second',
content: 'Second-content',
}, {
title: 'Last',
content: 'Last-content',
}];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
current: 0,
};
}
next() {
const current = this.state.current + 1;
this.setState({ current });
}
prev() {
const current = this.state.current - 1;
this.setState({ current });
}
render() {
const { current } = this.state;
return (
<div>
<Steps current={current}>
{steps.map(item => <Step key={item.title} title={item.title} />)}
</Steps>
<div className="steps-content">{steps[current].content}</div>
<div className="steps-action">
{
current < steps.length - 1
&& <Button type="primary" onClick={() => this.next()}>Next</Button>
}
{
current === steps.length - 1
&& <Button type="primary" onClick={() => message.success('Processing complete!')}>Done</Button>
}
{
current > 0
&& (
<Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>
Previous
</Button>
)
}
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('container'));
Use inline styles.
Code
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Steps, Button, message } from "antd";
const Step = Steps.Step;
const steps = [
{
title: "First",
content: "First-content"
},
{
title: "Second",
content: "Second-content"
},
{
title: "Last",
content: "Last-content"
}
];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
current: 0
};
}
next() {
const current = this.state.current + 1;
this.setState({ current });
}
prev() {
const current = this.state.current - 1;
this.setState({ current });
}
render() {
const { current } = this.state;
return (
<div>
<Steps current={current} style={{ "background-color": "blueviolet" }}>
{steps.map(item => (
<Step key={item.title} title={item.title} />
))}
</Steps>
<div className="steps-content" style={{ "background-color": "grey" }}>
{steps[current].content}
</div>
<div className="steps-action" style={{ "background-color": "blue" }}>
{current < steps.length - 1 && (
<Button
type="primary"
style={{ "background-color": "red" }}
onClick={() => this.next()}
>
Next
</Button>
)}
{current === steps.length - 1 && (
<Button
type="primary"
onClick={() => message.success("Processing complete!")}
>
Done
</Button>
)}
{current > 0 && (
<Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>
Previous
</Button>
)}
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
Try to add following CSS
.ant-steps-item-process .ant-steps-item-icon { background: red; }
See index.css in this example
By the way you a have a more robust way to change ant framework styling, please refer to the documenatation
if you change all your step tails color then
put the following style in index.css
.ant-steps-item-finish
> .ant-steps-item-container
> .ant-steps-item-tail::after {
background-color: red !important;
}
change background-color
if you change only one step tail color then put className in Step like this
<Steps className="custome-step" current={1} progressDot>
<Step title="In Progress" description="Loan Application" />
<Step title="" description="Loan Vetting" />
<Step title="" description="Disbursement" />
</Steps>
index.css
.custome-step .ant-steps-item-finish > .ant-steps-item-container > .ant-steps-item-tail::after {
background-color: red !important;
}
example
Add a span in your Step and style it or add a class name, just like this:
<Step title={<span className="font-bold">First content</span>} status="process"/>
If you want to style an indicating circle background, add it to your CSS and make sure you add !important, just like this:
.ant-steps-item-process .ant-steps-item-icon {
background: #46b3cb !important;
}
I have a parent and child component there is a button in parent component on Clicking that button it should send a Props -"red" so the child should receive the red and change its background color as red. Below my code is there
jsfiddle.net/t1ru6oyz/3/
Child
import React from "react";
import ReactDOM from "react-dom";
const childContainer = {
border: "0px solid #000",
width: "300px",
height: "300px",
textAlign: "middle",
margin: "0 auto",
marginTop: "60px"
};
const Child = props => {
return (
<div
style={{
backgroundColor: props.color
}}
/>
);
};
export default Child;
Parent
import React, { Component } from "react";
import "./App.css";
import Child from "./child";
const parentContainer = {
border: "10px solid #000",
width: "500px",
height: "500px",
margin: "20px",
textAlign: "middle"
};
class App extends Component {
constructor() {
super();
this.state = {
currentColor: "red"
};
}
componentDidMount() {
this.setState({
currectColor: "green"
});
}
changeColor = () => {
this.setState({
currectColor: "blue"
});
};
render() {
console.log("in render", this.state);
return (
<div style={parentContainer}>
<button onClick={this.changeColor}>Blue</button>
<p>{this.state.name}</p>
<Child color={this.state.currentColor} />
</div>
);
}
}
export default App;
You have a few typos there in your parent component like currectColor, just fix those first. Then, you can add the backgroundColor property to your childContainer if there is prop by checking it.
const parentContainer = {
border: "10px solid #000",
width: "500px",
height: "500px",
margin: "20px",
textAlign: "middle"
};
class App extends React.Component {
constructor() {
super();
this.state = {
currentColor: "red"
};
}
componentDidMount() {
this.setState({
currentColor: "green"
});
}
changeColor = () => {
this.setState({
currentColor: "blue"
});
};
render() {
return (
<div style={parentContainer}>
<button onClick={this.changeColor}>Blue</button>
<p>{this.state.name}</p>
<Child color={this.state.currentColor} />
</div>
);
}
}
const Child = props => {
let childContainer = {
border: "0px solid #000",
width: "300px",
height: "300px",
textAlign: "middle",
margin: "0 auto",
marginTop: "60px"
};
if ( props.color ) {
childContainer = { ...childContainer, backgroundColor: props.color }
}
return (
<div
style={childContainer}
/>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
I have created my own components, but you can apply this logic.
class Child extends React.Component {
constructor(props) {
super(props);
}
render() {
return ( <
h1 style = {
{
backgroundColor: this.props.color
}
} > hello < /h1>
)
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
color: ''
}
}
handleClick = () => {
this.setState({
color: 'red'
})
}
render() {
return ( <
div >
<
Child color = {
this.state.color
}
/> <
button onClick = {
this.handleClick
} > change Child color < /button> < /
div >
)
}
}
ReactDOM.render( <
Parent / > ,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You need change in App component. Keep currentColor to blue and change it to red in changeColor function but you are doing it in reverse
Try with below code
const parentContainer = {
border: "10px solid #000",
width: "500px",
height: "500px",
margin: "20px",
textAlign: "middle"
};
class App extends Component {
constructor() {
super();
this.state = {
currentColor: "blue"
};
}
componentDidMount() {
this.setState({
currentColor: "green"
});
}
changeColor = () => {
this.setState({
currentColor: "red"
});
};
render() {
console.log("in render", this.state);
return (
<div style={parentContainer}>
<button onClick={this.changeColor}>Blue</button>
<p>{this.state.name}</p>
<Child color={this.state.currentColor} />
</div>
);
}
}
export default App;
I am trying to make a component appear between other components. For that, I would like to create a generic wrapper able to calculate the size of its child component and create the correct animation.
So far, I succeeded (with a lot of trouble) to somehow make the component appear as expected when the size of the child element is hard coded. But It doesn't work as soon as a padding or margin is set...
See my test case here:
import React from "react";
import ReactDOM from "react-dom";
import { View, Text, TouchableOpacity } from "react-native-web";
import styled from "styled-components";
const Container = styled(View)`
flex-direction: row;
`;
//The button that will make the component appear
class Toggle extends React.PureComponent {
render() {
return (
<TouchableOpacity {...this.props}>
<Text>Press Me</Text>
</TouchableOpacity>
);
}
}
//This wrapper will carry the appearing animation
const Wrapper = styled(View)`
transition: all ${props => props.delay}s ease;
transform: scale(${props => (props.mount ? 1 : 0)});
width: ${props => (props.mount ? props.width : 0)}px;
`;
//This is the component in charge of the appearing effect
class Appearing extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
mounted: false,
render: false,
width: 0
};
}
//This will start the animation
componentDidMount() {
this.setState({ mounted: true, render: true });
}
componentDidUpdate() {
//this will start the disappearing animation
if (this.state.mounted && !this.props.mount) {
this.setState({ mounted: false });
setTimeout(
() => this.setState({ render: false }),
this.props.delay * 1000
);
//this will restart the appearing animation
} else if (!this.state.mounted && this.props.mount) {
this.setState({ mounted: true, render: true });
}
//We read the expected this of the child component
this.setState({ width: this.getWidth ? this.getWidth() : 0 });
}
render() {
return (
<Wrapper {...this.props} width={this.state.width}>
{React.cloneElement(this.props.children, {
//We read the child size with the 'onLayout' method
onLayout: event =>
(this.getWidth = () => event.nativeEvent.layout.width)
})}
</Wrapper>
);
}
}
//Carry the test case
class App extends React.PureComponent {
state = { toggle: false };
render() {
return (
<View>
{/* with only the width set */}
<Container>
<Appearing delay={0.5} mount={this.state.toggle}>
<Text style={{ width: "9em" }}>Tadaaaaaaaa !</Text>
</Appearing>
<Toggle
onPress={() => this.setState({ toggle: !this.state.toggle })}
/>
</Container>
{/* with the width and padding set */}
<Container>
<Appearing delay={0.5} mount={this.state.toggle}>
<Text style={{ width: "9em", paddingLeft: "10em" }}>
Tadaaaaaaaa !
</Text>
</Appearing>
<Toggle
onPress={() => this.setState({ toggle: !this.state.toggle })}
/>
</Container>
</View>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Do you know the best way to achieve that?