@multiplatform.one/forms 7.46.0 → 7.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/dist/cjs/Button/index.cjs +14 -3
  2. package/dist/cjs/Button/index.native.js +18 -7
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/ErrorSummary.cjs +1 -1
  5. package/dist/cjs/ErrorSummary.native.js +1 -1
  6. package/dist/cjs/ErrorSummary.native.js.map +1 -1
  7. package/dist/cjs/FloatingPanel/PanelPortal.cjs +1 -1
  8. package/dist/cjs/FloatingPanel/index.cjs +13 -4
  9. package/dist/cjs/FloatingPanel/index.native.js +9 -2
  10. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  11. package/dist/cjs/FloatingPanel/trailingAction.cjs +59 -0
  12. package/dist/cjs/FloatingPanel/trailingAction.native.js +64 -0
  13. package/dist/cjs/FloatingPanel/trailingAction.native.js.map +1 -0
  14. package/dist/cjs/FormGrid.cjs +1 -0
  15. package/dist/cjs/FormGrid.native.js +1 -0
  16. package/dist/cjs/FormGrid.native.js.map +1 -1
  17. package/dist/cjs/InputParts/PasswordReveal.cjs +96 -0
  18. package/dist/cjs/InputParts/PasswordReveal.native.js +104 -0
  19. package/dist/cjs/InputParts/PasswordReveal.native.js.map +1 -0
  20. package/dist/cjs/InputParts/index.cjs +95 -5
  21. package/dist/cjs/InputParts/index.native.js +99 -5
  22. package/dist/cjs/InputParts/index.native.js.map +1 -1
  23. package/dist/cjs/fields/ColorPicker/index.cjs +8 -17
  24. package/dist/cjs/fields/ColorPicker/index.native.js +9 -18
  25. package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
  26. package/dist/cjs/fields/Combobox/index.cjs +28 -44
  27. package/dist/cjs/fields/Combobox/index.native.js +30 -45
  28. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  29. package/dist/cjs/fields/DatePicker/Calendar.cjs +3 -4
  30. package/dist/cjs/fields/DatePicker/Calendar.native.js +3 -4
  31. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  32. package/dist/cjs/fields/DatePicker/parts.cjs +5 -9
  33. package/dist/cjs/fields/DatePicker/parts.native.js +5 -9
  34. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  35. package/dist/cjs/fields/Duration/durationMath.cjs +1 -1
  36. package/dist/cjs/fields/Duration/durationMath.native.js +1 -1
  37. package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
  38. package/dist/cjs/fields/Duration/index.cjs +100 -90
  39. package/dist/cjs/fields/Duration/index.native.js +108 -98
  40. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  41. package/dist/cjs/fields/FileUpload/index.cjs +134 -24
  42. package/dist/cjs/fields/FileUpload/index.native.js +149 -34
  43. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  44. package/dist/cjs/fields/Geolocation/GeolocationMap.cjs +2 -1
  45. package/dist/cjs/fields/Geolocation/GeolocationMap.native.js +3 -2
  46. package/dist/cjs/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  47. package/dist/cjs/fields/Geolocation/index.cjs +10 -8
  48. package/dist/cjs/fields/Geolocation/index.native.js +10 -8
  49. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  50. package/dist/cjs/fields/Icon/index.cjs +6 -13
  51. package/dist/cjs/fields/Icon/index.native.js +6 -13
  52. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  53. package/dist/cjs/fields/ImageField/index.cjs +5 -5
  54. package/dist/cjs/fields/ImageField/index.native.js +5 -5
  55. package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
  56. package/dist/cjs/fields/Input/index.cjs +27 -21
  57. package/dist/cjs/fields/Input/index.native.js +28 -21
  58. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  59. package/dist/cjs/fields/MentionInput/index.cjs +7 -8
  60. package/dist/cjs/fields/MentionInput/index.native.js +7 -8
  61. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  62. package/dist/cjs/fields/OTPInput/index.cjs +1 -1
  63. package/dist/cjs/fields/OTPInput/index.native.js +1 -1
  64. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  65. package/dist/cjs/fields/PhoneInput/index.cjs +3 -3
  66. package/dist/cjs/fields/PhoneInput/index.native.js +3 -3
  67. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  68. package/dist/cjs/fields/RadioGroup/index.cjs +1 -0
  69. package/dist/cjs/fields/RadioGroup/index.native.js +1 -0
  70. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  71. package/dist/cjs/fields/SearchInput/index.cjs +4 -48
  72. package/dist/cjs/fields/SearchInput/index.native.js +4 -46
  73. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  74. package/dist/cjs/fields/Select/index.cjs +14 -12
  75. package/dist/cjs/fields/Select/index.native.js +14 -12
  76. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  77. package/dist/cjs/fields/Signature/index.cjs +1 -1
  78. package/dist/cjs/fields/Signature/index.native.js +1 -1
  79. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  80. package/dist/cjs/fields/Slider/index.cjs +1 -1
  81. package/dist/cjs/fields/Slider/index.native.js +1 -1
  82. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  83. package/dist/cjs/fields/TimePicker/parts.cjs +5 -9
  84. package/dist/cjs/fields/TimePicker/parts.native.js +5 -9
  85. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  86. package/dist/cjs/fields/TimeRangeScrubber/index.cjs +14 -9
  87. package/dist/cjs/fields/TimeRangeScrubber/index.native.js +14 -9
  88. package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
  89. package/dist/cjs/fields/ToggleGroup/index.cjs +1 -1
  90. package/dist/cjs/fields/ToggleGroup/index.native.js +1 -1
  91. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  92. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +5 -5
  93. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +5 -5
  94. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  95. package/dist/cjs/hooks/useFocusManagement.cjs +3 -2
  96. package/dist/cjs/hooks/useFocusManagement.native.js +3 -2
  97. package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
  98. package/dist/cjs/index.cjs +7 -0
  99. package/dist/cjs/index.native.js +7 -0
  100. package/dist/cjs/index.native.js.map +1 -1
  101. package/dist/cjs/shared/focusManagement.cjs +1 -1
  102. package/dist/cjs/shared/focusManagement.native.js +1 -1
  103. package/dist/cjs/shared/panelPortal.cjs +1 -1
  104. package/dist/cjs/shared/panelPortal.native.js +1 -1
  105. package/dist/cjs/shared/panelPortal.native.js.map +1 -1
  106. package/dist/cjs/shared/useDragScroll.cjs +2 -2
  107. package/dist/cjs/shared/useDragScroll.native.js +2 -2
  108. package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
  109. package/dist/esm/Button/index.mjs +17 -6
  110. package/dist/esm/Button/index.mjs.map +1 -1
  111. package/dist/esm/Button/index.native.js +21 -10
  112. package/dist/esm/Button/index.native.js.map +1 -1
  113. package/dist/esm/ErrorSummary.mjs +2 -2
  114. package/dist/esm/ErrorSummary.mjs.map +1 -1
  115. package/dist/esm/ErrorSummary.native.js +2 -2
  116. package/dist/esm/ErrorSummary.native.js.map +1 -1
  117. package/dist/esm/FloatingPanel/PanelPortal.mjs +1 -1
  118. package/dist/esm/FloatingPanel/PanelPortal.mjs.map +1 -1
  119. package/dist/esm/FloatingPanel/index.mjs +13 -4
  120. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  121. package/dist/esm/FloatingPanel/index.native.js +9 -2
  122. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  123. package/dist/esm/FloatingPanel/trailingAction.mjs +33 -0
  124. package/dist/esm/FloatingPanel/trailingAction.mjs.map +1 -0
  125. package/dist/esm/FloatingPanel/trailingAction.native.js +35 -0
  126. package/dist/esm/FloatingPanel/trailingAction.native.js.map +1 -0
  127. package/dist/esm/FormGrid.mjs +1 -0
  128. package/dist/esm/FormGrid.mjs.map +1 -1
  129. package/dist/esm/FormGrid.native.js +1 -0
  130. package/dist/esm/FormGrid.native.js.map +1 -1
  131. package/dist/esm/InputParts/PasswordReveal.mjs +68 -0
  132. package/dist/esm/InputParts/PasswordReveal.mjs.map +1 -0
  133. package/dist/esm/InputParts/PasswordReveal.native.js +73 -0
  134. package/dist/esm/InputParts/PasswordReveal.native.js.map +1 -0
  135. package/dist/esm/InputParts/index.mjs +97 -8
  136. package/dist/esm/InputParts/index.mjs.map +1 -1
  137. package/dist/esm/InputParts/index.native.js +101 -8
  138. package/dist/esm/InputParts/index.native.js.map +1 -1
  139. package/dist/esm/fields/ColorPicker/index.mjs +8 -17
  140. package/dist/esm/fields/ColorPicker/index.mjs.map +1 -1
  141. package/dist/esm/fields/ColorPicker/index.native.js +9 -18
  142. package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
  143. package/dist/esm/fields/Combobox/index.mjs +29 -45
  144. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  145. package/dist/esm/fields/Combobox/index.native.js +31 -46
  146. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  147. package/dist/esm/fields/DatePicker/Calendar.mjs +4 -5
  148. package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
  149. package/dist/esm/fields/DatePicker/Calendar.native.js +4 -5
  150. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  151. package/dist/esm/fields/DatePicker/parts.mjs +5 -9
  152. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  153. package/dist/esm/fields/DatePicker/parts.native.js +5 -9
  154. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  155. package/dist/esm/fields/Duration/durationMath.mjs +1 -1
  156. package/dist/esm/fields/Duration/durationMath.mjs.map +1 -1
  157. package/dist/esm/fields/Duration/durationMath.native.js +1 -1
  158. package/dist/esm/fields/Duration/index.mjs +100 -90
  159. package/dist/esm/fields/Duration/index.mjs.map +1 -1
  160. package/dist/esm/fields/Duration/index.native.js +108 -98
  161. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  162. package/dist/esm/fields/FileUpload/index.mjs +135 -25
  163. package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
  164. package/dist/esm/fields/FileUpload/index.native.js +150 -35
  165. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  166. package/dist/esm/fields/Geolocation/GeolocationMap.mjs +2 -1
  167. package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  168. package/dist/esm/fields/Geolocation/GeolocationMap.native.js +2 -1
  169. package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  170. package/dist/esm/fields/Geolocation/index.mjs +13 -11
  171. package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
  172. package/dist/esm/fields/Geolocation/index.native.js +13 -11
  173. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  174. package/dist/esm/fields/Icon/index.mjs +8 -15
  175. package/dist/esm/fields/Icon/index.mjs.map +1 -1
  176. package/dist/esm/fields/Icon/index.native.js +8 -15
  177. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  178. package/dist/esm/fields/ImageField/index.mjs +7 -7
  179. package/dist/esm/fields/ImageField/index.mjs.map +1 -1
  180. package/dist/esm/fields/ImageField/index.native.js +7 -7
  181. package/dist/esm/fields/ImageField/index.native.js.map +1 -1
  182. package/dist/esm/fields/Input/index.mjs +28 -22
  183. package/dist/esm/fields/Input/index.mjs.map +1 -1
  184. package/dist/esm/fields/Input/index.native.js +29 -22
  185. package/dist/esm/fields/Input/index.native.js.map +1 -1
  186. package/dist/esm/fields/MentionInput/index.mjs +13 -14
  187. package/dist/esm/fields/MentionInput/index.mjs.map +1 -1
  188. package/dist/esm/fields/MentionInput/index.native.js +13 -14
  189. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  190. package/dist/esm/fields/OTPInput/index.mjs +2 -2
  191. package/dist/esm/fields/OTPInput/index.mjs.map +1 -1
  192. package/dist/esm/fields/OTPInput/index.native.js +2 -2
  193. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  194. package/dist/esm/fields/PhoneInput/index.mjs +5 -5
  195. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  196. package/dist/esm/fields/PhoneInput/index.native.js +5 -5
  197. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  198. package/dist/esm/fields/RadioGroup/index.mjs +1 -0
  199. package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
  200. package/dist/esm/fields/RadioGroup/index.native.js +1 -0
  201. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  202. package/dist/esm/fields/SearchInput/index.mjs +5 -49
  203. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  204. package/dist/esm/fields/SearchInput/index.native.js +5 -47
  205. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  206. package/dist/esm/fields/Select/index.mjs +15 -13
  207. package/dist/esm/fields/Select/index.mjs.map +1 -1
  208. package/dist/esm/fields/Select/index.native.js +15 -13
  209. package/dist/esm/fields/Select/index.native.js.map +1 -1
  210. package/dist/esm/fields/Signature/index.mjs +2 -2
  211. package/dist/esm/fields/Signature/index.mjs.map +1 -1
  212. package/dist/esm/fields/Signature/index.native.js +2 -2
  213. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  214. package/dist/esm/fields/Slider/index.mjs +2 -2
  215. package/dist/esm/fields/Slider/index.mjs.map +1 -1
  216. package/dist/esm/fields/Slider/index.native.js +2 -2
  217. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  218. package/dist/esm/fields/TimePicker/parts.mjs +5 -9
  219. package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
  220. package/dist/esm/fields/TimePicker/parts.native.js +5 -9
  221. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  222. package/dist/esm/fields/TimeRangeScrubber/index.mjs +20 -15
  223. package/dist/esm/fields/TimeRangeScrubber/index.mjs.map +1 -1
  224. package/dist/esm/fields/TimeRangeScrubber/index.native.js +20 -15
  225. package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
  226. package/dist/esm/fields/ToggleGroup/index.mjs +3 -3
  227. package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
  228. package/dist/esm/fields/ToggleGroup/index.native.js +3 -3
  229. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  230. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +2 -2
  231. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  232. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
  233. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  234. package/dist/esm/hooks/useFocusManagement.mjs +3 -2
  235. package/dist/esm/hooks/useFocusManagement.mjs.map +1 -1
  236. package/dist/esm/hooks/useFocusManagement.native.js +3 -2
  237. package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
  238. package/dist/esm/index.mjs +3 -1
  239. package/dist/esm/index.mjs.map +1 -1
  240. package/dist/esm/index.native.js +3 -1
  241. package/dist/esm/index.native.js.map +1 -1
  242. package/dist/esm/shared/focusManagement.mjs +1 -1
  243. package/dist/esm/shared/focusManagement.mjs.map +1 -1
  244. package/dist/esm/shared/focusManagement.native.js +1 -1
  245. package/dist/esm/shared/panelPortal.mjs +1 -1
  246. package/dist/esm/shared/panelPortal.mjs.map +1 -1
  247. package/dist/esm/shared/panelPortal.native.js +1 -1
  248. package/dist/esm/shared/panelPortal.native.js.map +1 -1
  249. package/dist/esm/shared/useDragScroll.mjs +2 -2
  250. package/dist/esm/shared/useDragScroll.mjs.map +1 -1
  251. package/dist/esm/shared/useDragScroll.native.js +2 -2
  252. package/dist/esm/shared/useDragScroll.native.js.map +1 -1
  253. package/dist/jsx/Button/index.mjs +17 -6
  254. package/dist/jsx/Button/index.mjs.map +1 -1
  255. package/dist/jsx/Button/index.native.js +18 -7
  256. package/dist/jsx/Button/index.native.js.map +1 -1
  257. package/dist/jsx/ErrorSummary.mjs +2 -2
  258. package/dist/jsx/ErrorSummary.mjs.map +1 -1
  259. package/dist/jsx/ErrorSummary.native.js +1 -1
  260. package/dist/jsx/ErrorSummary.native.js.map +1 -1
  261. package/dist/jsx/FloatingPanel/PanelPortal.mjs +1 -1
  262. package/dist/jsx/FloatingPanel/PanelPortal.mjs.map +1 -1
  263. package/dist/jsx/FloatingPanel/index.mjs +13 -4
  264. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  265. package/dist/jsx/FloatingPanel/index.native.js +9 -2
  266. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  267. package/dist/jsx/FloatingPanel/trailingAction.mjs +33 -0
  268. package/dist/jsx/FloatingPanel/trailingAction.mjs.map +1 -0
  269. package/dist/jsx/FloatingPanel/trailingAction.native.js +64 -0
  270. package/dist/jsx/FloatingPanel/trailingAction.native.js.map +1 -0
  271. package/dist/jsx/FormGrid.mjs +1 -0
  272. package/dist/jsx/FormGrid.mjs.map +1 -1
  273. package/dist/jsx/FormGrid.native.js +1 -0
  274. package/dist/jsx/FormGrid.native.js.map +1 -1
  275. package/dist/jsx/InputParts/PasswordReveal.mjs +68 -0
  276. package/dist/jsx/InputParts/PasswordReveal.mjs.map +1 -0
  277. package/dist/jsx/InputParts/PasswordReveal.native.js +104 -0
  278. package/dist/jsx/InputParts/PasswordReveal.native.js.map +1 -0
  279. package/dist/jsx/InputParts/index.mjs +97 -8
  280. package/dist/jsx/InputParts/index.mjs.map +1 -1
  281. package/dist/jsx/InputParts/index.native.js +99 -5
  282. package/dist/jsx/InputParts/index.native.js.map +1 -1
  283. package/dist/jsx/fields/ColorPicker/index.mjs +8 -17
  284. package/dist/jsx/fields/ColorPicker/index.mjs.map +1 -1
  285. package/dist/jsx/fields/ColorPicker/index.native.js +9 -18
  286. package/dist/jsx/fields/ColorPicker/index.native.js.map +1 -1
  287. package/dist/jsx/fields/Combobox/index.mjs +29 -45
  288. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  289. package/dist/jsx/fields/Combobox/index.native.js +30 -45
  290. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  291. package/dist/jsx/fields/DatePicker/Calendar.mjs +4 -5
  292. package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
  293. package/dist/jsx/fields/DatePicker/Calendar.native.js +3 -4
  294. package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
  295. package/dist/jsx/fields/DatePicker/parts.mjs +5 -9
  296. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  297. package/dist/jsx/fields/DatePicker/parts.native.js +5 -9
  298. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  299. package/dist/jsx/fields/Duration/durationMath.mjs +1 -1
  300. package/dist/jsx/fields/Duration/durationMath.mjs.map +1 -1
  301. package/dist/jsx/fields/Duration/durationMath.native.js +1 -1
  302. package/dist/jsx/fields/Duration/durationMath.native.js.map +1 -1
  303. package/dist/jsx/fields/Duration/index.mjs +100 -90
  304. package/dist/jsx/fields/Duration/index.mjs.map +1 -1
  305. package/dist/jsx/fields/Duration/index.native.js +108 -98
  306. package/dist/jsx/fields/Duration/index.native.js.map +1 -1
  307. package/dist/jsx/fields/FileUpload/index.mjs +135 -25
  308. package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
  309. package/dist/jsx/fields/FileUpload/index.native.js +149 -34
  310. package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
  311. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs +2 -1
  312. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  313. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js +3 -2
  314. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  315. package/dist/jsx/fields/Geolocation/index.mjs +13 -11
  316. package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
  317. package/dist/jsx/fields/Geolocation/index.native.js +10 -8
  318. package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
  319. package/dist/jsx/fields/Icon/index.mjs +8 -15
  320. package/dist/jsx/fields/Icon/index.mjs.map +1 -1
  321. package/dist/jsx/fields/Icon/index.native.js +6 -13
  322. package/dist/jsx/fields/Icon/index.native.js.map +1 -1
  323. package/dist/jsx/fields/ImageField/index.mjs +7 -7
  324. package/dist/jsx/fields/ImageField/index.mjs.map +1 -1
  325. package/dist/jsx/fields/ImageField/index.native.js +5 -5
  326. package/dist/jsx/fields/ImageField/index.native.js.map +1 -1
  327. package/dist/jsx/fields/Input/index.mjs +28 -22
  328. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  329. package/dist/jsx/fields/Input/index.native.js +28 -21
  330. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  331. package/dist/jsx/fields/MentionInput/index.mjs +13 -14
  332. package/dist/jsx/fields/MentionInput/index.mjs.map +1 -1
  333. package/dist/jsx/fields/MentionInput/index.native.js +7 -8
  334. package/dist/jsx/fields/MentionInput/index.native.js.map +1 -1
  335. package/dist/jsx/fields/OTPInput/index.mjs +2 -2
  336. package/dist/jsx/fields/OTPInput/index.mjs.map +1 -1
  337. package/dist/jsx/fields/OTPInput/index.native.js +1 -1
  338. package/dist/jsx/fields/OTPInput/index.native.js.map +1 -1
  339. package/dist/jsx/fields/PhoneInput/index.mjs +5 -5
  340. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  341. package/dist/jsx/fields/PhoneInput/index.native.js +3 -3
  342. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  343. package/dist/jsx/fields/RadioGroup/index.mjs +1 -0
  344. package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
  345. package/dist/jsx/fields/RadioGroup/index.native.js +1 -0
  346. package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
  347. package/dist/jsx/fields/SearchInput/index.mjs +5 -49
  348. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  349. package/dist/jsx/fields/SearchInput/index.native.js +4 -46
  350. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  351. package/dist/jsx/fields/Select/index.mjs +15 -13
  352. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  353. package/dist/jsx/fields/Select/index.native.js +14 -12
  354. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  355. package/dist/jsx/fields/Signature/index.mjs +2 -2
  356. package/dist/jsx/fields/Signature/index.mjs.map +1 -1
  357. package/dist/jsx/fields/Signature/index.native.js +1 -1
  358. package/dist/jsx/fields/Signature/index.native.js.map +1 -1
  359. package/dist/jsx/fields/Slider/index.mjs +2 -2
  360. package/dist/jsx/fields/Slider/index.mjs.map +1 -1
  361. package/dist/jsx/fields/Slider/index.native.js +1 -1
  362. package/dist/jsx/fields/Slider/index.native.js.map +1 -1
  363. package/dist/jsx/fields/TimePicker/parts.mjs +5 -9
  364. package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
  365. package/dist/jsx/fields/TimePicker/parts.native.js +5 -9
  366. package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
  367. package/dist/jsx/fields/TimeRangeScrubber/index.mjs +20 -15
  368. package/dist/jsx/fields/TimeRangeScrubber/index.mjs.map +1 -1
  369. package/dist/jsx/fields/TimeRangeScrubber/index.native.js +14 -9
  370. package/dist/jsx/fields/TimeRangeScrubber/index.native.js.map +1 -1
  371. package/dist/jsx/fields/ToggleGroup/index.mjs +3 -3
  372. package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
  373. package/dist/jsx/fields/ToggleGroup/index.native.js +1 -1
  374. package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
  375. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +2 -2
  376. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  377. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +5 -5
  378. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  379. package/dist/jsx/hooks/useFocusManagement.mjs +3 -2
  380. package/dist/jsx/hooks/useFocusManagement.mjs.map +1 -1
  381. package/dist/jsx/hooks/useFocusManagement.native.js +3 -2
  382. package/dist/jsx/hooks/useFocusManagement.native.js.map +1 -1
  383. package/dist/jsx/index.js +3 -1
  384. package/dist/jsx/index.js.map +1 -1
  385. package/dist/jsx/index.mjs +3 -1
  386. package/dist/jsx/index.mjs.map +1 -1
  387. package/dist/jsx/index.native.js +7 -0
  388. package/dist/jsx/index.native.js.map +1 -1
  389. package/dist/jsx/shared/focusManagement.mjs +1 -1
  390. package/dist/jsx/shared/focusManagement.mjs.map +1 -1
  391. package/dist/jsx/shared/focusManagement.native.js +1 -1
  392. package/dist/jsx/shared/focusManagement.native.js.map +1 -1
  393. package/dist/jsx/shared/panelPortal.mjs +1 -1
  394. package/dist/jsx/shared/panelPortal.mjs.map +1 -1
  395. package/dist/jsx/shared/panelPortal.native.js +1 -1
  396. package/dist/jsx/shared/panelPortal.native.js.map +1 -1
  397. package/dist/jsx/shared/useDragScroll.mjs +2 -2
  398. package/dist/jsx/shared/useDragScroll.mjs.map +1 -1
  399. package/dist/jsx/shared/useDragScroll.native.js +2 -2
  400. package/dist/jsx/shared/useDragScroll.native.js.map +1 -1
  401. package/package.json +8 -8
  402. package/src/AdaptivePopup/AdaptivePopup.stories.tsx +2 -1
  403. package/src/Button/Button.borderLadder.spec.tsx +32 -7
  404. package/src/Button/Button.edge.spec.tsx +68 -0
  405. package/src/Button/Button.stories.tsx +2 -1
  406. package/src/Button/index.tsx +37 -11
  407. package/src/Chip/Chip.stories.tsx +2 -1
  408. package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +2 -1
  409. package/src/ContextualSaveBar/UnsavedChangesDialog.stories.tsx +2 -1
  410. package/src/ControlGroup/ControlGroup.stories.tsx +2 -1
  411. package/src/DescriptionList/DescriptionList.stories.tsx +2 -1
  412. package/src/ErrorSummary.stories.tsx +2 -1
  413. package/src/ErrorSummary.tsx +2 -2
  414. package/src/FieldDisplay/FieldDisplay.stories.tsx +2 -1
  415. package/src/FieldLayout.stories.tsx +2 -2
  416. package/src/FloatingPanel/FloatingPanel.stories.tsx +2 -2
  417. package/src/FloatingPanel/PanelPortal.tsx +1 -0
  418. package/src/FloatingPanel/index.native.tsx +4 -2
  419. package/src/FloatingPanel/index.tsx +14 -4
  420. package/src/FloatingPanel/trailingAction.tsx +37 -0
  421. package/src/Form/Form.stories.tsx +2 -1
  422. package/src/FormGrid.stories.tsx +2 -1
  423. package/src/FormGrid.tsx +1 -0
  424. package/src/FormsIntegration.stories.tsx +4 -18
  425. package/src/InputParts/InputParts.stories.tsx +11 -11
  426. package/src/InputParts/PasswordReveal.tsx +94 -0
  427. package/src/InputParts/index.tsx +144 -2
  428. package/src/InputParts/inputPartsStories.spec.tsx +3 -1
  429. package/src/Skeleton/Skeleton.stories.tsx +2 -2
  430. package/src/Spinner/Spinner.stories.tsx +2 -2
  431. package/src/Wheel/Wheel.stories.tsx +2 -2
  432. package/src/fieldTrailingAction.spec.tsx +188 -0
  433. package/src/fields/Barcode/Barcode.stories.tsx +2 -1
  434. package/src/fields/Barcode/BarcodePreview.stories.tsx +2 -1
  435. package/src/fields/Checkbox/Checkbox.stories.tsx +3 -1
  436. package/src/fields/Checkbox/CheckboxGroup.stories.tsx +2 -2
  437. package/src/fields/Checkbox/Checkboxes.stories.tsx +2 -1
  438. package/src/fields/ColorPicker/PresetSwatches.stories.tsx +2 -1
  439. package/src/fields/ColorPicker/index.tsx +6 -12
  440. package/src/fields/Combobox/Combobox.stories.tsx +2 -1
  441. package/src/fields/Combobox/index.tsx +39 -41
  442. package/src/fields/DatePicker/Calendar.stories.tsx +2 -1
  443. package/src/fields/DatePicker/Calendar.tsx +4 -5
  444. package/src/fields/DatePicker/DatePicker.spec.tsx +2 -2
  445. package/src/fields/DatePicker/DatePicker.stories.tsx +2 -1
  446. package/src/fields/DatePicker/DateRangePicker.stories.tsx +2 -1
  447. package/src/fields/DatePicker/DatetimePicker.stories.tsx +2 -1
  448. package/src/fields/DatePicker/MonthPicker.stories.tsx +2 -1
  449. package/src/fields/DatePicker/MultiDatePicker.spec.tsx +1 -1
  450. package/src/fields/DatePicker/MultiDatePicker.stories.tsx +2 -1
  451. package/src/fields/DatePicker/parts.tsx +6 -10
  452. package/src/fields/Duration/Duration.spec.tsx +25 -1
  453. package/src/fields/Duration/Duration.stories.tsx +6 -1
  454. package/src/fields/Duration/durationMath.spec.ts +2 -2
  455. package/src/fields/Duration/durationMath.ts +1 -1
  456. package/src/fields/Duration/index.tsx +91 -70
  457. package/src/fields/FileUpload/FileUpload.spec.tsx +86 -3
  458. package/src/fields/FileUpload/FileUpload.stories.tsx +15 -0
  459. package/src/fields/FileUpload/index.tsx +170 -50
  460. package/src/fields/Geolocation/Geolocation.stories.tsx +2 -1
  461. package/src/fields/Geolocation/GeolocationMap.native.tsx +2 -1
  462. package/src/fields/Geolocation/GeolocationMap.tsx +2 -1
  463. package/src/fields/Geolocation/index.tsx +39 -16
  464. package/src/fields/Icon/index.tsx +9 -15
  465. package/src/fields/ImageField/index.tsx +9 -8
  466. package/src/fields/Input/Input.stories.tsx +39 -1
  467. package/src/fields/Input/index.tsx +45 -25
  468. package/src/fields/MentionInput/index.tsx +17 -18
  469. package/src/fields/OTPInput/OtpInput.stories.tsx +2 -1
  470. package/src/fields/OTPInput/index.tsx +2 -2
  471. package/src/fields/PhoneInput/PhoneInput.stories.tsx +2 -1
  472. package/src/fields/PhoneInput/index.tsx +10 -6
  473. package/src/fields/Progress/Progress.stories.tsx +2 -1
  474. package/src/fields/RadioGroup/RadioGroup.stories.tsx +3 -2
  475. package/src/fields/RadioGroup/index.tsx +1 -0
  476. package/src/fields/Rating/Rating.stories.tsx +2 -1
  477. package/src/fields/SearchInput/SearchInput.stories.tsx +2 -1
  478. package/src/fields/SearchInput/index.tsx +8 -45
  479. package/src/fields/Select/Select.stories.tsx +2 -2
  480. package/src/fields/Select/index.tsx +18 -12
  481. package/src/fields/Signature/Signature.stories.tsx +2 -1
  482. package/src/fields/Signature/index.tsx +6 -1
  483. package/src/fields/Slider/Slider.stories.tsx +2 -1
  484. package/src/fields/Slider/index.tsx +6 -2
  485. package/src/fields/Stepper/Stepper.stories.tsx +2 -1
  486. package/src/fields/Switch/Switch.stories.tsx +3 -1
  487. package/src/fields/TextArea/TextArea.stories.tsx +2 -1
  488. package/src/fields/TimePicker/TimePicker.stories.tsx +2 -1
  489. package/src/fields/TimePicker/parts.tsx +6 -10
  490. package/src/fields/TimeRangeScrubber/index.tsx +20 -18
  491. package/src/fields/ToggleGroup/ToggleGroup.stories.tsx +2 -8
  492. package/src/fields/ToggleGroup/index.tsx +10 -4
  493. package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +2 -2
  494. package/src/fields/pickerActivation.spec.tsx +7 -3
  495. package/src/hooks/useFocusManagement.ts +3 -2
  496. package/src/index.ts +9 -0
  497. package/src/shared/focusManagement.ts +1 -1
  498. package/src/shared/panelPortal.ts +2 -1
  499. package/src/shared/useDragScroll.ts +2 -2
  500. package/types/Button/index.d.ts +9 -1
  501. package/types/Button/index.d.ts.map +1 -1
  502. package/types/FloatingPanel/PanelPortal.d.ts.map +1 -1
  503. package/types/FloatingPanel/index.d.ts.map +1 -1
  504. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  505. package/types/FloatingPanel/trailingAction.d.ts +16 -0
  506. package/types/FloatingPanel/trailingAction.d.ts.map +1 -0
  507. package/types/InputParts/PasswordReveal.d.ts +28 -0
  508. package/types/InputParts/PasswordReveal.d.ts.map +1 -0
  509. package/types/InputParts/index.d.ts +34 -2
  510. package/types/InputParts/index.d.ts.map +1 -1
  511. package/types/fields/Checkbox/index.d.ts +4 -4
  512. package/types/fields/ColorPicker/index.d.ts.map +1 -1
  513. package/types/fields/Combobox/index.d.ts.map +1 -1
  514. package/types/fields/DatePicker/Calendar.d.ts.map +1 -1
  515. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  516. package/types/fields/Duration/index.d.ts.map +1 -1
  517. package/types/fields/FileUpload/index.d.ts +1 -0
  518. package/types/fields/FileUpload/index.d.ts.map +1 -1
  519. package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
  520. package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
  521. package/types/fields/Geolocation/index.d.ts.map +1 -1
  522. package/types/fields/Icon/index.d.ts.map +1 -1
  523. package/types/fields/ImageField/index.d.ts.map +1 -1
  524. package/types/fields/Input/index.d.ts +9 -3
  525. package/types/fields/Input/index.d.ts.map +1 -1
  526. package/types/fields/MentionInput/index.d.ts.map +1 -1
  527. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  528. package/types/fields/RadioGroup/index.d.ts +2 -2
  529. package/types/fields/RadioGroup/index.d.ts.map +1 -1
  530. package/types/fields/SearchInput/index.d.ts.map +1 -1
  531. package/types/fields/Select/index.d.ts.map +1 -1
  532. package/types/fields/Signature/index.d.ts.map +1 -1
  533. package/types/fields/Slider/index.d.ts.map +1 -1
  534. package/types/fields/TimePicker/parts.d.ts.map +1 -1
  535. package/types/fields/TimeRangeScrubber/index.d.ts.map +1 -1
  536. package/types/fields/ToggleGroup/index.d.ts +1 -1
  537. package/types/fields/ToggleGroup/index.d.ts.map +1 -1
  538. package/types/hooks/useFocusManagement.d.ts.map +1 -1
  539. package/types/index.d.ts +4 -0
  540. package/types/index.d.ts.map +1 -1
  541. package/types/shared/panelPortal.d.ts.map +1 -1
@@ -1,7 +1,15 @@
1
1
  import { transitionProps } from "@multiplatform.one/theme";
2
2
  import { getFontSized } from "@tamagui/get-font-sized";
3
3
  import type { SizeVariantSpreadFunction } from "@tamagui/web";
4
- import { useCallback, useEffect, useState, type ReactNode } from "react";
4
+ import {
5
+ createContext,
6
+ forwardRef,
7
+ useCallback,
8
+ useContext,
9
+ useEffect,
10
+ useState,
11
+ type ReactNode,
12
+ } from "react";
5
13
  import type { ComponentProps, Ref, RefObject } from "react";
6
14
  import { Pressable as RNPressable } from "react-native";
7
15
  import type {
@@ -51,6 +59,7 @@ import {
51
59
  import { formButtonColors, formCommonColors, formInputColors } from "../shared/colorRamps";
52
60
  import { useControlGrouped } from "../shared/groupContext";
53
61
  import { nativeAutoFocus } from "../shared/nativeAutoFocus";
62
+ import { pressSlopProps } from "../shared/pressSlopProps";
54
63
  import { useIsInTableCell } from "../shared/tableCellContext";
55
64
  import { useFieldA11y, useFieldDescribedBy } from "../fieldLayout";
56
65
 
@@ -286,6 +295,27 @@ const InputGroupFrame = styled(XGroup, {
286
295
  },
287
296
  });
288
297
 
298
+ /**
299
+ * LC-149 FIELD-TRAILING-ACTION: true while a field's trigger has an action
300
+ * overlaid on its trailing edge from outside the Box (FloatingPanel
301
+ * `triggerEnd`). The Box then keeps that end cap empty for it.
302
+ */
303
+ const FieldTrailingOverlayContext = createContext(false);
304
+
305
+ export function FieldTrailingOverlay({
306
+ active,
307
+ children,
308
+ }: {
309
+ active: boolean;
310
+ children: ReactNode;
311
+ }) {
312
+ return (
313
+ <FieldTrailingOverlayContext.Provider value={active}>
314
+ {children}
315
+ </FieldTrailingOverlayContext.Provider>
316
+ );
317
+ }
318
+
289
319
  /**
290
320
  * Fabric + Tamagui XGroup often claims the responder without firing `onPress`,
291
321
  * so Select/Date/Combobox triggers look tappable but never open. On native,
@@ -440,6 +470,21 @@ const InputGroupImpl = InputGroupFrame.styleable<{
440
470
  (typeof paddingHorizontalProp !== "number" && paddingHorizontalProp != null)
441
471
  ? undefined
442
472
  : { paddingHorizontal: fieldInset };
473
+ // LC-149: an action overlaid from outside the Box (a picker's native clear,
474
+ // which must sit outside the trigger's press capture) still lands in the
475
+ // trailing slot. The Box reserves the end cap and drops its end inset so
476
+ // the overlay reads as part of the field.
477
+ const trailingOverlay = useContext(FieldTrailingOverlayContext);
478
+ const trailingSlot = trailingOverlay ? (
479
+ <View
480
+ aria-hidden
481
+ data-field-action-slot=""
482
+ width={familyRecipe.height}
483
+ flexShrink={0}
484
+ pointerEvents="none"
485
+ />
486
+ ) : null;
487
+ const trailingPadProps = trailingOverlay ? { paddingInlineEnd: 0 } : undefined;
443
488
 
444
489
  // Chromeless rendering inside table cells
445
490
  if (inTableCell) {
@@ -472,12 +517,14 @@ const InputGroupImpl = InputGroupFrame.styleable<{
472
517
  {...controlFragment}
473
518
  {...passthroughSizeProps}
474
519
  {...insetPadProps}
520
+ {...trailingPadProps}
475
521
  {...sizeRecipeEscapeOverride}
476
522
  {...framePressProps}
477
523
  {...boxRingAttrs}
478
524
  overflow={boxOverflow}
479
525
  >
480
526
  {children}
527
+ {trailingSlot}
481
528
  </InputGroupFrame>,
482
529
  )}
483
530
  </FocusContext.Provider>
@@ -537,6 +584,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
537
584
  {...props}
538
585
  {...passthroughSizeProps}
539
586
  {...insetPadProps}
587
+ {...trailingPadProps}
540
588
  {...sizeRecipeEscapeOverride}
541
589
  {...framePressProps}
542
590
  {...boxRingAttrs}
@@ -554,6 +602,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
554
602
  overflow={boxOverflow}
555
603
  >
556
604
  {children}
605
+ {trailingSlot}
557
606
  </InputGroupFrame>,
558
607
  )}
559
608
  </FocusContext.Provider>
@@ -969,7 +1018,11 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
969
1018
  // knob's: a $2 field inside a $4 knob would otherwise ship a 44px stop
970
1019
  // on a 32px frame. LC-77 keeps the sub-floor case pressable via the
971
1020
  // caller's hitSlop, never by inflating the cap.
972
- const square = sizeRecipeForToken(String(size ?? "$true"), { touch: hydrationTouch }).height;
1021
+ const measured = (props as { height?: unknown }).height;
1022
+ const square =
1023
+ typeof measured === "number"
1024
+ ? measured
1025
+ : sizeRecipeForToken(String(size ?? "$true"), { touch: hydrationTouch }).height;
973
1026
  const disabled = (props as { disabled?: boolean }).disabled === true;
974
1027
  if (isWeb) ensureCompositeFocusRing();
975
1028
  return (
@@ -1026,6 +1079,94 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
1026
1079
  );
1027
1080
  });
1028
1081
 
1082
+ // ---------------------------------------------------------------------------
1083
+ // Input.Action
1084
+ // ---------------------------------------------------------------------------
1085
+
1086
+ export interface InputActionProps {
1087
+ /** Accessible name; the glyph is decorative. */
1088
+ label: string;
1089
+ onPress?: () => void;
1090
+ disabled?: boolean;
1091
+ /** Toggle state for a two-state action (reveal). Web announces aria-pressed. */
1092
+ pressed?: boolean;
1093
+ /** id of the input this action drives (aria-controls). */
1094
+ controls?: string;
1095
+ size?: SizeTokens | FontSizeTokens;
1096
+ /**
1097
+ * The field's measured height, when the action sits outside the Box (a
1098
+ * picker clear overlaid from FloatingPanel `triggerEnd`). Inside a Box the
1099
+ * square comes from `size`.
1100
+ */
1101
+ height?: number;
1102
+ tabIndex?: number;
1103
+ testID?: string;
1104
+ /** Web: swallow the mousedown a picker trigger would open on. */
1105
+ onMouseDown?: (e: { stopPropagation: () => void; preventDefault: () => void }) => void;
1106
+ [data: `data-${string}`]: string | undefined;
1107
+ children: ReactNode;
1108
+ }
1109
+
1110
+ /**
1111
+ * LC-149 FIELD-TRAILING-ACTION: the field's own action (reveal, clear, copy,
1112
+ * eyedropper) is a chromeless glyph on the Box's trailing edge, never a
1113
+ * bordered button beside the field. It squares off the field height and pads
1114
+ * its press target to MIN_PRESS_TARGET when the field is shorter. It is the
1115
+ * field's second tab stop and rings its glyph (the `glyphRing` end cap).
1116
+ */
1117
+ const InputActionImpl = forwardRef<TamaguiElement, InputActionProps>(function InputAction(
1118
+ { label, onPress, disabled, pressed, controls, size, height, tabIndex, children, ...rest },
1119
+ ref,
1120
+ ) {
1121
+ const { size: contextSize } = InputContext.useStyledContext();
1122
+ const hydrationTouch = useTouchSurface();
1123
+ const token = (size ?? contextSize ?? "$true") as FontSizeTokens;
1124
+ const square = height ?? sizeRecipeForToken(String(token), { touch: hydrationTouch }).height;
1125
+ const activate = () => {
1126
+ if (!disabled) onPress?.();
1127
+ };
1128
+ return (
1129
+ <InputButtonImpl
1130
+ ref={ref as never}
1131
+ glyphRing
1132
+ size={token}
1133
+ disabled={disabled}
1134
+ tabIndex={tabIndex}
1135
+ aria-label={label}
1136
+ accessibilityLabel={label}
1137
+ accessibilityRole="button"
1138
+ accessibilityState={{ disabled: !!disabled }}
1139
+ {...(isWeb && pressed !== undefined ? { "aria-pressed": pressed } : undefined)}
1140
+ {...(controls ? { "aria-controls": controls } : undefined)}
1141
+ height={square}
1142
+ width={square}
1143
+ {...pressSlopProps(square, true)}
1144
+ data-field-action="trailing"
1145
+ onPress={
1146
+ disabled
1147
+ ? undefined
1148
+ : (e?: { stopPropagation?: () => void }) => {
1149
+ e?.stopPropagation?.();
1150
+ activate();
1151
+ }
1152
+ }
1153
+ onKeyDown={
1154
+ ((e: KeyboardEvent) => {
1155
+ if (e.key !== "Enter" && e.key !== " ") return;
1156
+ e.preventDefault();
1157
+ e.stopPropagation();
1158
+ activate();
1159
+ }) as unknown as () => void
1160
+ }
1161
+ {...rest}
1162
+ >
1163
+ <InputIcon aria-hidden color={formCommonColors.muted}>
1164
+ {children}
1165
+ </InputIcon>
1166
+ </InputButtonImpl>
1167
+ );
1168
+ });
1169
+
1029
1170
  // ---------------------------------------------------------------------------
1030
1171
  // Input.Icon
1031
1172
  // ---------------------------------------------------------------------------
@@ -1321,6 +1462,7 @@ const InputCompound = Object.assign(InputContainerImpl, {
1321
1462
  TextArea: FocusWiredTextArea,
1322
1463
  Section: InputSection,
1323
1464
  Button: InputButtonImpl,
1465
+ Action: InputActionImpl,
1324
1466
  Icon: InputIcon,
1325
1467
  Info: InputInfo,
1326
1468
  Meta: InputFieldMeta,
@@ -74,10 +74,12 @@ describe("Forms/InputParts stories", () => {
74
74
  expect(placeholders).toEqual(["Leading icon", "Trailing icon", "Both ends"]);
75
75
  });
76
76
 
77
- it("TrailingButton exposes a labelled reveal toggle beside the field", () => {
77
+ it("TrailingButton puts a labelled reveal toggle inside the field (LC-149)", () => {
78
78
  const { container } = mount(TrailingButton as StoryLike);
79
79
  const button = container.querySelector("[aria-label='Show password']");
80
80
  expect(button).toBeTruthy();
81
+ expect(button?.getAttribute("data-field-action")).toBe("trailing");
82
+ expect(button?.closest("[data-mp-input-box]")).toBeTruthy();
81
83
  expect(container.querySelector("#parts-password")).toBeTruthy();
82
84
  });
83
85
 
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
- import { Preset } from "@multiplatform.one/theme";
3
- import { Paragraph, XStack, YStack } from "tamagui";
2
+ import { Preset, Paragraph } from "@multiplatform.one/theme";
3
+ import { XStack, YStack } from "tamagui";
4
4
  import { Skeleton, SkeletonCircle, SkeletonText } from "./index";
5
5
 
6
6
  const meta: Meta<typeof Skeleton> = {
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
2
  import { useState } from "react";
3
- import { Preset, Surface } from "@multiplatform.one/theme";
4
- import { XStack, YStack, Paragraph } from "tamagui";
3
+ import { Preset, Surface, Paragraph } from "@multiplatform.one/theme";
4
+ import { XStack, YStack } from "tamagui";
5
5
  import { Button } from "../Button";
6
6
  import { Spinner } from "./index";
7
7
 
@@ -1,8 +1,8 @@
1
1
  import { action } from "@multiplatform.one/storybook";
2
2
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
3
- import { Preset } from "@multiplatform.one/theme";
3
+ import { Preset, Paragraph } from "@multiplatform.one/theme";
4
4
  import { useState } from "react";
5
- import { Paragraph, XStack, YStack } from "tamagui";
5
+ import { XStack, YStack } from "tamagui";
6
6
  import { Wheel } from "./index";
7
7
 
8
8
  const numbers = Array.from({ length: 24 }, (_, i) => i);
@@ -0,0 +1,188 @@
1
+ import { readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { fireEvent } from "@testing-library/react";
4
+ import { inspectDesign } from "@multiplatform.one/config/design-lint";
5
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
6
+ import { describe, expect, it } from "vitest";
7
+ import { FloatingPanel } from "./FloatingPanel";
8
+ import { Input } from "./fields/Input";
9
+ import { Input as InputParts } from "./InputParts";
10
+
11
+ const src = join(process.cwd(), "src");
12
+
13
+ function sources(dir: string): string[] {
14
+ return readdirSync(dir).flatMap((entry) => {
15
+ const path = join(dir, entry);
16
+ if (statSync(path).isDirectory()) return sources(path);
17
+ return /\.tsx?$/.test(entry) && !/\.(spec|stories|test)\./.test(entry) ? [path] : [];
18
+ });
19
+ }
20
+
21
+ function revealOf(container: HTMLElement) {
22
+ return container.querySelector(
23
+ "[aria-label='Show password'], [aria-label='Hide password']",
24
+ ) as HTMLElement | null;
25
+ }
26
+
27
+ describe("LC-149 FIELD-TRAILING-ACTION", () => {
28
+ describe("password reveal", () => {
29
+ it("is a chromeless trailing action inside the field, not a button beside it", () => {
30
+ const result = renderWithProviders(
31
+ <Input label="Password" secureTextEntry defaultValue="hunter22" />,
32
+ );
33
+ const box = result.container.querySelector("[data-mp-input-box]") as HTMLElement;
34
+ const reveal = revealOf(result.container);
35
+ if (!box || !reveal) throw new Error("box or reveal missing");
36
+ expect(box.contains(reveal)).toBe(true);
37
+ expect(reveal.getAttribute("data-field-action")).toBe("trailing");
38
+ expect(reveal.getAttribute("data-end-cap")).toBe(box.getAttribute("data-visual-height"));
39
+ expect(reveal.className).toMatch(/mp-chip-dismiss/);
40
+ expect(box.lastElementChild?.contains(reveal)).toBe(true);
41
+ });
42
+
43
+ it("toggles eye / eye-slash with Show password / Hide password", () => {
44
+ const result = renderWithProviders(
45
+ <Input label="Password" secureTextEntry defaultValue="hunter22" />,
46
+ );
47
+ const input = result.container.querySelector("input") as HTMLInputElement;
48
+ const reveal = revealOf(result.container);
49
+ if (!input || !reveal) throw new Error("anatomy missing");
50
+ expect(input.getAttribute("type")).toBe("password");
51
+ expect(reveal.getAttribute("aria-label")).toBe("Show password");
52
+ expect(reveal.getAttribute("aria-pressed")).toBe("false");
53
+ const maskedGlyph = reveal.querySelector("svg")?.innerHTML;
54
+
55
+ fireEvent.click(reveal);
56
+ const shown = revealOf(result.container);
57
+ if (!shown) throw new Error("reveal missing after toggle");
58
+ expect(input.getAttribute("type")).not.toBe("password");
59
+ expect(shown.getAttribute("aria-label")).toBe("Hide password");
60
+ expect(shown.getAttribute("aria-pressed")).toBe("true");
61
+ expect(shown.querySelector("svg")?.innerHTML).not.toBe(maskedGlyph);
62
+
63
+ fireEvent.click(shown);
64
+ expect(input.getAttribute("type")).toBe("password");
65
+ expect(revealOf(result.container)?.getAttribute("aria-label")).toBe("Show password");
66
+ });
67
+
68
+ it("rides inputProps.secureTextEntry too, and reveal={false} drops it", () => {
69
+ const viaProps = renderWithProviders(
70
+ <Input label="Password" inputProps={{ secureTextEntry: true }} />,
71
+ );
72
+ expect(revealOf(viaProps.container)).not.toBeNull();
73
+ const opted = renderWithProviders(<Input label="PIN" secureTextEntry reveal={false} />);
74
+ expect(revealOf(opted.container)).toBeNull();
75
+ });
76
+ });
77
+
78
+ describe("error with a trailing action", () => {
79
+ it("shows the message and no in-field glyph when an action owns the slot", () => {
80
+ const result = renderWithProviders(
81
+ <Input label="Password" secureTextEntry error="Passwords do not match" />,
82
+ );
83
+ expect(result.container.querySelector("[data-field-error-glyph]")).toBeNull();
84
+ expect(revealOf(result.container)).not.toBeNull();
85
+ expect(result.findTextElement("Passwords do not match")).toBeDefined();
86
+ const input = result.container.querySelector("input") as HTMLInputElement;
87
+ expect(input.getAttribute("aria-invalid")).toBe("true");
88
+ });
89
+
90
+ it("drops the glyph for the copy action too", () => {
91
+ const result = renderWithProviders(
92
+ <Input label="Token" readOnly copy value="mpo_live" error="Token expired" />,
93
+ );
94
+ expect(result.container.querySelector("[data-field-error-glyph]")).toBeNull();
95
+ });
96
+
97
+ it("keeps the glyph when the trailing slot is empty", () => {
98
+ const result = renderWithProviders(<Input label="Name" error="Enter your name" />);
99
+ expect(result.container.querySelector("[data-field-error-glyph]")).not.toBeNull();
100
+ });
101
+ });
102
+
103
+ describe("picker clears overlaid from outside the trigger", () => {
104
+ it("land in the Box's trailing end cap, which the Box keeps empty for them", () => {
105
+ const result = renderWithProviders(
106
+ <FloatingPanel
107
+ open={false}
108
+ onOpenChange={() => {}}
109
+ sheet
110
+ trigger={
111
+ <InputParts size="$4">
112
+ <InputParts.Box>
113
+ <InputParts.Area value="2026-10-25" readOnly />
114
+ </InputParts.Box>
115
+ </InputParts>
116
+ }
117
+ triggerEnd={
118
+ <InputParts.Action label="Clear date" onPress={() => {}}>
119
+ <svg />
120
+ </InputParts.Action>
121
+ }
122
+ >
123
+ <span />
124
+ </FloatingPanel>,
125
+ );
126
+ const box = result.container.querySelector("[data-mp-input-box]") as HTMLElement;
127
+ const slot = box?.querySelector("[data-field-action-slot]") as HTMLElement | null;
128
+ const overlay = result.container.querySelector("[data-field-action-overlay]");
129
+ const clear = result.container.querySelector("[aria-label='Clear date']");
130
+ expect(slot).not.toBeNull();
131
+ expect(overlay?.contains(clear)).toBe(true);
132
+ expect(box.contains(clear)).toBe(false);
133
+ });
134
+
135
+ it("leave the Box alone when there is nothing to overlay", () => {
136
+ const result = renderWithProviders(
137
+ <FloatingPanel
138
+ open={false}
139
+ onOpenChange={() => {}}
140
+ sheet
141
+ trigger={
142
+ <InputParts size="$4">
143
+ <InputParts.Box>
144
+ <InputParts.Area value="" readOnly />
145
+ </InputParts.Box>
146
+ </InputParts>
147
+ }
148
+ >
149
+ <span />
150
+ </FloatingPanel>,
151
+ );
152
+ expect(result.container.querySelector("[data-field-action-slot]")).toBeNull();
153
+ expect(result.container.querySelector("[data-field-action-overlay]")).toBeNull();
154
+ });
155
+ });
156
+
157
+ describe("every MPO field keeps its own action in the trailing slot", () => {
158
+ const files = [
159
+ ...sources(join(src, "fields")),
160
+ ...sources(join(src, "InputParts")),
161
+ ...sources(join(src, "FloatingPanel")),
162
+ ...sources(join(src, "..", "..", "frappe-ui", "src", "fields")),
163
+ ...sources(join(src, "..", "..", "components", "src", "CopyField")),
164
+ ];
165
+
166
+ it("no field renders its action as a sibling button", () => {
167
+ const hits = files.flatMap((file) =>
168
+ (inspectDesign(readFileSync(file, "utf8"), file) as string[]).filter((error) =>
169
+ error.includes("[field-action]"),
170
+ ),
171
+ );
172
+ expect(hits).toEqual([]);
173
+ });
174
+
175
+ it("the detector flags an icon button beside a field", () => {
176
+ const sibling = inspectDesign(
177
+ `const x = (
178
+ <XStack>
179
+ <Input label="Password" secureTextEntry />
180
+ <Button icon={<EyeIcon />} aria-label="Show password" />
181
+ </XStack>
182
+ );`,
183
+ "Sibling.tsx",
184
+ ) as string[];
185
+ expect(sibling.join("\n")).toMatch(/\[field-action\]/);
186
+ });
187
+ });
188
+ });
@@ -3,10 +3,11 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
3
3
  import { BarcodeIcon, CameraIcon, XIcon } from "@phosphor-icons/react";
4
4
  import { useForm } from "@tanstack/react-form";
5
5
  import { useState } from "react";
6
- import { Text, YStack } from "tamagui";
6
+ import { YStack } from "tamagui";
7
7
  import { Button } from "../../Button";
8
8
  import { Form } from "../../Form";
9
9
  import { Barcode } from "./index";
10
+ import { Text } from "@multiplatform.one/theme";
10
11
 
11
12
  const iconProps = {
12
13
  barcodeIcon: <BarcodeIcon size={18} />,
@@ -8,8 +8,9 @@
8
8
  */
9
9
 
10
10
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
11
- import { Text, XStack, YStack } from "tamagui";
11
+ import { XStack, YStack } from "tamagui";
12
12
  import { BarcodePreview } from "./BarcodePreview";
13
+ import { Text } from "@multiplatform.one/theme";
13
14
 
14
15
  const meta: Meta<typeof BarcodePreview> = {
15
16
  title: "Forms/BarcodePreview",
@@ -4,10 +4,12 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
4
4
  import { CheckIcon } from "@phosphor-icons/react";
5
5
  import { useForm } from "@tanstack/react-form";
6
6
  import { useState } from "react";
7
- import { Checkbox as TamaguiCheckbox, Label, Paragraph, XStack, YStack } from "tamagui";
7
+ import { Checkbox as TamaguiCheckbox, XStack, YStack } from "tamagui";
8
+ import { Label } from "../../Label";
8
9
  import { Button } from "../../Button";
9
10
  import { Form } from "../../Form";
10
11
  import { Checkbox, Checkboxes, CheckboxGroup } from "./index";
12
+ import { Paragraph } from "@multiplatform.one/theme";
11
13
 
12
14
  const meta: Meta<typeof Checkbox> = {
13
15
  title: "Forms/Checkbox",
@@ -1,8 +1,8 @@
1
1
  import { action } from "@multiplatform.one/storybook";
2
2
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
3
- import { Preset } from "@multiplatform.one/theme";
3
+ import { Preset, Paragraph } from "@multiplatform.one/theme";
4
4
  import { useForm } from "@tanstack/react-form";
5
- import { Paragraph, YStack } from "tamagui";
5
+ import { YStack } from "tamagui";
6
6
  import { Button } from "../../Button";
7
7
  import { Form } from "../../Form";
8
8
  import { CheckboxGroup } from "./CheckboxGroup";
@@ -1,9 +1,10 @@
1
1
  import { action } from "@multiplatform.one/storybook";
2
2
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
3
3
  import { useState } from "react";
4
- import { Paragraph, XStack, YStack } from "tamagui";
4
+ import { XStack, YStack } from "tamagui";
5
5
  import { CheckboxGroup } from "./CheckboxGroup";
6
6
  import { Checkboxes } from "./index";
7
+ import { Paragraph } from "@multiplatform.one/theme";
7
8
 
8
9
  const meta: Meta = {
9
10
  title: "Forms/Checkboxes",
@@ -7,8 +7,9 @@
7
7
  import { action } from "@multiplatform.one/storybook";
8
8
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
9
9
  import { useState } from "react";
10
- import { Text, YStack } from "tamagui";
10
+ import { YStack } from "tamagui";
11
11
  import { PresetSwatches } from "./parts";
12
+ import { Text } from "@multiplatform.one/theme";
12
13
 
13
14
  const BRAND = ["#1E40AF", "#1D4ED8", "#2563EB", "#3B82F6", "#60A5FA", "#93C5FD", "#BFDBFE"];
14
15
 
@@ -8,7 +8,6 @@ import {
8
8
  } from "@multiplatform.one/theme";
9
9
  import { type ComponentProps, useCallback, useEffect, useMemo, useRef, useState } from "react";
10
10
  import { type Popover, View, XStack, YStack, isWeb, useProps, useTheme } from "tamagui";
11
- import { Button } from "../../Button";
12
11
 
13
12
  import { Field, FieldLayout } from "../../fieldLayout";
14
13
  import {
@@ -425,19 +424,13 @@ function ColorBody({
425
424
  placeholder="#000000"
426
425
  maxLength={showAlpha ? 9 : 7}
427
426
  />
427
+ {hasEyeDropper && (
428
+ <InputParts.Action label={t("Eyedropper")} onPress={handleEyeDropper}>
429
+ <Pipette />
430
+ </InputParts.Action>
431
+ )}
428
432
  </InputParts.Box>
429
433
  </InputParts>
430
- {hasEyeDropper && (
431
- <Button
432
- size={knobProps.sizeToken}
433
- chromeless
434
- icon={<Pipette size={CHIP_PX[sizeTokenStop(knobProps.sizeToken)] ?? 18} />}
435
- onPress={handleEyeDropper}
436
- cursor="pointer"
437
- aria-label={t("Eyedropper")}
438
- hoverStyle={{ opacity: 0.7 }}
439
- />
440
- )}
441
434
  </XStack>
442
435
  </YStack>
443
436
  );
@@ -500,6 +493,7 @@ function ColorPickerControl({
500
493
  // Focus can still be parked on a control inside the closing panel while
501
494
  // it animates out — treat that the same as focus already being lost.
502
495
  const inClosingPanel =
496
+ typeof HTMLElement !== "undefined" &&
503
497
  active instanceof HTMLElement &&
504
498
  !!active.closest('[data-testid="floating-panel-viewport"]');
505
499
  if (active && active !== document.body && !inClosingPanel) return;
@@ -3,11 +3,12 @@ import { DataTable, type DataTableColumn } from "@multiplatform.one/table";
3
3
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
4
4
  import { useForm } from "@tanstack/react-form";
5
5
  import { useState } from "react";
6
- import { Text, XStack, YStack } from "tamagui";
6
+ import { XStack, YStack } from "tamagui";
7
7
  import { Button } from "../../Button";
8
8
  import { Form } from "../../Form";
9
9
  import { Combobox, type ComboboxOption } from "./index";
10
10
  import { authorOptions } from "./authorOptions";
11
+ import { Text } from "@multiplatform.one/theme";
11
12
 
12
13
  const meta: Meta<typeof Combobox> = {
13
14
  title: "Forms/Combobox",