@acusti/input-text
Advanced tools
Comparing version 0.8.0 to 0.9.0
@@ -26,3 +26,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, 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 })); | ||
}); | ||
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.8.0", | ||
"version": "0.9.0", | ||
"type": "module", | ||
@@ -28,5 +28,5 @@ "sideEffects": false, | ||
"peerDependencies": { | ||
"react": "^16.8 || ^17", | ||
"react-dom": "^16.8 || ^17" | ||
"react": "^16.8 || ^17 || ^18", | ||
"react-dom": "^16.8 || ^17 || ^18" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
13994
241