| import { Stack, TextField } from "@mui/material" |
| import { styled } from "@mui/styles" |
| import React from "react" |
| import { InfoButton, ToggleVisibilityButton } from "./buttons" |
| import { CheckedIcon, RoundCrossIcon, LockIcon, PenIcon, PersonIcon } from "./svgIcons" |
| |
| const iconsHeight = "16px" |
| const StyledCheckedIconSuccess = styled(CheckedIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.success.main})) |
| const StyledRoundCrossIconError = styled(RoundCrossIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.error.main})) |
| const StyledPenIconLight = styled(PenIcon)({height: iconsHeight, color: "#03B9E9"}) |
| const StyledPenIconDark = styled(PenIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.primary.dark})) |
| const StyledPersonIconLight = styled(PersonIcon)({height: iconsHeight, color: "#03B9E9"}) |
| const StyledLockIcon = styled(LockIcon)({height: iconsHeight, color: "#03B9E9"}) |
| |
| export const UsernameInput = ({infoButtonProps, ...props}) => { |
| const [isSelected, setIsSelected] = React.useState(false); |
| const [input, setInput] = React.useState(props.defaultValue); |
| const [startAdornment, setStartAdornment] = React.useState() |
| |
| const onChange = React.useCallback((event) => { |
| setInput(event.target.value) |
| props.onChange?.(event) |
| }, [props.onChange]) |
| |
| React.useEffect(() => { |
| /* Handle startAdornment */ |
| let Icon = StyledPersonIconLight |
| let visibility = "visible" |
| if (props.error) { |
| Icon = StyledRoundCrossIconError |
| } |
| else if (props.success) { |
| Icon = StyledCheckedIconSuccess |
| } |
| else if (!isSelected && !input) { |
| visibility = "hidden" // keep icon's space so text does not move |
| } |
| setStartAdornment(<Icon sx={{visibility}}/>) |
| }, [props.error, props.success, isSelected, input]) |
| |
| return ( |
| <TextField |
| {...props} |
| label="Choose an identifier" |
| variant="standard" |
| InputLabelProps={{ shrink: !!(isSelected || input) }} |
| onChange={onChange} |
| InputProps={{ |
| startAdornment, |
| endAdornment: <InfoButton {...infoButtonProps}/>, |
| }} |
| onFocus={() => setIsSelected(true)} |
| onBlur={() => setIsSelected(false)} |
| /> |
| ) |
| } |
| |
| export const PasswordInput = ({infoButtonProps, ...props}) => { |
| const [showPassword, setShowPassword] = React.useState(false); |
| const [isSelected, setIsSelected] = React.useState(false); |
| const [input, setInput] = React.useState(props.defaultValue); |
| const [startAdornment, setStartAdornment] = React.useState() |
| |
| const toggleShowPassword = () => { |
| setShowPassword((showPassword) => !showPassword); |
| } |
| |
| const onChange = React.useCallback((event) => { |
| setInput(event.target.value) |
| props.onChange?.(event) |
| }, [props.onChange]) |
| |
| React.useEffect(() => { |
| /* Handle startAdornment */ |
| let Icon = StyledLockIcon |
| let visibility = "visible" |
| if (props.error) { |
| Icon = StyledRoundCrossIconError |
| } |
| else if (props.success) { |
| Icon = StyledCheckedIconSuccess |
| } |
| else if (!isSelected && !input) { |
| visibility = "hidden" // keep icon's space so text does not move |
| } |
| setStartAdornment(<Icon sx={{visibility}}/>) |
| }, [props.error, props.success, isSelected, input]) |
| |
| return ( |
| <TextField |
| {...props} |
| label="Password" |
| type={showPassword ? "text" : "password"} |
| variant="standard" |
| autoComplete="current-password" |
| InputLabelProps={{ shrink: !!(isSelected || input) }} |
| onChange={onChange} |
| InputProps={{ |
| startAdornment, |
| endAdornment: <Stack direction="row" spacing="14px"> |
| <InfoButton {...infoButtonProps}/> |
| <ToggleVisibilityButton |
| visible={showPassword} |
| onClick={toggleShowPassword} |
| /> |
| </Stack>, |
| }} |
| onFocus={() => setIsSelected(true)} |
| onBlur={() => setIsSelected(false)} |
| /> |
| ) |
| } |
| |
| export const NickNameInput = (props) => { |
| const [isSelected, setIsSelected] = React.useState(false); |
| const [input, setInput] = React.useState(props.defaultValue); |
| const [startAdornmentVisibility, setStartAdornmentVisibility] = React.useState() |
| |
| const onChange = React.useCallback((event) => { |
| setInput(event.target.value) |
| props.onChange?.(event) |
| }, [props.onChange]) |
| |
| React.useEffect(() => { |
| setStartAdornmentVisibility((isSelected || input) ? "visible" : "hidden") |
| }, [isSelected, input]) |
| |
| return ( |
| <TextField |
| {...props} |
| label="Nickname, surname..." |
| variant="standard" |
| InputLabelProps={{ shrink: !!(isSelected || input) }} |
| onChange={onChange} |
| InputProps={{ |
| startAdornment: <StyledPenIconLight sx={{visibility: startAdornmentVisibility}}/>, |
| }} |
| onFocus={() => setIsSelected(true)} |
| onBlur={() => setIsSelected(false)} |
| /> |
| ) |
| } |
| |
| export const RegularInput = (props) => { |
| const [isSelected, setIsSelected] = React.useState(false); |
| const [input, setInput] = React.useState(props.defaultValue); |
| const [startAdornmentVisibility, setStartAdornmentVisibility] = React.useState() |
| const [endAdornmentVisibility, setEndAdornmentVisibility] = React.useState() |
| |
| const onChange = React.useCallback((event) => { |
| setInput(event.target.value) |
| props.onChange?.(event) |
| }, [props.onChange]) |
| |
| React.useEffect(() => { |
| setStartAdornmentVisibility((isSelected || input) ? "visible" : "hidden") |
| setEndAdornmentVisibility((isSelected || input) ? "hidden" : "visible") |
| }, [isSelected, input]) |
| |
| return ( |
| <TextField |
| {...props} |
| variant="standard" |
| InputLabelProps={{ shrink: !!(isSelected || input) }} |
| onChange={onChange} |
| InputProps={{ |
| startAdornment: <StyledPenIconLight sx={{visibility: startAdornmentVisibility}}/>, |
| endAdornment: <StyledPenIconDark sx={{visibility: endAdornmentVisibility}}/>, |
| }} |
| onFocus={() => setIsSelected(true)} |
| onBlur={() => setIsSelected(false)} |
| /> |
| ) |
| } |