webui/src/components/common/Input.tsx

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;