Last active
April 15, 2026 19:12
-
-
Save isocroft/b488bb3dc7432835a244d374c19e242a to your computer and use it in GitHub Desktop.
A ReactJS hook that is used to track changes to the characters in the text of an input text box.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useRef, useEffect } from "react": | |
| import { useIsFirstRender } from "react-busser"; | |
| import type { Ref } from "react"; | |
| const use = <D extends unknown>(promise: Promise<D>) => { | |
| }; | |
| export const useInuptValueUpdate = ({ value, defaultedValue = "" }) => { | |
| const isFirstRender: boolean = useIsFirstRender(); | |
| const inputRef: Ref<HTMLInputElement | null> = useRef<HTMLInputElement | null>(null); | |
| const lastCaretStart = useRef<number>(0); | |
| // `defaultedValue` should equal `props.defaultValue` | |
| // `value` should equal `props.value` | |
| useEffect(() => { | |
| if (inputRef.current === null) { | |
| return; | |
| } | |
| if (isFirstRender | |
| && (typeof defaultedValue !== "string" | |
| || defaultedValue.length > 0)){ | |
| inputRef.current.value = defaultedValue ?? ""; | |
| } else { | |
| //ref.current.value = value ?? ""; | |
| inputRef.current.selectionStart = ref.current.selectionEnd = lastCaretStart.current ?? ref.current.value.length; | |
| } | |
| }, [defaultedValue, isFirstRender, value]); | |
| const applyInputTransform = ( | |
| inputType: string, | |
| inputTextEntry: string | |
| ) => { | |
| previousInputValue: string = inputRef.current.value; | |
| caretStartPosition: number = inputRef.current.selectionStart; | |
| carentEndPosition: number = inputRef.current.selectionEnd; | |
| let nextInputValue: string; | |
| let nextCaretStartPosition: number; | |
| if (caretStartPosition !== carentEndPosition) { | |
| nextInputValue = previousInputValue.slice(0, caretStartPosition) + (inputTextEntry || "") + previousInputValue.slice(carentEndPosition); | |
| nextCaretStartPosition = caretStartPosition; | |
| if (inputType.startsWith("insert")) nextCaretStartPosition++; | |
| } else if (inputType.startsWith("insert")) { | |
| nextInputValue = previousInputValue.slice(0, caretStartPosition) + inputTextEntry + previousInputValue.slice(carentEndPosition); | |
| nextCaretStartPosition = caretStartPosition + inputTextEntry.length; | |
| } else if (inputType === "deleteContentBackward") { | |
| nextInputValue = previousInputValue.slice(0, nextCaretStartPosition) + previousInputValue.slice(caretStartPosition); | |
| nextCaretStartPosition = Math.max(0, caretStartPosition - 1); | |
| } else if (inputType === "deleteContentForward") { | |
| nextInputValue = previousInputValue.slice(0, caretStartPosition) + previousInputValue.slice(caretStartPosition + 1); | |
| nextCaretStartPosition = caretStartPosition; | |
| } else { | |
| nextInputValue = previousInputValue; | |
| nextCaretStartPosition = caretStartPosition; | |
| } | |
| lastCaretStart.current = nextCaretStartPosition; | |
| inputRef.current.value = nextInputValue; | |
| return nextInputValue; | |
| }; | |
| return { | |
| inputRef, | |
| applyInputTransform | |
| } as const; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.