2024-08-28 10:04:50 +02:00
|
|
|
import {
|
|
|
|
|
ChangeEvent,
|
|
|
|
|
ComponentType,
|
|
|
|
|
CSSProperties,
|
|
|
|
|
forwardRef,
|
2024-10-14 20:36:12 +02:00
|
|
|
InputHTMLAttributes,
|
|
|
|
|
useState,
|
2024-08-28 10:04:50 +02:00
|
|
|
} from "react";
|
2024-08-21 17:14:40 +02:00
|
|
|
import { attributes } from "../utils/attributes";
|
|
|
|
|
import { classnames } from "../utils/classnames";
|
2024-08-20 15:57:58 +02:00
|
|
|
import "./input.css";
|
|
|
|
|
import { SimpleText } from "../SimpleText/SimpleText";
|
|
|
|
|
|
|
|
|
|
export interface InputCustomStyleCSS extends CSSProperties {
|
|
|
|
|
"--codex-input-background"?: string;
|
|
|
|
|
"--codex-color"?: string;
|
|
|
|
|
"--codex-border-radius"?: string;
|
|
|
|
|
"--codex-input-border"?: string;
|
|
|
|
|
"--codex-color-primary"?: string;
|
|
|
|
|
"--codex-input-background-disabled"?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
|
id: string;
|
|
|
|
|
|
2024-10-14 20:36:12 +02:00
|
|
|
label?: string;
|
2024-08-20 15:57:58 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper text to add indication about your input.
|
|
|
|
|
*/
|
|
|
|
|
helper?: string;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add an icon on the left.
|
|
|
|
|
*/
|
|
|
|
|
Icon?: ComponentType;
|
|
|
|
|
|
2024-09-20 11:03:04 +02:00
|
|
|
/**
|
2024-10-14 20:36:12 +02:00
|
|
|
* If the mode is "auto", the component will check the invalid state
|
|
|
|
|
* on change and add an invalid state if it is invalid.
|
2024-09-20 11:03:04 +02:00
|
|
|
*/
|
2024-10-14 20:36:12 +02:00
|
|
|
mode?: "auto";
|
|
|
|
|
|
|
|
|
|
isInvalid?: boolean;
|
2024-08-20 15:57:58 +02:00
|
|
|
|
|
|
|
|
/**
|
2024-10-14 20:36:12 +02:00
|
|
|
* Apply a class to the input element
|
2024-08-20 15:57:58 +02:00
|
|
|
*/
|
2024-10-14 20:36:12 +02:00
|
|
|
inputClassName?: string;
|
2024-10-25 18:01:37 +02:00
|
|
|
|
|
|
|
|
inputContainerClassName?: string;
|
2024-10-14 20:36:12 +02:00
|
|
|
} & InputHTMLAttributes<HTMLInputElement>;
|
2024-08-20 15:57:58 +02:00
|
|
|
|
2024-08-28 10:04:50 +02:00
|
|
|
export const Input = forwardRef<HTMLInputElement, Props>(
|
|
|
|
|
(
|
|
|
|
|
{
|
|
|
|
|
id,
|
|
|
|
|
label,
|
|
|
|
|
helper,
|
|
|
|
|
style,
|
|
|
|
|
Icon,
|
2024-09-20 11:03:04 +02:00
|
|
|
inputClassName,
|
2024-10-25 18:01:37 +02:00
|
|
|
inputContainerClassName = "",
|
2024-10-14 20:36:12 +02:00
|
|
|
disabled = false,
|
|
|
|
|
onChange,
|
|
|
|
|
mode,
|
|
|
|
|
isInvalid = false,
|
|
|
|
|
...rest
|
2024-08-28 10:04:50 +02:00
|
|
|
},
|
|
|
|
|
ref
|
|
|
|
|
) => {
|
2024-10-14 20:36:12 +02:00
|
|
|
const [invalid, setInvalid] = useState(isInvalid);
|
|
|
|
|
|
|
|
|
|
const onInternalChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
if (mode === "auto") {
|
|
|
|
|
setInvalid(e.currentTarget.checkValidity() !== true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onChange?.(e);
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-28 10:04:50 +02:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{label && (
|
|
|
|
|
<label className="input-label" htmlFor={id}>
|
|
|
|
|
{label}
|
|
|
|
|
</label>
|
2024-08-20 15:57:58 +02:00
|
|
|
)}
|
2024-08-28 10:04:50 +02:00
|
|
|
|
2024-10-25 18:01:37 +02:00
|
|
|
<div
|
|
|
|
|
className={classnames(
|
|
|
|
|
["input-icon", !!Icon],
|
|
|
|
|
[inputContainerClassName]
|
|
|
|
|
)}
|
|
|
|
|
>
|
2024-08-28 10:04:50 +02:00
|
|
|
{Icon && (
|
|
|
|
|
<div className="input-iconElement">
|
|
|
|
|
<Icon />
|
|
|
|
|
</div>
|
2024-08-20 15:57:58 +02:00
|
|
|
)}
|
2024-08-28 10:04:50 +02:00
|
|
|
<input
|
2024-09-16 19:06:51 +02:00
|
|
|
id={id}
|
2024-08-28 10:04:50 +02:00
|
|
|
ref={ref}
|
|
|
|
|
className={classnames(
|
|
|
|
|
["input"],
|
2024-10-14 20:36:12 +02:00
|
|
|
["input--invalid", invalid || isInvalid],
|
2024-08-28 10:04:50 +02:00
|
|
|
["input-icon-input", !!Icon],
|
2024-09-20 11:03:04 +02:00
|
|
|
[inputClassName || ""]
|
2024-08-28 10:04:50 +02:00
|
|
|
)}
|
2024-10-14 20:36:12 +02:00
|
|
|
onChange={onInternalChange}
|
2024-08-28 10:04:50 +02:00
|
|
|
style={style}
|
|
|
|
|
{...attributes({
|
|
|
|
|
disabled,
|
|
|
|
|
"aria-disabled": disabled,
|
|
|
|
|
})}
|
2024-10-14 20:36:12 +02:00
|
|
|
{...rest}
|
2024-08-28 10:04:50 +02:00
|
|
|
/>
|
2024-08-20 15:57:58 +02:00
|
|
|
</div>
|
2024-08-28 10:04:50 +02:00
|
|
|
|
|
|
|
|
{helper && (
|
|
|
|
|
<div>
|
2024-10-14 20:36:12 +02:00
|
|
|
<SimpleText
|
|
|
|
|
className="input-helper-text"
|
|
|
|
|
variant={invalid || isInvalid ? "error" : "light"}
|
|
|
|
|
>
|
2024-08-28 10:04:50 +02:00
|
|
|
{helper}
|
|
|
|
|
</SimpleText>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|