@acusti/input-text
Advanced tools
Comparing version 0.7.0 to 0.8.0
@@ -26,5 +26,3 @@ 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, max, maxLength, min, minLength, name, onBlur, onChange, onFocus, onKeyDown, onKeyUp, pattern, placeholder, readOnly, selectTextOnFocus, step, 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, max: max, maxLength: maxLength, min: min, 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, step: step, tabIndex: tabIndex, title: title, type: type })); | ||
}); | ||
export default InputText; | ||
//# sourceMappingURL=InputText.js.map | ||
//# sourceMappingURL=InputText.js.map |
{ | ||
"name": "@acusti/input-text", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "sideEffects": false, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
13229
190