@acusti/input-text
Advanced tools
Comparing version 1.2.1 to 1.3.0
import * as React from 'react'; | ||
import type { InputHTMLAttributes } from 'react'; | ||
type InputElement = HTMLInputElement | HTMLTextAreaElement; | ||
export type Props = { | ||
autoComplete?: string; | ||
autoCapitalize?: 'none' | 'off' | 'sentences' | 'words' | 'characters'; | ||
autoComplete?: HTMLInputElement['autocomplete']; | ||
className?: string; | ||
disabled?: boolean; | ||
enterKeyHint?: InputHTMLAttributes<HTMLInputElement>['enterKeyHint']; | ||
form?: string; | ||
@@ -17,7 +21,7 @@ initialValue?: string; | ||
name?: string; | ||
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => unknown; | ||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => unknown; | ||
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => unknown; | ||
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => unknown; | ||
onKeyUp?: (event: React.KeyboardEvent<HTMLInputElement>) => unknown; | ||
onBlur?: (event: React.FocusEvent<InputElement>) => unknown; | ||
onChange?: (event: React.ChangeEvent<InputElement>) => unknown; | ||
onFocus?: (event: React.FocusEvent<InputElement>) => unknown; | ||
onKeyDown?: (event: React.KeyboardEvent<InputElement>) => unknown; | ||
onKeyUp?: (event: React.KeyboardEvent<InputElement>) => unknown; | ||
pattern?: string; | ||
@@ -30,2 +34,4 @@ placeholder?: string; | ||
step?: number; | ||
style?: React.CSSProperties; | ||
submitOnEnter?: boolean; | ||
tabIndex?: number; | ||
@@ -35,3 +41,3 @@ title?: string; | ||
}; | ||
declare const InputText: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLInputElement>>; | ||
export default InputText; | ||
declare const _default: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLInputElement>>; | ||
export default _default; |
import * as React from 'react'; | ||
const { useCallback, useEffect, useImperativeHandle, useRef } = React; | ||
const InputText = React.forwardRef(({ autoComplete, className, disabled, form, initialValue, list, max, maxHeight = Infinity, maxLength, min, minLength, multiLine, multiple, name, onBlur, onChange, onFocus, onKeyDown, onKeyUp, pattern, placeholder, readOnly, required, selectTextOnFocus, size, step, tabIndex, title, type = 'text', }, ref) => { | ||
const { useCallback, useEffect, useImperativeHandle, useRef, useState } = React; | ||
export default React.forwardRef(function InputText({ autoCapitalize, autoComplete, className, disabled, enterKeyHint, form, initialValue, list, max, maxHeight = Infinity, maxLength, min, minLength, multiLine, multiple, name, onBlur, onChange, onFocus, onKeyDown, onKeyUp, pattern, placeholder, readOnly, required, selectTextOnFocus, size, style, step, submitOnEnter, tabIndex, title, type = 'text', }, ref) { | ||
const inputRef = useRef(null); | ||
useImperativeHandle(ref, () => inputRef.current); | ||
const [inputElement, _setInputElement] = useState(null); | ||
const setInputElement = useCallback((element) => { | ||
inputRef.current = element; | ||
_setInputElement(element); | ||
}, []); | ||
// If props.initialValue changes, override input value from it | ||
@@ -10,7 +15,7 @@ useEffect(() => { | ||
return; | ||
inputRef.current.value = initialValue || ''; | ||
inputRef.current.value = initialValue !== null && initialValue !== void 0 ? initialValue : ''; | ||
}, [initialValue]); | ||
const isInitialSelectionRef = useRef(true); | ||
const handleBlur = useCallback((event) => { | ||
inputRef.current = event.currentTarget; | ||
setInputElement(event.currentTarget); | ||
if (onBlur) | ||
@@ -20,15 +25,14 @@ onBlur(event); | ||
isInitialSelectionRef.current = true; | ||
}, [onBlur]); | ||
}, [onBlur, setInputElement]); | ||
const setInputHeight = useCallback(() => { | ||
const input = inputRef.current; | ||
if (!input) | ||
if (!inputElement) | ||
return; | ||
if (input.style.height) { | ||
input.style.height = ''; | ||
if (inputElement.style.height) { | ||
inputElement.style.height = ''; | ||
} | ||
if (!multiLine) | ||
return; | ||
const height = Math.min(input.scrollHeight, typeof maxHeight === 'string' ? parseFloat(maxHeight) : maxHeight); | ||
input.style.height = `${height}px`; | ||
}, [maxHeight, multiLine]); | ||
const height = Math.min(inputElement.scrollHeight, typeof maxHeight === 'string' ? parseFloat(maxHeight) : maxHeight); | ||
inputElement.style.height = `${height}px`; | ||
}, [inputElement, maxHeight, multiLine]); | ||
// Initialize input height in useEffect | ||
@@ -40,3 +44,3 @@ useEffect(setInputHeight, [setInputHeight]); | ||
const input = event.currentTarget; | ||
inputRef.current = input; | ||
setInputElement(input); | ||
// Do nothing if this isn’t the initial select-on-focus event | ||
@@ -59,9 +63,27 @@ if (!isInitialSelectionRef.current) | ||
input.selectionEnd = valueLength; | ||
}, []); | ||
}, [setInputElement]); | ||
const handleKeyDown = useCallback((event) => { | ||
if (onKeyDown) | ||
onKeyDown(event); | ||
if (multiLine && | ||
submitOnEnter && | ||
event.key === 'Enter' && | ||
!event.shiftKey && | ||
!event.altKey && | ||
!event.ctrlKey) { | ||
event.preventDefault(); | ||
const form = event.currentTarget.closest('form'); | ||
if (form) { | ||
form.requestSubmit(); | ||
} | ||
else { | ||
// if no form to submit, trigger input blur | ||
event.currentTarget.blur(); | ||
} | ||
} | ||
}, [multiLine, onKeyDown, submitOnEnter]); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment | ||
const Element = (multiLine ? 'textarea' : 'input'); | ||
return (React.createElement(Element, Object.assign({ autoComplete: autoComplete, className: className, defaultValue: initialValue || '', disabled: disabled, form: form, list: list, maxLength: maxLength, minLength: minLength, multiple: multiple, name: name, onBlur: selectTextOnFocus ? handleBlur : onBlur, onChange: onChange, onFocus: onFocus, onKeyDown: onKeyDown, onKeyUp: onKeyUp, onSelect: selectTextOnFocus ? handleSelect : undefined, pattern: pattern, placeholder: placeholder, readOnly: readOnly, required: required, ref: inputRef, size: size, tabIndex: tabIndex, title: title, type: type }, (multiLine | ||
? { onInput: setInputHeight, rows: 1 } | ||
: { max, min, step })))); | ||
return (React.createElement(Element, Object.assign({ autoCapitalize: autoCapitalize, autoComplete: autoComplete, className: className, defaultValue: initialValue !== null && initialValue !== void 0 ? initialValue : '', disabled: disabled, enterKeyHint: enterKeyHint, form: form, list: list, maxLength: maxLength, minLength: minLength, multiple: multiple, name: name, onBlur: selectTextOnFocus ? handleBlur : onBlur, onChange: onChange, onFocus: onFocus, onKeyDown: handleKeyDown, onKeyUp: onKeyUp, onSelect: selectTextOnFocus ? handleSelect : undefined, pattern: pattern, placeholder: placeholder, readOnly: readOnly, ref: setInputElement, required: required, size: size, style: style, tabIndex: tabIndex, title: title, type: type }, (multiLine ? { onInput: setInputHeight, rows: 1 } : { max, min, step })))); | ||
}); | ||
export default InputText; | ||
//# sourceMappingURL=InputText.js.map |
{ | ||
"name": "@acusti/input-text", | ||
"version": "1.2.1", | ||
"version": "1.3.0", | ||
"description": "React component that renders a semi-controlled input with multiLine and selectTextOnFocus support", | ||
@@ -38,4 +38,4 @@ "keywords": [ | ||
"devDependencies": { | ||
"@types/react": "^18.0.25", | ||
"typescript": "^5.1.6" | ||
"@types/react": "^18.2.45", | ||
"typescript": "^5.3.3" | ||
}, | ||
@@ -42,0 +42,0 @@ "peerDependencies": { |
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
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
21480
322