@acusti/input-text
Advanced tools
Comparing version 0.5.0 to 0.6.0
@@ -23,3 +23,5 @@ import * as React from 'react'; | ||
}; | ||
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, name, 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, name: name, 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 })); | ||
}); | ||
const InputText = React.forwardRef( | ||
( | ||
{ | ||
autoComplete, | ||
className, | ||
disabled, | ||
initialValue, | ||
maxLength, | ||
minLength, | ||
name, | ||
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, | ||
name: name, | ||
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.5.0", | ||
"version": "0.6.0", | ||
"type": "module", | ||
@@ -10,3 +10,4 @@ "sideEffects": false, | ||
"files": [ | ||
"dist" | ||
"dist", | ||
"src" | ||
], | ||
@@ -17,3 +18,3 @@ "repository": { | ||
}, | ||
"author": "andrew patton <andrew@acusti.ca> (http://acusti.ca)", | ||
"author": "andrew patton <andrew@acusti.ca> (https://www.acusti.ca)", | ||
"license": "Unlicense", | ||
@@ -26,3 +27,3 @@ "bugs": { | ||
"@types/react": "^17.0.3", | ||
"typescript": "^4.2.3" | ||
"typescript": "^4.4.3" | ||
}, | ||
@@ -29,0 +30,0 @@ "peerDependencies": { |
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
13480
7
223