Socket
Socket
Sign inDemoInstall

@acusti/input-text

Package Overview
Dependencies
5
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.6.2 to 1.7.0

6

dist/InputText.d.ts
import * as React from 'react';
import type { InputHTMLAttributes } from 'react';
type InputElement = HTMLInputElement | HTMLTextAreaElement;
export type InputElement = HTMLInputElement | HTMLTextAreaElement;
export type Props = {

@@ -60,5 +60,3 @@ autoCapitalize?: 'none' | 'off' | 'sentences' | 'words' | 'characters';

};
declare const _default: React.ForwardRefExoticComponent<
Props & React.RefAttributes<HTMLInputElement>
>;
declare const _default: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLInputElement>>;
export default _default;
import * as React from 'react';
const { useCallback, useEffect, useImperativeHandle, useRef, useState } = React;
export default React.forwardRef(function InputText(
{
autoCapitalize,
autoComplete,
autoFocus,
className,
disabled,
doubleClickToEdit,
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,
) {
export default React.forwardRef(function InputText({ autoCapitalize, autoComplete, autoFocus, className, disabled, doubleClickToEdit, 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);

@@ -53,3 +14,4 @@ useImperativeHandle(ref, () => inputRef.current);

inputRef.current.setAttribute('autofocus', 'autofocus');
} else if (!autoFocus && inputRef.current.autofocus) {
}
else if (!autoFocus && inputRef.current.autofocus) {
inputRef.current.removeAttribute('autofocus');

@@ -60,24 +22,22 @@ }

useEffect(() => {
if (!inputRef.current) return;
inputRef.current.value =
initialValue !== null && initialValue !== void 0 ? initialValue : '';
if (!inputRef.current)
return;
inputRef.current.value = initialValue !== null && initialValue !== void 0 ? initialValue : '';
}, [initialValue]);
const [readOnlyState, setReadOnlyState] = useState(
readOnly !== null && readOnly !== void 0 ? readOnly : doubleClickToEdit,
);
const [readOnlyState, setReadOnlyState] = useState(readOnly !== null && readOnly !== void 0 ? readOnly : doubleClickToEdit);
const isInitialSelectionRef = useRef(true);
const startEditing = useCallback(() => {
if (!doubleClickToEdit) return;
if (!doubleClickToEdit)
return;
setReadOnlyState(false);
}, [doubleClickToEdit]);
const setInputHeight = useCallback(() => {
if (!inputElement) return;
if (!inputElement)
return;
if (inputElement.style.height) {
inputElement.style.height = '';
}
if (!multiLine) return;
const height = Math.min(
inputElement.scrollHeight,
typeof maxHeight === 'string' ? parseFloat(maxHeight) : maxHeight,
);
if (!multiLine)
return;
const height = Math.min(inputElement.scrollHeight, typeof maxHeight === 'string' ? parseFloat(maxHeight) : maxHeight);
if (height) {

@@ -89,118 +49,79 @@ inputElement.style.height = `${height}px`;

useEffect(setInputHeight, [setInputHeight]);
const handleFocus = useCallback(
(event) => {
if (onFocus) onFocus(event);
if (multiLine) setInputHeight();
},
[multiLine, onFocus, setInputHeight],
);
const handleBlur = useCallback(
(event) => {
if (onBlur) onBlur(event);
if (doubleClickToEdit) {
setReadOnlyState(true);
}
if (!selectTextOnFocus) return;
setInputElement(event.currentTarget);
// When input loses focus, reset isInitialSelection to true for next onSelect event
isInitialSelectionRef.current = true;
},
[doubleClickToEdit, onBlur, selectTextOnFocus, setInputElement],
);
const handleFocus = useCallback((event) => {
if (onFocus)
onFocus(event);
if (multiLine)
setInputHeight();
}, [multiLine, onFocus, setInputHeight]);
const handleBlur = useCallback((event) => {
if (onBlur)
onBlur(event);
if (doubleClickToEdit) {
setReadOnlyState(true);
}
if (!selectTextOnFocus)
return;
setInputElement(event.currentTarget);
// When input loses focus, reset isInitialSelection to true for next onSelect event
isInitialSelectionRef.current = true;
}, [doubleClickToEdit, onBlur, selectTextOnFocus, setInputElement]);
// 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(
(event) => {
if (!selectTextOnFocus) return;
const input = event.currentTarget;
setInputElement(input);
// 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;
// Do nothing if input has no value
if (!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;
},
[selectTextOnFocus, 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();
const handleSelect = useCallback((event) => {
if (!selectTextOnFocus)
return;
const input = event.currentTarget;
setInputElement(input);
// 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;
// Do nothing if input has no value
if (!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;
}, [selectTextOnFocus, 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();
}
}
else if (doubleClickToEdit && inputRef.current) {
if (readOnlyState) {
if (event.key === 'Enter') {
setReadOnlyState(false);
}
} else if (doubleClickToEdit && inputRef.current) {
if (readOnlyState) {
if (event.key === 'Enter') {
setReadOnlyState(false);
}
} else if (event.key === 'Enter' || event.key === 'Escape') {
inputRef.current.blur();
}
}
},
[doubleClickToEdit, multiLine, onKeyDown, readOnlyState, submitOnEnter],
);
else if (event.key === 'Enter' || event.key === 'Escape') {
inputRef.current.blur();
}
}
}, [doubleClickToEdit, multiLine, onKeyDown, readOnlyState, 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(
{
autoCapitalize: autoCapitalize,
autoComplete: autoComplete,
autoFocus: autoFocus,
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: handleBlur,
onChange: onChange,
onDoubleClick: startEditing,
onFocus: handleFocus,
onKeyDown: handleKeyDown,
onKeyUp: onKeyUp,
onSelect: handleSelect,
pattern: pattern,
placeholder: placeholder,
readOnly: readOnlyState,
ref: setInputElement,
required: required,
size: size,
style: style,
tabIndex: tabIndex,
title: title,
type: type,
},
multiLine ? { onInput: setInputHeight, rows: 1 } : { max, min, step },
),
);
const Element = (multiLine ? 'textarea' : 'input');
return (React.createElement(Element, Object.assign({ autoCapitalize: autoCapitalize, autoComplete: autoComplete, autoFocus: autoFocus, 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: handleBlur, onChange: onChange, onDoubleClick: startEditing, onFocus: handleFocus, onKeyDown: handleKeyDown, onKeyUp: onKeyUp, onSelect: handleSelect, pattern: pattern, placeholder: placeholder, readOnly: readOnlyState, ref: setInputElement, required: required, size: size, style: style, tabIndex: tabIndex, title: title, type: type }, (multiLine ? { onInput: setInputHeight, rows: 1 } : { max, min, step }))));
});
//# sourceMappingURL=InputText.js.map
//# sourceMappingURL=InputText.js.map

@@ -10,3 +10,3 @@ // @vitest-environment happy-dom

it('renders a text input with the given props.initialValue', () => {
render(React.createElement(InputText, { initialValue: 'foo Bar' }));
render(React.createElement(InputText, { initialValue: "foo Bar" }));
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion

@@ -18,5 +18,3 @@ const input = screen.getByRole('textbox');

const user = userEvent.setup();
const { rerender } = render(
React.createElement(InputText, { initialValue: 'foo Bar' }),
);
const { rerender } = render(React.createElement(InputText, { initialValue: "foo Bar" }));
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion

@@ -28,6 +26,6 @@ const input = screen.getByRole('textbox');

// re-render with same initialValue, value state shouldn’t change
rerender(React.createElement(InputText, { initialValue: 'foo Bar' }));
rerender(React.createElement(InputText, { initialValue: "foo Bar" }));
expect(input.value).toBe('foo bar');
// re-render with different initialValue, value state should reset
rerender(React.createElement(InputText, { initialValue: 'foo Bar ' }));
rerender(React.createElement(InputText, { initialValue: "foo Bar " }));
expect(input.value).toBe('foo Bar ');

@@ -37,7 +35,4 @@ });

const user = userEvent.setup();
const longText =
'Lorem ipsum dolor sit amet. Consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi';
render(
React.createElement(InputText, { initialValue: longText, multiLine: true }),
);
const longText = 'Lorem ipsum dolor sit amet. Consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi';
render(React.createElement(InputText, { initialValue: longText, multiLine: true }));
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion

@@ -50,2 +45,2 @@ const textarea = screen.getByRole('textbox');

});
//# sourceMappingURL=InputText.test.js.map
//# sourceMappingURL=InputText.test.js.map
{
"name": "@acusti/input-text",
"version": "1.6.2",
"version": "1.7.0",
"type": "module",

@@ -5,0 +5,0 @@ "sideEffects": false,

@@ -98,1 +98,3 @@ # @acusti/input-text

```
Note: the `InputElement` type referenced in the event handlers above is a union of `HTMLInputElement` and `HTMLTextAreaElement` and is available as an export (`import type { InputElement } from '@acusti/input-text';`).

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc