formanitor 0.1.11 → 0.2.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.
Files changed (289) hide show
  1. package/dist/AddInvestigationWidget-7UGZQYI5.mjs +30 -0
  2. package/dist/AddInvestigationWidget-7UGZQYI5.mjs.map +1 -0
  3. package/dist/AddInvestigationWidget-RY62UCPM.cjs +32 -0
  4. package/dist/AddInvestigationWidget-RY62UCPM.cjs.map +1 -0
  5. package/dist/AddMedicationWidget-UG26VMUX.mjs +30 -0
  6. package/dist/AddMedicationWidget-UG26VMUX.mjs.map +1 -0
  7. package/dist/AddMedicationWidget-WPI32WAP.cjs +32 -0
  8. package/dist/AddMedicationWidget-WPI32WAP.cjs.map +1 -0
  9. package/dist/AddProcedureWidget-SF6MTRBV.cjs +278 -0
  10. package/dist/AddProcedureWidget-SF6MTRBV.cjs.map +1 -0
  11. package/dist/AddProcedureWidget-SQJUKKMK.mjs +276 -0
  12. package/dist/AddProcedureWidget-SQJUKKMK.mjs.map +1 -0
  13. package/dist/BiometryIolWorkupWidget-I5AJOYB2.cjs +300 -0
  14. package/dist/BiometryIolWorkupWidget-I5AJOYB2.cjs.map +1 -0
  15. package/dist/BiometryIolWorkupWidget-NL2M7ZAA.mjs +298 -0
  16. package/dist/BiometryIolWorkupWidget-NL2M7ZAA.mjs.map +1 -0
  17. package/dist/DateTimeWidget-DIDVF2EB.cjs +61 -0
  18. package/dist/DateTimeWidget-DIDVF2EB.cjs.map +1 -0
  19. package/dist/DateTimeWidget-LFBB6HOP.mjs +59 -0
  20. package/dist/DateTimeWidget-LFBB6HOP.mjs.map +1 -0
  21. package/dist/DateWidget-4ND5TKP2.mjs +72 -0
  22. package/dist/DateWidget-4ND5TKP2.mjs.map +1 -0
  23. package/dist/DateWidget-BCVR5GDK.cjs +74 -0
  24. package/dist/DateWidget-BCVR5GDK.cjs.map +1 -0
  25. package/dist/DiagnosisTextareaWidget-E7OQRUMX.cjs +190 -0
  26. package/dist/DiagnosisTextareaWidget-E7OQRUMX.cjs.map +1 -0
  27. package/dist/DiagnosisTextareaWidget-MAOXCXEZ.mjs +184 -0
  28. package/dist/DiagnosisTextareaWidget-MAOXCXEZ.mjs.map +1 -0
  29. package/dist/DifferentialDiagnosisWidget-ANALLNKL.cjs +17 -0
  30. package/dist/DifferentialDiagnosisWidget-ANALLNKL.cjs.map +1 -0
  31. package/dist/DifferentialDiagnosisWidget-LCY2SA2I.mjs +15 -0
  32. package/dist/DifferentialDiagnosisWidget-LCY2SA2I.mjs.map +1 -0
  33. package/dist/DischargeMedicationOrdersWidget-GYT35W7J.mjs +161 -0
  34. package/dist/DischargeMedicationOrdersWidget-GYT35W7J.mjs.map +1 -0
  35. package/dist/DischargeMedicationOrdersWidget-ILWNZ7VM.cjs +163 -0
  36. package/dist/DischargeMedicationOrdersWidget-ILWNZ7VM.cjs.map +1 -0
  37. package/dist/EditableTable-TGCVUBLO.mjs +279 -0
  38. package/dist/EditableTable-TGCVUBLO.mjs.map +1 -0
  39. package/dist/EditableTable-VCUNJZEX.cjs +281 -0
  40. package/dist/EditableTable-VCUNJZEX.cjs.map +1 -0
  41. package/dist/FollowupWidget-F6FRZO4T.mjs +283 -0
  42. package/dist/FollowupWidget-F6FRZO4T.mjs.map +1 -0
  43. package/dist/FollowupWidget-NBTOV2ML.cjs +285 -0
  44. package/dist/FollowupWidget-NBTOV2ML.cjs.map +1 -0
  45. package/dist/FunctionalImpairmentScoreWidget-5V5SNLTF.cjs +93 -0
  46. package/dist/FunctionalImpairmentScoreWidget-5V5SNLTF.cjs.map +1 -0
  47. package/dist/FunctionalImpairmentScoreWidget-QKIZE7KT.mjs +91 -0
  48. package/dist/FunctionalImpairmentScoreWidget-QKIZE7KT.mjs.map +1 -0
  49. package/dist/GsExaminationWidget-57SL4BCI.cjs +528 -0
  50. package/dist/GsExaminationWidget-57SL4BCI.cjs.map +1 -0
  51. package/dist/GsExaminationWidget-J4VABGY6.mjs +526 -0
  52. package/dist/GsExaminationWidget-J4VABGY6.mjs.map +1 -0
  53. package/dist/GsGradingWidget-3WTLIP33.mjs +90 -0
  54. package/dist/GsGradingWidget-3WTLIP33.mjs.map +1 -0
  55. package/dist/GsGradingWidget-CIXE36HF.cjs +92 -0
  56. package/dist/GsGradingWidget-CIXE36HF.cjs.map +1 -0
  57. package/dist/GsSmartHistoryWidget-6Q2IIGDG.cjs +398 -0
  58. package/dist/GsSmartHistoryWidget-6Q2IIGDG.cjs.map +1 -0
  59. package/dist/GsSmartHistoryWidget-IOGZ6GNS.mjs +396 -0
  60. package/dist/GsSmartHistoryWidget-IOGZ6GNS.mjs.map +1 -0
  61. package/dist/HiddenVitalsWidget-HBK7PBPR.cjs +55 -0
  62. package/dist/HiddenVitalsWidget-HBK7PBPR.cjs.map +1 -0
  63. package/dist/HiddenVitalsWidget-JH3NRZLM.mjs +53 -0
  64. package/dist/HiddenVitalsWidget-JH3NRZLM.mjs.map +1 -0
  65. package/dist/LensAssessmentWidget-7WMULFS2.mjs +232 -0
  66. package/dist/LensAssessmentWidget-7WMULFS2.mjs.map +1 -0
  67. package/dist/LensAssessmentWidget-GSOOD7BX.cjs +234 -0
  68. package/dist/LensAssessmentWidget-GSOOD7BX.cjs.map +1 -0
  69. package/dist/MarMedicationOrdersWidget-3E6GFOR6.cjs +76 -0
  70. package/dist/MarMedicationOrdersWidget-3E6GFOR6.cjs.map +1 -0
  71. package/dist/MarMedicationOrdersWidget-QZUVSEB5.mjs +74 -0
  72. package/dist/MarMedicationOrdersWidget-QZUVSEB5.mjs.map +1 -0
  73. package/dist/OBGExaminationWidget-F2ZNSP2M.cjs +215 -0
  74. package/dist/OBGExaminationWidget-F2ZNSP2M.cjs.map +1 -0
  75. package/dist/OBGExaminationWidget-POVLALMA.mjs +213 -0
  76. package/dist/OBGExaminationWidget-POVLALMA.mjs.map +1 -0
  77. package/dist/OBGPathwayWidget-CGT7Q4T2.mjs +517 -0
  78. package/dist/OBGPathwayWidget-CGT7Q4T2.mjs.map +1 -0
  79. package/dist/OBGPathwayWidget-WCIQENMO.cjs +519 -0
  80. package/dist/OBGPathwayWidget-WCIQENMO.cjs.map +1 -0
  81. package/dist/ObstetricHistoryWidget-EGVLL4X2.mjs +1113 -0
  82. package/dist/ObstetricHistoryWidget-EGVLL4X2.mjs.map +1 -0
  83. package/dist/ObstetricHistoryWidget-XU6R7IPP.cjs +1115 -0
  84. package/dist/ObstetricHistoryWidget-XU6R7IPP.cjs.map +1 -0
  85. package/dist/OphthalDiagnosisWidget-G5RCC2QZ.mjs +89 -0
  86. package/dist/OphthalDiagnosisWidget-G5RCC2QZ.mjs.map +1 -0
  87. package/dist/OphthalDiagnosisWidget-OQPTHJ7E.cjs +91 -0
  88. package/dist/OphthalDiagnosisWidget-OQPTHJ7E.cjs.map +1 -0
  89. package/dist/OphthalmologyWidget-I3BKWOI2.cjs +1331 -0
  90. package/dist/OphthalmologyWidget-I3BKWOI2.cjs.map +1 -0
  91. package/dist/OphthalmologyWidget-RG2AI6WA.mjs +1329 -0
  92. package/dist/OphthalmologyWidget-RG2AI6WA.mjs.map +1 -0
  93. package/dist/OrthopedicExamWidget-BBZP6NVT.mjs +366 -0
  94. package/dist/OrthopedicExamWidget-BBZP6NVT.mjs.map +1 -0
  95. package/dist/OrthopedicExamWidget-M4KKU5RC.cjs +368 -0
  96. package/dist/OrthopedicExamWidget-M4KKU5RC.cjs.map +1 -0
  97. package/dist/PainScaleFlagsWidget-E576R6QB.mjs +151 -0
  98. package/dist/PainScaleFlagsWidget-E576R6QB.mjs.map +1 -0
  99. package/dist/PainScaleFlagsWidget-QHGESXNE.cjs +153 -0
  100. package/dist/PainScaleFlagsWidget-QHGESXNE.cjs.map +1 -0
  101. package/dist/ReadOnlyTable-4Y2XW4MX.mjs +6 -0
  102. package/dist/ReadOnlyTable-4Y2XW4MX.mjs.map +1 -0
  103. package/dist/ReadOnlyTable-L7G6GWEJ.cjs +15 -0
  104. package/dist/ReadOnlyTable-L7G6GWEJ.cjs.map +1 -0
  105. package/dist/ReferralWidget-J2PWYFDT.cjs +171 -0
  106. package/dist/ReferralWidget-J2PWYFDT.cjs.map +1 -0
  107. package/dist/ReferralWidget-UPYWEO5R.mjs +169 -0
  108. package/dist/ReferralWidget-UPYWEO5R.mjs.map +1 -0
  109. package/dist/RichTextWidget-BBCNJPMH.mjs +11 -0
  110. package/dist/RichTextWidget-BBCNJPMH.mjs.map +1 -0
  111. package/dist/RichTextWidget-CRQHNVJR.cjs +24 -0
  112. package/dist/RichTextWidget-CRQHNVJR.cjs.map +1 -0
  113. package/dist/SmartTextarea-DKWV4R6H.cjs +19 -0
  114. package/dist/SmartTextarea-DKWV4R6H.cjs.map +1 -0
  115. package/dist/SmartTextarea-ZTQIW6O2.mjs +10 -0
  116. package/dist/SmartTextarea-ZTQIW6O2.mjs.map +1 -0
  117. package/dist/SuggestionTextareaWidget-22NR3JWM.mjs +215 -0
  118. package/dist/SuggestionTextareaWidget-22NR3JWM.mjs.map +1 -0
  119. package/dist/SuggestionTextareaWidget-WCTPWW2E.cjs +226 -0
  120. package/dist/SuggestionTextareaWidget-WCTPWW2E.cjs.map +1 -0
  121. package/dist/SurgicalRiskFlagsWidget-Q5FTWB3M.cjs +146 -0
  122. package/dist/SurgicalRiskFlagsWidget-Q5FTWB3M.cjs.map +1 -0
  123. package/dist/SurgicalRiskFlagsWidget-WCAHZKKG.mjs +144 -0
  124. package/dist/SurgicalRiskFlagsWidget-WCAHZKKG.mjs.map +1 -0
  125. package/dist/UrologyExaminationWidget-JYUGZ5CG.cjs +273 -0
  126. package/dist/UrologyExaminationWidget-JYUGZ5CG.cjs.map +1 -0
  127. package/dist/UrologyExaminationWidget-QDTD3FJX.mjs +271 -0
  128. package/dist/UrologyExaminationWidget-QDTD3FJX.mjs.map +1 -0
  129. package/dist/UrologyPathwayWidget-QTFKUIM7.mjs +153 -0
  130. package/dist/UrologyPathwayWidget-QTFKUIM7.mjs.map +1 -0
  131. package/dist/UrologyPathwayWidget-TXZQNGP4.cjs +155 -0
  132. package/dist/UrologyPathwayWidget-TXZQNGP4.cjs.map +1 -0
  133. package/dist/UrologySmartHistoryWidget-53NATEO3.cjs +471 -0
  134. package/dist/UrologySmartHistoryWidget-53NATEO3.cjs.map +1 -0
  135. package/dist/UrologySmartHistoryWidget-PBU4QXQJ.mjs +469 -0
  136. package/dist/UrologySmartHistoryWidget-PBU4QXQJ.mjs.map +1 -0
  137. package/dist/VitalsWidget-BRFUKGNO.mjs +187 -0
  138. package/dist/VitalsWidget-BRFUKGNO.mjs.map +1 -0
  139. package/dist/VitalsWidget-PDCYXNBM.cjs +208 -0
  140. package/dist/VitalsWidget-PDCYXNBM.cjs.map +1 -0
  141. package/dist/chunk-3KRDT7TX.mjs +137 -0
  142. package/dist/chunk-3KRDT7TX.mjs.map +1 -0
  143. package/dist/chunk-4BAKQIPJ.mjs +27 -0
  144. package/dist/chunk-4BAKQIPJ.mjs.map +1 -0
  145. package/dist/chunk-4KSZUIJE.cjs +143 -0
  146. package/dist/chunk-4KSZUIJE.cjs.map +1 -0
  147. package/dist/chunk-4PMNVBJD.mjs +121 -0
  148. package/dist/chunk-4PMNVBJD.mjs.map +1 -0
  149. package/dist/chunk-5E3APMY6.cjs +54 -0
  150. package/dist/chunk-5E3APMY6.cjs.map +1 -0
  151. package/dist/chunk-5I2RC47Y.mjs +75 -0
  152. package/dist/chunk-5I2RC47Y.mjs.map +1 -0
  153. package/dist/chunk-6YX37XBM.cjs +32 -0
  154. package/dist/chunk-6YX37XBM.cjs.map +1 -0
  155. package/dist/chunk-7L2JOWGA.mjs +30 -0
  156. package/dist/chunk-7L2JOWGA.mjs.map +1 -0
  157. package/dist/chunk-AIZ3XYEZ.cjs +551 -0
  158. package/dist/chunk-AIZ3XYEZ.cjs.map +1 -0
  159. package/dist/chunk-AZHTIUOL.mjs +116 -0
  160. package/dist/chunk-AZHTIUOL.mjs.map +1 -0
  161. package/dist/chunk-AZSAPO2V.cjs +174 -0
  162. package/dist/chunk-AZSAPO2V.cjs.map +1 -0
  163. package/dist/chunk-B3GBIAHZ.mjs +285 -0
  164. package/dist/chunk-B3GBIAHZ.mjs.map +1 -0
  165. package/dist/chunk-BMNY7F6H.mjs +148 -0
  166. package/dist/chunk-BMNY7F6H.mjs.map +1 -0
  167. package/dist/chunk-BOBX45NY.cjs +77 -0
  168. package/dist/chunk-BOBX45NY.cjs.map +1 -0
  169. package/dist/chunk-BU4ZEAAP.mjs +102 -0
  170. package/dist/chunk-BU4ZEAAP.mjs.map +1 -0
  171. package/dist/chunk-DZYV47QC.mjs +54 -0
  172. package/dist/chunk-DZYV47QC.mjs.map +1 -0
  173. package/dist/chunk-E7WUDHSA.cjs +127 -0
  174. package/dist/chunk-E7WUDHSA.cjs.map +1 -0
  175. package/dist/chunk-FHHISVCH.cjs +13 -0
  176. package/dist/chunk-FHHISVCH.cjs.map +1 -0
  177. package/dist/chunk-GNZWSVTB.mjs +29 -0
  178. package/dist/chunk-GNZWSVTB.mjs.map +1 -0
  179. package/dist/chunk-GPU5P3FB.cjs +236 -0
  180. package/dist/chunk-GPU5P3FB.cjs.map +1 -0
  181. package/dist/chunk-GXXWMHAA.mjs +49 -0
  182. package/dist/chunk-GXXWMHAA.mjs.map +1 -0
  183. package/dist/chunk-GZPCYSJK.mjs +104 -0
  184. package/dist/chunk-GZPCYSJK.mjs.map +1 -0
  185. package/dist/chunk-HEFZA2AH.mjs +22 -0
  186. package/dist/chunk-HEFZA2AH.mjs.map +1 -0
  187. package/dist/chunk-I4AV6BQF.mjs +10 -0
  188. package/dist/chunk-I4AV6BQF.mjs.map +1 -0
  189. package/dist/chunk-I7TJVWYV.cjs +73 -0
  190. package/dist/chunk-I7TJVWYV.cjs.map +1 -0
  191. package/dist/chunk-IFMQKLNW.mjs +39 -0
  192. package/dist/chunk-IFMQKLNW.mjs.map +1 -0
  193. package/dist/chunk-IFSKLIS2.cjs +12 -0
  194. package/dist/chunk-IFSKLIS2.cjs.map +1 -0
  195. package/dist/chunk-IKAKE7TR.mjs +527 -0
  196. package/dist/chunk-IKAKE7TR.mjs.map +1 -0
  197. package/dist/chunk-JE6VXRWW.cjs +86 -0
  198. package/dist/chunk-JE6VXRWW.cjs.map +1 -0
  199. package/dist/chunk-JMGUUFOJ.cjs +45 -0
  200. package/dist/chunk-JMGUUFOJ.cjs.map +1 -0
  201. package/dist/chunk-KJA5BLGX.cjs +31 -0
  202. package/dist/chunk-KJA5BLGX.cjs.map +1 -0
  203. package/dist/chunk-KMJOTMUQ.cjs +109 -0
  204. package/dist/chunk-KMJOTMUQ.cjs.map +1 -0
  205. package/dist/chunk-L4CIIT4U.cjs +388 -0
  206. package/dist/chunk-L4CIIT4U.cjs.map +1 -0
  207. package/dist/chunk-LBWB7MYU.cjs +287 -0
  208. package/dist/chunk-LBWB7MYU.cjs.map +1 -0
  209. package/dist/chunk-LGGOBIEA.mjs +61 -0
  210. package/dist/chunk-LGGOBIEA.mjs.map +1 -0
  211. package/dist/chunk-LQYWMYEC.mjs +28 -0
  212. package/dist/chunk-LQYWMYEC.mjs.map +1 -0
  213. package/dist/chunk-MQ2JV7HL.cjs +140 -0
  214. package/dist/chunk-MQ2JV7HL.cjs.map +1 -0
  215. package/dist/chunk-N4L76SHJ.cjs +65 -0
  216. package/dist/chunk-N4L76SHJ.cjs.map +1 -0
  217. package/dist/chunk-O3VQBPEW.cjs +72 -0
  218. package/dist/chunk-O3VQBPEW.cjs.map +1 -0
  219. package/dist/chunk-P62377LB.cjs +27 -0
  220. package/dist/chunk-P62377LB.cjs.map +1 -0
  221. package/dist/chunk-PHADAQSH.cjs +49 -0
  222. package/dist/chunk-PHADAQSH.cjs.map +1 -0
  223. package/dist/chunk-PZBJYPWW.cjs +52 -0
  224. package/dist/chunk-PZBJYPWW.cjs.map +1 -0
  225. package/dist/chunk-QKJ7BQSR.cjs +538 -0
  226. package/dist/chunk-QKJ7BQSR.cjs.map +1 -0
  227. package/dist/chunk-QS6WG2XJ.cjs +56 -0
  228. package/dist/chunk-QS6WG2XJ.cjs.map +1 -0
  229. package/dist/chunk-S7EMPE2D.cjs +104 -0
  230. package/dist/chunk-S7EMPE2D.cjs.map +1 -0
  231. package/dist/chunk-SCMXLRX5.mjs +42 -0
  232. package/dist/chunk-SCMXLRX5.mjs.map +1 -0
  233. package/dist/chunk-SHQHDSA4.cjs +1959 -0
  234. package/dist/chunk-SHQHDSA4.cjs.map +1 -0
  235. package/dist/chunk-TJHG5WHX.cjs +47 -0
  236. package/dist/chunk-TJHG5WHX.cjs.map +1 -0
  237. package/dist/chunk-UGGUIXUS.cjs +41 -0
  238. package/dist/chunk-UGGUIXUS.cjs.map +1 -0
  239. package/dist/chunk-ULMK3TUI.mjs +69 -0
  240. package/dist/chunk-ULMK3TUI.mjs.map +1 -0
  241. package/dist/chunk-UULLSS4O.mjs +82 -0
  242. package/dist/chunk-UULLSS4O.mjs.map +1 -0
  243. package/dist/chunk-VNFBUAZD.mjs +25 -0
  244. package/dist/chunk-VNFBUAZD.mjs.map +1 -0
  245. package/dist/chunk-VPU66PI6.mjs +11 -0
  246. package/dist/chunk-VPU66PI6.mjs.map +1 -0
  247. package/dist/chunk-VZT5YNCD.mjs +228 -0
  248. package/dist/chunk-VZT5YNCD.mjs.map +1 -0
  249. package/dist/chunk-WYVXXEZI.mjs +46 -0
  250. package/dist/chunk-WYVXXEZI.mjs.map +1 -0
  251. package/dist/chunk-XDUVO3IZ.mjs +547 -0
  252. package/dist/chunk-XDUVO3IZ.mjs.map +1 -0
  253. package/dist/chunk-Y7TIWH4I.mjs +25 -0
  254. package/dist/chunk-Y7TIWH4I.mjs.map +1 -0
  255. package/dist/chunk-YEFM2ERQ.cjs +143 -0
  256. package/dist/chunk-YEFM2ERQ.cjs.map +1 -0
  257. package/dist/chunk-YHNI5NIX.mjs +361 -0
  258. package/dist/chunk-YHNI5NIX.mjs.map +1 -0
  259. package/dist/chunk-ZTT5XJR7.mjs +1921 -0
  260. package/dist/chunk-ZTT5XJR7.mjs.map +1 -0
  261. package/dist/index.cjs +2091 -14564
  262. package/dist/index.cjs.map +1 -1
  263. package/dist/index.d.cts +62 -767
  264. package/dist/index.d.ts +62 -767
  265. package/dist/index.mjs +1873 -14394
  266. package/dist/index.mjs.map +1 -1
  267. package/dist/read-only-table.cjs +15 -0
  268. package/dist/read-only-table.cjs.map +1 -0
  269. package/dist/read-only-table.d.cts +10 -0
  270. package/dist/read-only-table.d.ts +10 -0
  271. package/dist/read-only-table.mjs +6 -0
  272. package/dist/read-only-table.mjs.map +1 -0
  273. package/dist/rich-text.cjs +24 -0
  274. package/dist/rich-text.cjs.map +1 -0
  275. package/dist/rich-text.d.cts +8 -0
  276. package/dist/rich-text.d.ts +8 -0
  277. package/dist/rich-text.mjs +11 -0
  278. package/dist/rich-text.mjs.map +1 -0
  279. package/dist/richTextClassName--8wkuHkW.d.cts +10 -0
  280. package/dist/richTextClassName--8wkuHkW.d.ts +10 -0
  281. package/dist/smart.cjs +23 -0
  282. package/dist/smart.cjs.map +1 -0
  283. package/dist/smart.d.cts +23 -0
  284. package/dist/smart.d.ts +23 -0
  285. package/dist/smart.mjs +10 -0
  286. package/dist/smart.mjs.map +1 -0
  287. package/dist/types-CYtJk8H9.d.cts +782 -0
  288. package/dist/types-CYtJk8H9.d.ts +782 -0
  289. package/package.json +20 -2
@@ -0,0 +1,187 @@
1
+ import { useField, useFieldHandlers } from './chunk-ZTT5XJR7.mjs';
2
+ import { cn } from './chunk-VPU66PI6.mjs';
3
+ import * as React from 'react';
4
+ import { useState, useCallback, useEffect } from 'react';
5
+ import { RefreshCw } from 'lucide-react';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+
8
+ var Spinner = React.forwardRef(
9
+ ({ className, size = "md", ...props }, ref) => {
10
+ const sizeClasses = {
11
+ sm: "h-4 w-4 border-2",
12
+ md: "h-6 w-6 border-2",
13
+ lg: "h-8 w-8 border-3"
14
+ };
15
+ return /* @__PURE__ */ jsx(
16
+ "div",
17
+ {
18
+ ref,
19
+ className: cn(
20
+ "animate-spin rounded-full border-primary border-t-transparent",
21
+ sizeClasses[size],
22
+ className
23
+ ),
24
+ ...props,
25
+ children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading..." })
26
+ }
27
+ );
28
+ }
29
+ );
30
+ Spinner.displayName = "Spinner";
31
+ function buildItems(data) {
32
+ const items = [];
33
+ const hasBP = data.blood_pressure_systolic != null || data.blood_pressure_diastolic != null;
34
+ if (hasBP) {
35
+ const sys = data.blood_pressure_systolic ?? "\u2013";
36
+ const dia = data.blood_pressure_diastolic ?? "\u2013";
37
+ items.push({ label: "BP", value: `${sys}/${dia}` });
38
+ }
39
+ if (data.heart_rate != null)
40
+ items.push({ label: "Heart Rate", value: `${data.heart_rate} bpm` });
41
+ if (data.respiratory_rate != null)
42
+ items.push({ label: "Resp. Rate", value: `${data.respiratory_rate}/min` });
43
+ if (data.oxygen_saturation != null)
44
+ items.push({ label: "SpO\u2082", value: `${data.oxygen_saturation}%` });
45
+ if (data.temperature != null)
46
+ items.push({ label: "Temp", value: `${data.temperature} \xB0F` });
47
+ if (data.height != null)
48
+ items.push({ label: "Height", value: `${data.height} cm` });
49
+ if (data.weight != null)
50
+ items.push({ label: "Weight", value: `${data.weight} kg` });
51
+ if (data.bmi != null)
52
+ items.push({ label: "BMI", value: `${data.bmi}` });
53
+ if (data.blood_sugar != null)
54
+ items.push({ label: "Blood Sugar", value: `${data.blood_sugar} mg/dL` });
55
+ if (data.circumference_of_head_in_cms != null)
56
+ items.push({ label: "Head Circ.", value: `${data.circumference_of_head_in_cms} cm` });
57
+ if (data.circumference_of_waist_in_cms != null)
58
+ items.push({ label: "Waist Circ.", value: `${data.circumference_of_waist_in_cms} cm` });
59
+ return items;
60
+ }
61
+ function formatRecordedAt(iso) {
62
+ if (!iso) return "";
63
+ try {
64
+ return new Date(iso).toLocaleString(void 0, {
65
+ day: "2-digit",
66
+ month: "short",
67
+ year: "numeric",
68
+ hour: "2-digit",
69
+ minute: "2-digit"
70
+ });
71
+ } catch {
72
+ return iso;
73
+ }
74
+ }
75
+ function VitalChip({ label, value }) {
76
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0 rounded-md min-w-fit px-1.5", children: [
77
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-sm text-gray-500 uppercase tracking-wide leading-none", children: label }),
78
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-900 leading-tight", children: value })
79
+ ] });
80
+ }
81
+ var Vitals = ({
82
+ data,
83
+ loading = false,
84
+ error = null,
85
+ onRefresh,
86
+ className
87
+ }) => {
88
+ const items = data ? buildItems(data) : [];
89
+ const hasItems = items.length > 0;
90
+ const recordedAt = data?.recorded_at ? formatRecordedAt(data.recorded_at) : null;
91
+ const notes = data?.notes?.trim() || null;
92
+ return /* @__PURE__ */ jsx(
93
+ "div",
94
+ {
95
+ className: cn(
96
+ "rounded-md overflow-hidden border border-[#D0D0D0] bg-white px-2 py-2",
97
+ className
98
+ ),
99
+ children: loading && !hasItems ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 py-1", children: [
100
+ /* @__PURE__ */ jsx(Spinner, { size: "sm" }),
101
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Loading vitals\u2026" })
102
+ ] }) : error ? /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500 py-1", children: error }) : hasItems ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
103
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-3 gap-y-1", children: [
104
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-x-2 gap-y-0.5", children: items.map((item) => /* @__PURE__ */ jsx(VitalChip, { ...item }, item.label)) }),
105
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end gap-0.5 shrink-0", children: [
106
+ recordedAt && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-slate-500", children: recordedAt }),
107
+ onRefresh && /* @__PURE__ */ jsxs(
108
+ "button",
109
+ {
110
+ type: "button",
111
+ onClick: onRefresh,
112
+ disabled: loading,
113
+ className: cn(
114
+ "flex items-center gap-0.5 text-[10px] font-medium text-slate-600",
115
+ "hover:text-slate-900 transition-colors disabled:opacity-50 cursor-pointer"
116
+ ),
117
+ "aria-label": "Refresh vitals",
118
+ children: [
119
+ /* @__PURE__ */ jsx(RefreshCw, { className: cn("h-2.5 w-2.5", loading && "animate-spin") }),
120
+ /* @__PURE__ */ jsx("span", { children: "Refresh" })
121
+ ]
122
+ }
123
+ )
124
+ ] })
125
+ ] }),
126
+ notes && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-600 pt-1.5 mt-0.5", children: notes })
127
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-1", children: [
128
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "No vitals recorded." }),
129
+ onRefresh && /* @__PURE__ */ jsxs(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: onRefresh,
134
+ disabled: loading,
135
+ className: cn(
136
+ "flex items-center gap-0.5 text-[10px] font-medium text-slate-600",
137
+ "hover:text-slate-900 transition-colors disabled:opacity-50 shrink-0"
138
+ ),
139
+ "aria-label": "Refresh vitals",
140
+ children: [
141
+ /* @__PURE__ */ jsx(RefreshCw, { className: cn("h-2.5 w-2.5", loading && "animate-spin") }),
142
+ /* @__PURE__ */ jsx("span", { children: "Refresh" })
143
+ ]
144
+ }
145
+ )
146
+ ] })
147
+ }
148
+ );
149
+ };
150
+ var VitalsWidget = ({ fieldId }) => {
151
+ const { value, setValue, fieldDef } = useField(fieldId);
152
+ const handlers = useFieldHandlers(fieldId);
153
+ const [loading, setLoading] = useState(false);
154
+ const [error, setError] = useState(null);
155
+ console.log("[VitalsWidget] fieldId:", fieldId, "| onFetch present:", !!handlers.onFetch, "| value:", value);
156
+ const fetchVitals = useCallback(async () => {
157
+ if (!handlers.onFetch) return;
158
+ setLoading(true);
159
+ setError(null);
160
+ try {
161
+ const data = await handlers.onFetch();
162
+ console.log("[VitalsWidget] fetched data:", data);
163
+ setValue(data);
164
+ } catch {
165
+ setError("Failed to load vitals. Please try again.");
166
+ } finally {
167
+ setLoading(false);
168
+ }
169
+ }, [handlers, setValue]);
170
+ useEffect(() => {
171
+ fetchVitals();
172
+ }, []);
173
+ return /* @__PURE__ */ jsx(
174
+ Vitals,
175
+ {
176
+ label: fieldDef?.label ?? "Vitals",
177
+ data: value ?? null,
178
+ loading,
179
+ error,
180
+ onRefresh: handlers.onFetch ? fetchVitals : void 0
181
+ }
182
+ );
183
+ };
184
+
185
+ export { VitalsWidget };
186
+ //# sourceMappingURL=VitalsWidget-BRFUKGNO.mjs.map
187
+ //# sourceMappingURL=VitalsWidget-BRFUKGNO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/shadcn/spinner.tsx","../src/ui/widgets/Vitals.tsx","../src/ui/widgets/VitalsWidget.tsx"],"names":["jsx"],"mappings":"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","file":"VitalsWidget-BRFUKGNO.mjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../core/utils\";\n\nexport interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: \"sm\" | \"md\" | \"lg\";\n}\n\nconst Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(\n ({ className, size = \"md\", ...props }, ref) => {\n const sizeClasses = {\n sm: \"h-4 w-4 border-2\",\n md: \"h-6 w-6 border-2\",\n lg: \"h-8 w-8 border-3\",\n };\n\n return (\n <div\n ref={ref}\n className={cn(\n \"animate-spin rounded-full border-primary border-t-transparent\",\n sizeClasses[size],\n className\n )}\n {...props}\n >\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n }\n);\nSpinner.displayName = \"Spinner\";\n\nexport { Spinner };\n","import React from 'react';\nimport { RefreshCw } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Spinner } from '../shadcn/spinner';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type VitalsData = {\n temperature?: number | null;\n height?: number | null;\n weight?: number | null;\n bmi?: number | null;\n blood_sugar?: number | null;\n notes?: string | null;\n circumference_of_head_in_cms?: number | null;\n circumference_of_waist_in_cms?: number | null;\n blood_pressure_systolic?: number | null;\n blood_pressure_diastolic?: number | null;\n heart_rate?: number | null;\n respiratory_rate?: number | null;\n oxygen_saturation?: number | null;\n recorded_at?: string | null;\n};\n\nexport type VitalsProps = {\n label?: string;\n data: VitalsData | null;\n loading?: boolean;\n error?: string | null;\n onRefresh?: () => void;\n className?: string;\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\ntype VitalItem = { label: string; value: string };\n\nfunction buildItems(data: VitalsData): VitalItem[] {\n const items: VitalItem[] = [];\n\n const hasBP =\n data.blood_pressure_systolic != null || data.blood_pressure_diastolic != null;\n if (hasBP) {\n const sys = data.blood_pressure_systolic ?? '–';\n const dia = data.blood_pressure_diastolic ?? '–';\n items.push({ label: 'BP', value: `${sys}/${dia}` });\n }\n\n if (data.heart_rate != null)\n items.push({ label: 'Heart Rate', value: `${data.heart_rate} bpm` });\n\n if (data.respiratory_rate != null)\n items.push({ label: 'Resp. Rate', value: `${data.respiratory_rate}/min` });\n\n if (data.oxygen_saturation != null)\n items.push({ label: 'SpO\\u2082', value: `${data.oxygen_saturation}%` });\n\n if (data.temperature != null)\n items.push({ label: 'Temp', value: `${data.temperature} \\u00b0F` });\n\n if (data.height != null)\n items.push({ label: 'Height', value: `${data.height} cm` });\n\n if (data.weight != null)\n items.push({ label: 'Weight', value: `${data.weight} kg` });\n\n if (data.bmi != null)\n items.push({ label: 'BMI', value: `${data.bmi}` });\n\n if (data.blood_sugar != null)\n items.push({ label: 'Blood Sugar', value: `${data.blood_sugar} mg/dL` });\n\n if (data.circumference_of_head_in_cms != null)\n items.push({ label: 'Head Circ.', value: `${data.circumference_of_head_in_cms} cm` });\n\n if (data.circumference_of_waist_in_cms != null)\n items.push({ label: 'Waist Circ.', value: `${data.circumference_of_waist_in_cms} cm` });\n\n return items;\n}\n\nfunction formatRecordedAt(iso: string | null | undefined): string {\n if (!iso) return '';\n try {\n return new Date(iso).toLocaleString(undefined, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return iso;\n }\n}\n\n// ─── Vital chip ───────────────────────────────────────────────────────────────\n\nfunction VitalChip({ label, value }: VitalItem) {\n return (\n <div className=\"flex flex-col gap-0 rounded-md min-w-fit px-1.5\">\n <span className=\"text-[10px] font-sm text-gray-500 uppercase tracking-wide leading-none\">\n {label}\n </span>\n <span className=\"text-xs text-gray-900 leading-tight\">{value}</span>\n </div>\n );\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const Vitals: React.FC<VitalsProps> = ({\n data,\n loading = false,\n error = null,\n onRefresh,\n className,\n}) => {\n const items = data ? buildItems(data) : [];\n const hasItems = items.length > 0;\n const recordedAt = data?.recorded_at ? formatRecordedAt(data.recorded_at) : null;\n const notes = data?.notes?.trim() || null;\n\n return (\n <div\n className={cn(\n 'rounded-md overflow-hidden border border-[#D0D0D0] bg-white px-2 py-2',\n className\n )}\n >\n {loading && !hasItems ? (\n <div className=\"flex items-center gap-1.5 py-1\">\n <Spinner size=\"sm\" />\n <span className=\"text-xs text-muted-foreground\">Loading vitals…</span>\n </div>\n ) : error ? (\n <p className=\"text-xs text-red-500 py-1\">{error}</p>\n ) : hasItems ? (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex flex-wrap items-center justify-between gap-x-3 gap-y-1\">\n <div className=\"flex flex-wrap gap-x-2 gap-y-0.5\">\n {items.map(item => (\n <VitalChip key={item.label} {...item} />\n ))}\n </div>\n <div className=\"flex flex-col items-end gap-0.5 shrink-0\">\n {recordedAt && (\n <span className=\"text-[10px] text-slate-500\">{recordedAt}</span>\n )}\n {onRefresh && (\n <button\n type=\"button\"\n onClick={onRefresh}\n disabled={loading}\n className={cn(\n 'flex items-center gap-0.5 text-[10px] font-medium text-slate-600',\n 'hover:text-slate-900 transition-colors disabled:opacity-50 cursor-pointer'\n )}\n aria-label=\"Refresh vitals\"\n >\n <RefreshCw className={cn('h-2.5 w-2.5', loading && 'animate-spin')} />\n <span>Refresh</span>\n </button>\n )}\n </div>\n </div>\n {notes && (\n <p className=\"text-xs text-gray-600 pt-1.5 mt-0.5\">\n {notes}\n </p>\n )}\n </div>\n ) : (\n <div className=\"flex items-center justify-between gap-2 py-1\">\n <p className=\"text-xs text-muted-foreground\">No vitals recorded.</p>\n {onRefresh && (\n <button\n type=\"button\"\n onClick={onRefresh}\n disabled={loading}\n className={cn(\n 'flex items-center gap-0.5 text-[10px] font-medium text-slate-600',\n 'hover:text-slate-900 transition-colors disabled:opacity-50 shrink-0'\n )}\n aria-label=\"Refresh vitals\"\n >\n <RefreshCw className={cn('h-2.5 w-2.5', loading && 'animate-spin')} />\n <span>Refresh</span>\n </button>\n )}\n </div>\n )}\n </div>\n );\n};\n","import React, { useCallback, useEffect, useState } from 'react';\nimport { useField } from '../../react/useField';\nimport { useFieldHandlers } from '../../react/FormProvider';\nimport { Vitals, type VitalsData } from './Vitals';\n\nexport const VitalsWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { value, setValue, fieldDef } = useField(fieldId);\n const handlers = useFieldHandlers(fieldId);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n console.log('[VitalsWidget] fieldId:', fieldId, '| onFetch present:', !!handlers.onFetch, '| value:', value);\n\n const fetchVitals = useCallback(async () => {\n if (!handlers.onFetch) return;\n setLoading(true);\n setError(null);\n try {\n const data = await handlers.onFetch();\n console.log('[VitalsWidget] fetched data:', data);\n setValue(data);\n } catch {\n setError('Failed to load vitals. Please try again.');\n } finally {\n setLoading(false);\n }\n }, [handlers, setValue]);\n\n // Fetch once on mount if a handler is provided\n useEffect(() => {\n fetchVitals();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <Vitals\n label={fieldDef?.label ?? 'Vitals'}\n data={(value as VitalsData | null) ?? null}\n loading={loading}\n error={error}\n onRefresh={handlers.onFetch ? fetchVitals : undefined}\n />\n );\n};\n"]}
@@ -0,0 +1,208 @@
1
+ 'use strict';
2
+
3
+ var chunkSHQHDSA4_cjs = require('./chunk-SHQHDSA4.cjs');
4
+ var chunkFHHISVCH_cjs = require('./chunk-FHHISVCH.cjs');
5
+ var React = require('react');
6
+ var lucideReact = require('lucide-react');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+
29
+ var Spinner = React__namespace.forwardRef(
30
+ ({ className, size = "md", ...props }, ref) => {
31
+ const sizeClasses = {
32
+ sm: "h-4 w-4 border-2",
33
+ md: "h-6 w-6 border-2",
34
+ lg: "h-8 w-8 border-3"
35
+ };
36
+ return /* @__PURE__ */ jsxRuntime.jsx(
37
+ "div",
38
+ {
39
+ ref,
40
+ className: chunkFHHISVCH_cjs.cn(
41
+ "animate-spin rounded-full border-primary border-t-transparent",
42
+ sizeClasses[size],
43
+ className
44
+ ),
45
+ ...props,
46
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading..." })
47
+ }
48
+ );
49
+ }
50
+ );
51
+ Spinner.displayName = "Spinner";
52
+ function buildItems(data) {
53
+ const items = [];
54
+ const hasBP = data.blood_pressure_systolic != null || data.blood_pressure_diastolic != null;
55
+ if (hasBP) {
56
+ const sys = data.blood_pressure_systolic ?? "\u2013";
57
+ const dia = data.blood_pressure_diastolic ?? "\u2013";
58
+ items.push({ label: "BP", value: `${sys}/${dia}` });
59
+ }
60
+ if (data.heart_rate != null)
61
+ items.push({ label: "Heart Rate", value: `${data.heart_rate} bpm` });
62
+ if (data.respiratory_rate != null)
63
+ items.push({ label: "Resp. Rate", value: `${data.respiratory_rate}/min` });
64
+ if (data.oxygen_saturation != null)
65
+ items.push({ label: "SpO\u2082", value: `${data.oxygen_saturation}%` });
66
+ if (data.temperature != null)
67
+ items.push({ label: "Temp", value: `${data.temperature} \xB0F` });
68
+ if (data.height != null)
69
+ items.push({ label: "Height", value: `${data.height} cm` });
70
+ if (data.weight != null)
71
+ items.push({ label: "Weight", value: `${data.weight} kg` });
72
+ if (data.bmi != null)
73
+ items.push({ label: "BMI", value: `${data.bmi}` });
74
+ if (data.blood_sugar != null)
75
+ items.push({ label: "Blood Sugar", value: `${data.blood_sugar} mg/dL` });
76
+ if (data.circumference_of_head_in_cms != null)
77
+ items.push({ label: "Head Circ.", value: `${data.circumference_of_head_in_cms} cm` });
78
+ if (data.circumference_of_waist_in_cms != null)
79
+ items.push({ label: "Waist Circ.", value: `${data.circumference_of_waist_in_cms} cm` });
80
+ return items;
81
+ }
82
+ function formatRecordedAt(iso) {
83
+ if (!iso) return "";
84
+ try {
85
+ return new Date(iso).toLocaleString(void 0, {
86
+ day: "2-digit",
87
+ month: "short",
88
+ year: "numeric",
89
+ hour: "2-digit",
90
+ minute: "2-digit"
91
+ });
92
+ } catch {
93
+ return iso;
94
+ }
95
+ }
96
+ function VitalChip({ label, value }) {
97
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0 rounded-md min-w-fit px-1.5", children: [
98
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-sm text-gray-500 uppercase tracking-wide leading-none", children: label }),
99
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-900 leading-tight", children: value })
100
+ ] });
101
+ }
102
+ var Vitals = ({
103
+ data,
104
+ loading = false,
105
+ error = null,
106
+ onRefresh,
107
+ className
108
+ }) => {
109
+ const items = data ? buildItems(data) : [];
110
+ const hasItems = items.length > 0;
111
+ const recordedAt = data?.recorded_at ? formatRecordedAt(data.recorded_at) : null;
112
+ const notes = data?.notes?.trim() || null;
113
+ return /* @__PURE__ */ jsxRuntime.jsx(
114
+ "div",
115
+ {
116
+ className: chunkFHHISVCH_cjs.cn(
117
+ "rounded-md overflow-hidden border border-[#D0D0D0] bg-white px-2 py-2",
118
+ className
119
+ ),
120
+ children: loading && !hasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 py-1", children: [
121
+ /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm" }),
122
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Loading vitals\u2026" })
123
+ ] }) : error ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500 py-1", children: error }) : hasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
124
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-3 gap-y-1", children: [
125
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-x-2 gap-y-0.5", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(VitalChip, { ...item }, item.label)) }),
126
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end gap-0.5 shrink-0", children: [
127
+ recordedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-slate-500", children: recordedAt }),
128
+ onRefresh && /* @__PURE__ */ jsxRuntime.jsxs(
129
+ "button",
130
+ {
131
+ type: "button",
132
+ onClick: onRefresh,
133
+ disabled: loading,
134
+ className: chunkFHHISVCH_cjs.cn(
135
+ "flex items-center gap-0.5 text-[10px] font-medium text-slate-600",
136
+ "hover:text-slate-900 transition-colors disabled:opacity-50 cursor-pointer"
137
+ ),
138
+ "aria-label": "Refresh vitals",
139
+ children: [
140
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: chunkFHHISVCH_cjs.cn("h-2.5 w-2.5", loading && "animate-spin") }),
141
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Refresh" })
142
+ ]
143
+ }
144
+ )
145
+ ] })
146
+ ] }),
147
+ notes && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-600 pt-1.5 mt-0.5", children: notes })
148
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 py-1", children: [
149
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "No vitals recorded." }),
150
+ onRefresh && /* @__PURE__ */ jsxRuntime.jsxs(
151
+ "button",
152
+ {
153
+ type: "button",
154
+ onClick: onRefresh,
155
+ disabled: loading,
156
+ className: chunkFHHISVCH_cjs.cn(
157
+ "flex items-center gap-0.5 text-[10px] font-medium text-slate-600",
158
+ "hover:text-slate-900 transition-colors disabled:opacity-50 shrink-0"
159
+ ),
160
+ "aria-label": "Refresh vitals",
161
+ children: [
162
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: chunkFHHISVCH_cjs.cn("h-2.5 w-2.5", loading && "animate-spin") }),
163
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Refresh" })
164
+ ]
165
+ }
166
+ )
167
+ ] })
168
+ }
169
+ );
170
+ };
171
+ var VitalsWidget = ({ fieldId }) => {
172
+ const { value, setValue, fieldDef } = chunkSHQHDSA4_cjs.useField(fieldId);
173
+ const handlers = chunkSHQHDSA4_cjs.useFieldHandlers(fieldId);
174
+ const [loading, setLoading] = React.useState(false);
175
+ const [error, setError] = React.useState(null);
176
+ console.log("[VitalsWidget] fieldId:", fieldId, "| onFetch present:", !!handlers.onFetch, "| value:", value);
177
+ const fetchVitals = React.useCallback(async () => {
178
+ if (!handlers.onFetch) return;
179
+ setLoading(true);
180
+ setError(null);
181
+ try {
182
+ const data = await handlers.onFetch();
183
+ console.log("[VitalsWidget] fetched data:", data);
184
+ setValue(data);
185
+ } catch {
186
+ setError("Failed to load vitals. Please try again.");
187
+ } finally {
188
+ setLoading(false);
189
+ }
190
+ }, [handlers, setValue]);
191
+ React.useEffect(() => {
192
+ fetchVitals();
193
+ }, []);
194
+ return /* @__PURE__ */ jsxRuntime.jsx(
195
+ Vitals,
196
+ {
197
+ label: fieldDef?.label ?? "Vitals",
198
+ data: value ?? null,
199
+ loading,
200
+ error,
201
+ onRefresh: handlers.onFetch ? fetchVitals : void 0
202
+ }
203
+ );
204
+ };
205
+
206
+ exports.VitalsWidget = VitalsWidget;
207
+ //# sourceMappingURL=VitalsWidget-PDCYXNBM.cjs.map
208
+ //# sourceMappingURL=VitalsWidget-PDCYXNBM.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/shadcn/spinner.tsx","../src/ui/widgets/Vitals.tsx","../src/ui/widgets/VitalsWidget.tsx"],"names":["React","jsx","cn","jsxs","RefreshCw","useField","useFieldHandlers","useState","useCallback","useEffect"],"mappings":"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","file":"VitalsWidget-PDCYXNBM.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../core/utils\";\n\nexport interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: \"sm\" | \"md\" | \"lg\";\n}\n\nconst Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(\n ({ className, size = \"md\", ...props }, ref) => {\n const sizeClasses = {\n sm: \"h-4 w-4 border-2\",\n md: \"h-6 w-6 border-2\",\n lg: \"h-8 w-8 border-3\",\n };\n\n return (\n <div\n ref={ref}\n className={cn(\n \"animate-spin rounded-full border-primary border-t-transparent\",\n sizeClasses[size],\n className\n )}\n {...props}\n >\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n }\n);\nSpinner.displayName = \"Spinner\";\n\nexport { Spinner };\n","import React from 'react';\nimport { RefreshCw } from 'lucide-react';\nimport { cn } from '../../core/utils';\nimport { Spinner } from '../shadcn/spinner';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type VitalsData = {\n temperature?: number | null;\n height?: number | null;\n weight?: number | null;\n bmi?: number | null;\n blood_sugar?: number | null;\n notes?: string | null;\n circumference_of_head_in_cms?: number | null;\n circumference_of_waist_in_cms?: number | null;\n blood_pressure_systolic?: number | null;\n blood_pressure_diastolic?: number | null;\n heart_rate?: number | null;\n respiratory_rate?: number | null;\n oxygen_saturation?: number | null;\n recorded_at?: string | null;\n};\n\nexport type VitalsProps = {\n label?: string;\n data: VitalsData | null;\n loading?: boolean;\n error?: string | null;\n onRefresh?: () => void;\n className?: string;\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\ntype VitalItem = { label: string; value: string };\n\nfunction buildItems(data: VitalsData): VitalItem[] {\n const items: VitalItem[] = [];\n\n const hasBP =\n data.blood_pressure_systolic != null || data.blood_pressure_diastolic != null;\n if (hasBP) {\n const sys = data.blood_pressure_systolic ?? '–';\n const dia = data.blood_pressure_diastolic ?? '–';\n items.push({ label: 'BP', value: `${sys}/${dia}` });\n }\n\n if (data.heart_rate != null)\n items.push({ label: 'Heart Rate', value: `${data.heart_rate} bpm` });\n\n if (data.respiratory_rate != null)\n items.push({ label: 'Resp. Rate', value: `${data.respiratory_rate}/min` });\n\n if (data.oxygen_saturation != null)\n items.push({ label: 'SpO\\u2082', value: `${data.oxygen_saturation}%` });\n\n if (data.temperature != null)\n items.push({ label: 'Temp', value: `${data.temperature} \\u00b0F` });\n\n if (data.height != null)\n items.push({ label: 'Height', value: `${data.height} cm` });\n\n if (data.weight != null)\n items.push({ label: 'Weight', value: `${data.weight} kg` });\n\n if (data.bmi != null)\n items.push({ label: 'BMI', value: `${data.bmi}` });\n\n if (data.blood_sugar != null)\n items.push({ label: 'Blood Sugar', value: `${data.blood_sugar} mg/dL` });\n\n if (data.circumference_of_head_in_cms != null)\n items.push({ label: 'Head Circ.', value: `${data.circumference_of_head_in_cms} cm` });\n\n if (data.circumference_of_waist_in_cms != null)\n items.push({ label: 'Waist Circ.', value: `${data.circumference_of_waist_in_cms} cm` });\n\n return items;\n}\n\nfunction formatRecordedAt(iso: string | null | undefined): string {\n if (!iso) return '';\n try {\n return new Date(iso).toLocaleString(undefined, {\n day: '2-digit',\n month: 'short',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n } catch {\n return iso;\n }\n}\n\n// ─── Vital chip ───────────────────────────────────────────────────────────────\n\nfunction VitalChip({ label, value }: VitalItem) {\n return (\n <div className=\"flex flex-col gap-0 rounded-md min-w-fit px-1.5\">\n <span className=\"text-[10px] font-sm text-gray-500 uppercase tracking-wide leading-none\">\n {label}\n </span>\n <span className=\"text-xs text-gray-900 leading-tight\">{value}</span>\n </div>\n );\n}\n\n// ─── Main component ───────────────────────────────────────────────────────────\n\nexport const Vitals: React.FC<VitalsProps> = ({\n data,\n loading = false,\n error = null,\n onRefresh,\n className,\n}) => {\n const items = data ? buildItems(data) : [];\n const hasItems = items.length > 0;\n const recordedAt = data?.recorded_at ? formatRecordedAt(data.recorded_at) : null;\n const notes = data?.notes?.trim() || null;\n\n return (\n <div\n className={cn(\n 'rounded-md overflow-hidden border border-[#D0D0D0] bg-white px-2 py-2',\n className\n )}\n >\n {loading && !hasItems ? (\n <div className=\"flex items-center gap-1.5 py-1\">\n <Spinner size=\"sm\" />\n <span className=\"text-xs text-muted-foreground\">Loading vitals…</span>\n </div>\n ) : error ? (\n <p className=\"text-xs text-red-500 py-1\">{error}</p>\n ) : hasItems ? (\n <div className=\"flex flex-col gap-1.5\">\n <div className=\"flex flex-wrap items-center justify-between gap-x-3 gap-y-1\">\n <div className=\"flex flex-wrap gap-x-2 gap-y-0.5\">\n {items.map(item => (\n <VitalChip key={item.label} {...item} />\n ))}\n </div>\n <div className=\"flex flex-col items-end gap-0.5 shrink-0\">\n {recordedAt && (\n <span className=\"text-[10px] text-slate-500\">{recordedAt}</span>\n )}\n {onRefresh && (\n <button\n type=\"button\"\n onClick={onRefresh}\n disabled={loading}\n className={cn(\n 'flex items-center gap-0.5 text-[10px] font-medium text-slate-600',\n 'hover:text-slate-900 transition-colors disabled:opacity-50 cursor-pointer'\n )}\n aria-label=\"Refresh vitals\"\n >\n <RefreshCw className={cn('h-2.5 w-2.5', loading && 'animate-spin')} />\n <span>Refresh</span>\n </button>\n )}\n </div>\n </div>\n {notes && (\n <p className=\"text-xs text-gray-600 pt-1.5 mt-0.5\">\n {notes}\n </p>\n )}\n </div>\n ) : (\n <div className=\"flex items-center justify-between gap-2 py-1\">\n <p className=\"text-xs text-muted-foreground\">No vitals recorded.</p>\n {onRefresh && (\n <button\n type=\"button\"\n onClick={onRefresh}\n disabled={loading}\n className={cn(\n 'flex items-center gap-0.5 text-[10px] font-medium text-slate-600',\n 'hover:text-slate-900 transition-colors disabled:opacity-50 shrink-0'\n )}\n aria-label=\"Refresh vitals\"\n >\n <RefreshCw className={cn('h-2.5 w-2.5', loading && 'animate-spin')} />\n <span>Refresh</span>\n </button>\n )}\n </div>\n )}\n </div>\n );\n};\n","import React, { useCallback, useEffect, useState } from 'react';\nimport { useField } from '../../react/useField';\nimport { useFieldHandlers } from '../../react/FormProvider';\nimport { Vitals, type VitalsData } from './Vitals';\n\nexport const VitalsWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { value, setValue, fieldDef } = useField(fieldId);\n const handlers = useFieldHandlers(fieldId);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n console.log('[VitalsWidget] fieldId:', fieldId, '| onFetch present:', !!handlers.onFetch, '| value:', value);\n\n const fetchVitals = useCallback(async () => {\n if (!handlers.onFetch) return;\n setLoading(true);\n setError(null);\n try {\n const data = await handlers.onFetch();\n console.log('[VitalsWidget] fetched data:', data);\n setValue(data);\n } catch {\n setError('Failed to load vitals. Please try again.');\n } finally {\n setLoading(false);\n }\n }, [handlers, setValue]);\n\n // Fetch once on mount if a handler is provided\n useEffect(() => {\n fetchVitals();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <Vitals\n label={fieldDef?.label ?? 'Vitals'}\n data={(value as VitalsData | null) ?? null}\n loading={loading}\n error={error}\n onRefresh={handlers.onFetch ? fetchVitals : undefined}\n />\n );\n};\n"]}
@@ -0,0 +1,137 @@
1
+ import { fetchOptions } from './chunk-IFMQKLNW.mjs';
2
+ import { Textarea } from './chunk-4BAKQIPJ.mjs';
3
+ import { getThemeConfig } from './chunk-Y7TIWH4I.mjs';
4
+ import { VoiceMicButton } from './chunk-5I2RC47Y.mjs';
5
+ import { isLabelVisible, FieldRequiredIndicator, fieldLabelClass, fieldControlClass, fieldErrorClass, fieldWrapperClass } from './chunk-WYVXXEZI.mjs';
6
+ import { useForm } from './chunk-7L2JOWGA.mjs';
7
+ import { Input } from './chunk-VNFBUAZD.mjs';
8
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-AZHTIUOL.mjs';
9
+ import { useField, useFormStore } from './chunk-ZTT5XJR7.mjs';
10
+ import { Label } from './chunk-HEFZA2AH.mjs';
11
+ import { cn } from './chunk-VPU66PI6.mjs';
12
+ import { useState, useEffect } from 'react';
13
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
14
+
15
+ var TextWidget = ({ fieldId }) => {
16
+ const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
17
+ const { state } = useForm();
18
+ const store = useFormStore();
19
+ const hasVoice = !!(fieldDef?.voice && store.getVoice());
20
+ const showError = !!error && (touched || state.submitAttempted);
21
+ if (!fieldDef) return null;
22
+ const Component = fieldDef.type === "textarea" ? Textarea : Input;
23
+ const isTextarea = fieldDef.type === "textarea";
24
+ const height = isTextarea && "height" in fieldDef ? fieldDef.height : void 0;
25
+ const theme = getThemeConfig(
26
+ isTextarea ? "textarea" : "text",
27
+ fieldDef.theme
28
+ );
29
+ const wrapperClass = theme?.wrapperClassName ?? "space-y-2";
30
+ const labelClass = theme?.labelClassName;
31
+ const inputClass = cn(theme?.inputClassName, showError && "border-red-500");
32
+ const showLabel = isLabelVisible(fieldDef);
33
+ const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
34
+ fieldDef.label,
35
+ " ",
36
+ /* @__PURE__ */ jsx(FieldRequiredIndicator, { fieldDef })
37
+ ] });
38
+ const labelEl = showLabel ? theme ? /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, className: fieldLabelClass(fieldDef, labelClass), children: labelContent }) : /* @__PURE__ */ jsx(Label, { htmlFor: fieldId, className: fieldLabelClass(fieldDef), children: labelContent }) : null;
39
+ const placeholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : void 0;
40
+ return /* @__PURE__ */ jsxs(
41
+ "div",
42
+ {
43
+ className: fieldWrapperClass(
44
+ fieldDef,
45
+ wrapperClass,
46
+ isTextarea ? "flex h-full min-h-0 flex-col" : void 0
47
+ ),
48
+ children: [
49
+ hasVoice ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
50
+ labelEl,
51
+ /* @__PURE__ */ jsx(VoiceMicButton, { fieldId, onTranscriptReady: setValue })
52
+ ] }) : labelEl,
53
+ /* @__PURE__ */ jsx(
54
+ Component,
55
+ {
56
+ id: fieldId,
57
+ value: value || "",
58
+ onChange: (e) => setValue(fieldDef.type === "number" ? Number(e.target.value) : e.target.value),
59
+ onBlur: setTouched,
60
+ disabled,
61
+ type: fieldDef.type === "number" ? "number" : "text",
62
+ className: fieldControlClass(
63
+ fieldDef,
64
+ inputClass,
65
+ isTextarea && height == null ? "min-h-[80px] flex-1" : void 0
66
+ ),
67
+ placeholder,
68
+ "aria-label": !showLabel ? fieldDef.label : void 0,
69
+ ...isTextarea && { height }
70
+ }
71
+ ),
72
+ showError && /* @__PURE__ */ jsx("p", { className: fieldErrorClass(fieldDef, "text-xs text-red-500"), children: error })
73
+ ]
74
+ }
75
+ );
76
+ };
77
+ var SelectWidget = ({ fieldId }) => {
78
+ const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);
79
+ const [options, setOptions] = useState([]);
80
+ const [loading, setLoading] = useState(false);
81
+ const { state } = useForm();
82
+ const showError = !!error && (touched || state.submitAttempted);
83
+ useEffect(() => {
84
+ if (!fieldDef) return;
85
+ const def = fieldDef;
86
+ if (def.options) {
87
+ setOptions(def.options);
88
+ } else if (def.dataSource) {
89
+ setLoading(true);
90
+ fetchOptions(def.dataSource.source, def.dataSource.params).then((opts) => {
91
+ setOptions(opts);
92
+ }).finally(() => setLoading(false));
93
+ }
94
+ }, [fieldDef]);
95
+ if (!fieldDef) return null;
96
+ const schemaPlaceholder = typeof fieldDef.placeholder === "string" && fieldDef.placeholder.trim() ? fieldDef.placeholder : void 0;
97
+ const selectPlaceholder = loading ? "Loading..." : schemaPlaceholder ?? "Select...";
98
+ const showLabel = isLabelVisible(fieldDef);
99
+ return /* @__PURE__ */ jsxs("div", { className: fieldWrapperClass(fieldDef, "space-y-2"), children: [
100
+ showLabel ? /* @__PURE__ */ jsxs(Label, { htmlFor: fieldId, className: fieldLabelClass(fieldDef), children: [
101
+ fieldDef.label,
102
+ " ",
103
+ /* @__PURE__ */ jsx(FieldRequiredIndicator, { fieldDef })
104
+ ] }) : null,
105
+ /* @__PURE__ */ jsxs(
106
+ Select,
107
+ {
108
+ disabled: disabled || loading,
109
+ value: value ? String(value) : void 0,
110
+ onValueChange: (val) => {
111
+ const opt = options.find((o) => String(o.value) === val);
112
+ setValue(opt ? opt.value : val);
113
+ setTouched();
114
+ },
115
+ children: [
116
+ /* @__PURE__ */ jsx(
117
+ SelectTrigger,
118
+ {
119
+ id: fieldId,
120
+ className: fieldControlClass(
121
+ fieldDef,
122
+ showError ? "border-red-500" : ""
123
+ ),
124
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: selectPlaceholder })
125
+ }
126
+ ),
127
+ /* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: String(opt.value), children: opt.label }, String(opt.value))) })
128
+ ]
129
+ }
130
+ ),
131
+ showError && /* @__PURE__ */ jsx("p", { className: fieldErrorClass(fieldDef, "text-xs text-red-500"), children: error })
132
+ ] });
133
+ };
134
+
135
+ export { SelectWidget, TextWidget };
136
+ //# sourceMappingURL=chunk-3KRDT7TX.mjs.map
137
+ //# sourceMappingURL=chunk-3KRDT7TX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/widgets/Text.tsx","../src/ui/widgets/Select.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"chunk-3KRDT7TX.mjs","sourcesContent":["import React from 'react';\nimport { useField } from '../../react/useField';\nimport { useForm } from '../../react/useForm';\nimport { useFormStore } from '../../react/FormProvider';\nimport { VoiceMicButton } from '../../react/VoiceMicButton';\nimport { Input } from '../shadcn/input';\nimport { Label } from '../shadcn/label';\nimport { Textarea } from '../shadcn/textarea';\nimport { getThemeConfig } from '../themes';\nimport { cn } from '../../core/utils';\nimport {\n FieldRequiredIndicator,\n fieldControlClass,\n fieldErrorClass,\n fieldLabelClass,\n fieldWrapperClass,\n isLabelVisible,\n} from '../../react/fieldStyle';\n\nexport const TextWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);\n const { state } = useForm();\n const store = useFormStore();\n const hasVoice = !!(fieldDef?.voice && store.getVoice());\n\n const showError = !!error && (touched || state.submitAttempted);\n\n if (!fieldDef) return null;\n\n const Component = fieldDef.type === 'textarea' ? Textarea : Input;\n const isTextarea = fieldDef.type === 'textarea';\n const height = isTextarea && 'height' in fieldDef ? fieldDef.height : undefined;\n const theme = getThemeConfig(\n isTextarea ? 'textarea' : 'text',\n fieldDef.theme\n );\n\n const wrapperClass = theme?.wrapperClassName ?? 'space-y-2';\n const labelClass = theme?.labelClassName;\n const inputClass = cn(theme?.inputClassName, showError && 'border-red-500');\n const showLabel = isLabelVisible(fieldDef);\n\n const labelContent = (\n <>\n {fieldDef.label}{' '}\n <FieldRequiredIndicator fieldDef={fieldDef} />\n </>\n );\n\n const labelEl = showLabel\n ? theme ? (\n <Label htmlFor={fieldId} className={fieldLabelClass(fieldDef, labelClass)}>\n {labelContent}\n </Label>\n ) : (\n <Label htmlFor={fieldId} className={fieldLabelClass(fieldDef)}>\n {labelContent}\n </Label>\n )\n : null;\n\n const placeholder =\n typeof fieldDef.placeholder === 'string' && fieldDef.placeholder.trim()\n ? fieldDef.placeholder\n : undefined;\n\n return (\n <div\n className={fieldWrapperClass(\n fieldDef,\n wrapperClass,\n isTextarea ? 'flex h-full min-h-0 flex-col' : undefined,\n )}\n >\n {hasVoice ? (\n <div className=\"flex items-center justify-between\">\n {labelEl}\n <VoiceMicButton fieldId={fieldId} onTranscriptReady={setValue} />\n </div>\n ) : (\n labelEl\n )}\n <Component\n id={fieldId}\n value={value || ''}\n onChange={(e) => setValue(fieldDef.type === 'number' ? Number(e.target.value) : e.target.value)}\n onBlur={setTouched}\n disabled={disabled}\n type={fieldDef.type === 'number' ? 'number' : 'text'}\n className={fieldControlClass(\n fieldDef,\n inputClass,\n isTextarea && height == null ? 'min-h-[80px] flex-1' : undefined,\n )}\n placeholder={placeholder}\n aria-label={!showLabel ? fieldDef.label : undefined}\n {...(isTextarea && { height })}\n />\n {showError && (\n <p className={fieldErrorClass(fieldDef, 'text-xs text-red-500')}>{error}</p>\n )}\n </div>\n );\n};\n\n","import React, { useEffect, useState } from 'react';\nimport { useField } from '../../react/useField';\nimport { useForm } from '../../react/useForm';\nimport { Label } from '../shadcn/label';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../shadcn/select';\nimport { fetchOptions } from '../../core/asyncOptions';\nimport type { SelectFieldDef } from '../../core/types';\nimport {\n FieldRequiredIndicator,\n fieldControlClass,\n fieldErrorClass,\n fieldLabelClass,\n fieldWrapperClass,\n isLabelVisible,\n} from '../../react/fieldStyle';\n\nexport const SelectWidget: React.FC<{ fieldId: string }> = ({ fieldId }) => {\n const { fieldDef, value, setValue, setTouched, error, disabled, touched } = useField(fieldId);\n const [options, setOptions] = useState<{ label: string; value: any }[]>([]);\n const [loading, setLoading] = useState(false);\n const { state } = useForm();\n const showError = !!error && (touched || state.submitAttempted);\n\n useEffect(() => {\n if (!fieldDef) return;\n const def = fieldDef as SelectFieldDef; // Cast safe due to Renderer check\n\n if (def.options) {\n setOptions(def.options);\n } else if (def.dataSource) {\n setLoading(true);\n fetchOptions(def.dataSource.source, def.dataSource.params)\n .then(opts => {\n setOptions(opts);\n })\n .finally(() => setLoading(false));\n }\n }, [fieldDef]);\n\n if (!fieldDef) return null;\n\n const schemaPlaceholder =\n typeof fieldDef.placeholder === 'string' && fieldDef.placeholder.trim()\n ? fieldDef.placeholder\n : undefined;\n const selectPlaceholder = loading ? 'Loading...' : schemaPlaceholder ?? 'Select...';\n\n const showLabel = isLabelVisible(fieldDef);\n\n return (\n <div className={fieldWrapperClass(fieldDef, 'space-y-2')}>\n {showLabel ? (\n <Label htmlFor={fieldId} className={fieldLabelClass(fieldDef)}>\n {fieldDef.label}{' '}\n <FieldRequiredIndicator fieldDef={fieldDef} />\n </Label>\n ) : null}\n\n <Select \n disabled={disabled || loading} \n value={value ? String(value) : undefined} \n onValueChange={(val) => {\n // Try to find original value type (number vs string)\n const opt = options.find(o => String(o.value) === val);\n setValue(opt ? opt.value : val);\n setTouched();\n }}\n >\n <SelectTrigger\n id={fieldId}\n className={fieldControlClass(\n fieldDef,\n showError ? 'border-red-500' : '',\n )}\n >\n <SelectValue placeholder={selectPlaceholder} />\n </SelectTrigger>\n <SelectContent>\n {options.map(opt => (\n <SelectItem key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n \n {showError && (\n <p className={fieldErrorClass(fieldDef, 'text-xs text-red-500')}>{error}</p>\n )}\n </div>\n );\n};\n\n"]}