@trackunit/react-form-components 1.8.145 → 1.8.151
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/index.cjs.js
CHANGED
|
@@ -2378,6 +2378,7 @@ EmailField.displayName = "EmailField";
|
|
|
2378
2378
|
function isWritableRef(r) {
|
|
2379
2379
|
return typeof r === "object" && r !== null && "current" in r;
|
|
2380
2380
|
}
|
|
2381
|
+
const IGNORED_RS_ACTIONS = new Set(["set-value", "input-blur", "menu-close"]);
|
|
2381
2382
|
/**
|
|
2382
2383
|
* Multi adapter:
|
|
2383
2384
|
* - keeps TOption[] semantics (via `MultiValue<TOption>`)
|
|
@@ -2390,9 +2391,11 @@ function isWritableRef(r) {
|
|
|
2390
2391
|
* @returns {ReactElement} FormFieldSelectAdapterMulti component
|
|
2391
2392
|
*/
|
|
2392
2393
|
const FormFieldSelectAdapterMulti = (props) => {
|
|
2393
|
-
const { className, "data-testid": dataTestId, helpText, helpAddon, tip, label, isInvalid, errorMessage, name, onBlur, options, value, defaultValue, id, htmlFor: htmlForProp, onChange, children, ref, ...selectProps } = props;
|
|
2394
|
+
const { className, "data-testid": dataTestId, helpText, helpAddon, tip, label, isInvalid, errorMessage, name, onBlur, options, value, defaultValue, id, htmlFor: htmlForProp, onChange, children, ref, onInputChange, ...selectProps } = props;
|
|
2395
|
+
const [inputValue, setInputValue] = react.useState("");
|
|
2394
2396
|
// Hidden select for a stable DOM ref target (API parity with single adapter)
|
|
2395
2397
|
const innerRef = react.useRef(null);
|
|
2398
|
+
const onInputChangeRef = react.useRef(undefined);
|
|
2396
2399
|
// Bridge external ref (supports both callback and object refs)
|
|
2397
2400
|
react.useEffect(() => {
|
|
2398
2401
|
if (typeof ref === "function") {
|
|
@@ -2414,6 +2417,20 @@ const FormFieldSelectAdapterMulti = (props) => {
|
|
|
2414
2417
|
: undefined, [selectPropsWithAccessors]);
|
|
2415
2418
|
// Compute selected options snapshot for hidden inputs (prefer controlled `value`)
|
|
2416
2419
|
const selectedOptions = react.useMemo(() => value ?? defaultValue ?? [], [value, defaultValue]);
|
|
2420
|
+
react.useEffect(() => {
|
|
2421
|
+
onInputChangeRef.current = onInputChange;
|
|
2422
|
+
}, [onInputChange]);
|
|
2423
|
+
const handleInputChange = react.useCallback((nextValue, meta) => {
|
|
2424
|
+
if (IGNORED_RS_ACTIONS.has(meta.action)) {
|
|
2425
|
+
return inputValue; // keep current visible value
|
|
2426
|
+
}
|
|
2427
|
+
if (nextValue !== inputValue) {
|
|
2428
|
+
setInputValue(nextValue);
|
|
2429
|
+
}
|
|
2430
|
+
// Call the latest external callback from ref
|
|
2431
|
+
onInputChangeRef.current?.(nextValue, meta);
|
|
2432
|
+
return nextValue;
|
|
2433
|
+
}, [inputValue]);
|
|
2417
2434
|
// Build the exact prop bag for BaseSelect (multi=true).
|
|
2418
2435
|
const childProps = react.useMemo(() => ({
|
|
2419
2436
|
...selectProps,
|
|
@@ -2425,7 +2442,9 @@ const FormFieldSelectAdapterMulti = (props) => {
|
|
|
2425
2442
|
value: value ?? null,
|
|
2426
2443
|
defaultValue,
|
|
2427
2444
|
onChange,
|
|
2428
|
-
|
|
2445
|
+
onInputChange: handleInputChange,
|
|
2446
|
+
inputValue,
|
|
2447
|
+
}), [selectProps, dataTestId, controlId, onBlur, options, value, defaultValue, onChange, handleInputChange, inputValue]);
|
|
2429
2448
|
return (jsxRuntime.jsxs(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: controlId, isInvalid: renderAsInvalid, label: label, required: "required" in selectProps && selectProps.required
|
|
2430
2449
|
? !(("disabled" in selectProps && Boolean(selectProps.disabled)) ||
|
|
2431
2450
|
("readOnly" in selectProps && Boolean(selectProps.readOnly)))
|
package/index.esm.js
CHANGED
|
@@ -2377,6 +2377,7 @@ EmailField.displayName = "EmailField";
|
|
|
2377
2377
|
function isWritableRef(r) {
|
|
2378
2378
|
return typeof r === "object" && r !== null && "current" in r;
|
|
2379
2379
|
}
|
|
2380
|
+
const IGNORED_RS_ACTIONS = new Set(["set-value", "input-blur", "menu-close"]);
|
|
2380
2381
|
/**
|
|
2381
2382
|
* Multi adapter:
|
|
2382
2383
|
* - keeps TOption[] semantics (via `MultiValue<TOption>`)
|
|
@@ -2389,9 +2390,11 @@ function isWritableRef(r) {
|
|
|
2389
2390
|
* @returns {ReactElement} FormFieldSelectAdapterMulti component
|
|
2390
2391
|
*/
|
|
2391
2392
|
const FormFieldSelectAdapterMulti = (props) => {
|
|
2392
|
-
const { className, "data-testid": dataTestId, helpText, helpAddon, tip, label, isInvalid, errorMessage, name, onBlur, options, value, defaultValue, id, htmlFor: htmlForProp, onChange, children, ref, ...selectProps } = props;
|
|
2393
|
+
const { className, "data-testid": dataTestId, helpText, helpAddon, tip, label, isInvalid, errorMessage, name, onBlur, options, value, defaultValue, id, htmlFor: htmlForProp, onChange, children, ref, onInputChange, ...selectProps } = props;
|
|
2394
|
+
const [inputValue, setInputValue] = useState("");
|
|
2393
2395
|
// Hidden select for a stable DOM ref target (API parity with single adapter)
|
|
2394
2396
|
const innerRef = useRef(null);
|
|
2397
|
+
const onInputChangeRef = useRef(undefined);
|
|
2395
2398
|
// Bridge external ref (supports both callback and object refs)
|
|
2396
2399
|
useEffect(() => {
|
|
2397
2400
|
if (typeof ref === "function") {
|
|
@@ -2413,6 +2416,20 @@ const FormFieldSelectAdapterMulti = (props) => {
|
|
|
2413
2416
|
: undefined, [selectPropsWithAccessors]);
|
|
2414
2417
|
// Compute selected options snapshot for hidden inputs (prefer controlled `value`)
|
|
2415
2418
|
const selectedOptions = useMemo(() => value ?? defaultValue ?? [], [value, defaultValue]);
|
|
2419
|
+
useEffect(() => {
|
|
2420
|
+
onInputChangeRef.current = onInputChange;
|
|
2421
|
+
}, [onInputChange]);
|
|
2422
|
+
const handleInputChange = useCallback((nextValue, meta) => {
|
|
2423
|
+
if (IGNORED_RS_ACTIONS.has(meta.action)) {
|
|
2424
|
+
return inputValue; // keep current visible value
|
|
2425
|
+
}
|
|
2426
|
+
if (nextValue !== inputValue) {
|
|
2427
|
+
setInputValue(nextValue);
|
|
2428
|
+
}
|
|
2429
|
+
// Call the latest external callback from ref
|
|
2430
|
+
onInputChangeRef.current?.(nextValue, meta);
|
|
2431
|
+
return nextValue;
|
|
2432
|
+
}, [inputValue]);
|
|
2416
2433
|
// Build the exact prop bag for BaseSelect (multi=true).
|
|
2417
2434
|
const childProps = useMemo(() => ({
|
|
2418
2435
|
...selectProps,
|
|
@@ -2424,7 +2441,9 @@ const FormFieldSelectAdapterMulti = (props) => {
|
|
|
2424
2441
|
value: value ?? null,
|
|
2425
2442
|
defaultValue,
|
|
2426
2443
|
onChange,
|
|
2427
|
-
|
|
2444
|
+
onInputChange: handleInputChange,
|
|
2445
|
+
inputValue,
|
|
2446
|
+
}), [selectProps, dataTestId, controlId, onBlur, options, value, defaultValue, onChange, handleInputChange, inputValue]);
|
|
2428
2447
|
return (jsxs(FormGroup, { className: className, "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: controlId, isInvalid: renderAsInvalid, label: label, required: "required" in selectProps && selectProps.required
|
|
2429
2448
|
? !(("disabled" in selectProps && Boolean(selectProps.disabled)) ||
|
|
2430
2449
|
("readOnly" in selectProps && Boolean(selectProps.readOnly)))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-form-components",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.151",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"zod": "^3.23.8",
|
|
15
15
|
"react-hook-form": "7.62.0",
|
|
16
16
|
"tailwind-merge": "^2.0.0",
|
|
17
|
-
"@trackunit/css-class-variance-utilities": "1.7.
|
|
18
|
-
"@trackunit/react-components": "1.10.
|
|
19
|
-
"@trackunit/ui-icons": "1.7.
|
|
20
|
-
"@trackunit/shared-utils": "1.9.
|
|
21
|
-
"@trackunit/ui-design-tokens": "1.7.
|
|
22
|
-
"@trackunit/i18n-library-translation": "1.7.
|
|
17
|
+
"@trackunit/css-class-variance-utilities": "1.7.103",
|
|
18
|
+
"@trackunit/react-components": "1.10.79",
|
|
19
|
+
"@trackunit/ui-icons": "1.7.104",
|
|
20
|
+
"@trackunit/shared-utils": "1.9.103",
|
|
21
|
+
"@trackunit/ui-design-tokens": "1.7.103",
|
|
22
|
+
"@trackunit/i18n-library-translation": "1.7.121",
|
|
23
23
|
"string-ts": "^2.0.0",
|
|
24
24
|
"@js-temporal/polyfill": "^0.5.1",
|
|
25
25
|
"es-toolkit": "^1.39.10",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CommonProps } from "@trackunit/react-components";
|
|
2
2
|
import { MappedOmit } from "@trackunit/shared-utils";
|
|
3
3
|
import { FocusEvent, ReactElement, ReactNode, Ref } from "react";
|
|
4
|
-
import { GroupBase, MultiValue } from "react-select";
|
|
4
|
+
import { GroupBase, InputActionMeta, MultiValue } from "react-select";
|
|
5
5
|
import { SelectProps } from "../BaseSelect/useSelect";
|
|
6
6
|
import { FormGroupProps } from "../FormGroup/FormGroup";
|
|
7
7
|
import { BaseOptionType } from "../SelectField/FormFieldSelectAdapter";
|
|
@@ -40,6 +40,8 @@ export type MultiSelectFieldProps<TOption extends BaseOptionType = BaseOptionTyp
|
|
|
40
40
|
name?: string;
|
|
41
41
|
/** Field id; also propagated to BaseSelect via child props */
|
|
42
42
|
id?: string;
|
|
43
|
+
/** Optional passthrough onInputChange (will be called in addition to internal logic) */
|
|
44
|
+
onInputChange?: (value: string, meta: InputActionMeta) => void;
|
|
43
45
|
};
|
|
44
46
|
interface FormFieldSelectAdapterMultiProps<TOption extends BaseOptionType = BaseOptionType, TIsAsync extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>> extends MultiSelectFieldProps<TOption, TIsAsync, TGroup> {
|
|
45
47
|
/**
|