@codeworker.br/govbr-tw-react
Version:
Biblioteca de componentes React usando Tailwind CSS que implementa o Padrão Digital de Governo.
54 lines (53 loc) • 4.87 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useMemo, useState } from "react";
import Card from "../Card";
import Input from "../Input";
import { Button } from "../Button";
import { GovBRLogo } from "../GovBRLogo";
const MIN_USERNAME_LENGTH = 3;
const MIN_PASSWORD_LENGTH = 6;
const Login = ({ title = "Acesso", subtitle = "Informe suas credenciais", initialUsername = "", initialPassword = "", minUsernameLength = MIN_USERNAME_LENGTH, minPasswordLength = MIN_PASSWORD_LENGTH, showGovBRLogo = true, locatorText, institutionText, usernameLabel = "Usuário", passwordLabel = "Senha", usernamePlaceholder = "Seu usuário", passwordPlaceholder = "Sua senha", submitLabel = "Entrar", usernameRequiredMessage = "Usuário obrigatório.", usernameMinLengthMessage = `Usuário deve ter ao menos ${minUsernameLength} caracteres.`, passwordRequiredMessage = "Senha obrigatória.", passwordMinLengthMessage = `Senha deve ter ao menos ${minPasswordLength} caracteres.`, onSubmit, disabled = false, className, }) => {
const [username, setUsername] = useState(initialUsername);
const [password, setPassword] = useState(initialPassword);
const [touched, setTouched] = useState({
username: false,
password: false,
});
const errors = useMemo(() => {
const nextErrors = {};
if (!username.trim()) {
nextErrors.username = usernameRequiredMessage;
}
else if (username.trim().length < minUsernameLength) {
nextErrors.username = usernameMinLengthMessage;
}
if (!password.trim()) {
nextErrors.password = passwordRequiredMessage;
}
else if (password.trim().length < minPasswordLength) {
nextErrors.password = passwordMinLengthMessage;
}
return nextErrors;
}, [
minPasswordLength,
minUsernameLength,
password,
passwordMinLengthMessage,
passwordRequiredMessage,
username,
usernameMinLengthMessage,
usernameRequiredMessage,
]);
const hasError = (field) => Boolean(errors[field]);
const showError = (field) => touched[field] ? errors[field] : "";
const handleSubmit = useCallback((event) => {
event.preventDefault();
setTouched({ username: true, password: true });
if (Object.keys(errors).length > 0) {
return;
}
onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit({ username: username.trim(), password: password.trim() });
}, [errors, onSubmit, password, username]);
return (_jsxs(Card, { className: className, disabled: disabled, children: [_jsxs(Card.Header, { className: "space-y-1", children: [(showGovBRLogo || locatorText || institutionText) && (_jsxs("div", { className: "flex items-center gap-6 pb-2", children: [showGovBRLogo && (_jsx("div", { className: "w-28", children: _jsx(GovBRLogo, {}) })), (locatorText || institutionText) && (_jsxs("div", { className: "text-govbr-gray-70", children: [locatorText && (_jsx("div", { className: "text-sm font-semibold text-govbr-gray-80", children: locatorText })), institutionText && (_jsx("div", { className: "text-xs text-govbr-gray-60", children: institutionText }))] }))] })), _jsx("h2", { className: "text-xl font-semibold text-govbr-gray-90", children: title }), _jsx("p", { className: "text-sm font-normal text-govbr-gray-60", children: subtitle })] }), _jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-6 pb-6", children: [_jsxs(Card.Main, { children: [_jsxs("label", { className: "flex flex-col gap-3", children: [_jsx("span", { className: "text-sm font-medium text-govbr-gray-80", children: usernameLabel }), _jsx(Input, { type: "text", placeholder: usernamePlaceholder, value: username, onChange: (event) => setUsername(event.target.value), onBlur: () => setTouched((prev) => (Object.assign(Object.assign({}, prev), { username: true }))), variant: showError("username") ? "danger" : "default", hint: showError("username"), disabled: disabled, autoComplete: "username", "aria-invalid": hasError("username") })] }), _jsxs("label", { className: "flex flex-col gap-3", children: [_jsx("span", { className: "text-sm font-medium text-govbr-gray-80", children: passwordLabel }), _jsx(Input, { type: "password", placeholder: passwordPlaceholder, value: password, onChange: (event) => setPassword(event.target.value), onBlur: () => setTouched((prev) => (Object.assign(Object.assign({}, prev), { password: true }))), variant: showError("password") ? "danger" : "default", hint: showError("password"), disabled: disabled, autoComplete: "current-password", "aria-invalid": hasError("password") })] })] }), _jsx(Card.Footer, { className: "pt-2", children: _jsx(Button, { type: "submit", disabled: disabled, children: submitLabel }) })] })] }));
};
export default Login;