Styled components for nested html elements (React) - reactjs

I am new to styled-components, and want to know how you would write it given the following html snippet:
<div class="segmentedControlContainer">
<input type="radio" name="segmentedControlExample" value="1" id="1" />
<label for="1"> One </label>
<input type="radio" name="segmentedControlExample" value="2" id="2" />
<label for="2"> Two </label>
<input type="radio" name="segmentedControlExample" value="3" id="3" />
<label for="3"> Three </label>
<div>
so far, I have defined
export const SegmentedControlWrapper = styled.div`
display: flex;
width: 100%;
position: relative;
z-index: 1;
user-select: none;
margin: 0 auto;
font-size: 16px;
border-radius: 3px;
border: solid 1px #bcbcbc
`
export const Input = styled.input`
display: none;
&:checked + label {
color: #fff;
background: #blah;
}
`
export const Label = styled.label`
flex: 1;
color: #blah;
padding: 15px;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
&:checked {
}
&:not(:last-child){
....
}
`
and use it in react as:
<SegmentedControlWrapper>
<Input />
<Label />
</SegmentedControlWrapper>
Most of this is correct, and I think the checked state isn't styled propelry. Any pointer would be appreciated. As I am confused with using &, >, etc.

Pass checked or not checked as props to style class. It will help to style in good way.
export const Input = styled.input
display: none;
&:checked + label {
color: #fff;
background: {$props => {this.props.checked ? "some" : "some"}}
}
<Input checked={this.state.checked}/>

Related

React Hook Form - onSubmit does not works

I have following component. I am making this based on react-hook-form documentation. Additionally I add styled components. But I find out problem with button. Submit button does not works. Nothing happen when I click on it
import styled from 'styled-components';
import { useForm } from "react-hook-form";
export const OrderDetailsForm = () => {
const { register, handleSubmit } = useForm();
const onSubmit = (data: any) => console.log(data);
return (
<OrderDetailsFormContainer>
<OrderForm onSubmit={handleSubmit(onSubmit)}>
<OrderDetailsFormContent>
<label>First Name</label>
<OrderDetailsFormInput {...register("firstName")} />
<label>Last Name</label>
<OrderDetailsFormInput {...register("lastName")} />
<label>Phone number</label>
<OrderDetailsFormInput {...register("phoneNumber")} />
<label>Email</label>
<OrderDetailsFormInput {...register("emailAddress")} />
<OrderDetailsFormHeader>Contact details</OrderDetailsFormHeader>
</OrderDetailsFormContent>
<OrderDetailsFormContent>
<label>Street</label>
<OrderDetailsFormInput {...register("street")} />
<label>House number</label>
<OrderDetailsFormInput {...register("houseNumber")} />
<label>City</label>
<OrderDetailsFormInput {...register("city")} />
<label>ZIP code</label>
<OrderDetailsFormInput {...register("zipCode")} />
<OrderDetailsFormHeader>Address</OrderDetailsFormHeader>
</OrderDetailsFormContent>
<input type='submit' />
</OrderForm>
</OrderDetailsFormContainer>
)
}
const OrderDetailsFormContainer = styled.main`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
`
const OrderForm = styled.article`
display: flex;
justify-content: center;
align-items: center;
width: 1200px;
`
const OrderDetailsFormContent = styled.section`
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
border: 1px solid #000;
box-sizing: border-box;
margin: 0 25px;
width: 50%;
padding: 30px 0 20px 20px;
position: relative;
`
const OrderDetailsFormInput = styled.input`
padding: 10px 40px;
margin: 15px 0;
`
const OrderDetailsFormHeader = styled.h1`
position: absolute;
top: -4%;
left: 4%;
margin: 0;
background-color: #fff;
padding: 0 20px;
font-size: 20px;
`
const Button = styled.button`
background-color: black;
color: white;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
`
Sorry for adding this, but it throws an error It looks like your post is mostly code; please add some more details. But I don't know what I can add more to this post.
Your issue is that you don't have a <form/> element.
Your <OrderForm/> component is rendering an <article/> element - this doesn't have an onSubmit prop, which is why the submission isn't working.
Change styled.article to styled.form here:
const OrderForm = styled.form`
const OrderForm = styled.article`
this line will generate an article element
and you know, article tag does not have onsubmit event.
change this line to:
const OrderForm = styled.form
good luck.

React(Styled Components)Navbar link not working

I am trying to allow the navbar to take you to each part of the website but it isnt working for some reason. It is only a one page website and I have another up & running website with the same Example it takes me right to the section, but on this website it just doesnt seem to work does anyone have a clue? Heres my code from navbar.jsx and a link to the github
https://github.com/Justin7933/chidgo
import React from 'react';
import styled from 'styled-components';
const Container = styled.div`
height: 50px;
`;
const Wrapper = styled.div`
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: space-between;
`;
const Left = styled.div`
width: 60%;
display: flex;
align-content: center;
justify-content: space-between;
`;
const Logo = styled.h1`
font-weight: bold;
text-decoration: underline crimson;
`;
const Menu = styled.nav`
display: flex;
list-style: none;
cursor: pointer;
#media only screen and (max-width: 480px) {
display: none;
}
`;
const MenuItem = styled.a`
margin-right: 30px;
font-size: 20px;
font-weight: bold;
color: gray;
text-decoration: none;
`;
const Button = styled.button`
border:2px solid white;
padding: 10px 15px;
background-color: crimson;
color: white;
font-weight: bold;
border-radius: 10px;
cursor: pointer;
`;
const Navbar = () => {
return (
<Container>
<Wrapper>
<Left>
<Logo>chidgo</Logo>
<Menu>
<MenuItem href="#intro">Home</MenuItem>
<MenuItem href="feature">Features</MenuItem>
<MenuItem href="#service">Services</MenuItem>
<MenuItem href="#price">Pricing</MenuItem>
<MenuItem href="#contact">Contact</MenuItem>
</Menu>
</Left>
<Button>JOIN TODAY</Button>
</Wrapper>
</Container>
)
}
export default Navbar
To be honest, I dont master the way that you coded yet, so I might embarrass mysef for lack of knowledge, but, have being said that:
Are you not forgeting to wrapp the proprer places with a < section id="">? Like is show here in the code of your contact componet:
<Container>
==>>>> <section id="contact">
<Wrapper>
<FormContainer>
<Title>
Questions? <br /> Let's Get In Touch
</Title>
<Form onSubmit={onSubmit}>
<LeftForm>
<Input name="from_name" value={toSend.from_name}
onChange={handleChange} placeholder="Your Name" />
<Input name="reply_to" value={toSend.reply_to}
onChange={handleChange} placeholder="Your Email" />
<Input placeholder="Subject" />
</LeftForm>
<RightForm>
<textarea name="message" className="TextArea" maxLength="100" value={toSend.message}
onChange={handleChange} placeholder="Your Message"/>
<Button type="submit">Send</Button>
</RightForm>
</Form>
</FormContainer>
<AddressContainer>
<AddressItem>
<Icon src={Map} />
<Text>Plymouth County, Hanson, Massachusetts</Text>
</AddressItem>
<AddressItem>
<Icon src={Phone} />
<Text>+7812175728</Text>
</AddressItem>
<AddressItem>
<Icon src={Send} />
<Text>damon.justin#outlook.com</Text>
</AddressItem>
</AddressContainer>
</Wrapper>
===>>> </section>
</Container>
At least, I had looked for thoose "targets" from your navebar and I have not found them in any file.

How do I Setup a excel like filter using react-data-table-component

Been searching on how to make a excel like filter using react-data-table-component, and found something interesting, like Data Table filtering using react-data-table-component.
Unfortunately, the FilterComponent Component seems to be deprecated, since I can't find anything regarding it but broken links, which is weird for such a interesting feature.
My code is the following:
const columns = Properties.columns;
const getSubHeaderComponent = () => {
return (
<FilterComponent
onFilter={(e) => {
let newFilterText = e.target.value;
filteredItems = statements.filter(
(item) =>
item.name &&
item.name.toLowerCase().includes(newFilterText.toLowerCase())
);
this.setState({ filterText: newFilterText });
}}
onClear={handleClear}
filterText={filterText}
/>
);
};
return (
<div>
<div className="row justify-content-md-center statements-table">
<div className="col-md-10">
<DataTable
columns={columns}
data={statements}
customStyles={Properties.customStyles}
fixedHeader
fixedHeaderScrollHeight="47em"
pagination
subheader
subHeaderComponent={getSubHeaderComponent()}
paginationPerPage={100}
paginationRowsPerPageOptions={[100, 500, 1000]}
subHeader
noHeader
/>
</div>
</div>
Any suggestions?
FilterComponent could be something as simple as
const FilterComponent = ({ filterText, onFilter, onClear }) => (
<div>
<input
type="text"
value={filterText}
onChange={onFilter}
/>
<button type="button" onClick={onClear}>
X
</button>
</div>
);
However, I found following official implementation of FilterComponent on Examples/Filtering | React Data Table Components (also referred Button.js) if you need it like that.
const TextField = styled.input`
height: 32px;
width: 200px;
border-radius: 3px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border: 1px solid #e5e5e5;
padding: 0 32px 0 16px;
&:hover {
cursor: pointer;
}
`;
const ButtonStyle = styled.button`
background-color: #2979ff;
border: none;
color: white;
padding: 8px 32px 8px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 3px;
&:hover {
cursor: pointer;
}
`;
const Button = ({ children, ...rest }) => <ButtonStyle {...rest}>{children}</ButtonStyle>;
const ClearButton = styled(Button)`
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
height: 34px;
width: 32px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
`;
const FilterComponent = ({ filterText, onFilter, onClear }) => (
<>
<TextField
id="search"
type="text"
placeholder="Filter By Name"
aria-label="Search Input"
value={filterText}
onChange={onFilter}
/>
<ClearButton type="button" onClick={onClear}>
X
</ClearButton>
</>
);

styled-components for input type password

how can I give styles for input type='password' in styled-components?
// export const Input = styled.input`
// width: 100%;
// height: 50px;
// border-radius: 4px;
// background-color: rgba(104, 105, 102, 0.1);
// border: 1px solid #354545;
// margin-top: 20px;
// outline: none;
// padding-left: 40px;
// color: white;
// font-size: 22px;
// `;
This should work. Unlike normal css, styled-components takes the attribute as props. You'll need to use props to style the elements conditionally.
export const Input = styled.input`
${props => props.type === 'password' && `
width: 100%;
height: 50px;
border-radius: 4px;
background-color: rgba(104, 105, 102, 0.1);
border: 1px solid #354545;
margin-top: 20px;
outline: none;
padding-left: 40px;
color: white;
font-size: 22px;
`}
`;
From styled-components documentation FAQ:
export const PasswordInput = styled.input.attrs(props => ({
// Every <PasswordInput /> should be type="password"
type: "password"
}))`
width: 100%;
height: 50px;
border-radius: 4px;
background-color: rgba(104, 105, 102, 0.1);
border: 1px solid #354545;
margin-top: 20px;
outline: none;
padding-left: 40px;
color: white;
font-size: 22px;`;
Both examples are a bit overkill for just styling purposes and can be easily avoided by using &[type="password"]
import styled from "styled-components";
export const Input = styled.input`
&[type="password"] {
border: 1px solid black;
background: red;
}
`;
export default function App() {
return (
<div>
<div>
<label htmlFor="username">Username</label>
<Input id="username" type="text" />
</div>
<div>
<label htmlFor="password">Password</label>
<Input type="password" />
</div>
</div>
);
}
Or, if you want to extend of of a base input component
import styled from "styled-components";
export const Input = styled.input`
border: 1px solid black;
`;
export const PasswordInput = styled(Input)`
&[type="password"] {
background: red;
}
`;
export default function App() {
return (
<div>
<div>
<label htmlFor="username">Username</label>
<Input id="username" type="text" />
</div>
<div>
<label htmlFor="password">Password</label>
<PasswordInput type="password" />
</div>
</div>
);
}

How can I style react-datepicker?

I'm using webpack, react-datepicker and have managed to import its css with the provided css module.
import 'react-datepicker/dist/react-datepicker-cssmodules.css
The component looks fine and dandy, but now I want to make it full width like the time element above it.
Looking at the CSS, what it needs is for the react-datepicker-wrapper element that gets dynamically added by the library to have display: block. Any modifications I make to react-datepicker-wrapper in my own css does nothing.
What should I do?
date-picker.component.jsx
import React from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker-cssmodules.css';
import './date-picker.component.bootstrap.css';
// eslint-disable-next-line no-confusing-arrow
const buildClassNames = (touched, isInvalid) =>
touched && isInvalid ? 'form-control is-invalid' : 'form-control';
export const DatePickerBootstrap = (props) => {
const { setFieldValue, setFieldTouched, errors, touched } = props;
const { name, value, label, ...rest } = props;
return (
<div className="form-group">
<label className='datePickerLabel' htmlFor={name}>{label}</label>
<DatePicker
selected={value}
onChange={(e) => {
setFieldValue(name, e);
setFieldTouched(name);
}}
className={buildClassNames(touched, !!errors)}
customInput={
<input
type="text"
id={name}
placeholder={label} />
}
{...rest}
/>
<div className="invalid-feedback">
{errors}
</div>
</div>
);
};
export default DatePickerBootstrap;
From https://github.com/Hacker0x01/react-datepicker/issues/2099#issuecomment-704194903
Try with wrapperClassName property:
<DatePicker wrapperClassName="datePicker" dateFormat="dd/MM/yyyy" />
CSS:
.datePicker {
width: 100%;
}
This way you won't modify the styles for the whole app
styled-components bonus:
import React from 'react';
import styled, { css, createGlobalStyle } from 'styled-components';
import DatePicker from 'react-datepicker';
const DatePickerWrapperStyles = createGlobalStyle`
.date_picker.full-width {
width: 100%;
}
`;
<>
<DatePicker wrapperClassName='date_picker full-width' />
<DatePickerWrapperStyles />
</>
I think you're just missing some CSS. Try this in your custom stylesheet (anywhere after the datepicker's stylesheet):
.react-datepicker-wrapper,
.react-datepicker__input-container,
.react-datepicker__input-container input {
display: block;
width: 100%;
}
Demo
styled-components
<>
<DatePickerWrapper
popperContainer={Popper}
calendarContainer={Calendar}
/>
</>
const DatePickerWrapper = styled(({ className, ...props }) => (
<DatePicker {...props} wrapperClassName={className} />
))`
width: 100%;
`;
const Calendar = styled.div`
border-radius: 10px;
box-shadow: 0 6px 12px rgba(27, 37, 86, 0.16);
overflow: hidden;
`;
const Popper = styled.div`
position: absolute;
top: 0;
left: 0;
z-index: 2;
`;
You can get your css work by putting !important at the end of the lines:
display: block !important;
And, you should import your css file at the end:
import 'library0.css';
import 'library1.css';
import 'library2.css';
import 'yourCss.css'; // Your css
overwrite the default css like
.react-datepicker__input-container input {
width: 100%;
}
working example
You can put it inside a flexbox.
If you are using bootstrap, you can use the d-flex and flex-column classes on the wrapper element.
<div className="d-flex flex-column">
<DatePickerField name="date" label="Date" />
</div>
If not, you can style the wrapper using CSS properties.
<div className="date-picker-wrapper">
<DatePickerField name="date" label="Date" />
</div>
CSS:
.date-picker-wrapper {
display: flex !important;
flex-direction: column !important;
}
You can add to the style sheet:
.react-datepicker__input-container{
input{
width: 100%;
padding: 0.375rem 2.25rem 0.375rem 0.75rem;
-moz-padding-start: calc(0.75rem - 3px);
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
background-color: #fff;
border: 1px solid #ced4da;
border-radius: 0.25rem;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
appearance: none;
}
}
Output
You can use the class of each element of the picker to override its default style, using the inspect tool you can identify each element's class, if your new style won't be applied you can use the !important property to override the default style
The following code is applied to most of the pickers elements
.react-datepicker__triangle {
display: none;
}
.react-datepicker__day.react-datepicker__day--keyboard-selected {
border: none;
border-radius: 7px;
background-color: var(--dark);
color: var(--white);
}
.react-datepicker__day.react-datepicker__day--keyboard-selected:hover {
border: none;
border-radius: 7px;
background-color: var(--dark);
color: var(--white);
}
.react-datepicker-popper .react-datepicker__navigation {
padding-top: 12px;
color: #000;
}
.react-datepicker {
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.189);
border: none !important;
font-family: "Inter" !important;
}
.react-datepicker__header {
border-bottom: solid 5px var(--light) !important;
background: white !important;
}
.react-datepicker__current-month {
color: var(--dark) !important;
}
.react-datepicker__day.react-datepicker__day--today {
border-radius: 7px;
border: solid 2px var(--brand) !important;
background-color: white !important;
color: var(--dark) !important;
width: 30px;
height: 30px;
}
.react-datepicker__day.react-datepicker__day--selected {
border: none;
border-radius: 7px;
background-color: black;
color: white;
}
.react-datepicker__day--selected:hover,
.react-datepicker__day--in-selecting-range:hover,
.react-datepicker__day--in-range:hover,
.react-datepicker__month-text--selected:hover,
.react-datepicker__month-text--in-selecting-range:hover,
.react-datepicker__month-text--in-range:hover,
.react-datepicker__quarter-text--selected:hover,
.react-datepicker__quarter-text--in-selecting-range:hover,
.react-datepicker__quarter-text--in-range:hover,
.react-datepicker__year-text--selected:hover,
.react-datepicker__year-text--in-selecting-range:hover,
.react-datepicker__year-text--in-range:hover {
border: none;
border-radius: 7px !important;
background-color: var(--brand) !important;
color: var(--dark) !important;
}
From https://github.com/Hacker0x01/react-datepicker/issues/2099#issuecomment-704194903
Try
<DatePicker calendarClassName={/* styles */}></DatePicker>

Resources