@ceed/ads 1.40.1 → 1.41.0

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/index.cjs CHANGED
@@ -415,13 +415,17 @@ var IconButton_default = IconButton;
415
415
  var import_react5 = require("react");
416
416
  function useControlledState(controlledValue, defaultValue, onChange) {
417
417
  const { current: isControlled } = (0, import_react5.useRef)(controlledValue !== void 0);
418
- const [internalValue, setInternalValue] = (0, import_react5.useState)(controlledValue ?? defaultValue);
419
- const displayValue = isControlled ? controlledValue : internalValue;
418
+ const [internalValue, setInternalValue] = (0, import_react5.useState)(controlledValue !== void 0 ? controlledValue : defaultValue);
419
+ const hasWarnedRef = (0, import_react5.useRef)(false);
420
420
  (0, import_react5.useEffect)(() => {
421
- if (isControlled) {
422
- setInternalValue(controlledValue);
423
- }
421
+ if (false) return;
422
+ if (hasWarnedRef.current || isControlled === (controlledValue !== void 0)) return;
423
+ hasWarnedRef.current = true;
424
+ console.warn(
425
+ isControlled ? "useControlledState: A component is changing a controlled input to be uncontrolled. Pass `null` instead of `undefined` to keep it controlled with an empty value." : "useControlledState: A component is changing an uncontrolled input to be controlled. Pass `null` instead of `undefined` for the initial empty value to make it controlled from the first render."
426
+ );
424
427
  }, [isControlled, controlledValue]);
428
+ const displayValue = isControlled ? controlledValue : internalValue;
425
429
  const handleChange = (0, import_react5.useCallback)(
426
430
  (value) => {
427
431
  const newValue = typeof value === "function" ? value(displayValue) : value;
@@ -528,6 +532,7 @@ var AutocompleteListBox = import_react6.default.forwardRef((props, ref) => {
528
532
  )
529
533
  ))));
530
534
  });
535
+ var EMPTY_MULTIPLE_VALUE = [];
531
536
  var autocompleteDeleteSize = {
532
537
  sm: "20px",
533
538
  md: "24px",
@@ -570,9 +575,9 @@ function Autocomplete(props) {
570
575
  className,
571
576
  ...innerProps
572
577
  } = props;
573
- const [_value, setValue] = useControlledState(
578
+ const [rawValue, setValue] = useControlledState(
574
579
  props.value,
575
- props.defaultValue || "",
580
+ props.defaultValue ?? null,
576
581
  (0, import_react6.useCallback)(
577
582
  (value2) => onChange?.({
578
583
  target: {
@@ -583,6 +588,7 @@ function Autocomplete(props) {
583
588
  [onChange, props.name]
584
589
  )
585
590
  );
591
+ const _value = rawValue ?? (props.multiple ? EMPTY_MULTIPLE_VALUE : "");
586
592
  const options = (0, import_react6.useMemo)(
587
593
  () => props.options.map((option) => {
588
594
  if (typeof option !== "object") {
@@ -643,7 +649,7 @@ function Autocomplete(props) {
643
649
  (event, value2) => {
644
650
  const newValue = value2;
645
651
  const _value2 = Array.isArray(newValue) ? newValue.map((value3) => value3.value) : newValue?.value;
646
- setValue(_value2);
652
+ setValue(_value2 ?? null);
647
653
  if (Array.isArray(newValue) && newValue.map((value3) => optionMap.get(value3.value)) || optionMap.get(newValue?.value)) {
648
654
  onChangeComplete?.({
649
655
  ...event,
@@ -1965,6 +1971,10 @@ var Input = import_react18.default.forwardRef((props, ref) => {
1965
1971
  onChange,
1966
1972
  name,
1967
1973
  type,
1974
+ // NOTE: value/defaultValue는 아래에서 직접 다루므로 innerProps 스프레드에서 제외한다.
1975
+ // defaultValue가 스프레드에 남으면 항상 정의되는 value와 함께 DOM input에 도달해 React가 경고한다.
1976
+ value: valueProp,
1977
+ defaultValue: defaultValueProp,
1968
1978
  // NOTE: 스타일 관련된 props는 최상위 엘리먼트에 적용한다.
1969
1979
  sx,
1970
1980
  className,
@@ -1977,8 +1987,8 @@ var Input = import_react18.default.forwardRef((props, ref) => {
1977
1987
  }
1978
1988
  const [passwordVisible, setPasswordVisible] = (0, import_react18.useState)(false);
1979
1989
  const [value, setValue] = useControlledState(
1980
- props.value,
1981
- props.defaultValue,
1990
+ valueProp,
1991
+ defaultValueProp ?? null,
1982
1992
  (0, import_react18.useCallback)(
1983
1993
  (value2) => {
1984
1994
  onChange?.({
@@ -1997,8 +2007,9 @@ var Input = import_react18.default.forwardRef((props, ref) => {
1997
2007
  setValue(e.target.value);
1998
2008
  };
1999
2009
  const handleClear = () => {
2000
- setValue(props.defaultValue || "");
2010
+ setValue(defaultValueProp || "");
2001
2011
  };
2012
+ const displayValue = valueProp !== void 0 ? valueProp : value;
2002
2013
  const handleTogglePasswordVisibility = () => {
2003
2014
  setPasswordVisible((prev) => !prev);
2004
2015
  };
@@ -2008,7 +2019,7 @@ var Input = import_react18.default.forwardRef((props, ref) => {
2008
2019
  const input = /* @__PURE__ */ import_react18.default.createElement(
2009
2020
  MotionInput,
2010
2021
  {
2011
- value,
2022
+ value: displayValue ?? "",
2012
2023
  name,
2013
2024
  onChange: handleChange,
2014
2025
  required,
@@ -2029,7 +2040,7 @@ var Input = import_react18.default.forwardRef((props, ref) => {
2029
2040
  "aria-label": passwordVisible ? "Hide password" : "Show password"
2030
2041
  },
2031
2042
  passwordVisible ? /* @__PURE__ */ import_react18.default.createElement(import_VisibilityOff.default, null) : /* @__PURE__ */ import_react18.default.createElement(import_Visibility.default, null)
2032
- )) : null : enableClearable ? /* @__PURE__ */ import_react18.default.createElement(Stack_default, { gap: 1, direction: "row" }, innerProps.endDecorator, value && /* @__PURE__ */ import_react18.default.createElement(
2043
+ )) : null : enableClearable ? /* @__PURE__ */ import_react18.default.createElement(Stack_default, { gap: 1, direction: "row" }, innerProps.endDecorator, displayValue && /* @__PURE__ */ import_react18.default.createElement(
2033
2044
  IconButton_default,
2034
2045
  {
2035
2046
  onMouseDown: (e) => e.preventDefault(),
@@ -2267,7 +2278,7 @@ var CurrencyInput = import_react19.default.forwardRef(function CurrencyInput2(in
2267
2278
  const { symbol, thousandSeparator, decimalSeparator, placeholder, fixedDecimalScale, decimalScale } = useCurrencySetting(props);
2268
2279
  const [_value, setValue] = useControlledState(
2269
2280
  props.value,
2270
- props.defaultValue,
2281
+ props.defaultValue ?? null,
2271
2282
  (0, import_react19.useCallback)((value2) => onChange?.({ target: { name, value: value2 } }), [onChange, name])
2272
2283
  );
2273
2284
  const value = (0, import_react19.useMemo)(() => {
@@ -2282,22 +2293,17 @@ var CurrencyInput = import_react19.default.forwardRef(function CurrencyInput2(in
2282
2293
  }
2283
2294
  return props.max;
2284
2295
  }, [props.max, useMinorUnit, decimalScale]);
2285
- const [isOverLimit, setIsOverLimit] = (0, import_react19.useState)(!!max && !!value && value > max);
2296
+ const isOverLimit = (0, import_react19.useMemo)(() => max != null && value != null && value > max, [max, value]);
2286
2297
  const handleChange = (0, import_react19.useCallback)(
2287
2298
  (event) => {
2288
2299
  if (event.target.value === "") {
2289
- setValue(void 0);
2300
+ setValue(null);
2290
2301
  return;
2291
2302
  }
2292
2303
  const amount = useMinorUnit ? Number(decimalSeparator ? event.target.value?.replace(decimalSeparator, "") : event.target.value) : Number(event.target.value);
2293
- if (!!max && Number(event.target.value) > max) {
2294
- setIsOverLimit(true);
2295
- } else {
2296
- setIsOverLimit(false);
2297
- }
2298
2304
  setValue(amount);
2299
2305
  },
2300
- [decimalSeparator, max, useMinorUnit, setValue]
2306
+ [decimalSeparator, useMinorUnit, setValue]
2301
2307
  );
2302
2308
  return /* @__PURE__ */ import_react19.default.createElement(
2303
2309
  CurrencyInputRoot,
@@ -2975,11 +2981,15 @@ var DatePicker = (0, import_react21.forwardRef)((inProps, ref) => {
2975
2981
  } = props;
2976
2982
  const innerRef = (0, import_react21.useRef)(null);
2977
2983
  const buttonRef = (0, import_react21.useRef)(null);
2978
- const [value, setValue] = useControlledState(
2984
+ const [rawValue, setValue] = useControlledState(
2979
2985
  props.value,
2980
- props.defaultValue || "",
2981
- (0, import_react21.useCallback)((value2) => onChange?.({ target: { name: props.name, value: value2 } }), [props.name, onChange])
2986
+ props.defaultValue ?? null,
2987
+ (0, import_react21.useCallback)(
2988
+ (value2) => onChange?.({ target: { name: props.name, value: value2 ?? "" } }),
2989
+ [props.name, onChange]
2990
+ )
2982
2991
  );
2992
+ const value = rawValue ?? "";
2983
2993
  const isAlphabeticDisplay = hasAlphabeticMonth(displayFormat);
2984
2994
  const [displayValue, setDisplayValue] = (0, import_react21.useState)(
2985
2995
  () => value ? formatValueString(parseDate(value, format), displayFormat, locale) : ""
@@ -5264,11 +5274,15 @@ var DateRangePicker = (0, import_react30.forwardRef)((inProps, ref) => {
5264
5274
  } = props;
5265
5275
  const innerRef = (0, import_react30.useRef)(null);
5266
5276
  const buttonRef = (0, import_react30.useRef)(null);
5267
- const [value, setValue] = useControlledState(
5277
+ const [rawValue, setValue] = useControlledState(
5268
5278
  props.value,
5269
- props.defaultValue || "",
5270
- (0, import_react30.useCallback)((value2) => onChange?.({ target: { name: props.name, value: value2 } }), [props.name, onChange])
5279
+ props.defaultValue ?? null,
5280
+ (0, import_react30.useCallback)(
5281
+ (value2) => onChange?.({ target: { name: props.name, value: value2 ?? "" } }),
5282
+ [props.name, onChange]
5283
+ )
5271
5284
  );
5285
+ const value = rawValue ?? "";
5272
5286
  const isAlphabeticDisplay = hasAlphabeticMonth2(displayFormat);
5273
5287
  const [displayValue, setDisplayValue] = (0, import_react30.useState)(
5274
5288
  () => value ? formatValueString2(parseDates(value, format), displayFormat, locale) : ""
@@ -5616,6 +5630,7 @@ var import_react34 = __toESM(require("react"));
5616
5630
  var import_Search = __toESM(require("@mui/icons-material/Search"));
5617
5631
  var import_joy44 = require("@mui/joy");
5618
5632
  var import_react_virtual3 = require("@tanstack/react-virtual");
5633
+ var EMPTY_VALUE = [];
5619
5634
  function LabelWithTooltip(props) {
5620
5635
  const { label, size } = props;
5621
5636
  const labelContentRef = (0, import_react34.useRef)(null);
@@ -5663,11 +5678,12 @@ function FilterableCheckboxGroup(inProps) {
5663
5678
  } = props;
5664
5679
  const [searchTerm, setSearchTerm] = (0, import_react34.useState)("");
5665
5680
  const [sortedOptions, setSortedOptions] = (0, import_react34.useState)(options);
5666
- const [internalValue, setInternalValue] = useControlledState(
5681
+ const [rawValue, setInternalValue] = useControlledState(
5667
5682
  value,
5668
- value ?? [],
5669
- (0, import_react34.useCallback)((newValue) => onChange?.(newValue), [onChange])
5683
+ value ?? EMPTY_VALUE,
5684
+ (0, import_react34.useCallback)((newValue) => onChange?.(newValue ?? []), [onChange])
5670
5685
  );
5686
+ const internalValue = rawValue ?? EMPTY_VALUE;
5671
5687
  const parentRef = (0, import_react34.useRef)(null);
5672
5688
  const isInitialSortRef = (0, import_react34.useRef)(false);
5673
5689
  const prevOptionsRef = (0, import_react34.useRef)([...options]);
@@ -6202,11 +6218,15 @@ var MonthRangePicker = (0, import_react39.forwardRef)((inProps, ref) => {
6202
6218
  const isAlphabeticDisplay = hasAlphabeticMonth3(displayFormat);
6203
6219
  const innerRef = (0, import_react39.useRef)(null);
6204
6220
  const buttonRef = (0, import_react39.useRef)(null);
6205
- const [value, setValue] = useControlledState(
6221
+ const [rawValue, setValue] = useControlledState(
6206
6222
  props.value,
6207
- props.defaultValue || "",
6208
- (0, import_react39.useCallback)((value2) => onChange?.({ target: { name: props.name, value: value2 } }), [props.name, onChange])
6223
+ props.defaultValue ?? null,
6224
+ (0, import_react39.useCallback)(
6225
+ (value2) => onChange?.({ target: { name: props.name, value: value2 ?? "" } }),
6226
+ [props.name, onChange]
6227
+ )
6209
6228
  );
6229
+ const value = rawValue ?? "";
6210
6230
  const [displayValue, setDisplayValue] = (0, import_react39.useState)(
6211
6231
  () => value ? formatValueString3(parseDates2(value), displayFormat, locale) : ""
6212
6232
  );
@@ -6433,7 +6453,7 @@ function CurrencyInput3(props) {
6433
6453
  const [internalValue, setInternalValue] = useControlledState(value, value, onChange);
6434
6454
  const handleCurrencyChange = (0, import_react41.useCallback)(
6435
6455
  (event) => {
6436
- const newValue = event.target.value;
6456
+ const newValue = event.target.value ?? void 0;
6437
6457
  setInternalValue(newValue);
6438
6458
  },
6439
6459
  [setInternalValue]
@@ -6466,7 +6486,7 @@ function CurrencyRange(props) {
6466
6486
  const maxValue = internalValue?.[1];
6467
6487
  const handleMinChange = (0, import_react42.useCallback)(
6468
6488
  (event) => {
6469
- const newMinValue = event.target.value;
6489
+ const newMinValue = event.target.value ?? void 0;
6470
6490
  const currentMaxValue = maxValue;
6471
6491
  if (newMinValue !== void 0 && currentMaxValue !== void 0) {
6472
6492
  setInternalValue([newMinValue, currentMaxValue]);
@@ -6480,7 +6500,7 @@ function CurrencyRange(props) {
6480
6500
  );
6481
6501
  const handleMaxChange = (0, import_react42.useCallback)(
6482
6502
  (event) => {
6483
- const newMaxValue = event.target.value;
6503
+ const newMaxValue = event.target.value ?? void 0;
6484
6504
  const currentMinValue = minValue;
6485
6505
  if (currentMinValue !== void 0 && newMaxValue !== void 0) {
6486
6506
  setInternalValue([currentMinValue, newMaxValue]);
@@ -6586,34 +6606,30 @@ var PercentageInput = import_react43.default.forwardRef(
6586
6606
  } = props;
6587
6607
  const [_value, setValue] = useControlledState(
6588
6608
  props.value,
6589
- props.defaultValue,
6609
+ props.defaultValue ?? null,
6590
6610
  (0, import_react43.useCallback)((value2) => onChange?.({ target: { name, value: value2 } }), [onChange, name])
6591
6611
  );
6592
- const [internalError, setInternalError] = (0, import_react43.useState)(
6593
- max && _value && _value > max || min && _value && _value < min
6594
- );
6595
6612
  const value = (0, import_react43.useMemo)(() => {
6596
6613
  if (_value && useMinorUnit) {
6597
6614
  return _value / Math.pow(10, maxDecimalScale);
6598
6615
  }
6599
6616
  return _value;
6600
6617
  }, [_value, useMinorUnit, maxDecimalScale]);
6618
+ const internalError = (0, import_react43.useMemo)(
6619
+ () => value != null && (max != null && value > max || min != null && value < min),
6620
+ [max, min, value]
6621
+ );
6601
6622
  const handleChange = (0, import_react43.useCallback)(
6602
6623
  (event) => {
6603
6624
  if (event.target.value === "") {
6604
- setValue(void 0);
6625
+ setValue(null);
6605
6626
  return;
6606
6627
  }
6607
6628
  const originalAmount = Number(event.target.value);
6608
- if (min && originalAmount < min || max && originalAmount > max) {
6609
- setInternalError(true);
6610
- } else {
6611
- setInternalError(false);
6612
- }
6613
6629
  const amount = useMinorUnit ? padDecimal(originalAmount, maxDecimalScale) : originalAmount;
6614
6630
  setValue(amount);
6615
6631
  },
6616
- [setValue, useMinorUnit, maxDecimalScale, min, max]
6632
+ [setValue, useMinorUnit, maxDecimalScale]
6617
6633
  );
6618
6634
  return /* @__PURE__ */ import_react43.default.createElement(
6619
6635
  PercentageInputRoot,
@@ -6666,7 +6682,7 @@ var PercentageInput3 = ({
6666
6682
  PercentageInput,
6667
6683
  {
6668
6684
  value: _value,
6669
- onChange: (event) => setValue(event.target.value),
6685
+ onChange: (event) => setValue(event.target.value ?? void 0),
6670
6686
  useMinorUnit,
6671
6687
  maxDecimalScale,
6672
6688
  min,
@@ -6690,7 +6706,7 @@ function PercentageRange(props) {
6690
6706
  const maxValue = internalValue?.[1];
6691
6707
  const handleMinChange = (0, import_react45.useCallback)(
6692
6708
  (event) => {
6693
- const newMinValue = event.target.value;
6709
+ const newMinValue = event.target.value ?? void 0;
6694
6710
  const currentMaxValue = maxValue;
6695
6711
  if (newMinValue !== void 0) {
6696
6712
  setInternalValue([newMinValue, currentMaxValue || null]);
@@ -6702,7 +6718,7 @@ function PercentageRange(props) {
6702
6718
  );
6703
6719
  const handleMaxChange = (0, import_react45.useCallback)(
6704
6720
  (event) => {
6705
- const newMaxValue = event.target.value;
6721
+ const newMaxValue = event.target.value ?? void 0;
6706
6722
  const currentMinValue = minValue;
6707
6723
  if (newMaxValue !== void 0) {
6708
6724
  setInternalValue([currentMinValue || null, newMaxValue]);
@@ -6756,7 +6772,7 @@ function Autocomplete2(props) {
6756
6772
  const autocompleteValue = typeof internalValue === "string" || typeof internalValue === "number" ? String(internalValue) : void 0;
6757
6773
  const handleChange = (0, import_react46.useCallback)(
6758
6774
  (event) => {
6759
- const val = event.target.value;
6775
+ const val = event.target.value ?? void 0;
6760
6776
  if (val) {
6761
6777
  const numVal = Number(val);
6762
6778
  setInternalValue(!isNaN(numVal) && isFinite(numVal) ? numVal : val);
@@ -7544,11 +7560,15 @@ var MonthPicker = (0, import_react52.forwardRef)((inProps, ref) => {
7544
7560
  } = props;
7545
7561
  const innerRef = (0, import_react52.useRef)(null);
7546
7562
  const buttonRef = (0, import_react52.useRef)(null);
7547
- const [value, setValue, isControlled] = useControlledState(
7563
+ const [rawValue, setValue, isControlled] = useControlledState(
7548
7564
  props.value,
7549
- props.defaultValue || "",
7550
- (0, import_react52.useCallback)((value2) => onChange?.({ target: { name: props.name, value: value2 } }), [props.name, onChange])
7565
+ props.defaultValue ?? null,
7566
+ (0, import_react52.useCallback)(
7567
+ (value2) => onChange?.({ target: { name: props.name, value: value2 ?? "" } }),
7568
+ [props.name, onChange]
7569
+ )
7551
7570
  );
7571
+ const value = rawValue ?? "";
7552
7572
  const getFormattedDisplayValue = (0, import_react52.useCallback)(
7553
7573
  (inputValue) => {
7554
7574
  if (!inputValue) return "";