blob: a607a3142ecf477b1a279d80073fb3aaaa6593e8 [file] [log] [blame]
simond47ef9e2022-09-28 22:24:28 -04001import { Stack, TextField } from '@mui/material';
2import { styled } from '@mui/material/styles';
simon07b4eb02022-09-29 17:50:26 -04003import { useCallback, useEffect, useState } from 'react';
4
simond47ef9e2022-09-28 22:24:28 -04005import { InfoButton, ToggleVisibilityButton } from './buttons';
simon07b4eb02022-09-29 17:50:26 -04006import { CheckedIcon, LockIcon, PenIcon, PersonIcon, RoundSaltireIcon } from './svgIcons';
idillon-sfl37c18df2022-08-26 18:44:27 -04007
simond47ef9e2022-09-28 22:24:28 -04008const iconsHeight = '16px';
9const StyledCheckedIconSuccess = styled(CheckedIcon)(({ theme }) => ({
10 height: iconsHeight,
11 color: theme.palette.success.main,
12}));
13const StyledRoundSaltireIconError = styled(RoundSaltireIcon)(({ theme }) => ({
14 height: iconsHeight,
15 color: theme.palette.error.main,
16}));
17const StyledPenIconLight = styled(PenIcon)({ height: iconsHeight, color: '#03B9E9' });
18const StyledPenIconDark = styled(PenIcon)(({ theme }) => ({ height: iconsHeight, color: theme.palette.primary.dark }));
19const StyledPersonIconLight = styled(PersonIcon)({ height: iconsHeight, color: '#03B9E9' });
20const StyledLockIcon = styled(LockIcon)({ height: iconsHeight, color: '#03B9E9' });
idillon-sfl37c18df2022-08-26 18:44:27 -040021
simond47ef9e2022-09-28 22:24:28 -040022export const UsernameInput = ({ infoButtonProps, ...props }) => {
23 const [isSelected, setIsSelected] = useState(false);
24 const [input, setInput] = useState(props.defaultValue);
25 const [startAdornment, setStartAdornment] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -040026
simond47ef9e2022-09-28 22:24:28 -040027 const onChange = useCallback(
28 (event) => {
29 setInput(event.target.value);
30 props.onChange?.(event);
31 },
32 [props.onChange]
33 );
idillon-sfl37c18df2022-08-26 18:44:27 -040034
simond47ef9e2022-09-28 22:24:28 -040035 useEffect(() => {
36 /* Handle startAdornment */
37 let Icon = StyledPersonIconLight;
38 let visibility = 'visible';
39 if (props.error) {
40 Icon = StyledRoundSaltireIconError;
41 } else if (props.success) {
42 Icon = StyledCheckedIconSuccess;
43 } else if (!isSelected && !input) {
44 visibility = 'hidden'; // keep icon's space so text does not move
idillon-sfl37c18df2022-08-26 18:44:27 -040045 }
simond47ef9e2022-09-28 22:24:28 -040046 setStartAdornment(<Icon sx={{ visibility }} />);
47 }, [props.error, props.success, isSelected, input]);
idillon-sfl37c18df2022-08-26 18:44:27 -040048
simond47ef9e2022-09-28 22:24:28 -040049 return (
50 <TextField
51 {...props}
52 label="Choose an identifier"
53 variant="standard"
54 InputLabelProps={{ shrink: !!(isSelected || input) }}
55 onChange={onChange}
56 InputProps={{
57 startAdornment,
58 endAdornment: <InfoButton {...infoButtonProps} />,
59 }}
60 onFocus={() => setIsSelected(true)}
61 onBlur={() => setIsSelected(false)}
62 />
63 );
64};
idillon-sfl37c18df2022-08-26 18:44:27 -040065
simond47ef9e2022-09-28 22:24:28 -040066export const PasswordInput = ({ infoButtonProps, ...props }) => {
67 const [showPassword, setShowPassword] = useState(false);
68 const [isSelected, setIsSelected] = useState(false);
69 const [input, setInput] = useState(props.defaultValue);
70 const [startAdornment, setStartAdornment] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -040071
simond47ef9e2022-09-28 22:24:28 -040072 const toggleShowPassword = () => {
73 setShowPassword((showPassword) => !showPassword);
74 };
75
76 const onChange = useCallback(
77 (event) => {
78 setInput(event.target.value);
79 props.onChange?.(event);
80 },
81 [props.onChange]
82 );
83
84 useEffect(() => {
85 /* Handle startAdornment */
86 let Icon = StyledLockIcon;
87 let visibility = 'visible';
88 if (props.error) {
89 Icon = StyledRoundSaltireIconError;
90 } else if (props.success) {
91 Icon = StyledCheckedIconSuccess;
92 } else if (!isSelected && !input) {
93 visibility = 'hidden'; // keep icon's space so text does not move
94 }
95 setStartAdornment(<Icon sx={{ visibility }} />);
96 }, [props.error, props.success, isSelected, input]);
97
98 return (
99 <TextField
100 {...props}
101 label="Password"
102 type={showPassword ? 'text' : 'password'}
103 variant="standard"
104 autoComplete="current-password"
105 InputLabelProps={{ shrink: !!(isSelected || input) }}
106 onChange={onChange}
107 InputProps={{
108 startAdornment,
109 endAdornment: (
110 <Stack direction="row" spacing="14px">
111 <InfoButton {...infoButtonProps} />
112 <ToggleVisibilityButton visible={showPassword} onClick={toggleShowPassword} />
113 </Stack>
114 ),
115 }}
116 onFocus={() => setIsSelected(true)}
117 onBlur={() => setIsSelected(false)}
118 />
119 );
120};
idillon-sfl37c18df2022-08-26 18:44:27 -0400121
122export const NickNameInput = (props) => {
simond47ef9e2022-09-28 22:24:28 -0400123 const [isSelected, setIsSelected] = useState(false);
124 const [input, setInput] = useState(props.defaultValue);
125 const [startAdornmentVisibility, setStartAdornmentVisibility] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -0400126
simond47ef9e2022-09-28 22:24:28 -0400127 const onChange = useCallback(
128 (event) => {
129 setInput(event.target.value);
130 props.onChange?.(event);
131 },
132 [props.onChange]
133 );
idillon-sfl37c18df2022-08-26 18:44:27 -0400134
simond47ef9e2022-09-28 22:24:28 -0400135 useEffect(() => {
136 setStartAdornmentVisibility(isSelected || input ? 'visible' : 'hidden');
137 }, [isSelected, input]);
idillon-sfl37c18df2022-08-26 18:44:27 -0400138
simond47ef9e2022-09-28 22:24:28 -0400139 return (
140 <TextField
141 {...props}
142 label="Nickname, surname..."
143 variant="standard"
144 InputLabelProps={{ shrink: !!(isSelected || input) }}
145 onChange={onChange}
146 InputProps={{
147 startAdornment: <StyledPenIconLight sx={{ visibility: startAdornmentVisibility }} />,
148 }}
149 onFocus={() => setIsSelected(true)}
150 onBlur={() => setIsSelected(false)}
151 />
152 );
153};
idillon-sfl37c18df2022-08-26 18:44:27 -0400154
155export const RegularInput = (props) => {
simond47ef9e2022-09-28 22:24:28 -0400156 const [isSelected, setIsSelected] = useState(false);
157 const [input, setInput] = useState(props.defaultValue);
158 const [startAdornmentVisibility, setStartAdornmentVisibility] = useState();
159 const [endAdornmentVisibility, setEndAdornmentVisibility] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -0400160
simond47ef9e2022-09-28 22:24:28 -0400161 const onChange = useCallback(
162 (event) => {
163 setInput(event.target.value);
164 props.onChange?.(event);
165 },
166 [props.onChange]
167 );
idillon-sfl37c18df2022-08-26 18:44:27 -0400168
simond47ef9e2022-09-28 22:24:28 -0400169 useEffect(() => {
170 setStartAdornmentVisibility(isSelected || input ? 'visible' : 'hidden');
171 setEndAdornmentVisibility(isSelected || input ? 'hidden' : 'visible');
172 }, [isSelected, input]);
idillon-sfl37c18df2022-08-26 18:44:27 -0400173
simond47ef9e2022-09-28 22:24:28 -0400174 return (
175 <TextField
176 {...props}
177 variant="standard"
178 InputLabelProps={{ shrink: !!(isSelected || input) }}
179 onChange={onChange}
180 InputProps={{
181 startAdornment: <StyledPenIconLight sx={{ visibility: startAdornmentVisibility }} />,
182 endAdornment: <StyledPenIconDark sx={{ visibility: endAdornmentVisibility }} />,
183 }}
184 onFocus={() => setIsSelected(true)}
185 onBlur={() => setIsSelected(false)}
186 />
187 );
188};