I am using react-typescript for my app. For styling I am using Style component. I have decided I will create my custom Hooks Input and Password input. So I first created Input wrapper where I added necessary input fields. After that I have created Password input field. i extended my Password input component props with Input component props. But when I am using Input component wrapper to my password component. I am getting error: This JSX tag's 'children' prop expects a single child of type 'Element | undefined', but multiple children were provided.
I don't know what I am doing wrong.
This is my Input wrapper component
import React from "react";
import styled from "styled-components";
import ErrorBoundary from "components/errorBoundary";
const Container = styled.div`
position: relative;
`;
const Label = styled.label<{ minimized?: boolean }>`
display: block;
color: ${({ theme }) => theme.inputLabelColor};
font-weight: 400;
font-size: ${({ minimized }) => (minimized ? "11px" : "16px")};
margin-bottom: 5px;
letter-spacing: -0.2px;
position: absolute;
transform: translateY(${({ minimized }) => (minimized ? "9px" : "16px")});
left: 20px;
top: 0;
pointer-events: none;
transition: transform 150ms linear, font-size 150ms linear;
`;
const Error = styled.p`
color: ${({ theme }) => theme.errorTextColor};
`;
const Description = styled.p`
color: blue;
`;
export interface IInputWrapperProps {
label?: string;
required?: boolean;
minimizedLabel?: boolean;
description?: string;
error?: string;
wrapperStyle?: React.CSSProperties;
children?: JSX.Element;
}
export default ({
label,
error,
description,
children,
required,
wrapperStyle,
minimizedLabel
}: IInputWrapperProps) => {
return (
<ErrorBoundary id="InputWrapperErrorBoundary">
<div style={wrapperStyle}>
<Container>
<Label minimized={minimizedLabel}>
{label} {required && <span style={{ color: "red" }}> *</span>}
</Label>
{children}
</Container>
{description && <Description>{description}</Description>}
{error && <Error>{error}</Error>}
</div>
</ErrorBoundary>
);
};
This is my password component
import React, { useState } from "react";
import styled from "styled-components";
import eyeHide from "./eye-svgfiles/eyeHide.svg";
import eyeShow from "./eye-svgfiles/eyeShow.svg";
import InputWrapper, { IInputWrapperProps } from "../wrapper";
const Passwordinput = styled.input`
border: 2px solid ${({ theme }) => theme.inputBorderColorFaded};
background: ${({ theme }) => theme.inputBackgroundColor};
display: block;
border-radius: 5px;
box-shadow: none;
color: ${({ theme }) => theme.inputTextColor};
height: 52px;
width: 100%;
margin: 0;
padding: 1px 15px;
&:focus {
border: 2px solid ${({ theme }) => theme.inputBorderColor};
outline: 0;
}
`;
const Svg = styled.div`
position: absolute;
left: 50%;
top: 65%;
transform: scale(0.8);
`;
export interface IPasswordProps extends IInputWrapperProps {
onChange: (i: string) => void;
value?: string | undefined;
}
export default ({ onChange, value, label, error, ...rest }: IPasswordProps) => {
const [state, setstate] = useState(false);
return (
<div>
<InputWrapper label={label} error={error} {...rest}> //I am getting error in here
<Passwordinput
label={label}
type={state ? "text" : "password"}
onChange={e => onChange(e.target.value)}
value={value}
error={error}
/>
<Svg>
<img
onClick={() => setstate(state => !state)}
style={{ cursor: "pointer" }}
src={state ? eyeShow : eyeHide}
alt="searchIcon"
/>
</Svg>
</InputWrapper>
</div>
);
};
Write your interface like this:
export interface IInputWrapperProps {
label?: string;
required?: boolean;
minimizedLabel?: boolean;
description?: string;
error?: string;
wrapperStyle?: React.CSSProperties;
children?: JSX.Element|JSX.Element[];
}
in fact writing:
children: JSX.Element|JSX.Element[];
The children can be either a single JSX Element or an array of Elements.