@acusti/input-text
Advanced tools
Comparing version 1.8.0 to 1.9.0
@@ -40,2 +40,7 @@ import * as React from 'react'; | ||
onChange?: (event: React.ChangeEvent<InputElement>) => unknown; | ||
/** | ||
* Custom change handler that only receives the changed value as an argument. | ||
* Enables passing a state setter function directly, e.g. onChangeValue={setValue}. | ||
*/ | ||
onChangeValue?: (value: string) => unknown; | ||
onFocus?: (event: React.FocusEvent<InputElement>) => unknown; | ||
@@ -48,2 +53,3 @@ onKeyDown?: (event: React.KeyboardEvent<InputElement>) => unknown; | ||
required?: boolean; | ||
rows?: number; | ||
/** If true, the contents of the input are selected when it’s focused. */ | ||
@@ -50,0 +56,0 @@ selectTextOnFocus?: boolean; |
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, id, 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, id, initialValue, list, max, maxHeight = Infinity, maxLength, min, minLength, multiLine, multiple, name, onBlur, onChange, onChangeValue, onFocus, onKeyDown, onKeyUp, pattern, placeholder, readOnly, required, rows = 1, selectTextOnFocus, size, style, step, submitOnEnter, tabIndex, title, type = 'text', }, ref) { | ||
const inputRef = useRef(null); | ||
@@ -47,2 +47,8 @@ useImperativeHandle(ref, () => inputRef.current); | ||
useEffect(setInputHeight, [setInputHeight]); | ||
const handleChange = useCallback((event) => { | ||
if (onChange) | ||
onChange(event); | ||
if (onChangeValue) | ||
onChangeValue(event.target.value); | ||
}, [onChange, onChangeValue]); | ||
const handleFocus = useCallback((event) => { | ||
@@ -92,13 +98,12 @@ if (onFocus) | ||
const handleKeyDown = useCallback((event) => { | ||
var _a; | ||
if (onKeyDown) | ||
onKeyDown(event); | ||
if (submitOnEnter && | ||
event.key === 'Enter' && | ||
if (event.key === 'Enter' && | ||
// for multi-line inputs, ⌘-Enter should always submit | ||
(submitOnEnter || (multiLine && isPrimaryModifierPressed(event))) && | ||
// for multi-line inputs, shift/alt/ctrl-Enter should insert newlines | ||
(!multiLine || (!event.shiftKey && !event.altKey && !event.ctrlKey))) { | ||
event.preventDefault(); | ||
const form = event.currentTarget.closest('form'); | ||
if (form) { | ||
form.requestSubmit(); | ||
} | ||
(_a = event.currentTarget.closest('form')) === null || _a === void 0 ? void 0 : _a.requestSubmit(); | ||
// always blur input on Enter when submitOnEnter is true | ||
@@ -118,6 +123,13 @@ event.currentTarget.blur(); | ||
}, [doubleClickToEdit, multiLine, onKeyDown, readOnlyState, submitOnEnter]); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
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, id: id, 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 })))); | ||
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, id: id, list: list, maxLength: maxLength, minLength: minLength, multiple: multiple, name: name, onBlur: handleBlur, onChange: handleChange, 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 } : { max, min, step })))); | ||
}); | ||
const IS_APPLE_REGEXP = /mac|iphone|ipad|ipod/i; | ||
function isPrimaryModifierPressed(event) { | ||
var _a, _b; | ||
// eslint-disable-next-line @typescript-eslint/no-deprecated | ||
const platform = (_b = (_a = globalThis.navigator) === null || _a === void 0 ? void 0 : _a.platform) !== null && _b !== void 0 ? _b : ''; | ||
return IS_APPLE_REGEXP.test(platform) ? event.metaKey : event.ctrlKey; | ||
} | ||
//# sourceMappingURL=InputText.js.map |
// @vitest-environment happy-dom | ||
import { cleanup, render, screen } from '@testing-library/react'; | ||
import { userEvent } from '@testing-library/user-event'; | ||
import React from 'react'; // eslint-disable-line @typescript-eslint/no-unused-vars | ||
import React from 'react'; | ||
import { afterEach, describe, expect, it } from 'vitest'; | ||
@@ -11,3 +11,2 @@ import InputText from './InputText.js'; | ||
render(React.createElement(InputText, { initialValue: "foo Bar" })); | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
const input = screen.getByRole('textbox'); | ||
@@ -19,3 +18,2 @@ expect(input.value).toBe('foo Bar'); | ||
const { rerender } = render(React.createElement(InputText, { initialValue: "foo Bar" })); | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
const input = screen.getByRole('textbox'); | ||
@@ -36,3 +34,2 @@ expect(input.value).toBe('foo Bar'); | ||
render(React.createElement(InputText, { initialValue: longText, multiLine: true })); | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
const textarea = screen.getByRole('textbox'); | ||
@@ -39,0 +36,0 @@ expect(textarea.value).toBe(longText); |
{ | ||
"name": "@acusti/input-text", | ||
"version": "1.8.0", | ||
"version": "1.9.0", | ||
"type": "module", | ||
@@ -42,15 +42,15 @@ "sideEffects": false, | ||
"@testing-library/dom": "^10.4.0", | ||
"@testing-library/react": "^16.0.1", | ||
"@testing-library/react": "^16.1.0", | ||
"@testing-library/user-event": "^14.5.2", | ||
"@types/react": "^18.3.3", | ||
"happy-dom": "^15.7.3", | ||
"react": "^19.0.0-0", | ||
"react-dom": "^19.0.0-0", | ||
"@types/react": "^19.0.2", | ||
"happy-dom": "^15.11.7", | ||
"react": "^19.0.0", | ||
"react-dom": "^19.0.0", | ||
"typescript": "5.3.3", | ||
"vitest": "^1.1.0" | ||
"vitest": "^2.1.8" | ||
}, | ||
"peerDependencies": { | ||
"react": "^16.8 || ^17 || ^18 || ^19.0.0-0", | ||
"react-dom": "^16.8 || ^17 || ^18 || ^19.0.0-0" | ||
"react": "^16.8 || ^17 || ^18 || ^19", | ||
"react-dom": "^16.8 || ^17 || ^18 || ^19" | ||
} | ||
} |
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
40805
553