fix(striker-ui): allow password fields to be visible

main
Tsu-ba-me 2 years ago
parent 7abca9b508
commit 09dbe0edf7
  1. 84
      striker-ui/components/OutlinedInput/OutlinedInput.tsx
  2. 18
      striker-ui/components/OutlinedInputWithLabel.tsx

@ -1,17 +1,64 @@
import { FC } from 'react';
import { import {
Visibility as MUIVisibilityIcon,
VisibilityOff as MUIVisibilityOffIcon,
} from '@mui/icons-material';
import {
IconButton as MUIIconButton,
OutlinedInput as MUIOutlinedInput, OutlinedInput as MUIOutlinedInput,
outlinedInputClasses as muiOutlinedInputClasses, outlinedInputClasses as muiOutlinedInputClasses,
OutlinedInputProps as MUIOutlinedInputProps, OutlinedInputProps as MUIOutlinedInputProps,
} from '@mui/material'; } from '@mui/material';
import { cloneElement, FC, ReactElement, useMemo, useState } from 'react';
import { GREY, TEXT, UNSELECTED } from '../../lib/consts/DEFAULT_THEME'; import { GREY, TEXT, UNSELECTED } from '../../lib/consts/DEFAULT_THEME';
type OutlinedInputProps = MUIOutlinedInputProps; type OutlinedInputProps = MUIOutlinedInputProps;
const INPUT_TYPES: Record<
Exclude<MUIOutlinedInputProps['type'], undefined>,
string
> = {
password: 'password',
text: 'text',
};
const OutlinedInput: FC<OutlinedInputProps> = (outlinedInputProps) => { const OutlinedInput: FC<OutlinedInputProps> = (outlinedInputProps) => {
const { label, sx, ...outlinedInputRestProps } = outlinedInputProps; const {
const combinedSx = { endAdornment,
label,
sx,
inputProps: { type: baseType, ...inputRestProps } = {},
...outlinedInputRestProps
} = outlinedInputProps;
const [type, setType] = useState<string>(baseType);
const additionalEndAdornment = useMemo(
() => (
<>
{baseType === INPUT_TYPES.password && (
<MUIIconButton
onClick={() => {
setType((previous) =>
previous === INPUT_TYPES.password
? INPUT_TYPES.text
: INPUT_TYPES.password,
);
}}
>
{type === INPUT_TYPES.password ? (
<MUIVisibilityIcon />
) : (
<MUIVisibilityOffIcon />
)}
</MUIIconButton>
)}
</>
),
[baseType, type],
);
const combinedSx = useMemo(
() => ({
color: GREY, color: GREY,
[`& .${muiOutlinedInputClasses.notchedOutline}`]: { [`& .${muiOutlinedInputClasses.notchedOutline}`]: {
@ -37,12 +84,41 @@ const OutlinedInput: FC<OutlinedInputProps> = (outlinedInputProps) => {
}, },
...sx, ...sx,
}; }),
[label, sx],
);
const combinedEndAdornment = useMemo(() => {
let result;
if (typeof endAdornment === 'object') {
const casted = endAdornment as ReactElement;
const {
props: { children: castedChildren = [], ...castedRestProps },
} = casted;
return cloneElement(casted, {
...castedRestProps,
children: (
<>
{additionalEndAdornment}
{castedChildren}
</>
),
});
}
return result;
}, [additionalEndAdornment, endAdornment]);
return ( return (
<MUIOutlinedInput <MUIOutlinedInput
{...{ {...{
endAdornment: combinedEndAdornment,
label, label,
inputProps: {
type,
...inputRestProps,
},
...outlinedInputRestProps, ...outlinedInputRestProps,
sx: combinedSx, sx: combinedSx,
}} }}

@ -1,12 +1,13 @@
import { FC, useCallback, useMemo, useState } from 'react'; import { FC, useCallback, useMemo, useState } from 'react';
import { QuestionMark as MUIQuestionMarkIcon } from '@mui/icons-material';
import { import {
FormControl as MUIFormControl, FormControl as MUIFormControl,
FormControlProps as MUIFormControlProps, FormControlProps as MUIFormControlProps,
IconButton as MUIIconButton, IconButton as MUIIconButton,
IconButtonProps as MUIIconButtonProps, IconButtonProps as MUIIconButtonProps,
iconButtonClasses as muiIconButtonClasses,
InputAdornment as MUIInputAdornment, InputAdornment as MUIInputAdornment,
} from '@mui/material'; } from '@mui/material';
import { QuestionMark as MUIQuestionMarkIcon } from '@mui/icons-material';
import { GREY } from '../lib/consts/DEFAULT_THEME'; import { GREY } from '../lib/consts/DEFAULT_THEME';
@ -113,21 +114,18 @@ const OutlinedInputWithLabel: FC<OutlinedInputWithLabelProps> = ({
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
'& > :not(:first-child)': { [`& > .${muiIconButtonClasses.root}`]: {
color: GREY,
},
[`& > :not(:first-child, .${muiIconButtonClasses.root})`]: {
marginLeft: '.3em', marginLeft: '.3em',
}, },
}} }}
> >
{endAdornment} {endAdornment}
{isShowHelpButton && ( {isShowHelpButton && (
<MUIIconButton <MUIIconButton onClick={handleHelp} tabIndex={-1}>
onClick={handleHelp}
sx={{
color: GREY,
padding: '.1em',
}}
tabIndex={-1}
>
<MUIQuestionMarkIcon /> <MUIQuestionMarkIcon />
</MUIIconButton> </MUIIconButton>
)} )}

Loading…
Cancel
Save