sellmate-design-system-react 0.1.3 → 0.1.4

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 +156 -3
  6. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  7. package/dist/components/SBarcodeInput/SBarcodeInput.js +157 -4
  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 +129 -1
  23. package/dist/components/SCheckbox/SCheckbox.cjs.map +1 -1
  24. package/dist/components/SCheckbox/SCheckbox.js +129 -1
  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 +153 -3
  31. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  32. package/dist/components/SChipInput/SChipInput.js +153 -3
  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 +158 -5
  39. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  40. package/dist/components/SDatePicker/SDatePicker.js +158 -5
  41. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  42. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +156 -3
  43. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  44. package/dist/components/SDateRangePicker/SDateRangePicker.js +156 -3
  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 +129 -1
  51. package/dist/components/SField/SField.cjs.map +1 -1
  52. package/dist/components/SField/SField.js +129 -1
  53. package/dist/components/SField/SField.js.map +1 -1
  54. package/dist/components/SFilePicker/SFilePicker.cjs +156 -3
  55. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  56. package/dist/components/SFilePicker/SFilePicker.js +156 -3
  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 +156 -3
  78. package/dist/components/SInput/SInput.cjs.map +1 -1
  79. package/dist/components/SInput/SInput.js +157 -4
  80. package/dist/components/SInput/SInput.js.map +1 -1
  81. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +212 -5
  82. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  83. package/dist/components/SKeyValueTable/SKeyValueTable.js +212 -5
  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 +156 -3
  94. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  95. package/dist/components/SNumberInput/SNumberInput.js +156 -3
  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 +156 -3
  111. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  112. package/dist/components/SSelect/SSelect.js +157 -4
  113. package/dist/components/SSelect/SSelect.js.map +1 -1
  114. package/dist/components/STable/STable.cjs +156 -3
  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 +156 -3
  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 +156 -3
  133. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  134. package/dist/components/STextarea/STextarea.js +157 -4
  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 +129 -1
  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 +129 -1
  148. package/dist/components/STooltip/STooltip.js.map +1 -1
  149. package/dist/index.cjs +306 -5
  150. package/dist/index.cjs.map +1 -1
  151. package/dist/index.d.ts +2 -0
  152. package/dist/index.js +303 -6
  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 +25 -0
  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,
@@ -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(
@@ -5873,6 +6026,15 @@ var SInput = react.forwardRef(function SInput2({
5873
6026
  const isPassword = type === "password";
5874
6027
  const inputType = isPassword ? visible ? "text" : "password" : type;
5875
6028
  const hasValue = value !== void 0 && value !== null && String(value) !== "";
6029
+ useFormField({
6030
+ name: rest.name,
6031
+ validate: () => {
6032
+ const msg = runRules(value, rules);
6033
+ setRuleError(msg);
6034
+ return msg === "";
6035
+ },
6036
+ resetValidation: () => setRuleError("")
6037
+ });
5876
6038
  const resolvedError = error || ruleError !== "";
5877
6039
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
5878
6040
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
@@ -6003,6 +6165,15 @@ var STextarea = react.forwardRef(function STextarea2({
6003
6165
  }, ref) {
6004
6166
  const p = PAD;
6005
6167
  const [ruleError, setRuleError] = react.useState("");
6168
+ useFormField({
6169
+ name: rest.name,
6170
+ validate: () => {
6171
+ const msg = runRules(value, rules);
6172
+ setRuleError(msg);
6173
+ return msg === "";
6174
+ },
6175
+ resetValidation: () => setRuleError("")
6176
+ });
6006
6177
  const resolvedError = error || ruleError !== "";
6007
6178
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
6008
6179
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
@@ -6136,6 +6307,15 @@ var SNumberInput = react.forwardRef(function SNumberInput2({
6136
6307
  react.useEffect(() => {
6137
6308
  setDisplay(formatWithCommas(toNumber(value)));
6138
6309
  }, [value]);
6310
+ useFormField({
6311
+ name,
6312
+ validate: () => {
6313
+ const msg = runRules(numValue, rules);
6314
+ setRuleError(msg);
6315
+ return msg === "";
6316
+ },
6317
+ resetValidation: () => setRuleError("")
6318
+ });
6139
6319
  const resolvedError = error || ruleError !== "";
6140
6320
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6141
6321
  const emit2 = (n) => {
@@ -6631,7 +6811,7 @@ function SCalendar({
6631
6811
  "span",
6632
6812
  {
6633
6813
  className: "h-[var(--cmp-datepicker-calendar-day-dot-size)] w-[var(--cmp-datepicker-calendar-day-dot-size)] rounded-full",
6634
- style: { backgroundColor: ev.color }
6814
+ style: { backgroundColor: resolveColor(ev.color) }
6635
6815
  },
6636
6816
  i
6637
6817
  ))
@@ -6659,7 +6839,7 @@ function SCalendar({
6659
6839
  "span",
6660
6840
  {
6661
6841
  className: "h-[var(--cmp-datepicker-calendar-day-dot-size)] w-[var(--cmp-datepicker-calendar-day-dot-size)] rounded-full",
6662
- style: { backgroundColor: item.color },
6842
+ style: { backgroundColor: resolveColor(item.color) },
6663
6843
  "aria-hidden": true
6664
6844
  }
6665
6845
  ),
@@ -6703,6 +6883,15 @@ function SDatePicker({
6703
6883
  const [focused, setFocused] = react.useState(false);
6704
6884
  const [ruleError, setRuleError] = react.useState("");
6705
6885
  const hasValue = value != null && value !== "";
6886
+ useFormField({
6887
+ name,
6888
+ validate: () => {
6889
+ const msg = runRules(value, rules);
6890
+ setRuleError(msg);
6891
+ return msg === "";
6892
+ },
6893
+ resetValidation: () => setRuleError("")
6894
+ });
6706
6895
  const resolvedError = error || ruleError !== "";
6707
6896
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6708
6897
  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 +7177,15 @@ function SDateRangePicker({
6988
7177
  const [ruleError, setRuleError] = react.useState("");
6989
7178
  const hasValue = value != null && value[0] !== "" && value[1] !== "";
6990
7179
  const display = hasValue ? `${value[0]} ~ ${value[1]}` : placeholder;
7180
+ useFormField({
7181
+ name,
7182
+ validate: () => {
7183
+ const msg = runRules(value, rules);
7184
+ setRuleError(msg);
7185
+ return msg === "";
7186
+ },
7187
+ resetValidation: () => setRuleError("")
7188
+ });
6991
7189
  const resolvedError = error || ruleError !== "";
6992
7190
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6993
7191
  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 +7450,15 @@ function SFilePicker({
7252
7450
  const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
7253
7451
  const hasSingle = !multiple && !!files;
7254
7452
  const displayText = hasSingle ? files.name : placeholder;
7453
+ useFormField({
7454
+ name,
7455
+ validate: () => {
7456
+ const msg = runRules(files, rules);
7457
+ setRuleError(msg);
7458
+ return msg === "";
7459
+ },
7460
+ resetValidation: () => setRuleError("")
7461
+ });
7255
7462
  const validate = (arr, existing = 0) => {
7256
7463
  const mfs = toBytes(maxFileSize), mts = toBytes(maxTotalSize), mf = maxFiles != null ? Number(maxFiles) : void 0;
7257
7464
  if (mf != null && existing + arr.length > mf)
@@ -7848,6 +8055,81 @@ var SToastContainer = react.forwardRef(
7848
8055
  );
7849
8056
  }
7850
8057
  );
8058
+ var SForm = react.forwardRef(function SForm2({ formClass, onSubmit, onValidationError, children, className, style }, ref) {
8059
+ const formRef = react.useRef(null);
8060
+ const fieldsRef = react.useRef(/* @__PURE__ */ new Set());
8061
+ const register = react.useCallback((entry) => {
8062
+ fieldsRef.current.add(entry);
8063
+ return () => {
8064
+ fieldsRef.current.delete(entry);
8065
+ };
8066
+ }, []);
8067
+ const ctx = react.useMemo(() => ({ register }), [register]);
8068
+ const orderByDom = react.useCallback((names) => {
8069
+ const form = formRef.current;
8070
+ if (!form || names.length < 2) return names;
8071
+ const domOrder = /* @__PURE__ */ new Map();
8072
+ form.querySelectorAll("[name],[data-name]").forEach((el, i) => {
8073
+ const n = el.getAttribute("name") || el.getAttribute("data-name");
8074
+ if (n && !domOrder.has(n)) domOrder.set(n, i);
8075
+ });
8076
+ return [...names].sort((a, b) => (domOrder.get(a) ?? Infinity) - (domOrder.get(b) ?? Infinity));
8077
+ }, []);
8078
+ const focusByName = react.useCallback((name) => {
8079
+ const form = formRef.current;
8080
+ if (!form || !name) return;
8081
+ const host = form.querySelector(`[name="${CSS.escape(name)}"]`) ?? form.querySelector(`[data-name="${CSS.escape(name)}"]`);
8082
+ if (!host) return;
8083
+ const focusable = host.matches("input,textarea,select,button,[tabindex]") ? host : host.querySelector("input,textarea,select,button,[tabindex]");
8084
+ focusable?.focus();
8085
+ (focusable ?? host).scrollIntoView({ block: "nearest" });
8086
+ }, []);
8087
+ const runValidation = react.useCallback(() => {
8088
+ let valid = true;
8089
+ const invalidNames = [];
8090
+ fieldsRef.current.forEach((f) => {
8091
+ if (!f.validate()) {
8092
+ valid = false;
8093
+ if (f.name) invalidNames.push(f.name);
8094
+ }
8095
+ });
8096
+ return { valid, names: orderByDom(invalidNames) };
8097
+ }, [orderByDom]);
8098
+ react.useImperativeHandle(
8099
+ ref,
8100
+ () => ({
8101
+ validate: () => runValidation().valid,
8102
+ resetValidation: () => fieldsRef.current.forEach((f) => f.resetValidation()),
8103
+ reset: () => fieldsRef.current.forEach((f) => f.resetValidation()),
8104
+ focusFirstInvalid: () => {
8105
+ const { names } = runValidation();
8106
+ if (names.length > 0) focusByName(names[0]);
8107
+ }
8108
+ }),
8109
+ [runValidation, focusByName]
8110
+ );
8111
+ const handleSubmit = (e) => {
8112
+ e.preventDefault();
8113
+ const { valid, names } = runValidation();
8114
+ if (!valid) {
8115
+ if (names.length > 0) focusByName(names[0]);
8116
+ onValidationError?.({ names });
8117
+ return;
8118
+ }
8119
+ onSubmit?.();
8120
+ };
8121
+ return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
8122
+ "form",
8123
+ {
8124
+ ref: formRef,
8125
+ onSubmit: handleSubmit,
8126
+ className: cn(formClass, className),
8127
+ style,
8128
+ noValidate: true,
8129
+ children
8130
+ }
8131
+ ) });
8132
+ });
7851
8133
  function SRadioButton({
7852
8134
  options = [],
7853
8135
  value,
@@ -7963,6 +8245,12 @@ function SChipInput({
7963
8245
  const resolvedErrorMessage = duplicateMessage || ruleMessage || errorMessage;
7964
8246
  const resolvedError = error || duplicateMessage !== "" || ruleMessage !== "";
7965
8247
  const resolvedStatus = status ?? (resolvedError ? "error" : void 0);
8248
+ useFormField({
8249
+ name,
8250
+ validate: () => runRules(values, rules) === "" && duplicateMessage === "",
8251
+ resetValidation: () => {
8252
+ }
8253
+ });
7966
8254
  const isMax = maxCount != null && values.length >= maxCount;
7967
8255
  const commit = (next) => onValueChange?.(next);
7968
8256
  const addChip = (v) => {
@@ -8235,6 +8523,15 @@ var SBarcodeInput = react.forwardRef(
8235
8523
  const f = FONT2[size];
8236
8524
  const [ruleError, setRuleError] = react.useState("");
8237
8525
  const hasValue = value !== void 0 && value !== null && String(value) !== "";
8526
+ useFormField({
8527
+ name,
8528
+ validate: () => {
8529
+ const msg = runRules(value, rules);
8530
+ setRuleError(msg);
8531
+ return msg === "";
8532
+ },
8533
+ resetValidation: () => setRuleError("")
8534
+ });
8238
8535
  const resolvedError = error || ruleError !== "";
8239
8536
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
8240
8537
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -8324,6 +8621,7 @@ var SBarcodeInput = react.forwardRef(
8324
8621
  exports.BADGE_COLORS = BADGE_COLORS;
8325
8622
  exports.BUTTON_COLORS = BUTTON_COLORS;
8326
8623
  exports.BUTTON_SIZES = BUTTON_SIZES;
8624
+ exports.COLOR_KEYS = COLOR_KEYS;
8327
8625
  exports.ICONS = ICONS;
8328
8626
  exports.SActionModal = SActionModal;
8329
8627
  exports.SBadge = SBadge;
@@ -8343,6 +8641,7 @@ exports.SDivider = SDivider;
8343
8641
  exports.SDropdownButton = SDropdownButton;
8344
8642
  exports.SField = SField;
8345
8643
  exports.SFilePicker = SFilePicker;
8644
+ exports.SForm = SForm;
8346
8645
  exports.SGhostButton = SGhostButton;
8347
8646
  exports.SGuide = SGuide;
8348
8647
  exports.SIcon = SIcon;
@@ -8377,6 +8676,8 @@ exports.TAG_SHAPES = TAG_SHAPES;
8377
8676
  exports.TAG_SIZES = TAG_SIZES;
8378
8677
  exports.buttonPreset = buttonPreset;
8379
8678
  exports.cn = cn;
8679
+ exports.isColorKey = isColorKey;
8380
8680
  exports.loading = loading;
8681
+ exports.resolveColor = resolveColor;
8381
8682
  //# sourceMappingURL=index.cjs.map
8382
8683
  //# sourceMappingURL=index.cjs.map