Skip to content

Commit

Permalink
fix(clerk-js): Wait for zxcvbn before showing success message
Browse files Browse the repository at this point in the history
chore(clerk-js): Replace NodeJS.Timeout type

refactor(clerk-js): Extract inAnimation ternary into variable

refactor(clerk-js): Handle the undefined case in getElementProps
  • Loading branch information
desiprisg committed Oct 24, 2023
1 parent 8173f98 commit 26ef242
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 23 deletions.
22 changes: 12 additions & 10 deletions packages/clerk-js/src/ui/elements/FormControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,13 @@ function useFormTextAnimation() {
animation: 'none',
};
}

const inAnimation = options?.inDelay ? animations.inDelayAnimation : animations.inAnimation;

return t => ({
animation: `${
enterAnimation
? options?.inDelay
? animations.inDelayAnimation
: animations.inAnimation
: animations.outAnimation
} ${t.transitionDuration.$textField} ${t.transitionTiming.$common}`,
animation: `${enterAnimation ? inAnimation : animations.outAnimation} ${t.transitionDuration.$textField} ${
t.transitionTiming.$common
}`,
transition: `height ${t.transitionDuration.$slow} ${t.transitionTiming.$common}`, // This is expensive but required for a smooth layout shift
});
},
Expand Down Expand Up @@ -205,7 +204,10 @@ export const FormFeedback = (props: FormFeedbackProps) => {
return max;
}, [heightA, heightB]);

const getElementProps = (type: FormFeedbackDescriptorsKeys) => {
const getElementProps = (type?: FormFeedbackDescriptorsKeys) => {
if (!type) {
return {};
}
const descriptor = (elementDescriptors?.[type] || defaultElementDescriptors[type]) as ElementDescriptor | undefined;
return {
elementDescriptor: descriptor,
Expand Down Expand Up @@ -235,7 +237,7 @@ export const FormFeedback = (props: FormFeedbackProps) => {
sx={[getFormTextAnimation(!!feedback)]}
>
<InfoComponentA
{...(feedbacks.a?.feedbackType ? getElementProps(feedbacks.a.feedbackType) : {})}
{...getElementProps(feedbacks.a?.feedbackType)}
ref={calculateHeightA}
sx={[
() => ({
Expand All @@ -246,7 +248,7 @@ export const FormFeedback = (props: FormFeedbackProps) => {
localizationKey={feedbacks.a?.feedback}
/>
<InfoComponentB
{...(feedbacks.b?.feedbackType ? getElementProps(feedbacks.b.feedbackType) : {})}
{...getElementProps(feedbacks.b?.feedbackType)}
ref={calculateHeightB}
sx={[
() => ({
Expand Down
9 changes: 6 additions & 3 deletions packages/clerk-js/src/ui/elements/PasswordInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>((p
const [hidden, setHidden] = React.useState(true);
const { id, onChange: onChangeProp, validatePassword: validatePasswordProp = false, ...rest } = props;
const inputRef = useRef<HTMLInputElement>(null);
const [timeoutState, setTimeoutState] = useState<NodeJS.Timeout | null>(null);
const [timeoutState, setTimeoutState] = useState<ReturnType<typeof setTimeout> | null>(null);

const {
userSettings: { passwordSettings },
Expand All @@ -41,6 +41,7 @@ export const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>((p
if (inputRef.current === document.activeElement) {
formControlProps?.setInfo?.(message);
} else {
// Turn the suggestion into an error if not focused.
formControlProps?.setError?.(message);
}
},
Expand Down Expand Up @@ -72,11 +73,13 @@ export const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>((p
onChange={onChange}
onBlur={e => {
rest.onBlur?.(e);
onChange(e);
// Call validate password because to calculate the new feedbackType as the element is now blurred
validatePassword(e.target.value);
}}
onFocus={e => {
rest.onFocus?.(e);
onChange(e);
// Call validate password because to calculate the new feedbackType as the element is now focused
validatePassword(e.target.value);
}}
//@ts-expect-error
ref={mergeRefs(ref, inputRef)}
Expand Down
2 changes: 1 addition & 1 deletion packages/clerk-js/src/ui/hooks/useDebounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';

export function useDebounce<T>(value: T, delayInMs?: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
const [timeoutState, setTimeoutState] = useState<NodeJS.Timeout | undefined>(undefined);
const [timeoutState, setTimeoutState] = useState<ReturnType<typeof setTimeout> | undefined>(undefined);

useEffect(() => {
const handleDebounce = () => {
Expand Down
6 changes: 2 additions & 4 deletions packages/clerk-js/src/ui/utils/useFormControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { ClerkAPIError } from '@clerk/types';
import type { HTMLInputTypeAttribute } from 'react';
import { useState } from 'react';

import { DEBOUNCE_MS } from '../../core/constants';
import { useDebounce } from '../hooks';
import type { LocalizationKey } from '../localization';
import { useLocalizations } from '../localization';
Expand Down Expand Up @@ -179,12 +178,11 @@ type DebouncingOption = {
isFocused?: boolean;
delayInMs?: number;
};

export const useFormControlFeedback = (opts?: DebouncingOption): DebouncedFeedback => {
const { feedback = '', delayInMs = 100, feedbackType = 'info', isFocused = false } = opts || {};

const debouncedFocused = useDebounce(isFocused, DEBOUNCE_MS);

const shouldHide = debouncedFocused ? false : ['info', 'warning'].includes(feedbackType);
const shouldHide = isFocused ? false : ['info', 'warning'].includes(feedbackType);

const debouncedState = useDebounce(
{ feedback: shouldHide ? '' : feedback, feedbackType: shouldHide ? 'info' : feedbackType },
Expand Down
11 changes: 6 additions & 5 deletions packages/clerk-js/src/utils/passwords/password.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const createValidatePassword = (config: UsePasswordConfig, callbacks?: Va
const { show_zxcvbn, validatePassword: validatePasswordProp } = config;
const getComplexity = createValidateComplexity(config);
const getScore = createValidatePasswordStrength(config);
let result = {} satisfies PasswordValidation;
let result: PasswordValidation = {} satisfies PasswordValidation;

return (password: string, internalCallbacks?: ValidatePasswordCallbacks) => {
const {
Expand Down Expand Up @@ -65,9 +65,10 @@ export const createValidatePassword = (config: UsePasswordConfig, callbacks?: Va
});
}

internalOnValidation({
...result,
complexity: failedValidationsComplexity,
});
if (result.complexity && Object.keys(result.complexity).length === 0 && show_zxcvbn) {
return;
}

internalOnValidation(result);
};
};

0 comments on commit 26ef242

Please sign in to comment.