blob: aec48d38599c98e74fcf4231014ca3c1f8573901 [file] [log] [blame]
idillon-sfl37c18df2022-08-26 18:44:27 -04001import { Stack, TextField } from "@mui/material"
idillonfb2af5b2022-09-16 13:40:08 -04002import { styled } from "@mui/material/styles"
Adrien Béraud023f7cf2022-09-18 14:57:53 -04003import { useState, useCallback, useEffect } from "react";
idillon-sfl37c18df2022-08-26 18:44:27 -04004import { InfoButton, ToggleVisibilityButton } from "./buttons"
idillon927b7592022-09-15 12:56:45 -04005import { CheckedIcon, RoundSaltireIcon, LockIcon, PenIcon, PersonIcon } from "./svgIcons"
idillon-sfl37c18df2022-08-26 18:44:27 -04006
7const iconsHeight = "16px"
8const StyledCheckedIconSuccess = styled(CheckedIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.success.main}))
idillon927b7592022-09-15 12:56:45 -04009const StyledRoundSaltireIconError = styled(RoundSaltireIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.error.main}))
idillon-sfl37c18df2022-08-26 18:44:27 -040010const StyledPenIconLight = styled(PenIcon)({height: iconsHeight, color: "#03B9E9"})
11const StyledPenIconDark = styled(PenIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.primary.dark}))
12const StyledPersonIconLight = styled(PersonIcon)({height: iconsHeight, color: "#03B9E9"})
13const StyledLockIcon = styled(LockIcon)({height: iconsHeight, color: "#03B9E9"})
14
15export const UsernameInput = ({infoButtonProps, ...props}) => {
Adrien Béraud023f7cf2022-09-18 14:57:53 -040016 const [isSelected, setIsSelected] = useState(false);
17 const [input, setInput] = useState(props.defaultValue);
18 const [startAdornment, setStartAdornment] = useState()
idillon-sfl37c18df2022-08-26 18:44:27 -040019
Adrien Béraud023f7cf2022-09-18 14:57:53 -040020 const onChange = useCallback((event) => {
idillon-sfl37c18df2022-08-26 18:44:27 -040021 setInput(event.target.value)
22 props.onChange?.(event)
23 }, [props.onChange])
24
Adrien Béraud023f7cf2022-09-18 14:57:53 -040025 useEffect(() => {
idillon-sfl37c18df2022-08-26 18:44:27 -040026 /* Handle startAdornment */
27 let Icon = StyledPersonIconLight
28 let visibility = "visible"
29 if (props.error) {
idillon927b7592022-09-15 12:56:45 -040030 Icon = StyledRoundSaltireIconError
idillon-sfl37c18df2022-08-26 18:44:27 -040031 }
32 else if (props.success) {
33 Icon = StyledCheckedIconSuccess
34 }
35 else if (!isSelected && !input) {
36 visibility = "hidden" // keep icon's space so text does not move
37 }
38 setStartAdornment(<Icon sx={{visibility}}/>)
39 }, [props.error, props.success, isSelected, input])
40
41 return (
42 <TextField
43 {...props}
44 label="Choose an identifier"
45 variant="standard"
46 InputLabelProps={{ shrink: !!(isSelected || input) }}
47 onChange={onChange}
48 InputProps={{
49 startAdornment,
50 endAdornment: <InfoButton {...infoButtonProps}/>,
51 }}
52 onFocus={() => setIsSelected(true)}
53 onBlur={() => setIsSelected(false)}
54 />
55 )
56}
57
58export const PasswordInput = ({infoButtonProps, ...props}) => {
Adrien Béraud023f7cf2022-09-18 14:57:53 -040059 const [showPassword, setShowPassword] = useState(false);
60 const [isSelected, setIsSelected] = useState(false);
61 const [input, setInput] = useState(props.defaultValue);
62 const [startAdornment, setStartAdornment] = useState()
idillon-sfl37c18df2022-08-26 18:44:27 -040063
64 const toggleShowPassword = () => {
65 setShowPassword((showPassword) => !showPassword);
66 }
67
Adrien Béraud023f7cf2022-09-18 14:57:53 -040068 const onChange = useCallback((event) => {
idillon-sfl37c18df2022-08-26 18:44:27 -040069 setInput(event.target.value)
70 props.onChange?.(event)
71 }, [props.onChange])
72
Adrien Béraud023f7cf2022-09-18 14:57:53 -040073 useEffect(() => {
idillon-sfl37c18df2022-08-26 18:44:27 -040074 /* Handle startAdornment */
75 let Icon = StyledLockIcon
76 let visibility = "visible"
77 if (props.error) {
idillon927b7592022-09-15 12:56:45 -040078 Icon = StyledRoundSaltireIconError
idillon-sfl37c18df2022-08-26 18:44:27 -040079 }
80 else if (props.success) {
81 Icon = StyledCheckedIconSuccess
82 }
83 else if (!isSelected && !input) {
84 visibility = "hidden" // keep icon's space so text does not move
85 }
86 setStartAdornment(<Icon sx={{visibility}}/>)
87 }, [props.error, props.success, isSelected, input])
88
89 return (
90 <TextField
91 {...props}
92 label="Password"
93 type={showPassword ? "text" : "password"}
94 variant="standard"
95 autoComplete="current-password"
96 InputLabelProps={{ shrink: !!(isSelected || input) }}
97 onChange={onChange}
98 InputProps={{
99 startAdornment,
100 endAdornment: <Stack direction="row" spacing="14px">
101 <InfoButton {...infoButtonProps}/>
102 <ToggleVisibilityButton
103 visible={showPassword}
104 onClick={toggleShowPassword}
105 />
106 </Stack>,
107 }}
108 onFocus={() => setIsSelected(true)}
109 onBlur={() => setIsSelected(false)}
110 />
111 )
112}
113
114export const NickNameInput = (props) => {
Adrien Béraud023f7cf2022-09-18 14:57:53 -0400115 const [isSelected, setIsSelected] = useState(false);
116 const [input, setInput] = useState(props.defaultValue);
117 const [startAdornmentVisibility, setStartAdornmentVisibility] = useState()
idillon-sfl37c18df2022-08-26 18:44:27 -0400118
Adrien Béraud023f7cf2022-09-18 14:57:53 -0400119 const onChange = useCallback((event) => {
idillon-sfl37c18df2022-08-26 18:44:27 -0400120 setInput(event.target.value)
121 props.onChange?.(event)
122 }, [props.onChange])
123
Adrien Béraud023f7cf2022-09-18 14:57:53 -0400124 useEffect(() => {
idillon-sfl37c18df2022-08-26 18:44:27 -0400125 setStartAdornmentVisibility((isSelected || input) ? "visible" : "hidden")
126 }, [isSelected, input])
127
128 return (
129 <TextField
130 {...props}
131 label="Nickname, surname..."
132 variant="standard"
133 InputLabelProps={{ shrink: !!(isSelected || input) }}
134 onChange={onChange}
135 InputProps={{
136 startAdornment: <StyledPenIconLight sx={{visibility: startAdornmentVisibility}}/>,
137 }}
138 onFocus={() => setIsSelected(true)}
139 onBlur={() => setIsSelected(false)}
140 />
141 )
142}
143
144export const RegularInput = (props) => {
Adrien Béraud023f7cf2022-09-18 14:57:53 -0400145 const [isSelected, setIsSelected] = useState(false);
146 const [input, setInput] = useState(props.defaultValue);
147 const [startAdornmentVisibility, setStartAdornmentVisibility] = useState()
148 const [endAdornmentVisibility, setEndAdornmentVisibility] = useState()
idillon-sfl37c18df2022-08-26 18:44:27 -0400149
Adrien Béraud023f7cf2022-09-18 14:57:53 -0400150 const onChange = useCallback((event) => {
idillon-sfl37c18df2022-08-26 18:44:27 -0400151 setInput(event.target.value)
152 props.onChange?.(event)
153 }, [props.onChange])
154
Adrien Béraud023f7cf2022-09-18 14:57:53 -0400155 useEffect(() => {
idillon-sfl37c18df2022-08-26 18:44:27 -0400156 setStartAdornmentVisibility((isSelected || input) ? "visible" : "hidden")
157 setEndAdornmentVisibility((isSelected || input) ? "hidden" : "visible")
158 }, [isSelected, input])
159
160 return (
161 <TextField
162 {...props}
163 variant="standard"
164 InputLabelProps={{ shrink: !!(isSelected || input) }}
165 onChange={onChange}
166 InputProps={{
167 startAdornment: <StyledPenIconLight sx={{visibility: startAdornmentVisibility}}/>,
168 endAdornment: <StyledPenIconDark sx={{visibility: endAdornmentVisibility}}/>,
169 }}
170 onFocus={() => setIsSelected(true)}
171 onBlur={() => setIsSelected(false)}
172 />
173 )
174}