@multiplatform.one/forms 7.6.2 → 7.7.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 (492) hide show
  1. package/dist/cjs/Button/index.cjs +7 -1
  2. package/dist/cjs/Button/index.native.js +7 -1
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/Chip/index.cjs +1 -3
  5. package/dist/cjs/Chip/index.native.js +5 -3
  6. package/dist/cjs/Chip/index.native.js.map +1 -1
  7. package/dist/cjs/ContextualSaveBar/index.cjs +19 -3
  8. package/dist/cjs/ContextualSaveBar/index.native.js +19 -3
  9. package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
  10. package/dist/cjs/DescriptionList/index.cjs +38 -12
  11. package/dist/cjs/DescriptionList/index.native.js +38 -12
  12. package/dist/cjs/DescriptionList/index.native.js.map +1 -1
  13. package/dist/cjs/ErrorSummary.cjs +4 -1
  14. package/dist/cjs/ErrorSummary.native.js +4 -1
  15. package/dist/cjs/ErrorSummary.native.js.map +1 -1
  16. package/dist/cjs/FloatingPanel/useFloatingPanel.cjs +24 -2
  17. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js +43 -2
  18. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  19. package/dist/cjs/InputParts/index.cjs +42 -2
  20. package/dist/cjs/InputParts/index.native.js +42 -2
  21. package/dist/cjs/InputParts/index.native.js.map +1 -1
  22. package/dist/cjs/fields/Checkbox/Checkbox.cjs +5 -2
  23. package/dist/cjs/fields/Checkbox/Checkbox.native.js +6 -3
  24. package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
  25. package/dist/cjs/fields/Checkbox/CheckboxGroup.cjs +69 -59
  26. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js +75 -65
  27. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  28. package/dist/cjs/fields/Checkbox/checkboxGroupContext.cjs +33 -0
  29. package/dist/cjs/fields/Checkbox/checkboxGroupContext.native.js +36 -0
  30. package/dist/cjs/fields/Checkbox/checkboxGroupContext.native.js.map +1 -0
  31. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +402 -0
  32. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +441 -0
  33. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -0
  34. package/dist/cjs/fields/DatePicker/DatetimePicker.cjs +2 -376
  35. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +69 -297
  36. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  37. package/dist/cjs/fields/DatePicker/catalog.cjs +306 -0
  38. package/dist/cjs/fields/DatePicker/catalog.native.js +350 -0
  39. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -0
  40. package/dist/cjs/fields/DatePicker/index.cjs +7 -280
  41. package/dist/cjs/fields/DatePicker/index.native.js +66 -185
  42. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  43. package/dist/cjs/fields/DatePicker/parts.cjs +12 -9
  44. package/dist/cjs/fields/DatePicker/parts.native.js +12 -9
  45. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  46. package/dist/cjs/fields/Duration/index.cjs +29 -3
  47. package/dist/cjs/fields/Duration/index.native.js +29 -3
  48. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  49. package/dist/cjs/fields/PhoneInput/index.cjs +9 -4
  50. package/dist/cjs/fields/PhoneInput/index.native.js +13 -6
  51. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  52. package/dist/cjs/fields/Rating/index.cjs +1 -1
  53. package/dist/cjs/fields/Rating/index.native.js +4 -1
  54. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  55. package/dist/cjs/fields/SearchInput/index.cjs +6 -0
  56. package/dist/cjs/fields/SearchInput/index.native.js +6 -0
  57. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  58. package/dist/cjs/fields/Select/index.cjs +75 -2
  59. package/dist/cjs/fields/Select/index.native.js +77 -2
  60. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  61. package/dist/cjs/fields/Signature/index.cjs +9 -5
  62. package/dist/cjs/fields/Signature/index.native.js +9 -5
  63. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  64. package/dist/cjs/fields/Slider/index.cjs +3 -1
  65. package/dist/cjs/fields/Slider/index.native.js +3 -1
  66. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  67. package/dist/cjs/fields/Switch/index.cjs +5 -18
  68. package/dist/cjs/fields/Switch/index.native.js +5 -18
  69. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  70. package/dist/cjs/fields/TextArea/index.cjs +19 -5
  71. package/dist/cjs/fields/TextArea/index.native.js +23 -5
  72. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  73. package/dist/cjs/fields/TimePicker/catalog.cjs +203 -0
  74. package/dist/cjs/fields/TimePicker/catalog.native.js +227 -0
  75. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -0
  76. package/dist/cjs/fields/TimePicker/index.cjs +6 -177
  77. package/dist/cjs/fields/TimePicker/index.native.js +74 -85
  78. package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
  79. package/dist/cjs/fields/TimeRangeScrubber/geometry.cjs +6 -0
  80. package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js +6 -0
  81. package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  82. package/dist/cjs/fields/TimeRangeScrubber/index.cjs +34 -14
  83. package/dist/cjs/fields/TimeRangeScrubber/index.native.js +38 -14
  84. package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
  85. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +202 -0
  86. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +211 -0
  87. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -0
  88. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.cjs +30 -0
  89. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js +33 -0
  90. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -0
  91. package/dist/cjs/fields/nativeSelect.cjs +30 -0
  92. package/dist/cjs/fields/nativeSelect.native.js +33 -0
  93. package/dist/cjs/fields/nativeSelect.native.js.map +1 -0
  94. package/dist/cjs/index.cjs +1 -0
  95. package/dist/cjs/index.native.js +1 -0
  96. package/dist/cjs/index.native.js.map +1 -1
  97. package/dist/cjs/themedPrimitives.cjs +5 -0
  98. package/dist/cjs/themedPrimitives.native.js +5 -0
  99. package/dist/cjs/themedPrimitives.native.js.map +1 -1
  100. package/dist/esm/Button/index.mjs +8 -2
  101. package/dist/esm/Button/index.mjs.map +1 -1
  102. package/dist/esm/Button/index.native.js +8 -2
  103. package/dist/esm/Button/index.native.js.map +1 -1
  104. package/dist/esm/Chip/index.mjs +1 -3
  105. package/dist/esm/Chip/index.mjs.map +1 -1
  106. package/dist/esm/Chip/index.native.js +5 -3
  107. package/dist/esm/Chip/index.native.js.map +1 -1
  108. package/dist/esm/ContextualSaveBar/index.mjs +19 -3
  109. package/dist/esm/ContextualSaveBar/index.mjs.map +1 -1
  110. package/dist/esm/ContextualSaveBar/index.native.js +19 -3
  111. package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
  112. package/dist/esm/DescriptionList/index.mjs +38 -12
  113. package/dist/esm/DescriptionList/index.mjs.map +1 -1
  114. package/dist/esm/DescriptionList/index.native.js +38 -12
  115. package/dist/esm/DescriptionList/index.native.js.map +1 -1
  116. package/dist/esm/ErrorSummary.mjs +5 -2
  117. package/dist/esm/ErrorSummary.mjs.map +1 -1
  118. package/dist/esm/ErrorSummary.native.js +5 -2
  119. package/dist/esm/ErrorSummary.native.js.map +1 -1
  120. package/dist/esm/FloatingPanel/useFloatingPanel.mjs +24 -3
  121. package/dist/esm/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  122. package/dist/esm/FloatingPanel/useFloatingPanel.native.js +43 -3
  123. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  124. package/dist/esm/InputParts/index.mjs +43 -3
  125. package/dist/esm/InputParts/index.mjs.map +1 -1
  126. package/dist/esm/InputParts/index.native.js +43 -3
  127. package/dist/esm/InputParts/index.native.js.map +1 -1
  128. package/dist/esm/fields/Checkbox/Checkbox.mjs +5 -2
  129. package/dist/esm/fields/Checkbox/Checkbox.mjs.map +1 -1
  130. package/dist/esm/fields/Checkbox/Checkbox.native.js +6 -3
  131. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  132. package/dist/esm/fields/Checkbox/CheckboxGroup.mjs +69 -59
  133. package/dist/esm/fields/Checkbox/CheckboxGroup.mjs.map +1 -1
  134. package/dist/esm/fields/Checkbox/CheckboxGroup.native.js +75 -65
  135. package/dist/esm/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  136. package/dist/esm/fields/Checkbox/checkboxGroupContext.mjs +7 -0
  137. package/dist/esm/fields/Checkbox/checkboxGroupContext.mjs.map +1 -0
  138. package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js +7 -0
  139. package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js.map +1 -0
  140. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +377 -0
  141. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -0
  142. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +413 -0
  143. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -0
  144. package/dist/esm/fields/DatePicker/DatetimePicker.mjs +1 -375
  145. package/dist/esm/fields/DatePicker/DatetimePicker.mjs.map +1 -1
  146. package/dist/esm/fields/DatePicker/DatetimePicker.native.js +65 -293
  147. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  148. package/dist/esm/fields/DatePicker/catalog.mjs +276 -0
  149. package/dist/esm/fields/DatePicker/catalog.mjs.map +1 -0
  150. package/dist/esm/fields/DatePicker/catalog.native.js +317 -0
  151. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -0
  152. package/dist/esm/fields/DatePicker/index.mjs +1 -274
  153. package/dist/esm/fields/DatePicker/index.mjs.map +1 -1
  154. package/dist/esm/fields/DatePicker/index.native.js +60 -179
  155. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  156. package/dist/esm/fields/DatePicker/parts.mjs +13 -10
  157. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  158. package/dist/esm/fields/DatePicker/parts.native.js +13 -10
  159. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  160. package/dist/esm/fields/Duration/index.mjs +29 -4
  161. package/dist/esm/fields/Duration/index.mjs.map +1 -1
  162. package/dist/esm/fields/Duration/index.native.js +29 -4
  163. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  164. package/dist/esm/fields/PhoneInput/index.mjs +9 -4
  165. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  166. package/dist/esm/fields/PhoneInput/index.native.js +13 -6
  167. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  168. package/dist/esm/fields/Rating/index.mjs +2 -2
  169. package/dist/esm/fields/Rating/index.mjs.map +1 -1
  170. package/dist/esm/fields/Rating/index.native.js +5 -2
  171. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  172. package/dist/esm/fields/SearchInput/index.mjs +6 -0
  173. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  174. package/dist/esm/fields/SearchInput/index.native.js +6 -0
  175. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  176. package/dist/esm/fields/Select/index.mjs +76 -3
  177. package/dist/esm/fields/Select/index.mjs.map +1 -1
  178. package/dist/esm/fields/Select/index.native.js +78 -3
  179. package/dist/esm/fields/Select/index.native.js.map +1 -1
  180. package/dist/esm/fields/Signature/index.mjs +10 -6
  181. package/dist/esm/fields/Signature/index.mjs.map +1 -1
  182. package/dist/esm/fields/Signature/index.native.js +10 -6
  183. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  184. package/dist/esm/fields/Slider/index.mjs +4 -2
  185. package/dist/esm/fields/Slider/index.mjs.map +1 -1
  186. package/dist/esm/fields/Slider/index.native.js +4 -2
  187. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  188. package/dist/esm/fields/Switch/index.mjs +6 -19
  189. package/dist/esm/fields/Switch/index.mjs.map +1 -1
  190. package/dist/esm/fields/Switch/index.native.js +6 -19
  191. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  192. package/dist/esm/fields/TextArea/index.mjs +19 -5
  193. package/dist/esm/fields/TextArea/index.mjs.map +1 -1
  194. package/dist/esm/fields/TextArea/index.native.js +23 -5
  195. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  196. package/dist/esm/fields/TimePicker/catalog.mjs +174 -0
  197. package/dist/esm/fields/TimePicker/catalog.mjs.map +1 -0
  198. package/dist/esm/fields/TimePicker/catalog.native.js +195 -0
  199. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -0
  200. package/dist/esm/fields/TimePicker/index.mjs +2 -173
  201. package/dist/esm/fields/TimePicker/index.mjs.map +1 -1
  202. package/dist/esm/fields/TimePicker/index.native.js +76 -87
  203. package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
  204. package/dist/esm/fields/TimeRangeScrubber/geometry.mjs +6 -1
  205. package/dist/esm/fields/TimeRangeScrubber/geometry.mjs.map +1 -1
  206. package/dist/esm/fields/TimeRangeScrubber/geometry.native.js +6 -1
  207. package/dist/esm/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  208. package/dist/esm/fields/TimeRangeScrubber/index.mjs +37 -18
  209. package/dist/esm/fields/TimeRangeScrubber/index.mjs.map +1 -1
  210. package/dist/esm/fields/TimeRangeScrubber/index.native.js +41 -18
  211. package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
  212. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +166 -0
  213. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -0
  214. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +172 -0
  215. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -0
  216. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.mjs +5 -0
  217. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.mjs.map +1 -0
  218. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js +5 -0
  219. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -0
  220. package/dist/esm/fields/nativeSelect.mjs +5 -0
  221. package/dist/esm/fields/nativeSelect.mjs.map +1 -0
  222. package/dist/esm/fields/nativeSelect.native.js +5 -0
  223. package/dist/esm/fields/nativeSelect.native.js.map +1 -0
  224. package/dist/esm/index.mjs +2 -2
  225. package/dist/esm/index.mjs.map +1 -1
  226. package/dist/esm/index.native.js +2 -2
  227. package/dist/esm/index.native.js.map +1 -1
  228. package/dist/esm/themedPrimitives.mjs +5 -0
  229. package/dist/esm/themedPrimitives.mjs.map +1 -1
  230. package/dist/esm/themedPrimitives.native.js +5 -0
  231. package/dist/esm/themedPrimitives.native.js.map +1 -1
  232. package/dist/jsx/Button/index.mjs +8 -2
  233. package/dist/jsx/Button/index.mjs.map +1 -1
  234. package/dist/jsx/Button/index.native.js +7 -1
  235. package/dist/jsx/Button/index.native.js.map +1 -1
  236. package/dist/jsx/Chip/index.mjs +1 -3
  237. package/dist/jsx/Chip/index.mjs.map +1 -1
  238. package/dist/jsx/Chip/index.native.js +5 -3
  239. package/dist/jsx/Chip/index.native.js.map +1 -1
  240. package/dist/jsx/ContextualSaveBar/index.mjs +19 -3
  241. package/dist/jsx/ContextualSaveBar/index.mjs.map +1 -1
  242. package/dist/jsx/ContextualSaveBar/index.native.js +19 -3
  243. package/dist/jsx/ContextualSaveBar/index.native.js.map +1 -1
  244. package/dist/jsx/DescriptionList/index.mjs +38 -12
  245. package/dist/jsx/DescriptionList/index.mjs.map +1 -1
  246. package/dist/jsx/DescriptionList/index.native.js +38 -12
  247. package/dist/jsx/DescriptionList/index.native.js.map +1 -1
  248. package/dist/jsx/ErrorSummary.mjs +5 -2
  249. package/dist/jsx/ErrorSummary.mjs.map +1 -1
  250. package/dist/jsx/ErrorSummary.native.js +4 -1
  251. package/dist/jsx/ErrorSummary.native.js.map +1 -1
  252. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs +24 -3
  253. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  254. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js +43 -2
  255. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  256. package/dist/jsx/InputParts/index.mjs +43 -3
  257. package/dist/jsx/InputParts/index.mjs.map +1 -1
  258. package/dist/jsx/InputParts/index.native.js +42 -2
  259. package/dist/jsx/InputParts/index.native.js.map +1 -1
  260. package/dist/jsx/fields/Checkbox/Checkbox.mjs +5 -2
  261. package/dist/jsx/fields/Checkbox/Checkbox.mjs.map +1 -1
  262. package/dist/jsx/fields/Checkbox/Checkbox.native.js +6 -3
  263. package/dist/jsx/fields/Checkbox/Checkbox.native.js.map +1 -1
  264. package/dist/jsx/fields/Checkbox/CheckboxGroup.mjs +69 -59
  265. package/dist/jsx/fields/Checkbox/CheckboxGroup.mjs.map +1 -1
  266. package/dist/jsx/fields/Checkbox/CheckboxGroup.native.js +75 -65
  267. package/dist/jsx/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  268. package/dist/jsx/fields/Checkbox/checkboxGroupContext.mjs +7 -0
  269. package/dist/jsx/fields/Checkbox/checkboxGroupContext.mjs.map +1 -0
  270. package/dist/jsx/fields/Checkbox/checkboxGroupContext.native.js +36 -0
  271. package/dist/jsx/fields/Checkbox/checkboxGroupContext.native.js.map +1 -0
  272. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +377 -0
  273. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -0
  274. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +441 -0
  275. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -0
  276. package/dist/jsx/fields/DatePicker/DatetimePicker.mjs +1 -375
  277. package/dist/jsx/fields/DatePicker/DatetimePicker.mjs.map +1 -1
  278. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +69 -297
  279. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  280. package/dist/jsx/fields/DatePicker/catalog.mjs +276 -0
  281. package/dist/jsx/fields/DatePicker/catalog.mjs.map +1 -0
  282. package/dist/jsx/fields/DatePicker/catalog.native.js +350 -0
  283. package/dist/jsx/fields/DatePicker/catalog.native.js.map +1 -0
  284. package/dist/jsx/fields/DatePicker/index.mjs +1 -274
  285. package/dist/jsx/fields/DatePicker/index.mjs.map +1 -1
  286. package/dist/jsx/fields/DatePicker/index.native.js +66 -185
  287. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  288. package/dist/jsx/fields/DatePicker/parts.mjs +13 -10
  289. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  290. package/dist/jsx/fields/DatePicker/parts.native.js +12 -9
  291. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  292. package/dist/jsx/fields/Duration/index.mjs +29 -4
  293. package/dist/jsx/fields/Duration/index.mjs.map +1 -1
  294. package/dist/jsx/fields/Duration/index.native.js +29 -3
  295. package/dist/jsx/fields/Duration/index.native.js.map +1 -1
  296. package/dist/jsx/fields/PhoneInput/index.mjs +9 -4
  297. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  298. package/dist/jsx/fields/PhoneInput/index.native.js +13 -6
  299. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  300. package/dist/jsx/fields/Rating/index.mjs +2 -2
  301. package/dist/jsx/fields/Rating/index.mjs.map +1 -1
  302. package/dist/jsx/fields/Rating/index.native.js +4 -1
  303. package/dist/jsx/fields/Rating/index.native.js.map +1 -1
  304. package/dist/jsx/fields/SearchInput/index.mjs +6 -0
  305. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  306. package/dist/jsx/fields/SearchInput/index.native.js +6 -0
  307. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  308. package/dist/jsx/fields/Select/index.mjs +76 -3
  309. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  310. package/dist/jsx/fields/Select/index.native.js +77 -2
  311. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  312. package/dist/jsx/fields/Signature/index.mjs +10 -6
  313. package/dist/jsx/fields/Signature/index.mjs.map +1 -1
  314. package/dist/jsx/fields/Signature/index.native.js +9 -5
  315. package/dist/jsx/fields/Signature/index.native.js.map +1 -1
  316. package/dist/jsx/fields/Slider/index.mjs +4 -2
  317. package/dist/jsx/fields/Slider/index.mjs.map +1 -1
  318. package/dist/jsx/fields/Slider/index.native.js +3 -1
  319. package/dist/jsx/fields/Slider/index.native.js.map +1 -1
  320. package/dist/jsx/fields/Switch/index.mjs +6 -19
  321. package/dist/jsx/fields/Switch/index.mjs.map +1 -1
  322. package/dist/jsx/fields/Switch/index.native.js +5 -18
  323. package/dist/jsx/fields/Switch/index.native.js.map +1 -1
  324. package/dist/jsx/fields/TextArea/index.mjs +19 -5
  325. package/dist/jsx/fields/TextArea/index.mjs.map +1 -1
  326. package/dist/jsx/fields/TextArea/index.native.js +23 -5
  327. package/dist/jsx/fields/TextArea/index.native.js.map +1 -1
  328. package/dist/jsx/fields/TimePicker/catalog.mjs +174 -0
  329. package/dist/jsx/fields/TimePicker/catalog.mjs.map +1 -0
  330. package/dist/jsx/fields/TimePicker/catalog.native.js +227 -0
  331. package/dist/jsx/fields/TimePicker/catalog.native.js.map +1 -0
  332. package/dist/jsx/fields/TimePicker/index.mjs +2 -173
  333. package/dist/jsx/fields/TimePicker/index.mjs.map +1 -1
  334. package/dist/jsx/fields/TimePicker/index.native.js +74 -85
  335. package/dist/jsx/fields/TimePicker/index.native.js.map +1 -1
  336. package/dist/jsx/fields/TimeRangeScrubber/geometry.mjs +6 -1
  337. package/dist/jsx/fields/TimeRangeScrubber/geometry.mjs.map +1 -1
  338. package/dist/jsx/fields/TimeRangeScrubber/geometry.native.js +6 -0
  339. package/dist/jsx/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  340. package/dist/jsx/fields/TimeRangeScrubber/index.mjs +37 -18
  341. package/dist/jsx/fields/TimeRangeScrubber/index.mjs.map +1 -1
  342. package/dist/jsx/fields/TimeRangeScrubber/index.native.js +38 -14
  343. package/dist/jsx/fields/TimeRangeScrubber/index.native.js.map +1 -1
  344. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +166 -0
  345. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -0
  346. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +211 -0
  347. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -0
  348. package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.mjs +5 -0
  349. package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.mjs.map +1 -0
  350. package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.native.js +33 -0
  351. package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -0
  352. package/dist/jsx/fields/nativeSelect.mjs +5 -0
  353. package/dist/jsx/fields/nativeSelect.mjs.map +1 -0
  354. package/dist/jsx/fields/nativeSelect.native.js +33 -0
  355. package/dist/jsx/fields/nativeSelect.native.js.map +1 -0
  356. package/dist/jsx/index.js +2 -2
  357. package/dist/jsx/index.js.map +1 -1
  358. package/dist/jsx/index.mjs +2 -2
  359. package/dist/jsx/index.mjs.map +1 -1
  360. package/dist/jsx/index.native.js +1 -0
  361. package/dist/jsx/index.native.js.map +1 -1
  362. package/dist/jsx/themedPrimitives.mjs +5 -0
  363. package/dist/jsx/themedPrimitives.mjs.map +1 -1
  364. package/dist/jsx/themedPrimitives.native.js +5 -0
  365. package/dist/jsx/themedPrimitives.native.js.map +1 -1
  366. package/package.json +12 -9
  367. package/src/Button/Button.labelInk.spec.tsx +1 -1
  368. package/src/Button/Button.sizeLadder.spec.tsx +124 -0
  369. package/src/Button/Button.spec.tsx +7 -17
  370. package/src/Button/Button.stories.tsx +14 -0
  371. package/src/Button/index.tsx +18 -3
  372. package/src/Chip/Chip.spec.tsx +15 -0
  373. package/src/Chip/Chip.stories.tsx +251 -0
  374. package/src/Chip/index.tsx +5 -1
  375. package/src/ContextualSaveBar/ContextualSaveBar.spec.tsx +51 -0
  376. package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +42 -23
  377. package/src/ContextualSaveBar/UnsavedChangesDialog.spec.tsx +167 -0
  378. package/src/ContextualSaveBar/index.tsx +14 -5
  379. package/src/DescriptionList/DescriptionList.spec.tsx +19 -1
  380. package/src/DescriptionList/DescriptionList.stories.tsx +5 -1
  381. package/src/DescriptionList/index.tsx +57 -19
  382. package/src/ErrorSummary.tsx +5 -2
  383. package/src/FloatingPanel/panelWidthContract.spec.ts +2 -2
  384. package/src/FloatingPanel/useFloatingPanel.spec.tsx +199 -1
  385. package/src/FloatingPanel/useFloatingPanel.ts +45 -3
  386. package/src/InputParts/index.tsx +56 -2
  387. package/src/Spinner/SpinnerGlyph.spec.tsx +132 -0
  388. package/src/Wheel/WheelEdgeFade.spec.tsx +141 -0
  389. package/src/fields/Checkbox/Checkbox.spec.tsx +24 -0
  390. package/src/fields/Checkbox/Checkbox.tsx +8 -3
  391. package/src/fields/Checkbox/CheckboxBox.spec.tsx +395 -0
  392. package/src/fields/Checkbox/CheckboxCard.spec.tsx +197 -0
  393. package/src/fields/Checkbox/CheckboxFieldFrame.spec.tsx +116 -0
  394. package/src/fields/Checkbox/CheckboxGroup.stories.tsx +15 -0
  395. package/src/fields/Checkbox/CheckboxGroup.tsx +77 -70
  396. package/src/fields/Checkbox/checkboxGroupContext.ts +12 -0
  397. package/src/fields/DatePicker/Calendar.spec.tsx +6 -5
  398. package/src/fields/DatePicker/DatePicker.stories.tsx +13 -0
  399. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +586 -0
  400. package/src/fields/DatePicker/DatetimePicker.native.tsx +243 -0
  401. package/src/fields/DatePicker/DatetimePicker.tsx +2 -584
  402. package/src/fields/DatePicker/catalog.tsx +450 -0
  403. package/src/fields/DatePicker/index.native.tsx +261 -0
  404. package/src/fields/DatePicker/index.tsx +20 -448
  405. package/src/fields/DatePicker/parts.tsx +11 -6
  406. package/src/fields/Duration/Duration.spec.tsx +50 -0
  407. package/src/fields/Duration/Duration.stories.tsx +21 -0
  408. package/src/fields/Duration/index.tsx +43 -5
  409. package/src/fields/PhoneInput/PhoneInput.spec.tsx +16 -63
  410. package/src/fields/PhoneInput/PhoneInput.tvalue-source.spec.ts +23 -0
  411. package/src/fields/PhoneInput/index.tsx +10 -3
  412. package/src/fields/Rating/index.tsx +9 -1
  413. package/src/fields/SearchInput/SearchInput.spec.tsx +20 -0
  414. package/src/fields/SearchInput/index.tsx +6 -0
  415. package/src/fields/Select/Select.stories.tsx +23 -1
  416. package/src/fields/Select/index.tsx +77 -1
  417. package/src/fields/Signature/Signature.spec.tsx +22 -3
  418. package/src/fields/Signature/index.tsx +16 -7
  419. package/src/fields/Slider/index.tsx +4 -1
  420. package/src/fields/Switch/index.tsx +14 -12
  421. package/src/fields/TextArea/TextArea.spec.tsx +68 -0
  422. package/src/fields/TextArea/index.tsx +23 -5
  423. package/src/fields/TimePicker/TimePicker.stories.tsx +13 -0
  424. package/src/fields/TimePicker/catalog.tsx +265 -0
  425. package/src/fields/TimePicker/index.native.tsx +229 -0
  426. package/src/fields/TimePicker/index.tsx +6 -261
  427. package/src/fields/TimeRangeScrubber/TimeRangeScrubber.spec.tsx +36 -0
  428. package/src/fields/TimeRangeScrubber/geometry.ts +13 -0
  429. package/src/fields/TimeRangeScrubber/index.tsx +49 -8
  430. package/src/fields/nativeDateTime/OsDateTimeSheet.spec.ts +12 -0
  431. package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +197 -0
  432. package/src/fields/nativeDateTime/osDateTimeIosDisplay.ts +4 -0
  433. package/src/fields/nativeSelect.spec.ts +28 -0
  434. package/src/fields/nativeSelect.ts +13 -0
  435. package/src/index.ts +2 -2
  436. package/src/themedPrimitives.tsx +10 -6
  437. package/types/Button/index.d.ts +3 -2
  438. package/types/Button/index.d.ts.map +1 -1
  439. package/types/Chip/index.d.ts.map +1 -1
  440. package/types/ContextualSaveBar/index.d.ts.map +1 -1
  441. package/types/DescriptionList/index.d.ts.map +1 -1
  442. package/types/ErrorSummary.d.ts.map +1 -1
  443. package/types/FloatingPanel/useFloatingPanel.d.ts +13 -0
  444. package/types/FloatingPanel/useFloatingPanel.d.ts.map +1 -1
  445. package/types/InputParts/index.d.ts.map +1 -1
  446. package/types/fields/Checkbox/Checkbox.d.ts.map +1 -1
  447. package/types/fields/Checkbox/CheckboxGroup.d.ts.map +1 -1
  448. package/types/fields/Checkbox/checkboxGroupContext.d.ts +8 -0
  449. package/types/fields/Checkbox/checkboxGroupContext.d.ts.map +1 -0
  450. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts +35 -0
  451. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -0
  452. package/types/fields/DatePicker/DatetimePicker.d.ts +2 -32
  453. package/types/fields/DatePicker/DatetimePicker.d.ts.map +1 -1
  454. package/types/fields/DatePicker/DatetimePicker.native.d.ts +26 -0
  455. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -0
  456. package/types/fields/DatePicker/catalog.d.ts +42 -0
  457. package/types/fields/DatePicker/catalog.d.ts.map +1 -0
  458. package/types/fields/DatePicker/index.d.ts +2 -39
  459. package/types/fields/DatePicker/index.d.ts.map +1 -1
  460. package/types/fields/DatePicker/index.native.d.ts +40 -0
  461. package/types/fields/DatePicker/index.native.d.ts.map +1 -0
  462. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  463. package/types/fields/Duration/index.d.ts +2 -0
  464. package/types/fields/Duration/index.d.ts.map +1 -1
  465. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  466. package/types/fields/Rating/index.d.ts.map +1 -1
  467. package/types/fields/SearchInput/index.d.ts.map +1 -1
  468. package/types/fields/Select/index.d.ts +6 -1
  469. package/types/fields/Select/index.d.ts.map +1 -1
  470. package/types/fields/Signature/index.d.ts.map +1 -1
  471. package/types/fields/Slider/index.d.ts.map +1 -1
  472. package/types/fields/Switch/index.d.ts.map +1 -1
  473. package/types/fields/TextArea/index.d.ts.map +1 -1
  474. package/types/fields/TimePicker/catalog.d.ts +41 -0
  475. package/types/fields/TimePicker/catalog.d.ts.map +1 -0
  476. package/types/fields/TimePicker/index.d.ts +2 -38
  477. package/types/fields/TimePicker/index.d.ts.map +1 -1
  478. package/types/fields/TimePicker/index.native.d.ts +31 -0
  479. package/types/fields/TimePicker/index.native.d.ts.map +1 -0
  480. package/types/fields/TimeRangeScrubber/geometry.d.ts +8 -0
  481. package/types/fields/TimeRangeScrubber/geometry.d.ts.map +1 -1
  482. package/types/fields/TimeRangeScrubber/index.d.ts +1 -1
  483. package/types/fields/TimeRangeScrubber/index.d.ts.map +1 -1
  484. package/types/fields/nativeDateTime/OsDateTimeSheet.d.ts +12 -0
  485. package/types/fields/nativeDateTime/OsDateTimeSheet.d.ts.map +1 -0
  486. package/types/fields/nativeDateTime/osDateTimeIosDisplay.d.ts +3 -0
  487. package/types/fields/nativeDateTime/osDateTimeIosDisplay.d.ts.map +1 -0
  488. package/types/fields/nativeSelect.d.ts +12 -0
  489. package/types/fields/nativeSelect.d.ts.map +1 -0
  490. package/types/index.d.ts +2 -2
  491. package/types/index.d.ts.map +1 -1
  492. package/types/themedPrimitives.d.ts.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/forms",
3
- "version": "7.6.2",
3
+ "version": "7.7.0",
4
4
  "description": "Cross-platform form components with URL state management",
5
5
  "keywords": [
6
6
  "cross-platform",
@@ -70,9 +70,9 @@
70
70
  "perfect-freehand": "^1.2.3",
71
71
  "react-native-svg": "15.15.4",
72
72
  "tamagui": "2.7.6",
73
- "@multiplatform.one/router": "7.6.2",
74
- "@multiplatform.one/table-primitives": "7.6.2",
75
- "@multiplatform.one/theme": "7.6.2"
73
+ "@multiplatform.one/router": "7.7.0",
74
+ "@multiplatform.one/table-primitives": "7.7.0",
75
+ "@multiplatform.one/theme": "7.7.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@tamagui/build": "2.7.6",
@@ -80,7 +80,6 @@
80
80
  "@tamagui/vite-plugin": "2.7.6",
81
81
  "@testing-library/jest-dom": "^6.9.1",
82
82
  "@testing-library/react": "^16.3.2",
83
- "@types/react": "~19.2.14",
84
83
  "@types/react-dom": "^19.2.3",
85
84
  "@vitejs/plugin-react": "^6.0.1",
86
85
  "@vitest/coverage-v8": "^4.1.5",
@@ -95,13 +94,14 @@
95
94
  "react-i18next": "^16.6.6",
96
95
  "react-native-web": "^0.21.2",
97
96
  "vitest": "^4.1.5",
98
- "@multiplatform.one/config": "7.6.2",
99
- "@multiplatform.one/storybook": "7.6.2",
100
- "@multiplatform.one/test-utils": "7.6.2"
97
+ "@multiplatform.one/config": "7.7.0",
98
+ "@multiplatform.one/storybook": "7.7.0",
99
+ "@multiplatform.one/test-utils": "7.7.0"
101
100
  },
102
101
  "peerDependencies": {
103
- "expo-haptics": "55.0.17",
102
+ "@react-native-community/datetimepicker": ">=8.0.1",
104
103
  "expo-document-picker": "*",
104
+ "expo-haptics": "55.0.17",
105
105
  "expo-image-picker": "*",
106
106
  "expo-maps": "*",
107
107
  "i18next": "^25.0.0",
@@ -110,6 +110,9 @@
110
110
  "react-i18next": ">=14"
111
111
  },
112
112
  "peerDependenciesMeta": {
113
+ "@react-native-community/datetimepicker": {
114
+ "optional": true
115
+ },
113
116
  "expo-document-picker": {
114
117
  "optional": true
115
118
  },
@@ -51,7 +51,7 @@ const WHITE_PAGE_SURFACES = ["background", "color1"] as const;
51
51
 
52
52
  function houseRender(ui: React.ReactElement, theme: "light" | "dark" = "light") {
53
53
  return render(
54
- <TamaguiProvider config={houseConfig} defaultTheme={theme} disableInjectCSS>
54
+ <TamaguiProvider config={houseConfig.tamagui} defaultTheme={theme} disableInjectCSS>
55
55
  <YStack backgroundColor="$background">{ui}</YStack>
56
56
  </TamaguiProvider>,
57
57
  );
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @vitest-environment jsdom
3
+ *
4
+ * MPO-46 AC-1: the painted Button, not the recipe source, matches the
5
+ * measured Tamagui v5 table at $2/$3/$4/$6. Radius used to sit on the
6
+ * borderRadius knob (flat 9px); it must step with the size token, and
7
+ * gap must equal that painted radius at every size and every knob stop.
8
+ */
9
+
10
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
11
+ import { Preset } from "@multiplatform.one/theme";
12
+ import { cleanup, screen } from "@testing-library/react";
13
+ import { afterEach, describe, expect, it } from "vitest";
14
+ import { Button } from "./index";
15
+
16
+ afterEach(cleanup);
17
+
18
+ const MEASURED = {
19
+ $2: { paddingHorizontal: 7, fontSize: 12, radius: 5 },
20
+ $3: { paddingHorizontal: 13, fontSize: 13, radius: 7 },
21
+ $4: { paddingHorizontal: 18, fontSize: 14, radius: 9 },
22
+ $6: { paddingHorizontal: 32, fontSize: 18, radius: 16 },
23
+ } as const;
24
+
25
+ const KNOB_STOPS = {
26
+ none: 0,
27
+ small: 5,
28
+ medium: 9,
29
+ large: 16,
30
+ full: 50,
31
+ } as const;
32
+
33
+ function lastPx(el: Element, re: RegExp): number | null {
34
+ let found: number | null = null;
35
+ for (const c of String((el as HTMLElement).className || "").split(/\s+/)) {
36
+ const m = c.match(re);
37
+ if (m) found = Number(m[1]);
38
+ }
39
+ return found;
40
+ }
41
+
42
+ const RADIUS_TOKEN_PX: Record<string, number> = {
43
+ "0": 0,
44
+ "2": 5,
45
+ "3": 7,
46
+ "4": 9,
47
+ "5": 10,
48
+ "6": 16,
49
+ "12": 50,
50
+ };
51
+
52
+ function radiusPx(el: HTMLElement): number | null {
53
+ let found: number | null = null;
54
+ for (const c of String(el.className || "").split(/\s+/)) {
55
+ const px = c.match(/^_btlr-(\d+)px$/);
56
+ if (px) found = Number(px[1]);
57
+ const tok = c.match(/^_btlr-t-radius-(\d+)$/);
58
+ if (tok) found = RADIUS_TOKEN_PX[tok[1]] ?? found;
59
+ }
60
+ return found;
61
+ }
62
+
63
+ function padXPx(el: HTMLElement): number | null {
64
+ return lastPx(el, /^_px-(\d+)px$/) ?? lastPx(el, /^_p[lr]-(\d+)px$/);
65
+ }
66
+
67
+ function gapPx(el: HTMLElement): number | null {
68
+ return lastPx(el, /^_gap-(\d+)px$/);
69
+ }
70
+
71
+ function labelPx(el: HTMLElement): number | null {
72
+ for (const node of Array.from(el.querySelectorAll("*"))) {
73
+ const n = lastPx(node, /^_fos-(\d+)px$/) ?? lastPx(node, /^_fs-(\d+)px$/);
74
+ if (n != null) return n;
75
+ }
76
+ return lastPx(el, /^_fos-(\d+)px$/) ?? lastPx(el, /^_fs-(\d+)px$/);
77
+ }
78
+
79
+ function renderSize(size: keyof typeof MEASURED) {
80
+ renderWithProviders(
81
+ <Button size={size} icon={<span>i</span>}>
82
+ Restart
83
+ </Button>,
84
+ );
85
+ return screen.getByRole("button");
86
+ }
87
+
88
+ describe("MPO-46 painted Button size ladder", () => {
89
+ it("padX, label and radius at $2/$3/$4/$6 match the reference table", () => {
90
+ for (const token of ["$2", "$3", "$4", "$6"] as const) {
91
+ const row = MEASURED[token];
92
+ const frame = renderSize(token);
93
+ expect(padXPx(frame), `${token} padX (${frame.className})`).toBe(row.paddingHorizontal);
94
+ expect(labelPx(frame), `${token} label`).toBe(row.fontSize);
95
+ expect(radiusPx(frame), `${token} radius (${frame.className})`).toBe(row.radius);
96
+ cleanup();
97
+ }
98
+ });
99
+
100
+ it("gap equals radius at every size step", () => {
101
+ for (const token of ["$2", "$3", "$4", "$6"] as const) {
102
+ const frame = renderSize(token);
103
+ expect(gapPx(frame), `${token} gap`).toBe(MEASURED[token].radius);
104
+ expect(gapPx(frame), `${token} gap==radius`).toBe(radiusPx(frame));
105
+ cleanup();
106
+ }
107
+ });
108
+
109
+ it("gap equals radius at every borderRadius knob stop", () => {
110
+ for (const [stop, px] of Object.entries(KNOB_STOPS) as [keyof typeof KNOB_STOPS, number][]) {
111
+ renderWithProviders(
112
+ <Preset overrides={{ borderRadius: stop }}>
113
+ <Button size="$4" icon={<span>i</span>}>
114
+ Restart
115
+ </Button>
116
+ </Preset>,
117
+ );
118
+ const frame = screen.getByRole("button");
119
+ expect(radiusPx(frame), `${stop} radius`).toBe(px);
120
+ expect(gapPx(frame), `${stop} gap`).toBe(px);
121
+ cleanup();
122
+ }
123
+ });
124
+ });
@@ -3,10 +3,10 @@
3
3
  *
4
4
  * LC-65 SIZE-RECIPE (Button arm): medium/$4 paints at 44px — since MPO-13
5
5
  * the recipe table IS the measured Tamagui $size ramp ($4/$true = 44), so
6
- * the recipe fragment and the raw token finally agree. Radius stays on the
7
- * borderRadius knob (same class across size steps). jsdom cannot cascade
8
- * Tamagui CSS, so assertions read the atomic height/radius classes the
9
- * frame emits.
6
+ * the recipe fragment and the raw token finally agree. Radius steps with
7
+ * the size token (MPO-46); the borderRadius knob is an override, not a
8
+ * flat 9px across heights. jsdom cannot cascade Tamagui CSS, so
9
+ * assertions read the atomic height/radius classes the frame emits.
10
10
  *
11
11
  * Desktop/jsdom: the touch floor (control.height >= 44) does not fire here;
12
12
  * at $4 it is a no-op anyway (desktop 44 = floor 44, touch lifts to 48).
@@ -48,7 +48,7 @@ describe("Button LC-65 SIZE-RECIPE", () => {
48
48
  expect(frame.className).not.toMatch(/_h-t-size-4/);
49
49
  });
50
50
 
51
- it("radius does not change between size steps", () => {
51
+ it("radius steps with the size token (MPO-46)", () => {
52
52
  renderWithProviders(
53
53
  <Preset overrides={{ size: "small" }}>
54
54
  <Button>Save</Button>
@@ -59,16 +59,6 @@ describe("Button LC-65 SIZE-RECIPE", () => {
59
59
  const smallRadius = frameRadiusClasses(small);
60
60
  cleanup();
61
61
 
62
- renderWithProviders(
63
- <Preset overrides={{ size: "medium" }}>
64
- <Button>Save</Button>
65
- </Preset>,
66
- );
67
- const medium = screen.getByRole("button");
68
- expect(medium.className).toMatch(/_h-44px/);
69
- const mediumRadius = frameRadiusClasses(medium);
70
- cleanup();
71
-
72
62
  renderWithProviders(
73
63
  <Preset overrides={{ size: "large" }}>
74
64
  <Button>Save</Button>
@@ -79,8 +69,8 @@ describe("Button LC-65 SIZE-RECIPE", () => {
79
69
  const largeRadius = frameRadiusClasses(large);
80
70
 
81
71
  expect(smallRadius.length).toBeGreaterThan(0);
82
- expect(smallRadius).toEqual(mediumRadius);
83
- expect(largeRadius).toEqual(mediumRadius);
72
+ expect(largeRadius.length).toBeGreaterThan(0);
73
+ expect(smallRadius).not.toEqual(largeRadius);
84
74
  });
85
75
 
86
76
  it("recipeFamily controlCompact has smaller padding than control at the same size token", () => {
@@ -147,6 +147,20 @@ export const CompoundPattern: Story = {
147
147
  * Size recipes (Polaris/Primer/Linear 28/32/40), density ≠ size, selected =
148
148
  * fill, nested scale-down, 44px via slop not painted chrome.
149
149
  */
150
+ export const SizeLadder: Story = {
151
+ name: "Size ladder $2–$6 (MPO-46)",
152
+ render: () => (
153
+ <YStack gap="$4" padding="$4">
154
+ <XStack gap="$3" alignItems="flex-end" flexWrap="wrap">
155
+ <Button size="$2">Restart</Button>
156
+ <Button size="$3">Restart</Button>
157
+ <Button size="$4">Restart</Button>
158
+ <Button size="$6">Restart</Button>
159
+ </XStack>
160
+ </YStack>
161
+ ),
162
+ };
163
+
150
164
  export const Anatomy: Story = {
151
165
  name: "Anatomy (size / density / selected / nested)",
152
166
  render: () => (
@@ -14,6 +14,8 @@ import {
14
14
  pressTargetHitSlop,
15
15
  radiusClassProps,
16
16
  recipeFamilies,
17
+ resolveControlRadius,
18
+ SIZE_RECIPE_RADIUS_TOKEN_TO_STOP,
17
19
  sizeRecipeForToken,
18
20
  sizeRecipeFromHeight,
19
21
  solidButtonIntents,
@@ -21,6 +23,7 @@ import {
21
23
  type HitSlopInsets,
22
24
  type RecipeFamilyName,
23
25
  type SizeRecipe,
26
+ type SizeRecipeRadiusStop,
24
27
  } from "@multiplatform.one/theme";
25
28
  import { getSize } from "@tamagui/get-token";
26
29
  import { useFormField } from "../shared/utils";
@@ -51,8 +54,9 @@ import { useControlGrouped } from "../shared/groupContext";
51
54
 
52
55
  /**
53
56
  * Coordinated size recipe (Polaris slim/medium/large, Primer s/m/l, Linear
54
- * 28/32/40, Spectrum S/M, M3 XS/S). Height, pad, type, and icon step together.
55
- * Radius is NOT on the recipe — it stays on the borderRadius knob.
57
+ * 28/32/40, Spectrum S/M, M3 XS/S). Height, pad, type, icon, gap and radius
58
+ * step together from the size table. The borderRadius knob is an override
59
+ * that retargets both painted radius and inner gap (`resolveControlRadius`).
56
60
  * Density is a different axis (pad/gap only).
57
61
  *
58
62
  * GENERATED (LC-75 / LC-80): Button consumes `recipeFamilies.control` — the
@@ -443,7 +447,15 @@ export function Button({
443
447
  buttonDensityFamily(recipeFamily, densityTight),
444
448
  );
445
449
  const padX = recipe.paddingHorizontal;
446
- const innerGap = recipe.gap;
450
+ const radiusToken = knobProps.borderRadius.borderRadius;
451
+ const radiusStop: SizeRecipeRadiusStop | undefined =
452
+ typeof radiusToken === "string"
453
+ ? SIZE_RECIPE_RADIUS_TOKEN_TO_STOP[
454
+ radiusToken as keyof typeof SIZE_RECIPE_RADIUS_TOKEN_TO_STOP
455
+ ]
456
+ : undefined;
457
+ const paintedRadius = resolveControlRadius(recipe, radiusStop ?? "medium");
458
+ const innerGap = paintedRadius.gap;
447
459
  if (skeleton) {
448
460
  return (
449
461
  <View
@@ -651,6 +663,9 @@ export function Button({
651
663
  opacity={1}
652
664
  transition={knobProps.transition}
653
665
  {...knobProps.borderRadius}
666
+ {...(radiusStop === "medium" || radiusStop == null
667
+ ? { borderRadius: paintedRadius.radius }
668
+ : undefined)}
654
669
  borderWidth={resolvedBorderWidth}
655
670
  // MPO-19 X3: the borderRadius knob fragment carries `$borderColor` for
656
671
  // bordered chrome, but a filled Button's edge is transparent by contract
@@ -1,6 +1,7 @@
1
1
  import { fireEvent } from "@testing-library/react";
2
2
  import { describe, expect, it, vi } from "vitest";
3
3
  import { renderWithProviders } from "@multiplatform.one/test-utils";
4
+ import { Preset } from "@multiplatform.one/theme";
4
5
  import { CHIP_DISMISS_MIN_TARGET_FINE, Chip, chipDismissFloorOutset } from "./index";
5
6
 
6
7
  describe("Chip", () => {
@@ -131,6 +132,20 @@ describe("Chip", () => {
131
132
  expect(dismiss.querySelector(".mp-chip-dismiss-ring")).not.toBeNull();
132
133
  });
133
134
 
135
+ it("unselected frame stays 1px under borderWidth none and large (chip-frame pin)", () => {
136
+ for (const stop of ["none", "large"] as const) {
137
+ const result = renderWithProviders(
138
+ <Preset overrides={{ borderWidth: stop }}>
139
+ <Chip>Tag</Chip>
140
+ </Preset>,
141
+ );
142
+ const frame = result.container.querySelector("[data-mp-chip]") as HTMLElement;
143
+ expect(frame).not.toBeNull();
144
+ expect(String(frame.className)).toMatch(/bw-1|borderWidth-1/);
145
+ expect(String(frame.className)).not.toMatch(/bw-2|borderWidth-2/);
146
+ }
147
+ });
148
+
134
149
  it("selected chip marks fill, not a selection outline (LC-71)", () => {
135
150
  const result = renderWithProviders(
136
151
  <Chip selected variant="outline">
@@ -0,0 +1,251 @@
1
+ import { action } from "@multiplatform.one/storybook";
2
+ import { CheckIcon, LightningIcon, TagIcon } from "@phosphor-icons/react";
3
+ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
4
+ import { useState } from "react";
5
+ import { Text, XStack, YStack } from "tamagui";
6
+ import { Chip, type ChipColor, type ChipSize, type ChipVariantProp } from "./index";
7
+
8
+ const meta: Meta<typeof Chip> = {
9
+ title: "Forms/Chip",
10
+ component: Chip,
11
+ parameters: {
12
+ status: { type: "stable" },
13
+ docs: {
14
+ description: {
15
+ component:
16
+ "Forms chip (`data-mp-chip`): solid / subtle / outline (filled / outlined / ghost aliases), semantic color, selected fill, leading icon, dismiss, optional stacked-group corners. Distinct from Components/Chip.",
17
+ },
18
+ },
19
+ },
20
+ };
21
+ export default meta;
22
+
23
+ type Story = StoryObj<typeof Chip>;
24
+
25
+ export const Default: Story = {
26
+ name: "Main",
27
+ render: () => <Chip>Default Chip</Chip>,
28
+ };
29
+
30
+ export const Variants: Story = {
31
+ render: () => {
32
+ const variants: ChipVariantProp[] = ["subtle", "solid", "outline"];
33
+ return (
34
+ <YStack gap="$3">
35
+ {variants.map((variant) => (
36
+ <XStack key={variant} gap="$2" alignItems="center">
37
+ <Text width={80} fontSize="$2" color="$color10">
38
+ {variant}
39
+ </Text>
40
+ <Chip variant={variant}>Chip</Chip>
41
+ <Chip variant={variant} color="blue">
42
+ Blue
43
+ </Chip>
44
+ </XStack>
45
+ ))}
46
+ </YStack>
47
+ );
48
+ },
49
+ };
50
+
51
+ export const Colors: Story = {
52
+ render: () => {
53
+ const colors: ChipColor[] = ["gray", "red", "green", "blue", "yellow", "orange", "purple"];
54
+ return (
55
+ <YStack gap="$4">
56
+ {(["subtle", "outline", "solid"] as ChipVariantProp[]).map((variant) => (
57
+ <YStack key={variant} gap="$2">
58
+ <Text fontWeight="400" fontSize="$2">
59
+ {variant}
60
+ </Text>
61
+ <XStack gap="$2" flexWrap="wrap">
62
+ {colors.map((color) => (
63
+ <Chip key={color} variant={variant} color={color}>
64
+ {color}
65
+ </Chip>
66
+ ))}
67
+ </XStack>
68
+ </YStack>
69
+ ))}
70
+ </YStack>
71
+ );
72
+ },
73
+ };
74
+
75
+ export const Sizes: Story = {
76
+ render: () => {
77
+ const sizes: ChipSize[] = ["$2", "$3", "$4", "$5"];
78
+ return (
79
+ <XStack gap="$2" alignItems="center">
80
+ {sizes.map((size) => (
81
+ <Chip key={size} size={size}>
82
+ Size {size}
83
+ </Chip>
84
+ ))}
85
+ </XStack>
86
+ );
87
+ },
88
+ };
89
+
90
+ export const Selected: Story = {
91
+ render: () => (
92
+ <XStack gap="$2" flexWrap="wrap" alignItems="center">
93
+ <Chip variant="outline" selected={false} onPress={() => action("press")("idle")}>
94
+ Idle
95
+ </Chip>
96
+ <Chip variant="outline" selected onPress={() => action("press")("on")}>
97
+ Selected
98
+ </Chip>
99
+ <Chip variant="outline" selected onPress={() => action("press")("blue")} color="blue">
100
+ Blue selected
101
+ </Chip>
102
+ </XStack>
103
+ ),
104
+ };
105
+
106
+ export const Filter: Story = {
107
+ render: function FilterDemo() {
108
+ const [on, setOn] = useState<Record<string, boolean>>({
109
+ Fire: true,
110
+ Water: false,
111
+ Grass: true,
112
+ Electric: false,
113
+ });
114
+ return (
115
+ <XStack gap="$2" flexWrap="wrap">
116
+ {Object.keys(on).map((label) => (
117
+ <Chip
118
+ key={label}
119
+ variant="outline"
120
+ selected={on[label]}
121
+ onPress={() => setOn((s) => ({ ...s, [label]: !s[label] }))}
122
+ >
123
+ {label}
124
+ </Chip>
125
+ ))}
126
+ </XStack>
127
+ );
128
+ },
129
+ };
130
+
131
+ export const WithIcon: Story = {
132
+ render: () => (
133
+ <XStack gap="$2" flexWrap="wrap" alignItems="center">
134
+ <Chip icon={<TagIcon />}>Tagged</Chip>
135
+ <Chip icon={<LightningIcon />} color="yellow" variant="solid">
136
+ Electric
137
+ </Chip>
138
+ <Chip icon={<CheckIcon />} color="green" selected onPress={() => {}}>
139
+ Ready
140
+ </Chip>
141
+ <Chip icon={<TagIcon />} onDismiss={() => action("onDismiss")("Tagged")} color="purple">
142
+ Removable
143
+ </Chip>
144
+ </XStack>
145
+ ),
146
+ };
147
+
148
+ export const Dismissible: Story = {
149
+ render: () => (
150
+ <XStack gap="$2" flexWrap="wrap">
151
+ <Chip onDismiss={() => action("onDismiss")("React")}>React</Chip>
152
+ <Chip onDismiss={() => action("onDismiss")("TypeScript")} color="blue">
153
+ TypeScript
154
+ </Chip>
155
+ <Chip onDismiss={() => action("onDismiss")("Tamagui")} color="purple">
156
+ Tamagui
157
+ </Chip>
158
+ </XStack>
159
+ ),
160
+ };
161
+
162
+ export const DismissibleSizes: Story = {
163
+ render: () => (
164
+ <XStack gap="$2" flexWrap="wrap" alignItems="center">
165
+ <Chip size="$2" onDismiss={() => action("onDismiss")("$2")}>
166
+ Size $2
167
+ </Chip>
168
+ <Chip size="$3" onDismiss={() => action("onDismiss")("$3")} color="blue">
169
+ Size $3
170
+ </Chip>
171
+ <Chip size="$4" onDismiss={() => action("onDismiss")("$4")} color="green">
172
+ Size $4
173
+ </Chip>
174
+ <Chip size="$5" onDismiss={() => action("onDismiss")("$5")} color="purple">
175
+ Size $5
176
+ </Chip>
177
+ </XStack>
178
+ ),
179
+ };
180
+
181
+ export const Disabled: Story = {
182
+ render: () => (
183
+ <XStack gap="$2">
184
+ <Chip disabled>Disabled</Chip>
185
+ <Chip disabled onDismiss={() => {}}>
186
+ Disabled Dismissible
187
+ </Chip>
188
+ <Chip disabled selected onPress={() => {}}>
189
+ Disabled selected
190
+ </Chip>
191
+ </XStack>
192
+ ),
193
+ };
194
+
195
+ /** stacked-group corners (LC-72) — forms Chip only; Components/Chip has no groupPosition. */
196
+ export const Grouped: Story = {
197
+ render: () => (
198
+ <XStack>
199
+ <Chip groupPosition="first" variant="outline">
200
+ First
201
+ </Chip>
202
+ <Chip groupPosition="middle" variant="outline">
203
+ Middle
204
+ </Chip>
205
+ <Chip groupPosition="last" variant="outline">
206
+ Last
207
+ </Chip>
208
+ </XStack>
209
+ ),
210
+ };
211
+
212
+ export const AllStates: Story = {
213
+ render: () => (
214
+ <YStack gap="$6">
215
+ <YStack gap="$2">
216
+ <Text fontWeight="400">Variants</Text>
217
+ <XStack gap="$2" flexWrap="wrap">
218
+ <Chip variant="solid">Solid</Chip>
219
+ <Chip variant="subtle">Subtle</Chip>
220
+ <Chip variant="outline">Outline</Chip>
221
+ </XStack>
222
+ </YStack>
223
+ <YStack gap="$2">
224
+ <Text fontWeight="400">Aliases</Text>
225
+ <XStack gap="$2" flexWrap="wrap">
226
+ <Chip variant="filled">Filled</Chip>
227
+ <Chip variant="ghost">Ghost</Chip>
228
+ <Chip variant="outlined">Outlined</Chip>
229
+ </XStack>
230
+ </YStack>
231
+ <YStack gap="$2">
232
+ <Text fontWeight="400">Dismissible</Text>
233
+ <XStack gap="$2">
234
+ <Chip onDismiss={() => action("dismiss")()}>Dismissible</Chip>
235
+ <Chip onDismiss={() => action("dismiss")()} color="blue">
236
+ Blue Dismissible
237
+ </Chip>
238
+ </XStack>
239
+ </YStack>
240
+ <YStack gap="$2">
241
+ <Text fontWeight="400">Disabled</Text>
242
+ <XStack gap="$2">
243
+ <Chip disabled>Disabled</Chip>
244
+ <Chip disabled onDismiss={() => {}}>
245
+ Disabled with dismiss
246
+ </Chip>
247
+ </XStack>
248
+ </YStack>
249
+ </YStack>
250
+ ),
251
+ };
@@ -485,7 +485,11 @@ export function Chip({
485
485
  }
486
486
  : undefined)}
487
487
  borderColor={borderColor}
488
- {...(selected ? { borderWidth: 0 } : undefined)}
488
+ // Chip-frame law: borderWidth is pinned at 1 (ignore the knob). The
489
+ // radius fragment also carries borderWidth, so this must land AFTER
490
+ // `{...knobProps.borderRadius}` or large would paint 2 and grow the
491
+ // box. Selected fill drops the stroke (LC-71).
492
+ borderWidth={selected ? 0 : 1}
489
493
  // LC-40 DISABLED-VISIBLE: hue tint washes to the muted neutral tiers
490
494
  // while the label pins to the lowest AA step (keepLabel); dimWhole
491
495
  // dims the chip as its own assembly.
@@ -1,6 +1,7 @@
1
1
  import { act, fireEvent, waitFor } from "@testing-library/react";
2
2
  import { useState } from "react";
3
3
  import { describe, expect, it, vi } from "vitest";
4
+ import { Preset } from "@multiplatform.one/theme";
4
5
  import { renderWithProviders } from "@multiplatform.one/test-utils";
5
6
  import { Checkbox } from "../fields/Checkbox";
6
7
  import { Input } from "../fields/Input";
@@ -254,6 +255,56 @@ describe("ContextualSaveBar", () => {
254
255
  expect(discard.getAttribute("aria-disabled")).toBeNull();
255
256
  expect(discard.getAttribute("data-mp-cancel-disabled-ignored")).toBe("true");
256
257
  });
258
+
259
+ it("CONTAINER-CAP on the top pair only; bottom pair pinned 0 (bottom-docked sheet)", () => {
260
+ const result = renderWithProviders(
261
+ <Preset overrides={{ borderRadius: "full", space: "medium" }}>
262
+ <Form formOptions={{ defaultValues: { name: "x" } }}>
263
+ <Input name="name" label="Name" />
264
+ <ContextualSaveBar forceVisible />
265
+ </Form>
266
+ </Preset>,
267
+ );
268
+ const bar = savebar(result.container);
269
+ expect(bar).toBeTruthy();
270
+ expect(bar?.getAttribute("data-mp-savebar-radius-class")).toBe("CONTAINER-CAP");
271
+ expect(bar?.getAttribute("data-mp-savebar-dock")).toBe("bottom");
272
+ expect(bar?.getAttribute("data-mp-savebar-top-radius")).toBe("18");
273
+ expect(bar?.getAttribute("data-mp-savebar-bottom-radius")).toBe("0");
274
+ const cls = String(bar?.className ?? "");
275
+ expect(cls).not.toMatch(/t-radius-12/);
276
+ const cs = bar ? getComputedStyle(bar) : null;
277
+ expect(cs?.borderBottomLeftRadius === "0px" || cs?.borderBottomLeftRadius === "0").toBe(true);
278
+ expect(cs?.borderBottomRightRadius === "0px" || cs?.borderBottomRightRadius === "0").toBe(true);
279
+ });
280
+
281
+ it("large under space=small caps the top pair at pad 13; bottoms stay 0", () => {
282
+ const result = renderWithProviders(
283
+ <Preset overrides={{ borderRadius: "large", space: "small" }}>
284
+ <Form formOptions={{ defaultValues: { name: "x" } }}>
285
+ <Input name="name" label="Name" />
286
+ <ContextualSaveBar forceVisible />
287
+ </Form>
288
+ </Preset>,
289
+ );
290
+ const bar = savebar(result.container);
291
+ expect(bar?.getAttribute("data-mp-savebar-top-radius")).toBe("13");
292
+ expect(bar?.getAttribute("data-mp-savebar-bottom-radius")).toBe("0");
293
+ });
294
+
295
+ it("none squares the top pair; bottoms stay 0", () => {
296
+ const result = renderWithProviders(
297
+ <Preset overrides={{ borderRadius: "none" }}>
298
+ <Form formOptions={{ defaultValues: { name: "x" } }}>
299
+ <Input name="name" label="Name" />
300
+ <ContextualSaveBar forceVisible />
301
+ </Form>
302
+ </Preset>,
303
+ );
304
+ const bar = savebar(result.container);
305
+ expect(bar?.getAttribute("data-mp-savebar-top-radius")).toBe("$0");
306
+ expect(bar?.getAttribute("data-mp-savebar-bottom-radius")).toBe("0");
307
+ });
257
308
  });
258
309
 
259
310
  describe("clientKnownIdentity (LC-64)", () => {