From ffac42880a47671548aed0d53055374191976acd Mon Sep 17 00:00:00 2001 From: satnaing Date: Sat, 14 Sep 2024 12:40:09 +0700 Subject: [PATCH] fix: optimize onComplete/onIncomplete invocation Ensure onComplete is invoked only once when the pin input is fully completed. Invoke onIncomplete only once when the pin input changes from complete to incomplete. Adjust default font-size for pin-input-raw snippet. --- src/assets/snippets/pin-input-raw.ts | 17 ++++++++++------- src/assets/snippets/pin-input-shadcn.ts | 15 +++++++++------ src/components/ui/pin-input.tsx | 15 +++++++++------ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/assets/snippets/pin-input-raw.ts b/src/assets/snippets/pin-input-raw.ts index 11a23ff..de33ffa 100644 --- a/src/assets/snippets/pin-input-raw.ts +++ b/src/assets/snippets/pin-input-raw.ts @@ -114,15 +114,18 @@ const PinInput = React.forwardRef( onChange(pinValue) }, [onChange, pinValue]) - /* call onComplete func if pinValue is valid and completed */ + /* call onComplete/onIncomplete func if pinValue is valid and completed/incompleted */ + const completeRef = React.useRef(pinValue.length === length); React.useEffect(() => { - if (onComplete && pinValue.length === length) { - onComplete(pinValue) + if (pinValue.length === length && completeRef.current === false) { + completeRef.current = true; + if (onComplete) onComplete(pinValue); } - if (onIncomplete && pinValue.length !== length) { - onIncomplete(pinValue) + if (pinValue.length !== length && completeRef.current === true) { + completeRef.current = false; + if (onIncomplete) onIncomplete(pinValue); } - }, [length, onComplete, onIncomplete, pinValue]) + }, [length, onComplete, onIncomplete, pinValue, pins, value]); /* focus on first input field if autoFocus is set */ React.useEffect(() => { @@ -207,7 +210,7 @@ const PinInputFieldNoRef = ( { className, component, - fontSize = '2.5rem', + fontSize = '1rem', ...props }: PinInputFieldProps & (React.ComponentType extends undefined diff --git a/src/assets/snippets/pin-input-shadcn.ts b/src/assets/snippets/pin-input-shadcn.ts index 6d3272d..91baa72 100644 --- a/src/assets/snippets/pin-input-shadcn.ts +++ b/src/assets/snippets/pin-input-shadcn.ts @@ -115,15 +115,18 @@ const PinInput = React.forwardRef( onChange(pinValue) }, [onChange, pinValue]); - /* call onComplete func if pinValue is valid and completed */ + /* call onComplete/onIncomplete func if pinValue is valid and completed/incompleted */ + const completeRef = React.useRef(pinValue.length === length); React.useEffect(() => { - if (onComplete && pinValue.length === length) { - onComplete(pinValue); + if (pinValue.length === length && completeRef.current === false) { + completeRef.current = true; + if (onComplete) onComplete(pinValue); } - if (onIncomplete && pinValue.length !== length) { - onIncomplete(pinValue); + if (pinValue.length !== length && completeRef.current === true) { + completeRef.current = false; + if (onIncomplete) onIncomplete(pinValue); } - }, [length, onComplete, onIncomplete, pinValue]); + }, [length, onComplete, onIncomplete, pinValue, pins, value]); /* focus on first input field if autoFocus is set */ React.useEffect(() => { diff --git a/src/components/ui/pin-input.tsx b/src/components/ui/pin-input.tsx index b207553..b20ccbe 100644 --- a/src/components/ui/pin-input.tsx +++ b/src/components/ui/pin-input.tsx @@ -115,15 +115,18 @@ const PinInput = React.forwardRef( onChange(pinValue); }, [onChange, pinValue]); - /* call onComplete func if pinValue is valid and completed */ + /* call onComplete/onIncomplete func if pinValue is valid and completed/incompleted */ + const completeRef = React.useRef(pinValue.length === length); React.useEffect(() => { - if (onComplete && pinValue.length === length) { - onComplete(pinValue); + if (pinValue.length === length && completeRef.current === false) { + completeRef.current = true; + if (onComplete) onComplete(pinValue); } - if (onIncomplete && pinValue.length !== length) { - onIncomplete(pinValue); + if (pinValue.length !== length && completeRef.current === true) { + completeRef.current = false; + if (onIncomplete) onIncomplete(pinValue); } - }, [length, onComplete, onIncomplete, pinValue]); + }, [length, onComplete, onIncomplete, pinValue, pins, value]); /* focus on first input field if autoFocus is set */ React.useEffect(() => {