blob: 42ca4beba6e0aae713a1e3ac1a55952b07e64d1f [file] [log] [blame]
simond47ef9e2022-09-28 22:24:28 -04001import { Stack, TextField } from '@mui/material';
2import { styled } from '@mui/material/styles';
3import { useState, useCallback, useEffect } from 'react';
4import { InfoButton, ToggleVisibilityButton } from './buttons';
5import { CheckedIcon, RoundSaltireIcon, LockIcon, PenIcon, PersonIcon } from './svgIcons';
idillon-sfl37c18df2022-08-26 18:44:27 -04006
simond47ef9e2022-09-28 22:24:28 -04007const iconsHeight = '16px';
8const StyledCheckedIconSuccess = styled(CheckedIcon)(({ theme }) => ({
9 height: iconsHeight,
10 color: theme.palette.success.main,
11}));
12const StyledRoundSaltireIconError = styled(RoundSaltireIcon)(({ theme }) => ({
13 height: iconsHeight,
14 color: theme.palette.error.main,
15}));
16const StyledPenIconLight = styled(PenIcon)({ height: iconsHeight, color: '#03B9E9' });
17const StyledPenIconDark = styled(PenIcon)(({ theme }) => ({ height: iconsHeight, color: theme.palette.primary.dark }));
18const StyledPersonIconLight = styled(PersonIcon)({ height: iconsHeight, color: '#03B9E9' });
19const StyledLockIcon = styled(LockIcon)({ height: iconsHeight, color: '#03B9E9' });
idillon-sfl37c18df2022-08-26 18:44:27 -040020
simond47ef9e2022-09-28 22:24:28 -040021export const UsernameInput = ({ infoButtonProps, ...props }) => {
22 const [isSelected, setIsSelected] = useState(false);
23 const [input, setInput] = useState(props.defaultValue);
24 const [startAdornment, setStartAdornment] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -040025
simond47ef9e2022-09-28 22:24:28 -040026 const onChange = useCallback(
27 (event) => {
28 setInput(event.target.value);
29 props.onChange?.(event);
30 },
31 [props.onChange]
32 );
idillon-sfl37c18df2022-08-26 18:44:27 -040033
simond47ef9e2022-09-28 22:24:28 -040034 useEffect(() => {
35 /* Handle startAdornment */
36 let Icon = StyledPersonIconLight;
37 let visibility = 'visible';
38 if (props.error) {
39 Icon = StyledRoundSaltireIconError;
40 } else if (props.success) {
41 Icon = StyledCheckedIconSuccess;
42 } else if (!isSelected && !input) {
43 visibility = 'hidden'; // keep icon's space so text does not move
idillon-sfl37c18df2022-08-26 18:44:27 -040044 }
simond47ef9e2022-09-28 22:24:28 -040045 setStartAdornment(<Icon sx={{ visibility }} />);
46 }, [props.error, props.success, isSelected, input]);
idillon-sfl37c18df2022-08-26 18:44:27 -040047
simond47ef9e2022-09-28 22:24:28 -040048 return (
49 <TextField
50 {...props}
51 label="Choose an identifier"
52 variant="standard"
53 InputLabelProps={{ shrink: !!(isSelected || input) }}
54 onChange={onChange}
55 InputProps={{
56 startAdornment,
57 endAdornment: <InfoButton {...infoButtonProps} />,
58 }}
59 onFocus={() => setIsSelected(true)}
60 onBlur={() => setIsSelected(false)}
61 />
62 );
63};
idillon-sfl37c18df2022-08-26 18:44:27 -040064
simond47ef9e2022-09-28 22:24:28 -040065export const PasswordInput = ({ infoButtonProps, ...props }) => {
66 const [showPassword, setShowPassword] = useState(false);
67 const [isSelected, setIsSelected] = useState(false);
68 const [input, setInput] = useState(props.defaultValue);
69 const [startAdornment, setStartAdornment] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -040070
simond47ef9e2022-09-28 22:24:28 -040071 const toggleShowPassword = () => {
72 setShowPassword((showPassword) => !showPassword);
73 };
74
75 const onChange = useCallback(
76 (event) => {
77 setInput(event.target.value);
78 props.onChange?.(event);
79 },
80 [props.onChange]
81 );
82
83 useEffect(() => {
84 /* Handle startAdornment */
85 let Icon = StyledLockIcon;
86 let visibility = 'visible';
87 if (props.error) {
88 Icon = StyledRoundSaltireIconError;
89 } else if (props.success) {
90 Icon = StyledCheckedIconSuccess;
91 } else if (!isSelected && !input) {
92 visibility = 'hidden'; // keep icon's space so text does not move
93 }
94 setStartAdornment(<Icon sx={{ visibility }} />);
95 }, [props.error, props.success, isSelected, input]);
96
97 return (
98 <TextField
99 {...props}
100 label="Password"
101 type={showPassword ? 'text' : 'password'}
102 variant="standard"
103 autoComplete="current-password"
104 InputLabelProps={{ shrink: !!(isSelected || input) }}
105 onChange={onChange}
106 InputProps={{
107 startAdornment,
108 endAdornment: (
109 <Stack direction="row" spacing="14px">
110 <InfoButton {...infoButtonProps} />
111 <ToggleVisibilityButton visible={showPassword} onClick={toggleShowPassword} />
112 </Stack>
113 ),
114 }}
115 onFocus={() => setIsSelected(true)}
116 onBlur={() => setIsSelected(false)}
117 />
118 );
119};
idillon-sfl37c18df2022-08-26 18:44:27 -0400120
121export const NickNameInput = (props) => {
simond47ef9e2022-09-28 22:24:28 -0400122 const [isSelected, setIsSelected] = useState(false);
123 const [input, setInput] = useState(props.defaultValue);
124 const [startAdornmentVisibility, setStartAdornmentVisibility] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -0400125
simond47ef9e2022-09-28 22:24:28 -0400126 const onChange = useCallback(
127 (event) => {
128 setInput(event.target.value);
129 props.onChange?.(event);
130 },
131 [props.onChange]
132 );
idillon-sfl37c18df2022-08-26 18:44:27 -0400133
simond47ef9e2022-09-28 22:24:28 -0400134 useEffect(() => {
135 setStartAdornmentVisibility(isSelected || input ? 'visible' : 'hidden');
136 }, [isSelected, input]);
idillon-sfl37c18df2022-08-26 18:44:27 -0400137
simond47ef9e2022-09-28 22:24:28 -0400138 return (
139 <TextField
140 {...props}
141 label="Nickname, surname..."
142 variant="standard"
143 InputLabelProps={{ shrink: !!(isSelected || input) }}
144 onChange={onChange}
145 InputProps={{
146 startAdornment: <StyledPenIconLight sx={{ visibility: startAdornmentVisibility }} />,
147 }}
148 onFocus={() => setIsSelected(true)}
149 onBlur={() => setIsSelected(false)}
150 />
151 );
152};
idillon-sfl37c18df2022-08-26 18:44:27 -0400153
154export const RegularInput = (props) => {
simond47ef9e2022-09-28 22:24:28 -0400155 const [isSelected, setIsSelected] = useState(false);
156 const [input, setInput] = useState(props.defaultValue);
157 const [startAdornmentVisibility, setStartAdornmentVisibility] = useState();
158 const [endAdornmentVisibility, setEndAdornmentVisibility] = useState();
idillon-sfl37c18df2022-08-26 18:44:27 -0400159
simond47ef9e2022-09-28 22:24:28 -0400160 const onChange = useCallback(
161 (event) => {
162 setInput(event.target.value);
163 props.onChange?.(event);
164 },
165 [props.onChange]
166 );
idillon-sfl37c18df2022-08-26 18:44:27 -0400167
simond47ef9e2022-09-28 22:24:28 -0400168 useEffect(() => {
169 setStartAdornmentVisibility(isSelected || input ? 'visible' : 'hidden');
170 setEndAdornmentVisibility(isSelected || input ? 'hidden' : 'visible');
171 }, [isSelected, input]);
idillon-sfl37c18df2022-08-26 18:44:27 -0400172
simond47ef9e2022-09-28 22:24:28 -0400173 return (
174 <TextField
175 {...props}
176 variant="standard"
177 InputLabelProps={{ shrink: !!(isSelected || input) }}
178 onChange={onChange}
179 InputProps={{
180 startAdornment: <StyledPenIconLight sx={{ visibility: startAdornmentVisibility }} />,
181 endAdornment: <StyledPenIconDark sx={{ visibility: endAdornmentVisibility }} />,
182 }}
183 onFocus={() => setIsSelected(true)}
184 onBlur={() => setIsSelected(false)}
185 />
186 );
187};