160 lines
4.1 KiB
TypeScript
160 lines
4.1 KiB
TypeScript
import React, { useState } from "react";
|
|
import "../../Sass/_forms.scss";
|
|
import ErrorBlock from "./ErrorBlock";
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
|
|
|
|
export enum InputType {
|
|
button = "button",
|
|
checkbox = "checkbox",
|
|
color = "color",
|
|
date = "date",
|
|
datetimelocal = "datetime-local",
|
|
email = "email",
|
|
file = "file",
|
|
hidden = "hidden",
|
|
image = "image",
|
|
month = "month",
|
|
number = "number",
|
|
password = "password",
|
|
radio = "radio",
|
|
range = "range",
|
|
reset = "reset",
|
|
search = "search",
|
|
submit = "submit",
|
|
tel = "tel",
|
|
text = "text",
|
|
textarea = "textarea",
|
|
time = "time",
|
|
url = "url",
|
|
week = "week",
|
|
}
|
|
|
|
export interface InputProps {
|
|
includeLabel?: boolean;
|
|
name: string;
|
|
label: string;
|
|
error: string;
|
|
placeHolder?: string;
|
|
readOnly?: boolean;
|
|
type: InputType;
|
|
value?: string | number | readonly string[] | undefined;
|
|
defaultValue?: string | number | readonly string[] | undefined;
|
|
min?: number;
|
|
max?: number;
|
|
step?: number;
|
|
hidden?: boolean;
|
|
autoComplete?: string;
|
|
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
maxLength?: number;
|
|
}
|
|
|
|
function Input(props: InputProps) {
|
|
const {
|
|
includeLabel,
|
|
name,
|
|
label,
|
|
error,
|
|
placeHolder,
|
|
readOnly,
|
|
type,
|
|
value,
|
|
defaultValue,
|
|
maxLength,
|
|
hidden,
|
|
autoComplete,
|
|
onChange,
|
|
...rest
|
|
} = props;
|
|
|
|
let showValue = value;
|
|
let checked: boolean = false;
|
|
|
|
let divClassName = "form-group";
|
|
let labelClassName = "label";
|
|
let className = "form-control";
|
|
let flexClassName = "";
|
|
|
|
const [showPasswordIcon, setShowPasswordIcon] = useState(faEyeSlash);
|
|
|
|
if (type === InputType.checkbox) {
|
|
checked = value === String(true);
|
|
showValue = undefined;
|
|
divClassName = "form-check";
|
|
className = "form-check-input";
|
|
labelClassName += " form-check-label";
|
|
flexClassName += "checkbox";
|
|
}
|
|
|
|
if (type === InputType.checkbox) {
|
|
divClassName += " allignedCheckBox";
|
|
}
|
|
|
|
const renderType =
|
|
type === InputType.password && showPasswordIcon === faEye
|
|
? InputType.text
|
|
: type;
|
|
const divEyeIconClassName = readOnly
|
|
? "fullHeight disabledIcon"
|
|
: "fullHeight";
|
|
|
|
if (type === InputType.password) {
|
|
flexClassName += "flex";
|
|
}
|
|
|
|
return (
|
|
<div className={divClassName} hidden={hidden}>
|
|
{(includeLabel === true || includeLabel === undefined) && (
|
|
<label className={labelClassName} htmlFor={name} hidden={hidden}>
|
|
{label}
|
|
</label>
|
|
)}
|
|
<div className={flexClassName}>
|
|
{type === InputType.textarea && (
|
|
<textarea
|
|
id={name}
|
|
className={className}
|
|
name={name}
|
|
onChange={onChange}
|
|
disabled={readOnly}
|
|
value={showValue || defaultValue}
|
|
autoComplete={autoComplete}
|
|
></textarea>
|
|
)}
|
|
{type !== InputType.textarea && (
|
|
<input
|
|
{...rest}
|
|
id={name}
|
|
type={renderType}
|
|
className={className}
|
|
placeholder={placeHolder}
|
|
name={name}
|
|
onChange={onChange}
|
|
disabled={readOnly}
|
|
value={showValue}
|
|
checked={checked}
|
|
defaultValue={defaultValue}
|
|
maxLength={maxLength! > 0 ? maxLength : undefined}
|
|
autoComplete={autoComplete}
|
|
/>
|
|
)}
|
|
{type === InputType.password && (
|
|
<div className={divEyeIconClassName}>
|
|
<FontAwesomeIcon
|
|
className="passwordIcon"
|
|
icon={showPasswordIcon}
|
|
onClick={() => {
|
|
const newIcon = showPasswordIcon === faEye ? faEyeSlash : faEye;
|
|
setShowPasswordIcon(newIcon);
|
|
}}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<ErrorBlock error={error}></ErrorBlock>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default Input;
|