@mpen/react-basic-inputs 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.cjs +61 -13
- package/dist/bundle.d.ts +1 -0
- package/dist/bundle.mjs +61 -15
- package/dist/components/TextArea.d.ts +8 -0
- package/dist/hooks/useEvent.d.ts +3 -3
- package/dist/types/utility.d.ts +1 -0
- package/package.json +2 -2
package/dist/bundle.cjs
CHANGED
|
@@ -10,24 +10,34 @@ function identity(x) {
|
|
|
10
10
|
return x;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
let
|
|
13
|
+
let useEventHandler;
|
|
14
14
|
|
|
15
15
|
if (typeof window !== "undefined") {
|
|
16
|
-
|
|
17
|
-
React.useDebugValue(
|
|
18
|
-
const
|
|
19
|
-
React.
|
|
20
|
-
|
|
21
|
-
}), [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
useEventHandler = callback => {
|
|
17
|
+
React.useDebugValue(callback);
|
|
18
|
+
const latestRef = React.useRef(useEvent_shouldNotBeInvokedBeforeMount);
|
|
19
|
+
React.useInsertionEffect((() => {
|
|
20
|
+
latestRef.current = callback;
|
|
21
|
+
}), [ callback ]);
|
|
22
|
+
const stableRef = React.useRef(null);
|
|
23
|
+
if (!stableRef.current) {
|
|
24
|
+
stableRef.current = function() {
|
|
25
|
+
return latestRef.current.apply(this, arguments);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return stableRef.current;
|
|
25
29
|
};
|
|
26
30
|
} else {
|
|
27
|
-
|
|
31
|
+
useEventHandler = NOOP;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function useEvent(handler) {
|
|
35
|
+
return useEventHandler(handler);
|
|
28
36
|
}
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
function useEvent_shouldNotBeInvokedBeforeMount() {
|
|
39
|
+
throw new Error("INVALID_USE_EVENT_INVOCATION: the callback from useEvent cannot be invoked before the component has mounted.");
|
|
40
|
+
}
|
|
31
41
|
|
|
32
42
|
function resolveValue(val, ...args) {
|
|
33
43
|
return typeof val === "function" ? val(...args) : val;
|
|
@@ -97,7 +107,7 @@ function Select({options, value, invalidValueOption = defaultMakeInvalidValueOpt
|
|
|
97
107
|
}
|
|
98
108
|
return fixedOptions;
|
|
99
109
|
}), [ isValid, options, isNotSelected, extraOption, placeholder ]);
|
|
100
|
-
const handleChange = useEvent
|
|
110
|
+
const handleChange = useEvent((ev => {
|
|
101
111
|
const idx = ev.target.selectedIndex;
|
|
102
112
|
const opt = fixedOptions[idx];
|
|
103
113
|
onChange?.({
|
|
@@ -205,8 +215,46 @@ function TextInput({formatOnChange = collapseWhitespace, ...otherProps}) {
|
|
|
205
215
|
});
|
|
206
216
|
}
|
|
207
217
|
|
|
218
|
+
const TextArea = React.forwardRef((function TextArea({onInput, style, ...rest}, fwdRef) {
|
|
219
|
+
const ref = React.useRef(null);
|
|
220
|
+
const [height, setHeight] = React.useState("auto");
|
|
221
|
+
const adjustHeight = () => {
|
|
222
|
+
const textarea = ref.current;
|
|
223
|
+
if (!textarea) return;
|
|
224
|
+
textarea.style.height = "auto";
|
|
225
|
+
const newHeight = `${textarea.scrollHeight}px`;
|
|
226
|
+
setHeight(newHeight);
|
|
227
|
+
textarea.style.height = newHeight;
|
|
228
|
+
};
|
|
229
|
+
React.useImperativeHandle(fwdRef, (() => ({
|
|
230
|
+
element: ref.current,
|
|
231
|
+
resize: adjustHeight
|
|
232
|
+
})), [ setHeight, ref.current ]);
|
|
233
|
+
const input = useEventHandler((ev => {
|
|
234
|
+
adjustHeight();
|
|
235
|
+
onInput?.(ev);
|
|
236
|
+
}));
|
|
237
|
+
React.useLayoutEffect((() => {
|
|
238
|
+
adjustHeight();
|
|
239
|
+
}), []);
|
|
240
|
+
return jsxRuntime.jsx("textarea", {
|
|
241
|
+
rows: 1,
|
|
242
|
+
...rest,
|
|
243
|
+
style: {
|
|
244
|
+
...style,
|
|
245
|
+
overflow: "hidden",
|
|
246
|
+
resize: "none",
|
|
247
|
+
height
|
|
248
|
+
},
|
|
249
|
+
onInput: input,
|
|
250
|
+
ref
|
|
251
|
+
});
|
|
252
|
+
}));
|
|
253
|
+
|
|
208
254
|
exports.Input = Input;
|
|
209
255
|
|
|
210
256
|
exports.Select = Select;
|
|
211
257
|
|
|
258
|
+
exports.TextArea = TextArea;
|
|
259
|
+
|
|
212
260
|
exports.TextInput = TextInput;
|
package/dist/bundle.d.ts
CHANGED
package/dist/bundle.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
|
|
3
|
-
import { useDebugValue, useRef,
|
|
3
|
+
import { useDebugValue, useRef, useInsertionEffect, useEffect, useMemo, useCallback, createElement, forwardRef, useState, useImperativeHandle, useLayoutEffect } from "react";
|
|
4
4
|
|
|
5
5
|
const NOOP = Object.freeze((() => {}));
|
|
6
6
|
|
|
@@ -8,24 +8,34 @@ function identity(x) {
|
|
|
8
8
|
return x;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
let
|
|
11
|
+
let useEventHandler;
|
|
12
12
|
|
|
13
13
|
if (typeof window !== "undefined") {
|
|
14
|
-
|
|
15
|
-
useDebugValue(
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}), [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
useEventHandler = callback => {
|
|
15
|
+
useDebugValue(callback);
|
|
16
|
+
const latestRef = useRef(useEvent_shouldNotBeInvokedBeforeMount);
|
|
17
|
+
useInsertionEffect((() => {
|
|
18
|
+
latestRef.current = callback;
|
|
19
|
+
}), [ callback ]);
|
|
20
|
+
const stableRef = useRef(null);
|
|
21
|
+
if (!stableRef.current) {
|
|
22
|
+
stableRef.current = function() {
|
|
23
|
+
return latestRef.current.apply(this, arguments);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return stableRef.current;
|
|
23
27
|
};
|
|
24
28
|
} else {
|
|
25
|
-
|
|
29
|
+
useEventHandler = NOOP;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function useEvent(handler) {
|
|
33
|
+
return useEventHandler(handler);
|
|
26
34
|
}
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
function useEvent_shouldNotBeInvokedBeforeMount() {
|
|
37
|
+
throw new Error("INVALID_USE_EVENT_INVOCATION: the callback from useEvent cannot be invoked before the component has mounted.");
|
|
38
|
+
}
|
|
29
39
|
|
|
30
40
|
function resolveValue(val, ...args) {
|
|
31
41
|
return typeof val === "function" ? val(...args) : val;
|
|
@@ -95,7 +105,7 @@ function Select({options, value, invalidValueOption = defaultMakeInvalidValueOpt
|
|
|
95
105
|
}
|
|
96
106
|
return fixedOptions;
|
|
97
107
|
}), [ isValid, options, isNotSelected, extraOption, placeholder ]);
|
|
98
|
-
const handleChange = useEvent
|
|
108
|
+
const handleChange = useEvent((ev => {
|
|
99
109
|
const idx = ev.target.selectedIndex;
|
|
100
110
|
const opt = fixedOptions[idx];
|
|
101
111
|
onChange?.({
|
|
@@ -203,4 +213,40 @@ function TextInput({formatOnChange = collapseWhitespace, ...otherProps}) {
|
|
|
203
213
|
});
|
|
204
214
|
}
|
|
205
215
|
|
|
206
|
-
|
|
216
|
+
const TextArea = forwardRef((function TextArea({onInput, style, ...rest}, fwdRef) {
|
|
217
|
+
const ref = useRef(null);
|
|
218
|
+
const [height, setHeight] = useState("auto");
|
|
219
|
+
const adjustHeight = () => {
|
|
220
|
+
const textarea = ref.current;
|
|
221
|
+
if (!textarea) return;
|
|
222
|
+
textarea.style.height = "auto";
|
|
223
|
+
const newHeight = `${textarea.scrollHeight}px`;
|
|
224
|
+
setHeight(newHeight);
|
|
225
|
+
textarea.style.height = newHeight;
|
|
226
|
+
};
|
|
227
|
+
useImperativeHandle(fwdRef, (() => ({
|
|
228
|
+
element: ref.current,
|
|
229
|
+
resize: adjustHeight
|
|
230
|
+
})), [ setHeight, ref.current ]);
|
|
231
|
+
const input = useEventHandler((ev => {
|
|
232
|
+
adjustHeight();
|
|
233
|
+
onInput?.(ev);
|
|
234
|
+
}));
|
|
235
|
+
useLayoutEffect((() => {
|
|
236
|
+
adjustHeight();
|
|
237
|
+
}), []);
|
|
238
|
+
return jsx("textarea", {
|
|
239
|
+
rows: 1,
|
|
240
|
+
...rest,
|
|
241
|
+
style: {
|
|
242
|
+
...style,
|
|
243
|
+
overflow: "hidden",
|
|
244
|
+
resize: "none",
|
|
245
|
+
height
|
|
246
|
+
},
|
|
247
|
+
onInput: input,
|
|
248
|
+
ref
|
|
249
|
+
});
|
|
250
|
+
}));
|
|
251
|
+
|
|
252
|
+
export { Input, Select, TextArea, TextInput };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { HtmlTextAreaElement, OverrideProps, VoidFn } from '../types/utility';
|
|
3
|
+
export type TextAreaRef = {
|
|
4
|
+
element: HtmlTextAreaElement;
|
|
5
|
+
resize: VoidFn;
|
|
6
|
+
};
|
|
7
|
+
export type TextAreaProps = OverrideProps<'textarea', {}>;
|
|
8
|
+
export declare const TextArea: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "ref">, never> & import("react").RefAttributes<TextAreaRef>>;
|
package/dist/hooks/useEvent.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EventCallback } from "../types/utility";
|
|
1
|
+
import { AnyFn, EventCallback } from "../types/utility";
|
|
2
2
|
/**
|
|
3
3
|
* @see https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md
|
|
4
4
|
*/
|
|
5
|
-
declare let
|
|
6
|
-
export default useEvent
|
|
5
|
+
export declare let useEventHandler: <TCallback extends AnyFn>(callback: TCallback) => TCallback;
|
|
6
|
+
export default function useEvent<T>(handler: EventCallback<T>): EventCallback<T>;
|
package/dist/types/utility.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export type OmitProps<Base extends import('react').ElementType, DeleteKeys exten
|
|
|
20
20
|
export type MapKeyType<M> = M extends Map<infer K, any> ? K : never;
|
|
21
21
|
export type MapValueType<M> = M extends Map<any, infer V> ? V : never;
|
|
22
22
|
/** Hack to de-conflict React's HTMLInputElement vs the standard dom lib */
|
|
23
|
+
export type HtmlTextAreaElement = HTMLElementTagNameMap['textarea'];
|
|
23
24
|
export type HtmlInputElement = HTMLElementTagNameMap['input'];
|
|
24
25
|
export type HtmlSelectElement = HTMLElementTagNameMap['select'];
|
|
25
26
|
export type HtmlInputChangeEvent = import('react').ChangeEvent<HtmlInputElement>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpen/react-basic-inputs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"packageManager": "yarn@3.5.0",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"serve": "^14.2.0",
|
|
50
50
|
"ts-jest": "^29.1.0",
|
|
51
51
|
"tslib": "^2.5.0",
|
|
52
|
-
"typescript": "^5.
|
|
52
|
+
"typescript": "^5.3.3"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"react": ">=17 <19",
|