@mtes-mct/monitor-ui 4.0.0 → 4.0.2

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.
@@ -1,3 +1,4 @@
1
1
  import type { SearchProps } from '../fields/Search';
2
- export type FormikSearchProps<OptionValue extends number | string | Record<string, any> = string> = Omit<SearchProps<OptionValue>, 'defaultValue' | 'error' | 'onChange'>;
3
- export declare function FormikSearch<OptionValue extends number | string | Record<string, any> = string>({ name, ...originalProps }: FormikSearchProps<OptionValue>): JSX.Element;
2
+ import type { OptionValueType } from '../types';
3
+ export type FormikSearchProps<OptionValue extends OptionValueType = string> = Omit<SearchProps<OptionValue>, 'defaultValue' | 'error' | 'onChange'>;
4
+ export declare function FormikSearch<OptionValue extends OptionValueType = string>({ name, ...originalProps }: FormikSearchProps<OptionValue>): JSX.Element;
@@ -1,3 +1,4 @@
1
1
  import type { SelectProps } from '../fields/Select';
2
- export type FormikSelectProps<OptionValue extends number | string | Record<string, any> = string> = Omit<SelectProps<OptionValue>, 'error' | 'onChange' | 'value'>;
3
- export declare function FormikSelect<OptionValue extends number | string | Record<string, any> = string>({ name, ...originalProps }: FormikSelectProps<OptionValue>): JSX.Element;
2
+ import type { OptionValueType } from '../types';
3
+ export type FormikSelectProps<OptionValue extends OptionValueType = string> = Omit<SelectProps<OptionValue>, 'error' | 'onChange' | 'value'>;
4
+ export declare function FormikSelect<OptionValue extends OptionValueType = string>({ name, ...originalProps }: FormikSelectProps<OptionValue>): JSX.Element;
@@ -0,0 +1,9 @@
1
+ import type { Promisable } from 'type-fest';
2
+ export declare function useFieldControl<T>(value: T, onChange: ((nextValue: T) => Promisable<void>) | undefined, props: {
3
+ [key: string]: any;
4
+ disabled: boolean;
5
+ isUndefinedWhenDisabled: boolean;
6
+ }): {
7
+ controlledOnChange: (nextValue: T) => Promisable<void>;
8
+ controlledValue: T | undefined;
9
+ };
package/index.d.ts CHANGED
@@ -53,7 +53,7 @@ export { noop } from './utils/noop';
53
53
  export { isNumeric } from './utils/isNumeric';
54
54
  export { stopMouseEventPropagation } from './utils/stopMouseEventPropagation';
55
55
  export type { PartialTheme, Theme } from './theme';
56
- export type { Coordinates, DateAsStringRange, DateRange, IconProps, Option, Undefine } from './types';
56
+ export type { Coordinates, DateAsStringRange, DateRange, IconProps, Option, OptionValueType, Undefine } from './types';
57
57
  export type { DropdownProps, DropdownItemProps } from './components/Dropdown';
58
58
  export type { SingleTagProps } from './components/SingleTag';
59
59
  export type { ButtonProps } from './elements/Button';
package/index.js CHANGED
@@ -2841,7 +2841,6 @@ p.disabled ? p.theme.color.lightGray : p.hasError ? p.theme.color.maximumRed : p
2841
2841
  margin-bottom: 4px;
2842
2842
  `;
2843
2843
 
2844
- // eslint-disable-next-line @typescript-eslint/naming-convention
2845
2844
  function Legend({ disabled = false, hasError = false, isHidden = false, ...nativeProps }) {
2846
2845
  return jsx(StyledLabel, { as: "legend", disabled: disabled, hasError: hasError, isHidden: isHidden, ...nativeProps });
2847
2846
  }
@@ -3491,9 +3490,7 @@ const useClickOutsideEffect = (zoneRefOrzoneRefs, action, baseContainer) => {
3491
3490
  }, [baseContainer, handleClickOutside]);
3492
3491
  };
3493
3492
 
3494
- function useFieldUndefineEffect(
3495
- // eslint-disable-next-line @typescript-eslint/naming-convention
3496
- disabled, onChange, onDisable) {
3493
+ function useFieldUndefineEffect(disabled, onChange, onDisable) {
3497
3494
  useEffect(() => {
3498
3495
  if (!disabled) {
3499
3496
  return;
@@ -20718,8 +20715,7 @@ var lodash = {
20718
20715
  * @see https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
20719
20716
  */
20720
20717
  function useForceUpdate() {
20721
- // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars
20722
- const [_, forceUpdate] = useReducer(x => x + 1, 0);
20718
+ const [, forceUpdate] = useReducer(x => x + 1, 0);
20723
20719
  const forceDebouncedUpdate = useMemo(() => lodashExports.throttle(forceUpdate, 500), [forceUpdate]);
20724
20720
  return { forceDebouncedUpdate, forceUpdate };
20725
20721
  }
@@ -20737,7 +20733,7 @@ const getPseudoRandomString = () => Math.random().toString(36).slice(2);
20737
20733
  function useKey(deps) {
20738
20734
  const keyRef = useRef(getPseudoRandomString());
20739
20735
  const prevDeps = usePrevious(deps);
20740
- if (!prevDeps || equals(deps, prevDeps)) {
20736
+ if (lodashExports.isEqual(deps, prevDeps)) {
20741
20737
  return keyRef.current;
20742
20738
  }
20743
20739
  keyRef.current = getPseudoRandomString();
@@ -21393,9 +21389,7 @@ const StyledNumberInput = styled.input `
21393
21389
  }
21394
21390
  `;
21395
21391
 
21396
- function DateInputWithRef({ baseContainer, defaultValue,
21397
- // eslint-disable-next-line @typescript-eslint/naming-convention
21398
- disabled = false, isCompact, isEndDate = false, isForcedFocused, isLight, isStartDate = false, onBack, onChange, onClick, onNext, onPrevious }, ref) {
21392
+ function DateInputWithRef({ baseContainer, defaultValue, disabled = false, isCompact, isEndDate = false, isForcedFocused, isLight, isStartDate = false, onBack, onChange, onClick, onNext, onPrevious }, ref) {
21399
21393
  const boxRef = useRef();
21400
21394
  const dayInputRef = useRef();
21401
21395
  const monthInputRef = useRef();
@@ -21579,9 +21573,7 @@ const Option = styled.div `
21579
21573
  }
21580
21574
  `;
21581
21575
 
21582
- function TimeInputWithRef({ baseContainer, defaultValue,
21583
- // eslint-disable-next-line @typescript-eslint/naming-convention
21584
- disabled = false, isCompact, isEndDate = false, isLight, isStartDate = false, minutesRange = 15, onBack, onChange, onFocus, onNext, onPrevious }, ref) {
21576
+ function TimeInputWithRef({ baseContainer, defaultValue, disabled = false, isCompact, isEndDate = false, isLight, isStartDate = false, minutesRange = 15, onBack, onChange, onFocus, onNext, onPrevious }, ref) {
21585
21577
  const boxRef = useRef();
21586
21578
  const hourInputRef = useRef();
21587
21579
  const minuteInputRef = useRef();
@@ -21693,9 +21685,7 @@ const InputGroup = styled.div `
21693
21685
  }
21694
21686
  `;
21695
21687
 
21696
- function DatePicker({ baseContainer, defaultValue,
21697
- // eslint-disable-next-line @typescript-eslint/naming-convention
21698
- disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
21688
+ function DatePicker({ baseContainer, defaultValue, disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
21699
21689
  const boxRef = useRef();
21700
21690
  const dateInputRef = useRef();
21701
21691
  const timeInputRef = useRef();
@@ -22016,9 +22006,7 @@ var DateRangePosition;
22016
22006
  DateRangePosition["START"] = "START";
22017
22007
  })(DateRangePosition || (DateRangePosition = {}));
22018
22008
 
22019
- function DateRangePicker({ baseContainer, defaultValue,
22020
- // eslint-disable-next-line @typescript-eslint/naming-convention
22021
- disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
22009
+ function DateRangePicker({ baseContainer, defaultValue, disabled = false, error, isCompact = false, isHistorical = false, isLabelHidden = false, isLight = false, isStringDate = false, label, minutesRange = 15, onChange, withTime = false, ...nativeProps }) {
22022
22010
  const startDateInputRef = useRef();
22023
22011
  const startTimeInputRef = useRef();
22024
22012
  const endDateInputRef = useRef();
@@ -22207,9 +22195,7 @@ const Field = styled.span `
22207
22195
  }};
22208
22196
  `;
22209
22197
 
22210
- function MultiCheckbox({ value = [],
22211
- // eslint-disable-next-line @typescript-eslint/naming-convention
22212
- disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, name, onChange, options }) {
22198
+ function MultiCheckbox({ value = [], disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, name, onChange, options }) {
22213
22199
  // This tracks the component internal value which allows us to react to value changes after each checkbox toggling
22214
22200
  const [internalValue, setInternalValue] = useState(value);
22215
22201
  // and compare it with an eventual external value change (via the `value` prop)
@@ -22272,12 +22258,40 @@ const ChecboxesBox = styled.div `
22272
22258
  `}
22273
22259
  `;
22274
22260
 
22261
+ function useFieldControl(value, onChange, props) {
22262
+ const { disabled, isUndefinedWhenDisabled } = props;
22263
+ // This tracks the component internal value which allows us to react to value changes after the checkbox toggling
22264
+ const internalValueRef = useRef(value);
22265
+ // and compare it with an eventual external value change (via the `value` prop)
22266
+ const previousValue = usePrevious(value);
22267
+ const { forceUpdate } = useForceUpdate();
22268
+ const controlledValue = isUndefinedWhenDisabled && disabled ? undefined : internalValueRef.current;
22269
+ const controlledOnChange = useCallback((nextValue) => {
22270
+ internalValueRef.current = nextValue;
22271
+ if (onChange) {
22272
+ onChange(nextValue);
22273
+ }
22274
+ }, [onChange]);
22275
+ // We update the `internalValue` each time the `value` prop is updated
22276
+ useEffect(() => {
22277
+ if (lodashExports.isEqual(value, previousValue)) {
22278
+ return;
22279
+ }
22280
+ internalValueRef.current = value;
22281
+ forceUpdate();
22282
+ }, [forceUpdate, previousValue, value]);
22283
+ return { controlledOnChange, controlledValue };
22284
+ }
22285
+
22286
+ function getRsuiteValueFromOptionValue(optionValue, optionValueKey) {
22287
+ return optionValue !== undefined ? String(optionValueKey ? optionValue[optionValueKey] : optionValue) : undefined;
22288
+ }
22289
+
22275
22290
  function getRsuiteDataFromOptions(options, optionValueKey) {
22276
- const getDataValueFromOptionValue = (value) => String(optionValueKey ? value[optionValueKey] : value);
22277
22291
  return options.map(({ value, ...rest }) => ({
22278
22292
  ...rest,
22279
22293
  optionValue: value,
22280
- value: getDataValueFromOptionValue(value)
22294
+ value: getRsuiteValueFromOptionValue(value, optionValueKey)
22281
22295
  }));
22282
22296
  }
22283
22297
 
@@ -22291,36 +22305,33 @@ function toggleInCollection(item, collection) {
22291
22305
  return isInCollection ? reject(equals(item), collection) : [...collection, item];
22292
22306
  }
22293
22307
 
22294
- function MultiSelect({ baseContainer, error, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, onChange, options, optionValueKey,
22295
- // eslint-disable-next-line @typescript-eslint/naming-convention
22296
- searchable = false, value, ...originalProps }) {
22308
+ function MultiSelect({ baseContainer, disabled = false, error, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, onChange, options, optionValueKey, searchable = false, value, ...originalProps }) {
22297
22309
  // eslint-disable-next-line no-null/no-null
22298
22310
  const boxRef = useRef(null);
22299
22311
  const selectedOptionValuesRef = useRef(value || []);
22300
22312
  const [isOpen, setIsOpen] = useState(false);
22301
- const controlledValue = useMemo(() => (!isUndefinedWhenDisabled || !originalProps.disabled ? value : undefined), [isUndefinedWhenDisabled, originalProps.disabled, value]);
22313
+ const { controlledOnChange, controlledValue } = useFieldControl(value, onChange, {
22314
+ disabled,
22315
+ isUndefinedWhenDisabled
22316
+ });
22302
22317
  const controlledError = useMemo(() => normalizeString(error), [error]);
22303
22318
  const data = useMemo(() => getRsuiteDataFromOptions(options, optionValueKey), [options, optionValueKey]);
22304
22319
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
22305
- const key = useKey([controlledValue, originalProps.disabled, originalProps.name]);
22320
+ const key = useKey([disabled, originalProps.name, value]);
22306
22321
  const { forceUpdate } = useForceUpdate();
22307
22322
  const close = useCallback(() => {
22308
22323
  setIsOpen(false);
22309
22324
  }, []);
22310
22325
  const handleClean = useCallback(() => {
22311
22326
  selectedOptionValuesRef.current = [];
22312
- if (onChange) {
22313
- onChange(undefined);
22314
- }
22315
- }, [onChange]);
22327
+ controlledOnChange(undefined);
22328
+ }, [controlledOnChange]);
22316
22329
  const handleSelect = useCallback((_, selectedItem) => {
22317
22330
  const nextValues = toggleInCollection(selectedItem.optionValue, selectedOptionValuesRef.current);
22318
22331
  selectedOptionValuesRef.current = nextValues;
22319
- if (onChange) {
22320
- const normalizedNextValue = !nextValues.length ? undefined : nextValues;
22321
- onChange(normalizedNextValue);
22322
- }
22323
- }, [onChange]);
22332
+ const normalizedNextValue = !nextValues.length ? undefined : nextValues;
22333
+ controlledOnChange(normalizedNextValue);
22334
+ }, [controlledOnChange]);
22324
22335
  const renderMenuItem = useCallback((node) => jsx("span", { title: String(node), children: String(node) }), []);
22325
22336
  const toggle = useCallback((event) => {
22326
22337
  let targetElement = event.target;
@@ -22335,12 +22346,12 @@ searchable = false, value, ...originalProps }) {
22335
22346
  setIsOpen(!isOpen);
22336
22347
  }
22337
22348
  }, [isOpen]);
22338
- useFieldUndefineEffect(isUndefinedWhenDisabled && originalProps.disabled, onChange);
22349
+ useFieldUndefineEffect(isUndefinedWhenDisabled && disabled, onChange);
22339
22350
  useClickOutsideEffect(boxRef, close, baseContainer);
22340
22351
  useEffect(() => {
22341
22352
  forceUpdate();
22342
22353
  }, [forceUpdate]);
22343
- return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box$4, { ref: boxRef, "$hasError": hasError, "$isActive": isOpen, "$isLight": isLight, onClick: toggle, children: boxRef.current && (jsx(TagPicker, { container: boxRef.current, data: data, id: originalProps.name, onClean: handleClean, onClick: toggle,
22354
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box$4, { ref: boxRef, "$hasError": hasError, "$isActive": isOpen, "$isLight": isLight, onClick: toggle, children: boxRef.current && (jsx(TagPicker, { container: boxRef.current, data: data, disabled: disabled, id: originalProps.name, onClean: handleClean, onClick: toggle,
22344
22355
  // Since we customized `ItemDataType` type by adding `optionValue`, we have an optional vs required conflict
22345
22356
  onSelect: handleSelect, open: isOpen, renderMenuItem: renderMenuItem, searchable: searchable, value: controlledValue, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
22346
22357
  }
@@ -22465,30 +22476,18 @@ const Box$4 = styled.div `
22465
22476
  }
22466
22477
  `;
22467
22478
 
22468
- function MultiRadio({
22469
- // eslint-disable-next-line @typescript-eslint/naming-convention
22470
- disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, name, onChange, options, value }) {
22471
- // This tracks the component internal value which allows us to react to value changes after a radio toggling
22472
- const [internalValue, setInternalValue] = useState(value);
22473
- // and compare it with an eventual external value change (via the `value` prop)
22474
- const previousValue = usePrevious(value);
22475
- // to decide which on is the source of "truth" in `controlledValue` (the last one to be changed is the true value)
22476
- const controlledValue = useMemo(() => {
22477
- // If the `value` has changed, `value` takes precedence,
22478
- // otherwise we can use our current internal value
22479
- const nextControlledValue = lodashExports.isEqual(value, previousValue) ? internalValue : value;
22480
- return !isUndefinedWhenDisabled || !disabled ? nextControlledValue : undefined;
22481
- }, [disabled, internalValue, isUndefinedWhenDisabled, previousValue, value]);
22479
+ function MultiRadio({ disabled = false, error, isInline = false, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, name, onChange, options, value }) {
22480
+ const { controlledOnChange, controlledValue } = useFieldControl(value, onChange, {
22481
+ disabled,
22482
+ isUndefinedWhenDisabled
22483
+ });
22482
22484
  const controlledError = useMemo(() => normalizeString(error), [error]);
22483
22485
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
22484
- const key = useKey([controlledValue, disabled, name]);
22486
+ const key = useKey([disabled, name, value]);
22485
22487
  const handleChange = useCallback((nextOptionValue, isChecked) => {
22486
22488
  const nextCheckedOptionValue = isChecked ? nextOptionValue : undefined;
22487
- setInternalValue(nextCheckedOptionValue);
22488
- if (onChange) {
22489
- onChange(nextCheckedOptionValue);
22490
- }
22491
- }, [onChange]);
22489
+ controlledOnChange(nextCheckedOptionValue);
22490
+ }, [controlledOnChange]);
22492
22491
  useFieldUndefineEffect(isUndefinedWhenDisabled && disabled, onChange);
22493
22492
  return (jsxs(Fieldset, { disabled: disabled, hasError: hasError, isLegendHidden: isLabelHidden, isLight: isLight, legend: label, children: [jsx(CheckboxesBox, { "$isInline": isInline, children: options.map(option => (jsx(Radio, { checked: equals(option.value, controlledValue), disabled: disabled, name: name, onChange: (_, isChecked) => handleChange(option.value, isChecked), children: option.label }, JSON.stringify(option.value)))) }), hasError && jsx(FieldError, { children: controlledError })] }, key));
22494
22493
  }
@@ -22530,9 +22529,7 @@ const CheckboxesBox = styled.div `
22530
22529
  `}
22531
22530
  `;
22532
22531
 
22533
- function MultiZoneEditor({ addButtonLabel, defaultValue = [],
22534
- // eslint-disable-next-line @typescript-eslint/naming-convention
22535
- disabled = false, error, initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onChange, onDelete, onEdit }) {
22532
+ function MultiZoneEditor({ addButtonLabel, defaultValue = [], disabled = false, error, initialZone, isLabelHidden = false, isLight = false, label, labelPropName, onAdd, onCenter, onChange, onDelete, onEdit }) {
22536
22533
  const prevDefaultValueRef = useRef(defaultValue);
22537
22534
  const [zones, setZones] = useState(defaultValue);
22538
22535
  const controlledError = useMemo(() => normalizeString(error), [error]);
@@ -22642,9 +22639,7 @@ function isNumeric(val) {
22642
22639
  }
22643
22640
 
22644
22641
  // TODO This field should return undefined when cleared (i.e.: Select all & Backspace/Delete)
22645
- function DDCoordinatesInput({ coordinates,
22646
- // eslint-disable-next-line @typescript-eslint/naming-convention
22647
- disabled = false, onChange }) {
22642
+ function DDCoordinatesInput({ coordinates, disabled = false, onChange }) {
22648
22643
  const latitudeInputRef = useRef();
22649
22644
  const longitudeInputRef = useRef();
22650
22645
  const [latitudeError, setLatitudeError] = useState('');
@@ -32638,9 +32633,7 @@ const coordinatesAreDistinct = (nextCoordinates, coordinates) => {
32638
32633
  // Open issue: https://github.com/uNmAnNeR/imaskjs/issues/761
32639
32634
  const UntypedIMaskInput = IMaskInput;
32640
32635
  // TODO This field should return undefined when cleared (i.e.: Select all & Backspace/Delete)
32641
- function DMDCoordinatesInput({ coordinates, coordinatesFormat,
32642
- // eslint-disable-next-line @typescript-eslint/naming-convention
32643
- disabled = false, onChange }) {
32636
+ function DMDCoordinatesInput({ coordinates, coordinatesFormat, disabled = false, onChange }) {
32644
32637
  const [error, setError] = useState('');
32645
32638
  const [value, setValue] = useState('');
32646
32639
  useEffect(() => {
@@ -32712,9 +32705,7 @@ const Box$2 = styled.div `
32712
32705
  text-align: left;
32713
32706
  `;
32714
32707
 
32715
- function DMSCoordinatesInput({ coordinates, coordinatesFormat,
32716
- // eslint-disable-next-line @typescript-eslint/naming-convention
32717
- disabled = false, onChange }) {
32708
+ function DMSCoordinatesInput({ coordinates, coordinatesFormat, disabled = false, onChange }) {
32718
32709
  /** Convert the coordinates to the [latitude, longitude] string format */
32719
32710
  const defaultValue = useMemo(() => {
32720
32711
  if (!coordinates?.length || !coordinatesFormat) {
@@ -32741,9 +32732,7 @@ const Box$1 = styled.div `
32741
32732
 
32742
32733
  const noop = () => { };
32743
32734
 
32744
- function CoordinatesInput({ coordinatesFormat, defaultValue,
32745
- // eslint-disable-next-line @typescript-eslint/naming-convention
32746
- error, isLabelHidden = false, isLight = false, label, onChange = noop, ...nativeProps }) {
32735
+ function CoordinatesInput({ coordinatesFormat, defaultValue, error, isLabelHidden = false, isLight = false, label, onChange = noop, ...nativeProps }) {
32747
32736
  const controlledError = useMemo(() => normalizeString(error), [error]);
32748
32737
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
32749
32738
  const getCoordinatesInput = useCallback(() => {
@@ -32772,32 +32761,30 @@ const StyledFieldset = styled(Fieldset) `
32772
32761
  }
32773
32762
  `;
32774
32763
 
32775
- function Select({ baseContainer, error, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, onChange, options, optionValueKey,
32776
- // eslint-disable-next-line @typescript-eslint/naming-convention
32777
- searchable = false, value, ...originalProps }) {
32764
+ function Select({ baseContainer, disabled = false, error, isLabelHidden = false, isLight = false, isUndefinedWhenDisabled = false, label, onChange, options, optionValueKey, searchable = false, value, ...originalProps }) {
32778
32765
  // eslint-disable-next-line no-null/no-null
32779
32766
  const boxRef = useRef(null);
32780
32767
  const [isOpen, setIsOpen] = useState(false);
32781
32768
  const { forceUpdate } = useForceUpdate();
32782
- const controlledValue = useMemo(() => (!isUndefinedWhenDisabled || !originalProps.disabled ? value : undefined), [isUndefinedWhenDisabled, originalProps.disabled, value]);
32769
+ const { controlledOnChange, controlledValue } = useFieldControl(value, onChange, {
32770
+ disabled,
32771
+ isUndefinedWhenDisabled
32772
+ });
32773
+ const controlledRsuiteValue = useMemo(() => getRsuiteValueFromOptionValue(controlledValue, optionValueKey), [controlledValue, optionValueKey]);
32783
32774
  const controlledError = useMemo(() => normalizeString(error), [error]);
32784
32775
  const data = useMemo(() => getRsuiteDataFromOptions(options, optionValueKey), [options, optionValueKey]);
32785
32776
  const hasError = useMemo(() => Boolean(controlledError), [controlledError]);
32786
- const key = useKey([controlledValue, originalProps.disabled, originalProps.name]);
32777
+ const key = useKey([disabled, originalProps.name, value]);
32787
32778
  const close = useCallback(() => {
32788
32779
  setIsOpen(false);
32789
32780
  }, []);
32790
32781
  const handleClean = useCallback(() => {
32791
- if (onChange) {
32792
- onChange(undefined);
32793
- }
32794
- }, [onChange]);
32782
+ controlledOnChange(undefined);
32783
+ }, [controlledOnChange]);
32795
32784
  const handleSelect = useCallback((_, selectedItem) => {
32796
32785
  close();
32797
- if (onChange) {
32798
- onChange(selectedItem.optionValue);
32799
- }
32800
- }, [close, onChange]);
32786
+ controlledOnChange(selectedItem.optionValue);
32787
+ }, [close, controlledOnChange]);
32801
32788
  const renderMenuItem = useCallback((node) => jsx("span", { title: String(node), children: String(node) }), []);
32802
32789
  const toggle = useCallback((event) => {
32803
32790
  let targetElement = event.target;
@@ -32814,14 +32801,14 @@ searchable = false, value, ...originalProps }) {
32814
32801
  setIsOpen(!isOpen);
32815
32802
  }
32816
32803
  }, [isOpen]);
32817
- useFieldUndefineEffect(isUndefinedWhenDisabled && originalProps.disabled, onChange);
32804
+ useFieldUndefineEffect(isUndefinedWhenDisabled && disabled, onChange);
32818
32805
  useClickOutsideEffect(boxRef, close, baseContainer);
32819
32806
  useEffect(() => {
32820
32807
  forceUpdate();
32821
32808
  }, [forceUpdate]);
32822
- return (jsxs(Field$2, { children: [jsx(Label, { disabled: originalProps.disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box, { ref: boxRef, onClick: toggle, children: boxRef.current && (jsx(StyledSelectPicker, { "$isLight": isLight, container: boxRef.current, data: data, id: originalProps.name, onClean: handleClean,
32809
+ return (jsxs(Field$2, { children: [jsx(Label, { disabled: disabled, hasError: hasError, htmlFor: originalProps.name, isHidden: isLabelHidden, children: label }), jsx(Box, { ref: boxRef, onClick: toggle, children: boxRef.current && (jsx(StyledSelectPicker, { "$isLight": isLight, container: boxRef.current, data: data, disabled: disabled, id: originalProps.name, onClean: handleClean,
32823
32810
  // Since we customized `ItemDataType` type by adding `optionValue`, we have an optional vs required conflict
32824
- onSelect: handleSelect, open: isOpen, renderMenuItem: renderMenuItem, searchable: searchable, value: controlledValue, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
32811
+ onSelect: handleSelect, open: isOpen, renderMenuItem: renderMenuItem, searchable: searchable, value: controlledRsuiteValue, ...originalProps }, key)) }), hasError && jsx(FieldError, { children: controlledError })] }));
32825
32812
  }
32826
32813
  const StyledSelectPicker = styled(SelectPicker) `
32827
32814
  > .rs-picker-toggle {