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

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

@ -1,48 +1,124 @@
import { FC } from 'react';
import {
Visibility as MUIVisibilityIcon,
VisibilityOff as MUIVisibilityOffIcon,
} from '@mui/icons-material';
import {
IconButton as MUIIconButton,
OutlinedInput as MUIOutlinedInput,
outlinedInputClasses as muiOutlinedInputClasses,
OutlinedInputProps as MUIOutlinedInputProps,
} from '@mui/material';
import { cloneElement, FC, ReactElement, useMemo, useState } from 'react';
import { GREY, TEXT, UNSELECTED } from '../../lib/consts/DEFAULT_THEME';
type OutlinedInputProps = MUIOutlinedInputProps;
const INPUT_TYPES: Record<
Exclude<MUIOutlinedInputProps['type'], undefined>,
string
> = {
password: 'password',
text: 'text',
};
const OutlinedInput: FC<OutlinedInputProps> = (outlinedInputProps) => {
const { label, sx, ...outlinedInputRestProps } = outlinedInputProps;
const combinedSx = {
color: GREY,
const {
endAdornment,
label,
sx,
inputProps: { type: baseType, ...inputRestProps } = {},
...outlinedInputRestProps
} = outlinedInputProps;
[`& .${muiOutlinedInputClasses.notchedOutline}`]: {
borderColor: UNSELECTED,
},
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,
'&:hover': {
[`& .${muiOutlinedInputClasses.notchedOutline}`]: {
borderColor: GREY,
borderColor: UNSELECTED,
},
'&:hover': {
[`& .${muiOutlinedInputClasses.notchedOutline}`]: {
borderColor: GREY,
},
},
},
[`&.${muiOutlinedInputClasses.focused}`]: {
color: TEXT,
[`&.${muiOutlinedInputClasses.focused}`]: {
color: TEXT,
[`& .${muiOutlinedInputClasses.notchedOutline}`]: {
borderColor: GREY,
[`& .${muiOutlinedInputClasses.notchedOutline}`]: {
borderColor: GREY,
'& legend': {
paddingRight: label ? '1.2em' : 0,
'& legend': {
paddingRight: label ? '1.2em' : 0,
},
},
},
},
...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 (
<MUIOutlinedInput
{...{
endAdornment: combinedEndAdornment,
label,
inputProps: {
type,
...inputRestProps,
},
...outlinedInputRestProps,
sx: combinedSx,
}}

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

Loading…
Cancel
Save