80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
import {
|
|
Component,
|
|
createEffect,
|
|
createSignal,
|
|
createUniqueId,
|
|
onMount,
|
|
Show,
|
|
} from "solid-js";
|
|
import formStyles from "./form.module.css";
|
|
|
|
export type TextFieldProps = {
|
|
label?: string;
|
|
helperText?: string;
|
|
type?: "text" | "password";
|
|
onChange?: (value: string) => void;
|
|
onInput?: (value: string) => void;
|
|
inputId?: string;
|
|
error?: boolean;
|
|
required?: boolean;
|
|
name?: string;
|
|
};
|
|
|
|
const TextField: Component<TextFieldProps> = (props) => {
|
|
let input: HTMLInputElement;
|
|
let field: HTMLDivElement;
|
|
const [hasContent, setHasContent] = createSignal(false);
|
|
const altInputId = createUniqueId();
|
|
|
|
createEffect(() => {
|
|
if (hasContent()) {
|
|
field.classList.add("float-label");
|
|
} else {
|
|
field.classList.remove("float-label");
|
|
}
|
|
});
|
|
|
|
onMount(() => {
|
|
setHasContent(input.value.length > 0);
|
|
});
|
|
|
|
const onInputChange = (e: { currentTarget: HTMLInputElement }) => {
|
|
const value = (e.currentTarget as HTMLInputElement).value;
|
|
setHasContent(value.length > 0);
|
|
props.onInput?.(value);
|
|
};
|
|
|
|
const inputId = () => props.inputId ?? altInputId;
|
|
|
|
const fieldClass = () => {
|
|
const cls = [formStyles.textfield];
|
|
if (typeof props.helperText !== "undefined") {
|
|
cls.push(formStyles.withHelperText);
|
|
}
|
|
if (props.error) {
|
|
cls.push(formStyles.error);
|
|
}
|
|
return cls.join(" ");
|
|
};
|
|
|
|
return (
|
|
<div ref={field!} class={fieldClass()}>
|
|
<label for={inputId()}>{props.label}</label>
|
|
<input
|
|
ref={input!}
|
|
id={inputId()}
|
|
type={props.type ?? "text"}
|
|
onInput={onInputChange}
|
|
onChange={(e) => props.onChange?.(e.currentTarget.value)}
|
|
placeholder=""
|
|
required={props.required}
|
|
name={props.name}
|
|
/>
|
|
<Show when={typeof props.helperText !== "undefined"}>
|
|
<span class={formStyles.helperText}>{props.helperText}</span>
|
|
</Show>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default TextField;
|