Web: Components: PasswordInput: added isSimulateType

This commit is contained in:
Nikita Gopienko 2024-08-29 17:25:14 +03:00
parent ee7fe469b2
commit ccebb14019
3 changed files with 86 additions and 71 deletions

View File

@ -104,6 +104,8 @@ const PasswordInput = React.forwardRef(
tooltipOffsetTop,
isAutoFocussed,
tooltipAllowedCharacters,
isSimulateType,
simulateSymbol,
}: PasswordInputProps,
ref,
) => {
@ -119,6 +121,8 @@ const PasswordInput = React.forwardRef(
validSpecial: false,
});
const [caretPosition, setCaretPosition] = useState();
const refProgress = useRef(null);
const refTooltip = useRef(null);
const refTooltipContent = useRef(null);
@ -268,10 +272,52 @@ const PasswordInput = React.forwardRef(
[onValidateInput, testStrength],
);
const setPasswordSettings = useCallback(
(newPassword: string) => {
let newValue;
const oldPassword = state.value ?? "";
const oldPasswordLength = oldPassword.length;
const newCaretPosition = document.getElementById(
"conversion-password",
)?.selectionStart;
setCaretPosition(newCaretPosition);
const newCharactersUntilCaret = newPassword.substring(
0,
newCaretPosition,
);
const unchangedStartCharacters = newCharactersUntilCaret
.split("")
.filter((el) => el === simulateSymbol).length;
const unchangedEndingCharacters =
newPassword.substring(newCaretPosition).length;
const addedCharacters = newCharactersUntilCaret.substring(
unchangedStartCharacters,
);
const startingPartOldPassword = oldPassword.substring(
0,
unchangedStartCharacters,
);
const countOfCharacters = oldPasswordLength - unchangedEndingCharacters;
const endingPartOldPassword = oldPassword.substring(countOfCharacters);
newValue = startingPartOldPassword + addedCharacters;
if (unchangedEndingCharacters) {
newValue += endingPartOldPassword;
}
return newValue;
},
[simulateSymbol, state.value],
);
const onChangeAction = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
onChange?.(e);
if (refTooltip.current) {
const tooltip = refTooltip.current as TooltipRefProps;
if (tooltip?.isOpen) {
@ -279,17 +325,30 @@ const PasswordInput = React.forwardRef(
}
}
let value = e.target.value;
if (isSimulateType) {
value = setPasswordSettings(e.target.value);
}
onChange?.(e, value);
if (simpleView) {
setState((s) => ({
...s,
value: e.target.value,
value,
}));
return;
}
checkPassword(e.target.value);
checkPassword(value);
},
[onChange, simpleView, checkPassword],
[
onChange,
simpleView,
checkPassword,
isSimulateType,
setPasswordSettings,
],
);
const getNewPassword = React.useCallback(() => {
@ -398,6 +457,14 @@ const PasswordInput = React.forwardRef(
setState((s) => ({ ...s, copyLabel: clipActionResource }));
}, [clipActionResource, clipCopiedResource]);
React.useEffect(() => {
if (caretPosition && state.type === "password" && isSimulateType) {
document
.getElementById("conversion-password")
.setSelectionRange(caretPosition, caretPosition);
}
}, [caretPosition, state.type, state.value, isSimulateType]);
React.useImperativeHandle(
ref,
() => {
@ -501,6 +568,9 @@ const PasswordInput = React.forwardRef(
type === "password" ? "close" : "open"
}`;
const copyPassword = value ?? "";
const bullets = copyPassword.replace(/(.)/g, simulateSymbol);
return (
<>
<InputBlock
@ -511,12 +581,14 @@ const PasswordInput = React.forwardRef(
isDisabled={isDisabled}
iconName={iconName}
iconButtonClassName={iconButtonClassName}
value={value ?? ""}
value={
isSimulateType && type === "password" ? bullets : value ?? ""
}
onIconClick={changeInputType}
onChange={onChangeAction}
scale={scale}
size={size}
type={type}
type={isSimulateType ? InputType.text : type}
iconSize={16}
isIconFill
onBlur={onBlurAction}
@ -610,6 +682,8 @@ PasswordInput.defaultProps = {
specSymbolsRegexStr: "(?=.*[\\x21-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E])",
},
isFullWidth: false,
isSimulateType: false,
simulateSymbol: "•",
};
export { PasswordInput };

View File

@ -60,7 +60,7 @@ export interface PasswordInputProps {
/** Input value */
inputValue?: string;
/** Sets a callback function that is triggered on PasswordInput */
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
onChange?: (e: React.ChangeEvent<HTMLInputElement>, value?: string) => void;
/** Default event that is triggered when the button is already pressed but not released */
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
/** Event that is triggered when the focused item is lost */
@ -135,4 +135,8 @@ export interface PasswordInputProps {
isFullWidth?: boolean;
/** Focus the input field on initial render */
isAutoFocussed?: boolean;
/** Indicating the password type simulation. Disables the browser password window */
isSimulateType?: boolean;
/** Sets simulate input symbol */
simulateSymbol: string;
}

View File

@ -183,66 +183,3 @@ export const getLastColumn = (tableStorageName: string) => {
return null;
};
export const getNewPassword = (
settings: {
minLength?: number;
upperCase?: boolean;
digits?: boolean;
specSymbols?: boolean;
digitsRegexStr?: string;
upperCaseRegexStr?: string;
specSymbolsRegexStr?: string;
allowedCharactersRegexStr?: string;
},
generatorSpecial: string = "!@#$%^&*",
) => {
const passwordSettings = settings ?? {
minLength: 8,
upperCase: false,
digits: false,
specSymbols: false,
digitsRegexStr: "(?=.*\\d)",
upperCaseRegexStr: "(?=.*[A-Z])",
specSymbolsRegexStr: "(?=.*[\\x21-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E])",
};
const length = passwordSettings?.minLength || 0;
const string = "abcdefghijklmnopqrstuvwxyz";
const numeric = "0123456789";
const special = generatorSpecial || "";
let password = "";
let character = "";
while (password.length < length) {
const a = Math.ceil(string.length * Math.random() * Math.random());
const b = Math.ceil(numeric.length * Math.random() * Math.random());
const c = Math.ceil(special.length * Math.random() * Math.random());
let hold = string.charAt(a);
if (passwordSettings?.upperCase) {
hold = password.length % 2 === 0 ? hold.toUpperCase() : hold;
}
character += hold;
if (passwordSettings?.digits) {
character += numeric.charAt(b);
}
if (passwordSettings?.specSymbols) {
character += special.charAt(c);
}
password = character;
}
password = password
.split("")
.sort(() => 0.5 - Math.random())
.join("");
return password.substring(0, length);
};