@trackunit/react-form-components 1.7.23 → 1.7.26

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
@@ -2100,7 +2100,7 @@ const TagWithWidth = ({ onWidthKnown, children, ...rest }) => {
2100
2100
  * @param {TagsContainerProps} props - The props for the TagContainer
2101
2101
  * @returns {ReactElement} TagsContainer
2102
2102
  */
2103
- const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled }) => {
2103
+ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, preFix, disabled, }) => {
2104
2104
  const containerRef = react.useRef(null);
2105
2105
  const [isReady, setIsReady] = react.useState(false);
2106
2106
  const [counterWidth, setCounterWidth] = react.useState(0);
@@ -2167,9 +2167,9 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
2167
2167
  }, { elements: [], counter: 0 });
2168
2168
  return elements;
2169
2169
  }, [items, availableSpaceWidth, counterWidth, disabled, onWidthKnownHandler, childrenWidths]);
2170
- return (jsxRuntime.jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady }), ref: containerRef, style: {
2170
+ return (jsxRuntime.jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady || !!preFix }), ref: containerRef, style: {
2171
2171
  width: `${width}`,
2172
- }, children: [renderedElements, postFix] }));
2172
+ }, children: [preFix, renderedElements, postFix] }));
2173
2173
  };
2174
2174
 
2175
2175
  /**
@@ -2202,6 +2202,9 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
2202
2202
  const tags = key === PLACEHOLDER_KEY ? [] : values;
2203
2203
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2204
2204
  const searchInput = props && props.children && props.children[1];
2205
+ const placeholderElement = Array.isArray(props.children)
2206
+ ? props.children.find(child => child && child.key === PLACEHOLDER_KEY)
2207
+ : null;
2205
2208
  return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, { ...props, isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsxRuntime.jsx(TagsContainer, { disabled: disabled, items: tags
2206
2209
  ? tags.map(({ props: tagProps }) => {
2207
2210
  const optionPrefix = tagProps.data && getOptionPrefix ? getOptionPrefix(tagProps.data) : null;
@@ -2217,7 +2220,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
2217
2220
  Icon: optionPrefix,
2218
2221
  };
2219
2222
  })
2220
- : [], postFix: searchInput, width: "100%" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [tags
2223
+ : [], postFix: searchInput, preFix: placeholderElement ? jsxRuntime.jsx("span", { className: "absolute", children: placeholderElement }) : null, width: "100%" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [tags
2221
2224
  ? tags.slice(0, maxSelectedDisplayCount).map(({ props: tagProps }) => {
2222
2225
  return (jsxRuntime.jsx(reactComponents.Tag, { className: "inline-flex shrink-0", color: disabled ? "unknown" : "primary", dataTestId: tagProps.children ? `${tagProps.children.toString()}-tag` : undefined, onClose: e => {
2223
2226
  e.stopPropagation();
@@ -2225,7 +2228,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
2225
2228
  tagProps.removeProps.onClick && tagProps.removeProps.onClick(e);
2226
2229
  }, children: tagProps.children }, tagProps.children?.toString()));
2227
2230
  })
2228
- : null, tags && tags.length > maxSelectedDisplayCount ? (jsxRuntime.jsxs(reactComponents.Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })) : null, searchInput] })) }));
2231
+ : null, tags && tags.length > maxSelectedDisplayCount ? (jsxRuntime.jsxs(reactComponents.Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })) : null, searchInput, placeholderElement] })) }));
2229
2232
  }
2230
2233
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(ReactSelect.components.ValueContainer, { ...props, isDisabled: props.selectProps.isDisabled, children: props.children }) }));
2231
2234
  },
@@ -2548,6 +2551,19 @@ const ReactSyncSelect = ReactSelect.default || ReactSelect;
2548
2551
  const Select = (props) => {
2549
2552
  const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = "select", onMenuScrollToBottom, onInputChange, isSearchable, isClearable = false, readOnly, fieldSize = "medium", openMenuOnClick = !disabled, openMenuOnFocus = false, hideSelectedOptions = false, } = props;
2550
2553
  const { refContainer, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler } = useSelect(props);
2554
+ // Control the search input value so it doesn’t reset after selection
2555
+ const [inputValue, setInputValue] = react.useState("");
2556
+ const handleInputChange = react.useCallback((nextValue, meta) => {
2557
+ // Ignore internal actions that clear the input to preserve the typed text
2558
+ // and avoid resetting the parent’s search state
2559
+ const ignoreActions = new Set(["set-value", "input-blur", "menu-close"]);
2560
+ if (ignoreActions.has(meta.action)) {
2561
+ return inputValue;
2562
+ }
2563
+ setInputValue(nextValue);
2564
+ onInputChange?.(nextValue, meta);
2565
+ return nextValue;
2566
+ }, [inputValue, onInputChange]);
2551
2567
  const reactSelectProps = react.useMemo(() => ({
2552
2568
  value,
2553
2569
  menuPlacement,
@@ -2576,7 +2592,8 @@ const Select = (props) => {
2576
2592
  isClearable,
2577
2593
  id,
2578
2594
  onMenuScrollToBottom,
2579
- onInputChange,
2595
+ onInputChange: handleInputChange,
2596
+ inputValue,
2580
2597
  hideSelectedOptions,
2581
2598
  isDisabled: Boolean(disabled),
2582
2599
  }), [
@@ -2585,8 +2602,10 @@ const Select = (props) => {
2585
2602
  customStyles,
2586
2603
  dataTestId,
2587
2604
  disabled,
2605
+ handleInputChange,
2588
2606
  hideSelectedOptions,
2589
2607
  id,
2608
+ inputValue,
2590
2609
  isClearable,
2591
2610
  isLoading,
2592
2611
  isMulti,
@@ -2596,7 +2615,6 @@ const Select = (props) => {
2596
2615
  menuIsOpen,
2597
2616
  menuPlacement,
2598
2617
  onChange,
2599
- onInputChange,
2600
2618
  onMenuScrollToBottom,
2601
2619
  openMenuOnClick,
2602
2620
  openMenuOnFocus,
package/index.esm.js CHANGED
@@ -2099,7 +2099,7 @@ const TagWithWidth = ({ onWidthKnown, children, ...rest }) => {
2099
2099
  * @param {TagsContainerProps} props - The props for the TagContainer
2100
2100
  * @returns {ReactElement} TagsContainer
2101
2101
  */
2102
- const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled }) => {
2102
+ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, preFix, disabled, }) => {
2103
2103
  const containerRef = useRef(null);
2104
2104
  const [isReady, setIsReady] = useState(false);
2105
2105
  const [counterWidth, setCounterWidth] = useState(0);
@@ -2166,9 +2166,9 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
2166
2166
  }, { elements: [], counter: 0 });
2167
2167
  return elements;
2168
2168
  }, [items, availableSpaceWidth, counterWidth, disabled, onWidthKnownHandler, childrenWidths]);
2169
- return (jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady }), ref: containerRef, style: {
2169
+ return (jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady || !!preFix }), ref: containerRef, style: {
2170
2170
  width: `${width}`,
2171
- }, children: [renderedElements, postFix] }));
2171
+ }, children: [preFix, renderedElements, postFix] }));
2172
2172
  };
2173
2173
 
2174
2174
  /**
@@ -2201,6 +2201,9 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
2201
2201
  const tags = key === PLACEHOLDER_KEY ? [] : values;
2202
2202
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
2203
2203
  const searchInput = props && props.children && props.children[1];
2204
+ const placeholderElement = Array.isArray(props.children)
2205
+ ? props.children.find(child => child && child.key === PLACEHOLDER_KEY)
2206
+ : null;
2204
2207
  return (jsx(components.ValueContainer, { ...props, isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsx(TagsContainer, { disabled: disabled, items: tags
2205
2208
  ? tags.map(({ props: tagProps }) => {
2206
2209
  const optionPrefix = tagProps.data && getOptionPrefix ? getOptionPrefix(tagProps.data) : null;
@@ -2216,7 +2219,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
2216
2219
  Icon: optionPrefix,
2217
2220
  };
2218
2221
  })
2219
- : [], postFix: searchInput, width: "100%" })) : (jsxs(Fragment, { children: [tags
2222
+ : [], postFix: searchInput, preFix: placeholderElement ? jsx("span", { className: "absolute", children: placeholderElement }) : null, width: "100%" })) : (jsxs(Fragment, { children: [tags
2220
2223
  ? tags.slice(0, maxSelectedDisplayCount).map(({ props: tagProps }) => {
2221
2224
  return (jsx(Tag, { className: "inline-flex shrink-0", color: disabled ? "unknown" : "primary", dataTestId: tagProps.children ? `${tagProps.children.toString()}-tag` : undefined, onClose: e => {
2222
2225
  e.stopPropagation();
@@ -2224,7 +2227,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
2224
2227
  tagProps.removeProps.onClick && tagProps.removeProps.onClick(e);
2225
2228
  }, children: tagProps.children }, tagProps.children?.toString()));
2226
2229
  })
2227
- : null, tags && tags.length > maxSelectedDisplayCount ? (jsxs(Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })) : null, searchInput] })) }));
2230
+ : null, tags && tags.length > maxSelectedDisplayCount ? (jsxs(Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })) : null, searchInput, placeholderElement] })) }));
2228
2231
  }
2229
2232
  return (jsx(Fragment, { children: jsx(components.ValueContainer, { ...props, isDisabled: props.selectProps.isDisabled, children: props.children }) }));
2230
2233
  },
@@ -2547,6 +2550,19 @@ const ReactSyncSelect = ReactSelect.default || ReactSelect;
2547
2550
  const Select = (props) => {
2548
2551
  const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = "select", onMenuScrollToBottom, onInputChange, isSearchable, isClearable = false, readOnly, fieldSize = "medium", openMenuOnClick = !disabled, openMenuOnFocus = false, hideSelectedOptions = false, } = props;
2549
2552
  const { refContainer, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler } = useSelect(props);
2553
+ // Control the search input value so it doesn’t reset after selection
2554
+ const [inputValue, setInputValue] = useState("");
2555
+ const handleInputChange = useCallback((nextValue, meta) => {
2556
+ // Ignore internal actions that clear the input to preserve the typed text
2557
+ // and avoid resetting the parent’s search state
2558
+ const ignoreActions = new Set(["set-value", "input-blur", "menu-close"]);
2559
+ if (ignoreActions.has(meta.action)) {
2560
+ return inputValue;
2561
+ }
2562
+ setInputValue(nextValue);
2563
+ onInputChange?.(nextValue, meta);
2564
+ return nextValue;
2565
+ }, [inputValue, onInputChange]);
2550
2566
  const reactSelectProps = useMemo(() => ({
2551
2567
  value,
2552
2568
  menuPlacement,
@@ -2575,7 +2591,8 @@ const Select = (props) => {
2575
2591
  isClearable,
2576
2592
  id,
2577
2593
  onMenuScrollToBottom,
2578
- onInputChange,
2594
+ onInputChange: handleInputChange,
2595
+ inputValue,
2579
2596
  hideSelectedOptions,
2580
2597
  isDisabled: Boolean(disabled),
2581
2598
  }), [
@@ -2584,8 +2601,10 @@ const Select = (props) => {
2584
2601
  customStyles,
2585
2602
  dataTestId,
2586
2603
  disabled,
2604
+ handleInputChange,
2587
2605
  hideSelectedOptions,
2588
2606
  id,
2607
+ inputValue,
2589
2608
  isClearable,
2590
2609
  isLoading,
2591
2610
  isMulti,
@@ -2595,7 +2614,6 @@ const Select = (props) => {
2595
2614
  menuIsOpen,
2596
2615
  menuPlacement,
2597
2616
  onChange,
2598
- onInputChange,
2599
2617
  onMenuScrollToBottom,
2600
2618
  openMenuOnClick,
2601
2619
  openMenuOnFocus,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-form-components",
3
- "version": "1.7.23",
3
+ "version": "1.7.26",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -16,14 +16,14 @@
16
16
  "zod": "^3.23.8",
17
17
  "react-hook-form": "7.62.0",
18
18
  "tailwind-merge": "^2.0.0",
19
- "@trackunit/css-class-variance-utilities": "1.6.38",
20
- "@trackunit/react-components": "1.8.10",
21
- "@trackunit/ui-icons": "1.6.37",
22
- "@trackunit/shared-utils": "1.8.38",
23
- "@trackunit/ui-design-tokens": "1.6.40",
24
- "@trackunit/i18n-library-translation": "1.6.42",
19
+ "@trackunit/css-class-variance-utilities": "1.6.39",
20
+ "@trackunit/react-components": "1.8.11",
21
+ "@trackunit/ui-icons": "1.6.38",
22
+ "@trackunit/shared-utils": "1.8.39",
23
+ "@trackunit/ui-design-tokens": "1.6.41",
24
+ "@trackunit/i18n-library-translation": "1.6.43",
25
25
  "string-ts": "^2.0.0",
26
- "@trackunit/react-test-setup": "1.3.38",
26
+ "@trackunit/react-test-setup": "1.3.39",
27
27
  "@js-temporal/polyfill": "^0.5.1"
28
28
  },
29
29
  "module": "./index.esm.js",
@@ -34,6 +34,7 @@ interface TagsContainerProps {
34
34
  * @memberof TagsContainerProps
35
35
  */
36
36
  itemsGap?: number;
37
+ preFix: ReactElement | null;
37
38
  postFix: ReactElement;
38
39
  /**
39
40
  * Is the parent dropdown disabled
@@ -46,5 +47,5 @@ interface TagsContainerProps {
46
47
  * @param {TagsContainerProps} props - The props for the TagContainer
47
48
  * @returns {ReactElement} TagsContainer
48
49
  */
49
- export declare const TagsContainer: ({ items, width, itemsGap, postFix, disabled }: TagsContainerProps) => import("react/jsx-runtime").JSX.Element;
50
+ export declare const TagsContainer: ({ items, width, itemsGap, postFix, preFix, disabled, }: TagsContainerProps) => import("react/jsx-runtime").JSX.Element;
50
51
  export {};