@farmzone/fz-react-ui 0.0.11 → 1.0.1

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
@@ -973,7 +973,7 @@ function Select2(props) {
973
973
  onChange("");
974
974
  onReset?.();
975
975
  };
976
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-0.5", containerClass ?? "w-30"), children: [
976
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-0.5", containerClass ?? "w-20"), children: [
977
977
  label && /* @__PURE__ */ jsxRuntime.jsx(
978
978
  "label",
979
979
  {
@@ -2031,7 +2031,8 @@ function RenderCalendar(props) {
2031
2031
  onYearChange,
2032
2032
  onMonthChange,
2033
2033
  editDateSelect = true,
2034
- datePosition = "bottom"
2034
+ datePosition = "bottom",
2035
+ calendarSelectContainerClass
2035
2036
  } = props;
2036
2037
  const year = currentDate.getFullYear();
2037
2038
  const month = currentDate.getMonth();
@@ -2115,7 +2116,8 @@ function RenderCalendar(props) {
2115
2116
  value: year.toString(),
2116
2117
  options: yearOptions,
2117
2118
  onChange: handleYearChange,
2118
- className: "cursor-pointer"
2119
+ className: "cursor-pointer",
2120
+ containerClass: calendarSelectContainerClass
2119
2121
  }
2120
2122
  ) }),
2121
2123
  /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: handleStopPropagation, onMouseDown: handleStopPropagation, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2124,7 +2126,8 @@ function RenderCalendar(props) {
2124
2126
  value: (month + 1).toString(),
2125
2127
  options: monthOptions,
2126
2128
  onChange: handleMonthChange,
2127
- className: " cursor-pointer"
2129
+ className: "cursor-pointer",
2130
+ containerClass: calendarSelectContainerClass
2128
2131
  }
2129
2132
  ) })
2130
2133
  ]
@@ -2292,6 +2295,7 @@ function DatePickerRange(props) {
2292
2295
  disabled = false,
2293
2296
  maxDate,
2294
2297
  calendarYearRange,
2298
+ calendarSelectContainerClass,
2295
2299
  showTodayButton = true
2296
2300
  } = props;
2297
2301
  const [inputs, setInputs] = React6.useState({ start: startValue, end: endValue });
@@ -2428,6 +2432,7 @@ function DatePickerRange(props) {
2428
2432
  datePosition: autoDatePosition,
2429
2433
  maxDate,
2430
2434
  calendarYearRange,
2435
+ calendarSelectContainerClass,
2431
2436
  showTodayButton
2432
2437
  }
2433
2438
  )
@@ -2507,6 +2512,7 @@ function DatePickerSingle(props) {
2507
2512
  disabled = false,
2508
2513
  maxDate,
2509
2514
  calendarYearRange,
2515
+ calendarSelectContainerClass,
2510
2516
  onBlur,
2511
2517
  showTodayButton = true
2512
2518
  } = props;
@@ -2599,6 +2605,7 @@ function DatePickerSingle(props) {
2599
2605
  datePosition: autoDatePosition,
2600
2606
  maxDate,
2601
2607
  calendarYearRange,
2608
+ calendarSelectContainerClass,
2602
2609
  showTodayButton
2603
2610
  }
2604
2611
  )
@@ -2657,6 +2664,7 @@ function DatePicker(props) {
2657
2664
  disabled,
2658
2665
  maxDate,
2659
2666
  calendarYearRange,
2667
+ calendarSelectContainerClass,
2660
2668
  showTodayButton
2661
2669
  } = props;
2662
2670
  if (isRange) {
@@ -2674,6 +2682,7 @@ function DatePicker(props) {
2674
2682
  disabled,
2675
2683
  maxDate,
2676
2684
  calendarYearRange,
2685
+ calendarSelectContainerClass,
2677
2686
  showTodayButton
2678
2687
  }
2679
2688
  );
@@ -2693,6 +2702,7 @@ function DatePicker(props) {
2693
2702
  disabled,
2694
2703
  maxDate,
2695
2704
  calendarYearRange,
2705
+ calendarSelectContainerClass,
2696
2706
  showTodayButton,
2697
2707
  onBlur
2698
2708
  }
@@ -3558,7 +3568,7 @@ function TableFooter(props) {
3558
3568
  const { paginationInfo, renderLeft, renderRight } = props;
3559
3569
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-4 min-h-16", children: [
3560
3570
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-start flex-1 min-w-0", children: renderLeft }),
3561
- paginationInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 px-5", children: /* @__PURE__ */ jsxRuntime.jsx(Pagination, { ...paginationInfo }) }),
3571
+ paginationInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5", children: /* @__PURE__ */ jsxRuntime.jsx(Pagination, { ...paginationInfo }) }),
3562
3572
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end flex-1 min-w-0", children: renderRight })
3563
3573
  ] }) });
3564
3574
  }
@@ -3714,7 +3724,7 @@ function useTableFixed(columns, isHeader = false) {
3714
3724
  window.addEventListener("resize", onResize);
3715
3725
  const firstKey = columns[0]?.key;
3716
3726
  const cell = firstKey ? document.getElementById(`${firstKey}${isHeader ? "-header" : "-body"}`) : null;
3717
- const tableEl = cell?.closest("table") || document.querySelector("table.table-layout");
3727
+ const tableEl = cell?.closest("table") || document.querySelector("table.table-fixed");
3718
3728
  if (tableEl && "ResizeObserver" in window) {
3719
3729
  resizeObserverRef.current = new ResizeObserver(handleResize);
3720
3730
  resizeObserverRef.current.observe(tableEl);
@@ -3801,19 +3811,14 @@ function TableHeader(props) {
3801
3811
  const columns = React6.useMemo(() => {
3802
3812
  return customColumns.map((column) => {
3803
3813
  const { key } = column;
3804
- const getWidth = () => {
3805
- if (key === "__checkbox__") {
3806
- return "40px";
3807
- }
3808
- return column.width ?? "calc(100%/4)";
3809
- };
3810
- const getAlign = () => {
3811
- if (key === "__checkbox__") {
3812
- return "center";
3813
- }
3814
- return column.align ?? "left";
3814
+ const isCheckbox = key === "__checkbox__";
3815
+ return {
3816
+ ...column,
3817
+ width: isCheckbox ? "40px" : column.width,
3818
+ minWidth: isCheckbox ? "40px" : column.minWidth ?? column.width,
3819
+ maxWidth: isCheckbox ? "40px" : column.maxWidth,
3820
+ align: isCheckbox ? "center" : column.align ?? "left"
3815
3821
  };
3816
- return { ...column, width: getWidth(), align: getAlign() };
3817
3822
  });
3818
3823
  }, [customColumns]);
3819
3824
  const { getColumnFixedStyle } = useTableFixed(columns, true);
@@ -4286,11 +4291,11 @@ function SkeletonTd(props) {
4286
4291
  return /* @__PURE__ */ jsxRuntime.jsx(
4287
4292
  "td",
4288
4293
  {
4289
- className: "px-2 py-[6.8px] whitespace-nowrap text-sm border-r border-b border-gray-200/70 last:border-r-0",
4294
+ className: `${col.key === "__checkbox__" ? "p-0" : "px-2 py-[6.8px]"} whitespace-nowrap text-sm border-r border-b border-gray-200/70 last:border-r-0`,
4290
4295
  style: {
4291
4296
  width: col.width,
4292
4297
  minWidth: col.minWidth || col.width,
4293
- maxWidth: col.maxWidth || col.width
4298
+ maxWidth: col.key === "__checkbox__" ? col.maxWidth || col.width : void 0
4294
4299
  },
4295
4300
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-4", children: showSquare ? /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "size-4 rounded-xs" }) : /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-1.5 rounded-sm", style: { width: "calc(100% - 20px)" } }) })
4296
4301
  }
@@ -4371,7 +4376,7 @@ function getAlignStyle(align) {
4371
4376
  return align === "left" ? "flex-start" : align === "center" ? "center" : "flex-end";
4372
4377
  }
4373
4378
  function applyColDefaults(col) {
4374
- const width = col.key === "__checkbox__" ? "40px" : col.width ?? col.minWidth ?? "100px";
4379
+ const width = col.key === "__checkbox__" ? "40px" : col.width ?? col.minWidth;
4375
4380
  const align = col.key === "__checkbox__" ? "center" : col.align ?? "left";
4376
4381
  return { ...col, width, align };
4377
4382
  }
@@ -4820,17 +4825,18 @@ function Table(props) {
4820
4825
  const { width, minWidth, maxWidth, align } = col;
4821
4826
  const fixedStyle = isPinned ? getColumnFixedStyleRef.current(col) : void 0;
4822
4827
  const cellContent = col.render ? col.render(record[col.key], record, rowIdx) : String(record[col.key] ?? "");
4828
+ const isCheckbox = col.key === "__checkbox__";
4823
4829
  return /* @__PURE__ */ jsxRuntime.jsx(
4824
4830
  "td",
4825
4831
  {
4826
4832
  id: `${col.key}-body`,
4827
4833
  "data-row-cell": "true",
4828
4834
  "data-col-key": col.key,
4829
- className: "px-2 py-[6.8px] whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-200 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all",
4835
+ className: `${isCheckbox ? "p-0" : "px-2 py-[6.8px]"} whitespace-nowrap text-sm text-gray-900 border-r border-b border-gray-200 last:border-r-0 bg-inherit group-hover:bg-gray-100 transition-all`,
4830
4836
  style: {
4831
4837
  width,
4832
4838
  minWidth: minWidth || width,
4833
- maxWidth: maxWidth || width,
4839
+ maxWidth: isCheckbox ? maxWidth || width : void 0,
4834
4840
  ...fixedStyle
4835
4841
  },
4836
4842
  onClick: (event) => {
@@ -4926,7 +4932,7 @@ function Table(props) {
4926
4932
  ref: scrollRef,
4927
4933
  className: "relative w-full overflow-y-auto overflow-x-auto custom-view-scrollbar bg-white",
4928
4934
  style: { height: `${tableHeight}px` },
4929
- children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full table-layout", children: [
4935
+ children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full table-fixed", children: [
4930
4936
  /* @__PURE__ */ jsxRuntime.jsx(
4931
4937
  TableHeader,
4932
4938
  {
@@ -6026,6 +6032,7 @@ var FORM_CONTROL_CLASS = "h-8 w-full rounded border border-gray-300 bg-white px-
6026
6032
  function formControlClass(hasError, extra) {
6027
6033
  return cn2(FORM_CONTROL_CLASS, FORM_CONTROL_FOCUS_CLASS, hasError && FORM_FIELD_ERROR_BORDER_CLASS, extra);
6028
6034
  }
6035
+ var FIELD_READONLY_TEXT_CLASS = "text-sm text-gray-800 leading-tight";
6029
6036
  function fieldControlWrapClass(className) {
6030
6037
  return className ? cn2("min-w-0 shrink-0", className) : "min-w-0 w-full";
6031
6038
  }
@@ -6372,6 +6379,7 @@ function AddressField(props) {
6372
6379
  const {
6373
6380
  placeholder = "\uC8FC\uC18C\uB97C \uAC80\uC0C9\uD558\uC138\uC694",
6374
6381
  disabled = false,
6382
+ readOnly = false,
6375
6383
  className = "",
6376
6384
  addressDetailKey,
6377
6385
  addressClassNames
@@ -6386,6 +6394,9 @@ function AddressField(props) {
6386
6394
  searchButtonRef.current?.click();
6387
6395
  }
6388
6396
  }, [isFocused]);
6397
+ if (readOnly) {
6398
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
6399
+ }
6389
6400
  const handleComplete = (data) => {
6390
6401
  isAddressSelectedRef.current = true;
6391
6402
  const nextAddress = data.roadAddress || data.address;
@@ -6504,12 +6515,12 @@ function CascadingSelectField(props) {
6504
6515
  }
6505
6516
  function CascadingSelectFieldInner(props) {
6506
6517
  const {
6507
- field: { onChange, value },
6518
+ field: { onChange, onBlur, value },
6508
6519
  config,
6509
6520
  hasError = false,
6510
6521
  cascadingSelect
6511
6522
  } = props;
6512
- const { disabled = false, className = "", cascadingSelectClassNames } = config;
6523
+ const { disabled = false, readOnly = false, className = "", cascadingSelectClassNames } = config;
6513
6524
  const {
6514
6525
  primaryOptions,
6515
6526
  getSecondaryOptions,
@@ -6523,10 +6534,17 @@ function CascadingSelectFieldInner(props) {
6523
6534
  [formValue, getSecondaryOptions, separator]
6524
6535
  );
6525
6536
  React6.useLayoutEffect(() => {
6537
+ if (readOnly) return;
6526
6538
  if (normalizedFormValue !== formValue) {
6527
6539
  onChange(normalizedFormValue);
6528
6540
  }
6529
- }, [formValue, normalizedFormValue, onChange]);
6541
+ }, [formValue, normalizedFormValue, onChange, readOnly]);
6542
+ if (readOnly) {
6543
+ const primaryLabel = primaryOptions.find((o) => String(o.value) === primary)?.label ?? primary;
6544
+ const secondaryLabel = secondary ? secondaryOptions.find((o) => String(o.value) === secondary)?.label ?? secondary : "";
6545
+ const displayText = secondaryLabel ? `${primaryLabel} ${secondaryLabel}` : primaryLabel || "\u2014";
6546
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: displayText }) });
6547
+ }
6530
6548
  const updateValue = (nextPrimary, nextSecondary) => {
6531
6549
  onChange(createCascadingSelectValue(nextPrimary, nextSecondary, separator));
6532
6550
  };
@@ -6552,6 +6570,7 @@ function CascadingSelectFieldInner(props) {
6552
6570
  canReset: true,
6553
6571
  onChange: (nextPrimary) => {
6554
6572
  updateValue(nextPrimary, "");
6573
+ if (!nextPrimary) onBlur();
6555
6574
  }
6556
6575
  }
6557
6576
  ),
@@ -6568,6 +6587,7 @@ function CascadingSelectFieldInner(props) {
6568
6587
  canReset: true,
6569
6588
  onChange: (nextSecondary) => {
6570
6589
  updateValue(primary, nextSecondary);
6590
+ onBlur();
6571
6591
  }
6572
6592
  }
6573
6593
  )
@@ -6578,7 +6598,11 @@ function CheckboxField(props) {
6578
6598
  field: { onChange, value },
6579
6599
  config
6580
6600
  } = props;
6581
- const { disabled = false, checkboxLabel, className = "" } = config;
6601
+ const { disabled = false, readOnly = false, checkboxLabel, className = "" } = config;
6602
+ if (readOnly) {
6603
+ const text = value ? checkboxLabel ?? "\uC120\uD0DD\uB428" : "\u2014";
6604
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: text }) });
6605
+ }
6582
6606
  return /* @__PURE__ */ jsxRuntime.jsx(
6583
6607
  Checkbox,
6584
6608
  {
@@ -6599,11 +6623,15 @@ function DateField(props) {
6599
6623
  const {
6600
6624
  placeholder = "YYYY-MM-DD",
6601
6625
  disabled = false,
6626
+ readOnly = false,
6602
6627
  className = "w-40",
6603
6628
  datePosition = "bottom",
6604
6629
  disableFutureDates = false
6605
6630
  } = config;
6606
6631
  const maxDate = disableFutureDates ? formatDate(/* @__PURE__ */ new Date()) : void 0;
6632
+ if (readOnly) {
6633
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn2("flex items-center", fieldControlWrapClass(className)), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
6634
+ }
6607
6635
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn2("flex items-center", fieldControlWrapClass(className)), children: /* @__PURE__ */ jsxRuntime.jsx(
6608
6636
  DatePicker,
6609
6637
  {
@@ -6631,11 +6659,17 @@ function InputField(props) {
6631
6659
  readOnly = false,
6632
6660
  maxLength,
6633
6661
  className = "",
6634
- type = "input"
6662
+ type = "input",
6663
+ numbersOnly = false
6635
6664
  } = config;
6636
6665
  const inputType = type === "email" ? "email" : type === "password" ? "password" : "text";
6666
+ if (readOnly) {
6667
+ const text = type === "password" ? value ? "**********" : "" : String(value ?? "") || "";
6668
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: text }) });
6669
+ }
6637
6670
  const handleChange = (e) => {
6638
- onChange(e.target.value);
6671
+ const value2 = numbersOnly ? e.target.value.replace(/\D/g, "") : e.target.value;
6672
+ onChange(value2);
6639
6673
  };
6640
6674
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx(
6641
6675
  Input2,
@@ -6666,7 +6700,7 @@ function InputWithButtonField(props) {
6666
6700
  placeholder = "\uC870\uD68C \uBC84\uD2BC\uC73C\uB85C \uC120\uD0DD",
6667
6701
  disabled = false,
6668
6702
  className = "",
6669
- readOnly = true,
6703
+ readOnly = false,
6670
6704
  inputWithButton,
6671
6705
  onClickInputWithButton
6672
6706
  } = config;
@@ -6675,13 +6709,16 @@ function InputWithButtonField(props) {
6675
6709
  if (disabled) return;
6676
6710
  onClickInputWithButton?.();
6677
6711
  };
6712
+ if (readOnly) {
6713
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
6714
+ }
6678
6715
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full min-w-0 items-center gap-2", children: [
6679
6716
  /* @__PURE__ */ jsxRuntime.jsx(
6680
6717
  Input2,
6681
6718
  {
6682
6719
  placeholder,
6683
6720
  value: String(value ?? ""),
6684
- readOnly,
6721
+ readOnly: true,
6685
6722
  disabled,
6686
6723
  bare: true,
6687
6724
  className: formControlClass(hasError),
@@ -6721,6 +6758,9 @@ function NumberField(props) {
6721
6758
  }
6722
6759
  };
6723
6760
  const displayValue = value != null && value !== "" ? isMoney ? formatNumberWithCommas(value) : String(value) : "";
6761
+ if (readOnly) {
6762
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: displayValue || "\u2014" }) });
6763
+ }
6724
6764
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx(
6725
6765
  Input2,
6726
6766
  {
@@ -6750,6 +6790,9 @@ function PhoneField(props) {
6750
6790
  const handleChange = (e) => {
6751
6791
  onChange(formatPhoneNumber(e.target.value));
6752
6792
  };
6793
+ if (readOnly) {
6794
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: String(value ?? "") || "\u2014" }) });
6795
+ }
6753
6796
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx(
6754
6797
  Input2,
6755
6798
  {
@@ -6774,7 +6817,11 @@ function RadioField(props) {
6774
6817
  field: { onChange, value, name },
6775
6818
  config
6776
6819
  } = props;
6777
- const { disabled = false, options = [], className = "" } = config;
6820
+ const { disabled = false, readOnly = false, options = [], className = "" } = config;
6821
+ if (readOnly) {
6822
+ const label = options.find((o) => String(o.value) === String(value ?? ""))?.label ?? String(value ?? "");
6823
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: label || "\u2014" }) });
6824
+ }
6778
6825
  return /* @__PURE__ */ jsxRuntime.jsx(
6779
6826
  RadioGroup,
6780
6827
  {
@@ -6806,11 +6853,16 @@ function SelectField(props) {
6806
6853
  const {
6807
6854
  placeholder = "\uC120\uD0DD\uD558\uC138\uC694",
6808
6855
  disabled = false,
6856
+ readOnly = false,
6809
6857
  options = [],
6810
6858
  className = "",
6811
6859
  canReset = false
6812
6860
  } = config;
6813
6861
  const selectOptions = toSelectOptions2(options);
6862
+ if (readOnly) {
6863
+ const label = selectOptions.find((o) => o.value === String(value ?? ""))?.label ?? String(value ?? "");
6864
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: label || "\u2014" }) });
6865
+ }
6814
6866
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx(
6815
6867
  Select2,
6816
6868
  {
@@ -6857,16 +6909,6 @@ function combineSelectWithInputValue(prefix, input) {
6857
6909
  return `${prefix}${input}`;
6858
6910
  }
6859
6911
  var DEFAULT_SELECT_TRIGGER = "h-8 rounded border bg-white px-2 text-sm shadow-none min-w-[5rem]";
6860
- function resolveSelectWithInputState(formValue, defaultPrefix, options) {
6861
- const parsed = parseSelectWithInputValue(formValue, defaultPrefix);
6862
- const validPrefixes = new Set(options.map((opt) => String(opt.value)));
6863
- const prefix = validPrefixes.has(parsed.prefix) ? parsed.prefix : defaultPrefix;
6864
- return {
6865
- prefix,
6866
- inputPart: parsed.input,
6867
- normalizedFormValue: combineSelectWithInputValue(prefix, parsed.input)
6868
- };
6869
- }
6870
6912
  function SelectWithInputField(props) {
6871
6913
  const {
6872
6914
  field: { onChange, onBlur, value },
@@ -6875,37 +6917,58 @@ function SelectWithInputField(props) {
6875
6917
  } = props;
6876
6918
  const {
6877
6919
  disabled = false,
6920
+ readOnly = false,
6878
6921
  options = [],
6879
6922
  maxLength,
6880
6923
  className = "",
6881
6924
  selectWithInput,
6882
6925
  selectWithInputClassNames
6883
6926
  } = config;
6884
- const inputMode = selectWithInput?.inputMode ?? "number";
6927
+ const validationCtx = useSubmitFormValidation();
6928
+ const numbersOnly = selectWithInput?.numbersOnly ?? selectWithInput?.inputMode !== "text";
6885
6929
  const defaultPrefix = String(options[0]?.value ?? "");
6886
6930
  const numberInputRef = React6.useRef(null);
6887
6931
  const formValue = String(value ?? "");
6888
- const { prefix, inputPart, normalizedFormValue } = React6.useMemo(
6889
- () => resolveSelectWithInputState(formValue, defaultPrefix, options),
6890
- [defaultPrefix, formValue, options]
6891
- );
6932
+ const { prefix, inputPart, normalizedFormValue } = React6.useMemo(() => {
6933
+ const parsed = parseSelectWithInputValue(formValue, defaultPrefix);
6934
+ const validPrefixes = new Set(options.map((opt) => String(opt.value)));
6935
+ const resolvedPrefix = validPrefixes.has(parsed.prefix) ? parsed.prefix : defaultPrefix;
6936
+ return {
6937
+ prefix: resolvedPrefix,
6938
+ inputPart: parsed.input,
6939
+ normalizedFormValue: combineSelectWithInputValue(resolvedPrefix, parsed.input)
6940
+ };
6941
+ }, [defaultPrefix, formValue, options]);
6942
+ const [selectedPrefix, setSelectedPrefix] = React6.useState(prefix);
6943
+ const [prevFormValue, setPrevFormValue] = React6.useState(formValue);
6944
+ if (prevFormValue !== formValue) {
6945
+ setPrevFormValue(formValue);
6946
+ setSelectedPrefix(formValue ? prefix : defaultPrefix);
6947
+ }
6892
6948
  React6.useLayoutEffect(() => {
6893
- if (normalizedFormValue !== formValue) {
6949
+ if (readOnly) return;
6950
+ if (formValue && normalizedFormValue !== formValue) {
6894
6951
  onChange(normalizedFormValue);
6895
6952
  }
6896
- }, [formValue, normalizedFormValue, onChange]);
6953
+ }, [formValue, normalizedFormValue, onChange, readOnly]);
6954
+ if (readOnly) {
6955
+ const prefixLabel = options.find((o) => String(o.value) === prefix)?.label ?? prefix;
6956
+ const displayText = inputPart ? `${prefixLabel} ${inputPart}` : prefix ? prefixLabel : "\u2014";
6957
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: displayText || "\u2014" }) });
6958
+ }
6897
6959
  const updateCombined = (nextPrefix, nextInput) => {
6898
6960
  onChange(combineSelectWithInputValue(nextPrefix, nextInput));
6899
6961
  };
6900
6962
  const normalizeInput = (raw) => {
6901
- if (inputMode === "number") {
6902
- return raw.replace(/\D+/g, "");
6903
- }
6963
+ if (numbersOnly) return raw.replace(/\D+/g, "");
6904
6964
  return raw;
6905
6965
  };
6906
6966
  const handleInputChange = (raw) => {
6907
6967
  const normalized = normalizeInput(raw.normalize("NFKC"));
6908
- updateCombined(prefix, normalized);
6968
+ if (normalized) {
6969
+ validationCtx?.markFieldHadValue(String(config.name));
6970
+ }
6971
+ updateCombined(selectedPrefix, normalized);
6909
6972
  };
6910
6973
  const selectClass = resolveSelectClassNameProp(selectWithInputClassNames?.selectClassName, {
6911
6974
  containerClassName: "shrink-0",
@@ -6915,7 +6978,7 @@ function SelectWithInputField(props) {
6915
6978
  /* @__PURE__ */ jsxRuntime.jsx(
6916
6979
  Select2,
6917
6980
  {
6918
- value: prefix,
6981
+ value: selectedPrefix,
6919
6982
  placeholder: "\uC120\uD0DD",
6920
6983
  disabled,
6921
6984
  hasError,
@@ -6923,6 +6986,7 @@ function SelectWithInputField(props) {
6923
6986
  containerClass: selectClass.containerClassName,
6924
6987
  triggerClassName: selectClass.triggerClassName,
6925
6988
  onChange: (nextPrefix) => {
6989
+ setSelectedPrefix(nextPrefix);
6926
6990
  updateCombined(nextPrefix, inputPart);
6927
6991
  }
6928
6992
  }
@@ -6941,7 +7005,7 @@ function SelectWithInputField(props) {
6941
7005
  },
6942
7006
  onBlur: (e) => {
6943
7007
  const normalized = normalizeInput(e.target.value.normalize("NFKC"));
6944
- handleInputChange(normalized);
7008
+ updateCombined(selectedPrefix, normalized);
6945
7009
  onBlur();
6946
7010
  }
6947
7011
  }
@@ -6953,7 +7017,10 @@ function SwitchField(props) {
6953
7017
  field: { onChange, value },
6954
7018
  config
6955
7019
  } = props;
6956
- const { disabled = false, className = "" } = config;
7020
+ const { disabled = false, readOnly = false, className = "" } = config;
7021
+ if (readOnly) {
7022
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: FIELD_READONLY_TEXT_CLASS, children: value ? "\uCF1C\uC9D0" : "\uAEBC\uC9D0" }) });
7023
+ }
6957
7024
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx(BaseSwitch, { checked: Boolean(value), onCheckedChange: onChange, disabled }) });
6958
7025
  }
6959
7026
  function TextareaField(props) {
@@ -6966,6 +7033,9 @@ function TextareaField(props) {
6966
7033
  const handleChange = (e) => {
6967
7034
  onChange(e.target.value);
6968
7035
  };
7036
+ if (readOnly) {
7037
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn2(FIELD_READONLY_TEXT_CLASS, "whitespace-pre-wrap"), children: String(value ?? "") || "\u2014" }) });
7038
+ }
6969
7039
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: fieldControlWrapClass(className), children: /* @__PURE__ */ jsxRuntime.jsx(
6970
7040
  Textarea,
6971
7041
  {
@@ -7211,6 +7281,7 @@ function rowPropsToFieldConfig(props) {
7211
7281
  options,
7212
7282
  className,
7213
7283
  allowDecimal,
7284
+ numbersOnly,
7214
7285
  canReset,
7215
7286
  datePosition,
7216
7287
  disableFutureDates,
@@ -7240,6 +7311,7 @@ function rowPropsToFieldConfig(props) {
7240
7311
  options,
7241
7312
  className,
7242
7313
  allowDecimal,
7314
+ numbersOnly,
7243
7315
  canReset,
7244
7316
  datePosition,
7245
7317
  disableFutureDates,