Refactored textfield component

This commit is contained in:
Daniel Cojocea
2024-07-12 18:45:23 -04:00
parent 3cb1817639
commit 3855d4e4d5
5 changed files with 179 additions and 9 deletions

View File

@@ -0,0 +1,49 @@
.field {
min-width: 250px;
}
.field h1.MuiTypography-root,
.field h5.MuiTypography-root,
.field input,
.field .input-error {
font-size: var(--env-var-font-size-medium);
}
.field h1.MuiTypography-root,
.field h5.MuiTypography-root,
.field input {
color: var(--env-var-color-5);
}
.field h1.MuiTypography-root {
font-weight: 600;
}
.field h1.MuiTypography-root span {
color: var(--env-var-color-19);
margin-left: 1px;
}
.field h5.MuiTypography-root {
position: relative;
opacity: 0.8;
padding: var(--env-var-spacing-1-minus);
padding-left: 0;
border-right: solid 1px var(--env-var-color-29);
}
.field .MuiInputBase-root {
height: 39px;
padding-right: var(--env-var-spacing-1-minus);
}
.field input {
padding: var(--env-var-spacing-1-minus);
}
.field .MuiOutlinedInput-root fieldset {
border-color: var(--env-var-color-29);
border-radius: var(--env-var-radius-1);
}
.field .MuiOutlinedInput-root:hover fieldset {
border-color: var(--env-var-color-25);
}
.field .input-error {
color: var(--env-var-color-24);
opacity: 0.8;
}
.field:has(.input-error) .MuiOutlinedInput-root fieldset {
border-color: #fda29b;
}

View File

@@ -0,0 +1,93 @@
import { useTheme } from "@emotion/react";
import {
IconButton,
InputAdornment,
Stack,
TextField,
Typography,
} from "@mui/material";
import VisibilityOff from "@mui/icons-material/VisibilityOff";
import Visibility from "@mui/icons-material/Visibility";
import "./index.css";
const Field = ({
type,
id,
label,
isRequired,
isVisible,
setVisibility,
autoComplete,
placeholder,
value,
onChange,
error,
disabled,
}) => {
const theme = useTheme();
return (
<Stack gap={theme.gap.xs} className={`field field-${type}`}>
{label && (
<Typography component="h1">
{label}
{isRequired ? <span>*</span> : ""}
</Typography>
)}
<TextField
type={
type === "password"
? isVisible
? "text"
: type
: type === "website"
? "text"
: type
}
id={id}
autoComplete={autoComplete}
placeholder={placeholder}
value={value}
onChange={onChange}
disabled={disabled}
InputProps={
type === "website"
? {
startAdornment: <Typography component="h5">http://</Typography>,
}
: type === "password" && {
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={() => setVisibility((show) => !show)}
tabIndex={-1}
sx={{
color: theme.palette.section.borderColor,
padding: theme.gap.xs,
"&:focus": {
outline: "none",
},
"& .MuiTouchRipple-root": {
pointerEvents: "none",
display: "none",
},
}}
>
{!isVisible ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}
}
/>
{error && (
<Typography component="p" className="input-error" mt={theme.gap.xs}>
{error}
</Typography>
)}
</Stack>
);
};
export default Field;

View File

@@ -41,7 +41,7 @@ import ImageField from "../../Components/TextFields/Image";
import ProgressUpload from "../../Components/ProgressBars";
import Alert from "../../Components/Alert";
import { createToast } from "../../Utils/toastUtils";
import { ToastContainer } from "react-toastify";
import Field from "../../Components/TextFields/Field";
const cols = [
{
@@ -203,6 +203,9 @@ const Demo = () => {
setIsLoading(false);
}, 4000);
};
//fields
const [visibility, setVisibility] = useState(false);
return (
<div>
<div style={{ padding: "4rem", border: "1px solid black" }}>
@@ -439,7 +442,7 @@ const Demo = () => {
/>
</Stack>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<Stack justifyContent="center" alignItems="center">
<Stack direction="row" gap="10px" flexWrap="wrap">
<Box width="500px">
<Alert
variant="info"
@@ -447,20 +450,20 @@ const Demo = () => {
body="Since you logged in via SSO, you cannot reset or modify your password."
/>
</Box>
<Box width="500px" mt="5px">
<Box width="500px">
<Alert
variant="warning"
body="New password must contain at least 8 characters and must have at least one uppercase letter, one number and one symbol."
/>
</Box>
<Box width="500px" mt="5px">
<Box width="500px">
<Alert
variant="error"
title="Error"
body="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
/>
</Box>
<Box width="500px" mt="5px">
<Box width="500px">
<Alert
variant="info"
title="We've just released a new feature"
@@ -468,7 +471,7 @@ const Demo = () => {
isToast={true}
/>
</Box>
<Box width="500px" mt="5px">
<Box width="500px">
<Alert
variant="info"
body="Your password is incorrect."
@@ -491,7 +494,30 @@ const Demo = () => {
</Box>
</Stack>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<ToastContainer />
<Stack direction="row" justifyContent="center" gap="20px">
<Field type="text" label="Name" placeholder="Enter a name" />
<Field
type="email"
label="Email"
isRequired={true}
placeholder="name.surname@companyname.com"
error="This is an error message."
/>
<Field
type="password"
label="Password"
isRequired={true}
isVisible={visibility}
setVisibility={setVisibility}
placeholder="Create a password"
/>
<Field
type="website"
label="Website"
placeholder="google.com"
/>
</Stack>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
</div>
);
};

View File

@@ -91,6 +91,7 @@ const theme = createTheme({
pY: "40px",
},
gap: {
xs: "4px",
small: "8px",
medium: "12px",
ml: "16px",
@@ -101,7 +102,7 @@ const theme = createTheme({
info: {
color: secondaryMain,
bg: otherColorsWhite,
border: "#d0d5dd",
border: sectionBorder,
},
error: {
color: "#d92d20",
@@ -111,7 +112,7 @@ const theme = createTheme({
warning: {
color: "#DC6803",
bg: "#fffcf5",
border: "#fec84b"
border: "#fec84b",
},
},
});

View File

@@ -59,6 +59,7 @@
--env-var-spacing-1: 12px;
--env-var-spacing-1-plus: 16px;
--env-var-spacing-1-minus: 10px;
--env-var-spacing-2: 24px;
--env-var-spacing-3: 32px;
--env-var-spacing-4: 40px;