sellmate-design-system-react 0.1.3 → 0.1.5

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.
Files changed (165) hide show
  1. package/dist/components/SActionModal/SActionModal.cjs +129 -1
  2. package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
  3. package/dist/components/SActionModal/SActionModal.js +129 -1
  4. package/dist/components/SActionModal/SActionModal.js.map +1 -1
  5. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +157 -4
  6. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  7. package/dist/components/SBarcodeInput/SBarcodeInput.js +158 -5
  8. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  9. package/dist/components/SButton/SButton.cjs +129 -1
  10. package/dist/components/SButton/SButton.cjs.map +1 -1
  11. package/dist/components/SButton/SButton.js +129 -1
  12. package/dist/components/SButton/SButton.js.map +1 -1
  13. package/dist/components/SCalendar/SCalendar.cjs +131 -3
  14. package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
  15. package/dist/components/SCalendar/SCalendar.d.ts +3 -1
  16. package/dist/components/SCalendar/SCalendar.js +131 -3
  17. package/dist/components/SCalendar/SCalendar.js.map +1 -1
  18. package/dist/components/SCallout/SCallout.cjs +129 -1
  19. package/dist/components/SCallout/SCallout.cjs.map +1 -1
  20. package/dist/components/SCallout/SCallout.js +129 -1
  21. package/dist/components/SCallout/SCallout.js.map +1 -1
  22. package/dist/components/SCheckbox/SCheckbox.cjs +130 -2
  23. package/dist/components/SCheckbox/SCheckbox.cjs.map +1 -1
  24. package/dist/components/SCheckbox/SCheckbox.js +130 -2
  25. package/dist/components/SCheckbox/SCheckbox.js.map +1 -1
  26. package/dist/components/SChip/SChip.cjs +130 -3
  27. package/dist/components/SChip/SChip.cjs.map +1 -1
  28. package/dist/components/SChip/SChip.js +130 -3
  29. package/dist/components/SChip/SChip.js.map +1 -1
  30. package/dist/components/SChipInput/SChipInput.cjs +154 -4
  31. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  32. package/dist/components/SChipInput/SChipInput.js +154 -4
  33. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  34. package/dist/components/SConfirmModal/SConfirmModal.cjs +129 -1
  35. package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
  36. package/dist/components/SConfirmModal/SConfirmModal.js +129 -1
  37. package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
  38. package/dist/components/SDatePicker/SDatePicker.cjs +159 -6
  39. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  40. package/dist/components/SDatePicker/SDatePicker.js +159 -6
  41. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  42. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +157 -4
  43. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  44. package/dist/components/SDateRangePicker/SDateRangePicker.js +157 -4
  45. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  46. package/dist/components/SDropdownButton/SDropdownButton.cjs +129 -1
  47. package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
  48. package/dist/components/SDropdownButton/SDropdownButton.js +129 -1
  49. package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
  50. package/dist/components/SField/SField.cjs +130 -2
  51. package/dist/components/SField/SField.cjs.map +1 -1
  52. package/dist/components/SField/SField.js +130 -2
  53. package/dist/components/SField/SField.js.map +1 -1
  54. package/dist/components/SFilePicker/SFilePicker.cjs +157 -4
  55. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  56. package/dist/components/SFilePicker/SFilePicker.js +157 -4
  57. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  58. package/dist/components/SForm/SForm.cjs +91 -0
  59. package/dist/components/SForm/SForm.cjs.map +1 -0
  60. package/dist/components/SForm/SForm.d.ts +33 -0
  61. package/dist/components/SForm/SForm.js +89 -0
  62. package/dist/components/SForm/SForm.js.map +1 -0
  63. package/dist/components/SForm/index.d.ts +1 -0
  64. package/dist/components/SGhostButton/SGhostButton.cjs +129 -1
  65. package/dist/components/SGhostButton/SGhostButton.cjs.map +1 -1
  66. package/dist/components/SGhostButton/SGhostButton.js +129 -1
  67. package/dist/components/SGhostButton/SGhostButton.js.map +1 -1
  68. package/dist/components/SGuide/SGuide.cjs +129 -1
  69. package/dist/components/SGuide/SGuide.cjs.map +1 -1
  70. package/dist/components/SGuide/SGuide.js +129 -1
  71. package/dist/components/SGuide/SGuide.js.map +1 -1
  72. package/dist/components/SIcon/SIcon.cjs +129 -1
  73. package/dist/components/SIcon/SIcon.cjs.map +1 -1
  74. package/dist/components/SIcon/SIcon.d.ts +3 -2
  75. package/dist/components/SIcon/SIcon.js +129 -1
  76. package/dist/components/SIcon/SIcon.js.map +1 -1
  77. package/dist/components/SInput/SInput.cjs +157 -4
  78. package/dist/components/SInput/SInput.cjs.map +1 -1
  79. package/dist/components/SInput/SInput.js +158 -5
  80. package/dist/components/SInput/SInput.js.map +1 -1
  81. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +214 -7
  82. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  83. package/dist/components/SKeyValueTable/SKeyValueTable.js +214 -7
  84. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  85. package/dist/components/SLoadingModal/SLoadingModal.cjs +129 -1
  86. package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
  87. package/dist/components/SLoadingModal/SLoadingModal.js +129 -1
  88. package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
  89. package/dist/components/SModalContainer/SModalContainer.cjs +129 -1
  90. package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
  91. package/dist/components/SModalContainer/SModalContainer.js +129 -1
  92. package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
  93. package/dist/components/SNumberInput/SNumberInput.cjs +157 -4
  94. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  95. package/dist/components/SNumberInput/SNumberInput.js +157 -4
  96. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  97. package/dist/components/SPagination/SPagination.cjs +129 -1
  98. package/dist/components/SPagination/SPagination.cjs.map +1 -1
  99. package/dist/components/SPagination/SPagination.js +129 -1
  100. package/dist/components/SPagination/SPagination.js.map +1 -1
  101. package/dist/components/SPopover/SPopover.cjs +129 -1
  102. package/dist/components/SPopover/SPopover.cjs.map +1 -1
  103. package/dist/components/SPopover/SPopover.d.ts +3 -1
  104. package/dist/components/SPopover/SPopover.js +129 -1
  105. package/dist/components/SPopover/SPopover.js.map +1 -1
  106. package/dist/components/SPopup/SPopup.cjs +129 -1
  107. package/dist/components/SPopup/SPopup.cjs.map +1 -1
  108. package/dist/components/SPopup/SPopup.js +129 -1
  109. package/dist/components/SPopup/SPopup.js.map +1 -1
  110. package/dist/components/SSelect/SSelect.cjs +157 -4
  111. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  112. package/dist/components/SSelect/SSelect.js +158 -5
  113. package/dist/components/SSelect/SSelect.js.map +1 -1
  114. package/dist/components/STable/STable.cjs +161 -6
  115. package/dist/components/STable/STable.cjs.map +1 -1
  116. package/dist/components/STable/STable.d.ts +3 -1
  117. package/dist/components/STable/STable.js +161 -6
  118. package/dist/components/STable/STable.js.map +1 -1
  119. package/dist/components/STabs/STabs.cjs +129 -1
  120. package/dist/components/STabs/STabs.cjs.map +1 -1
  121. package/dist/components/STabs/STabs.js +129 -1
  122. package/dist/components/STabs/STabs.js.map +1 -1
  123. package/dist/components/STag/STag.cjs +129 -1
  124. package/dist/components/STag/STag.cjs.map +1 -1
  125. package/dist/components/STag/STag.js +129 -1
  126. package/dist/components/STag/STag.js.map +1 -1
  127. package/dist/components/STextLink/STextLink.cjs +129 -1
  128. package/dist/components/STextLink/STextLink.cjs.map +1 -1
  129. package/dist/components/STextLink/STextLink.d.ts +3 -2
  130. package/dist/components/STextLink/STextLink.js +129 -1
  131. package/dist/components/STextLink/STextLink.js.map +1 -1
  132. package/dist/components/STextarea/STextarea.cjs +157 -4
  133. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  134. package/dist/components/STextarea/STextarea.js +158 -5
  135. package/dist/components/STextarea/STextarea.js.map +1 -1
  136. package/dist/components/SToast/SToast.cjs +129 -1
  137. package/dist/components/SToast/SToast.cjs.map +1 -1
  138. package/dist/components/SToast/SToast.js +129 -1
  139. package/dist/components/SToast/SToast.js.map +1 -1
  140. package/dist/components/SToast/SToastContainer.cjs +129 -1
  141. package/dist/components/SToast/SToastContainer.cjs.map +1 -1
  142. package/dist/components/SToast/SToastContainer.js +129 -1
  143. package/dist/components/SToast/SToastContainer.js.map +1 -1
  144. package/dist/components/STooltip/STooltip.cjs +130 -2
  145. package/dist/components/STooltip/STooltip.cjs.map +1 -1
  146. package/dist/components/STooltip/STooltip.d.ts +3 -1
  147. package/dist/components/STooltip/STooltip.js +130 -2
  148. package/dist/components/STooltip/STooltip.js.map +1 -1
  149. package/dist/index.cjs +311 -8
  150. package/dist/index.cjs.map +1 -1
  151. package/dist/index.d.ts +2 -0
  152. package/dist/index.js +308 -9
  153. package/dist/index.js.map +1 -1
  154. package/dist/lib/color.cjs +135 -0
  155. package/dist/lib/color.cjs.map +1 -0
  156. package/dist/lib/color.d.ts +28 -0
  157. package/dist/lib/color.js +131 -0
  158. package/dist/lib/color.js.map +1 -0
  159. package/dist/lib/form.cjs +23 -0
  160. package/dist/lib/form.cjs.map +1 -1
  161. package/dist/lib/form.d.ts +25 -0
  162. package/dist/lib/form.js +21 -1
  163. package/dist/lib/form.js.map +1 -1
  164. package/dist/styles.css +35 -3
  165. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -44,6 +44,134 @@ var Ariakit__namespace = /*#__PURE__*/_interopNamespace(Ariakit);
44
44
  function cn(...inputs) {
45
45
  return tailwindMerge.twMerge(clsx.clsx(inputs));
46
46
  }
47
+
48
+ // src/lib/color.ts
49
+ var COLOR_KEYS = [
50
+ "white",
51
+ "black",
52
+ "grey_10",
53
+ "grey_20",
54
+ "grey_25",
55
+ "grey_30",
56
+ "grey_35",
57
+ "grey_45",
58
+ "grey_50",
59
+ "grey_55",
60
+ "grey_60",
61
+ "grey_65",
62
+ "grey_70",
63
+ "grey_80",
64
+ "grey_85",
65
+ "grey_90",
66
+ "grey_95",
67
+ "grey_05",
68
+ "red_15",
69
+ "red_20",
70
+ "red_30",
71
+ "red_45",
72
+ "red_60",
73
+ "red_70",
74
+ "red_75",
75
+ "red_80",
76
+ "red_85",
77
+ "red_90",
78
+ "red_95",
79
+ "red_99",
80
+ "orange_10",
81
+ "orange_20",
82
+ "orange_35",
83
+ "orange_45",
84
+ "orange_55",
85
+ "orange_60",
86
+ "orange_65",
87
+ "orange_75",
88
+ "orange_85",
89
+ "orange_90",
90
+ "orange_95",
91
+ "orange_99",
92
+ "yellow_10",
93
+ "yellow_20",
94
+ "yellow_25",
95
+ "yellow_30",
96
+ "yellow_40",
97
+ "yellow_45",
98
+ "yellow_50",
99
+ "yellow_60",
100
+ "yellow_70",
101
+ "yellow_80",
102
+ "yellow_90",
103
+ "yellow_95",
104
+ "olive_10",
105
+ "olive_15",
106
+ "olive_20",
107
+ "olive_30",
108
+ "olive_45",
109
+ "olive_55",
110
+ "olive_65",
111
+ "olive_70",
112
+ "olive_80",
113
+ "olive_90",
114
+ "olive_95",
115
+ "olive_05",
116
+ "green_15",
117
+ "green_25",
118
+ "green_45",
119
+ "green_55",
120
+ "green_65",
121
+ "green_70",
122
+ "green_75",
123
+ "green_80",
124
+ "green_85",
125
+ "green_90",
126
+ "green_95",
127
+ "green_99",
128
+ "steelblue_10",
129
+ "steelblue_25",
130
+ "steelblue_45",
131
+ "steelblue_60",
132
+ "steelblue_65",
133
+ "steelblue_70",
134
+ "steelblue_75",
135
+ "steelblue_80",
136
+ "steelblue_85",
137
+ "steelblue_90",
138
+ "steelblue_95",
139
+ "steelblue_99",
140
+ "oceanblue_15",
141
+ "oceanblue_25",
142
+ "oceanblue_50",
143
+ "oceanblue_60",
144
+ "oceanblue_65",
145
+ "oceanblue_70",
146
+ "oceanblue_75",
147
+ "oceanblue_80",
148
+ "oceanblue_85",
149
+ "oceanblue_90",
150
+ "oceanblue_95",
151
+ "oceanblue_99",
152
+ "brilliantblue_10",
153
+ "brilliantblue_20",
154
+ "brilliantblue_25",
155
+ "brilliantblue_40",
156
+ "brilliantblue_50",
157
+ "brilliantblue_60",
158
+ "brilliantblue_70",
159
+ "brilliantblue_75",
160
+ "brilliantblue_80",
161
+ "brilliantblue_85",
162
+ "brilliantblue_90",
163
+ "brilliantblue_95",
164
+ "brilliantblue_99",
165
+ "brilliantblue_05"
166
+ ];
167
+ var KEY_SET = new Set(COLOR_KEYS);
168
+ function isColorKey(input) {
169
+ return KEY_SET.has(input);
170
+ }
171
+ function resolveColor(input, fallback) {
172
+ if (input === null || input === void 0 || input === "") return fallback;
173
+ return isColorKey(input) ? `var(--color-${input.replace(/_/g, "-")})` : input;
174
+ }
47
175
  var Icon_add = (p) => {
48
176
  const { size = 24, ...rest } = p;
49
177
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2743,7 +2871,7 @@ var SIcon = react.forwardRef(function SIcon2({ name, size = 24, color, rotate, l
2743
2871
  {
2744
2872
  ref,
2745
2873
  className: cn("inline-flex items-center justify-center", rotateClass, className),
2746
- style: { color, ...style },
2874
+ style: { color: resolveColor(color), ...style },
2747
2875
  role: label ? "img" : void 0,
2748
2876
  "aria-label": label,
2749
2877
  "aria-hidden": label ? void 0 : true,
@@ -3788,7 +3916,7 @@ var HIDE_DELAY_MS = 100;
3788
3916
  function useBody(content, message = []) {
3789
3917
  if (content != null) return content;
3790
3918
  if (message.length === 0) return null;
3791
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[12px]", children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: line }, i)) });
3919
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: message.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: line }, i)) });
3792
3920
  }
3793
3921
  var STooltip = react.forwardRef(function STooltip2({
3794
3922
  content,
@@ -4752,7 +4880,7 @@ function SCheckbox({
4752
4880
  onValueChange(false);
4753
4881
  }
4754
4882
  };
4755
- const boxBg = disabled ? "var(--cmp-checkbox-bg-disabled)" : isChecked && !inverse ? "var(--cmp-checkbox-checked-bg-default)" : "transparent";
4883
+ const boxBg = disabled ? "var(--cmp-checkbox-bg-disabled)" : inverse ? "transparent" : isChecked ? "var(--cmp-checkbox-checked-bg-default)" : "var(--cmp-checkbox-unchecked-bg-default)";
4756
4884
  const boxBorder = disabled ? "var(--cmp-checkbox-border-disabled)" : inverse ? "var(--cmp-checkbox-checked-border-inverse)" : isChecked ? "var(--cmp-checkbox-checked-bg-default)" : "var(--cmp-checkbox-unchecked-border-default)";
4757
4885
  const iconColor = disabled ? "var(--cmp-checkbox-checked-icon-disabled)" : "var(--cmp-checkbox-checked-icon-default)";
4758
4886
  const labelColor = disabled ? "var(--cmp-checkbox-label-disabled)" : inverse ? "var(--cmp-checkbox-label-inverse)" : "var(--cmp-checkbox-label-default)";
@@ -4797,8 +4925,6 @@ function SCheckbox({
4797
4925
  }
4798
4926
  );
4799
4927
  }
4800
-
4801
- // src/lib/form.ts
4802
4928
  function runRules(value, rules) {
4803
4929
  if (!rules || rules.length === 0) return "";
4804
4930
  for (const rule of rules) {
@@ -4807,6 +4933,24 @@ function runRules(value, rules) {
4807
4933
  }
4808
4934
  return "";
4809
4935
  }
4936
+ var FormContext = react.createContext(null);
4937
+ function useFormContext() {
4938
+ return react.useContext(FormContext);
4939
+ }
4940
+ function useFormField(field) {
4941
+ const ctx = useFormContext();
4942
+ const cbRef = react.useRef(field);
4943
+ cbRef.current = field;
4944
+ const name = field.name ?? "";
4945
+ react.useEffect(() => {
4946
+ if (!ctx) return;
4947
+ return ctx.register({
4948
+ name,
4949
+ validate: () => cbRef.current.validate(),
4950
+ resetValidation: () => cbRef.current.resetValidation()
4951
+ });
4952
+ }, [ctx, name]);
4953
+ }
4810
4954
  var FIELD_SIZE = {
4811
4955
  sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 12 },
4812
4956
  md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 12 }
@@ -5099,6 +5243,15 @@ var SSelect = react.forwardRef(function SSelect2({
5099
5243
  const arr = Array.isArray(value) ? value : [value];
5100
5244
  return arr.map((v) => v != null && typeof v === "object" ? v.value : v).filter((v) => v != null && v !== "").map(String);
5101
5245
  }, [value]);
5246
+ useFormField({
5247
+ name,
5248
+ validate: () => {
5249
+ const msg = runRules(multi ? selected : selected[0] ?? "", rules);
5250
+ setRuleError(msg);
5251
+ return msg === "";
5252
+ },
5253
+ resetValidation: () => setRuleError("")
5254
+ });
5102
5255
  const emit2 = (next) => {
5103
5256
  if (!onValueChange) return;
5104
5257
  const mapped = next.map(
@@ -5773,8 +5926,10 @@ var STable = react.forwardRef(function STable2({
5773
5926
  {
5774
5927
  className: cn(
5775
5928
  // 원본 .td: 컬럼 폭에 맞춰 내용 말줄임(overflow hidden + ellipsis) + 행 구분선(border-b)
5929
+ // 셀 배경은 흰색으로 채워 뒤 배경이 비치지 않게 하고, hover 시 행 배경(grey_05)을 따른다.
5776
5930
  "overflow-hidden text-ellipsis whitespace-nowrap border-b border-solid border-[color:var(--cmp-table-border-color)] px-[16px] text-[12px] leading-[20px] text-[color:var(--sys-color-fg-primary)]",
5777
- stickyInfo(i).isSticky && cn(rowBg, "group-hover:bg-[var(--color-grey-05)]"),
5931
+ rowBg,
5932
+ "group-hover:bg-[var(--color-grey-05)]",
5778
5933
  stickyShadowClass(i),
5779
5934
  col.tdClass
5780
5935
  ),
@@ -5873,6 +6028,15 @@ var SInput = react.forwardRef(function SInput2({
5873
6028
  const isPassword = type === "password";
5874
6029
  const inputType = isPassword ? visible ? "text" : "password" : type;
5875
6030
  const hasValue = value !== void 0 && value !== null && String(value) !== "";
6031
+ useFormField({
6032
+ name: rest.name,
6033
+ validate: () => {
6034
+ const msg = runRules(value, rules);
6035
+ setRuleError(msg);
6036
+ return msg === "";
6037
+ },
6038
+ resetValidation: () => setRuleError("")
6039
+ });
5876
6040
  const resolvedError = error || ruleError !== "";
5877
6041
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
5878
6042
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
@@ -6003,6 +6167,15 @@ var STextarea = react.forwardRef(function STextarea2({
6003
6167
  }, ref) {
6004
6168
  const p = PAD;
6005
6169
  const [ruleError, setRuleError] = react.useState("");
6170
+ useFormField({
6171
+ name: rest.name,
6172
+ validate: () => {
6173
+ const msg = runRules(value, rules);
6174
+ setRuleError(msg);
6175
+ return msg === "";
6176
+ },
6177
+ resetValidation: () => setRuleError("")
6178
+ });
6006
6179
  const resolvedError = error || ruleError !== "";
6007
6180
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
6008
6181
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
@@ -6136,6 +6309,15 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
6136
6309
  react.useEffect(() => {
6137
6310
  setDisplay(formatWithCommas(toNumber(value)));
6138
6311
  }, [value]);
6312
+ useFormField({
6313
+ name,
6314
+ validate: () => {
6315
+ const msg = runRules(numValue, rules);
6316
+ setRuleError(msg);
6317
+ return msg === "";
6318
+ },
6319
+ resetValidation: () => setRuleError("")
6320
+ });
6139
6321
  const resolvedError = error || ruleError !== "";
6140
6322
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6141
6323
  const emit2 = (n) => {
@@ -6631,7 +6813,7 @@ function SCalendar({
6631
6813
  "span",
6632
6814
  {
6633
6815
  className: "h-[var(--cmp-datepicker-calendar-day-dot-size)] w-[var(--cmp-datepicker-calendar-day-dot-size)] rounded-full",
6634
- style: { backgroundColor: ev.color }
6816
+ style: { backgroundColor: resolveColor(ev.color) }
6635
6817
  },
6636
6818
  i
6637
6819
  ))
@@ -6659,7 +6841,7 @@ function SCalendar({
6659
6841
  "span",
6660
6842
  {
6661
6843
  className: "h-[var(--cmp-datepicker-calendar-day-dot-size)] w-[var(--cmp-datepicker-calendar-day-dot-size)] rounded-full",
6662
- style: { backgroundColor: item.color },
6844
+ style: { backgroundColor: resolveColor(item.color) },
6663
6845
  "aria-hidden": true
6664
6846
  }
6665
6847
  ),
@@ -6703,6 +6885,15 @@ function SDatePicker({
6703
6885
  const [focused, setFocused] = react.useState(false);
6704
6886
  const [ruleError, setRuleError] = react.useState("");
6705
6887
  const hasValue = value != null && value !== "";
6888
+ useFormField({
6889
+ name,
6890
+ validate: () => {
6891
+ const msg = runRules(value, rules);
6892
+ setRuleError(msg);
6893
+ return msg === "";
6894
+ },
6895
+ resetValidation: () => setRuleError("")
6896
+ });
6706
6897
  const resolvedError = error || ruleError !== "";
6707
6898
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6708
6899
  const dims = size === "md" ? { padX: 16, gap: 12, icon: 20, minW: 104, fontSize: 14, lineHeight: 24, radius: 6 } : { padX: 12, gap: 8, icon: 16, minW: 80, fontSize: 12, lineHeight: 20, radius: 4 };
@@ -6988,6 +7179,15 @@ function SDateRangePicker({
6988
7179
  const [ruleError, setRuleError] = react.useState("");
6989
7180
  const hasValue = value != null && value[0] !== "" && value[1] !== "";
6990
7181
  const display = hasValue ? `${value[0]} ~ ${value[1]}` : placeholder;
7182
+ useFormField({
7183
+ name,
7184
+ validate: () => {
7185
+ const msg = runRules(value, rules);
7186
+ setRuleError(msg);
7187
+ return msg === "";
7188
+ },
7189
+ resetValidation: () => setRuleError("")
7190
+ });
6991
7191
  const resolvedError = error || ruleError !== "";
6992
7192
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6993
7193
  const dims = size === "md" ? { padX: 16, gap: 12, icon: 20, minW: 104, fontSize: 14, lineHeight: 24, radius: 6 } : { padX: 12, gap: 8, icon: 16, minW: 80, fontSize: 12, lineHeight: 20, radius: 4 };
@@ -7252,6 +7452,15 @@ function SFilePicker({
7252
7452
  const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
7253
7453
  const hasSingle = !multiple && !!files;
7254
7454
  const displayText = hasSingle ? files.name : placeholder;
7455
+ useFormField({
7456
+ name,
7457
+ validate: () => {
7458
+ const msg = runRules(files, rules);
7459
+ setRuleError(msg);
7460
+ return msg === "";
7461
+ },
7462
+ resetValidation: () => setRuleError("")
7463
+ });
7255
7464
  const validate = (arr, existing = 0) => {
7256
7465
  const mfs = toBytes(maxFileSize), mts = toBytes(maxTotalSize), mf = maxFiles != null ? Number(maxFiles) : void 0;
7257
7466
  if (mf != null && existing + arr.length > mf)
@@ -7848,6 +8057,81 @@ var SToastContainer = react.forwardRef(
7848
8057
  );
7849
8058
  }
7850
8059
  );
8060
+ var SForm = react.forwardRef(function SForm2({ formClass, onSubmit, onValidationError, children, className, style }, ref) {
8061
+ const formRef = react.useRef(null);
8062
+ const fieldsRef = react.useRef(/* @__PURE__ */ new Set());
8063
+ const register = react.useCallback((entry) => {
8064
+ fieldsRef.current.add(entry);
8065
+ return () => {
8066
+ fieldsRef.current.delete(entry);
8067
+ };
8068
+ }, []);
8069
+ const ctx = react.useMemo(() => ({ register }), [register]);
8070
+ const orderByDom = react.useCallback((names) => {
8071
+ const form = formRef.current;
8072
+ if (!form || names.length < 2) return names;
8073
+ const domOrder = /* @__PURE__ */ new Map();
8074
+ form.querySelectorAll("[name],[data-name]").forEach((el, i) => {
8075
+ const n = el.getAttribute("name") || el.getAttribute("data-name");
8076
+ if (n && !domOrder.has(n)) domOrder.set(n, i);
8077
+ });
8078
+ return [...names].sort((a, b) => (domOrder.get(a) ?? Infinity) - (domOrder.get(b) ?? Infinity));
8079
+ }, []);
8080
+ const focusByName = react.useCallback((name) => {
8081
+ const form = formRef.current;
8082
+ if (!form || !name) return;
8083
+ const host = form.querySelector(`[name="${CSS.escape(name)}"]`) ?? form.querySelector(`[data-name="${CSS.escape(name)}"]`);
8084
+ if (!host) return;
8085
+ const focusable = host.matches("input,textarea,select,button,[tabindex]") ? host : host.querySelector("input,textarea,select,button,[tabindex]");
8086
+ focusable?.focus();
8087
+ (focusable ?? host).scrollIntoView({ block: "nearest" });
8088
+ }, []);
8089
+ const runValidation = react.useCallback(() => {
8090
+ let valid = true;
8091
+ const invalidNames = [];
8092
+ fieldsRef.current.forEach((f) => {
8093
+ if (!f.validate()) {
8094
+ valid = false;
8095
+ if (f.name) invalidNames.push(f.name);
8096
+ }
8097
+ });
8098
+ return { valid, names: orderByDom(invalidNames) };
8099
+ }, [orderByDom]);
8100
+ react.useImperativeHandle(
8101
+ ref,
8102
+ () => ({
8103
+ validate: () => runValidation().valid,
8104
+ resetValidation: () => fieldsRef.current.forEach((f) => f.resetValidation()),
8105
+ reset: () => fieldsRef.current.forEach((f) => f.resetValidation()),
8106
+ focusFirstInvalid: () => {
8107
+ const { names } = runValidation();
8108
+ if (names.length > 0) focusByName(names[0]);
8109
+ }
8110
+ }),
8111
+ [runValidation, focusByName]
8112
+ );
8113
+ const handleSubmit = (e) => {
8114
+ e.preventDefault();
8115
+ const { valid, names } = runValidation();
8116
+ if (!valid) {
8117
+ if (names.length > 0) focusByName(names[0]);
8118
+ onValidationError?.({ names });
8119
+ return;
8120
+ }
8121
+ onSubmit?.();
8122
+ };
8123
+ return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
8124
+ "form",
8125
+ {
8126
+ ref: formRef,
8127
+ onSubmit: handleSubmit,
8128
+ className: cn(formClass, className),
8129
+ style,
8130
+ noValidate: true,
8131
+ children
8132
+ }
8133
+ ) });
8134
+ });
7851
8135
  function SRadioButton({
7852
8136
  options = [],
7853
8137
  value,
@@ -7963,6 +8247,12 @@ function SChipInput({
7963
8247
  const resolvedErrorMessage = duplicateMessage || ruleMessage || errorMessage;
7964
8248
  const resolvedError = error || duplicateMessage !== "" || ruleMessage !== "";
7965
8249
  const resolvedStatus = status ?? (resolvedError ? "error" : void 0);
8250
+ useFormField({
8251
+ name,
8252
+ validate: () => runRules(values, rules) === "" && duplicateMessage === "",
8253
+ resetValidation: () => {
8254
+ }
8255
+ });
7966
8256
  const isMax = maxCount != null && values.length >= maxCount;
7967
8257
  const commit = (next) => onValueChange?.(next);
7968
8258
  const addChip = (v) => {
@@ -8235,6 +8525,15 @@ var SBarcodeInput = react.forwardRef(
8235
8525
  const f = FONT2[size];
8236
8526
  const [ruleError, setRuleError] = react.useState("");
8237
8527
  const hasValue = value !== void 0 && value !== null && String(value) !== "";
8528
+ useFormField({
8529
+ name,
8530
+ validate: () => {
8531
+ const msg = runRules(value, rules);
8532
+ setRuleError(msg);
8533
+ return msg === "";
8534
+ },
8535
+ resetValidation: () => setRuleError("")
8536
+ });
8238
8537
  const resolvedError = error || ruleError !== "";
8239
8538
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
8240
8539
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -8324,6 +8623,7 @@ var SBarcodeInput = react.forwardRef(
8324
8623
  exports.BADGE_COLORS = BADGE_COLORS;
8325
8624
  exports.BUTTON_COLORS = BUTTON_COLORS;
8326
8625
  exports.BUTTON_SIZES = BUTTON_SIZES;
8626
+ exports.COLOR_KEYS = COLOR_KEYS;
8327
8627
  exports.ICONS = ICONS;
8328
8628
  exports.SActionModal = SActionModal;
8329
8629
  exports.SBadge = SBadge;
@@ -8343,6 +8643,7 @@ exports.SDivider = SDivider;
8343
8643
  exports.SDropdownButton = SDropdownButton;
8344
8644
  exports.SField = SField;
8345
8645
  exports.SFilePicker = SFilePicker;
8646
+ exports.SForm = SForm;
8346
8647
  exports.SGhostButton = SGhostButton;
8347
8648
  exports.SGuide = SGuide;
8348
8649
  exports.SIcon = SIcon;
@@ -8377,6 +8678,8 @@ exports.TAG_SHAPES = TAG_SHAPES;
8377
8678
  exports.TAG_SIZES = TAG_SIZES;
8378
8679
  exports.buttonPreset = buttonPreset;
8379
8680
  exports.cn = cn;
8681
+ exports.isColorKey = isColorKey;
8380
8682
  exports.loading = loading;
8683
+ exports.resolveColor = resolveColor;
8381
8684
  //# sourceMappingURL=index.cjs.map
8382
8685
  //# sourceMappingURL=index.cjs.map