1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-08-09 07:25:24 +02:00

Add visibility toggle of password input. Closes #2

This commit is contained in:
Maksim Eltyshev 2019-11-15 03:45:59 +05:00
parent a11f6260c0
commit 00c7f514ae
25 changed files with 111 additions and 92 deletions

View file

@ -1,28 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Input as SemanticUIInput } from 'semantic-ui-react';
import MaskedInput from './MaskedInput';
import InputPassword from './InputPassword';
import InputMask from './InputMask';
const Input = React.forwardRef(({ mask, maskChar, ...props }, ref) => {
const nextProps = props;
const Input = SemanticUIInput;
if (mask) {
nextProps.input = <MaskedInput mask={mask} maskChar={maskChar} />;
}
Input.Password = InputPassword;
Input.Mask = InputMask;
// eslint-disable-next-line react/jsx-props-no-spreading
return <SemanticUIInput {...nextProps} ref={ref} />;
});
Input.propTypes = {
mask: PropTypes.string,
maskChar: PropTypes.string,
};
Input.defaultProps = {
mask: undefined,
maskChar: undefined,
};
export default React.memo(Input);
export default Input;

View file

@ -0,0 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Input } from 'semantic-ui-react';
import MaskedInput from './MaskedInput';
const InputMask = React.forwardRef(({ mask, maskChar, ...props }, ref) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<Input {...props} ref={ref} input={<MaskedInput mask={mask} maskChar={maskChar} />} />
));
InputMask.propTypes = {
mask: PropTypes.string.isRequired,
maskChar: PropTypes.string,
};
InputMask.defaultProps = {
maskChar: undefined,
};
export default React.memo(InputMask);

View file

@ -0,0 +1,22 @@
import React, { useCallback } from 'react';
import { Icon, Input } from 'semantic-ui-react';
import { useToggle } from '../../../hooks';
const InputPassword = React.forwardRef((props, ref) => {
const [isHidden, toggleHidden] = useToggle(true);
const handleToggleClick = useCallback(() => {
toggleHidden();
}, [toggleHidden]);
return (
<Input
{...props} // eslint-disable-line react/jsx-props-no-spreading
ref={ref}
type={isHidden ? 'password' : 'text'}
icon={<Icon link name={isHidden ? 'eye slash' : 'eye'} onClick={handleToggleClick} />}
/>
);
});
export default React.memo(InputPassword);

View file

@ -0,0 +1,8 @@
import usePrevious from './use-previous';
import useToggle from './use-toggle';
import useForceUpdate from './use-force-update';
import useDidUpdate from './use-did-update';
export {
usePrevious, useToggle, useForceUpdate, useDidUpdate,
};

View file

@ -0,0 +1,13 @@
import { useEffect, useRef } from 'react';
export default (callback, dependencies) => {
const isMounted = useRef(false);
useEffect(() => {
if (isMounted.current) {
callback();
} else {
isMounted.current = true;
}
}, dependencies); // eslint-disable-line react-hooks/exhaustive-deps
};

View file

@ -0,0 +1,3 @@
import useToggle from './use-toggle';
export default () => useToggle()[1];

View file

@ -0,0 +1,11 @@
import { useEffect, useRef } from 'react';
export default (value) => {
const prevValue = useRef();
useEffect(() => {
prevValue.current = value;
}, [value]);
return prevValue.current;
};

View file

@ -0,0 +1,11 @@
import { useCallback, useState } from 'react';
export default (defaultState = false) => {
const [state, setState] = useState(defaultState);
const toggle = useCallback(() => {
setState((prevState) => !prevState);
}, []);
return [state, toggle];
};