@multiplatform.one/forms 7.10.0 → 7.15.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 (721) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/AdaptivePopup/index.cjs +0 -10
  3. package/dist/cjs/AdaptivePopup/index.native.js +0 -10
  4. package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
  5. package/dist/cjs/Button/index.cjs +6 -3
  6. package/dist/cjs/Button/index.native.js +6 -3
  7. package/dist/cjs/Button/index.native.js.map +1 -1
  8. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.cjs +2 -11
  9. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js +2 -11
  10. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  11. package/dist/cjs/ContextualSaveBar/index.cjs +12 -10
  12. package/dist/cjs/ContextualSaveBar/index.native.js +12 -19
  13. package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
  14. package/dist/cjs/FieldDisplay/index.cjs +24 -12
  15. package/dist/cjs/FieldDisplay/index.native.js +25 -13
  16. package/dist/cjs/FieldDisplay/index.native.js.map +1 -1
  17. package/dist/cjs/FloatingPanel/PanelPortal.cjs +145 -0
  18. package/dist/cjs/FloatingPanel/PanelPortal.native.js +43 -0
  19. package/dist/cjs/FloatingPanel/PanelPortal.native.js.map +1 -0
  20. package/dist/cjs/FloatingPanel/index.cjs +115 -67
  21. package/dist/cjs/FloatingPanel/index.native.js +67 -12
  22. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  23. package/dist/cjs/FloatingPanel/useFloatingPanel.cjs +4 -2
  24. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js +4 -2
  25. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  26. package/dist/cjs/Form/index.cjs +2 -1
  27. package/dist/cjs/Form/index.native.js +2 -1
  28. package/dist/cjs/Form/index.native.js.map +1 -1
  29. package/dist/cjs/Form/submissionController.cjs +74 -0
  30. package/dist/cjs/Form/submissionController.native.js +99 -0
  31. package/dist/cjs/Form/submissionController.native.js.map +1 -0
  32. package/dist/cjs/InputParts/index.cjs +66 -12
  33. package/dist/cjs/InputParts/index.native.js +72 -12
  34. package/dist/cjs/InputParts/index.native.js.map +1 -1
  35. package/dist/cjs/Wheel/index.cjs +0 -2
  36. package/dist/cjs/Wheel/index.native.js +0 -2
  37. package/dist/cjs/Wheel/index.native.js.map +1 -1
  38. package/dist/cjs/fields/Barcode/BarcodePreview.cjs +18 -15
  39. package/dist/cjs/fields/Barcode/BarcodePreview.native.js +21 -18
  40. package/dist/cjs/fields/Barcode/BarcodePreview.native.js.map +1 -1
  41. package/dist/cjs/fields/Checkbox/Checkbox.cjs +1 -3
  42. package/dist/cjs/fields/Checkbox/Checkbox.native.js +1 -3
  43. package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
  44. package/dist/cjs/fields/Checkbox/CheckboxBox.cjs +2 -3
  45. package/dist/cjs/fields/Checkbox/CheckboxBox.native.js +2 -3
  46. package/dist/cjs/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  47. package/dist/cjs/fields/ColorPicker/index.cjs +2 -0
  48. package/dist/cjs/fields/ColorPicker/index.native.js +2 -0
  49. package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
  50. package/dist/cjs/fields/ColorPicker/parts.cjs +1 -0
  51. package/dist/cjs/fields/ColorPicker/parts.native.js +1 -0
  52. package/dist/cjs/fields/ColorPicker/parts.native.js.map +1 -1
  53. package/dist/cjs/fields/Combobox/index.cjs +206 -200
  54. package/dist/cjs/fields/Combobox/index.native.js +214 -208
  55. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  56. package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +7 -7
  57. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +7 -7
  58. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  59. package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +6 -4
  60. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +6 -4
  61. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  62. package/dist/cjs/fields/Duration/index.cjs +5 -3
  63. package/dist/cjs/fields/Duration/index.native.js +5 -3
  64. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  65. package/dist/cjs/fields/FileUpload/index.cjs +10 -8
  66. package/dist/cjs/fields/FileUpload/index.native.js +10 -8
  67. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  68. package/dist/cjs/fields/FileUpload/nativePickerLoader.cjs +7 -2
  69. package/dist/cjs/fields/FileUpload/nativePickerLoader.native.js +7 -2
  70. package/dist/cjs/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  71. package/dist/cjs/fields/Geolocation/GeolocationMap.cjs +3 -0
  72. package/dist/cjs/fields/Geolocation/geocoderContext.cjs +71 -0
  73. package/dist/cjs/fields/Geolocation/geocoderContext.native.js +75 -0
  74. package/dist/cjs/fields/Geolocation/geocoderContext.native.js.map +1 -0
  75. package/dist/cjs/fields/Geolocation/index.cjs +72 -82
  76. package/dist/cjs/fields/Geolocation/index.native.js +72 -82
  77. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  78. package/dist/cjs/fields/Geolocation/photonGeocoder.cjs +138 -0
  79. package/dist/cjs/fields/Geolocation/photonGeocoder.native.js +179 -0
  80. package/dist/cjs/fields/Geolocation/photonGeocoder.native.js.map +1 -0
  81. package/dist/cjs/fields/Input/index.cjs +7 -5
  82. package/dist/cjs/fields/Input/index.native.js +7 -5
  83. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  84. package/dist/cjs/fields/MentionInput/index.cjs +118 -112
  85. package/dist/cjs/fields/MentionInput/index.native.js +130 -124
  86. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  87. package/dist/cjs/fields/OTPInput/index.cjs +11 -8
  88. package/dist/cjs/fields/OTPInput/index.native.js +11 -8
  89. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  90. package/dist/cjs/fields/PhoneInput/index.cjs +9 -6
  91. package/dist/cjs/fields/PhoneInput/index.native.js +9 -6
  92. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  93. package/dist/cjs/fields/PhoneInput/phone.cjs +6 -5
  94. package/dist/cjs/fields/PhoneInput/phone.native.js +7 -6
  95. package/dist/cjs/fields/PhoneInput/phone.native.js.map +1 -1
  96. package/dist/cjs/fields/PhoneInput/regionNames.cjs +274 -0
  97. package/dist/cjs/fields/PhoneInput/regionNames.native.js +277 -0
  98. package/dist/cjs/fields/PhoneInput/regionNames.native.js.map +1 -0
  99. package/dist/cjs/fields/RadioGroup/index.cjs +2 -6
  100. package/dist/cjs/fields/RadioGroup/index.native.js +2 -6
  101. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  102. package/dist/cjs/fields/SearchInput/index.cjs +10 -8
  103. package/dist/cjs/fields/SearchInput/index.native.js +10 -8
  104. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  105. package/dist/cjs/fields/Select/index.cjs +20 -17
  106. package/dist/cjs/fields/Select/index.native.js +20 -17
  107. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  108. package/dist/cjs/fields/Signature/index.cjs +10 -9
  109. package/dist/cjs/fields/Signature/index.native.js +10 -9
  110. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  111. package/dist/cjs/fields/Slider/index.cjs +21 -15
  112. package/dist/cjs/fields/Slider/index.native.js +21 -17
  113. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  114. package/dist/cjs/fields/Slider/jumpMotion.cjs +2 -2
  115. package/dist/cjs/fields/Slider/jumpMotion.native.js +2 -1
  116. package/dist/cjs/fields/Slider/jumpMotion.native.js.map +1 -1
  117. package/dist/cjs/fields/Stepper/index.cjs +25 -6
  118. package/dist/cjs/fields/Stepper/index.native.js +25 -6
  119. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  120. package/dist/cjs/fields/Switch/footprint.cjs +54 -0
  121. package/dist/cjs/fields/Switch/footprint.native.js +57 -0
  122. package/dist/cjs/fields/Switch/footprint.native.js.map +1 -0
  123. package/dist/cjs/fields/Switch/index.cjs +60 -43
  124. package/dist/cjs/fields/Switch/index.native.js +60 -50
  125. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  126. package/dist/cjs/fields/TextArea/index.cjs +6 -3
  127. package/dist/cjs/fields/TextArea/index.native.js +6 -3
  128. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  129. package/dist/cjs/fields/TimePicker/catalog.cjs +1 -0
  130. package/dist/cjs/fields/TimePicker/catalog.native.js +1 -0
  131. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  132. package/dist/cjs/fields/TimePicker/parts.cjs +5 -0
  133. package/dist/cjs/fields/TimePicker/parts.native.js +7 -0
  134. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  135. package/dist/cjs/index.cjs +12 -0
  136. package/dist/cjs/index.native.js +12 -0
  137. package/dist/cjs/index.native.js.map +1 -1
  138. package/dist/cjs/shared/panelPortal.cjs +52 -0
  139. package/dist/cjs/shared/panelPortal.native.js +65 -0
  140. package/dist/cjs/shared/panelPortal.native.js.map +1 -0
  141. package/dist/cjs/shared/pressSlopProps.cjs +16 -11
  142. package/dist/cjs/shared/pressSlopProps.native.js +18 -12
  143. package/dist/cjs/shared/pressSlopProps.native.js.map +1 -1
  144. package/dist/cjs/shared/utils.cjs +2 -2
  145. package/dist/cjs/shared/utils.native.js +3 -2
  146. package/dist/cjs/shared/utils.native.js.map +1 -1
  147. package/dist/cjs/themedPrimitives.cjs +15 -2
  148. package/dist/cjs/themedPrimitives.native.js +16 -3
  149. package/dist/cjs/themedPrimitives.native.js.map +1 -1
  150. package/dist/esm/AdaptivePopup/index.mjs +0 -10
  151. package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
  152. package/dist/esm/AdaptivePopup/index.native.js +0 -10
  153. package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
  154. package/dist/esm/Button/index.mjs +6 -3
  155. package/dist/esm/Button/index.mjs.map +1 -1
  156. package/dist/esm/Button/index.native.js +6 -3
  157. package/dist/esm/Button/index.native.js.map +1 -1
  158. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.mjs +3 -12
  159. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.mjs.map +1 -1
  160. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js +3 -12
  161. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  162. package/dist/esm/ContextualSaveBar/index.mjs +13 -11
  163. package/dist/esm/ContextualSaveBar/index.mjs.map +1 -1
  164. package/dist/esm/ContextualSaveBar/index.native.js +13 -20
  165. package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
  166. package/dist/esm/FieldDisplay/index.mjs +24 -12
  167. package/dist/esm/FieldDisplay/index.mjs.map +1 -1
  168. package/dist/esm/FieldDisplay/index.native.js +25 -13
  169. package/dist/esm/FieldDisplay/index.native.js.map +1 -1
  170. package/dist/esm/FloatingPanel/PanelPortal.mjs +119 -0
  171. package/dist/esm/FloatingPanel/PanelPortal.mjs.map +1 -0
  172. package/dist/esm/FloatingPanel/PanelPortal.native.js +14 -0
  173. package/dist/esm/FloatingPanel/PanelPortal.native.js.map +1 -0
  174. package/dist/esm/FloatingPanel/index.mjs +117 -69
  175. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  176. package/dist/esm/FloatingPanel/index.native.js +68 -13
  177. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  178. package/dist/esm/FloatingPanel/useFloatingPanel.mjs +4 -2
  179. package/dist/esm/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  180. package/dist/esm/FloatingPanel/useFloatingPanel.native.js +4 -2
  181. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  182. package/dist/esm/Form/index.mjs +2 -1
  183. package/dist/esm/Form/index.mjs.map +1 -1
  184. package/dist/esm/Form/index.native.js +2 -1
  185. package/dist/esm/Form/index.native.js.map +1 -1
  186. package/dist/esm/Form/submissionController.mjs +49 -0
  187. package/dist/esm/Form/submissionController.mjs.map +1 -0
  188. package/dist/esm/Form/submissionController.native.js +71 -0
  189. package/dist/esm/Form/submissionController.native.js.map +1 -0
  190. package/dist/esm/InputParts/index.mjs +67 -13
  191. package/dist/esm/InputParts/index.mjs.map +1 -1
  192. package/dist/esm/InputParts/index.native.js +73 -13
  193. package/dist/esm/InputParts/index.native.js.map +1 -1
  194. package/dist/esm/Wheel/index.mjs +0 -2
  195. package/dist/esm/Wheel/index.mjs.map +1 -1
  196. package/dist/esm/Wheel/index.native.js +0 -2
  197. package/dist/esm/Wheel/index.native.js.map +1 -1
  198. package/dist/esm/fields/Barcode/BarcodePreview.mjs +19 -16
  199. package/dist/esm/fields/Barcode/BarcodePreview.mjs.map +1 -1
  200. package/dist/esm/fields/Barcode/BarcodePreview.native.js +22 -19
  201. package/dist/esm/fields/Barcode/BarcodePreview.native.js.map +1 -1
  202. package/dist/esm/fields/Checkbox/Checkbox.mjs +2 -4
  203. package/dist/esm/fields/Checkbox/Checkbox.mjs.map +1 -1
  204. package/dist/esm/fields/Checkbox/Checkbox.native.js +2 -4
  205. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  206. package/dist/esm/fields/Checkbox/CheckboxBox.mjs +3 -4
  207. package/dist/esm/fields/Checkbox/CheckboxBox.mjs.map +1 -1
  208. package/dist/esm/fields/Checkbox/CheckboxBox.native.js +3 -4
  209. package/dist/esm/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  210. package/dist/esm/fields/ColorPicker/index.mjs +2 -0
  211. package/dist/esm/fields/ColorPicker/index.mjs.map +1 -1
  212. package/dist/esm/fields/ColorPicker/index.native.js +2 -0
  213. package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
  214. package/dist/esm/fields/ColorPicker/parts.mjs +1 -0
  215. package/dist/esm/fields/ColorPicker/parts.mjs.map +1 -1
  216. package/dist/esm/fields/ColorPicker/parts.native.js +1 -0
  217. package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
  218. package/dist/esm/fields/Combobox/index.mjs +197 -191
  219. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  220. package/dist/esm/fields/Combobox/index.native.js +205 -199
  221. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  222. package/dist/esm/fields/DatePicker/DateRangePicker.mjs +5 -5
  223. package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  224. package/dist/esm/fields/DatePicker/DateRangePicker.native.js +5 -5
  225. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  226. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +3 -1
  227. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  228. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +3 -1
  229. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  230. package/dist/esm/fields/Duration/index.mjs +3 -1
  231. package/dist/esm/fields/Duration/index.mjs.map +1 -1
  232. package/dist/esm/fields/Duration/index.native.js +3 -1
  233. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  234. package/dist/esm/fields/FileUpload/index.mjs +5 -3
  235. package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
  236. package/dist/esm/fields/FileUpload/index.native.js +5 -3
  237. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  238. package/dist/esm/fields/FileUpload/nativePickerLoader.mjs +7 -3
  239. package/dist/esm/fields/FileUpload/nativePickerLoader.mjs.map +1 -1
  240. package/dist/esm/fields/FileUpload/nativePickerLoader.native.js +7 -3
  241. package/dist/esm/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  242. package/dist/esm/fields/Geolocation/GeolocationMap.mjs +3 -0
  243. package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  244. package/dist/esm/fields/Geolocation/geocoderContext.mjs +44 -0
  245. package/dist/esm/fields/Geolocation/geocoderContext.mjs.map +1 -0
  246. package/dist/esm/fields/Geolocation/geocoderContext.native.js +45 -0
  247. package/dist/esm/fields/Geolocation/geocoderContext.native.js.map +1 -0
  248. package/dist/esm/fields/Geolocation/index.mjs +73 -83
  249. package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
  250. package/dist/esm/fields/Geolocation/index.native.js +73 -83
  251. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  252. package/dist/esm/fields/Geolocation/photonGeocoder.mjs +112 -0
  253. package/dist/esm/fields/Geolocation/photonGeocoder.mjs.map +1 -0
  254. package/dist/esm/fields/Geolocation/photonGeocoder.native.js +150 -0
  255. package/dist/esm/fields/Geolocation/photonGeocoder.native.js.map +1 -0
  256. package/dist/esm/fields/Input/index.mjs +3 -1
  257. package/dist/esm/fields/Input/index.mjs.map +1 -1
  258. package/dist/esm/fields/Input/index.native.js +3 -1
  259. package/dist/esm/fields/Input/index.native.js.map +1 -1
  260. package/dist/esm/fields/MentionInput/index.mjs +115 -109
  261. package/dist/esm/fields/MentionInput/index.mjs.map +1 -1
  262. package/dist/esm/fields/MentionInput/index.native.js +127 -121
  263. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  264. package/dist/esm/fields/OTPInput/index.mjs +7 -4
  265. package/dist/esm/fields/OTPInput/index.mjs.map +1 -1
  266. package/dist/esm/fields/OTPInput/index.native.js +7 -4
  267. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  268. package/dist/esm/fields/PhoneInput/index.mjs +6 -3
  269. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  270. package/dist/esm/fields/PhoneInput/index.native.js +6 -3
  271. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  272. package/dist/esm/fields/PhoneInput/phone.mjs +6 -5
  273. package/dist/esm/fields/PhoneInput/phone.mjs.map +1 -1
  274. package/dist/esm/fields/PhoneInput/phone.native.js +7 -6
  275. package/dist/esm/fields/PhoneInput/phone.native.js.map +1 -1
  276. package/dist/esm/fields/PhoneInput/regionNames.mjs +249 -0
  277. package/dist/esm/fields/PhoneInput/regionNames.mjs.map +1 -0
  278. package/dist/esm/fields/PhoneInput/regionNames.native.js +249 -0
  279. package/dist/esm/fields/PhoneInput/regionNames.native.js.map +1 -0
  280. package/dist/esm/fields/RadioGroup/index.mjs +3 -7
  281. package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
  282. package/dist/esm/fields/RadioGroup/index.native.js +3 -7
  283. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  284. package/dist/esm/fields/SearchInput/index.mjs +5 -3
  285. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  286. package/dist/esm/fields/SearchInput/index.native.js +5 -3
  287. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  288. package/dist/esm/fields/Select/index.mjs +10 -7
  289. package/dist/esm/fields/Select/index.mjs.map +1 -1
  290. package/dist/esm/fields/Select/index.native.js +10 -7
  291. package/dist/esm/fields/Select/index.native.js.map +1 -1
  292. package/dist/esm/fields/Signature/index.mjs +7 -6
  293. package/dist/esm/fields/Signature/index.mjs.map +1 -1
  294. package/dist/esm/fields/Signature/index.native.js +7 -6
  295. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  296. package/dist/esm/fields/Slider/index.mjs +10 -4
  297. package/dist/esm/fields/Slider/index.mjs.map +1 -1
  298. package/dist/esm/fields/Slider/index.native.js +10 -6
  299. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  300. package/dist/esm/fields/Slider/jumpMotion.mjs +2 -2
  301. package/dist/esm/fields/Slider/jumpMotion.mjs.map +1 -1
  302. package/dist/esm/fields/Slider/jumpMotion.native.js +2 -1
  303. package/dist/esm/fields/Slider/jumpMotion.native.js.map +1 -1
  304. package/dist/esm/fields/Stepper/index.mjs +24 -5
  305. package/dist/esm/fields/Stepper/index.mjs.map +1 -1
  306. package/dist/esm/fields/Stepper/index.native.js +24 -5
  307. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  308. package/dist/esm/fields/Switch/footprint.mjs +29 -0
  309. package/dist/esm/fields/Switch/footprint.mjs.map +1 -0
  310. package/dist/esm/fields/Switch/footprint.native.js +29 -0
  311. package/dist/esm/fields/Switch/footprint.native.js.map +1 -0
  312. package/dist/esm/fields/Switch/index.mjs +44 -27
  313. package/dist/esm/fields/Switch/index.mjs.map +1 -1
  314. package/dist/esm/fields/Switch/index.native.js +44 -34
  315. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  316. package/dist/esm/fields/TextArea/index.mjs +6 -3
  317. package/dist/esm/fields/TextArea/index.mjs.map +1 -1
  318. package/dist/esm/fields/TextArea/index.native.js +6 -3
  319. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  320. package/dist/esm/fields/TimePicker/catalog.mjs +1 -0
  321. package/dist/esm/fields/TimePicker/catalog.mjs.map +1 -1
  322. package/dist/esm/fields/TimePicker/catalog.native.js +1 -0
  323. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  324. package/dist/esm/fields/TimePicker/parts.mjs +5 -0
  325. package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
  326. package/dist/esm/fields/TimePicker/parts.native.js +7 -0
  327. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  328. package/dist/esm/index.mjs +6 -1
  329. package/dist/esm/index.mjs.map +1 -1
  330. package/dist/esm/index.native.js +6 -1
  331. package/dist/esm/index.native.js.map +1 -1
  332. package/dist/esm/shared/panelPortal.mjs +24 -0
  333. package/dist/esm/shared/panelPortal.mjs.map +1 -0
  334. package/dist/esm/shared/panelPortal.native.js +34 -0
  335. package/dist/esm/shared/panelPortal.native.js.map +1 -0
  336. package/dist/esm/shared/pressSlopProps.mjs +16 -12
  337. package/dist/esm/shared/pressSlopProps.mjs.map +1 -1
  338. package/dist/esm/shared/pressSlopProps.native.js +18 -13
  339. package/dist/esm/shared/pressSlopProps.native.js.map +1 -1
  340. package/dist/esm/shared/utils.mjs +2 -2
  341. package/dist/esm/shared/utils.mjs.map +1 -1
  342. package/dist/esm/shared/utils.native.js +3 -2
  343. package/dist/esm/shared/utils.native.js.map +1 -1
  344. package/dist/esm/themedPrimitives.mjs +16 -3
  345. package/dist/esm/themedPrimitives.mjs.map +1 -1
  346. package/dist/esm/themedPrimitives.native.js +17 -4
  347. package/dist/esm/themedPrimitives.native.js.map +1 -1
  348. package/dist/jsx/AdaptivePopup/index.mjs +0 -10
  349. package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
  350. package/dist/jsx/AdaptivePopup/index.native.js +0 -10
  351. package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
  352. package/dist/jsx/Button/index.mjs +6 -3
  353. package/dist/jsx/Button/index.mjs.map +1 -1
  354. package/dist/jsx/Button/index.native.js +6 -3
  355. package/dist/jsx/Button/index.native.js.map +1 -1
  356. package/dist/jsx/ContextualSaveBar/UnsavedChangesDialog.mjs +3 -12
  357. package/dist/jsx/ContextualSaveBar/UnsavedChangesDialog.mjs.map +1 -1
  358. package/dist/jsx/ContextualSaveBar/UnsavedChangesDialog.native.js +2 -11
  359. package/dist/jsx/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  360. package/dist/jsx/ContextualSaveBar/index.mjs +13 -11
  361. package/dist/jsx/ContextualSaveBar/index.mjs.map +1 -1
  362. package/dist/jsx/ContextualSaveBar/index.native.js +12 -19
  363. package/dist/jsx/ContextualSaveBar/index.native.js.map +1 -1
  364. package/dist/jsx/FieldDisplay/index.mjs +24 -12
  365. package/dist/jsx/FieldDisplay/index.mjs.map +1 -1
  366. package/dist/jsx/FieldDisplay/index.native.js +25 -13
  367. package/dist/jsx/FieldDisplay/index.native.js.map +1 -1
  368. package/dist/jsx/FloatingPanel/PanelPortal.mjs +119 -0
  369. package/dist/jsx/FloatingPanel/PanelPortal.mjs.map +1 -0
  370. package/dist/jsx/FloatingPanel/PanelPortal.native.js +43 -0
  371. package/dist/jsx/FloatingPanel/PanelPortal.native.js.map +1 -0
  372. package/dist/jsx/FloatingPanel/index.mjs +117 -69
  373. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  374. package/dist/jsx/FloatingPanel/index.native.js +67 -12
  375. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  376. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs +4 -2
  377. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  378. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js +4 -2
  379. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  380. package/dist/jsx/Form/index.mjs +2 -1
  381. package/dist/jsx/Form/index.mjs.map +1 -1
  382. package/dist/jsx/Form/index.native.js +2 -1
  383. package/dist/jsx/Form/index.native.js.map +1 -1
  384. package/dist/jsx/Form/submissionController.mjs +49 -0
  385. package/dist/jsx/Form/submissionController.mjs.map +1 -0
  386. package/dist/jsx/Form/submissionController.native.js +99 -0
  387. package/dist/jsx/Form/submissionController.native.js.map +1 -0
  388. package/dist/jsx/InputParts/index.mjs +67 -13
  389. package/dist/jsx/InputParts/index.mjs.map +1 -1
  390. package/dist/jsx/InputParts/index.native.js +72 -12
  391. package/dist/jsx/InputParts/index.native.js.map +1 -1
  392. package/dist/jsx/Wheel/index.mjs +0 -2
  393. package/dist/jsx/Wheel/index.mjs.map +1 -1
  394. package/dist/jsx/Wheel/index.native.js +0 -2
  395. package/dist/jsx/Wheel/index.native.js.map +1 -1
  396. package/dist/jsx/fields/Barcode/BarcodePreview.mjs +19 -16
  397. package/dist/jsx/fields/Barcode/BarcodePreview.mjs.map +1 -1
  398. package/dist/jsx/fields/Barcode/BarcodePreview.native.js +21 -18
  399. package/dist/jsx/fields/Barcode/BarcodePreview.native.js.map +1 -1
  400. package/dist/jsx/fields/Checkbox/Checkbox.mjs +2 -4
  401. package/dist/jsx/fields/Checkbox/Checkbox.mjs.map +1 -1
  402. package/dist/jsx/fields/Checkbox/Checkbox.native.js +1 -3
  403. package/dist/jsx/fields/Checkbox/Checkbox.native.js.map +1 -1
  404. package/dist/jsx/fields/Checkbox/CheckboxBox.mjs +3 -4
  405. package/dist/jsx/fields/Checkbox/CheckboxBox.mjs.map +1 -1
  406. package/dist/jsx/fields/Checkbox/CheckboxBox.native.js +2 -3
  407. package/dist/jsx/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  408. package/dist/jsx/fields/ColorPicker/index.mjs +2 -0
  409. package/dist/jsx/fields/ColorPicker/index.mjs.map +1 -1
  410. package/dist/jsx/fields/ColorPicker/index.native.js +2 -0
  411. package/dist/jsx/fields/ColorPicker/index.native.js.map +1 -1
  412. package/dist/jsx/fields/ColorPicker/parts.mjs +1 -0
  413. package/dist/jsx/fields/ColorPicker/parts.mjs.map +1 -1
  414. package/dist/jsx/fields/ColorPicker/parts.native.js +1 -0
  415. package/dist/jsx/fields/ColorPicker/parts.native.js.map +1 -1
  416. package/dist/jsx/fields/Combobox/index.mjs +197 -191
  417. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  418. package/dist/jsx/fields/Combobox/index.native.js +214 -208
  419. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  420. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +5 -5
  421. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  422. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +7 -7
  423. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  424. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +3 -1
  425. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  426. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +6 -4
  427. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  428. package/dist/jsx/fields/Duration/index.mjs +3 -1
  429. package/dist/jsx/fields/Duration/index.mjs.map +1 -1
  430. package/dist/jsx/fields/Duration/index.native.js +5 -3
  431. package/dist/jsx/fields/Duration/index.native.js.map +1 -1
  432. package/dist/jsx/fields/FileUpload/index.mjs +5 -3
  433. package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
  434. package/dist/jsx/fields/FileUpload/index.native.js +10 -8
  435. package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
  436. package/dist/jsx/fields/FileUpload/nativePickerLoader.mjs +7 -3
  437. package/dist/jsx/fields/FileUpload/nativePickerLoader.mjs.map +1 -1
  438. package/dist/jsx/fields/FileUpload/nativePickerLoader.native.js +7 -2
  439. package/dist/jsx/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  440. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs +3 -0
  441. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  442. package/dist/jsx/fields/Geolocation/geocoderContext.mjs +44 -0
  443. package/dist/jsx/fields/Geolocation/geocoderContext.mjs.map +1 -0
  444. package/dist/jsx/fields/Geolocation/geocoderContext.native.js +75 -0
  445. package/dist/jsx/fields/Geolocation/geocoderContext.native.js.map +1 -0
  446. package/dist/jsx/fields/Geolocation/index.mjs +73 -83
  447. package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
  448. package/dist/jsx/fields/Geolocation/index.native.js +72 -82
  449. package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
  450. package/dist/jsx/fields/Geolocation/photonGeocoder.mjs +112 -0
  451. package/dist/jsx/fields/Geolocation/photonGeocoder.mjs.map +1 -0
  452. package/dist/jsx/fields/Geolocation/photonGeocoder.native.js +179 -0
  453. package/dist/jsx/fields/Geolocation/photonGeocoder.native.js.map +1 -0
  454. package/dist/jsx/fields/Input/index.mjs +3 -1
  455. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  456. package/dist/jsx/fields/Input/index.native.js +7 -5
  457. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  458. package/dist/jsx/fields/MentionInput/index.mjs +115 -109
  459. package/dist/jsx/fields/MentionInput/index.mjs.map +1 -1
  460. package/dist/jsx/fields/MentionInput/index.native.js +130 -124
  461. package/dist/jsx/fields/MentionInput/index.native.js.map +1 -1
  462. package/dist/jsx/fields/OTPInput/index.mjs +7 -4
  463. package/dist/jsx/fields/OTPInput/index.mjs.map +1 -1
  464. package/dist/jsx/fields/OTPInput/index.native.js +11 -8
  465. package/dist/jsx/fields/OTPInput/index.native.js.map +1 -1
  466. package/dist/jsx/fields/PhoneInput/index.mjs +6 -3
  467. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  468. package/dist/jsx/fields/PhoneInput/index.native.js +9 -6
  469. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  470. package/dist/jsx/fields/PhoneInput/phone.mjs +6 -5
  471. package/dist/jsx/fields/PhoneInput/phone.mjs.map +1 -1
  472. package/dist/jsx/fields/PhoneInput/phone.native.js +7 -6
  473. package/dist/jsx/fields/PhoneInput/phone.native.js.map +1 -1
  474. package/dist/jsx/fields/PhoneInput/regionNames.mjs +249 -0
  475. package/dist/jsx/fields/PhoneInput/regionNames.mjs.map +1 -0
  476. package/dist/jsx/fields/PhoneInput/regionNames.native.js +277 -0
  477. package/dist/jsx/fields/PhoneInput/regionNames.native.js.map +1 -0
  478. package/dist/jsx/fields/RadioGroup/index.mjs +3 -7
  479. package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
  480. package/dist/jsx/fields/RadioGroup/index.native.js +2 -6
  481. package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
  482. package/dist/jsx/fields/SearchInput/index.mjs +5 -3
  483. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  484. package/dist/jsx/fields/SearchInput/index.native.js +10 -8
  485. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  486. package/dist/jsx/fields/Select/index.mjs +10 -7
  487. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  488. package/dist/jsx/fields/Select/index.native.js +20 -17
  489. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  490. package/dist/jsx/fields/Signature/index.mjs +7 -6
  491. package/dist/jsx/fields/Signature/index.mjs.map +1 -1
  492. package/dist/jsx/fields/Signature/index.native.js +10 -9
  493. package/dist/jsx/fields/Signature/index.native.js.map +1 -1
  494. package/dist/jsx/fields/Slider/index.mjs +10 -4
  495. package/dist/jsx/fields/Slider/index.mjs.map +1 -1
  496. package/dist/jsx/fields/Slider/index.native.js +21 -17
  497. package/dist/jsx/fields/Slider/index.native.js.map +1 -1
  498. package/dist/jsx/fields/Slider/jumpMotion.mjs +2 -2
  499. package/dist/jsx/fields/Slider/jumpMotion.mjs.map +1 -1
  500. package/dist/jsx/fields/Slider/jumpMotion.native.js +2 -1
  501. package/dist/jsx/fields/Slider/jumpMotion.native.js.map +1 -1
  502. package/dist/jsx/fields/Stepper/index.mjs +24 -5
  503. package/dist/jsx/fields/Stepper/index.mjs.map +1 -1
  504. package/dist/jsx/fields/Stepper/index.native.js +25 -6
  505. package/dist/jsx/fields/Stepper/index.native.js.map +1 -1
  506. package/dist/jsx/fields/Switch/footprint.mjs +29 -0
  507. package/dist/jsx/fields/Switch/footprint.mjs.map +1 -0
  508. package/dist/jsx/fields/Switch/footprint.native.js +57 -0
  509. package/dist/jsx/fields/Switch/footprint.native.js.map +1 -0
  510. package/dist/jsx/fields/Switch/index.mjs +44 -27
  511. package/dist/jsx/fields/Switch/index.mjs.map +1 -1
  512. package/dist/jsx/fields/Switch/index.native.js +60 -50
  513. package/dist/jsx/fields/Switch/index.native.js.map +1 -1
  514. package/dist/jsx/fields/TextArea/index.mjs +6 -3
  515. package/dist/jsx/fields/TextArea/index.mjs.map +1 -1
  516. package/dist/jsx/fields/TextArea/index.native.js +6 -3
  517. package/dist/jsx/fields/TextArea/index.native.js.map +1 -1
  518. package/dist/jsx/fields/TimePicker/catalog.mjs +1 -0
  519. package/dist/jsx/fields/TimePicker/catalog.mjs.map +1 -1
  520. package/dist/jsx/fields/TimePicker/catalog.native.js +1 -0
  521. package/dist/jsx/fields/TimePicker/catalog.native.js.map +1 -1
  522. package/dist/jsx/fields/TimePicker/parts.mjs +5 -0
  523. package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
  524. package/dist/jsx/fields/TimePicker/parts.native.js +7 -0
  525. package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
  526. package/dist/jsx/index.js +6 -1
  527. package/dist/jsx/index.js.map +1 -1
  528. package/dist/jsx/index.mjs +6 -1
  529. package/dist/jsx/index.mjs.map +1 -1
  530. package/dist/jsx/index.native.js +12 -0
  531. package/dist/jsx/index.native.js.map +1 -1
  532. package/dist/jsx/shared/panelPortal.mjs +24 -0
  533. package/dist/jsx/shared/panelPortal.mjs.map +1 -0
  534. package/dist/jsx/shared/panelPortal.native.js +65 -0
  535. package/dist/jsx/shared/panelPortal.native.js.map +1 -0
  536. package/dist/jsx/shared/pressSlopProps.mjs +16 -12
  537. package/dist/jsx/shared/pressSlopProps.mjs.map +1 -1
  538. package/dist/jsx/shared/pressSlopProps.native.js +18 -12
  539. package/dist/jsx/shared/pressSlopProps.native.js.map +1 -1
  540. package/dist/jsx/shared/utils.mjs +2 -2
  541. package/dist/jsx/shared/utils.mjs.map +1 -1
  542. package/dist/jsx/shared/utils.native.js +3 -2
  543. package/dist/jsx/shared/utils.native.js.map +1 -1
  544. package/dist/jsx/themedPrimitives.mjs +16 -3
  545. package/dist/jsx/themedPrimitives.mjs.map +1 -1
  546. package/dist/jsx/themedPrimitives.native.js +16 -3
  547. package/dist/jsx/themedPrimitives.native.js.map +1 -1
  548. package/package.json +17 -13
  549. package/src/AdaptivePopup/AdaptivePopup.spec.tsx +2 -3
  550. package/src/AdaptivePopup/index.tsx +11 -10
  551. package/src/Button/Button.borderLadder.spec.tsx +82 -0
  552. package/src/Button/Button.labelInk.spec.tsx +4 -1
  553. package/src/Button/Button.radiusLaw.spec.tsx +153 -0
  554. package/src/Button/index.tsx +6 -3
  555. package/src/ContextualSaveBar/ContextualSaveBar.spec.tsx +24 -0
  556. package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +37 -1
  557. package/src/ContextualSaveBar/UnsavedChangesDialog.tsx +3 -11
  558. package/src/ContextualSaveBar/index.tsx +17 -11
  559. package/src/ErrorSummary.stories.tsx +20 -11
  560. package/src/FieldDisplay/FieldDisplay.spec.tsx +47 -2
  561. package/src/FieldDisplay/index.tsx +21 -13
  562. package/src/FloatingPanel/FloatingPanel.detentLayout.spec.tsx +148 -0
  563. package/src/FloatingPanel/FloatingPanel.spec.tsx +140 -1
  564. package/src/FloatingPanel/FloatingPanel.stories.tsx +86 -1
  565. package/src/FloatingPanel/PanelPortal.native.tsx +15 -0
  566. package/src/FloatingPanel/PanelPortal.tsx +149 -0
  567. package/src/FloatingPanel/index.native.tsx +96 -19
  568. package/src/FloatingPanel/index.tsx +172 -86
  569. package/src/FloatingPanel/panelPortal.spec.tsx +142 -0
  570. package/src/FloatingPanel/panelWidthContract.spec.ts +17 -5
  571. package/src/FloatingPanel/touchRecipeHydration.spec.tsx +82 -0
  572. package/src/FloatingPanel/useFloatingPanel.ts +5 -2
  573. package/src/FloatingPanel/viewportHydration.spec.tsx +118 -0
  574. package/src/Form/index.tsx +2 -1
  575. package/src/Form/submission.spec.tsx +148 -0
  576. package/src/Form/submissionController.spec.ts +73 -0
  577. package/src/Form/submissionController.ts +59 -0
  578. package/src/Form/submissionDiscard.spec.tsx +41 -0
  579. package/src/Form/submissionPaths.spec.tsx +214 -0
  580. package/src/InputParts/index.tsx +48 -12
  581. package/src/Label/Label.stories.tsx +27 -11
  582. package/src/Wheel/Wheel.spec.tsx +9 -2
  583. package/src/Wheel/index.tsx +0 -2
  584. package/src/fieldFamilyStories.radius.spec.tsx +48 -0
  585. package/src/fields/Barcode/BarcodePreview.spec.tsx +32 -12
  586. package/src/fields/Barcode/BarcodePreview.stories.tsx +5 -4
  587. package/src/fields/Barcode/BarcodePreview.tsx +31 -25
  588. package/src/fields/Checkbox/Checkbox.native.spec.tsx +92 -0
  589. package/src/fields/Checkbox/Checkbox.stories.tsx +1 -0
  590. package/src/fields/Checkbox/Checkbox.tsx +2 -2
  591. package/src/fields/Checkbox/CheckboxBox.spec.tsx +13 -13
  592. package/src/fields/Checkbox/CheckboxBox.tsx +7 -1
  593. package/src/fields/ColorPicker/index.tsx +6 -1
  594. package/src/fields/ColorPicker/parts.tsx +1 -0
  595. package/src/fields/Combobox/Combobox.spec.tsx +85 -55
  596. package/src/fields/Combobox/index.tsx +259 -240
  597. package/src/fields/DatePicker/DateRangePicker.tsx +5 -3
  598. package/src/fields/DatePicker/MultiDatePicker.tsx +3 -1
  599. package/src/fields/Duration/index.tsx +3 -1
  600. package/src/fields/FileUpload/index.tsx +13 -3
  601. package/src/fields/FileUpload/nativePickerLoader.spec.ts +34 -0
  602. package/src/fields/FileUpload/nativePickerLoader.ts +11 -2
  603. package/src/fields/Geolocation/Geolocation.spec.tsx +165 -4
  604. package/src/fields/Geolocation/Geolocation.stories.tsx +110 -26
  605. package/src/fields/Geolocation/GeolocationMap.tsx +3 -0
  606. package/src/fields/Geolocation/geocoderContext.tsx +56 -0
  607. package/src/fields/Geolocation/index.tsx +75 -80
  608. package/src/fields/Geolocation/photonGeocoder.spec.ts +214 -0
  609. package/src/fields/Geolocation/photonGeocoder.ts +150 -0
  610. package/src/fields/Input/index.tsx +3 -1
  611. package/src/fields/MentionInput/MentionInput.spec.tsx +41 -30
  612. package/src/fields/MentionInput/index.tsx +128 -119
  613. package/src/fields/OTPInput/index.tsx +7 -4
  614. package/src/fields/PhoneInput/PhoneInput.spec.tsx +63 -0
  615. package/src/fields/PhoneInput/index.tsx +13 -8
  616. package/src/fields/PhoneInput/phone.native.spec.ts +32 -0
  617. package/src/fields/PhoneInput/phone.ts +5 -2
  618. package/src/fields/PhoneInput/regionNames.ts +250 -0
  619. package/src/fields/RadioGroup/RadioGroup.stories.tsx +4 -3
  620. package/src/fields/RadioGroup/index.tsx +3 -2
  621. package/src/fields/Rating/StarInk.native.spec.tsx +1 -1
  622. package/src/fields/SearchInput/index.tsx +4 -3
  623. package/src/fields/Select/Select.spec.tsx +36 -29
  624. package/src/fields/Select/index.tsx +14 -5
  625. package/src/fields/Signature/index.tsx +7 -3
  626. package/src/fields/Slider/index.tsx +14 -4
  627. package/src/fields/Slider/jumpMotion.ts +6 -2
  628. package/src/fields/Stepper/Stepper.spec.tsx +30 -0
  629. package/src/fields/Stepper/index.tsx +34 -4
  630. package/src/fields/Switch/Switch.footprint.native.spec.tsx +58 -0
  631. package/src/fields/Switch/Switch.footprint.spec.tsx +79 -0
  632. package/src/fields/Switch/Switch.radius.spec.tsx +37 -6
  633. package/src/fields/Switch/footprint.ts +45 -0
  634. package/src/fields/Switch/index.tsx +46 -49
  635. package/src/fields/TextArea/TextArea.spec.tsx +30 -1
  636. package/src/fields/TextArea/index.tsx +6 -3
  637. package/src/fields/TimePicker/TimePicker.native.spec.tsx +48 -0
  638. package/src/fields/TimePicker/catalog.tsx +1 -0
  639. package/src/fields/TimePicker/parts.tsx +4 -0
  640. package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +17 -8
  641. package/src/fields/pickerShellPadding.spec.tsx +54 -0
  642. package/src/index.ts +8 -0
  643. package/src/shared/panelPortal.ts +36 -0
  644. package/src/shared/pressSlopProps.spec.ts +27 -1
  645. package/src/shared/pressSlopProps.ts +26 -17
  646. package/src/shared/utils.ts +2 -2
  647. package/src/themedPrimitives.tsx +16 -3
  648. package/types/AdaptivePopup/index.d.ts.map +1 -1
  649. package/types/Button/index.d.ts.map +1 -1
  650. package/types/ContextualSaveBar/UnsavedChangesDialog.d.ts.map +1 -1
  651. package/types/ContextualSaveBar/index.d.ts.map +1 -1
  652. package/types/FieldDisplay/index.d.ts.map +1 -1
  653. package/types/FloatingPanel/PanelPortal.d.ts +24 -0
  654. package/types/FloatingPanel/PanelPortal.d.ts.map +1 -0
  655. package/types/FloatingPanel/PanelPortal.native.d.ts +9 -0
  656. package/types/FloatingPanel/PanelPortal.native.d.ts.map +1 -0
  657. package/types/FloatingPanel/index.d.ts +0 -5
  658. package/types/FloatingPanel/index.d.ts.map +1 -1
  659. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  660. package/types/FloatingPanel/useFloatingPanel.d.ts.map +1 -1
  661. package/types/Form/index.d.ts.map +1 -1
  662. package/types/Form/submissionController.d.ts +21 -0
  663. package/types/Form/submissionController.d.ts.map +1 -0
  664. package/types/InputParts/index.d.ts +34 -2
  665. package/types/InputParts/index.d.ts.map +1 -1
  666. package/types/Wheel/index.d.ts.map +1 -1
  667. package/types/fields/Barcode/BarcodePreview.d.ts +7 -3
  668. package/types/fields/Barcode/BarcodePreview.d.ts.map +1 -1
  669. package/types/fields/Checkbox/CheckboxBox.d.ts +5 -0
  670. package/types/fields/Checkbox/CheckboxBox.d.ts.map +1 -1
  671. package/types/fields/ColorPicker/index.d.ts.map +1 -1
  672. package/types/fields/ColorPicker/parts.d.ts +2 -0
  673. package/types/fields/ColorPicker/parts.d.ts.map +1 -1
  674. package/types/fields/Combobox/index.d.ts.map +1 -1
  675. package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
  676. package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
  677. package/types/fields/Duration/index.d.ts.map +1 -1
  678. package/types/fields/FileUpload/index.d.ts.map +1 -1
  679. package/types/fields/FileUpload/nativePickerLoader.d.ts +8 -0
  680. package/types/fields/FileUpload/nativePickerLoader.d.ts.map +1 -1
  681. package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
  682. package/types/fields/Geolocation/geocoderContext.d.ts +24 -0
  683. package/types/fields/Geolocation/geocoderContext.d.ts.map +1 -0
  684. package/types/fields/Geolocation/index.d.ts +2 -1
  685. package/types/fields/Geolocation/index.d.ts.map +1 -1
  686. package/types/fields/Geolocation/photonGeocoder.d.ts +46 -0
  687. package/types/fields/Geolocation/photonGeocoder.d.ts.map +1 -0
  688. package/types/fields/Input/index.d.ts +19 -1
  689. package/types/fields/Input/index.d.ts.map +1 -1
  690. package/types/fields/MentionInput/index.d.ts.map +1 -1
  691. package/types/fields/OTPInput/index.d.ts +1 -1
  692. package/types/fields/OTPInput/index.d.ts.map +1 -1
  693. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  694. package/types/fields/PhoneInput/phone.d.ts.map +1 -1
  695. package/types/fields/PhoneInput/regionNames.d.ts +2 -0
  696. package/types/fields/PhoneInput/regionNames.d.ts.map +1 -0
  697. package/types/fields/RadioGroup/index.d.ts.map +1 -1
  698. package/types/fields/SearchInput/index.d.ts.map +1 -1
  699. package/types/fields/Select/index.d.ts.map +1 -1
  700. package/types/fields/Signature/index.d.ts.map +1 -1
  701. package/types/fields/Slider/index.d.ts.map +1 -1
  702. package/types/fields/Slider/jumpMotion.d.ts +1 -1
  703. package/types/fields/Slider/jumpMotion.d.ts.map +1 -1
  704. package/types/fields/Stepper/index.d.ts +6 -0
  705. package/types/fields/Stepper/index.d.ts.map +1 -1
  706. package/types/fields/Switch/footprint.d.ts +12 -0
  707. package/types/fields/Switch/footprint.d.ts.map +1 -0
  708. package/types/fields/Switch/index.d.ts.map +1 -1
  709. package/types/fields/TextArea/index.d.ts.map +1 -1
  710. package/types/fields/TimePicker/catalog.d.ts.map +1 -1
  711. package/types/fields/TimePicker/parts.d.ts.map +1 -1
  712. package/types/index.d.ts +8 -0
  713. package/types/index.d.ts.map +1 -1
  714. package/types/shared/panelPortal.d.ts +13 -0
  715. package/types/shared/panelPortal.d.ts.map +1 -0
  716. package/types/shared/pressSlopProps.d.ts +9 -2
  717. package/types/shared/pressSlopProps.d.ts.map +1 -1
  718. package/types/shared/utils.d.ts +1 -1
  719. package/types/shared/utils.d.ts.map +1 -1
  720. package/types/themedPrimitives.d.ts +48 -1
  721. package/types/themedPrimitives.d.ts.map +1 -1
@@ -1,3 +1,4 @@
1
+ import { useTouchSurface } from "@multiplatform.one/theme";
1
2
  import type { DeepKeys, DeepValue } from "@tanstack/form-core";
2
3
  import { formatAbsoluteDate, useResolvedKnobs } from "@multiplatform.one/theme";
3
4
  import { type ComponentProps, useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -306,6 +307,7 @@ export function MultiDatePicker<
306
307
  TFormValidator extends Validator<TParentData, unknown> | undefined = undefined,
307
308
  TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
308
309
  >(props: MultiDatePickerProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) {
310
+ const hydrationTouch = useTouchSurface();
309
311
  const {
310
312
  defaultValue,
311
313
  value: valueProp,
@@ -338,7 +340,7 @@ export function MultiDatePicker<
338
340
  const { resolvedForm, knobProps, id } = useFormField({ form, id: idProp, compact });
339
341
  const resolvedValidators = useResolvedValidators(required, validators, label, name, isEmptyDates);
340
342
  const resolvedSize = (size ?? knobProps.sizeToken) as SizeTokens;
341
- const visualHeight = getFieldHeight(resolvedSize);
343
+ const visualHeight = getFieldHeight(resolvedSize, 1, hydrationTouch);
342
344
 
343
345
  const initialDates = (
344
346
  Array.isArray(valueProp) ? valueProp : Array.isArray(defaultValue) ? defaultValue : []
@@ -1,3 +1,4 @@
1
+ import { useTouchSurface } from "@multiplatform.one/theme";
1
2
  import { sizeRecipeForToken, type KnobProps } from "@multiplatform.one/theme";
2
3
  import { ClockIcon } from "@phosphor-icons/react";
3
4
  import type { ReactNode } from "react";
@@ -434,6 +435,7 @@ export function Duration({
434
435
  skeleton,
435
436
  compact,
436
437
  }: DurationProps) {
438
+ const hydrationTouch = useTouchSurface();
437
439
  const { resolvedForm, knobProps, id } = useFormField({
438
440
  form: formProp,
439
441
  id: idProp,
@@ -445,7 +447,7 @@ export function Duration({
445
447
  const seconds = normalizeSeconds(isControlled ? value : internal);
446
448
  const inTableCell = useIsInTableCell();
447
449
  const resolvedSize = (size ?? knobProps.sizeToken) as SizeTokens;
448
- const visualHeight = getFieldHeight(resolvedSize);
450
+ const visualHeight = getFieldHeight(resolvedSize, 1, hydrationTouch);
449
451
 
450
452
  const handleChange = useCallback(
451
453
  (next: number, fieldChange?: (v: any) => void) => {
@@ -1,3 +1,4 @@
1
+ import { useTouchSurface } from "@multiplatform.one/theme";
1
2
  import { FileIcon, UploadIcon, XIcon } from "@phosphor-icons/react";
2
3
  import type { DeepKeys, DeepValue } from "@tanstack/form-core";
3
4
  import { type DragEvent, type ReactNode, useCallback, useEffect, useRef, useState } from "react";
@@ -195,6 +196,7 @@ export function FileUpload<
195
196
  TFormValidator extends Validator<TParentData, unknown> | undefined = undefined,
196
197
  TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
197
198
  >(props: FileUploadProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) {
199
+ const hydrationTouch = useTouchSurface();
198
200
  const {
199
201
  defaultValue,
200
202
  form,
@@ -263,7 +265,7 @@ export function FileUpload<
263
265
  // frame move together per size. The corner remove disc hangs a quarter of
264
266
  // its own nestedControl step (8 at medium) outside the tile's top-right,
265
267
  // which is the Bento Image Picker overlap read under the house tokens.
266
- const tilePx = getFieldHeight(knobProps.sizeToken as SizeTokens, 2);
268
+ const tilePx = getFieldHeight(knobProps.sizeToken as SizeTokens, 2, hydrationTouch);
267
269
  const tileRemoveInset = -Math.round(knobProps.nestedControl.px / 4);
268
270
 
269
271
  const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
@@ -688,7 +690,11 @@ export function FileUpload<
688
690
 
689
691
  // Render skeleton placeholder
690
692
  if (skeleton) {
691
- const minHeightPx = getFieldHeight((fieldProps.size || knobProps.sizeToken) as SizeTokens, 5);
693
+ const minHeightPx = getFieldHeight(
694
+ (fieldProps.size || knobProps.sizeToken) as SizeTokens,
695
+ 5,
696
+ hydrationTouch,
697
+ );
692
698
  return (
693
699
  <FieldLayout id={id} label={fieldProps.label} size={fieldProps.size} knobProps={knobProps}>
694
700
  <Skeleton variant="rounded" width="100%" height={minHeightPx} />
@@ -876,7 +882,11 @@ export function FileUpload<
876
882
  // CONTRACT (boards media-01..03): the getFieldHeight floor sits on
877
883
  // the FRAME, so the frame border-box measures 220 — hanging it on
878
884
  // the inner stack painted 222, a number no token expresses.
879
- minHeight={getFieldHeight((fieldProps.size || knobProps.sizeToken) as SizeTokens, 5)}
885
+ minHeight={getFieldHeight(
886
+ (fieldProps.size || knobProps.sizeToken) as SizeTokens,
887
+ 5,
888
+ hydrationTouch,
889
+ )}
880
890
  aria-required={fieldProps.required || undefined}
881
891
  aria-invalid={!!errorProp || undefined}
882
892
  aria-readonly={readOnly || undefined}
@@ -0,0 +1,34 @@
1
+ import { readdirSync, readFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { dirname, join } from "node:path";
4
+ import { describe, expect, it } from "vitest";
5
+ import { pickerNativeModules } from "./nativePickerLoader";
6
+
7
+ const nodeRequire = createRequire(import.meta.url);
8
+
9
+ /** Every native module name a package's build asks expo-modules-core for. */
10
+ function registeredNativeModules(pkg: string): string[] {
11
+ const build = join(dirname(nodeRequire.resolve(`${pkg}/package.json`)), "build");
12
+ const names = new Set<string>();
13
+ for (const file of readdirSync(build)) {
14
+ if (!file.endsWith(".js")) continue;
15
+ const source = readFileSync(join(build, file), "utf8");
16
+ for (const match of source.matchAll(/require(?:Optional)?NativeModule\(\s*['"]([^'"]+)['"]/g)) {
17
+ names.add(match[1]!);
18
+ }
19
+ }
20
+ return [...names];
21
+ }
22
+
23
+ // MPO-73: the probe runs before the require, so a name the package never
24
+ // registers makes the picker look absent and an image-only field opens the
25
+ // Files browser instead of the photo library.
26
+ describe("native picker probes", () => {
27
+ it("probe the name expo-image-picker registers", () => {
28
+ expect(registeredNativeModules("expo-image-picker")).toContain(pickerNativeModules.image);
29
+ });
30
+
31
+ it("probe the name expo-document-picker registers", () => {
32
+ expect(registeredNativeModules("expo-document-picker")).toContain(pickerNativeModules.document);
33
+ });
34
+ });
@@ -1,6 +1,15 @@
1
1
  export type DocumentPickerModule = typeof import("expo-document-picker");
2
2
  export type ImagePickerModule = typeof import("expo-image-picker");
3
3
 
4
+ /**
5
+ * The names each picker registers with expo-modules-core. expo-image-picker
6
+ * keeps its Exponent-era name (MPO-73).
7
+ */
8
+ export const pickerNativeModules = {
9
+ document: "ExpoDocumentPicker",
10
+ image: "ExponentImagePicker",
11
+ } as const;
12
+
4
13
  let cachedDocumentPicker: DocumentPickerModule | null | undefined;
5
14
  let cachedImagePicker: ImagePickerModule | null | undefined;
6
15
 
@@ -36,7 +45,7 @@ function hasNativeModule(name: string): boolean {
36
45
  export function loadDocumentPicker(): DocumentPickerModule | null {
37
46
  if (cachedDocumentPicker !== undefined) return cachedDocumentPicker;
38
47
  try {
39
- cachedDocumentPicker = hasNativeModule("ExpoDocumentPicker")
48
+ cachedDocumentPicker = hasNativeModule(pickerNativeModules.document)
40
49
  ? (require("expo-document-picker") as DocumentPickerModule)
41
50
  : null;
42
51
  } catch {
@@ -49,7 +58,7 @@ export function loadDocumentPicker(): DocumentPickerModule | null {
49
58
  export function loadImagePicker(): ImagePickerModule | null {
50
59
  if (cachedImagePicker !== undefined) return cachedImagePicker;
51
60
  try {
52
- cachedImagePicker = hasNativeModule("ExpoImagePicker")
61
+ cachedImagePicker = hasNativeModule(pickerNativeModules.image)
53
62
  ? (require("expo-image-picker") as ImagePickerModule)
54
63
  : null;
55
64
  } catch {
@@ -4,7 +4,8 @@ import { renderWithProviders } from "@multiplatform.one/test-utils";
4
4
  import { Form } from "../../Form";
5
5
  import { TableCellContext } from "../../shared/tableCellContext";
6
6
  import { Geolocation, preflightGeolocation } from "./index";
7
- import type { GeocodeResult } from "./geocoder";
7
+ import type { GeocodeResult, Geocoder } from "./geocoder";
8
+ import { GeocoderProvider } from "./geocoderContext";
8
9
  import { Theme } from "tamagui";
9
10
  import { NavigationArrowIcon } from "@phosphor-icons/react";
10
11
 
@@ -31,6 +32,15 @@ function searchInput(container: HTMLElement | Document = document) {
31
32
  container.querySelector("[aria-label='Search for a location']")) as HTMLInputElement | null;
32
33
  }
33
34
 
35
+ const mapControlSelector =
36
+ "button, input, textarea, select, [role='button'], [role='combobox'], [role='option'], [tabindex]";
37
+
38
+ function mapControls(container: HTMLElement): Element[] {
39
+ const map = container.querySelector("[data-testid='geolocation-map']");
40
+ expect(map).not.toBeNull();
41
+ return [...(map as HTMLElement).querySelectorAll(mapControlSelector)];
42
+ }
43
+
34
44
  function typeSearch(container: HTMLElement, text: string) {
35
45
  const input = searchInput(container);
36
46
  expect(input).not.toBeNull();
@@ -161,6 +171,35 @@ describe("Geolocation", () => {
161
171
  expect(result.container.querySelector("[data-testid='geolocation-coords-chip']")).toBeNull();
162
172
  });
163
173
 
174
+ it.each([
175
+ ["a set value", HELSINKI],
176
+ ["the empty state", ""],
177
+ ])("with %s, nothing interactive sits on the map; the controls live below it", (_, value) => {
178
+ const result = renderWithProviders(
179
+ <Geolocation
180
+ label="Location"
181
+ value={value}
182
+ geocode={mockGeocode()}
183
+ locationIcon={locationIcon}
184
+ expandIcon={<span data-testid="expand-icon" />}
185
+ />,
186
+ );
187
+ expect(mapControls(result.container)).toEqual([]);
188
+ const map = result.container.querySelector("[data-testid='geolocation-map']") as HTMLElement;
189
+ const footer = result.container.querySelector(
190
+ "[data-testid='geolocation-map-footer']",
191
+ ) as HTMLElement;
192
+ expect(footer).not.toBeNull();
193
+ expect(map.compareDocumentPosition(footer) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
194
+ const locate = footer.querySelector(
195
+ value ? "[aria-label='Locate']" : "[aria-label='Use my current location']",
196
+ );
197
+ expect(locate).not.toBeNull();
198
+ expect(locate?.textContent).toContain(value ? "Locate" : "Use my current location");
199
+ expect(footer.querySelector("[aria-label='Expand map']")).not.toBeNull();
200
+ expect(footer.querySelector("[data-testid='geolocation-coordline']")).not.toBeNull();
201
+ });
202
+
164
203
  it("without an injected geocoder, search is disabled and map/manual paths stay", () => {
165
204
  const result = renderWithProviders(
166
205
  <Geolocation label="Location" value={HELSINKI} locationIcon={locationIcon} />,
@@ -280,6 +319,37 @@ describe("Geolocation", () => {
280
319
  expect(onChange).toHaveBeenCalled();
281
320
  });
282
321
 
322
+ it("after a geocoder failure the coordinate editor still commits", async () => {
323
+ const geocode = vi.fn().mockRejectedValue(new Error("down"));
324
+ const onChange = vi.fn();
325
+ const result = renderWithProviders(
326
+ <Geolocation
327
+ label="Location"
328
+ geocode={geocode}
329
+ onChange={onChange}
330
+ locationIcon={locationIcon}
331
+ />,
332
+ );
333
+ typeSearch(result.container, "manner");
334
+ await waitFor(() => {
335
+ expect(document.body.textContent).toContain(
336
+ "Search is unavailable — check your connection",
337
+ );
338
+ });
339
+ fireEvent.keyDown(document, { key: "Escape" });
340
+ fireEvent.click(result.container.querySelector("[aria-label='Edit coordinates']") as Element);
341
+ const lat = await waitFor(() => {
342
+ const input = document.querySelector("input[aria-label='Latitude']");
343
+ expect(input).not.toBeNull();
344
+ return input as HTMLInputElement;
345
+ });
346
+ fireEvent.change(lat, { target: { value: "12.5" } });
347
+ await waitFor(() => {
348
+ expect(onChange).toHaveBeenCalledWith(JSON.stringify({ lat: 12.5, lng: 0 }));
349
+ });
350
+ expect(result.container.querySelector("[data-testid='geolocation-map']")).not.toBeNull();
351
+ });
352
+
283
353
  it("a typed lat, lng pair offers the exact point", async () => {
284
354
  const geocode = mockGeocode();
285
355
  const onChange = vi.fn();
@@ -573,6 +643,55 @@ describe("Geolocation", () => {
573
643
  });
574
644
  });
575
645
 
646
+ describe("GeocoderProvider", () => {
647
+ const provided: Geocoder = {
648
+ geocode: mockGeocode(),
649
+ reverseGeocode: mockReverse(),
650
+ };
651
+
652
+ it("hands its geocoder to a field that was given none", async () => {
653
+ const result = renderWithProviders(
654
+ <GeocoderProvider geocoder={provided}>
655
+ <Geolocation label="Location" value={HELSINKI} locationIcon={locationIcon} />
656
+ </GeocoderProvider>,
657
+ );
658
+ await waitFor(() => {
659
+ expect(searchInput(result.container)?.value).toBe(
660
+ "Mannerheimintie 3, Kamppi, Helsinki, Finland",
661
+ );
662
+ });
663
+ expect(searchInput(result.container)?.disabled).toBe(false);
664
+ typeSearch(result.container, "manner");
665
+ await waitFor(() => {
666
+ expect(provided.geocode).toHaveBeenCalledWith({ query: "manner" });
667
+ });
668
+ });
669
+
670
+ it("loses to the field's own props, and geocoder={null} opts out", async () => {
671
+ const own = mockReverse({ ...mannerheim, label: "Own provider", description: undefined });
672
+ const result = renderWithProviders(
673
+ <GeocoderProvider geocoder={provided}>
674
+ <Geolocation
675
+ label="Own"
676
+ value={HELSINKI}
677
+ reverseGeocode={own}
678
+ locationIcon={locationIcon}
679
+ />
680
+ <Geolocation label="None" value={HELSINKI} geocoder={null} locationIcon={locationIcon} />
681
+ </GeocoderProvider>,
682
+ );
683
+ const inputs = () =>
684
+ [
685
+ ...result.container.querySelectorAll("[data-testid='geolocation-search']"),
686
+ ] as HTMLInputElement[];
687
+ await waitFor(() => {
688
+ expect(inputs()[0].value).toBe("Own provider");
689
+ });
690
+ expect(inputs()[1].value).toBe("");
691
+ expect(inputs()[1].disabled).toBe(true);
692
+ });
693
+ });
694
+
576
695
  describe("geolocation pre-flight (LC-19 CAPABILITY-PREFLIGHT)", () => {
577
696
  afterEach(() => {
578
697
  vi.unstubAllGlobals();
@@ -628,7 +747,7 @@ describe("Geolocation", () => {
628
747
  const result = renderWithProviders(
629
748
  <Geolocation label="Location" name="loc" locationIcon={locationIcon} />,
630
749
  );
631
- const button = result.container.querySelector("[aria-label='Locate']");
750
+ const button = result.container.querySelector("[aria-label='Use my current location']");
632
751
  expect(button).not.toBeNull();
633
752
  fireEvent.click(button as Element);
634
753
  await waitFor(() => {
@@ -650,7 +769,9 @@ describe("Geolocation", () => {
650
769
  const result = renderWithProviders(
651
770
  <Geolocation label="Location" name="loc" locationIcon={locationIcon} />,
652
771
  );
653
- fireEvent.click(result.container.querySelector("[aria-label='Locate']") as Element);
772
+ fireEvent.click(
773
+ result.container.querySelector("[aria-label='Use my current location']") as Element,
774
+ );
654
775
  await waitFor(() => {
655
776
  expect(result.container.textContent).toContain("permission denied");
656
777
  });
@@ -681,7 +802,9 @@ describe("Geolocation", () => {
681
802
  const result = renderWithProviders(
682
803
  <Geolocation label="Location" name="loc" locationIcon={locationIcon} />,
683
804
  );
684
- fireEvent.click(result.container.querySelector("[aria-label='Locate']") as Element);
805
+ fireEvent.click(
806
+ result.container.querySelector("[aria-label='Use my current location']") as Element,
807
+ );
685
808
 
686
809
  await waitFor(() => {
687
810
  expect(
@@ -689,6 +812,7 @@ describe("Geolocation", () => {
689
812
  ).not.toBeNull();
690
813
  expect(result.container.textContent).toContain("timed out");
691
814
  });
815
+ expect(mapControls(result.container)).toEqual([]);
692
816
  const retry = result.container.querySelector("[aria-label='Retry location']");
693
817
  expect(retry).not.toBeNull();
694
818
  expect(getCurrentPosition).toHaveBeenCalledTimes(1);
@@ -797,3 +921,40 @@ describe("Geolocation", () => {
797
921
  });
798
922
  });
799
923
  });
924
+
925
+ describe("Geolocation search opens on intent, not on focus (MPO-360)", () => {
926
+ const resultsPanel = () => document.querySelector("[data-testid='geolocation-results']");
927
+
928
+ it("a focus alone, as a cell editor's focus-into-panel gives, leaves the results closed", async () => {
929
+ const result = renderWithProviders(
930
+ <Geolocation label="Location" geocode={mockGeocode()} locationIcon={locationIcon} />,
931
+ );
932
+ const input = searchInput(result.container) as HTMLInputElement;
933
+ input.focus();
934
+ fireEvent.focus(input);
935
+ await new Promise((resolve) => setTimeout(resolve, 50));
936
+ expect(resultsPanel()).toBeNull();
937
+ expect(input.getAttribute("aria-expanded")).toBe("false");
938
+ });
939
+
940
+ it("a press on the search still opens the results with Use my current location first", async () => {
941
+ const result = renderWithProviders(
942
+ <Geolocation label="Location" geocode={mockGeocode()} locationIcon={locationIcon} />,
943
+ );
944
+ fireEvent.click(searchInput(result.container) as HTMLInputElement);
945
+ await waitFor(() => expect(resultsPanel()).not.toBeNull());
946
+ expect((resultsPanel() as HTMLElement).firstElementChild?.getAttribute("data-testid")).toBe(
947
+ "geolocation-use-location",
948
+ );
949
+ });
950
+
951
+ it("ArrowDown on a focused search opens the results", async () => {
952
+ const result = renderWithProviders(
953
+ <Geolocation label="Location" geocode={mockGeocode()} locationIcon={locationIcon} />,
954
+ );
955
+ const input = searchInput(result.container) as HTMLInputElement;
956
+ input.focus();
957
+ fireEvent.keyDown(input, { key: "ArrowDown" });
958
+ await waitFor(() => expect(resultsPanel()).not.toBeNull());
959
+ });
960
+ });
@@ -10,7 +10,9 @@ import { Form } from "../../Form";
10
10
  import { TableCellContext } from "../../shared/tableCellContext";
11
11
  import { Geolocation, type GeolocationProps } from "./index";
12
12
  import type { GeocodeResult, Geocoder } from "./geocoder";
13
+ import { GeocoderProvider } from "./geocoderContext";
13
14
  import { parseGeoValue } from "./geoValue";
15
+ import { createPhotonGeocoder } from "./photonGeocoder";
14
16
 
15
17
  const meta: Meta<typeof Geolocation> = {
16
18
  title: "Forms/Geolocation",
@@ -19,7 +21,7 @@ const meta: Meta<typeof Geolocation> = {
19
21
  docs: {
20
22
  description: {
21
23
  component:
22
- "Search-first geolocation field. Inject `geocode` / `reverseGeocode` (or a `geocoder` object); No default provider is supplied. The map is the output; coordinates live below it as a mono disclosure. Locate is a labeled action. LC-19 preflight gates Locate. LC-21: no Apply on the coordinate editor.",
24
+ "Search-first geolocation field. Inject `geocode` / `reverseGeocode` (or a `geocoder` object), or wrap an app in `GeocoderProvider`; the field supplies no provider of its own. `createPhotonGeocoder()` is a keyless opt-in adapter (the Live stories use it). The map is the output and carries no controls: coordinates, Locate and Expand sit in a row below it. LC-19 preflight gates Locate. LC-21: no Apply on the coordinate editor.",
23
25
  },
24
26
  },
25
27
  },
@@ -71,7 +73,7 @@ export const Main: Story = {
71
73
  export const Standalone: Story = {
72
74
  args: {
73
75
  label: "Location",
74
- helperText: "Click the map to set a pin, or open the coordinate chip to type Lat/Lng",
76
+ helperText: "Click the map to set a pin, or edit the coordinates below it",
75
77
  },
76
78
  render: (args) => <Geolocation {...args} locationIcon={<NavigationArrowIcon size={16} />} />,
77
79
  };
@@ -92,7 +94,7 @@ export const Bare: Story = {
92
94
  export const Basic: Story = {
93
95
  args: {
94
96
  label: "Location",
95
- helperText: "Click the map to set a pin, or open the coordinate chip to type Lat/Lng",
97
+ helperText: "Click the map to set a pin, or edit the coordinates below it",
96
98
  onChange: action("onChange"),
97
99
  },
98
100
  render: (args) => <Geolocation {...args} locationIcon={<NavigationArrowIcon size={16} />} />,
@@ -120,7 +122,7 @@ export const Disabled: Story = {
120
122
  export const WithError: Story = {
121
123
  args: {
122
124
  label: "Location",
123
- helperText: "Click the map to set a pin, or open the coordinate chip to type Lat/Lng",
125
+ helperText: "Click the map to set a pin, or edit the coordinates below it",
124
126
  required: true,
125
127
  error: "Location is required",
126
128
  onChange: action("onChange"),
@@ -217,7 +219,7 @@ export const WithExpandButton: Story = {
217
219
  <YStack gap="$4" maxWidth={500}>
218
220
  <Geolocation
219
221
  label="Delivery Location"
220
- helperText="Click the expand button on the map for a larger view"
222
+ helperText="Press Expand below the map for a larger view"
221
223
  value={value}
222
224
  onChange={(v) => {
223
225
  setValue(v);
@@ -274,29 +276,31 @@ export const SkeletonState: Story = {
274
276
  type InTableRow = { id: string; label: string; value: { lat: number; lng: number } | "" };
275
277
 
276
278
  /** LC-06: Geolocation stays hosted in DataTable; the cell opens a modal. */
279
+ function InTableExample({ geocoder }: { geocoder?: Geocoder }) {
280
+ const [data, setData] = useState<InTableRow[]>([
281
+ { id: "1", label: "Alpha", value: { lat: 30.2672, lng: -97.7431 } },
282
+ { id: "2", label: "Beta", value: { lat: 48.8566, lng: 2.3522 } },
283
+ { id: "3", label: "Gamma", value: "" },
284
+ ]);
285
+ const columns: DataTableColumn<InTableRow>[] = [
286
+ { accessorKey: "label", header: "Row" },
287
+ {
288
+ accessorKey: "value",
289
+ header: "Location",
290
+ field: "geolocation",
291
+ fieldProps: { locationIcon: <NavigationArrowIcon size={16} />, geocoder },
292
+ },
293
+ ];
294
+ return (
295
+ <YStack width="100%" height={320}>
296
+ <DataTable data={data} columns={columns} enablePagination={false} onDataChange={setData} />
297
+ </YStack>
298
+ );
299
+ }
300
+
277
301
  export const InTable: Story = {
278
302
  name: "In table",
279
- render: () => {
280
- const [data, setData] = useState<InTableRow[]>([
281
- { id: "1", label: "Alpha", value: { lat: 30.2672, lng: -97.7431 } },
282
- { id: "2", label: "Beta", value: { lat: 48.8566, lng: 2.3522 } },
283
- { id: "3", label: "Gamma", value: "" },
284
- ]);
285
- const columns: DataTableColumn<InTableRow>[] = [
286
- { accessorKey: "label", header: "Row" },
287
- {
288
- accessorKey: "value",
289
- header: "Location",
290
- field: "geolocation",
291
- fieldProps: { locationIcon: <NavigationArrowIcon size={16} /> },
292
- },
293
- ];
294
- return (
295
- <YStack width="100%" height={320}>
296
- <DataTable data={data} columns={columns} enablePagination={false} onDataChange={setData} />
297
- </YStack>
298
- );
299
- },
303
+ render: () => <InTableExample />,
300
304
  };
301
305
 
302
306
  const places: GeocodeResult[] = [
@@ -347,6 +351,12 @@ export const FailedFakeProvider: Story = {
347
351
  render: (args) => <FakeProviderExample {...args} />,
348
352
  };
349
353
 
354
+ /** The table's cell editor with a live search: opening it must not open the results (MPO-360). */
355
+ export const InTableWithFakeProvider: Story = {
356
+ name: "In table with fake provider",
357
+ render: () => <InTableExample geocoder={fakeGeocoder} />,
358
+ };
359
+
350
360
  /** Direct cell contract, independent of the table adapter's display formatter. */
351
361
  export const CellWithFakeProvider: Story = {
352
362
  args: {
@@ -429,3 +439,77 @@ function PendingReverseExample() {
429
439
  export const PendingControlledReverse: Story = {
430
440
  render: () => <PendingReverseExample />,
431
441
  };
442
+
443
+ const photon = createPhotonGeocoder();
444
+
445
+ function LiveField(props: GeolocationProps) {
446
+ const [value, setValue] = useState(props.value ?? "");
447
+ return (
448
+ <Geolocation
449
+ {...props}
450
+ value={value}
451
+ onChange={(next) => {
452
+ setValue(next);
453
+ action("onChange")(next);
454
+ }}
455
+ />
456
+ );
457
+ }
458
+
459
+ /**
460
+ * Keyless live search through Photon (photon.komoot.io). Type a place name;
461
+ * the results panel lists real geocoded places. No key, no account.
462
+ */
463
+ export const LiveKeylessSearch: Story = {
464
+ render: () => (
465
+ <GeocoderProvider geocoder={photon}>
466
+ <YStack gap="$4" maxWidth={500}>
467
+ <LiveField label="Location" expandIcon={<ArrowsOutIcon size={16} />} />
468
+ </YStack>
469
+ </GeocoderProvider>
470
+ ),
471
+ };
472
+
473
+ /** A set value reverse-geocodes to an address, editable and read-only. */
474
+ export const LiveKeylessAddress: Story = {
475
+ render: () => (
476
+ <GeocoderProvider geocoder={photon}>
477
+ <YStack gap="$4" maxWidth={500}>
478
+ <LiveField label="Office" value={JSON.stringify({ lat: 60.16952, lng: 24.93545 })} />
479
+ <Geolocation
480
+ label="Office (read-only)"
481
+ value={JSON.stringify({ lat: 60.16952, lng: 24.93545 })}
482
+ readOnly
483
+ />
484
+ </YStack>
485
+ </GeocoderProvider>
486
+ ),
487
+ };
488
+
489
+ type LiveRow = { id: string; label: string; value: { lat: number; lng: number } | "" };
490
+
491
+ function LiveTable() {
492
+ const [data, setData] = useState<LiveRow[]>([
493
+ { id: "1", label: "Austin", value: { lat: 30.2672, lng: -97.7431 } },
494
+ { id: "2", label: "Paris", value: { lat: 48.8566, lng: 2.3522 } },
495
+ { id: "3", label: "Empty", value: "" },
496
+ ]);
497
+ const columns: DataTableColumn<LiveRow>[] = [
498
+ { accessorKey: "label", header: "Row" },
499
+ { accessorKey: "value", header: "Location", field: "geolocation" },
500
+ ];
501
+ return (
502
+ <YStack width="100%" height={320}>
503
+ <DataTable data={data} columns={columns} enablePagination={false} onDataChange={setData} />
504
+ </YStack>
505
+ );
506
+ }
507
+
508
+ /** The provider reaches fields a table renders: cell faces read as addresses. */
509
+ export const LiveKeylessInTable: Story = {
510
+ render: () => (
511
+ <GeocoderProvider geocoder={photon}>
512
+ <LiveTable />
513
+ </GeocoderProvider>
514
+ ),
515
+ };
@@ -87,6 +87,9 @@ export function GeolocationMap({
87
87
  key={`${zoom}-${tile.tx}-${tile.ty}-${Math.round(tile.left)}-${Math.round(tile.top)}`}
88
88
  alt=""
89
89
  draggable={false}
90
+ onError={(event) => {
91
+ event.currentTarget.style.visibility = "hidden";
92
+ }}
90
93
  src={tileSrc(zoom, tile.tx, tile.ty)}
91
94
  width={OSM_TILE_SIZE}
92
95
  height={OSM_TILE_SIZE}
@@ -0,0 +1,56 @@
1
+ import type { ReactNode } from "react";
2
+ import { createContext, useContext, useEffect, useState } from "react";
3
+ import type { Geocoder } from "./geocoder";
4
+ import { formatPlace } from "./geocoder";
5
+
6
+ const GeocoderContext = createContext<Geocoder | null>(null);
7
+
8
+ /**
9
+ * Hands one geocoder to every Geolocation field below it, including fields a
10
+ * registry or a table renders where the app cannot reach props. A field's own
11
+ * `geocode` / `reverseGeocode` / `geocoder` props win, and `geocoder={null}`
12
+ * opts a field out. Create the geocoder once (module scope or `useMemo`), not
13
+ * per render.
14
+ */
15
+ export function GeocoderProvider({
16
+ geocoder,
17
+ children,
18
+ }: {
19
+ geocoder: Geocoder | null;
20
+ children?: ReactNode;
21
+ }) {
22
+ return <GeocoderContext.Provider value={geocoder}>{children}</GeocoderContext.Provider>;
23
+ }
24
+
25
+ export function useGeocoder(): Geocoder | null {
26
+ return useContext(GeocoderContext);
27
+ }
28
+
29
+ /**
30
+ * The provider's address for a pair, or null while it resolves, when no
31
+ * provider is mounted, when nothing is near, or when the lookup fails. A
32
+ * read-only face shows the pair until this answers.
33
+ */
34
+ export function useReverseGeocodedLabel(pair: { lat: number; lng: number } | null): string | null {
35
+ const geocoder = useGeocoder();
36
+ const lat = pair?.lat;
37
+ const lng = pair?.lng;
38
+ const key = lat === undefined || lng === undefined ? null : `${lat},${lng}`;
39
+ const [resolved, setResolved] = useState<{ key: string; label: string } | null>(null);
40
+ useEffect(() => {
41
+ if (!geocoder || lat === undefined || lng === undefined || key === null) return;
42
+ let live = true;
43
+ geocoder.reverseGeocode({ lat, lng }).then(
44
+ (result) => {
45
+ if (live) setResolved(result ? { key, label: formatPlace(result) } : null);
46
+ },
47
+ () => {
48
+ if (live) setResolved(null);
49
+ },
50
+ );
51
+ return () => {
52
+ live = false;
53
+ };
54
+ }, [geocoder, key, lat, lng]);
55
+ return resolved && resolved.key === key ? resolved.label : null;
56
+ }