UNPKG

@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
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;