I have a 4 text fields which are meant to be used to type in a 4 digit code sent to the phone. How can I automatically change to the next field if a number is written and for it not to take anything apart from numbers
Ill attach a picture along with my code base
// flow
import React, { useRef } from 'react';
import { signup } from '../../assets/images';
import FormDiv from '../shared/Sign-in-div';
import ImageDiv from '../shared/Image-div';
import { Nunito32, Nunito20 } from '../shared/nunito/nunito';
import ImageContainer from '../shared/image-container';
import OtpField from '../shared/otp-field';
import PinkButton from '../shared/button-color-pink';
let [fieldOne, fieldTwo, fieldThree, fieldFour] = useRef(null);
const onChange = field => {
field.focus();
};
const SignUpVerification = () => (
<div style={{ display: 'flex' }}>
<FormDiv style={{ textAlign: 'center' }}>
<Nunito32
style={{
display: 'inline-block',
textAlign: 'center',
marginRight: 236,
marginLeft: 200,
}}
>
Verify your mobile number by entering the code we sent you
</Nunito32>
<div style={{ flexDirection: 'row' }}>
<OtpField
ref={input => {
fieldOne = input;
}}
style={{ marginRight: 10.5 }}
onChange={() => onChange(fieldTwo)}
/>
<OtpField
ref={input => {
fieldTwo = input;
}}
onChange={() => onChange(fieldThree)}
style={{ marginRight: 10.5 }}
/>
<OtpField
ref={input => {
fieldThree = input;
}}
onChange={() => onChange(fieldFour)}
style={{ marginRight: 10.5 }}
/>
<OtpField
ref={input => {
fieldFour = input;
}}
style={{ marginRight: 10.5 }}
/>
</div>
<PinkButton style={{ marginTop: 75 }}>Continue</PinkButton>
<Nunito20>Send again</Nunito20>
</FormDiv>
<ImageContainer>
<ImageDiv bg={signup} src={signup} alt="logo" />
</ImageContainer>
</div>
);
export default SignUpVerification;
It now gives me 2 errors that fieldOne is created but not used and ×
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
How about re-render when the state you change?
Handling focus is good task for Refs in React. So idea will be to have refs for input fields and in onChange event handler check if user typed 3 digits and turn focus to next input.
I have created demo on codesandbox to showcase how it works
Since you are making use of React JS, you can go forward with React Refs and the DOM where you can select the nodes and handle the focus pragmatically. This is a sample implementation. Find the implementation here.
class App extends React.Component{
componentDidMount(){
this.fieldOne.focus();
}
onChange(field) {
field.focus();
}
render() {
return(
<div>
<input
onChange={() => this.onChange(this.fieldTwo)}
ref={(input) => { this.fieldOne = input; }}
placeholder="First Field"
/>
<input
onChange={() => this.onChange(this.fieldThree)}
ref={(input) => { this.fieldTwo = input; }}
placeholder="Second Field"
/>
<input
onChange={() => this.onChange(this.fieldFour)}
ref={(input) => { this.fieldThree = input; }}
placeholder="Third Field"
/>
<input
ref={(input) => { this.fieldFour = input; }}
placeholder="Fourth Field"
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.1/react-dom.min.js"></script>
<div class="container-fluid" id="main">
<div class="row">
<div class="col-xs-12">
<div id="root"></div>
</div>
</div>
</div>
Related
I have a react component that dynamically loads a widget component using react lazy, with the component path passed as a prop.
It renders fine, but when I drag it, the component flickers between its Suspense fallback and the fully rendered component. How can I prevent the Suspense fallback from being shown while dragging?
The draggable list looks like this:
<DragDropContext
onDragEnd={result => {
console.log(result);
reorder({ result, previousData: dashboard.data });
}}
>
<Title title={`Dashboard`} />
<Droppable droppableId={"dashboard"}>
{(
provided
// snapshot
) => {
return (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{
display: "flex",
flexDirection: "column"
}}
>
{Array.isArray(dashboardItems.data) && dashboardItems.data.length > 0 ? (
dashboardItems.data.map((item: any, index: number) => {
return (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => {
return (
<div ref={provided.innerRef} {...provided.draggableProps}>
<WidgetCard item={item} dragHandleProps={provided.dragHandleProps} />
{!snapshot.isDragging && <AddWidgetControl />}
</div>
);
}}
</Draggable>
);
})
) : (
<Button
onClick={() =>
addDashboardItem.mutate({
index: 0,
dashboardItem: widgets.overview
})
}
>
<Typography variant="body2">Add</Typography>
</Button>
)}
{provided.placeholder}
</div>
);
}}
</Droppable>
</DragDropContext>
and the WidgetCard component that conditionally renders the widgets using lazy looks like this:
const WidgetCard = ({
item,
dragHandleProps
}: {
item: DashboardItemEntity,
dragHandleProps?: any
}) => {
{...}
const renderLoader = () => <p>Loading</p>;
const WidgetComponent = lazy(() => import(`../${item.component}`));
{...}
return (
{...}
<CardContent sx={{ marginTop: 0, paddingTop: 0 }}>
{/* {description} */}
<Box sx={{ marginLeft: 2 }}>
<Suspense fallback={renderLoader()}>
<WidgetComponent item={item} />
</Suspense>
</Box>
</CardContent>
{...}
);
};
I'm trying to target the span, but haven't been able to do so. I want to be able to change the background color of the span when the checkbox is checked.
<div className={classes.container}>
<input type="checkbox" id="checkboxid" />
<label className={classes.label} htmlFor="checkboxid">
<span className={classes.labelText}>Target</span>
</label>
</div>
container: {
'& input:checked': {
'& label': {
'& $labelText': {
background: 'red'
}
}
}
}
While label is not inside the input but a sibiling you need to make use of the css sibling selector +
In your context
const useSpanStyles = makeStyles({
container: {
'& input:checked + label': {
'& span': {
background: 'red'
}
},
},
label: {},
labelText: {}
});
export function ComponentXYZ(){
const classes = useSpanStyles();
return (
<div className={classes.container}>
<input type="checkbox" id="checkboxid" />
<label className={classes.label} htmlFor="checkboxid">
<span className={classes.labelText}>Target</span>
</label>
</div>
);
}
To be honest with you, if you are using MUI you should've used their components as its easier to compose and build UI with
Here's my suggestion
function ComponentXYZ(){
const [checked, setIsChecked] = useState(false);
const checkedHandler = useCallback(function _checkedHandler(event: any) {
setIsChecked(event.target.checked);
}, []);
return (
<div>
<FormGroup>
<FormControlLabel
control={<Checkbox
checked={checked}
onChange={checkedHandler}
/>}
label={
<Typography style={{ background: checked ? 'red' : 'inherit' }}>
{'Label That change color'}
</Typography>
}
/>
</FormGroup>
</div>
);
}
I am currently designing a login page using ant design in React. I tried using the grid system to design the login page. However, I am stuck with this issue where my columns are too far apart from one another. I would like to close the gap between them. Below is the screenshot of my issue:
Below is my code
import React from 'react'; import { Row, Alert, Col, Form, Input, Button, Checkbox, Card } from 'antd'; import { UserOutlined, MailOutlined, LockOutlined } from '#ant-design/icons';
const Register = () => { const onSubmit = (values) => {};
return (
<>
<Row
justify='center'
align='middle'
style={{ height: '100vh', flexWrap: 'wrap' }}
>
<Row style={{ width: '100%' }} justify='center'>
<Col xs={18} md={8}>
<Alert type='error' message='User already exist' banner />
</Col>
</Row>
<Col xs={18} md={8} style={{ width: '100%' }}>
<Card className='login-card'>
<Form
name='normal_login'
className='login-form'
initialValues={{
remember: true,
}}
onFinish={onSubmit}
>
<h1 id='signin-header'>Register</h1>
<Form.Item
name='name'
rules={[
{
required: true,
message: 'Please input your name!',
},
]}
hasFeedback
>
<Input
prefix={<UserOutlined className='site-form-item-icon' />}
placeholder='Name'
/>
</Form.Item>
<Form.Item
name='email'
rules={[
{
required: true,
message: 'Please input your email!',
},
{
type: 'email',
message: 'Please input a valid email!',
},
]}
hasFeedback
>
<Input
prefix={<MailOutlined className='site-form-item-icon' />}
placeholder='Email'
/>
</Form.Item>
<Form.Item
name='password'
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
hasFeedback
>
<Input.Password
placeholder='Password'
prefix={<LockOutlined className='site-form-item-icon' />}
/>
</Form.Item>
<Form.Item>
<Form.Item name='remember' valuePropName='checked' noStyle>
<Checkbox>Remember me</Checkbox>
</Form.Item>
</Form.Item>
<Form.Item>
<Button type='primary' htmlType='submit' block>
Register
</Button>
<div id='register-text'>
Arleady have an account? Login now!
</div>
</Form.Item>
</Form>
</Card>
</Col>
</Row>
</> ); };
export default Register;
Try to use alignItems: 'stretch' in your first row.
...
<Row
justify='center'
align='middle'
style={{ height: '100vh', flexWrap: 'wrap', alignItems: 'stretch' }}
>
<Row style={{ width: '100%', marginBottom: '10px' }} justify='center' align="bottom">
...
Working CodeSandBox
I am trying to make a popup window with a description for the project whenever someone clicks the description button.
I can't figure out how to do it. I have looked for components in react-mdl but I don't know how to insert it to my program.
The hirarchy of the button is:
-App
---NAVBAR
---Pages
-------Projects
---------ProjectCard
------------description button
I have tried to integrate components from react-mdl, semantic-ui etc, but I couldn't figure out how to adapt it to my program.
Thanks in advance guys!
import React from "react";
import { Layout, Content } from "react-mdl";
import Pages from "./Pages";
import { NavBar } from "./NavBar";
import { LeftDrawer } from "./LeftDrawer";
class App extends React.Component {
render() {
return (
<div>
<Layout>
<NavBar />
<LeftDrawer />
<Content className="app-content">
<Pages />
</Content>
</Layout>
</div>
);
}
}
export default App;
import React from "react";
import { Tabs, Tab } from "react-mdl";
import { CProjects } from "./CProjects";
import { ReactProjects } from "./ReactProjects";
import { SwiftProjects } from "./SwiftProjects";
import { TypescriptProjects } from "./TypescriptProjects";
import { JavaProjects } from "./JavaProjects";
import { CPPProjects } from "./CPPProjects";
import { PythonProjects } from "./PythonProjects";
import { AssemblyProjects } from "./AssemblyProjects";
class Projects extends React.Component {
state = { activeTab: 0 };
handleChange = tabId => {
this.setState({ activeTab: tabId });
};
toggleCategiries = () => {
switch (this.state.activeTab) {
case 0:
return (
<div className="react-projects">
<ReactProjects />
</div>
);
case 1:
return (
<div className="typescript-projects">
<TypescriptProjects />
</div>
);
case 2:
return (
<div className="java-projects">
<JavaProjects />
</div>
);
case 3:
return (
<div className="c-projects">
<CProjects />
</div>
);
case 4:
return (
<div className="c++-projects">
<CPPProjects />
</div>
);
case 5:
return (
<div className="swift-projects">
<SwiftProjects />
</div>
);
case 6:
return (
<div className="python-projects">
<PythonProjects />
</div>
);
case 7:
return (
<div className="assembly-projects">
<AssemblyProjects />
</div>
);
default:
return <div>lala</div>;
}
};
render() {
return (
<div className="page">
<div className="categories">
<Tabs
activeTab={this.state.activeTab}
onChange={this.handleChange}
ripple
>
<Tab className="tab">React</Tab>
<Tab className="tab">TypeScript</Tab>
<Tab className="tab">Java</Tab>
<Tab className="tab">C</Tab>
<Tab className="tab">C++</Tab>
<Tab className="tab">Swift</Tab>
<Tab className="tab">Python</Tab>
<Tab className="tab">Assembly</Tab>
</Tabs>
{this.toggleCategiries()}
</div>
</div>
);
}
}
export default Projects;
import React from "react";
import {
Card,
CardTitle,
CardActions,
Button,
CardMenu,
IconButton,
CardText
} from "react-mdl";
import { Link } from "react-router-dom";
class ProjectCard extends React.Component {
render() {
const titleStyle = {
backgroundImage: "url(" + this.props.background + ")",
backgroundSize: "100% 100%",
color: "#fff",
height: "176px"
};
return (
<div>
<Card shadow={6} style={{ borderRadius: "6px" }}>
<CardTitle style={titleStyle}>{this.props.name}</CardTitle>
<CardText>{this.props.shortDescription}</CardText>
<CardActions border>
<div style={{ display: "flex", justifyContent: "center" }}>
<a href={this.props.github} target="_blank">
<Button colored>GitHub</Button>
</a>
<Button colored>Description</Button>
</div>
</CardActions>
<CardMenu style={{ color: "#fff" }}>
<IconButton name="share" />
</CardMenu>
</Card>
</div>
);
}
}
export default ProjectCard;
import React from "react";
import { Spring } from "react-spring/renderprops";
import ProjectCard from "./ProjectCard";
import backgroundImage from "../../additional-files/images/React_background.png";
export const ReactProjects = () => {
return (
<Spring
config={{ duration: 1000 }}
from={{ opacity: 0 }}
to={{ opacity: 1 }}
>
{props => (
<div style={props}>
<div className="projects">
<div className="project">
<ProjectCard
name="Lab1"
shortDescription="Encoder and Debug mode"
description="This is the desired description in Modal"
github="https://github.com/avishaiyaniv605/Computer-Architectue-Lab1"
background={backgroundImage}
/>
</div>
<div className="project">
<ProjectCard
name="Lab1"
shortDescription="Encoder and Debug mode"
description="This is the desired description in Modal"
github="https://github.com/avishaiyaniv605/Computer-Architectue-Lab1"
background={backgroundImage}
/>
</div>
<div className="project">
<ProjectCard
name="Lab1"
shortDescription="Encoder and Debug mode"
description="This is the desired description in Modal"
github="https://github.com/avishaiyaniv605/Computer-Architectue-Lab1"
background={backgroundImage}
/>
</div>
</div>
</div>
)}
</Spring>
);
};
I managed to do it with a Dialog component of evergreen ui.
Inserted it where the Description button was and inside it, I inserted the button
import React from "react";
import {
Card,
CardTitle,
CardActions,
Button,
CardMenu,
IconButton,
CardText
} from "react-mdl";
import Component from "#reach/component-component";
import { Pane, Dialog } from "evergreen-ui";
class ProjectCard extends React.Component {
state = {
active: false
};
handleToggle = () => {
this.setState({ active: !this.state.active });
};
actions = [
{ label: "Cancel", onClick: this.handleToggle },
{ label: "Save", onClick: this.handleToggle }
];
render() {
const titleStyle = {
backgroundImage: "url(" + this.props.background + ")",
backgroundSize: "100% 100%",
color: "#fff",
height: "176px"
};
return (
<div>
<Card shadow={6} style={{ borderRadius: "6px" }}>
<CardTitle style={titleStyle}>{this.props.name}</CardTitle>
<CardText>{this.props.shortDescription}</CardText>
<CardActions border>
<div style={{ display: "flex", justifyContent: "center" }}>
<a href={this.props.github} target="_blank">
<Button colored>GitHub</Button>
</a>
<Component initialState={{ isShown: false }}>
{({ state, setState }) => (
<Pane>
<Dialog
isShown={state.isShown}
title={this.props.name + " description"}
onCloseComplete={() => setState({ isShown: false })}
confirmLabel="close"
hasFooter={false}
>
<Pane height={1800} width="100%" backgroundColor="#ddd" style={{ borderRadius: '6px' }}>
<div style={{ padding: "1vw 0 0 1vw" }}>
{this.props.description}
</div>
</Pane>
</Dialog>
<Button colored onClick={() => setState({ isShown: true })}>
Description
</Button>
</Pane>
)}
</Component>
</div>
</CardActions>
<CardMenu style={{ color: "#fff" }}>
<IconButton name="share" />
</CardMenu>
</Card>
</div>
);
}
}
export default ProjectCard;
I'm using MaterialUI's tabs in my React project.
This is the JSX for the tabs:
<AppBar color="default" position="static">
<Tabs indicatorColor="primary" textColor="primary" value={tabIndex} onChange={this.handleChange}>
{instances.map(instance =>
<StyledTab
style={{ textTransform: 'initial' }}
onClick={() => { this.changeActiveInstance(instance.id) }}
label={this.getTabAddress(instance)}
icon={<ClearIcon ></ClearIcon>}
>
</StyledTab>
)}
</Tabs>
This is how i inject the css:
const StyledTab = withStyles({
root: {
textTransform: 'initial'
},
})(Tab);
The result is this:
I would like to position the "ClearIcon" elsewhere. I tried playing with the style injection a bit, with no success.
Can somebody point me to the right direction?
When trying to customize any Material-UI component, the starting point is the CSS portion of the API documentation. The most relevant classes that you may want to override in this case are wrapper, labelContainer, and label.
The best way to fully understand how these are used and how they are styled by default (and therefore what you may want to override) is to look at the source code.
Here are the most relevant portions of the styles from Tab.js:
/* Styles applied to the `icon` and `label`'s wrapper element. */
wrapper: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
flexDirection: 'column',
},
/* Styles applied to the label container element if `label` is provided. */
labelContainer: {
width: '100%', // Fix an IE 11 issue
boxSizing: 'border-box',
padding: '6px 12px',
[theme.breakpoints.up('md')]: {
padding: '6px 24px',
},
},
And here is the relevant code for understanding how these are used:
if (labelProp !== undefined) {
label = (
<span className={classes.labelContainer}>
<span
className={classNames(classes.label, {
[classes.labelWrapped]: this.state.labelWrapped,
})}
ref={ref => {
this.labelRef = ref;
}}
>
{labelProp}
</span>
</span>
);
}
<span className={classes.wrapper}>
{icon}
{label}
</span>
Below are some examples of possible ways to customize this.
import React from "react";
import PropTypes from "prop-types";
import Paper from "#material-ui/core/Paper";
import { withStyles } from "#material-ui/core/styles";
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import PhoneIcon from "#material-ui/icons/Phone";
import FavoriteIcon from "#material-ui/icons/Favorite";
import PersonPinIcon from "#material-ui/icons/PersonPin";
const styles = {
root: {
flexGrow: 1,
maxWidth: 700
},
firstIcon: {
paddingLeft: 70
},
labelContainer: {
width: "auto",
padding: 0
},
iconLabelWrapper: {
flexDirection: "row"
},
iconLabelWrapper2: {
flexDirection: "row-reverse"
}
};
class IconLabelTabs extends React.Component {
state = {
value: 0
};
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { classes } = this.props;
return (
<Paper square className={classes.root}>
<Tabs
value={this.state.value}
onChange={this.handleChange}
variant="fullWidth"
indicatorColor="secondary"
textColor="secondary"
>
<Tab
icon={<PhoneIcon className={classes.firstIcon} />}
label="Class On Icon"
/>
<Tab
classes={{
wrapper: classes.iconLabelWrapper,
labelContainer: classes.labelContainer
}}
icon={<FavoriteIcon />}
label="Row"
/>
<Tab
classes={{
wrapper: classes.iconLabelWrapper2,
labelContainer: classes.labelContainer
}}
icon={<PersonPinIcon />}
label="Row-Reverse"
/>
<Tab icon={<PersonPinIcon />} label="Default" />
</Tabs>
</Paper>
);
}
}
IconLabelTabs.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(IconLabelTabs);
We have a inbuilt property to set the icon position of tab in material ui. Document link
iconPosition:'bottom' | 'end' | 'start' | 'top'