@multiplatform.one/forms 7.7.6 → 7.10.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 (497) hide show
  1. package/dist/cjs/Button/index.cjs +1 -4
  2. package/dist/cjs/Button/index.native.js +5 -6
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/Chip/index.cjs +1 -1
  5. package/dist/cjs/Chip/index.native.js +1 -1
  6. package/dist/cjs/Chip/index.native.js.map +1 -1
  7. package/dist/cjs/FloatingPanel/index.cjs +59 -14
  8. package/dist/cjs/FloatingPanel/index.native.js +16 -7
  9. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  10. package/dist/cjs/FloatingPanel/nestedAction.cjs +37 -0
  11. package/dist/cjs/FloatingPanel/nestedAction.native.js +42 -0
  12. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -0
  13. package/dist/cjs/InputParts/index.cjs +19 -8
  14. package/dist/cjs/InputParts/index.native.js +20 -11
  15. package/dist/cjs/InputParts/index.native.js.map +1 -1
  16. package/dist/cjs/Wheel/index.cjs +3 -3
  17. package/dist/cjs/Wheel/index.native.js +3 -3
  18. package/dist/cjs/Wheel/index.native.js.map +1 -1
  19. package/dist/cjs/fieldLayout.cjs +3 -3
  20. package/dist/cjs/fieldLayout.native.js +3 -3
  21. package/dist/cjs/fieldLayout.native.js.map +1 -1
  22. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.cjs +9 -2
  23. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  24. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  25. package/dist/cjs/fields/Combobox/index.cjs +36 -29
  26. package/dist/cjs/fields/Combobox/index.native.js +38 -38
  27. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  28. package/dist/cjs/fields/DatePicker/Calendar.cjs +6 -1
  29. package/dist/cjs/fields/DatePicker/Calendar.native.js +6 -1
  30. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  31. package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +2 -2
  32. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  33. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  34. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +15 -12
  35. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  36. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  37. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +39 -14
  38. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  39. package/dist/cjs/fields/DatePicker/MonthPicker.cjs +10 -3
  40. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +10 -3
  41. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  42. package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +2 -2
  43. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  44. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  45. package/dist/cjs/fields/DatePicker/index.native.js +3 -0
  46. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  47. package/dist/cjs/fields/DatePicker/parts.cjs +26 -14
  48. package/dist/cjs/fields/DatePicker/parts.native.js +28 -14
  49. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  50. package/dist/cjs/fields/FileUpload/index.cjs +6 -0
  51. package/dist/cjs/fields/FileUpload/index.native.js +6 -0
  52. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  53. package/dist/cjs/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  54. package/dist/cjs/fields/Geolocation/geocoder.cjs +63 -0
  55. package/dist/cjs/fields/Geolocation/geocoder.native.js +68 -0
  56. package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -0
  57. package/dist/cjs/fields/Geolocation/index.cjs +801 -152
  58. package/dist/cjs/fields/Geolocation/index.native.js +856 -167
  59. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  60. package/dist/cjs/fields/Geolocation/nativeSearchFocus.cjs +44 -0
  61. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  62. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  63. package/dist/cjs/fields/Icon/drawnSet.cjs +16 -3
  64. package/dist/cjs/fields/Icon/drawnSet.native.js +20 -3
  65. package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
  66. package/dist/cjs/fields/Icon/index.cjs +102 -27
  67. package/dist/cjs/fields/Icon/index.native.js +115 -31
  68. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  69. package/dist/cjs/fields/Input/index.cjs +5 -12
  70. package/dist/cjs/fields/Input/index.native.js +5 -13
  71. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  72. package/dist/cjs/fields/PhoneInput/index.cjs +2 -2
  73. package/dist/cjs/fields/PhoneInput/index.native.js +2 -2
  74. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  75. package/dist/cjs/fields/RadioGroup/index.cjs +34 -5
  76. package/dist/cjs/fields/RadioGroup/index.native.js +49 -7
  77. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  78. package/dist/cjs/fields/SearchInput/index.cjs +8 -9
  79. package/dist/cjs/fields/SearchInput/index.native.js +8 -9
  80. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  81. package/dist/cjs/fields/Select/index.cjs +42 -11
  82. package/dist/cjs/fields/Select/index.native.js +52 -20
  83. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  84. package/dist/cjs/fields/Stepper/index.cjs +144 -31
  85. package/dist/cjs/fields/Stepper/index.native.js +151 -31
  86. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  87. package/dist/cjs/fields/ToggleGroup/index.cjs +35 -2
  88. package/dist/cjs/fields/ToggleGroup/index.native.js +42 -2
  89. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  90. package/dist/cjs/index.cjs +2 -0
  91. package/dist/cjs/index.native.js +2 -0
  92. package/dist/cjs/index.native.js.map +1 -1
  93. package/dist/cjs/shared/focusManagement.cjs +24 -11
  94. package/dist/cjs/shared/focusManagement.native.js +24 -11
  95. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  96. package/dist/cjs/shared/nativeA11y.cjs +57 -0
  97. package/dist/cjs/shared/nativeA11y.native.js +61 -0
  98. package/dist/cjs/shared/nativeA11y.native.js.map +1 -0
  99. package/dist/esm/Button/index.mjs +1 -4
  100. package/dist/esm/Button/index.mjs.map +1 -1
  101. package/dist/esm/Button/index.native.js +5 -6
  102. package/dist/esm/Button/index.native.js.map +1 -1
  103. package/dist/esm/Chip/index.mjs +1 -1
  104. package/dist/esm/Chip/index.mjs.map +1 -1
  105. package/dist/esm/Chip/index.native.js +1 -1
  106. package/dist/esm/Chip/index.native.js.map +1 -1
  107. package/dist/esm/FloatingPanel/index.mjs +58 -15
  108. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  109. package/dist/esm/FloatingPanel/index.native.js +15 -8
  110. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  111. package/dist/esm/FloatingPanel/nestedAction.mjs +11 -0
  112. package/dist/esm/FloatingPanel/nestedAction.mjs.map +1 -0
  113. package/dist/esm/FloatingPanel/nestedAction.native.js +13 -0
  114. package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -0
  115. package/dist/esm/InputParts/index.mjs +20 -9
  116. package/dist/esm/InputParts/index.mjs.map +1 -1
  117. package/dist/esm/InputParts/index.native.js +21 -12
  118. package/dist/esm/InputParts/index.native.js.map +1 -1
  119. package/dist/esm/Wheel/index.mjs +3 -3
  120. package/dist/esm/Wheel/index.mjs.map +1 -1
  121. package/dist/esm/Wheel/index.native.js +3 -3
  122. package/dist/esm/Wheel/index.native.js.map +1 -1
  123. package/dist/esm/fieldLayout.mjs +3 -3
  124. package/dist/esm/fieldLayout.mjs.map +1 -1
  125. package/dist/esm/fieldLayout.native.js +3 -3
  126. package/dist/esm/fieldLayout.native.js.map +1 -1
  127. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  128. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  129. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  130. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  131. package/dist/esm/fields/Combobox/index.mjs +36 -29
  132. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  133. package/dist/esm/fields/Combobox/index.native.js +38 -38
  134. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  135. package/dist/esm/fields/DatePicker/Calendar.mjs +6 -1
  136. package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
  137. package/dist/esm/fields/DatePicker/Calendar.native.js +6 -1
  138. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  139. package/dist/esm/fields/DatePicker/DateRangePicker.mjs +2 -2
  140. package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  141. package/dist/esm/fields/DatePicker/DateRangePicker.native.js +2 -2
  142. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  143. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  144. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  145. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  146. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  147. package/dist/esm/fields/DatePicker/DatetimePicker.native.js +39 -14
  148. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  149. package/dist/esm/fields/DatePicker/MonthPicker.mjs +10 -3
  150. package/dist/esm/fields/DatePicker/MonthPicker.mjs.map +1 -1
  151. package/dist/esm/fields/DatePicker/MonthPicker.native.js +10 -3
  152. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  153. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +2 -2
  154. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  155. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +2 -2
  156. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  157. package/dist/esm/fields/DatePicker/index.native.js +3 -0
  158. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  159. package/dist/esm/fields/DatePicker/parts.mjs +28 -16
  160. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  161. package/dist/esm/fields/DatePicker/parts.native.js +30 -16
  162. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  163. package/dist/esm/fields/FileUpload/index.mjs +6 -0
  164. package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
  165. package/dist/esm/fields/FileUpload/index.native.js +6 -0
  166. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  167. package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  168. package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  169. package/dist/esm/fields/Geolocation/geocoder.mjs +33 -0
  170. package/dist/esm/fields/Geolocation/geocoder.mjs.map +1 -0
  171. package/dist/esm/fields/Geolocation/geocoder.native.js +35 -0
  172. package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -0
  173. package/dist/esm/fields/Geolocation/index.mjs +792 -149
  174. package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
  175. package/dist/esm/fields/Geolocation/index.native.js +847 -164
  176. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  177. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  178. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  179. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js +19 -0
  180. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  181. package/dist/esm/fields/Icon/drawnSet.mjs +16 -3
  182. package/dist/esm/fields/Icon/drawnSet.mjs.map +1 -1
  183. package/dist/esm/fields/Icon/drawnSet.native.js +20 -3
  184. package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
  185. package/dist/esm/fields/Icon/index.mjs +93 -18
  186. package/dist/esm/fields/Icon/index.mjs.map +1 -1
  187. package/dist/esm/fields/Icon/index.native.js +106 -22
  188. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  189. package/dist/esm/fields/Input/index.mjs +5 -12
  190. package/dist/esm/fields/Input/index.mjs.map +1 -1
  191. package/dist/esm/fields/Input/index.native.js +5 -13
  192. package/dist/esm/fields/Input/index.native.js.map +1 -1
  193. package/dist/esm/fields/PhoneInput/index.mjs +2 -2
  194. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  195. package/dist/esm/fields/PhoneInput/index.native.js +2 -2
  196. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  197. package/dist/esm/fields/RadioGroup/index.mjs +34 -5
  198. package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
  199. package/dist/esm/fields/RadioGroup/index.native.js +49 -7
  200. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  201. package/dist/esm/fields/SearchInput/index.mjs +9 -10
  202. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  203. package/dist/esm/fields/SearchInput/index.native.js +9 -10
  204. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  205. package/dist/esm/fields/Select/index.mjs +42 -11
  206. package/dist/esm/fields/Select/index.mjs.map +1 -1
  207. package/dist/esm/fields/Select/index.native.js +52 -20
  208. package/dist/esm/fields/Select/index.native.js.map +1 -1
  209. package/dist/esm/fields/Stepper/index.mjs +145 -32
  210. package/dist/esm/fields/Stepper/index.mjs.map +1 -1
  211. package/dist/esm/fields/Stepper/index.native.js +152 -32
  212. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  213. package/dist/esm/fields/ToggleGroup/index.mjs +35 -2
  214. package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
  215. package/dist/esm/fields/ToggleGroup/index.native.js +42 -2
  216. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  217. package/dist/esm/index.mjs +2 -1
  218. package/dist/esm/index.mjs.map +1 -1
  219. package/dist/esm/index.native.js +2 -1
  220. package/dist/esm/index.native.js.map +1 -1
  221. package/dist/esm/shared/focusManagement.mjs +24 -11
  222. package/dist/esm/shared/focusManagement.mjs.map +1 -1
  223. package/dist/esm/shared/focusManagement.native.js +24 -11
  224. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  225. package/dist/esm/shared/nativeA11y.mjs +31 -0
  226. package/dist/esm/shared/nativeA11y.mjs.map +1 -0
  227. package/dist/esm/shared/nativeA11y.native.js +32 -0
  228. package/dist/esm/shared/nativeA11y.native.js.map +1 -0
  229. package/dist/jsx/Button/index.mjs +1 -4
  230. package/dist/jsx/Button/index.mjs.map +1 -1
  231. package/dist/jsx/Button/index.native.js +5 -6
  232. package/dist/jsx/Button/index.native.js.map +1 -1
  233. package/dist/jsx/Chip/index.mjs +1 -1
  234. package/dist/jsx/Chip/index.mjs.map +1 -1
  235. package/dist/jsx/Chip/index.native.js +1 -1
  236. package/dist/jsx/Chip/index.native.js.map +1 -1
  237. package/dist/jsx/FloatingPanel/index.mjs +58 -15
  238. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  239. package/dist/jsx/FloatingPanel/index.native.js +16 -7
  240. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  241. package/dist/jsx/FloatingPanel/nestedAction.mjs +11 -0
  242. package/dist/jsx/FloatingPanel/nestedAction.mjs.map +1 -0
  243. package/dist/jsx/FloatingPanel/nestedAction.native.js +42 -0
  244. package/dist/jsx/FloatingPanel/nestedAction.native.js.map +1 -0
  245. package/dist/jsx/InputParts/index.mjs +20 -9
  246. package/dist/jsx/InputParts/index.mjs.map +1 -1
  247. package/dist/jsx/InputParts/index.native.js +20 -11
  248. package/dist/jsx/InputParts/index.native.js.map +1 -1
  249. package/dist/jsx/Wheel/index.mjs +3 -3
  250. package/dist/jsx/Wheel/index.mjs.map +1 -1
  251. package/dist/jsx/Wheel/index.native.js +3 -3
  252. package/dist/jsx/Wheel/index.native.js.map +1 -1
  253. package/dist/jsx/fieldLayout.mjs +3 -3
  254. package/dist/jsx/fieldLayout.mjs.map +1 -1
  255. package/dist/jsx/fieldLayout.native.js +3 -3
  256. package/dist/jsx/fieldLayout.native.js.map +1 -1
  257. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  258. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  259. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  260. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  261. package/dist/jsx/fields/Combobox/index.mjs +36 -29
  262. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  263. package/dist/jsx/fields/Combobox/index.native.js +38 -38
  264. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  265. package/dist/jsx/fields/DatePicker/Calendar.mjs +6 -1
  266. package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
  267. package/dist/jsx/fields/DatePicker/Calendar.native.js +6 -1
  268. package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
  269. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +2 -2
  270. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  271. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +2 -2
  272. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  273. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  274. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  275. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  276. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  277. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +39 -14
  278. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  279. package/dist/jsx/fields/DatePicker/MonthPicker.mjs +10 -3
  280. package/dist/jsx/fields/DatePicker/MonthPicker.mjs.map +1 -1
  281. package/dist/jsx/fields/DatePicker/MonthPicker.native.js +10 -3
  282. package/dist/jsx/fields/DatePicker/MonthPicker.native.js.map +1 -1
  283. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +2 -2
  284. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  285. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +2 -2
  286. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  287. package/dist/jsx/fields/DatePicker/index.native.js +3 -0
  288. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  289. package/dist/jsx/fields/DatePicker/parts.mjs +28 -16
  290. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  291. package/dist/jsx/fields/DatePicker/parts.native.js +28 -14
  292. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  293. package/dist/jsx/fields/FileUpload/index.mjs +6 -0
  294. package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
  295. package/dist/jsx/fields/FileUpload/index.native.js +6 -0
  296. package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
  297. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  298. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  299. package/dist/jsx/fields/Geolocation/geocoder.mjs +33 -0
  300. package/dist/jsx/fields/Geolocation/geocoder.mjs.map +1 -0
  301. package/dist/jsx/fields/Geolocation/geocoder.native.js +68 -0
  302. package/dist/jsx/fields/Geolocation/geocoder.native.js.map +1 -0
  303. package/dist/jsx/fields/Geolocation/index.mjs +792 -149
  304. package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
  305. package/dist/jsx/fields/Geolocation/index.native.js +856 -167
  306. package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
  307. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  308. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  309. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  310. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  311. package/dist/jsx/fields/Icon/drawnSet.mjs +16 -3
  312. package/dist/jsx/fields/Icon/drawnSet.mjs.map +1 -1
  313. package/dist/jsx/fields/Icon/drawnSet.native.js +20 -3
  314. package/dist/jsx/fields/Icon/drawnSet.native.js.map +1 -1
  315. package/dist/jsx/fields/Icon/index.mjs +93 -18
  316. package/dist/jsx/fields/Icon/index.mjs.map +1 -1
  317. package/dist/jsx/fields/Icon/index.native.js +115 -31
  318. package/dist/jsx/fields/Icon/index.native.js.map +1 -1
  319. package/dist/jsx/fields/Input/index.mjs +5 -12
  320. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  321. package/dist/jsx/fields/Input/index.native.js +5 -13
  322. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  323. package/dist/jsx/fields/PhoneInput/index.mjs +2 -2
  324. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  325. package/dist/jsx/fields/PhoneInput/index.native.js +2 -2
  326. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  327. package/dist/jsx/fields/RadioGroup/index.mjs +34 -5
  328. package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
  329. package/dist/jsx/fields/RadioGroup/index.native.js +49 -7
  330. package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
  331. package/dist/jsx/fields/SearchInput/index.mjs +9 -10
  332. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  333. package/dist/jsx/fields/SearchInput/index.native.js +8 -9
  334. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  335. package/dist/jsx/fields/Select/index.mjs +42 -11
  336. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  337. package/dist/jsx/fields/Select/index.native.js +52 -20
  338. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  339. package/dist/jsx/fields/Stepper/index.mjs +145 -32
  340. package/dist/jsx/fields/Stepper/index.mjs.map +1 -1
  341. package/dist/jsx/fields/Stepper/index.native.js +151 -31
  342. package/dist/jsx/fields/Stepper/index.native.js.map +1 -1
  343. package/dist/jsx/fields/ToggleGroup/index.mjs +35 -2
  344. package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
  345. package/dist/jsx/fields/ToggleGroup/index.native.js +42 -2
  346. package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
  347. package/dist/jsx/index.js +2 -1
  348. package/dist/jsx/index.js.map +1 -1
  349. package/dist/jsx/index.mjs +2 -1
  350. package/dist/jsx/index.mjs.map +1 -1
  351. package/dist/jsx/index.native.js +2 -0
  352. package/dist/jsx/index.native.js.map +1 -1
  353. package/dist/jsx/shared/focusManagement.mjs +24 -11
  354. package/dist/jsx/shared/focusManagement.mjs.map +1 -1
  355. package/dist/jsx/shared/focusManagement.native.js +24 -11
  356. package/dist/jsx/shared/focusManagement.native.js.map +1 -1
  357. package/dist/jsx/shared/nativeA11y.mjs +31 -0
  358. package/dist/jsx/shared/nativeA11y.mjs.map +1 -0
  359. package/dist/jsx/shared/nativeA11y.native.js +61 -0
  360. package/dist/jsx/shared/nativeA11y.native.js.map +1 -0
  361. package/package.json +9 -7
  362. package/src/Button/Button.fontWeight.spec.tsx +75 -0
  363. package/src/Button/Button.labelInk.spec.tsx +21 -18
  364. package/src/Button/Button.outlinedChannel.spec.tsx +46 -0
  365. package/src/Button/Button.sizeLadder.spec.tsx +4 -3
  366. package/src/Button/Button.stories.tsx +20 -0
  367. package/src/Button/index.tsx +30 -7
  368. package/src/Chip/Chip.spec.tsx +3 -1
  369. package/src/Chip/index.tsx +1 -5
  370. package/src/FieldGroup.stories.tsx +3 -7
  371. package/src/FieldLayout.stories.tsx +75 -12
  372. package/src/Fieldset.stories.tsx +3 -7
  373. package/src/FloatingPanel/FloatingPanel.native.spec.tsx +54 -0
  374. package/src/FloatingPanel/FloatingPanel.spec.tsx +109 -0
  375. package/src/FloatingPanel/index.native.tsx +24 -7
  376. package/src/FloatingPanel/index.tsx +80 -13
  377. package/src/FloatingPanel/nestedAction.spec.ts +36 -0
  378. package/src/FloatingPanel/nestedAction.ts +15 -0
  379. package/src/FloatingPanel/panelWidthContract.spec.ts +12 -15
  380. package/src/FormGrid.stories.tsx +5 -11
  381. package/src/FormsIntegration.stories.tsx +2 -6
  382. package/src/InputParts/InputButton.spec.tsx +16 -0
  383. package/src/InputParts/index.tsx +34 -7
  384. package/src/InputParts/layoutGap.spec.tsx +43 -0
  385. package/src/Wheel/Wheel.spec.tsx +16 -0
  386. package/src/Wheel/index.tsx +3 -3
  387. package/src/fieldFamilyStories.radius.spec.tsx +118 -0
  388. package/src/fieldLayout.spec.tsx +42 -1
  389. package/src/fieldLayout.tsx +9 -9
  390. package/src/fields/Barcode/Barcode.spec.tsx +2 -0
  391. package/src/fields/Checkbox/CheckboxFieldFrame.spec.tsx +18 -0
  392. package/src/fields/Checkbox/CheckboxFieldFrame.tsx +6 -1
  393. package/src/fields/Combobox/Combobox.spec.tsx +48 -1
  394. package/src/fields/Combobox/index.tsx +53 -39
  395. package/src/fields/DatePicker/Calendar.tsx +4 -1
  396. package/src/fields/DatePicker/DatePicker.stories.tsx +22 -1
  397. package/src/fields/DatePicker/DateRangePicker.tsx +4 -2
  398. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +21 -19
  399. package/src/fields/DatePicker/DatetimePicker.native.spec.tsx +144 -0
  400. package/src/fields/DatePicker/DatetimePicker.native.tsx +57 -32
  401. package/src/fields/DatePicker/DatetimePicker.stories.tsx +22 -0
  402. package/src/fields/DatePicker/MonthPicker.tsx +8 -3
  403. package/src/fields/DatePicker/MultiDatePicker.tsx +4 -2
  404. package/src/fields/DatePicker/index.native.tsx +1 -0
  405. package/src/fields/DatePicker/parts.spec.tsx +56 -0
  406. package/src/fields/DatePicker/parts.tsx +33 -12
  407. package/src/fields/FileUpload/FileUpload.spec.tsx +29 -0
  408. package/src/fields/FileUpload/index.tsx +6 -0
  409. package/src/fields/Geolocation/Geolocation.spec.tsx +287 -35
  410. package/src/fields/Geolocation/Geolocation.stories.tsx +141 -7
  411. package/src/fields/Geolocation/GeolocationMap.native.tsx +3 -0
  412. package/src/fields/Geolocation/GeolocationMap.tsx +4 -0
  413. package/src/fields/Geolocation/geocoder.spec.ts +59 -0
  414. package/src/fields/Geolocation/geocoder.ts +84 -0
  415. package/src/fields/Geolocation/geocoderSeam.spec.tsx +203 -0
  416. package/src/fields/Geolocation/index.tsx +912 -180
  417. package/src/fields/Geolocation/nativeSearchFocus.spec.ts +34 -0
  418. package/src/fields/Geolocation/nativeSearchFocus.ts +19 -0
  419. package/src/fields/Geolocation/salvage.spec.tsx +398 -0
  420. package/src/fields/Geolocation/storyProviders.spec.tsx +44 -0
  421. package/src/fields/Icon/Icon.spec.tsx +215 -1
  422. package/src/fields/Icon/Icon.stories.tsx +9 -1
  423. package/src/fields/Icon/drawnSet.tsx +44 -4
  424. package/src/fields/Icon/index.tsx +118 -18
  425. package/src/fields/Input/Input.copy.spec.tsx +1 -0
  426. package/src/fields/Input/Input.spec.tsx +50 -0
  427. package/src/fields/Input/Input.stories.tsx +1 -1
  428. package/src/fields/Input/index.tsx +7 -13
  429. package/src/fields/PhoneInput/index.tsx +2 -2
  430. package/src/fields/RadioGroup/RadioGroup.native.spec.tsx +67 -0
  431. package/src/fields/RadioGroup/index.tsx +82 -8
  432. package/src/fields/SearchInput/SearchInput.spec.tsx +14 -0
  433. package/src/fields/SearchInput/index.tsx +5 -6
  434. package/src/fields/Select/Select.spec.tsx +54 -0
  435. package/src/fields/Select/index.tsx +52 -17
  436. package/src/fields/Stepper/Stepper.spec.tsx +34 -1
  437. package/src/fields/Stepper/index.tsx +193 -33
  438. package/src/fields/ToggleGroup/ToggleGroup.native.spec.tsx +73 -0
  439. package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +49 -0
  440. package/src/fields/ToggleGroup/index.tsx +76 -1
  441. package/src/index.ts +9 -0
  442. package/src/shared/focusManagement.spec.tsx +68 -0
  443. package/src/shared/focusManagement.ts +20 -10
  444. package/src/shared/nativeA11y.spec.ts +64 -0
  445. package/src/shared/nativeA11y.ts +80 -0
  446. package/types/Button/index.d.ts +22 -3
  447. package/types/Button/index.d.ts.map +1 -1
  448. package/types/Chip/index.d.ts.map +1 -1
  449. package/types/FloatingPanel/index.d.ts +11 -1
  450. package/types/FloatingPanel/index.d.ts.map +1 -1
  451. package/types/FloatingPanel/index.native.d.ts +2 -1
  452. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  453. package/types/FloatingPanel/nestedAction.d.ts +13 -0
  454. package/types/FloatingPanel/nestedAction.d.ts.map +1 -0
  455. package/types/InputParts/index.d.ts.map +1 -1
  456. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts +46 -2
  457. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts.map +1 -1
  458. package/types/fields/Checkbox/index.d.ts +3 -3
  459. package/types/fields/Combobox/index.d.ts +3 -1
  460. package/types/fields/Combobox/index.d.ts.map +1 -1
  461. package/types/fields/DatePicker/Calendar.d.ts.map +1 -1
  462. package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
  463. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
  464. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
  465. package/types/fields/DatePicker/MonthPicker.d.ts.map +1 -1
  466. package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
  467. package/types/fields/DatePicker/index.native.d.ts.map +1 -1
  468. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  469. package/types/fields/FileUpload/index.d.ts.map +1 -1
  470. package/types/fields/Geolocation/GeolocationMap.d.ts +4 -0
  471. package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
  472. package/types/fields/Geolocation/GeolocationMap.native.d.ts +3 -0
  473. package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
  474. package/types/fields/Geolocation/geocoder.d.ts +53 -0
  475. package/types/fields/Geolocation/geocoder.d.ts.map +1 -0
  476. package/types/fields/Geolocation/index.d.ts +18 -2
  477. package/types/fields/Geolocation/index.d.ts.map +1 -1
  478. package/types/fields/Geolocation/nativeSearchFocus.d.ts +8 -0
  479. package/types/fields/Geolocation/nativeSearchFocus.d.ts.map +1 -0
  480. package/types/fields/Icon/drawnSet.d.ts.map +1 -1
  481. package/types/fields/Icon/index.d.ts.map +1 -1
  482. package/types/fields/Input/index.d.ts.map +1 -1
  483. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  484. package/types/fields/RadioGroup/index.d.ts +30 -3
  485. package/types/fields/RadioGroup/index.d.ts.map +1 -1
  486. package/types/fields/SearchInput/index.d.ts.map +1 -1
  487. package/types/fields/Select/index.d.ts.map +1 -1
  488. package/types/fields/Stepper/index.d.ts.map +1 -1
  489. package/types/fields/ToggleGroup/index.d.ts +31 -2
  490. package/types/fields/ToggleGroup/index.d.ts.map +1 -1
  491. package/types/index.d.ts +2 -0
  492. package/types/index.d.ts.map +1 -1
  493. package/types/shared/focusManagement.d.ts +2 -2
  494. package/types/shared/focusManagement.d.ts.map +1 -1
  495. package/types/shared/nativeA11y.d.ts +61 -0
  496. package/types/shared/nativeA11y.d.ts.map +1 -0
  497. package/src/router.d.ts +0 -16
@@ -1,10 +1,36 @@
1
1
  import { action } from "@multiplatform.one/storybook";
2
2
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
3
3
  import { useForm } from "@tanstack/react-form";
4
- import { Input as TamaguiInput, Paragraph, YStack, XStack } from "tamagui";
4
+ import { useState } from "react";
5
+ import { Preset } from "@multiplatform.one/theme";
6
+ import { Paragraph, YStack, XStack } from "tamagui";
5
7
  import { Button } from "./Button";
6
8
  import { Form } from "./Form";
7
9
  import { Field, FieldLayout } from "./fieldLayout";
10
+ import { Input } from "./fields/Input";
11
+ import { Input as InputParts } from "./InputParts";
12
+ import { Checkbox } from "./fields/Checkbox";
13
+
14
+ /**
15
+ * FieldLayout wraps a CONTROL, so these stories cannot mount the house `Input`
16
+ * field — it brings its own FieldLayout. `InputParts.Box` is the house chrome
17
+ * underneath that field, and it is the part that consumes the knobs.
18
+ */
19
+ function Control(props: {
20
+ id?: string;
21
+ placeholder?: string;
22
+ value?: string;
23
+ onChangeText?: (text: string) => void;
24
+ secureTextEntry?: boolean;
25
+ }) {
26
+ return (
27
+ <InputParts>
28
+ <InputParts.Box>
29
+ <InputParts.Area {...props} />
30
+ </InputParts.Box>
31
+ </InputParts>
32
+ );
33
+ }
8
34
 
9
35
  const meta: Meta<typeof FieldLayout> = {
10
36
  title: "Forms/FieldLayout",
@@ -33,12 +59,49 @@ export const Basic: Story = {
33
59
  render: (args) => (
34
60
  <YStack maxWidth={360}>
35
61
  <FieldLayout {...args}>
36
- <TamaguiInput id={args.id} placeholder="you@example.com" />
62
+ <Control id={args.id} placeholder="you@example.com" />
37
63
  </FieldLayout>
38
64
  </YStack>
39
65
  ),
40
66
  };
41
67
 
68
+ /** Shared message order with real controls, including the inline checkbox row. */
69
+ export const MessageOrder: Story = {
70
+ render: () => {
71
+ const Example = () => {
72
+ const [showErrors, setShowErrors] = useState(false);
73
+ return (
74
+ <YStack gap="$4" width="100%" maxWidth={480}>
75
+ <Input
76
+ id="message-top"
77
+ label="Contact"
78
+ helperText="Use an address where we can reach you"
79
+ error={showErrors ? "Enter a contact address" : undefined}
80
+ />
81
+ <Preset overrides={{ fieldLabelPlacement: "side" }}>
82
+ <Input
83
+ id="message-side"
84
+ label="Office"
85
+ helperText="Use the office name shown on your account"
86
+ error={showErrors ? "Enter your office name" : undefined}
87
+ />
88
+ </Preset>
89
+ <Checkbox
90
+ id="message-inline"
91
+ label="Accept terms"
92
+ helperText="Read the terms before continuing"
93
+ error={showErrors ? "Accept the terms to continue" : undefined}
94
+ />
95
+ <Button onPress={() => setShowErrors((shown) => !shown)}>
96
+ {showErrors ? "Show helpers" : "Show validation"}
97
+ </Button>
98
+ </YStack>
99
+ );
100
+ };
101
+ return <Example />;
102
+ },
103
+ };
104
+
42
105
  export const ErrorStates: Story = {
43
106
  render: () => (
44
107
  <YStack gap="$6" maxWidth={360}>
@@ -49,7 +112,7 @@ export const ErrorStates: Story = {
49
112
  // DG-COPY-02: error copy states the rule broken — never "invalid"/"please"/"error".
50
113
  error="Value must use letters only"
51
114
  >
52
- <TamaguiInput id="fl-err-string" />
115
+ <Control id="fl-err-string" />
53
116
  </FieldLayout>
54
117
  <FieldLayout
55
118
  id="fl-err-bool"
@@ -57,7 +120,7 @@ export const ErrorStates: Story = {
57
120
  helperText="Helper should remain visible"
58
121
  error={true}
59
122
  >
60
- <TamaguiInput id="fl-err-bool" />
123
+ <Control id="fl-err-bool" />
61
124
  </FieldLayout>
62
125
  <FieldLayout
63
126
  id="fl-err-empty"
@@ -65,7 +128,7 @@ export const ErrorStates: Story = {
65
128
  helperText="Empty string should act as no message"
66
129
  error=""
67
130
  >
68
- <TamaguiInput id="fl-err-empty" />
131
+ <Control id="fl-err-empty" />
69
132
  </FieldLayout>
70
133
  </YStack>
71
134
  ),
@@ -75,13 +138,13 @@ export const AnatomyEdgeCases: Story = {
75
138
  render: () => (
76
139
  <YStack gap="$6" maxWidth={360}>
77
140
  <FieldLayout id="fl-required" label="Required field" required>
78
- <TamaguiInput id="fl-required" />
141
+ <Control id="fl-required" />
79
142
  </FieldLayout>
80
143
  <FieldLayout id="fl-nolabel" helperText="No label means compact $1 gap">
81
- <TamaguiInput id="fl-nolabel" />
144
+ <Control id="fl-nolabel" />
82
145
  </FieldLayout>
83
146
  <FieldLayout id="fl-compact" label="Compact spacing" compactSpacing helperText="Compact gap">
84
- <TamaguiInput id="fl-compact" />
147
+ <Control id="fl-compact" />
85
148
  </FieldLayout>
86
149
  <FieldLayout
87
150
  id="fl-node-label"
@@ -92,14 +155,14 @@ export const AnatomyEdgeCases: Story = {
92
155
  </XStack>
93
156
  }
94
157
  >
95
- <TamaguiInput id="fl-node-label" />
158
+ <Control id="fl-node-label" />
96
159
  </FieldLayout>
97
160
  <FieldLayout
98
161
  id="fl-long"
99
162
  label="Long messages"
100
163
  error="This validation message is extremely long and keeps going to make sure long validation copy wraps correctly under the control without pushing the layout sideways or clipping any of its content at narrow widths"
101
164
  >
102
- <TamaguiInput id="fl-long" />
165
+ <Control id="fl-long" />
103
166
  </FieldLayout>
104
167
  </YStack>
105
168
  ),
@@ -125,7 +188,7 @@ export const FieldWrapper: Story = {
125
188
  helperText="TanStack Field wrapper"
126
189
  field={field as any}
127
190
  >
128
- <TamaguiInput
191
+ <Control
129
192
  id="field-username"
130
193
  value={String(field.state.value ?? "")}
131
194
  onChangeText={(text) => field.handleChange(text)}
@@ -167,7 +230,7 @@ export const FieldRequiredValidator: Story = {
167
230
  >
168
231
  {(field) => (
169
232
  <FieldLayout id="field-nickname" label="Nickname" required field={field as any}>
170
- <TamaguiInput
233
+ <Control
171
234
  id="field-nickname"
172
235
  value={String(field.state.value ?? "")}
173
236
  onChangeText={(text) => field.handleChange(text)}
@@ -1,14 +1,10 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
2
- import { Input as TamaguiInput, YStack } from "tamagui";
3
- import { FieldLayout } from "./fieldLayout";
2
+ import { YStack } from "tamagui";
4
3
  import { Fieldset, FormSectionStack } from "./FormSection";
4
+ import { Input } from "./fields/Input";
5
5
 
6
6
  function Field({ id, label, ...rest }: { id: string; label: string; secureTextEntry?: boolean }) {
7
- return (
8
- <FieldLayout id={id} label={label}>
9
- <TamaguiInput id={id} placeholder={label} {...rest} />
10
- </FieldLayout>
11
- );
7
+ return <Input id={id} label={label} placeholder={label} {...rest} />;
12
8
  }
13
9
 
14
10
  const meta: Meta<typeof Fieldset> = {
@@ -57,6 +57,60 @@ function panel(open: boolean) {
57
57
  }
58
58
 
59
59
  describe("FloatingPanel native presentation lifecycle", () => {
60
+ it("keeps full-field triggers stretched and allows content-sized composite adornments", () => {
61
+ for (const triggerSizing of [undefined, "content"] as const) {
62
+ const result = renderWithProviders(
63
+ <FloatingPanel
64
+ open={false}
65
+ onOpenChange={onOpenChange}
66
+ trigger={<Text>Country</Text>}
67
+ triggerSizing={triggerSizing}
68
+ triggerA11y={{ label: "Country code" }}
69
+ >
70
+ <Text>row</Text>
71
+ </FloatingPanel>,
72
+ );
73
+ const trigger = result.getByRole("button", { name: "Country code" });
74
+ expect(getComputedStyle(trigger).width).toBe(triggerSizing === "content" ? "" : "100%");
75
+ expect(getComputedStyle(trigger).alignSelf).toBe("stretch");
76
+ expect(getComputedStyle(trigger.parentElement!).width).toBe(
77
+ triggerSizing === "content" ? "" : "100%",
78
+ );
79
+ result.unmount();
80
+ }
81
+ });
82
+
83
+ it("composes native readiness with entrance and ignores late closed or unmounted events", () => {
84
+ const onNativeShow = vi.fn();
85
+ const example = (open: boolean) => (
86
+ <FloatingPanel
87
+ open={open}
88
+ onOpenChange={onOpenChange}
89
+ onNativeShow={onNativeShow}
90
+ trigger={<Text>Pick</Text>}
91
+ >
92
+ <Text>row</Text>
93
+ </FloatingPanel>
94
+ );
95
+ const result = renderWithProviders(example(true));
96
+ expect(Animated.timing).toHaveBeenCalledTimes(1);
97
+ expect(onNativeShow).not.toHaveBeenCalled();
98
+ const shown = modal.onShow;
99
+ act(() => shown?.());
100
+ expect(onNativeShow).toHaveBeenCalledTimes(1);
101
+ expect(Animated.timing).toHaveBeenCalledTimes(1);
102
+ result.rerender(example(false));
103
+ act(() => shown?.());
104
+ expect(onNativeShow).toHaveBeenCalledTimes(1);
105
+ result.rerender(example(true));
106
+ const nextShown = modal.onShow;
107
+ act(() => nextShown?.());
108
+ expect(onNativeShow).toHaveBeenCalledTimes(2);
109
+ result.unmount();
110
+ act(() => nextShown?.());
111
+ expect(onNativeShow).toHaveBeenCalledTimes(2);
112
+ });
113
+
60
114
  it("enters without onShow and ignores onShow for the same presentation", () => {
61
115
  renderWithProviders(panel(true));
62
116
  expect(Animated.timing).toHaveBeenCalledTimes(1);
@@ -40,12 +40,16 @@ function Harness({
40
40
  sheet,
41
41
  onOpenChange,
42
42
  extra,
43
+ openOn,
44
+ sizing,
43
45
  }: {
44
46
  trigger: ReactNode;
45
47
  disabled?: boolean;
46
48
  sheet?: boolean;
47
49
  onOpenChange?: (open: boolean) => void;
48
50
  extra?: ReactNode;
51
+ openOn?: "press" | "contextmenu";
52
+ sizing?: "grow" | "fill";
49
53
  }) {
50
54
  const [open, setOpen] = useState(false);
51
55
  return (
@@ -64,6 +68,8 @@ function Harness({
64
68
  trigger={trigger}
65
69
  disabled={disabled}
66
70
  sheet={sheet}
71
+ openOn={openOn}
72
+ sizing={sizing}
67
73
  >
68
74
  <Text>panel body</Text>
69
75
  {extra}
@@ -79,6 +85,75 @@ const isOpen = (result: { container: HTMLElement }) =>
79
85
 
80
86
  const floatingViewport = () => document.querySelector('[data-testid="floating-panel-viewport"]');
81
87
 
88
+ describe("FloatingPanel nested actions", () => {
89
+ it("does not require a marked DOM button to stop propagation", () => {
90
+ const action = vi.fn();
91
+ const onOpenChange = vi.fn();
92
+ const result = renderWithProviders(
93
+ <Harness
94
+ onOpenChange={onOpenChange}
95
+ trigger={
96
+ <button type="button" data-floating-panel-action="true" onClick={action}>
97
+ Clear selection
98
+ </button>
99
+ }
100
+ />,
101
+ );
102
+ fireEvent.click(result.getByRole("button", { name: "Clear selection" }), { detail: 0 });
103
+ expect(action).toHaveBeenCalledOnce();
104
+ expect(onOpenChange).not.toHaveBeenCalled();
105
+ });
106
+
107
+ for (const sheet of [true, false]) {
108
+ for (const activation of ["pointer", "keyboard"] as const) {
109
+ it(`lets a marked ${activation} action run without opening ${sheet ? "sheet" : "float"}`, () => {
110
+ const action = vi.fn();
111
+ const onOpenChange = vi.fn();
112
+ const result = renderWithProviders(
113
+ <Harness
114
+ sheet={sheet}
115
+ onOpenChange={onOpenChange}
116
+ trigger={
117
+ <Button
118
+ data-floating-panel-action="true"
119
+ onPress={(event) => {
120
+ event.stopPropagation();
121
+ action();
122
+ }}
123
+ >
124
+ Clear selection
125
+ </Button>
126
+ }
127
+ />,
128
+ );
129
+ const button = result.getByRole("button", { name: "Clear selection" });
130
+ if (activation === "pointer") pointerPress(button);
131
+ else {
132
+ fireEvent.keyDown(button, { key: "Enter" });
133
+ fireEvent.keyUp(button, { key: "Enter" });
134
+ }
135
+ expect(action).toHaveBeenCalledOnce();
136
+ expect(onOpenChange).not.toHaveBeenCalled();
137
+ expect(isOpen(result)).toBe(false);
138
+ });
139
+ }
140
+
141
+ it(`preserves context-menu opening from a marked action in ${sheet ? "sheet" : "float"}`, () => {
142
+ const onOpenChange = vi.fn();
143
+ const result = renderWithProviders(
144
+ <Harness
145
+ sheet={sheet}
146
+ openOn="contextmenu"
147
+ onOpenChange={onOpenChange}
148
+ trigger={<Button data-floating-panel-action="true">Context action</Button>}
149
+ />,
150
+ );
151
+ fireEvent.contextMenu(result.getByRole("button", { name: "Context action" }));
152
+ expect(onOpenChange).toHaveBeenCalledWith(true);
153
+ });
154
+ }
155
+ });
156
+
82
157
  /** The DEEPEST node carrying the whole label — several ancestors report the
83
158
  * same `textContent`, and pressing one of those would sidestep the very
84
159
  * swallow these cases exist to catch. */
@@ -260,4 +335,38 @@ describe("FloatingPanel trigger — floating mode", () => {
260
335
  expect(document.activeElement).toBe(trigger);
261
336
  });
262
337
  });
338
+
339
+ it("disconnects fill content observation on close and unmount", async () => {
340
+ const observers: { target: Element; disconnected: boolean }[] = [];
341
+ class TrackingResizeObserver {
342
+ private tracked?: { target: Element; disconnected: boolean };
343
+ observe(target: Element) {
344
+ if (target.parentElement?.getAttribute("data-testid") !== "floating-panel-viewport") return;
345
+ this.tracked = { target, disconnected: false };
346
+ observers.push(this.tracked);
347
+ }
348
+ unobserve() {}
349
+ disconnect() {
350
+ if (this.tracked) this.tracked.disconnected = true;
351
+ }
352
+ }
353
+ vi.stubGlobal("ResizeObserver", TrackingResizeObserver);
354
+ const result = renderWithProviders(
355
+ <Harness sizing="fill" trigger={<Button>Open Panel</Button>} />,
356
+ );
357
+ try {
358
+ const trigger = result.container.querySelector("[role='button']") as HTMLElement;
359
+ pointerPress(trigger);
360
+ await waitFor(() => expect(observers.some((observer) => !observer.disconnected)).toBe(true));
361
+ fireEvent.keyDown(document, { key: "Escape" });
362
+ await waitFor(() => expect(observers.every((observer) => observer.disconnected)).toBe(true));
363
+ pointerPress(trigger);
364
+ await waitFor(() => expect(observers.some((observer) => !observer.disconnected)).toBe(true));
365
+ result.unmount();
366
+ expect(observers.every((observer) => observer.disconnected)).toBe(true);
367
+ } finally {
368
+ result.unmount();
369
+ vi.unstubAllGlobals();
370
+ }
371
+ });
263
372
  });
@@ -76,6 +76,7 @@ export {
76
76
  } from "./useFloatingPanel";
77
77
  export type { UseFloatingPanelOptions, UseFloatingPanelReturn } from "./useFloatingPanel";
78
78
  export type { FloatingPanelProps } from "./index";
79
+ export { floatingPanelActionProps, isNestedPanelAction } from "./nestedAction";
79
80
 
80
81
  /** Native never has a >sm web viewport; AdaptivePopup uses this to pick Sheet mode. */
81
82
  export function useViewportGtSm() {
@@ -103,8 +104,10 @@ const enterDuration = 280;
103
104
  export function FloatingPanel({
104
105
  open,
105
106
  onOpenChange,
107
+ onNativeShow,
106
108
  trigger,
107
109
  triggerEnd,
110
+ triggerSizing = "stretch",
108
111
  children,
109
112
  scrollable,
110
113
  disabled,
@@ -355,7 +358,13 @@ export function FloatingPanel({
355
358
 
356
359
  return (
357
360
  <>
358
- <RNView style={{ flexDirection: "row", alignItems: "center", width: "100%" }}>
361
+ <RNView
362
+ style={{
363
+ flexDirection: "row",
364
+ alignItems: "center",
365
+ width: triggerSizing === "content" ? undefined : "100%",
366
+ }}
367
+ >
359
368
  <Pressable
360
369
  {...(isContextMenu
361
370
  ? { onLongPress: handleTriggerLongPress, delayLongPress: 500 }
@@ -368,18 +377,22 @@ export function FloatingPanel({
368
377
  ? { accessibilityValue: { text: triggerA11y.value } }
369
378
  : undefined)}
370
379
  {...(triggerA11y?.hint ? { accessibilityHint: triggerA11y.hint } : undefined)}
371
- // Stretch to the cell/row width — content-sized triggers (~70pt) make
372
- // most of the edit box look tappable but miss the Pressable.
380
+ // Whole-field triggers stretch; composite adornments hug their
381
+ // content so sibling inputs retain their editable space.
373
382
  style={{
374
- flex: 1,
383
+ flex: triggerSizing === "content" ? undefined : 1,
375
384
  minWidth: 0,
376
385
  alignSelf: "stretch",
377
- width: "100%",
386
+ width: triggerSizing === "content" ? undefined : "100%",
378
387
  opacity: disabled ? 0.5 : 1,
379
388
  }}
380
389
  >
381
390
  {/* Own the hit target — see file header for why pointerEvents="none". */}
382
- <RNView pointerEvents="none" collapsable={false} style={{ width: "100%" }}>
391
+ <RNView
392
+ pointerEvents="none"
393
+ collapsable={false}
394
+ style={{ width: triggerSizing === "content" ? undefined : "100%" }}
395
+ >
383
396
  {trigger}
384
397
  </RNView>
385
398
  </Pressable>
@@ -391,7 +404,11 @@ export function FloatingPanel({
391
404
  animationType="fade"
392
405
  statusBarTranslucent
393
406
  onRequestClose={close}
394
- onShow={enter}
407
+ onShow={() => {
408
+ if (!activeRef.current) return;
409
+ enter();
410
+ onNativeShow?.();
411
+ }}
395
412
  >
396
413
  {/*
397
414
  A plain padded column, not KeyboardAvoidingView: inside a Modal the
@@ -1,4 +1,4 @@
1
- import type { ReactNode, UIEvent } from "react";
1
+ import type { ReactNode, RefObject, UIEvent } from "react";
2
2
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
3
3
  import {
4
4
  OVERLAY_ATTACH_GAP,
@@ -15,6 +15,9 @@ import { useSheetEscapeDismiss } from "../shared/useSheetEscapeDismiss";
15
15
  import { useFloatingPanel, panelTransition, panelViewportPadding } from "./useFloatingPanel";
16
16
  import type { PanelWidthMode } from "./useFloatingPanel";
17
17
  import { zIndex } from "../shared/zIndex";
18
+ import { isNestedPanelAction, type PanelActionEvent } from "./nestedAction";
19
+
20
+ export { floatingPanelActionProps, isNestedPanelAction } from "./nestedAction";
18
21
 
19
22
  // Re-export hook for Select / Combobox / external consumers
20
23
  export {
@@ -37,6 +40,10 @@ export type {
37
40
  export interface FloatingPanelProps {
38
41
  open: boolean;
39
42
  onOpenChange: (open: boolean) => void;
43
+ /** Native only: the modal is presented and its inputs can receive focus. */
44
+ onNativeShow?: () => void;
45
+ /** Suppress delayed trigger focus when a consumer handles close focus itself. Web only. */
46
+ skipReturnFocusRef?: RefObject<boolean>;
40
47
  trigger: ReactNode;
41
48
  /**
42
49
  * Optional control rendered beside the trigger but OUTSIDE the native press
@@ -120,6 +127,11 @@ export interface FloatingPanelProps {
120
127
  * the strings must live on the Pressable itself. Web ignores this.
121
128
  */
122
129
  triggerA11y?: { label?: string; value?: string; hint?: string };
130
+ /**
131
+ * Stretch keeps the whole field pressable by default. Content lets an
132
+ * adornment trigger hug its content inside a composite field.
133
+ */
134
+ triggerSizing?: "stretch" | "content";
123
135
  /**
124
136
  * How the trigger opens the panel. `"press"` (default) is click/tap.
125
137
  * `"contextmenu"` is the ContextMenu gesture: web `contextmenu` (right-click
@@ -231,8 +243,10 @@ export function FloatingPanel(props: FloatingPanelProps) {
231
243
  function FloatingPanelSheet({
232
244
  open,
233
245
  onOpenChange,
246
+ skipReturnFocusRef,
234
247
  trigger,
235
248
  triggerEnd,
249
+ triggerSizing = "stretch",
236
250
  children,
237
251
  scrollable,
238
252
  disabled,
@@ -260,7 +274,7 @@ function FloatingPanelSheet({
260
274
  // DG-A11Y-04 / Axiom 7: Sheet has no focus scope — move focus into the
261
275
  // frame on open, trap Tab while open, return focus to the trigger on close.
262
276
  const sheetFrameRef = useRef<HTMLElement | null>(null);
263
- useSheetModalFocus(open, sheetFrameRef);
277
+ useSheetModalFocus(open, sheetFrameRef, skipReturnFocusRef);
264
278
  useKeyboardFocusIntoPanel(open, sheetFrameRef);
265
279
 
266
280
  const framePadding = contentPadding === "none" ? "$0" : knobProps.panelPadding.padding;
@@ -283,7 +297,10 @@ function FloatingPanelSheet({
283
297
  // shut the sheet it had just opened. Nothing is lost: the sheet is modal, so
284
298
  // its overlay covers the trigger and the toggle could only ever have run
285
299
  // with `open === false`.
286
- const openFromTrigger = () => handleOpenChange(true);
300
+ const openFromTrigger = (event?: PanelActionEvent) => {
301
+ if (event && isNestedPanelAction(event)) return;
302
+ handleOpenChange(true);
303
+ };
287
304
  const isContextMenu = openOn === "contextmenu";
288
305
  const triggerActivation = isWeb
289
306
  ? isContextMenu
@@ -298,9 +315,13 @@ function FloatingPanelSheet({
298
315
 
299
316
  return (
300
317
  <>
301
- <View flexDirection="row" alignItems="center" width="100%">
318
+ <View
319
+ flexDirection="row"
320
+ alignItems="center"
321
+ width={triggerSizing === "content" ? "auto" : "100%"}
322
+ >
302
323
  <View
303
- flex={1}
324
+ flex={triggerSizing === "content" ? undefined : 1}
304
325
  minWidth={0}
305
326
  {...(isContextMenu ? undefined : { onPress: openFromTrigger })}
306
327
  cursor={disabled ? "not-allowed" : "pointer"}
@@ -361,6 +382,7 @@ function FloatingPanelSheet({
361
382
  function FloatingPanelWeb({
362
383
  open,
363
384
  onOpenChange,
385
+ skipReturnFocusRef,
364
386
  trigger,
365
387
  children,
366
388
  disabled,
@@ -379,6 +401,7 @@ function FloatingPanelWeb({
379
401
  const growDownOnlyRef = useRef(false);
380
402
  const lastScrollTopRef = useRef(0);
381
403
  const keyboardOpenRef = useRef(false);
404
+ const contentRef = useRef<HTMLElement | null>(null);
382
405
 
383
406
  const repositionFnRef = useRef<(() => void) | null>(null);
384
407
 
@@ -405,7 +428,7 @@ function FloatingPanelWeb({
405
428
  // Escape (or outside click on empty space) closes the panel while focus is
406
429
  // inside it, focus falls to <body>. Return it to the pre-open element
407
430
  // (the trigger's focusable). Deliberate focus moves elsewhere are kept.
408
- useReturnFocusOnClose(open);
431
+ useReturnFocusOnClose(open, skipReturnFocusRef);
409
432
  useKeyboardFocusIntoPanel(open && panel.mounted, panel.refs.floating, keyboardOpenRef);
410
433
  useEffect(() => {
411
434
  if (!open) keyboardOpenRef.current = false;
@@ -573,6 +596,29 @@ function FloatingPanelWeb({
573
596
  repositionOverlay();
574
597
  }, [open, panel.mounted, repositionOverlay, panel.y]);
575
598
 
599
+ useLayoutEffect(() => {
600
+ const content = contentRef.current;
601
+ if (!open || !panel.mounted || !isFill || !content || typeof ResizeObserver === "undefined") {
602
+ return;
603
+ }
604
+ // Matching the trigger width can rewrap content after the panel's first
605
+ // height measurement. Observe the content, not the clamped viewport, so a
606
+ // later open or result change uses its actual height without a resize loop.
607
+ let frame = 0;
608
+ const observer = new ResizeObserver(() => {
609
+ if (frame) cancelAnimationFrame(frame);
610
+ frame = requestAnimationFrame(() => {
611
+ frame = 0;
612
+ repositionOverlay();
613
+ });
614
+ });
615
+ observer.observe(content);
616
+ return () => {
617
+ observer.disconnect();
618
+ if (frame) cancelAnimationFrame(frame);
619
+ };
620
+ }, [open, panel.mounted, isFill, repositionOverlay]);
621
+
576
622
  const handleScroll = useCallback(
577
623
  (event: UIEvent) => {
578
624
  const el = event.target as HTMLElement;
@@ -633,8 +679,8 @@ function FloatingPanelWeb({
633
679
  // (`p-results/trigger-slot/detail.json`): a pointer click carries the click
634
680
  // count, `element.click()` and native keyboard activation carry 0.
635
681
  const openFromSynthesizedClick = useCallback(
636
- (event: { detail: number }) => {
637
- if (disabled || isContextMenu || event.detail !== 0) return;
682
+ (event: { detail: number } & PanelActionEvent) => {
683
+ if (disabled || isContextMenu || event.detail !== 0 || isNestedPanelAction(event)) return;
638
684
  // detail 0 is keyboard/programmatic activation (LC-50). Count it as
639
685
  // keyboard-origin so the first inner control rings (LC-71).
640
686
  keyboardOpenRef.current = true;
@@ -652,14 +698,26 @@ function FloatingPanelWeb({
652
698
  [disabled, onOpenChange],
653
699
  );
654
700
 
701
+ const referenceProps = getReferenceProps({
702
+ ref: panel.setReferenceRef,
703
+ onClickCapture: openFromSynthesizedClick,
704
+ ...(isContextMenu ? { onContextMenu: openFromContextMenu } : {}),
705
+ });
706
+ // Guard the composed floating-ui openers, after hook handlers are merged.
707
+ // Declining leaves each action's own events and focus defaults intact.
708
+ for (const name of ["onMouseDown", "onClick", "onKeyDown", "onKeyUp"] as const) {
709
+ const handler = referenceProps[name];
710
+ if (typeof handler === "function") {
711
+ referenceProps[name] = (event: PanelActionEvent) => {
712
+ if (!isNestedPanelAction(event)) handler(event);
713
+ };
714
+ }
715
+ }
716
+
655
717
  return (
656
718
  <>
657
719
  <View
658
- {...getReferenceProps({
659
- ref: panel.setReferenceRef,
660
- onClickCapture: openFromSynthesizedClick,
661
- ...(isContextMenu ? { onContextMenu: openFromContextMenu } : {}),
662
- })}
720
+ {...referenceProps}
663
721
  cursor={disabled ? "not-allowed" : "pointer"}
664
722
  opacity={disabled ? 0.5 : 1}
665
723
  // The cover contract is stated as a relation between the panel's top
@@ -693,6 +751,14 @@ function FloatingPanelWeb({
693
751
  transformOrigin: panelTransformOrigin(panel.placement),
694
752
  },
695
753
  onScroll: handleScroll,
754
+ onTransitionEnd: (event) => {
755
+ if (
756
+ event.target === event.currentTarget &&
757
+ (event.propertyName === "height" || event.propertyName === "max-height")
758
+ ) {
759
+ panel.updateArrows(event.currentTarget);
760
+ }
761
+ },
696
762
  })}
697
763
  data-testid="floating-panel-viewport"
698
764
  data-fp-panel=""
@@ -714,6 +780,7 @@ function FloatingPanelWeb({
714
780
  arrowScrollDirRef={panel.arrowScrollDirRef}
715
781
  />
716
782
  <View
783
+ ref={contentRef as any}
717
784
  {...(contentPadding !== "none" ? panel.knobProps.panelPadding : undefined)}
718
785
  {...(contentPadding !== "none" ? panel.knobProps.gapLg : undefined)}
719
786
  >