@multiplatform.one/forms 6.4.2 → 6.6.0

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 (405) hide show
  1. package/dist/cjs/Button/index.cjs +23 -8
  2. package/dist/cjs/Button/index.native.js +23 -8
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/FieldDisplay/formatters.cjs +7 -12
  5. package/dist/cjs/FieldDisplay/formatters.native.js +7 -12
  6. package/dist/cjs/FieldDisplay/formatters.native.js.map +1 -1
  7. package/dist/cjs/Skeleton/index.cjs +1 -0
  8. package/dist/cjs/Skeleton/index.native.js +4 -0
  9. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  10. package/dist/cjs/Wheel/index.cjs +1 -1
  11. package/dist/cjs/Wheel/index.native.js +1 -1
  12. package/dist/cjs/Wheel/index.native.js.map +1 -1
  13. package/dist/cjs/fields/Checkbox/Checkbox.cjs +22 -15
  14. package/dist/cjs/fields/Checkbox/Checkbox.native.js +11 -6
  15. package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
  16. package/dist/cjs/fields/Checkbox/index.cjs +9 -3
  17. package/dist/cjs/fields/Checkbox/index.native.js +9 -3
  18. package/dist/cjs/fields/Checkbox/index.native.js.map +1 -1
  19. package/dist/cjs/fields/ColorPicker/parts.native.js.map +1 -1
  20. package/dist/cjs/fields/Combobox/index.cjs +9 -4
  21. package/dist/cjs/fields/Combobox/index.native.js +9 -4
  22. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  23. package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +30 -20
  24. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +36 -21
  25. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  26. package/dist/cjs/fields/DatePicker/DatetimePicker.cjs +21 -15
  27. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +26 -16
  28. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  29. package/dist/cjs/fields/DatePicker/MonthPicker.cjs +24 -14
  30. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +36 -15
  31. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  32. package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +27 -18
  33. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +32 -19
  34. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  35. package/dist/cjs/fields/DatePicker/fieldValueSync.cjs +49 -0
  36. package/dist/cjs/fields/DatePicker/fieldValueSync.native.js +56 -0
  37. package/dist/cjs/fields/DatePicker/fieldValueSync.native.js.map +1 -0
  38. package/dist/cjs/fields/DatePicker/index.cjs +20 -14
  39. package/dist/cjs/fields/DatePicker/index.native.js +25 -15
  40. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  41. package/dist/cjs/fields/DatePicker/parts.cjs +2 -3
  42. package/dist/cjs/fields/DatePicker/parts.native.js +2 -3
  43. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  44. package/dist/cjs/fields/Geolocation/GeolocationMap.native.js +2 -2
  45. package/dist/cjs/fields/RadioGroup/index.cjs +4 -6
  46. package/dist/cjs/fields/RadioGroup/index.native.js +7 -6
  47. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  48. package/dist/cjs/fields/Rating/index.cjs +20 -3
  49. package/dist/cjs/fields/Rating/index.native.js +31 -6
  50. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  51. package/dist/cjs/fields/SearchInput/index.cjs +5 -1
  52. package/dist/cjs/fields/SearchInput/index.native.js +5 -1
  53. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  54. package/dist/cjs/fields/Select/index.cjs +6 -10
  55. package/dist/cjs/fields/Select/index.native.js +12 -10
  56. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  57. package/dist/cjs/fields/Signature/index.cjs +1 -1
  58. package/dist/cjs/fields/Signature/index.native.js +1 -1
  59. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  60. package/dist/cjs/fields/Slider/index.cjs +16 -4
  61. package/dist/cjs/fields/Slider/index.native.js +24 -4
  62. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  63. package/dist/cjs/fields/TextArea/index.cjs +3 -2
  64. package/dist/cjs/fields/TextArea/index.native.js +5 -2
  65. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  66. package/dist/cjs/fields/TimePicker/index.cjs +1 -1
  67. package/dist/cjs/fields/TimePicker/index.native.js +1 -1
  68. package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
  69. package/dist/cjs/fields/ToggleGroup/index.cjs +6 -22
  70. package/dist/cjs/fields/ToggleGroup/index.native.js +11 -28
  71. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  72. package/dist/cjs/shared/TimeColumn.cjs +1 -1
  73. package/dist/cjs/shared/TimeColumn.native.js +1 -1
  74. package/dist/cjs/shared/TimeColumn.native.js.map +1 -1
  75. package/dist/cjs/shared/colorRamps.cjs +5 -1
  76. package/dist/cjs/shared/colorRamps.native.js +5 -1
  77. package/dist/cjs/shared/colorRamps.native.js.map +1 -1
  78. package/dist/cjs/shared/focusManagement.cjs +7 -1
  79. package/dist/cjs/shared/focusManagement.native.js +5 -1
  80. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  81. package/dist/cjs/shared/t.cjs +5 -0
  82. package/dist/cjs/shared/t.native.js +5 -0
  83. package/dist/cjs/shared/t.native.js.map +1 -1
  84. package/dist/esm/Button/index.mjs +24 -9
  85. package/dist/esm/Button/index.mjs.map +1 -1
  86. package/dist/esm/Button/index.native.js +24 -9
  87. package/dist/esm/Button/index.native.js.map +1 -1
  88. package/dist/esm/FieldDisplay/formatters.mjs +8 -13
  89. package/dist/esm/FieldDisplay/formatters.mjs.map +1 -1
  90. package/dist/esm/FieldDisplay/formatters.native.js +8 -13
  91. package/dist/esm/FieldDisplay/formatters.native.js.map +1 -1
  92. package/dist/esm/FieldDisplay/index.mjs.map +1 -1
  93. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  94. package/dist/esm/Skeleton/index.mjs +2 -1
  95. package/dist/esm/Skeleton/index.mjs.map +1 -1
  96. package/dist/esm/Skeleton/index.native.js +5 -1
  97. package/dist/esm/Skeleton/index.native.js.map +1 -1
  98. package/dist/esm/Wheel/index.mjs +1 -1
  99. package/dist/esm/Wheel/index.mjs.map +1 -1
  100. package/dist/esm/Wheel/index.native.js +1 -1
  101. package/dist/esm/Wheel/index.native.js.map +1 -1
  102. package/dist/esm/fields/Checkbox/Checkbox.mjs +24 -17
  103. package/dist/esm/fields/Checkbox/Checkbox.mjs.map +1 -1
  104. package/dist/esm/fields/Checkbox/Checkbox.native.js +13 -8
  105. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  106. package/dist/esm/fields/Checkbox/index.mjs +11 -5
  107. package/dist/esm/fields/Checkbox/index.mjs.map +1 -1
  108. package/dist/esm/fields/Checkbox/index.native.js +11 -5
  109. package/dist/esm/fields/Checkbox/index.native.js.map +1 -1
  110. package/dist/esm/fields/ColorPicker/index.mjs.map +1 -1
  111. package/dist/esm/fields/ColorPicker/parts.mjs.map +1 -1
  112. package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
  113. package/dist/esm/fields/Combobox/index.mjs +9 -4
  114. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  115. package/dist/esm/fields/Combobox/index.native.js +9 -4
  116. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  117. package/dist/esm/fields/DatePicker/DateRangePicker.mjs +31 -21
  118. package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  119. package/dist/esm/fields/DatePicker/DateRangePicker.native.js +37 -22
  120. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  121. package/dist/esm/fields/DatePicker/DatetimePicker.mjs +21 -15
  122. package/dist/esm/fields/DatePicker/DatetimePicker.mjs.map +1 -1
  123. package/dist/esm/fields/DatePicker/DatetimePicker.native.js +26 -16
  124. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  125. package/dist/esm/fields/DatePicker/MonthPicker.mjs +25 -15
  126. package/dist/esm/fields/DatePicker/MonthPicker.mjs.map +1 -1
  127. package/dist/esm/fields/DatePicker/MonthPicker.native.js +37 -16
  128. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  129. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +28 -19
  130. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  131. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +33 -20
  132. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  133. package/dist/esm/fields/DatePicker/fieldValueSync.mjs +23 -0
  134. package/dist/esm/fields/DatePicker/fieldValueSync.mjs.map +1 -0
  135. package/dist/esm/fields/DatePicker/fieldValueSync.native.js +27 -0
  136. package/dist/esm/fields/DatePicker/fieldValueSync.native.js.map +1 -0
  137. package/dist/esm/fields/DatePicker/index.mjs +21 -15
  138. package/dist/esm/fields/DatePicker/index.mjs.map +1 -1
  139. package/dist/esm/fields/DatePicker/index.native.js +26 -16
  140. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  141. package/dist/esm/fields/DatePicker/parts.mjs +3 -4
  142. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  143. package/dist/esm/fields/DatePicker/parts.native.js +3 -4
  144. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  145. package/dist/esm/fields/DatePicker/utils.mjs.map +1 -1
  146. package/dist/esm/fields/Geolocation/GeolocationMap.native.js +2 -2
  147. package/dist/esm/fields/ImageField/index.mjs.map +1 -1
  148. package/dist/esm/fields/OTPInput/index.mjs.map +1 -1
  149. package/dist/esm/fields/RadioGroup/index.mjs +5 -7
  150. package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
  151. package/dist/esm/fields/RadioGroup/index.native.js +8 -7
  152. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  153. package/dist/esm/fields/Rating/index.mjs +20 -3
  154. package/dist/esm/fields/Rating/index.mjs.map +1 -1
  155. package/dist/esm/fields/Rating/index.native.js +31 -6
  156. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  157. package/dist/esm/fields/SearchInput/index.mjs +6 -2
  158. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  159. package/dist/esm/fields/SearchInput/index.native.js +6 -2
  160. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  161. package/dist/esm/fields/Select/index.mjs +6 -10
  162. package/dist/esm/fields/Select/index.mjs.map +1 -1
  163. package/dist/esm/fields/Select/index.native.js +12 -10
  164. package/dist/esm/fields/Select/index.native.js.map +1 -1
  165. package/dist/esm/fields/Signature/index.mjs +1 -1
  166. package/dist/esm/fields/Signature/index.mjs.map +1 -1
  167. package/dist/esm/fields/Signature/index.native.js +1 -1
  168. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  169. package/dist/esm/fields/Slider/index.mjs +16 -4
  170. package/dist/esm/fields/Slider/index.mjs.map +1 -1
  171. package/dist/esm/fields/Slider/index.native.js +24 -4
  172. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  173. package/dist/esm/fields/TextArea/index.mjs +3 -2
  174. package/dist/esm/fields/TextArea/index.mjs.map +1 -1
  175. package/dist/esm/fields/TextArea/index.native.js +5 -2
  176. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  177. package/dist/esm/fields/TimePicker/index.mjs +1 -1
  178. package/dist/esm/fields/TimePicker/index.mjs.map +1 -1
  179. package/dist/esm/fields/TimePicker/index.native.js +1 -1
  180. package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
  181. package/dist/esm/fields/ToggleGroup/index.mjs +7 -23
  182. package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
  183. package/dist/esm/fields/ToggleGroup/index.native.js +12 -29
  184. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  185. package/dist/esm/shared/TimeColumn.mjs +1 -1
  186. package/dist/esm/shared/TimeColumn.mjs.map +1 -1
  187. package/dist/esm/shared/TimeColumn.native.js +1 -1
  188. package/dist/esm/shared/TimeColumn.native.js.map +1 -1
  189. package/dist/esm/shared/colorRamps.mjs +5 -2
  190. package/dist/esm/shared/colorRamps.mjs.map +1 -1
  191. package/dist/esm/shared/colorRamps.native.js +5 -2
  192. package/dist/esm/shared/colorRamps.native.js.map +1 -1
  193. package/dist/esm/shared/focusManagement.mjs +7 -1
  194. package/dist/esm/shared/focusManagement.mjs.map +1 -1
  195. package/dist/esm/shared/focusManagement.native.js +5 -1
  196. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  197. package/dist/esm/shared/t.mjs +5 -1
  198. package/dist/esm/shared/t.mjs.map +1 -1
  199. package/dist/esm/shared/t.native.js +5 -1
  200. package/dist/esm/shared/t.native.js.map +1 -1
  201. package/dist/jsx/Button/index.mjs +24 -9
  202. package/dist/jsx/Button/index.mjs.map +1 -1
  203. package/dist/jsx/Button/index.native.js +23 -8
  204. package/dist/jsx/Button/index.native.js.map +1 -1
  205. package/dist/jsx/FieldDisplay/formatters.mjs +8 -13
  206. package/dist/jsx/FieldDisplay/formatters.mjs.map +1 -1
  207. package/dist/jsx/FieldDisplay/formatters.native.js +7 -12
  208. package/dist/jsx/FieldDisplay/formatters.native.js.map +1 -1
  209. package/dist/jsx/FieldDisplay/index.mjs.map +1 -1
  210. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  211. package/dist/jsx/Skeleton/index.mjs +2 -1
  212. package/dist/jsx/Skeleton/index.mjs.map +1 -1
  213. package/dist/jsx/Skeleton/index.native.js +4 -0
  214. package/dist/jsx/Skeleton/index.native.js.map +1 -1
  215. package/dist/jsx/Wheel/index.mjs +1 -1
  216. package/dist/jsx/Wheel/index.mjs.map +1 -1
  217. package/dist/jsx/Wheel/index.native.js +1 -1
  218. package/dist/jsx/Wheel/index.native.js.map +1 -1
  219. package/dist/jsx/fields/Checkbox/Checkbox.mjs +24 -17
  220. package/dist/jsx/fields/Checkbox/Checkbox.mjs.map +1 -1
  221. package/dist/jsx/fields/Checkbox/Checkbox.native.js +11 -6
  222. package/dist/jsx/fields/Checkbox/Checkbox.native.js.map +1 -1
  223. package/dist/jsx/fields/Checkbox/index.mjs +11 -5
  224. package/dist/jsx/fields/Checkbox/index.mjs.map +1 -1
  225. package/dist/jsx/fields/Checkbox/index.native.js +9 -3
  226. package/dist/jsx/fields/Checkbox/index.native.js.map +1 -1
  227. package/dist/jsx/fields/ColorPicker/index.mjs.map +1 -1
  228. package/dist/jsx/fields/ColorPicker/parts.mjs.map +1 -1
  229. package/dist/jsx/fields/ColorPicker/parts.native.js.map +1 -1
  230. package/dist/jsx/fields/Combobox/index.mjs +9 -4
  231. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  232. package/dist/jsx/fields/Combobox/index.native.js +9 -4
  233. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  234. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +31 -21
  235. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  236. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +36 -21
  237. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  238. package/dist/jsx/fields/DatePicker/DatetimePicker.mjs +21 -15
  239. package/dist/jsx/fields/DatePicker/DatetimePicker.mjs.map +1 -1
  240. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +26 -16
  241. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  242. package/dist/jsx/fields/DatePicker/MonthPicker.mjs +25 -15
  243. package/dist/jsx/fields/DatePicker/MonthPicker.mjs.map +1 -1
  244. package/dist/jsx/fields/DatePicker/MonthPicker.native.js +36 -15
  245. package/dist/jsx/fields/DatePicker/MonthPicker.native.js.map +1 -1
  246. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +28 -19
  247. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  248. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +32 -19
  249. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  250. package/dist/jsx/fields/DatePicker/fieldValueSync.mjs +23 -0
  251. package/dist/jsx/fields/DatePicker/fieldValueSync.mjs.map +1 -0
  252. package/dist/jsx/fields/DatePicker/fieldValueSync.native.js +56 -0
  253. package/dist/jsx/fields/DatePicker/fieldValueSync.native.js.map +1 -0
  254. package/dist/jsx/fields/DatePicker/index.mjs +21 -15
  255. package/dist/jsx/fields/DatePicker/index.mjs.map +1 -1
  256. package/dist/jsx/fields/DatePicker/index.native.js +25 -15
  257. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  258. package/dist/jsx/fields/DatePicker/parts.mjs +3 -4
  259. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  260. package/dist/jsx/fields/DatePicker/parts.native.js +2 -3
  261. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  262. package/dist/jsx/fields/DatePicker/utils.mjs.map +1 -1
  263. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js +2 -2
  264. package/dist/jsx/fields/ImageField/index.mjs.map +1 -1
  265. package/dist/jsx/fields/OTPInput/index.mjs.map +1 -1
  266. package/dist/jsx/fields/RadioGroup/index.mjs +5 -7
  267. package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
  268. package/dist/jsx/fields/RadioGroup/index.native.js +7 -6
  269. package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
  270. package/dist/jsx/fields/Rating/index.mjs +20 -3
  271. package/dist/jsx/fields/Rating/index.mjs.map +1 -1
  272. package/dist/jsx/fields/Rating/index.native.js +31 -6
  273. package/dist/jsx/fields/Rating/index.native.js.map +1 -1
  274. package/dist/jsx/fields/SearchInput/index.mjs +6 -2
  275. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  276. package/dist/jsx/fields/SearchInput/index.native.js +5 -1
  277. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  278. package/dist/jsx/fields/Select/index.mjs +6 -10
  279. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  280. package/dist/jsx/fields/Select/index.native.js +12 -10
  281. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  282. package/dist/jsx/fields/Signature/index.mjs +1 -1
  283. package/dist/jsx/fields/Signature/index.mjs.map +1 -1
  284. package/dist/jsx/fields/Signature/index.native.js +1 -1
  285. package/dist/jsx/fields/Signature/index.native.js.map +1 -1
  286. package/dist/jsx/fields/Slider/index.mjs +16 -4
  287. package/dist/jsx/fields/Slider/index.mjs.map +1 -1
  288. package/dist/jsx/fields/Slider/index.native.js +24 -4
  289. package/dist/jsx/fields/Slider/index.native.js.map +1 -1
  290. package/dist/jsx/fields/TextArea/index.mjs +3 -2
  291. package/dist/jsx/fields/TextArea/index.mjs.map +1 -1
  292. package/dist/jsx/fields/TextArea/index.native.js +5 -2
  293. package/dist/jsx/fields/TextArea/index.native.js.map +1 -1
  294. package/dist/jsx/fields/TimePicker/index.mjs +1 -1
  295. package/dist/jsx/fields/TimePicker/index.mjs.map +1 -1
  296. package/dist/jsx/fields/TimePicker/index.native.js +1 -1
  297. package/dist/jsx/fields/TimePicker/index.native.js.map +1 -1
  298. package/dist/jsx/fields/ToggleGroup/index.mjs +7 -23
  299. package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
  300. package/dist/jsx/fields/ToggleGroup/index.native.js +11 -28
  301. package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
  302. package/dist/jsx/shared/TimeColumn.mjs +1 -1
  303. package/dist/jsx/shared/TimeColumn.mjs.map +1 -1
  304. package/dist/jsx/shared/TimeColumn.native.js +1 -1
  305. package/dist/jsx/shared/TimeColumn.native.js.map +1 -1
  306. package/dist/jsx/shared/colorRamps.mjs +5 -2
  307. package/dist/jsx/shared/colorRamps.mjs.map +1 -1
  308. package/dist/jsx/shared/colorRamps.native.js +5 -1
  309. package/dist/jsx/shared/colorRamps.native.js.map +1 -1
  310. package/dist/jsx/shared/focusManagement.mjs +7 -1
  311. package/dist/jsx/shared/focusManagement.mjs.map +1 -1
  312. package/dist/jsx/shared/focusManagement.native.js +5 -1
  313. package/dist/jsx/shared/focusManagement.native.js.map +1 -1
  314. package/dist/jsx/shared/t.mjs +5 -1
  315. package/dist/jsx/shared/t.mjs.map +1 -1
  316. package/dist/jsx/shared/t.native.js +5 -0
  317. package/dist/jsx/shared/t.native.js.map +1 -1
  318. package/package.json +8 -7
  319. package/src/Button/Button.stories.tsx +19 -0
  320. package/src/Button/index.tsx +45 -12
  321. package/src/ControlGroup/ControlGroup.stories.tsx +12 -0
  322. package/src/FieldDisplay/formatters.ts +10 -14
  323. package/src/FieldLayout.stories.tsx +3 -2
  324. package/src/Form/Form.stories.tsx +13 -0
  325. package/src/Skeleton/index.tsx +5 -1
  326. package/src/fields/Checkbox/Checkbox.spec.tsx +50 -1
  327. package/src/fields/Checkbox/Checkbox.tsx +47 -19
  328. package/src/fields/Checkbox/index.tsx +23 -5
  329. package/src/fields/ColorPicker/ColorPicker.stories.tsx +2 -1
  330. package/src/fields/Combobox/index.tsx +8 -3
  331. package/src/fields/DatePicker/DatePicker.spec.tsx +93 -0
  332. package/src/fields/DatePicker/DatePicker.stories.tsx +2 -1
  333. package/src/fields/DatePicker/DateRangePicker.spec.tsx +72 -0
  334. package/src/fields/DatePicker/DateRangePicker.tsx +44 -30
  335. package/src/fields/DatePicker/DatetimePicker.spec.tsx +39 -0
  336. package/src/fields/DatePicker/DatetimePicker.tsx +1 -1
  337. package/src/fields/DatePicker/MonthPicker.spec.tsx +61 -0
  338. package/src/fields/DatePicker/MonthPicker.tsx +47 -21
  339. package/src/fields/DatePicker/MultiDatePicker.spec.tsx +34 -0
  340. package/src/fields/DatePicker/MultiDatePicker.tsx +39 -27
  341. package/src/fields/DatePicker/fieldValueSync.tsx +23 -0
  342. package/src/fields/DatePicker/parts.tsx +6 -1
  343. package/src/fields/FileUpload/FileUpload.stories.tsx +11 -1
  344. package/src/fields/Geolocation/Geolocation.stories.tsx +9 -0
  345. package/src/fields/Geolocation/GeolocationMap.native.tsx +2 -2
  346. package/src/fields/ImageField/ImageField.stories.tsx +2 -1
  347. package/src/fields/Input/Input.stories.tsx +19 -0
  348. package/src/fields/Progress/Progress.stories.tsx +19 -0
  349. package/src/fields/RadioGroup/RadioGroup.spec.tsx +139 -2
  350. package/src/fields/RadioGroup/index.tsx +2 -2
  351. package/src/fields/Rating/Rating.spec.tsx +43 -1
  352. package/src/fields/Rating/index.tsx +43 -4
  353. package/src/fields/SearchInput/SearchInput.spec.tsx +11 -0
  354. package/src/fields/SearchInput/index.tsx +6 -2
  355. package/src/fields/Select/Select.stories.tsx +19 -0
  356. package/src/fields/Select/index.tsx +12 -5
  357. package/src/fields/Signature/index.tsx +1 -1
  358. package/src/fields/Slider/Slider.spec.tsx +89 -4
  359. package/src/fields/Slider/Slider.stories.tsx +19 -0
  360. package/src/fields/Slider/index.tsx +4 -0
  361. package/src/fields/Stepper/Stepper.stories.tsx +12 -0
  362. package/src/fields/Switch/Switch.spec.tsx +50 -2
  363. package/src/fields/TextArea/TextArea.spec.tsx +57 -0
  364. package/src/fields/TextArea/TextArea.stories.tsx +19 -0
  365. package/src/fields/TextArea/index.tsx +10 -2
  366. package/src/fields/TimePicker/index.tsx +1 -1
  367. package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +64 -1
  368. package/src/fields/ToggleGroup/ToggleGroup.stories.tsx +19 -0
  369. package/src/fields/ToggleGroup/index.tsx +31 -29
  370. package/src/shared/FloatingListScrollArrows.stories.tsx +4 -2
  371. package/src/shared/TimeColumn.tsx +1 -1
  372. package/src/shared/focusManagement.ts +12 -1
  373. package/src/shared/t.spec.ts +39 -0
  374. package/src/shared/t.ts +20 -0
  375. package/types/Button/index.d.ts +9 -1
  376. package/types/Button/index.d.ts.map +1 -1
  377. package/types/FieldDisplay/formatters.d.ts +7 -1
  378. package/types/FieldDisplay/formatters.d.ts.map +1 -1
  379. package/types/InputParts/index.d.ts +4 -4
  380. package/types/Skeleton/index.d.ts.map +1 -1
  381. package/types/fields/Checkbox/Checkbox.d.ts.map +1 -1
  382. package/types/fields/Checkbox/index.d.ts +3 -3
  383. package/types/fields/Checkbox/index.d.ts.map +1 -1
  384. package/types/fields/Combobox/index.d.ts.map +1 -1
  385. package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
  386. package/types/fields/DatePicker/DatetimePicker.d.ts.map +1 -1
  387. package/types/fields/DatePicker/MonthPicker.d.ts.map +1 -1
  388. package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
  389. package/types/fields/DatePicker/fieldValueSync.d.ts +31 -0
  390. package/types/fields/DatePicker/fieldValueSync.d.ts.map +1 -0
  391. package/types/fields/DatePicker/index.d.ts.map +1 -1
  392. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  393. package/types/fields/Input/index.d.ts +2 -2
  394. package/types/fields/RadioGroup/index.d.ts.map +1 -1
  395. package/types/fields/Rating/index.d.ts.map +1 -1
  396. package/types/fields/SearchInput/index.d.ts.map +1 -1
  397. package/types/fields/Select/index.d.ts.map +1 -1
  398. package/types/fields/Slider/index.d.ts.map +1 -1
  399. package/types/fields/TextArea/index.d.ts.map +1 -1
  400. package/types/fields/ToggleGroup/index.d.ts.map +1 -1
  401. package/types/shared/colorRamps.d.ts +14 -0
  402. package/types/shared/colorRamps.d.ts.map +1 -1
  403. package/types/shared/focusManagement.d.ts.map +1 -1
  404. package/types/shared/t.d.ts +16 -0
  405. package/types/shared/t.d.ts.map +1 -1
@@ -119,7 +119,26 @@ export const CompoundPattern: Story = {
119
119
  ),
120
120
  };
121
121
 
122
+ /**
123
+ * FOREIGN CONTRAST SPECIMEN (LC-56 STORY-HONESTY): the right column renders the
124
+ * RAW tamagui Button beside the house Button strictly so the difference stays
125
+ * visible. Raw primitives here are by design and labeled — knob/contrast probes
126
+ * skip this story via `parameters.foreignContrastSpecimen`.
127
+ */
122
128
  export const Comparison: Story = {
129
+ name: "Foreign contrast specimen (raw tamagui)",
130
+ parameters: {
131
+ // Machine-readable exemption for knob/contrast probes and the LC-56 linter arm.
132
+ foreignContrastSpecimen: true,
133
+ docs: {
134
+ description: {
135
+ story:
136
+ "FOREIGN CONTRAST SPECIMEN (LC-56 STORY-HONESTY). The right column is the raw " +
137
+ "tamagui Button, rendered for contrast only: it ignores house knobs and intent " +
138
+ "recipes by design. Probes asserting house rendering must skip this story.",
139
+ },
140
+ },
141
+ },
123
142
  render: () => (
124
143
  <XStack gap="$6" alignItems="flex-start" padding="$4" flexWrap="wrap">
125
144
  <YStack gap="$3" width={200}>
@@ -19,6 +19,7 @@ import {
19
19
  type ButtonProps as TamaguiButtonProps,
20
20
  SizableText,
21
21
  View,
22
+ XStack,
22
23
  YStack,
23
24
  Theme,
24
25
  styled,
@@ -173,6 +174,14 @@ export interface ButtonProps extends Omit<TamaguiButtonProps, "form" | "icon" |
173
174
  * — bare `disabled` emits `bare-disabled`.
174
175
  */
175
176
  disabledReason?: string;
177
+ /**
178
+ * Where the visible reason renders relative to the control. `"below"`
179
+ * (default) stacks it under the button — right for forms and vertical
180
+ * layouts. `"inline"` puts it beside the button on the same line — for
181
+ * toolbar/control rows, where a stacked reason breaks the row's shared
182
+ * control height and wraps into cramped multi-line type.
183
+ */
184
+ disabledReasonPlacement?: "below" | "inline";
176
185
  }
177
186
 
178
187
  export function Button({
@@ -198,6 +207,7 @@ export function Button({
198
207
  noun,
199
208
  actionRole,
200
209
  disabledReason,
210
+ disabledReasonPlacement = "below",
201
211
  ...props
202
212
  }: ButtonProps) {
203
213
  const { resolvedForm: formFromHook } = useFormField({ form: formProp });
@@ -360,6 +370,15 @@ export function Button({
360
370
  : isCircular
361
371
  ? { minWidth: MIN_PRESS_TARGET, minHeight: MIN_PRESS_TARGET }
362
372
  : { minHeight: MIN_PRESS_TARGET };
373
+ // Axiom 3 NULL / LC-18: `circular` is a SHAPE eject, not a radius eject —
374
+ // a Button is R-SCALE, so in the square world (`borderRadius:none`) it goes
375
+ // square like every other control. The tamagui `circular` variant expands
376
+ // to a ~100000 radius that beats a plain borderRadius prop, so this rides
377
+ // an inline style (same idiom as the DatePicker day cell). Without it every
378
+ // `circular` Button in the catalog is an undeclared knob-immune shape
379
+ // (D-09 / LC-60 sweep finding: Pagination prev/next).
380
+ const circularSquareAtNone =
381
+ isCircular && knobProps.pointy ? { style: { borderRadius: 0 } } : null;
363
382
  const buttonElement = (
364
383
  <ButtonFrame
365
384
  // DG-ST-03: an explained disable is aria-disabled (focusable, press
@@ -427,6 +446,7 @@ export function Button({
427
446
  {...(tabIndex != null ? { tabIndex } : undefined)}
428
447
  {...props}
429
448
  {...circularPressFloor}
449
+ {...circularSquareAtNone}
430
450
  {...(explainedDisable
431
451
  ? {
432
452
  // No `title`: hover-only reveals are banned on disabled controls
@@ -466,19 +486,32 @@ export function Button({
466
486
 
467
487
  // DG-ST-03 explain affordance: visible reason adjacent to the control —
468
488
  // discoverable by pointer, touch, keyboard, and SR (aria-describedby)
469
- // without any hover interaction (Axiom 12).
489
+ // without any hover interaction (Axiom 12). "below" stacks (forms);
490
+ // "inline" keeps toolbar rows on one shared control line, where the
491
+ // stacked reason wrapped into cramped multi-line type under the button.
492
+ const reasonText = explainedDisable ? (
493
+ <SizableText
494
+ id={reasonId}
495
+ size="$2"
496
+ color={formCommonColors.muted}
497
+ flexShrink={1}
498
+ data-mp-disabled-reason="true"
499
+ >
500
+ {disabledReason}
501
+ </SizableText>
502
+ ) : null;
470
503
  const explainedElement = explainedDisable ? (
471
- <YStack gap="$1" flexShrink={1} data-mp-disabled-reason-wrapper="true">
472
- {buttonElement}
473
- <SizableText
474
- id={reasonId}
475
- size="$1"
476
- color={formCommonColors.muted}
477
- data-mp-disabled-reason="true"
478
- >
479
- {disabledReason}
480
- </SizableText>
481
- </YStack>
504
+ disabledReasonPlacement === "inline" ? (
505
+ <XStack gap="$2" alignItems="center" flexShrink={1} data-mp-disabled-reason-wrapper="true">
506
+ {buttonElement}
507
+ {reasonText}
508
+ </XStack>
509
+ ) : (
510
+ <YStack gap="$1" flexShrink={1} data-mp-disabled-reason-wrapper="true">
511
+ {buttonElement}
512
+ {reasonText}
513
+ </YStack>
514
+ )
482
515
  ) : (
483
516
  buttonElement
484
517
  );
@@ -1,3 +1,4 @@
1
+ import type { GuardrailSpecimenParameter } from "@multiplatform.one/theme";
1
2
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
3
  import { Input as TamaguiInput, Paragraph, YStack } from "tamagui";
3
4
  import { Button } from "../Button";
@@ -69,6 +70,17 @@ export const ChildCounts: Story = {
69
70
  };
70
71
 
71
72
  export const MixedControls: Story = {
73
+ parameters: {
74
+ // LC-57 allowlist: the middle group deliberately shows a disabled segment
75
+ // inside a joined strip. ControlGroup styles its DIRECT children by index,
76
+ // so Button's visible disabledReason wrapper cannot ride along without
77
+ // breaking the strip geometry — the same no-room class as icon toolbars.
78
+ guardrailSpecimen: {
79
+ warns: ["bare-disabled"],
80
+ reason:
81
+ "Disabled-segment specimen: a joined ControlGroup strip has no room for the visible reason line.",
82
+ } satisfies GuardrailSpecimenParameter,
83
+ },
72
84
  render: () => (
73
85
  <YStack gap="$4" maxWidth={480}>
74
86
  <ControlGroup>
@@ -7,7 +7,7 @@
7
7
  * either component.
8
8
  */
9
9
 
10
- import { formatAbsoluteDate } from "@multiplatform.one/theme";
10
+ import { formatAbsoluteDate, formatCurrency, formatNumber } from "@multiplatform.one/theme";
11
11
 
12
12
  export const EMPTY = "—";
13
13
 
@@ -27,24 +27,20 @@ export function asText(v: any): string {
27
27
 
28
28
  export interface NumericFormatOptions {
29
29
  precision?: number;
30
- /** ISO 4217 currency code, e.g. "USD". */
30
+ /** ISO 4217 currency code (or a symbol a code is known for), e.g. "USD". */
31
31
  currency?: string;
32
32
  }
33
33
 
34
+ /**
35
+ * Read-only numeric cells speak the house number registers (LC-12 render
36
+ * channel): the same figure reads identically in a table cell, a KPI tile
37
+ * and a group aggregate. `precision` pins the fraction digits a Frappe field
38
+ * declares; the register owns everything else.
39
+ */
34
40
  export function formatNumericText(num: number, options: NumericFormatOptions = {}): string {
35
41
  const { precision, currency } = options;
36
- if (currency) {
37
- return new Intl.NumberFormat(undefined, {
38
- style: "currency",
39
- currency,
40
- minimumFractionDigits: precision,
41
- maximumFractionDigits: precision,
42
- }).format(num);
43
- }
44
- return new Intl.NumberFormat(undefined, {
45
- minimumFractionDigits: precision,
46
- maximumFractionDigits: precision,
47
- }).format(num);
42
+ if (currency) return formatCurrency(num, { precision, symbol: currency });
43
+ return formatNumber(num, { precision });
48
44
  }
49
45
 
50
46
  // Re-exported for existing consumers; the canonical shape lives in theme.
@@ -46,7 +46,8 @@ export const ErrorStates: Story = {
46
46
  id="fl-err-string"
47
47
  label="String error"
48
48
  helperText="Helper should be hidden"
49
- error="This field is invalid"
49
+ // DG-COPY-02: error copy states the rule broken — never "invalid"/"please"/"error".
50
+ error="Value must use letters only"
50
51
  >
51
52
  <TamaguiInput id="fl-err-string" />
52
53
  </FieldLayout>
@@ -96,7 +97,7 @@ export const AnatomyEdgeCases: Story = {
96
97
  <FieldLayout
97
98
  id="fl-long"
98
99
  label="Long messages"
99
- error="This error message is extremely long and keeps going to make sure long validation copy wraps correctly under the control without pushing the layout sideways or clipping any of its content at narrow widths"
100
+ error="This validation message is extremely long and keeps going to make sure long validation copy wraps correctly under the control without pushing the layout sideways or clipping any of its content at narrow widths"
100
101
  >
101
102
  <TamaguiInput id="fl-long" />
102
103
  </FieldLayout>
@@ -224,9 +224,14 @@ export const DynamicFields = () => {
224
224
  label="Account Type"
225
225
  name="accountType"
226
226
  required
227
+ // >5 options: shorter single-select lists trip `select-too-few-options` (DG-CTRL-01).
227
228
  options={[
228
229
  { label: "Personal", value: "personal" },
229
230
  { label: "Business", value: "business" },
231
+ { label: "Nonprofit", value: "nonprofit" },
232
+ { label: "Government", value: "government" },
233
+ { label: "Education", value: "education" },
234
+ { label: "Other", value: "other" },
230
235
  ]}
231
236
  />
232
237
 
@@ -323,18 +328,26 @@ InputWithLinkResolver.parameters = {
323
328
  },
324
329
  };
325
330
 
331
+ // Six entries: still renders without scroll (the "short list" the story demos)
332
+ // while clearing the ≤5 `select-too-few-options` guardrail (DG-CTRL-01).
326
333
  const shortPriorityOptions = [
334
+ { value: "lowest", label: "Lowest" },
327
335
  { value: "low", label: "Low" },
328
336
  { value: "medium", label: "Medium" },
329
337
  { value: "high", label: "High" },
338
+ { value: "highest", label: "Highest" },
339
+ { value: "critical", label: "Critical" },
330
340
  ];
331
341
 
342
+ // Six entries: still the "short list" the story demos, while clearing the ≤5
343
+ // `select-too-few-options` guardrail (DG-CTRL-01).
332
344
  const shortCountryOptions: ComboboxOption[] = [
333
345
  { value: "us", label: "United States", keywords: "usa america" },
334
346
  { value: "ca", label: "Canada", keywords: "north america" },
335
347
  { value: "uk", label: "United Kingdom", keywords: "britain england" },
336
348
  { value: "de", label: "Germany", keywords: "europe deutschland" },
337
349
  { value: "fr", label: "France", keywords: "europe paris" },
350
+ { value: "jp", label: "Japan", keywords: "asia tokyo" },
338
351
  ];
339
352
 
340
353
  const countryOptions: ComboboxOption[] = [
@@ -1,4 +1,4 @@
1
- import { useResolvedKnobs } from "@multiplatform.one/theme";
1
+ import { radiusClassProps, useResolvedKnobs } from "@multiplatform.one/theme";
2
2
  import type { GetProps } from "tamagui";
3
3
  import { View, styled, isWeb } from "tamagui";
4
4
 
@@ -107,6 +107,10 @@ export function Skeleton({
107
107
  : variant === "text" && knobProps.pointy
108
108
  ? { borderRadius: 0 }
109
109
  : undefined)}
110
+ // R-PILL (spec Skeleton "circle"): the circular variant stays 1:1 and
111
+ // round at every radius value, so it declares the class the
112
+ // `radius:none` sweep licenses it under (D-09 / LC-60).
113
+ {...(variant === "circular" ? radiusClassProps("R-PILL", "SkeletonCircle") : undefined)}
110
114
  {...props}
111
115
  {...(mergedStyle ? { style: mergedStyle } : undefined)}
112
116
  />
@@ -1,10 +1,34 @@
1
- import { fireEvent } from "@testing-library/react";
1
+ import { fireEvent, render } from "@testing-library/react";
2
2
  import { describe, expect, it, vi } from "vitest";
3
3
  import { renderWithProviders } from "@multiplatform.one/test-utils";
4
+ import {
5
+ createThemesBuilder,
6
+ defaultAccentTheme,
7
+ defaultBaseTheme,
8
+ defaultBuilderOptions,
9
+ } from "@multiplatform.one/theme";
10
+ import { configWithoutAnimations } from "@tamagui/config";
11
+ import { animationsCSS } from "@tamagui/config/v5-css";
12
+ import { TamaguiProvider, createTamagui } from "tamagui";
4
13
  import { Form } from "../../Form";
5
14
  import { Checkbox } from "./Checkbox";
6
15
  import { CheckboxGroup } from "./CheckboxGroup";
7
16
 
17
+ // House builder themes for the LC-05 mark assertion — created at MODULE
18
+ // scope: tamagui registers a config's theme variables globally at
19
+ // createTamagui time, and a config created after the first render (inside a
20
+ // test body) never resolves its tokens (Progress.spec pattern).
21
+ const houseThemes = createThemesBuilder(
22
+ defaultBaseTheme,
23
+ defaultAccentTheme,
24
+ defaultBuilderOptions,
25
+ ).themes() as Record<string, Record<string, string>>;
26
+ const houseConfig = createTamagui({
27
+ ...configWithoutAnimations,
28
+ animations: animationsCSS,
29
+ themes: houseThemes as any,
30
+ });
31
+
8
32
  describe("Checkbox", () => {
9
33
  describe("without form context", () => {
10
34
  it("renders with label", () => {
@@ -256,4 +280,29 @@ describe("CheckboxGroup", () => {
256
280
  expect(new Set(ids).size).toBe(2);
257
281
  });
258
282
  });
283
+
284
+ describe("selected mark (LC-05 ONE-EMPHASIS / D-01 census addition)", () => {
285
+ it("fills the checked box with the accent mark; the unchecked box stays neutral chrome", () => {
286
+ const { container } = render(
287
+ <TamaguiProvider config={houseConfig} defaultTheme="light" disableInjectCSS>
288
+ <Checkbox label="Checked" checked />
289
+ <Checkbox label="Unchecked" checked={false} />
290
+ </TamaguiProvider>,
291
+ );
292
+ const boxes = Array.from(container.querySelectorAll('[role="checkbox"]'));
293
+ expect(boxes.length).toBe(2);
294
+ const checked = boxes.find((b) => b.getAttribute("aria-checked") === "true");
295
+ const unchecked = boxes.find((b) => b.getAttribute("aria-checked") === "false");
296
+ expect(checked).toBeTruthy();
297
+ expect(unchecked).toBeTruthy();
298
+ // The visible glyph box (a descendant of the 44px transparent target)
299
+ // carries the accent mark fill only while checked.
300
+ const marked = (root: Element) =>
301
+ Array.from(root.querySelectorAll("*")).filter((el) =>
302
+ (el as HTMLElement).className?.toString().includes("_bg-accentBackg"),
303
+ );
304
+ expect(marked(checked!).length).toBeGreaterThan(0);
305
+ expect(marked(unchecked!).length).toBe(0);
306
+ });
307
+ });
259
308
  });
@@ -1,7 +1,8 @@
1
1
  import { CheckIcon as CheckRegular, MinusIcon as MinusRegular } from "@phosphor-icons/react";
2
+ import { useReadableTextOn } from "@multiplatform.one/theme";
2
3
  import type { AnyFormApi } from "../../types";
3
4
  import type { ReactNode } from "react";
4
- import { useMemo } from "react";
5
+ import { useMemo, useState } from "react";
5
6
  import type {
6
7
  CheckedState,
7
8
  CheckboxProps as TamaguiCheckboxProps,
@@ -23,7 +24,7 @@ import { getSize } from "@tamagui/get-token";
23
24
  import { useIsInTableCell } from "../../shared/tableCellContext";
24
25
  import { Skeleton } from "../../Skeleton";
25
26
  import { Field, FieldLayout } from "../../fieldLayout";
26
- import { formCommonColors, formControlColors } from "../../shared/colorRamps";
27
+ import { formCommonColors, formControlColors, formSelectedColors } from "../../shared/colorRamps";
27
28
  import {
28
29
  clampRadiusForControl,
29
30
  clampRadiusInStateProps,
@@ -150,6 +151,15 @@ export function Checkbox({
150
151
  const indicatorColor = getVariable(
151
152
  tamaguiTheme[accentTokenKey as any]?.get("web") ?? tamaguiTheme.color?.get("web"),
152
153
  );
154
+ // LC-05 ONE-EMPHASIS / D-01 (census addition): the checked box IS the
155
+ // selection mark, so it fills with the shared accent mark — the checked
156
+ // Switch track precedent — and the check/minus glyph takes the
157
+ // luminance-computed anchor for that fill. It painted the LABEL ink tier
158
+ // (`textAccentColor`) on unchanged neutral chrome — the same defect the
159
+ // RadioGroup dot carried — so a checked box read as chrome, not as chosen.
160
+ // When the accent ramp is absent, `onMark` is undefined and the glyph keeps
161
+ // the previous ink resolution as the declared fallback.
162
+ const onMark = useReadableTextOn(formSelectedColors.mark);
153
163
  const indicatorWeight =
154
164
  knobProps.textWeight.fontWeight === "700"
155
165
  ? "bold"
@@ -161,12 +171,12 @@ export function Checkbox({
161
171
  if (children) return children;
162
172
  return (
163
173
  <TamaguiCheckbox.Indicator
164
- {...(knobProps.transition ? { animation: knobProps.transition } : undefined)}
174
+ {...(knobProps.transition ? { transition: knobProps.transition } : undefined)}
165
175
  >
166
176
  {currentChecked === "indeterminate" ? (
167
- <MinusRegular color={indicatorColor} weight={indicatorWeight} />
177
+ <MinusRegular color={onMark ?? indicatorColor} weight={indicatorWeight} />
168
178
  ) : (
169
- <CheckRegular color={indicatorColor} weight={indicatorWeight} />
179
+ <CheckRegular color={onMark ?? indicatorColor} weight={indicatorWeight} />
170
180
  )}
171
181
  </TamaguiCheckbox.Indicator>
172
182
  );
@@ -196,20 +206,37 @@ export function Checkbox({
196
206
  // Interaction-state tints stay off the (invisible) 44px frame; the knob
197
207
  // state props (ring/halo) still apply around the target.
198
208
  const stateBaseStyle = { backgroundColor: "transparent" };
199
- const glyphBox = (currentChecked: CheckedState | undefined) => (
200
- <View
201
- width={glyphSize}
202
- height={glyphSize}
203
- {...knobProps.inputSurface}
204
- {...resolvedRadius}
205
- backgroundColor={knobProps.outlined ? "transparent" : formControlColors.background}
206
- borderColor={formControlColors.border}
207
- alignItems="center"
208
- justifyContent="center"
209
- >
210
- {renderIndicator(currentChecked)}
211
- </View>
209
+ // Live checked value for the standalone-uncontrolled branch: the box fill
210
+ // below is keyed on it (tamagui's internal state only mounts/unmounts the
211
+ // indicator, it cannot repaint the box).
212
+ const [uncontrolledChecked, setUncontrolledChecked] = useState<CheckedState | undefined>(
213
+ defaultValue as CheckedState | undefined,
212
214
  );
215
+ const glyphBox = (currentChecked: CheckedState | undefined) => {
216
+ // Indeterminate is a selected-ish state: it carries the mark fill too,
217
+ // with the minus glyph, so "partially chosen" never reads as idle chrome.
218
+ const isMarked = currentChecked === true || currentChecked === "indeterminate";
219
+ return (
220
+ <View
221
+ width={glyphSize}
222
+ height={glyphSize}
223
+ {...knobProps.inputSurface}
224
+ {...resolvedRadius}
225
+ backgroundColor={
226
+ isMarked
227
+ ? formSelectedColors.mark
228
+ : knobProps.outlined
229
+ ? "transparent"
230
+ : formControlColors.background
231
+ }
232
+ borderColor={isMarked ? formSelectedColors.mark : formControlColors.border}
233
+ alignItems="center"
234
+ justifyContent="center"
235
+ >
236
+ {renderIndicator(currentChecked)}
237
+ </View>
238
+ );
239
+ };
213
240
  // Elevation wraps the visible glyph, never the invisible target (cells
214
241
  // keep elevation suppressed as before).
215
242
  const renderControlContent = (currentChecked: CheckedState | undefined) =>
@@ -308,11 +335,12 @@ export function Checkbox({
308
335
  {...nativeCheckboxA11y(typeof error === "string" && error ? error : undefined)}
309
336
  onCheckedChange={(val) => {
310
337
  if (disabled || readOnly) return;
338
+ setUncontrolledChecked(val);
311
339
  handleValueChange(val);
312
340
  }}
313
341
  {...(onBlur ? { onBlur } : undefined)}
314
342
  >
315
- {renderControlContent(checked ?? (defaultValue as CheckedState | undefined))}
343
+ {renderControlContent(checked ?? uncontrolledChecked)}
316
344
  </CheckboxFieldFrame>
317
345
  );
318
346
 
@@ -1,7 +1,11 @@
1
1
  import type { RovingFocusGroupProps, RovingFocusItemProps } from "@tamagui/roving-focus";
2
2
  import { RovingFocusGroup } from "@tamagui/roving-focus";
3
3
  import { CheckIcon as CheckRegular } from "@phosphor-icons/react";
4
- import { ensureFocusVisibleRing, useResolvedKnobs } from "@multiplatform.one/theme";
4
+ import {
5
+ ensureFocusVisibleRing,
6
+ useReadableTextOn,
7
+ useResolvedKnobs,
8
+ } from "@multiplatform.one/theme";
5
9
  import type { ElementRef, KeyboardEvent, PropsWithChildren } from "react";
6
10
  import { forwardRef } from "react";
7
11
  import type { CheckedState, YStackProps } from "tamagui";
@@ -28,7 +32,7 @@ import {
28
32
  } from "./CheckboxCard";
29
33
  import { CheckboxFieldFrame } from "./CheckboxFieldFrame";
30
34
  import { clampRadiusForControl } from "../../shared/utils";
31
- import { formControlColors } from "../../shared/colorRamps";
35
+ import { formControlColors, formSelectedColors } from "../../shared/colorRamps";
32
36
 
33
37
  // ─── Checkboxes Compound Component ────────────────────────────────────────────
34
38
 
@@ -133,6 +137,10 @@ const CheckboxesCheckbox = TamaguiCheckbox.styleable((checkboxProps, ref) => {
133
137
  const { values, onValuesChange } = CheckboxesContext.useStyledContext();
134
138
  const { value: focusItemValue } = FocusItemContext.useStyledContext();
135
139
  const { knobProps } = useResolvedKnobs();
140
+ // LC-05 ONE-EMPHASIS / D-01: the checked box is the selection mark, so it
141
+ // fills with the shared accent mark (same treatment as fields/Checkbox and
142
+ // the checked Switch track); unchecked chrome stays neutral.
143
+ const isMarked = Boolean(values[focusItemValue]);
136
144
  const radiusToken = knobProps.borderRadius.borderRadius;
137
145
  const cappedRadius = clampRadiusForControl(radiusToken, 2);
138
146
  const resolvedRadius =
@@ -196,8 +204,14 @@ const CheckboxesCheckbox = TamaguiCheckbox.styleable((checkboxProps, ref) => {
196
204
  height={glyphSize}
197
205
  {...knobProps.inputSurface}
198
206
  {...resolvedRadius}
199
- backgroundColor={knobProps.outlined ? "transparent" : formControlColors.background}
200
- borderColor={formControlColors.border}
207
+ backgroundColor={
208
+ isMarked
209
+ ? formSelectedColors.mark
210
+ : knobProps.outlined
211
+ ? "transparent"
212
+ : formControlColors.background
213
+ }
214
+ borderColor={isMarked ? formSelectedColors.mark : formControlColors.border}
201
215
  alignItems="center"
202
216
  justifyContent="center"
203
217
  >
@@ -240,9 +254,13 @@ const CheckboxCardDescriptionSized = CheckboxCardDescription.styleable((props, r
240
254
 
241
255
  const CheckboxesIndicator = TamaguiCheckbox.Indicator.styleable((indicatorProps, ref) => {
242
256
  const { children, ...props } = indicatorProps;
257
+ // LC-05: the glyph rides the accent mark fill, so it takes the
258
+ // luminance-computed anchor for that fill (never assumed scheme ink);
259
+ // consumer-provided children keep their own colors (explicit eject).
260
+ const onMark = useReadableTextOn(formSelectedColors.mark);
243
261
  return (
244
262
  <TamaguiCheckbox.Indicator ref={ref} {...props}>
245
- {children ?? <CheckRegular />}
263
+ {children ?? <CheckRegular {...(onMark ? { color: onMark } : undefined)} />}
246
264
  </TamaguiCheckbox.Indicator>
247
265
  );
248
266
  });
@@ -158,7 +158,8 @@ export const WithError: Story = {
158
158
  render: (args) => <ColorPicker {...args} />,
159
159
  args: {
160
160
  label: "Required Color",
161
- error: "Please select a valid color",
161
+ // DG-COPY-02: error copy states the rule broken — never "please"/"invalid"/"error".
162
+ error: "Color must be a recognized value",
162
163
  required: true,
163
164
  },
164
165
  };
@@ -333,7 +333,7 @@ const ComboboxItem = memo(function ComboboxItem({
333
333
  ? // Two-line rows need to grow past the size-variant height.
334
334
  { height: "auto", paddingVertical: "$2" }
335
335
  : undefined)}
336
- {...(ctx.knobProps.transition ? { animation: ctx.knobProps.transition } : undefined)}
336
+ {...(ctx.knobProps.transition ? { transition: ctx.knobProps.transition } : undefined)}
337
337
  >
338
338
  {option.description ? (
339
339
  <YStack flex={1} minWidth={0}>
@@ -1258,6 +1258,11 @@ function FloatingComboboxCore({
1258
1258
  : {
1259
1259
  borderRadius: knobProps.borderRadius.borderRadius,
1260
1260
  borderWidth: knobProps.borderRadius.borderWidth,
1261
+ // LC-54 PRESS-FLOOR: compact/small size tokens render a sub-44
1262
+ // trigger (the 36px "Allocated To" quick filter breaking the
1263
+ // list's 44px control row) — same floor the house Select holds
1264
+ // on both its trigger variants.
1265
+ minHeight: 44,
1261
1266
  })}
1262
1267
  >
1263
1268
  <SyncFocusToOpen open={open} />
@@ -1497,7 +1502,7 @@ function FloatingComboboxCore({
1497
1502
  : undefined
1498
1503
  }
1499
1504
  onPress={handleCreate}
1500
- {...(knobProps.transition ? { animation: knobProps.transition } : undefined)}
1505
+ {...(knobProps.transition ? { transition: knobProps.transition } : undefined)}
1501
1506
  >
1502
1507
  <PlusIcon size={14} color={knobProps.textAccentColor} />
1503
1508
  <Text
@@ -1538,7 +1543,7 @@ function FloatingComboboxCore({
1538
1543
  : "transparent"
1539
1544
  }
1540
1545
  pressStyle={{ backgroundColor: formInputColors.background.focus }}
1541
- {...(knobProps.transition ? { animation: knobProps.transition } : undefined)}
1546
+ {...(knobProps.transition ? { transition: knobProps.transition } : undefined)}
1542
1547
  >
1543
1548
  <PlusIcon size={14} color={knobProps.textAccentColor} />
1544
1549
  <Text
@@ -223,6 +223,99 @@ describe("DatePicker", () => {
223
223
  });
224
224
  });
225
225
 
226
+ describe("late-arriving value display (create-mode seeding)", () => {
227
+ // The form branch only ever displayed the mount-time value (`selectedDate`
228
+ // was never re-synced from field state), so a value applied AFTER first
229
+ // paint — create-mode engine seeding, form.setFieldValue, live server
230
+ // merge — never rendered. Adopting a programmatic value must not emit
231
+ // onChange (LC-14: a seeded value is not a user edit).
232
+ const getDisplayInput = (container: ParentNode) =>
233
+ container.querySelector("input") as HTMLInputElement | null;
234
+
235
+ it("standalone controlled: a value arriving after mount displays, without onChange", async () => {
236
+ const DatePicker = await loadDatePicker();
237
+ const onChange = vi.fn();
238
+ const onValueChange = vi.fn();
239
+ const result = renderWithProviders(
240
+ <DatePicker
241
+ label="Due Date"
242
+ value={null}
243
+ onChange={onChange}
244
+ onValueChange={onValueChange}
245
+ />,
246
+ );
247
+ expect(getDisplayInput(result.container)?.value ?? "").toBe("");
248
+
249
+ // Late seed: the upstream doc value (frappe wire string) arrives after
250
+ // first paint.
251
+ result.rerender(
252
+ <DatePicker
253
+ label="Due Date"
254
+ value="2026-03-05"
255
+ onChange={onChange}
256
+ onValueChange={onValueChange}
257
+ />,
258
+ );
259
+ await waitFor(() => {
260
+ expect(getDisplayInput(result.container)?.value).toBe("Mar 5, 2026");
261
+ });
262
+ expect(onChange).not.toHaveBeenCalled();
263
+ expect(onValueChange).not.toHaveBeenCalled();
264
+ });
265
+
266
+ it("form-integrated: a field value set after mount displays, without onChange", async () => {
267
+ const DatePicker = await loadDatePicker();
268
+ const onChange = vi.fn();
269
+ let formApi: { setFieldValue: (name: "date", value: string | null) => void } | undefined;
270
+ const TestComponent = () => {
271
+ const form = useForm({ defaultValues: { date: null as string | null } });
272
+ formApi = form as unknown as typeof formApi;
273
+ return (
274
+ <Form form={form}>
275
+ <DatePicker label="Due Date" name="date" onChange={onChange} />
276
+ </Form>
277
+ );
278
+ };
279
+ const result = renderWithProviders(<TestComponent />);
280
+ expect(getDisplayInput(result.container)?.value ?? "").toBe("");
281
+
282
+ await act(async () => {
283
+ formApi?.setFieldValue("date", "2026-03-05");
284
+ });
285
+ await waitFor(() => {
286
+ expect(getDisplayInput(result.container)?.value).toBe("Mar 5, 2026");
287
+ });
288
+ expect(onChange).not.toHaveBeenCalled();
289
+ });
290
+
291
+ it("form-integrated: clearing the field value programmatically clears the display", async () => {
292
+ const DatePicker = await loadDatePicker();
293
+ const onChange = vi.fn();
294
+ let formApi: { setFieldValue: (name: "date", value: string | null) => void } | undefined;
295
+ const TestComponent = () => {
296
+ const form = useForm({ defaultValues: { date: "2026-03-05" as string | null } });
297
+ formApi = form as unknown as typeof formApi;
298
+ return (
299
+ <Form form={form}>
300
+ <DatePicker label="Due Date" name="date" onChange={onChange} />
301
+ </Form>
302
+ );
303
+ };
304
+ const result = renderWithProviders(<TestComponent />);
305
+ await waitFor(() => {
306
+ expect(getDisplayInput(result.container)?.value).toBe("Mar 5, 2026");
307
+ });
308
+
309
+ await act(async () => {
310
+ formApi?.setFieldValue("date", null);
311
+ });
312
+ await waitFor(() => {
313
+ expect(getDisplayInput(result.container)?.value ?? "").toBe("");
314
+ });
315
+ expect(onChange).not.toHaveBeenCalled();
316
+ });
317
+ });
318
+
226
319
  describe("date utilities", () => {
227
320
  it("formats display values in the house absolute register and handles null", () => {
228
321
  expect(formatDateDisplay(null)).toBe("");