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.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { cn } from './lib/cn';
2
+ export { resolveColor, isColorKey, COLOR_KEYS, type SColor, type SColorKey } from './lib/color';
2
3
  export * from './components/SIcon';
3
4
  export * from './components/SBadge';
4
5
  export * from './components/SCard';
@@ -28,6 +29,7 @@ export * from './components/SPagination';
28
29
  export * from './components/STable';
29
30
  export * from './components/SKeyValueTable';
30
31
  export * from './components/SToast';
32
+ export * from './components/SForm';
31
33
  export * from './components/SField';
32
34
  export * from './components/SCheckbox';
33
35
  export * from './components/SRadio';
package/dist/index.js CHANGED
@@ -16,6 +16,134 @@ import * as Ariakit from '@ariakit/react';
16
16
  function cn(...inputs) {
17
17
  return twMerge(clsx(inputs));
18
18
  }
19
+
20
+ // src/lib/color.ts
21
+ var COLOR_KEYS = [
22
+ "white",
23
+ "black",
24
+ "grey_10",
25
+ "grey_20",
26
+ "grey_25",
27
+ "grey_30",
28
+ "grey_35",
29
+ "grey_45",
30
+ "grey_50",
31
+ "grey_55",
32
+ "grey_60",
33
+ "grey_65",
34
+ "grey_70",
35
+ "grey_80",
36
+ "grey_85",
37
+ "grey_90",
38
+ "grey_95",
39
+ "grey_05",
40
+ "red_15",
41
+ "red_20",
42
+ "red_30",
43
+ "red_45",
44
+ "red_60",
45
+ "red_70",
46
+ "red_75",
47
+ "red_80",
48
+ "red_85",
49
+ "red_90",
50
+ "red_95",
51
+ "red_99",
52
+ "orange_10",
53
+ "orange_20",
54
+ "orange_35",
55
+ "orange_45",
56
+ "orange_55",
57
+ "orange_60",
58
+ "orange_65",
59
+ "orange_75",
60
+ "orange_85",
61
+ "orange_90",
62
+ "orange_95",
63
+ "orange_99",
64
+ "yellow_10",
65
+ "yellow_20",
66
+ "yellow_25",
67
+ "yellow_30",
68
+ "yellow_40",
69
+ "yellow_45",
70
+ "yellow_50",
71
+ "yellow_60",
72
+ "yellow_70",
73
+ "yellow_80",
74
+ "yellow_90",
75
+ "yellow_95",
76
+ "olive_10",
77
+ "olive_15",
78
+ "olive_20",
79
+ "olive_30",
80
+ "olive_45",
81
+ "olive_55",
82
+ "olive_65",
83
+ "olive_70",
84
+ "olive_80",
85
+ "olive_90",
86
+ "olive_95",
87
+ "olive_05",
88
+ "green_15",
89
+ "green_25",
90
+ "green_45",
91
+ "green_55",
92
+ "green_65",
93
+ "green_70",
94
+ "green_75",
95
+ "green_80",
96
+ "green_85",
97
+ "green_90",
98
+ "green_95",
99
+ "green_99",
100
+ "steelblue_10",
101
+ "steelblue_25",
102
+ "steelblue_45",
103
+ "steelblue_60",
104
+ "steelblue_65",
105
+ "steelblue_70",
106
+ "steelblue_75",
107
+ "steelblue_80",
108
+ "steelblue_85",
109
+ "steelblue_90",
110
+ "steelblue_95",
111
+ "steelblue_99",
112
+ "oceanblue_15",
113
+ "oceanblue_25",
114
+ "oceanblue_50",
115
+ "oceanblue_60",
116
+ "oceanblue_65",
117
+ "oceanblue_70",
118
+ "oceanblue_75",
119
+ "oceanblue_80",
120
+ "oceanblue_85",
121
+ "oceanblue_90",
122
+ "oceanblue_95",
123
+ "oceanblue_99",
124
+ "brilliantblue_10",
125
+ "brilliantblue_20",
126
+ "brilliantblue_25",
127
+ "brilliantblue_40",
128
+ "brilliantblue_50",
129
+ "brilliantblue_60",
130
+ "brilliantblue_70",
131
+ "brilliantblue_75",
132
+ "brilliantblue_80",
133
+ "brilliantblue_85",
134
+ "brilliantblue_90",
135
+ "brilliantblue_95",
136
+ "brilliantblue_99",
137
+ "brilliantblue_05"
138
+ ];
139
+ var KEY_SET = new Set(COLOR_KEYS);
140
+ function isColorKey(input) {
141
+ return KEY_SET.has(input);
142
+ }
143
+ function resolveColor(input, fallback) {
144
+ if (input === null || input === void 0 || input === "") return fallback;
145
+ return isColorKey(input) ? `var(--color-${input.replace(/_/g, "-")})` : input;
146
+ }
19
147
  var Icon_add = (p) => {
20
148
  const { size = 24, ...rest } = p;
21
149
  return /* @__PURE__ */ jsx(
@@ -2715,7 +2843,7 @@ var SIcon = forwardRef(function SIcon2({ name, size = 24, color, rotate, label,
2715
2843
  {
2716
2844
  ref,
2717
2845
  className: cn("inline-flex items-center justify-center", rotateClass, className),
2718
- style: { color, ...style },
2846
+ style: { color: resolveColor(color), ...style },
2719
2847
  role: label ? "img" : void 0,
2720
2848
  "aria-label": label,
2721
2849
  "aria-hidden": label ? void 0 : true,
@@ -4769,8 +4897,6 @@ function SCheckbox({
4769
4897
  }
4770
4898
  );
4771
4899
  }
4772
-
4773
- // src/lib/form.ts
4774
4900
  function runRules(value, rules) {
4775
4901
  if (!rules || rules.length === 0) return "";
4776
4902
  for (const rule of rules) {
@@ -4779,6 +4905,24 @@ function runRules(value, rules) {
4779
4905
  }
4780
4906
  return "";
4781
4907
  }
4908
+ var FormContext = createContext(null);
4909
+ function useFormContext() {
4910
+ return useContext(FormContext);
4911
+ }
4912
+ function useFormField(field) {
4913
+ const ctx = useFormContext();
4914
+ const cbRef = useRef(field);
4915
+ cbRef.current = field;
4916
+ const name = field.name ?? "";
4917
+ useEffect(() => {
4918
+ if (!ctx) return;
4919
+ return ctx.register({
4920
+ name,
4921
+ validate: () => cbRef.current.validate(),
4922
+ resetValidation: () => cbRef.current.resetValidation()
4923
+ });
4924
+ }, [ctx, name]);
4925
+ }
4782
4926
  var FIELD_SIZE = {
4783
4927
  sm: { height: 28, radius: 4, fieldGap: 12, labelGap: 6, fontSize: 12, lineHeight: 20, icon: 12 },
4784
4928
  md: { height: 36, radius: 6, fieldGap: 16, labelGap: 8, fontSize: 14, lineHeight: 24, icon: 12 }
@@ -5071,6 +5215,15 @@ var SSelect = forwardRef(function SSelect2({
5071
5215
  const arr = Array.isArray(value) ? value : [value];
5072
5216
  return arr.map((v) => v != null && typeof v === "object" ? v.value : v).filter((v) => v != null && v !== "").map(String);
5073
5217
  }, [value]);
5218
+ useFormField({
5219
+ name,
5220
+ validate: () => {
5221
+ const msg = runRules(multi ? selected : selected[0] ?? "", rules);
5222
+ setRuleError(msg);
5223
+ return msg === "";
5224
+ },
5225
+ resetValidation: () => setRuleError("")
5226
+ });
5074
5227
  const emit2 = (next) => {
5075
5228
  if (!onValueChange) return;
5076
5229
  const mapped = next.map(
@@ -5845,6 +5998,15 @@ var SInput = forwardRef(function SInput2({
5845
5998
  const isPassword = type === "password";
5846
5999
  const inputType = isPassword ? visible ? "text" : "password" : type;
5847
6000
  const hasValue = value !== void 0 && value !== null && String(value) !== "";
6001
+ useFormField({
6002
+ name: rest.name,
6003
+ validate: () => {
6004
+ const msg = runRules(value, rules);
6005
+ setRuleError(msg);
6006
+ return msg === "";
6007
+ },
6008
+ resetValidation: () => setRuleError("")
6009
+ });
5848
6010
  const resolvedError = error || ruleError !== "";
5849
6011
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
5850
6012
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
@@ -5975,6 +6137,15 @@ var STextarea = forwardRef(function STextarea2({
5975
6137
  }, ref) {
5976
6138
  const p = PAD;
5977
6139
  const [ruleError, setRuleError] = useState("");
6140
+ useFormField({
6141
+ name: rest.name,
6142
+ validate: () => {
6143
+ const msg = runRules(value, rules);
6144
+ setRuleError(msg);
6145
+ return msg === "";
6146
+ },
6147
+ resetValidation: () => setRuleError("")
6148
+ });
5978
6149
  const resolvedError = error || ruleError !== "";
5979
6150
  const resolvedErrorMessage = ruleError !== "" ? ruleError : errorMessage;
5980
6151
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
@@ -6108,6 +6279,15 @@ var SNumberInput = forwardRef(function SNumberInput2({
6108
6279
  useEffect(() => {
6109
6280
  setDisplay(formatWithCommas(toNumber(value)));
6110
6281
  }, [value]);
6282
+ useFormField({
6283
+ name,
6284
+ validate: () => {
6285
+ const msg = runRules(numValue, rules);
6286
+ setRuleError(msg);
6287
+ return msg === "";
6288
+ },
6289
+ resetValidation: () => setRuleError("")
6290
+ });
6111
6291
  const resolvedError = error || ruleError !== "";
6112
6292
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6113
6293
  const emit2 = (n) => {
@@ -6603,7 +6783,7 @@ function SCalendar({
6603
6783
  "span",
6604
6784
  {
6605
6785
  className: "h-[var(--cmp-datepicker-calendar-day-dot-size)] w-[var(--cmp-datepicker-calendar-day-dot-size)] rounded-full",
6606
- style: { backgroundColor: ev.color }
6786
+ style: { backgroundColor: resolveColor(ev.color) }
6607
6787
  },
6608
6788
  i
6609
6789
  ))
@@ -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: item.color },
6814
+ style: { backgroundColor: resolveColor(item.color) },
6635
6815
  "aria-hidden": true
6636
6816
  }
6637
6817
  ),
@@ -6675,6 +6855,15 @@ function SDatePicker({
6675
6855
  const [focused, setFocused] = useState(false);
6676
6856
  const [ruleError, setRuleError] = useState("");
6677
6857
  const hasValue = value != null && value !== "";
6858
+ useFormField({
6859
+ name,
6860
+ validate: () => {
6861
+ const msg = runRules(value, rules);
6862
+ setRuleError(msg);
6863
+ return msg === "";
6864
+ },
6865
+ resetValidation: () => setRuleError("")
6866
+ });
6678
6867
  const resolvedError = error || ruleError !== "";
6679
6868
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6680
6869
  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 };
@@ -6960,6 +7149,15 @@ function SDateRangePicker({
6960
7149
  const [ruleError, setRuleError] = useState("");
6961
7150
  const hasValue = value != null && value[0] !== "" && value[1] !== "";
6962
7151
  const display = hasValue ? `${value[0]} ~ ${value[1]}` : placeholder;
7152
+ useFormField({
7153
+ name,
7154
+ validate: () => {
7155
+ const msg = runRules(value, rules);
7156
+ setRuleError(msg);
7157
+ return msg === "";
7158
+ },
7159
+ resetValidation: () => setRuleError("")
7160
+ });
6963
7161
  const resolvedError = error || ruleError !== "";
6964
7162
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
6965
7163
  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 };
@@ -7224,6 +7422,15 @@ function SFilePicker({
7224
7422
  const files = multiple ? Array.isArray(value) ? value : [] : value && !Array.isArray(value) ? value : null;
7225
7423
  const hasSingle = !multiple && !!files;
7226
7424
  const displayText = hasSingle ? files.name : placeholder;
7425
+ useFormField({
7426
+ name,
7427
+ validate: () => {
7428
+ const msg = runRules(files, rules);
7429
+ setRuleError(msg);
7430
+ return msg === "";
7431
+ },
7432
+ resetValidation: () => setRuleError("")
7433
+ });
7227
7434
  const validate = (arr, existing = 0) => {
7228
7435
  const mfs = toBytes(maxFileSize), mts = toBytes(maxTotalSize), mf = maxFiles != null ? Number(maxFiles) : void 0;
7229
7436
  if (mf != null && existing + arr.length > mf)
@@ -7820,6 +8027,81 @@ var SToastContainer = forwardRef(
7820
8027
  );
7821
8028
  }
7822
8029
  );
8030
+ var SForm = forwardRef(function SForm2({ formClass, onSubmit, onValidationError, children, className, style }, ref) {
8031
+ const formRef = useRef(null);
8032
+ const fieldsRef = useRef(/* @__PURE__ */ new Set());
8033
+ const register = useCallback((entry) => {
8034
+ fieldsRef.current.add(entry);
8035
+ return () => {
8036
+ fieldsRef.current.delete(entry);
8037
+ };
8038
+ }, []);
8039
+ const ctx = useMemo(() => ({ register }), [register]);
8040
+ const orderByDom = useCallback((names) => {
8041
+ const form = formRef.current;
8042
+ if (!form || names.length < 2) return names;
8043
+ const domOrder = /* @__PURE__ */ new Map();
8044
+ form.querySelectorAll("[name],[data-name]").forEach((el, i) => {
8045
+ const n = el.getAttribute("name") || el.getAttribute("data-name");
8046
+ if (n && !domOrder.has(n)) domOrder.set(n, i);
8047
+ });
8048
+ return [...names].sort((a, b) => (domOrder.get(a) ?? Infinity) - (domOrder.get(b) ?? Infinity));
8049
+ }, []);
8050
+ const focusByName = useCallback((name) => {
8051
+ const form = formRef.current;
8052
+ if (!form || !name) return;
8053
+ const host = form.querySelector(`[name="${CSS.escape(name)}"]`) ?? form.querySelector(`[data-name="${CSS.escape(name)}"]`);
8054
+ if (!host) return;
8055
+ const focusable = host.matches("input,textarea,select,button,[tabindex]") ? host : host.querySelector("input,textarea,select,button,[tabindex]");
8056
+ focusable?.focus();
8057
+ (focusable ?? host).scrollIntoView({ block: "nearest" });
8058
+ }, []);
8059
+ const runValidation = useCallback(() => {
8060
+ let valid = true;
8061
+ const invalidNames = [];
8062
+ fieldsRef.current.forEach((f) => {
8063
+ if (!f.validate()) {
8064
+ valid = false;
8065
+ if (f.name) invalidNames.push(f.name);
8066
+ }
8067
+ });
8068
+ return { valid, names: orderByDom(invalidNames) };
8069
+ }, [orderByDom]);
8070
+ useImperativeHandle(
8071
+ ref,
8072
+ () => ({
8073
+ validate: () => runValidation().valid,
8074
+ resetValidation: () => fieldsRef.current.forEach((f) => f.resetValidation()),
8075
+ reset: () => fieldsRef.current.forEach((f) => f.resetValidation()),
8076
+ focusFirstInvalid: () => {
8077
+ const { names } = runValidation();
8078
+ if (names.length > 0) focusByName(names[0]);
8079
+ }
8080
+ }),
8081
+ [runValidation, focusByName]
8082
+ );
8083
+ const handleSubmit = (e) => {
8084
+ e.preventDefault();
8085
+ const { valid, names } = runValidation();
8086
+ if (!valid) {
8087
+ if (names.length > 0) focusByName(names[0]);
8088
+ onValidationError?.({ names });
8089
+ return;
8090
+ }
8091
+ onSubmit?.();
8092
+ };
8093
+ return /* @__PURE__ */ jsx(FormContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
8094
+ "form",
8095
+ {
8096
+ ref: formRef,
8097
+ onSubmit: handleSubmit,
8098
+ className: cn(formClass, className),
8099
+ style,
8100
+ noValidate: true,
8101
+ children
8102
+ }
8103
+ ) });
8104
+ });
7823
8105
  function SRadioButton({
7824
8106
  options = [],
7825
8107
  value,
@@ -7935,6 +8217,12 @@ function SChipInput({
7935
8217
  const resolvedErrorMessage = duplicateMessage || ruleMessage || errorMessage;
7936
8218
  const resolvedError = error || duplicateMessage !== "" || ruleMessage !== "";
7937
8219
  const resolvedStatus = status ?? (resolvedError ? "error" : void 0);
8220
+ useFormField({
8221
+ name,
8222
+ validate: () => runRules(values, rules) === "" && duplicateMessage === "",
8223
+ resetValidation: () => {
8224
+ }
8225
+ });
7938
8226
  const isMax = maxCount != null && values.length >= maxCount;
7939
8227
  const commit = (next) => onValueChange?.(next);
7940
8228
  const addChip = (v) => {
@@ -8207,6 +8495,15 @@ var SBarcodeInput = forwardRef(
8207
8495
  const f = FONT2[size];
8208
8496
  const [ruleError, setRuleError] = useState("");
8209
8497
  const hasValue = value !== void 0 && value !== null && String(value) !== "";
8498
+ useFormField({
8499
+ name,
8500
+ validate: () => {
8501
+ const msg = runRules(value, rules);
8502
+ setRuleError(msg);
8503
+ return msg === "";
8504
+ },
8505
+ resetValidation: () => setRuleError("")
8506
+ });
8210
8507
  const resolvedError = error || ruleError !== "";
8211
8508
  const resolvedStatus = status ?? (rules && rules.length > 0 ? ruleError !== "" ? "error" : void 0 : void 0);
8212
8509
  return /* @__PURE__ */ jsx(
@@ -8293,6 +8590,6 @@ var SBarcodeInput = forwardRef(
8293
8590
  }
8294
8591
  );
8295
8592
 
8296
- export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SGhostButton, SGuide, SIcon, SInput, SKeyValueTable, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SModalContainer, SNumberInput, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, buttonPreset, cn, loading };
8593
+ export { BADGE_COLORS, BUTTON_COLORS, BUTTON_SIZES, COLOR_KEYS, ICONS, SActionModal, SBadge, SBarcodeInput, SButton, SCalendar, SCallout, SCard, SCheckbox, SChip, SChipInput, SCircleProgress, SConfirmModal, SDatePicker, SDateRangePicker, SDivider, SDropdownButton, SField, SFilePicker, SForm, SGhostButton, SGuide, SIcon, SInput, SKeyValueTable, SLinearProgress, SLoadingContainer, SLoadingModal, SLoadingViewport, SModalContainer, SNumberInput, SPagination, SPopover, SPopup, SPortal, SRadio, SRadioButton, SRadioGroup, SSelect, SSwitch, STable, STabs, STag, STextLink, STextarea, SToast, SToastContainer, SToggle, STooltip, TAG_COLORS, TAG_SHAPES, TAG_SIZES, buttonPreset, cn, isColorKey, loading, resolveColor };
8297
8594
  //# sourceMappingURL=index.js.map
8298
8595
  //# sourceMappingURL=index.js.map