@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
@@ -333,6 +333,10 @@ function SliderControl({
333
333
  const trackActive = (
334
334
  <TamaguiSlider.TrackActive
335
335
  backgroundColor={formControlColors.border}
336
+ // The fill rides the same radius as the track it sits in: without it
337
+ // tamagui's default left a pill fill inside a square track at
338
+ // `borderRadius:none` — an undeclared knob-immune shape (D-09 / LC-60).
339
+ borderRadius={borderRadius}
336
340
  transition={transitionProp}
337
341
  />
338
342
  );
@@ -1,4 +1,5 @@
1
1
  import { action } from "@multiplatform.one/storybook";
2
+ import type { GuardrailSpecimenParameter } from "@multiplatform.one/theme";
2
3
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
3
4
  import { useForm } from "@tanstack/react-form";
4
5
  import { useState } from "react";
@@ -94,6 +95,17 @@ export const Basic: Story = {
94
95
  };
95
96
 
96
97
  export const Disabled: Story = {
98
+ parameters: {
99
+ // LC-57 allowlist: this story IS the disabled-dial demo. Stepper has no
100
+ // disabledReason plumbing (component-contract change, tracked separately),
101
+ // so its +/- buttons bare-disable here by design. The warn still fires;
102
+ // the harvester tolerates exactly this code on this story.
103
+ guardrailSpecimen: {
104
+ warns: ["bare-disabled"],
105
+ reason:
106
+ "Disabled-dial specimen: the whole field rests disabled and Stepper has no disabledReason plumbing yet.",
107
+ } satisfies GuardrailSpecimenParameter,
108
+ },
97
109
  args: {
98
110
  label: "Disabled Field",
99
111
  disabled: true,
@@ -1,12 +1,35 @@
1
1
  import { useForm } from "@tanstack/react-form";
2
- import { act, fireEvent, waitFor } from "@testing-library/react";
3
- import { YStack } from "tamagui";
2
+ import { act, fireEvent, render, waitFor } from "@testing-library/react";
3
+ import { TamaguiProvider, YStack, createTamagui } from "tamagui";
4
4
  import { describe, expect, it, vi } from "vitest";
5
5
  import { renderWithProviders } from "@multiplatform.one/test-utils";
6
+ import {
7
+ createThemesBuilder,
8
+ defaultAccentTheme,
9
+ defaultBaseTheme,
10
+ defaultBuilderOptions,
11
+ } from "@multiplatform.one/theme";
12
+ import { configWithoutAnimations } from "@tamagui/config";
13
+ import { animationsCSS } from "@tamagui/config/v5-css";
6
14
  import { Button } from "../../Button";
7
15
  import { Form } from "../../Form";
8
16
  import { Switch } from "./index";
9
17
 
18
+ // House builder themes for the LC-05 mark assertion — created at MODULE
19
+ // scope: tamagui registers a config's theme variables globally at
20
+ // createTamagui time, and a config created after the first render (inside a
21
+ // test body) never resolves its tokens (Progress.spec pattern).
22
+ const houseThemes = createThemesBuilder(
23
+ defaultBaseTheme,
24
+ defaultAccentTheme,
25
+ defaultBuilderOptions,
26
+ ).themes() as Record<string, Record<string, string>>;
27
+ const houseConfig = createTamagui({
28
+ ...configWithoutAnimations,
29
+ animations: animationsCSS,
30
+ themes: houseThemes as any,
31
+ });
32
+
10
33
  describe("Switch", () => {
11
34
  describe("without form context", () => {
12
35
  it("should render with label and helper text correctly", () => {
@@ -315,4 +338,29 @@ describe("Switch", () => {
315
338
  });
316
339
  });
317
340
  });
341
+
342
+ describe("checked track mark (LC-05 ONE-EMPHASIS / UX-002)", () => {
343
+ // The checked Switch track IS a selection mark, so it resolves the shared
344
+ // accent mark token; the unchecked track stays neutral chrome. Stock test
345
+ // themes carry no $accentBackground, so mount the house builder themes
346
+ // for real resolution.
347
+ it("paints the checked track with the accent mark and the unchecked track neutral", () => {
348
+ const { container } = render(
349
+ <TamaguiProvider config={houseConfig} defaultTheme="light" disableInjectCSS>
350
+ <YStack>
351
+ <Switch label="On" name="on" defaultValue={true} />
352
+ <Switch label="Off" name="off" defaultValue={false} />
353
+ </YStack>
354
+ </TamaguiProvider>,
355
+ );
356
+ const switches = Array.from(container.querySelectorAll("[role='switch']"));
357
+ expect(switches.length).toBe(2);
358
+ const on = switches.find((s) => s.getAttribute("aria-checked") === "true") as HTMLElement;
359
+ const off = switches.find((s) => s.getAttribute("aria-checked") === "false") as HTMLElement;
360
+ expect(on).toBeTruthy();
361
+ expect(off).toBeTruthy();
362
+ expect(on.className).toContain("_bg-accentBackg");
363
+ expect(off.className).not.toContain("_bg-accentBackg");
364
+ });
365
+ });
318
366
  });
@@ -182,6 +182,63 @@ describe("TextArea", () => {
182
182
  });
183
183
  });
184
184
 
185
+ describe("late-arriving value display (create-mode seeding)", () => {
186
+ // The DOM textarea itself adopts late `defaultValue` updates while
187
+ // pristine (React DOM keeps the value attribute synced), but `charCount`
188
+ // was mount-only state — a value applied AFTER first paint (create-mode
189
+ // engine seeding, setFieldValue) rendered a stale count. Adopting a
190
+ // programmatic value must not emit onChange (LC-14).
191
+ it("form-integrated: a field value set after mount displays with a live count, without onChange", async () => {
192
+ const onChange = vi.fn();
193
+ const onChangeText = vi.fn();
194
+ let formApi: { setFieldValue: (name: "notes", value: string) => void } | undefined;
195
+ const TestComponent = () => {
196
+ const form = useForm({ defaultValues: { notes: "" } });
197
+ formApi = form as unknown as typeof formApi;
198
+ return (
199
+ <Form form={form}>
200
+ <TextArea
201
+ label="Notes"
202
+ name="notes"
203
+ showCount
204
+ onChange={onChange}
205
+ onChangeText={onChangeText}
206
+ />
207
+ </Form>
208
+ );
209
+ };
210
+ const result = renderWithProviders(<TestComponent />);
211
+ expect(result.findTextElement("0 characters")).toBeDefined();
212
+
213
+ await act(async () => {
214
+ formApi?.setFieldValue("notes", "seeded text");
215
+ });
216
+ await waitFor(() => {
217
+ expect((result.getTextArea() as HTMLTextAreaElement)?.value).toBe("seeded text");
218
+ expect(result.findTextElement("11 characters")).toBeDefined();
219
+ });
220
+ expect(onChange).not.toHaveBeenCalled();
221
+ expect(onChangeText).not.toHaveBeenCalled();
222
+ });
223
+
224
+ it("standalone controlled: a value arriving after mount updates the count, without onChange", async () => {
225
+ const onChangeText = vi.fn();
226
+ const result = renderWithProviders(
227
+ <TextArea label="Notes" value="" showCount onChangeText={onChangeText} />,
228
+ );
229
+ expect(result.findTextElement("0 characters")).toBeDefined();
230
+
231
+ result.rerender(
232
+ <TextArea label="Notes" value="late value" showCount onChangeText={onChangeText} />,
233
+ );
234
+ await waitFor(() => {
235
+ expect((result.getTextArea() as HTMLTextAreaElement)?.value).toBe("late value");
236
+ expect(result.findTextElement("10 characters")).toBeDefined();
237
+ });
238
+ expect(onChangeText).not.toHaveBeenCalled();
239
+ });
240
+ });
241
+
185
242
  describe("with useForm hook directly", () => {
186
243
  it("should handle form submission with useForm", async () => {
187
244
  const onSubmitMock = vi.fn();
@@ -190,7 +190,26 @@ export const AutoResize: Story = {
190
190
  },
191
191
  };
192
192
 
193
+ /**
194
+ * FOREIGN CONTRAST SPECIMEN (LC-56 STORY-HONESTY): the right column renders the
195
+ * RAW tamagui TextArea beside the house TextArea strictly so the difference
196
+ * stays visible. Raw primitives here are by design and labeled — knob/contrast
197
+ * probes skip this story via `parameters.foreignContrastSpecimen`.
198
+ */
193
199
  export const Comparison: Story = {
200
+ name: "Foreign contrast specimen (raw tamagui)",
201
+ parameters: {
202
+ // Machine-readable exemption for knob/contrast probes and the LC-56 linter arm.
203
+ foreignContrastSpecimen: true,
204
+ docs: {
205
+ description: {
206
+ story:
207
+ "FOREIGN CONTRAST SPECIMEN (LC-56 STORY-HONESTY). The right column is the raw " +
208
+ "tamagui TextArea, rendered for contrast only: it ignores house knobs and field " +
209
+ "recipes by design. Probes asserting house rendering must skip this story.",
210
+ },
211
+ },
212
+ },
194
213
  render: () => {
195
214
  const ComparisonExample = () => {
196
215
  const [customVal, setCustomVal] = useState("");
@@ -171,6 +171,14 @@ export function TextArea({
171
171
 
172
172
  const isControlled = value !== undefined;
173
173
 
174
+ // Count from the live value whenever an upstream source drives the field
175
+ // (controlled `value` prop or TanStack field state): the mount-only
176
+ // charCount state froze counts for values applied after first paint
177
+ // (create-mode seeding, setFieldValue). Uncontrolled standalone keeps the
178
+ // keystroke-fed local state (its defaultValue never changes underneath).
179
+ const countFrom = (textValue: string | undefined) =>
180
+ isControlled || !!(resolvedForm && name) ? (textValue ?? "").length : charCount;
181
+
174
182
  const renderTextArea = (
175
183
  textValue: string | undefined,
176
184
  handleChange?: (text: string) => void,
@@ -178,7 +186,7 @@ export function TextArea({
178
186
  hasError?: boolean,
179
187
  ) => (
180
188
  <>
181
- {showCount && countPosition.startsWith("top") && renderCount(charCount)}
189
+ {showCount && countPosition.startsWith("top") && renderCount(countFrom(textValue))}
182
190
  <YStack position="relative">
183
191
  <InputParts.Box
184
192
  height="auto"
@@ -232,7 +240,7 @@ export function TextArea({
232
240
  </InputParts.Box>
233
241
  {renderOverlay?.()}
234
242
  </YStack>
235
- {showCount && countPosition.startsWith("bottom") && renderCount(charCount)}
243
+ {showCount && countPosition.startsWith("bottom") && renderCount(countFrom(textValue))}
236
244
  </>
237
245
  );
238
246
 
@@ -106,7 +106,7 @@ function AmPmColumn({
106
106
  backgroundColor={isSelected ? formInputColors.background.focus : "transparent"}
107
107
  hoverStyle={{ backgroundColor: formInputColors.background.focus }}
108
108
  onPress={() => onChange(period)}
109
- {...(knobProps.transition ? { animation: knobProps.transition } : undefined)}
109
+ {...(knobProps.transition ? { transition: knobProps.transition } : undefined)}
110
110
  >
111
111
  <Text
112
112
  fontSize="$3"
@@ -1,10 +1,52 @@
1
- import { fireEvent, screen } from "@testing-library/react";
1
+ import { fireEvent, render, screen } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, 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 type { ReactElement } from "react";
13
+ import { TamaguiProvider, createTamagui } from "tamagui";
4
14
  import { __resetDevWarnSeen } from "../../shared/devWarn";
5
15
  import { Form } from "../../Form";
6
16
  import { ToggleGroup } from "./index";
7
17
 
18
+ // The stock test themes carry no accent ramp, so token resolution for the
19
+ // LC-05 selected mark is invisible under renderWithProviders. Mount the house
20
+ // builder themes (the same ones apps run) to assert the real resolved fill —
21
+ // the pattern Progress.spec.tsx established.
22
+ const houseThemes = createThemesBuilder(
23
+ defaultBaseTheme,
24
+ defaultAccentTheme,
25
+ defaultBuilderOptions,
26
+ ).themes() as Record<string, Record<string, string>>;
27
+
28
+ const houseConfig = createTamagui({
29
+ ...configWithoutAnimations,
30
+ animations: animationsCSS,
31
+ themes: houseThemes as any,
32
+ });
33
+
34
+ function renderWithHouseThemes(ui: ReactElement) {
35
+ return render(
36
+ <TamaguiProvider config={houseConfig} defaultTheme="light" disableInjectCSS>
37
+ {ui}
38
+ </TamaguiProvider>,
39
+ );
40
+ }
41
+
42
+ /**
43
+ * First three numeric groups (h, s, l) of an hsla() string — the digit prefix
44
+ * Tamagui embeds in the atomic class it generates for a concrete color value.
45
+ */
46
+ function hslDigits(hsla: string): string {
47
+ return (hsla.match(/\d+/g) ?? []).slice(0, 3).join("");
48
+ }
49
+
8
50
  const options = [
9
51
  { label: "Left", value: "left" },
10
52
  { label: "Center", value: "center" },
@@ -162,4 +204,25 @@ describe("ToggleGroup", () => {
162
204
  expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("bare-disabled"));
163
205
  });
164
206
  });
207
+
208
+ describe("selected mark (LC-05 ONE-EMPHASIS / D-01)", () => {
209
+ it("fills the selected segment with the accent-tinted surface, never the neutral tier", () => {
210
+ const { container } = renderWithHouseThemes(
211
+ <ToggleGroup label="Alignment" options={options} defaultValue="left" />,
212
+ );
213
+ // Segmented-control selection strength is pinned at TINTED (D-01
214
+ // ViewSwitcher rider): the accent ramp's surface tier in a light scheme
215
+ // is its palest step (accent11) — the same channel ViewSwitcher takes.
216
+ const tint = houseThemes.light.accent11;
217
+ expect(tint).toBeTruthy();
218
+ const selected = container.querySelector('[data-state="on"]') as HTMLElement;
219
+ const idle = container.querySelector('[data-state="off"]') as HTMLElement;
220
+ expect(selected).toBeTruthy();
221
+ expect(idle).toBeTruthy();
222
+ expect(selected.className).toContain(`_bg-hsla${hslDigits(tint)}`);
223
+ expect(idle.className).not.toContain(`_bg-hsla${hslDigits(tint)}`);
224
+ // Ink marks selection nowhere: the old neutral $color8 fill is gone.
225
+ expect(selected.className).not.toContain("_bg-color8");
226
+ });
227
+ });
165
228
  });
@@ -252,7 +252,26 @@ const alignmentOptions = [
252
252
  { label: "Right", value: "right" },
253
253
  ];
254
254
 
255
+ /**
256
+ * FOREIGN CONTRAST SPECIMEN (LC-56 STORY-HONESTY): the right column renders the
257
+ * RAW tamagui ToggleGroup beside the house ToggleGroup strictly so the
258
+ * difference stays visible. Raw primitives here are by design and labeled —
259
+ * knob/contrast probes skip this story via `parameters.foreignContrastSpecimen`.
260
+ */
255
261
  export const Comparison: Story = {
262
+ name: "Foreign contrast specimen (raw tamagui)",
263
+ parameters: {
264
+ // Machine-readable exemption for knob/contrast probes and the LC-56 linter arm.
265
+ foreignContrastSpecimen: true,
266
+ docs: {
267
+ description: {
268
+ story:
269
+ "FOREIGN CONTRAST SPECIMEN (LC-56 STORY-HONESTY). The right column is the raw " +
270
+ "tamagui ToggleGroup, rendered for contrast only: it ignores house knobs and " +
271
+ "control recipes by design. Probes asserting house rendering must skip this story.",
272
+ },
273
+ },
274
+ },
256
275
  render: () => {
257
276
  const ComparisonExample = () => {
258
277
  const [customVal, setCustomVal] = useState("left");
@@ -4,6 +4,7 @@ import {
4
4
  ensureFocusVisibleRing,
5
5
  ensureKeyboardModalityTracking,
6
6
  keyboardFocusRingProps,
7
+ useAccentTintedSurface,
7
8
  useReadableTextOn,
8
9
  wasKeyboardFocus,
9
10
  } from "@multiplatform.one/theme";
@@ -30,6 +31,11 @@ import {
30
31
  useResolvedValidators,
31
32
  } from "../../shared/utils";
32
33
 
34
+ // NOTE: no `active` variant here — the selected fill is runtime-resolved
35
+ // (accent-tinted surface, LC-05/D-01), so it rides direct props re-applied
36
+ // through hover/press. A static variant would expand at its key position and
37
+ // paint its stale value OVER those direct props (the exact drift the LC-40
38
+ // wash comment below records for the disabled tier).
33
39
  const ToggleItemFrame = styled(TamaguiToggleGroup.Item, {
34
40
  cursor: "pointer",
35
41
  userSelect: "none",
@@ -56,20 +62,6 @@ const ToggleItemFrame = styled(TamaguiToggleGroup.Item, {
56
62
  },
57
63
  },
58
64
  },
59
- active: {
60
- true: {
61
- backgroundColor: formButtonColors.border.active,
62
- borderColor: formButtonColors.border.active,
63
- hoverStyle: {
64
- backgroundColor: formButtonColors.border.active,
65
- borderColor: formButtonColors.border.active,
66
- },
67
- pressStyle: {
68
- backgroundColor: formButtonColors.border.active,
69
- borderColor: formButtonColors.border.active,
70
- },
71
- },
72
- },
73
65
  } as const,
74
66
  });
75
67
 
@@ -244,11 +236,19 @@ export function ToggleGroup({
244
236
  id: idProp,
245
237
  compact,
246
238
  });
247
- // UX-018 / Axiom 15: the selected segment fills with `$color8`
248
- // (formButtonColors.border.active). Under a bright tint the label inherits
249
- // the scheme `$color` (near-white in dark) → 1.24:1 on bright yellow. The
250
- // readable label is the paper/ink anchor that reads on the actual fill.
251
- const onSelectedLabel = useReadableTextOn("$color8");
239
+ // LC-05 / D-01: selection is ONE accent language across every choice-control
240
+ // family this selected segment filled with the neutral `$color8` tier, the
241
+ // catalog's last ink/neutral-marked selection surface. Segmented-control
242
+ // STRENGTH is pinned at TINTED (the D-01 ViewSwitcher rider not the solid
243
+ // an accent CTA takes), so the fill is the accent ramp's surface tier
244
+ // mirrored by scheme, the same channel ViewSwitcher resolves. When the
245
+ // accent ramp is absent (tint sub-themes) the neutral tier stays as the
246
+ // declared fallback so selection never goes invisible.
247
+ // UX-018 / Axiom 15 kept: the label is the paper/ink anchor luminance-picked
248
+ // for the ACTUAL fill, never an assumed scheme token.
249
+ const selectedTint = useAccentTintedSurface();
250
+ const selectedFill = selectedTint ?? formButtonColors.border.active;
251
+ const onSelectedLabel = useReadableTextOn(selectedFill);
252
252
  // Chromium drops keyboard modality when tamagui's group redirects focus to
253
253
  // an item, so :focus-visible/focusVisibleStyle can miss — paint the ring
254
254
  // manually on keyboard-origin focus (see theme keyboardFocusRing).
@@ -344,9 +344,13 @@ export function ToggleGroup({
344
344
  const itemDisabled = Boolean(disabled || option.disabled);
345
345
  const itemDescribedBy = option.disabled ? itemReasonIdFor(option.disabledReason) : undefined;
346
346
  const isTabStop = index === tabStopIndex;
347
+ // The accent-tinted selected fill (border rides the fill, as the
348
+ // neutral chip's did) — re-applied through hover/press below so the
349
+ // neutral state layer never paints over the selection mark (the LC-05
350
+ // rule the checked Switch track and ViewSwitcher chip already follow).
347
351
  const activeColors = {
348
- backgroundColor: formButtonColors.border.active,
349
- borderColor: formButtonColors.border.active,
352
+ backgroundColor: selectedFill,
353
+ borderColor: selectedFill,
350
354
  };
351
355
 
352
356
  return (
@@ -365,18 +369,16 @@ export function ToggleGroup({
365
369
  paddingHorizontal="$2"
366
370
  borderWidth={knobProps.borderRadius.borderWidth}
367
371
  outlined={knobProps.outlined}
368
- animation={knobProps.transition}
372
+ transition={knobProps.transition}
369
373
  disabled={itemDisabled}
370
374
  {...(itemDescribedBy ? { "aria-describedby": itemDescribedBy } : undefined)}
371
375
  // LC-40 DISABLED-VISIBLE (was DG-ST-03 hand-roll): segments are
372
- // text-bearing chrome — a disabled segment drops the live active
373
- // fill entirely (the `active` variant expands at its key position
374
- // and would beat the wash), so the wash owns the chrome and the
375
- // label pins to the lowest AA tier below. A SELECTED disabled
376
- // segment takes the recipe's stronger selected tier so the chosen
377
- // option stays visible (Axiom 6), not aria-only.
376
+ // text-bearing chrome — a disabled segment drops the live selected
377
+ // fill entirely, so the wash owns the chrome and the label pins to
378
+ // the lowest AA tier below. A SELECTED disabled segment takes the
379
+ // recipe's stronger selected tier so the chosen option stays
380
+ // visible (Axiom 6), not aria-only.
378
381
  {...(selected && !itemDisabled ? activeColors : undefined)}
379
- {...(selected && !itemDisabled ? { active: true, activeStyle: activeColors } : undefined)}
380
382
  {...(itemDisabled
381
383
  ? selected
382
384
  ? disabledState.selectedSurfaceKnobProps
@@ -15,7 +15,9 @@ const manyOptions = Array.from({ length: 60 }, (_, i) => ({
15
15
  label: `Option ${i + 1}`,
16
16
  }));
17
17
 
18
- const fewOptions = Array.from({ length: 3 }, (_, i) => ({
18
+ // Six entries: short enough that the floating list never scrolls (the story's
19
+ // point) while clearing the ≤5 `select-too-few-options` guardrail (DG-CTRL-01).
20
+ const fewOptions = Array.from({ length: 6 }, (_, i) => ({
19
21
  value: `option-${i + 1}`,
20
22
  label: `Option ${i + 1}`,
21
23
  }));
@@ -45,7 +47,7 @@ export const ShortSelect: Story = {
45
47
  <YStack maxWidth={320}>
46
48
  <Select
47
49
  id="fls-short"
48
- label="Three options"
50
+ label="Six options"
49
51
  options={fewOptions}
50
52
  helperText="No arrows expected"
51
53
  />
@@ -66,7 +66,7 @@ export function TimeColumn({
66
66
  justifyContent="center"
67
67
  backgroundColor={isSelected ? formInputColors.background.focus : "transparent"}
68
68
  hoverStyle={{ backgroundColor: formInputColors.background.focus }}
69
- {...(knobProps.transition ? { animation: knobProps.transition } : undefined)}
69
+ {...(knobProps.transition ? { transition: knobProps.transition } : undefined)}
70
70
  >
71
71
  <Text
72
72
  fontSize="$4"
@@ -66,6 +66,10 @@ function restoreLater(
66
66
  insideRef?: RefObject<HTMLElement | null>,
67
67
  ) {
68
68
  const restore = () => {
69
+ // Fires from the unmount path, so the document can be gone by now (a test
70
+ // environment torn down inside the retry window). `isConnected` stays
71
+ // stale-true on a detached node, so it does not cover this.
72
+ if (!canUseDom()) return;
69
73
  const target = prevRef.current;
70
74
  if (!target || !target.isConnected) return;
71
75
  if (focusIsDropped(insideRef?.current ?? null)) target.focus();
@@ -102,11 +106,17 @@ export function useSheetModalFocus(open: boolean, frameRef: RefObject<HTMLElemen
102
106
 
103
107
  // Focus moves in once the sheet has mounted its frame (spring start).
104
108
  const focusIn = () => {
109
+ if (!canUseDom()) return;
105
110
  if (frame.contains(document.activeElement)) return;
106
111
  const first = frame.querySelector<HTMLElement>(FOCUSABLE);
107
112
  (first ?? frame).focus({ preventScroll: true });
108
113
  };
109
- const raf = requestAnimationFrame(() => requestAnimationFrame(focusIn));
114
+ // Both frames are tracked: cancelling only the outer one leaves the inner
115
+ // callback live once the outer has already run.
116
+ let innerRaf = 0;
117
+ const raf = requestAnimationFrame(() => {
118
+ innerRaf = requestAnimationFrame(focusIn);
119
+ });
110
120
 
111
121
  // Light Tab trap: cycle within the frame (modal sheet owns focus).
112
122
  const onKeyDown = (e: KeyboardEvent) => {
@@ -132,6 +142,7 @@ export function useSheetModalFocus(open: boolean, frameRef: RefObject<HTMLElemen
132
142
  frame.addEventListener("keydown", onKeyDown);
133
143
  return () => {
134
144
  cancelAnimationFrame(raf);
145
+ cancelAnimationFrame(innerRaf);
135
146
  frame.removeEventListener("keydown", onKeyDown);
136
147
  restoreLater(prevRef, frameRef);
137
148
  };
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { bidiIsolate, t } from "./t";
3
+
4
+ describe("t (uninitialized-i18n fallback)", () => {
5
+ it("returns the key with {{var}} interpolation applied", () => {
6
+ expect(t("Delete row {{row}}", { row: 3 })).toBe("Delete row 3");
7
+ });
8
+
9
+ it("leaves unknown variables as-is", () => {
10
+ expect(t("Delete row {{row}}", { other: 1 })).toBe("Delete row {{row}}");
11
+ });
12
+ });
13
+
14
+ describe("bidiIsolate (LC-58 BIDI-ISOLATION)", () => {
15
+ it("wraps the run in FSI…PDI so RTL contexts cannot reorder it", () => {
16
+ expect(bidiIsolate("1–5 of 5")).toBe("\u20681–5 of 5\u2069");
17
+ expect(bidiIsolate("Search...")).toBe("\u2068Search...\u2069");
18
+ });
19
+
20
+ it("keeps LTR content byte-identical inside the isolates", () => {
21
+ // First-strong isolation adds only the invisible FSI/PDI frame — the
22
+ // visible run is unchanged, so LTR rendering is unaffected.
23
+ const isolated = bidiIsolate("Search...");
24
+ expect(isolated.slice(1, -1)).toBe("Search...");
25
+ expect(isolated.startsWith("\u2068")).toBe(true);
26
+ expect(isolated.endsWith("\u2069")).toBe(true);
27
+ });
28
+
29
+ it("preserves an RTL run's own base direction (first-strong semantics)", () => {
30
+ // An Arabic run keeps its first strong character (RTL) as the isolate's
31
+ // base direction — isolation never forces LTR on translated copy.
32
+ const rtl = "بحث…";
33
+ expect(bidiIsolate(rtl)).toBe(`\u2068${rtl}\u2069`);
34
+ });
35
+
36
+ it("leaves empty strings alone (nothing to isolate)", () => {
37
+ expect(bidiIsolate("")).toBe("");
38
+ });
39
+ });
package/src/shared/t.ts CHANGED
@@ -21,3 +21,23 @@ export function t(key: string, options?: TOptions): string {
21
21
  }
22
22
  return interpolate(key, options);
23
23
  }
24
+
25
+ /**
26
+ * First-strong bidi isolation — FSI…PDI (`\u2068…\u2069`), the string form of
27
+ * `<bdi>` (LC-58 BIDI-ISOLATION). Same helper as `components/src/shared/t.ts`
28
+ * and `table/src/utils/withInterp.ts` (the interpolation-home duplication
29
+ * precedent) — the helper lives beside each package's `t()` interpolator.
30
+ * Formatted runs that mix directions inside an RTL paragraph reorder by the
31
+ * bidi algorithm's rules — "1–5 of 5" renders "of 5 5–1", a trailing
32
+ * "Search..." ellipsis flips to "…Search" — because each weak/latin segment
33
+ * resolves independently. Isolating the WHOLE run gives it its own base
34
+ * direction from its first strong character, so untranslated latin copy
35
+ * renders LTR as a unit while translated RTL copy still renders RTL. Apply
36
+ * at the interpolation site of visible strings; never per-string manual
37
+ * marks, never aria-labels (invisible to reorder; breaks exact-match label
38
+ * queries).
39
+ */
40
+ export function bidiIsolate(text: string): string {
41
+ if (!text) return text;
42
+ return `\u2068${text}\u2069`;
43
+ }
@@ -40,8 +40,16 @@ export interface ButtonProps extends Omit<TamaguiButtonProps, "form" | "icon" |
40
40
  * — bare `disabled` emits `bare-disabled`.
41
41
  */
42
42
  disabledReason?: string;
43
+ /**
44
+ * Where the visible reason renders relative to the control. `"below"`
45
+ * (default) stacks it under the button — right for forms and vertical
46
+ * layouts. `"inline"` puts it beside the button on the same line — for
47
+ * toolbar/control rows, where a stacked reason breaks the row's shared
48
+ * control height and wraps into cramped multi-line type.
49
+ */
50
+ disabledReasonPlacement?: "below" | "inline";
43
51
  }
44
- export declare function Button({ children, action, form: formProp, loading, accent, error, warning, success, skeleton, outlined, disabled, theme, onPress, onKeyDown, tabIndex, icon, iconAfter, compact, verb, noun, actionRole, disabledReason, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
52
+ export declare function Button({ children, action, form: formProp, loading, accent, error, warning, success, skeleton, outlined, disabled, theme, onPress, onKeyDown, tabIndex, icon, iconAfter, compact, verb, noun, actionRole, disabledReason, disabledReasonPlacement, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
45
53
  export declare namespace Button {
46
54
  var Icon: (props: {
47
55
  children: React.ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Button/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAO,EAEL,KAAK,WAAW,IAAI,kBAAkB,EAQvC,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAuB,MAAM,cAAc,CAAC;AAyBpE,0DAA0D;AAC1D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE,KAAK,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAgF7D,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;IAC1F,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,MAAM,EACN,IAAI,EAAE,QAAQ,EACd,OAAO,EACP,MAAM,EACN,KAAK,EACL,OAAO,EACP,OAAO,EACP,QAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,OAAO,EACP,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,cAAc,EACd,GAAG,KAAK,EACT,EAAE,WAAW,2CAgSb;yBAxTe,MAAM;;;iBAsCP,CAAC;YACH,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Button/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAO,EAEL,KAAK,WAAW,IAAI,kBAAkB,EASvC,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAuB,MAAM,cAAc,CAAC;AAyBpE,0DAA0D;AAC1D,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE,KAAK,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAgF7D,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;IAC1F,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC9C;AAED,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,MAAM,EACN,IAAI,EAAE,QAAQ,EACd,OAAO,EACP,MAAM,EACN,KAAK,EACL,OAAO,EACP,OAAO,EACP,QAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,OAAO,EACP,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,cAAc,EACd,uBAAiC,EACjC,GAAG,KAAK,EACT,EAAE,WAAW,2CAuTb;yBAhVe,MAAM;;;iBA0BS,CAAC;YAAsB,CAAC"}
@@ -10,9 +10,15 @@ export declare const EMPTY = "\u2014";
10
10
  export declare function asText(v: any): string;
11
11
  export interface NumericFormatOptions {
12
12
  precision?: number;
13
- /** ISO 4217 currency code, e.g. "USD". */
13
+ /** ISO 4217 currency code (or a symbol a code is known for), e.g. "USD". */
14
14
  currency?: string;
15
15
  }
16
+ /**
17
+ * Read-only numeric cells speak the house number registers (LC-12 render
18
+ * channel): the same figure reads identically in a table cell, a KPI tile
19
+ * and a group aggregate. `precision` pins the fraction digits a Frappe field
20
+ * declares; the register owns everything else.
21
+ */
16
22
  export declare function formatNumericText(num: number, options?: NumericFormatOptions): string;
17
23
  export { ISO_DATE_ONLY } from "@multiplatform.one/theme";
18
24
  export interface DateFormatOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/FieldDisplay/formatters.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,KAAK,WAAM,CAAC;AAEzB,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAYrC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAczF;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAIlF"}
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/FieldDisplay/formatters.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,KAAK,WAAM,CAAC;AAEzB,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAYrC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAIzF;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAIlF"}