@acusti/input-text
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -17,2 +17,3 @@ import * as React from 'react'; | ||
readOnly?: boolean; | ||
selectTextOnFocus?: boolean; | ||
tabIndex?: number; | ||
@@ -22,5 +23,3 @@ title?: string; | ||
}; | ||
declare const InputText: React.ForwardRefExoticComponent< | ||
Props & React.RefAttributes<HTMLInputElement> | ||
>; | ||
declare const InputText: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLInputElement>>; | ||
export default InputText; |
import * as React from 'react'; | ||
const { useCallback, useEffect, useImperativeHandle, useRef } = React; | ||
const InputText = React.forwardRef( | ||
( | ||
{ | ||
autoComplete, | ||
className, | ||
disabled, | ||
initialValue, | ||
maxLength, | ||
minLength, | ||
onBlur, | ||
onChange, | ||
onFocus, | ||
onKeyDown, | ||
onKeyUp, | ||
pattern, | ||
placeholder, | ||
readOnly, | ||
tabIndex, | ||
title, | ||
type = 'text', | ||
}, | ||
ref, | ||
) => { | ||
const inputRef = useRef(null); | ||
useImperativeHandle(ref, () => inputRef.current); | ||
// If props.initialValue changes, override input value from it | ||
useEffect(() => { | ||
if (!inputRef.current) return; | ||
inputRef.current.value = initialValue || ''; | ||
}, [initialValue]); | ||
const isInitialSelectionRef = useRef(true); | ||
const handleBlur = useCallback( | ||
(event) => { | ||
if (onBlur) onBlur(event); | ||
// When input loses focus, reset isInitialSelection to true for next onSelect event | ||
isInitialSelectionRef.current = true; | ||
}, | ||
[onBlur], | ||
); | ||
// NOTE Selecting the contents of the input onFocus makes for the best UX, | ||
// but it doesn’t work in Safari, so we use the initial onSelect event instead | ||
const handleSelect = useCallback(() => { | ||
// Do nothing if this isn’t the initial select-on-focus event | ||
if (!isInitialSelectionRef.current) return; | ||
// This is the initial select-on-focus event, so reset isInitialSelection to false | ||
isInitialSelectionRef.current = false; | ||
const input = inputRef.current; | ||
// Do nothing if input has no value | ||
if (!input || !input.value) return; | ||
// Do nothing if input is no longer the document’s activeElement | ||
if (input.ownerDocument.activeElement !== input) return; | ||
// Do nothing if input’s contents are already selected | ||
const valueLength = input.value.length; | ||
if (input.selectionStart === 0 && input.selectionEnd === valueLength) return; | ||
input.selectionStart = 0; | ||
input.selectionEnd = valueLength; | ||
}, []); | ||
return React.createElement('input', { | ||
autoComplete: autoComplete, | ||
className: className, | ||
defaultValue: initialValue || '', | ||
disabled: disabled, | ||
maxLength: maxLength, | ||
minLength: minLength, | ||
onBlur: handleBlur, | ||
onChange: onChange, | ||
onFocus: onFocus, | ||
onKeyDown: onKeyDown, | ||
onKeyUp: onKeyUp, | ||
onSelect: handleSelect, | ||
pattern: pattern, | ||
placeholder: placeholder, | ||
readOnly: readOnly, | ||
ref: inputRef, | ||
tabIndex: tabIndex, | ||
title: title, | ||
type: type, | ||
}); | ||
}, | ||
); | ||
const InputText = React.forwardRef(({ autoComplete, className, disabled, initialValue, maxLength, minLength, onBlur, onChange, onFocus, onKeyDown, onKeyUp, pattern, placeholder, readOnly, selectTextOnFocus, tabIndex, title, type = 'text', }, ref) => { | ||
const inputRef = useRef(null); | ||
useImperativeHandle(ref, () => inputRef.current); | ||
// If props.initialValue changes, override input value from it | ||
useEffect(() => { | ||
if (!inputRef.current) | ||
return; | ||
inputRef.current.value = initialValue || ''; | ||
}, [initialValue]); | ||
const isInitialSelectionRef = useRef(true); | ||
const handleBlur = useCallback((event) => { | ||
if (onBlur) | ||
onBlur(event); | ||
// When input loses focus, reset isInitialSelection to true for next onSelect event | ||
isInitialSelectionRef.current = true; | ||
}, [onBlur]); | ||
// NOTE Selecting the contents of the input onFocus makes for the best UX, | ||
// but it doesn’t work in Safari, so we use the initial onSelect event instead | ||
const handleSelect = useCallback(() => { | ||
// Do nothing if this isn’t the initial select-on-focus event | ||
if (!isInitialSelectionRef.current) | ||
return; | ||
// This is the initial select-on-focus event, so reset isInitialSelection to false | ||
isInitialSelectionRef.current = false; | ||
const input = inputRef.current; | ||
// Do nothing if input has no value | ||
if (!input || !input.value) | ||
return; | ||
// Do nothing if input is no longer the document’s activeElement | ||
if (input.ownerDocument.activeElement !== input) | ||
return; | ||
// Do nothing if input’s contents are already selected | ||
const valueLength = input.value.length; | ||
if (input.selectionStart === 0 && input.selectionEnd === valueLength) | ||
return; | ||
input.selectionStart = 0; | ||
input.selectionEnd = valueLength; | ||
}, []); | ||
return (React.createElement("input", { autoComplete: autoComplete, className: className, defaultValue: initialValue || '', disabled: disabled, maxLength: maxLength, minLength: minLength, onBlur: selectTextOnFocus ? handleBlur : onBlur, onChange: onChange, onFocus: onFocus, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onSelect: selectTextOnFocus ? handleSelect : undefined, pattern: pattern, placeholder: placeholder, readOnly: readOnly, ref: inputRef, tabIndex: tabIndex, title: title, type: type })); | ||
}); | ||
export default InputText; | ||
//# sourceMappingURL=InputText.js.map | ||
//# sourceMappingURL=InputText.js.map |
{ | ||
"name": "@acusti/input-text", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
@@ -9,3 +9,4 @@ # @acusti/input-text | ||
`InputText` is a React component that renders an uncontrolled input whose | ||
value is overwritten whenever props.initialValue changes and that selects | ||
the contents of the input whenever it is focused. | ||
value is overwritten whenever props.initialValue changes. Also, if | ||
props.selectTextOnFocus is true, it selects the entire contents of the | ||
input whenever the input is focused. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12
8456
67