@zeix/ui-element
Version:
UIElement - minimal reactive framework based on Web Components
73 lines (67 loc) • 1.47 kB
text/typescript
import {
type Component,
asString,
component,
first,
on,
setAttribute,
setProperty,
setText,
UNSET,
} from "../../../";
export type InputTextProps = {
value: string;
length: number;
error: string;
description: string;
};
export default component(
"input-text",
{
value: asString(),
length: 0,
error: "",
description: "",
},
(el) => {
const input = el.querySelector("input");
if (!input) throw new Error("No input element found");
const errorId = el.querySelector(".error")?.id;
const descriptionId = el.querySelector(".description")?.id;
return [
first(
"input",
on("change", () => {
el.value = input.value;
el.error = input.validationMessage ?? "";
}),
on("input", () => {
el.length = input.value.length;
}),
setProperty("ariaInvalid", () => (el.error ? "true" : "false")),
setAttribute("aria-errormessage", () =>
el.error && errorId ? errorId : UNSET,
),
setAttribute("aria-describedby", () =>
el.description && descriptionId ? descriptionId : UNSET,
),
),
first<InputTextProps, HTMLButtonElement>(
".clear",
on("click", () => {
el.value = "";
el.length = 0;
input.focus();
}),
setProperty("hidden", () => !el.length),
),
first(".error", setText("error")),
first(".description", setText("description")),
];
},
);
declare global {
interface HTMLElementTagNameMap {
"input-text": Component<InputTextProps>;
}
}