diff --git a/src/components/atoms/PasswordTextField.tsx b/src/components/atoms/PasswordTextField.tsx new file mode 100644 index 00000000..b2a91907 --- /dev/null +++ b/src/components/atoms/PasswordTextField.tsx @@ -0,0 +1,44 @@ +/* + * Copyright (C) Contributors to the Suwayomi project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +import { InputAdornment, TextFieldProps } from '@mui/material'; +import TextField from '@mui/material/TextField'; +import { useState } from 'react'; +import IconButton from '@mui/material/IconButton'; +import { Visibility, VisibilityOff } from '@mui/icons-material'; +import { useTranslation } from 'react-i18next'; + +export const PasswordTextField = (props: TextFieldProps) => { + const { t } = useTranslation(); + const [showPassword, setShowPassword] = useState(false); + + const handleClickShowPassword = () => setShowPassword((show) => !show); + + return ( + + + {showPassword ? : } + + + ), + }} + {...props} + /> + ); +}; diff --git a/src/components/settings/text/TextSettingDialog.tsx b/src/components/settings/text/TextSettingDialog.tsx index ce1f59ba..a4dcafbe 100644 --- a/src/components/settings/text/TextSettingDialog.tsx +++ b/src/components/settings/text/TextSettingDialog.tsx @@ -6,15 +6,14 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { Button, Dialog, DialogTitle, InputAdornment } from '@mui/material'; +import { Button, Dialog, DialogTitle } from '@mui/material'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import TextField from '@mui/material/TextField'; -import IconButton from '@mui/material/IconButton'; -import { Visibility, VisibilityOff } from '@mui/icons-material'; import DialogActions from '@mui/material/DialogActions'; -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { PasswordTextField } from '@/components/atoms/PasswordTextField.tsx'; export type TextSettingDialogProps = { settingName: string; @@ -42,9 +41,8 @@ export const TextSettingDialog = ({ const { t } = useTranslation(); const [dialogValue, setDialogValue] = useState(value ?? ''); - const [showPassword, setShowPassword] = useState(false); - const handleClickShowPassword = () => setShowPassword((show) => !show); + const TextFieldComponent = useMemo(() => (isPassword ? PasswordTextField : TextField), [isPassword]); useEffect(() => { if (!value) { @@ -59,7 +57,6 @@ export const TextSettingDialog = ({ setDialogValue(value ?? ''); } - setShowPassword(false); setIsDialogOpen(false); }; @@ -75,7 +72,7 @@ export const TextSettingDialog = ({ {!!dialogDescription && ( {dialogDescription} )} - setDialogValue(e.target.value)} - InputProps={{ - endAdornment: isPassword ? ( - - - {showPassword ? : } - - - ) : null, - }} />