@multiplatform.one/forms 7.7.4 → 7.8.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 (579) hide show
  1. package/dist/cjs/Button/index.cjs +3 -36
  2. package/dist/cjs/Button/index.native.js +3 -36
  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/ContextualSaveBar/index.cjs +17 -10
  8. package/dist/cjs/ContextualSaveBar/index.native.js +18 -10
  9. package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
  10. package/dist/cjs/FloatingPanel/index.cjs +59 -14
  11. package/dist/cjs/FloatingPanel/index.native.js +16 -7
  12. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  13. package/dist/cjs/FloatingPanel/nestedAction.cjs +37 -0
  14. package/dist/cjs/FloatingPanel/nestedAction.native.js +42 -0
  15. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -0
  16. package/dist/cjs/InputParts/index.cjs +11 -7
  17. package/dist/cjs/InputParts/index.native.js +12 -10
  18. package/dist/cjs/InputParts/index.native.js.map +1 -1
  19. package/dist/cjs/Wheel/index.cjs +3 -3
  20. package/dist/cjs/Wheel/index.native.js +3 -3
  21. package/dist/cjs/Wheel/index.native.js.map +1 -1
  22. package/dist/cjs/fieldLayout.cjs +3 -3
  23. package/dist/cjs/fieldLayout.native.js +3 -3
  24. package/dist/cjs/fieldLayout.native.js.map +1 -1
  25. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.cjs +9 -2
  26. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  27. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  28. package/dist/cjs/fields/Combobox/index.cjs +74 -76
  29. package/dist/cjs/fields/Combobox/index.native.js +78 -86
  30. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  31. package/dist/cjs/fields/DatePicker/Calendar.cjs +6 -1
  32. package/dist/cjs/fields/DatePicker/Calendar.native.js +6 -1
  33. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  34. package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +2 -2
  35. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  36. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  37. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +15 -12
  38. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  39. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  40. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +39 -14
  41. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  42. package/dist/cjs/fields/DatePicker/MonthPicker.cjs +10 -3
  43. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +10 -3
  44. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  45. package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +2 -2
  46. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  47. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  48. package/dist/cjs/fields/DatePicker/index.native.js +3 -0
  49. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  50. package/dist/cjs/fields/DatePicker/parts.cjs +26 -14
  51. package/dist/cjs/fields/DatePicker/parts.native.js +28 -14
  52. package/dist/cjs/fields/DatePicker/parts.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 +14 -3
  64. package/dist/cjs/fields/Icon/drawnSet.native.js +18 -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/SearchInput/index.cjs +8 -9
  76. package/dist/cjs/fields/SearchInput/index.native.js +8 -9
  77. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  78. package/dist/cjs/fields/Select/index.cjs +53 -18
  79. package/dist/cjs/fields/Select/index.native.js +63 -37
  80. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  81. package/dist/cjs/fields/Stepper/index.cjs +144 -31
  82. package/dist/cjs/fields/Stepper/index.native.js +151 -31
  83. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  84. package/dist/cjs/index.cjs +2 -0
  85. package/dist/cjs/index.native.js +2 -0
  86. package/dist/cjs/index.native.js.map +1 -1
  87. package/dist/cjs/shared/focusManagement.cjs +24 -11
  88. package/dist/cjs/shared/focusManagement.native.js +24 -11
  89. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  90. package/dist/cjs/shared/pickerTriggerContract.cjs +38 -0
  91. package/dist/cjs/shared/pickerTriggerContract.native.js +41 -0
  92. package/dist/cjs/shared/pickerTriggerContract.native.js.map +1 -0
  93. package/dist/cjs/shared/pressSlopProps.cjs +68 -0
  94. package/dist/cjs/shared/pressSlopProps.native.js +72 -0
  95. package/dist/cjs/shared/pressSlopProps.native.js.map +1 -0
  96. package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
  97. package/dist/esm/Button/index.mjs +1 -34
  98. package/dist/esm/Button/index.mjs.map +1 -1
  99. package/dist/esm/Button/index.native.js +1 -34
  100. package/dist/esm/Button/index.native.js.map +1 -1
  101. package/dist/esm/Chip/index.mjs +1 -1
  102. package/dist/esm/Chip/index.mjs.map +1 -1
  103. package/dist/esm/Chip/index.native.js +1 -1
  104. package/dist/esm/Chip/index.native.js.map +1 -1
  105. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  106. package/dist/esm/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  107. package/dist/esm/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  108. package/dist/esm/ContextualSaveBar/index.mjs +17 -10
  109. package/dist/esm/ContextualSaveBar/index.mjs.map +1 -1
  110. package/dist/esm/ContextualSaveBar/index.native.js +18 -10
  111. package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
  112. package/dist/esm/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  113. package/dist/esm/ControlGroup/index.native.js.map +1 -1
  114. package/dist/esm/DescriptionList/index.native.js.map +1 -1
  115. package/dist/esm/ErrorSummary.native.js.map +1 -1
  116. package/dist/esm/FieldDisplay/editMode.native.js.map +1 -1
  117. package/dist/esm/FieldDisplay/formatters.native.js.map +1 -1
  118. package/dist/esm/FieldDisplay/index.native.js.map +1 -1
  119. package/dist/esm/FieldGroup.native.js.map +1 -1
  120. package/dist/esm/FloatingPanel/index.mjs +58 -15
  121. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  122. package/dist/esm/FloatingPanel/index.native.js +15 -8
  123. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  124. package/dist/esm/FloatingPanel/nestedAction.mjs +11 -0
  125. package/dist/esm/FloatingPanel/nestedAction.mjs.map +1 -0
  126. package/dist/esm/FloatingPanel/nestedAction.native.js +13 -0
  127. package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -0
  128. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  129. package/dist/esm/Form/index.native.js.map +1 -1
  130. package/dist/esm/Form/validateOn.native.js.map +1 -1
  131. package/dist/esm/FormGrid.native.js.map +1 -1
  132. package/dist/esm/FormSection.native.js.map +1 -1
  133. package/dist/esm/InputParts/index.mjs +12 -8
  134. package/dist/esm/InputParts/index.mjs.map +1 -1
  135. package/dist/esm/InputParts/index.native.js +13 -11
  136. package/dist/esm/InputParts/index.native.js.map +1 -1
  137. package/dist/esm/Label/index.native.js.map +1 -1
  138. package/dist/esm/Skeleton/index.native.js.map +1 -1
  139. package/dist/esm/Spinner/SpinnerGlyph.native.js.map +1 -1
  140. package/dist/esm/Spinner/spinnerSize.native.js.map +1 -1
  141. package/dist/esm/Table/index.native.js.map +1 -1
  142. package/dist/esm/Wheel/haptic.native.js.map +1 -1
  143. package/dist/esm/Wheel/index.mjs +3 -3
  144. package/dist/esm/Wheel/index.mjs.map +1 -1
  145. package/dist/esm/Wheel/index.native.js +3 -3
  146. package/dist/esm/Wheel/index.native.js.map +1 -1
  147. package/dist/esm/actionLabel.native.js.map +1 -1
  148. package/dist/esm/fieldDefaults.native.js.map +1 -1
  149. package/dist/esm/fieldLayout.mjs +3 -3
  150. package/dist/esm/fieldLayout.mjs.map +1 -1
  151. package/dist/esm/fieldLayout.native.js +3 -3
  152. package/dist/esm/fieldLayout.native.js.map +1 -1
  153. package/dist/esm/fields/Barcode/BarcodePreview.native.js.map +1 -1
  154. package/dist/esm/fields/Barcode/code128.native.js.map +1 -1
  155. package/dist/esm/fields/Barcode/index.native.js.map +1 -1
  156. package/dist/esm/fields/Barcode/qr.native.js.map +1 -1
  157. package/dist/esm/fields/Barcode/scannerTypes.native.js.map +1 -1
  158. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  159. package/dist/esm/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  160. package/dist/esm/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  161. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  162. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  163. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  164. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  165. package/dist/esm/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  166. package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  167. package/dist/esm/fields/Checkbox/index.native.js.map +1 -1
  168. package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
  169. package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
  170. package/dist/esm/fields/Combobox/authorOptions.native.js.map +1 -1
  171. package/dist/esm/fields/Combobox/index.mjs +74 -76
  172. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  173. package/dist/esm/fields/Combobox/index.native.js +78 -86
  174. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  175. package/dist/esm/fields/DatePicker/Calendar.mjs +6 -1
  176. package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
  177. package/dist/esm/fields/DatePicker/Calendar.native.js +6 -1
  178. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  179. package/dist/esm/fields/DatePicker/DateRangePicker.mjs +2 -2
  180. package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  181. package/dist/esm/fields/DatePicker/DateRangePicker.native.js +2 -2
  182. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  183. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  184. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  185. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  186. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  187. package/dist/esm/fields/DatePicker/DatetimePicker.native.js +39 -14
  188. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  189. package/dist/esm/fields/DatePicker/MonthPicker.mjs +10 -3
  190. package/dist/esm/fields/DatePicker/MonthPicker.mjs.map +1 -1
  191. package/dist/esm/fields/DatePicker/MonthPicker.native.js +10 -3
  192. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  193. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +2 -2
  194. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  195. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +2 -2
  196. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  197. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
  198. package/dist/esm/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  199. package/dist/esm/fields/DatePicker/index.native.js +3 -0
  200. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  201. package/dist/esm/fields/DatePicker/parts.mjs +28 -16
  202. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  203. package/dist/esm/fields/DatePicker/parts.native.js +30 -16
  204. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  205. package/dist/esm/fields/DatePicker/utils.native.js.map +1 -1
  206. package/dist/esm/fields/Duration/durationMath.native.js.map +1 -1
  207. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  208. package/dist/esm/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  209. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  210. package/dist/esm/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  211. package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  212. package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  213. package/dist/esm/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  214. package/dist/esm/fields/Geolocation/geoValue.native.js.map +1 -1
  215. package/dist/esm/fields/Geolocation/geocoder.mjs +33 -0
  216. package/dist/esm/fields/Geolocation/geocoder.mjs.map +1 -0
  217. package/dist/esm/fields/Geolocation/geocoder.native.js +35 -0
  218. package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -0
  219. package/dist/esm/fields/Geolocation/index.mjs +792 -149
  220. package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
  221. package/dist/esm/fields/Geolocation/index.native.js +847 -164
  222. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  223. package/dist/esm/fields/Geolocation/mapMath.native.js.map +1 -1
  224. package/dist/esm/fields/Geolocation/mapTypes.native.js.map +1 -1
  225. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  226. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  227. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js +19 -0
  228. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  229. package/dist/esm/fields/Icon/drawnSet.mjs +14 -3
  230. package/dist/esm/fields/Icon/drawnSet.mjs.map +1 -1
  231. package/dist/esm/fields/Icon/drawnSet.native.js +18 -3
  232. package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
  233. package/dist/esm/fields/Icon/index.mjs +93 -18
  234. package/dist/esm/fields/Icon/index.mjs.map +1 -1
  235. package/dist/esm/fields/Icon/index.native.js +106 -22
  236. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  237. package/dist/esm/fields/ImageField/index.native.js.map +1 -1
  238. package/dist/esm/fields/Input/index.mjs +5 -12
  239. package/dist/esm/fields/Input/index.mjs.map +1 -1
  240. package/dist/esm/fields/Input/index.native.js +5 -13
  241. package/dist/esm/fields/Input/index.native.js.map +1 -1
  242. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  243. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  244. package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
  245. package/dist/esm/fields/PhoneInput/dialCodes.native.js.map +1 -1
  246. package/dist/esm/fields/PhoneInput/index.mjs +2 -2
  247. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  248. package/dist/esm/fields/PhoneInput/index.native.js +2 -2
  249. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  250. package/dist/esm/fields/PhoneInput/phone.native.js.map +1 -1
  251. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  252. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  253. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  254. package/dist/esm/fields/Rating/ratingMath.native.js.map +1 -1
  255. package/dist/esm/fields/Rating/types.native.js.map +1 -1
  256. package/dist/esm/fields/SearchInput/index.mjs +9 -10
  257. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  258. package/dist/esm/fields/SearchInput/index.native.js +9 -10
  259. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  260. package/dist/esm/fields/Select/index.mjs +54 -19
  261. package/dist/esm/fields/Select/index.mjs.map +1 -1
  262. package/dist/esm/fields/Select/index.native.js +64 -38
  263. package/dist/esm/fields/Select/index.native.js.map +1 -1
  264. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  265. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  266. package/dist/esm/fields/Slider/jumpMotion.native.js.map +1 -1
  267. package/dist/esm/fields/Stepper/index.mjs +145 -32
  268. package/dist/esm/fields/Stepper/index.mjs.map +1 -1
  269. package/dist/esm/fields/Stepper/index.native.js +152 -32
  270. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  271. package/dist/esm/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  272. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  273. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  274. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  275. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  276. package/dist/esm/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  277. package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
  278. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  279. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  280. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  281. package/dist/esm/fields/nativeSelect.native.js.map +1 -1
  282. package/dist/esm/fields/selectedOrder.native.js.map +1 -1
  283. package/dist/esm/formSpacing.native.js.map +1 -1
  284. package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
  285. package/dist/esm/index.mjs +2 -1
  286. package/dist/esm/index.mjs.map +1 -1
  287. package/dist/esm/index.native.js +2 -1
  288. package/dist/esm/index.native.js.map +1 -1
  289. package/dist/esm/requiredMarking.native.js.map +1 -1
  290. package/dist/esm/shared/TimeColumn.native.js.map +1 -1
  291. package/dist/esm/shared/capabilityPreflight.native.js.map +1 -1
  292. package/dist/esm/shared/colorRamps.native.js.map +1 -1
  293. package/dist/esm/shared/devWarn.native.js.map +1 -1
  294. package/dist/esm/shared/floatingList.native.js.map +1 -1
  295. package/dist/esm/shared/focusManagement.mjs +24 -11
  296. package/dist/esm/shared/focusManagement.mjs.map +1 -1
  297. package/dist/esm/shared/focusManagement.native.js +24 -11
  298. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  299. package/dist/esm/shared/groupContext.native.js.map +1 -1
  300. package/dist/esm/shared/i18n.native.js.map +1 -1
  301. package/dist/esm/shared/pickerTriggerContract.mjs +13 -0
  302. package/dist/esm/shared/pickerTriggerContract.mjs.map +1 -0
  303. package/dist/esm/shared/pickerTriggerContract.native.js +13 -0
  304. package/dist/esm/shared/pickerTriggerContract.native.js.map +1 -0
  305. package/dist/esm/shared/pressSlopProps.mjs +43 -0
  306. package/dist/esm/shared/pressSlopProps.mjs.map +1 -0
  307. package/dist/esm/shared/pressSlopProps.native.js +44 -0
  308. package/dist/esm/shared/pressSlopProps.native.js.map +1 -0
  309. package/dist/esm/shared/t.native.js.map +1 -1
  310. package/dist/esm/shared/tableCellContext.native.js.map +1 -1
  311. package/dist/esm/shared/useDragScroll.native.js.map +1 -1
  312. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  313. package/dist/esm/shared/useSheetEscapeDismiss.native.js.map +1 -1
  314. package/dist/esm/shared/useWheelIncrement.native.js.map +1 -1
  315. package/dist/esm/shared/utils.native.js.map +1 -1
  316. package/dist/esm/shared/zIndex.native.js.map +1 -1
  317. package/dist/esm/themedPrimitives.native.js.map +1 -1
  318. package/dist/esm/types.native.js.map +1 -1
  319. package/dist/esm/utils/LinkCell.native.js.map +1 -1
  320. package/dist/jsx/Button/index.mjs +1 -34
  321. package/dist/jsx/Button/index.mjs.map +1 -1
  322. package/dist/jsx/Button/index.native.js +3 -36
  323. package/dist/jsx/Button/index.native.js.map +1 -1
  324. package/dist/jsx/Chip/index.mjs +1 -1
  325. package/dist/jsx/Chip/index.mjs.map +1 -1
  326. package/dist/jsx/Chip/index.native.js +1 -1
  327. package/dist/jsx/Chip/index.native.js.map +1 -1
  328. package/dist/jsx/ContextualSaveBar/index.mjs +17 -10
  329. package/dist/jsx/ContextualSaveBar/index.mjs.map +1 -1
  330. package/dist/jsx/ContextualSaveBar/index.native.js +18 -10
  331. package/dist/jsx/ContextualSaveBar/index.native.js.map +1 -1
  332. package/dist/jsx/FloatingPanel/index.mjs +58 -15
  333. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  334. package/dist/jsx/FloatingPanel/index.native.js +16 -7
  335. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  336. package/dist/jsx/FloatingPanel/nestedAction.mjs +11 -0
  337. package/dist/jsx/FloatingPanel/nestedAction.mjs.map +1 -0
  338. package/dist/jsx/FloatingPanel/nestedAction.native.js +42 -0
  339. package/dist/jsx/FloatingPanel/nestedAction.native.js.map +1 -0
  340. package/dist/jsx/InputParts/index.mjs +12 -8
  341. package/dist/jsx/InputParts/index.mjs.map +1 -1
  342. package/dist/jsx/InputParts/index.native.js +12 -10
  343. package/dist/jsx/InputParts/index.native.js.map +1 -1
  344. package/dist/jsx/Wheel/index.mjs +3 -3
  345. package/dist/jsx/Wheel/index.mjs.map +1 -1
  346. package/dist/jsx/Wheel/index.native.js +3 -3
  347. package/dist/jsx/Wheel/index.native.js.map +1 -1
  348. package/dist/jsx/fieldLayout.mjs +3 -3
  349. package/dist/jsx/fieldLayout.mjs.map +1 -1
  350. package/dist/jsx/fieldLayout.native.js +3 -3
  351. package/dist/jsx/fieldLayout.native.js.map +1 -1
  352. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  353. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  354. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  355. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  356. package/dist/jsx/fields/Combobox/index.mjs +74 -76
  357. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  358. package/dist/jsx/fields/Combobox/index.native.js +78 -86
  359. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  360. package/dist/jsx/fields/DatePicker/Calendar.mjs +6 -1
  361. package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
  362. package/dist/jsx/fields/DatePicker/Calendar.native.js +6 -1
  363. package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
  364. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +2 -2
  365. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  366. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +2 -2
  367. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  368. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  369. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  370. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  371. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  372. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +39 -14
  373. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  374. package/dist/jsx/fields/DatePicker/MonthPicker.mjs +10 -3
  375. package/dist/jsx/fields/DatePicker/MonthPicker.mjs.map +1 -1
  376. package/dist/jsx/fields/DatePicker/MonthPicker.native.js +10 -3
  377. package/dist/jsx/fields/DatePicker/MonthPicker.native.js.map +1 -1
  378. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +2 -2
  379. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  380. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +2 -2
  381. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  382. package/dist/jsx/fields/DatePicker/index.native.js +3 -0
  383. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  384. package/dist/jsx/fields/DatePicker/parts.mjs +28 -16
  385. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  386. package/dist/jsx/fields/DatePicker/parts.native.js +28 -14
  387. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  388. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  389. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  390. package/dist/jsx/fields/Geolocation/geocoder.mjs +33 -0
  391. package/dist/jsx/fields/Geolocation/geocoder.mjs.map +1 -0
  392. package/dist/jsx/fields/Geolocation/geocoder.native.js +68 -0
  393. package/dist/jsx/fields/Geolocation/geocoder.native.js.map +1 -0
  394. package/dist/jsx/fields/Geolocation/index.mjs +792 -149
  395. package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
  396. package/dist/jsx/fields/Geolocation/index.native.js +856 -167
  397. package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
  398. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  399. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  400. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  401. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  402. package/dist/jsx/fields/Icon/drawnSet.mjs +14 -3
  403. package/dist/jsx/fields/Icon/drawnSet.mjs.map +1 -1
  404. package/dist/jsx/fields/Icon/drawnSet.native.js +18 -3
  405. package/dist/jsx/fields/Icon/drawnSet.native.js.map +1 -1
  406. package/dist/jsx/fields/Icon/index.mjs +93 -18
  407. package/dist/jsx/fields/Icon/index.mjs.map +1 -1
  408. package/dist/jsx/fields/Icon/index.native.js +115 -31
  409. package/dist/jsx/fields/Icon/index.native.js.map +1 -1
  410. package/dist/jsx/fields/Input/index.mjs +5 -12
  411. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  412. package/dist/jsx/fields/Input/index.native.js +5 -13
  413. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  414. package/dist/jsx/fields/PhoneInput/index.mjs +2 -2
  415. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  416. package/dist/jsx/fields/PhoneInput/index.native.js +2 -2
  417. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  418. package/dist/jsx/fields/SearchInput/index.mjs +9 -10
  419. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  420. package/dist/jsx/fields/SearchInput/index.native.js +8 -9
  421. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  422. package/dist/jsx/fields/Select/index.mjs +54 -19
  423. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  424. package/dist/jsx/fields/Select/index.native.js +63 -37
  425. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  426. package/dist/jsx/fields/Stepper/index.mjs +145 -32
  427. package/dist/jsx/fields/Stepper/index.mjs.map +1 -1
  428. package/dist/jsx/fields/Stepper/index.native.js +151 -31
  429. package/dist/jsx/fields/Stepper/index.native.js.map +1 -1
  430. package/dist/jsx/index.js +2 -1
  431. package/dist/jsx/index.js.map +1 -1
  432. package/dist/jsx/index.mjs +2 -1
  433. package/dist/jsx/index.mjs.map +1 -1
  434. package/dist/jsx/index.native.js +2 -0
  435. package/dist/jsx/index.native.js.map +1 -1
  436. package/dist/jsx/shared/focusManagement.mjs +24 -11
  437. package/dist/jsx/shared/focusManagement.mjs.map +1 -1
  438. package/dist/jsx/shared/focusManagement.native.js +24 -11
  439. package/dist/jsx/shared/focusManagement.native.js.map +1 -1
  440. package/dist/jsx/shared/pickerTriggerContract.mjs +13 -0
  441. package/dist/jsx/shared/pickerTriggerContract.mjs.map +1 -0
  442. package/dist/jsx/shared/pickerTriggerContract.native.js +41 -0
  443. package/dist/jsx/shared/pickerTriggerContract.native.js.map +1 -0
  444. package/dist/jsx/shared/pressSlopProps.mjs +43 -0
  445. package/dist/jsx/shared/pressSlopProps.mjs.map +1 -0
  446. package/dist/jsx/shared/pressSlopProps.native.js +72 -0
  447. package/dist/jsx/shared/pressSlopProps.native.js.map +1 -0
  448. package/package.json +8 -7
  449. package/src/Button/Button.labelInk.spec.tsx +21 -18
  450. package/src/Button/Button.outlinedChannel.spec.tsx +46 -0
  451. package/src/Button/Button.sizeLadder.spec.tsx +4 -3
  452. package/src/Button/Button.stories.tsx +20 -0
  453. package/src/Button/index.tsx +26 -39
  454. package/src/Chip/Chip.spec.tsx +3 -1
  455. package/src/Chip/index.tsx +1 -5
  456. package/src/ContextualSaveBar/ContextualSaveBar.spec.tsx +33 -0
  457. package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +19 -0
  458. package/src/ContextualSaveBar/index.tsx +12 -8
  459. package/src/ContextualSaveBar/nativeFlow.spec.tsx +20 -0
  460. package/src/FieldLayout.stories.tsx +41 -0
  461. package/src/FloatingPanel/FloatingPanel.native.spec.tsx +54 -0
  462. package/src/FloatingPanel/FloatingPanel.spec.tsx +109 -0
  463. package/src/FloatingPanel/index.native.tsx +24 -7
  464. package/src/FloatingPanel/index.tsx +80 -13
  465. package/src/FloatingPanel/nestedAction.spec.ts +36 -0
  466. package/src/FloatingPanel/nestedAction.ts +15 -0
  467. package/src/FloatingPanel/panelWidthContract.spec.ts +12 -15
  468. package/src/FormsIntegration.stories.tsx +2 -6
  469. package/src/InputParts/index.tsx +20 -6
  470. package/src/InputParts/layoutGap.spec.tsx +43 -0
  471. package/src/Wheel/Wheel.spec.tsx +16 -0
  472. package/src/Wheel/index.tsx +3 -3
  473. package/src/fieldLayout.spec.tsx +42 -1
  474. package/src/fieldLayout.tsx +9 -9
  475. package/src/fields/Checkbox/CheckboxFieldFrame.spec.tsx +18 -0
  476. package/src/fields/Checkbox/CheckboxFieldFrame.tsx +6 -1
  477. package/src/fields/Combobox/Combobox.spec.tsx +48 -1
  478. package/src/fields/Combobox/index.tsx +90 -80
  479. package/src/fields/DatePicker/Calendar.tsx +4 -1
  480. package/src/fields/DatePicker/DatePicker.stories.tsx +22 -1
  481. package/src/fields/DatePicker/DateRangePicker.tsx +4 -2
  482. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +21 -19
  483. package/src/fields/DatePicker/DatetimePicker.native.spec.tsx +144 -0
  484. package/src/fields/DatePicker/DatetimePicker.native.tsx +57 -32
  485. package/src/fields/DatePicker/DatetimePicker.stories.tsx +22 -0
  486. package/src/fields/DatePicker/MonthPicker.tsx +8 -3
  487. package/src/fields/DatePicker/MultiDatePicker.tsx +4 -2
  488. package/src/fields/DatePicker/index.native.tsx +1 -0
  489. package/src/fields/DatePicker/parts.spec.tsx +56 -0
  490. package/src/fields/DatePicker/parts.tsx +33 -12
  491. package/src/fields/Geolocation/Geolocation.spec.tsx +287 -35
  492. package/src/fields/Geolocation/Geolocation.stories.tsx +141 -7
  493. package/src/fields/Geolocation/GeolocationMap.native.tsx +3 -0
  494. package/src/fields/Geolocation/GeolocationMap.tsx +4 -0
  495. package/src/fields/Geolocation/geocoder.spec.ts +59 -0
  496. package/src/fields/Geolocation/geocoder.ts +84 -0
  497. package/src/fields/Geolocation/geocoderSeam.spec.tsx +203 -0
  498. package/src/fields/Geolocation/index.tsx +912 -180
  499. package/src/fields/Geolocation/nativeSearchFocus.spec.ts +34 -0
  500. package/src/fields/Geolocation/nativeSearchFocus.ts +19 -0
  501. package/src/fields/Geolocation/salvage.spec.tsx +398 -0
  502. package/src/fields/Geolocation/storyProviders.spec.tsx +44 -0
  503. package/src/fields/Icon/Icon.spec.tsx +215 -1
  504. package/src/fields/Icon/Icon.stories.tsx +9 -1
  505. package/src/fields/Icon/drawnSet.tsx +39 -4
  506. package/src/fields/Icon/index.tsx +118 -18
  507. package/src/fields/Input/Input.copy.spec.tsx +1 -0
  508. package/src/fields/Input/Input.spec.tsx +50 -0
  509. package/src/fields/Input/Input.stories.tsx +1 -1
  510. package/src/fields/Input/index.tsx +7 -13
  511. package/src/fields/PhoneInput/index.tsx +2 -2
  512. package/src/fields/SearchInput/SearchInput.spec.tsx +14 -0
  513. package/src/fields/SearchInput/index.tsx +5 -6
  514. package/src/fields/Select/Select.spec.tsx +54 -0
  515. package/src/fields/Select/index.tsx +63 -33
  516. package/src/fields/Stepper/Stepper.spec.tsx +34 -1
  517. package/src/fields/Stepper/index.tsx +193 -33
  518. package/src/fields/pickerActivation.spec.tsx +105 -0
  519. package/src/fields/pickerDensity.spec.tsx +86 -0
  520. package/src/fields/pickerRows.spec.tsx +66 -0
  521. package/src/index.ts +9 -0
  522. package/src/shared/focusManagement.spec.tsx +68 -0
  523. package/src/shared/focusManagement.ts +20 -10
  524. package/src/shared/pickerTriggerContract.ts +13 -0
  525. package/src/shared/pressSlopProps.spec.ts +39 -0
  526. package/src/shared/pressSlopProps.ts +52 -0
  527. package/types/Button/index.d.ts +22 -3
  528. package/types/Button/index.d.ts.map +1 -1
  529. package/types/Chip/index.d.ts.map +1 -1
  530. package/types/ContextualSaveBar/index.d.ts +1 -1
  531. package/types/ContextualSaveBar/index.d.ts.map +1 -1
  532. package/types/FloatingPanel/index.d.ts +11 -1
  533. package/types/FloatingPanel/index.d.ts.map +1 -1
  534. package/types/FloatingPanel/index.native.d.ts +2 -1
  535. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  536. package/types/FloatingPanel/nestedAction.d.ts +13 -0
  537. package/types/FloatingPanel/nestedAction.d.ts.map +1 -0
  538. package/types/InputParts/index.d.ts.map +1 -1
  539. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts +46 -2
  540. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts.map +1 -1
  541. package/types/fields/Checkbox/index.d.ts +3 -3
  542. package/types/fields/Combobox/index.d.ts +3 -1
  543. package/types/fields/Combobox/index.d.ts.map +1 -1
  544. package/types/fields/DatePicker/Calendar.d.ts.map +1 -1
  545. package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
  546. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
  547. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
  548. package/types/fields/DatePicker/MonthPicker.d.ts.map +1 -1
  549. package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
  550. package/types/fields/DatePicker/index.native.d.ts.map +1 -1
  551. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  552. package/types/fields/Geolocation/GeolocationMap.d.ts +4 -0
  553. package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
  554. package/types/fields/Geolocation/GeolocationMap.native.d.ts +3 -0
  555. package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
  556. package/types/fields/Geolocation/geocoder.d.ts +53 -0
  557. package/types/fields/Geolocation/geocoder.d.ts.map +1 -0
  558. package/types/fields/Geolocation/index.d.ts +18 -2
  559. package/types/fields/Geolocation/index.d.ts.map +1 -1
  560. package/types/fields/Geolocation/nativeSearchFocus.d.ts +8 -0
  561. package/types/fields/Geolocation/nativeSearchFocus.d.ts.map +1 -0
  562. package/types/fields/Icon/drawnSet.d.ts.map +1 -1
  563. package/types/fields/Icon/index.d.ts.map +1 -1
  564. package/types/fields/Input/index.d.ts.map +1 -1
  565. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  566. package/types/fields/RadioGroup/index.d.ts +2 -2
  567. package/types/fields/SearchInput/index.d.ts.map +1 -1
  568. package/types/fields/Select/index.d.ts.map +1 -1
  569. package/types/fields/Stepper/index.d.ts.map +1 -1
  570. package/types/fields/ToggleGroup/index.d.ts +1 -1
  571. package/types/index.d.ts +2 -0
  572. package/types/index.d.ts.map +1 -1
  573. package/types/shared/focusManagement.d.ts +2 -2
  574. package/types/shared/focusManagement.d.ts.map +1 -1
  575. package/types/shared/pickerTriggerContract.d.ts +18 -0
  576. package/types/shared/pickerTriggerContract.d.ts.map +1 -0
  577. package/types/shared/pressSlopProps.d.ts +8 -0
  578. package/types/shared/pressSlopProps.d.ts.map +1 -0
  579. package/src/router.d.ts +0 -16
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createNativeSearchFocus } from "./nativeSearchFocus";
3
+
4
+ describe("native search focus ownership", () => {
5
+ it("keeps delayed outer and header return focus closed after a selection or dismissal", () => {
6
+ const focus = createNativeSearchFocus();
7
+ expect(focus.canOpen(false)).toBe(true);
8
+ focus.dismiss();
9
+ expect(focus.canOpen(false)).toBe(false);
10
+ expect(focus.canOpen(true)).toBe(false);
11
+ expect(focus.canOpen(false)).toBe(false);
12
+ });
13
+
14
+ it.each(["press", "text change", "accessibility activation"])(
15
+ "permits deliberate %s after dismissal, even when the input never blurred",
16
+ () => {
17
+ const focus = createNativeSearchFocus();
18
+ focus.dismiss();
19
+ focus.activate();
20
+ expect(focus.canOpen(false)).toBe(true);
21
+ },
22
+ );
23
+
24
+ it("preserves suppression across modal blur but permits a later hardware focus visit", () => {
25
+ const focus = createNativeSearchFocus();
26
+ focus.dismiss();
27
+ focus.blur(true, false);
28
+ focus.blur(false, true);
29
+ expect(focus.canOpen(false)).toBe(false);
30
+ focus.blur(false, false);
31
+ expect(focus.canOpen(false)).toBe(true);
32
+ expect(focus.canOpen(true)).toBe(false);
33
+ });
34
+ });
@@ -0,0 +1,19 @@
1
+ /** Modal return focus must not reopen a dismissed native search. */
2
+ export function createNativeSearchFocus() {
3
+ let dismissed = false;
4
+ return {
5
+ dismiss() {
6
+ dismissed = true;
7
+ },
8
+ activate() {
9
+ dismissed = false;
10
+ },
11
+ blur(sheetHeader: boolean, resultsOpen: boolean) {
12
+ // A later visit by hardware keyboard is deliberate. Modal handoff is not.
13
+ if (!sheetHeader && !resultsOpen) dismissed = false;
14
+ },
15
+ canOpen(sheetHeader: boolean) {
16
+ return !sheetHeader && !dismissed;
17
+ },
18
+ };
19
+ }
@@ -0,0 +1,398 @@
1
+ import { useState } from "react";
2
+ import { act, fireEvent, waitFor } from "@testing-library/react";
3
+ import { afterEach, describe, expect, it, vi } from "vitest";
4
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
5
+ import { Geolocation, type GeolocationProps } from "./index";
6
+ import { TableCellContext } from "../../shared/tableCellContext";
7
+ import type { GeocodeResult } from "./geocoder";
8
+
9
+ const place = { lat: 60.16952, lng: 24.93545, label: "Helsinki" };
10
+ const sydney = { lat: -33.8688, lng: 151.2093, label: "Sydney" };
11
+ const helsinkiValue = JSON.stringify({ lat: place.lat, lng: place.lng });
12
+ const sydneyValue = JSON.stringify({ lat: sydney.lat, lng: sydney.lng });
13
+ const boundMap = ({ lat, lng }: { lat: number; lng: number }) => (
14
+ <span data-testid="bound-map">{`${lat},${lng}`}</span>
15
+ );
16
+ const original = JSON.stringify({
17
+ type: "FeatureCollection",
18
+ features: [
19
+ {
20
+ type: "Feature",
21
+ properties: { point_type: "circle", radius: 10 },
22
+ geometry: { type: "Point", coordinates: [20, 10] },
23
+ },
24
+ {
25
+ type: "Feature",
26
+ properties: { name: "route" },
27
+ geometry: {
28
+ type: "LineString",
29
+ coordinates: [
30
+ [1, 2],
31
+ [3, 4],
32
+ ],
33
+ },
34
+ },
35
+ ],
36
+ });
37
+
38
+ function input(container: HTMLElement) {
39
+ return container.querySelector("[aria-label='Search for a location']") as HTMLInputElement;
40
+ }
41
+ function deferred<T>() {
42
+ let resolve!: (value: T) => void;
43
+ const promise = new Promise<T>((done) => {
44
+ resolve = done;
45
+ });
46
+ return { promise, resolve };
47
+ }
48
+ function Controlled(props: GeolocationProps) {
49
+ const [value, setValue] = useState(props.value ?? "");
50
+ return (
51
+ <Geolocation
52
+ {...props}
53
+ value={value}
54
+ onChange={(next) => {
55
+ setValue(next);
56
+ props.onChange?.(next);
57
+ }}
58
+ renderMap={({ lat, lng }) => (
59
+ <span data-testid="map-center">
60
+ {lat},{lng}
61
+ </span>
62
+ )}
63
+ />
64
+ );
65
+ }
66
+
67
+ describe("Geolocation salvage regressions", () => {
68
+ afterEach(() => vi.unstubAllGlobals());
69
+ it.each([false, true])(
70
+ "does not display a rejected controlled pick as fact (cell=%s)",
71
+ async (cell) => {
72
+ const onChange = vi.fn();
73
+ const props = {
74
+ value: helsinkiValue,
75
+ geocode: async () => [sydney],
76
+ onChange,
77
+ renderMap: boundMap,
78
+ };
79
+ const result = renderWithProviders(
80
+ <TableCellContext.Provider value={{ inTableCell: false, isHeader: false, editable: true }}>
81
+ <Geolocation {...props} />
82
+ </TableCellContext.Provider>,
83
+ );
84
+ fireEvent.change(input(result.container), { target: { value: "Sydney" } });
85
+ await waitFor(() =>
86
+ expect(document.querySelector("[data-testid='geolocation-result-0']")).not.toBeNull(),
87
+ );
88
+ fireEvent.click(document.querySelector("[data-testid='geolocation-result-0']") as Element);
89
+ expect(onChange).toHaveBeenCalledExactlyOnceWith(sydneyValue);
90
+ expect(input(result.container).value).toBe("Sydney");
91
+ result.rerender(
92
+ <TableCellContext.Provider value={{ inTableCell: cell, isHeader: false, editable: false }}>
93
+ <Geolocation {...props} readOnly />
94
+ </TableCellContext.Provider>,
95
+ );
96
+ const face = result.getByTestId(
97
+ cell ? "geolocation-cell-face" : "geolocation-readonly-address",
98
+ );
99
+ expect(face.textContent).toBe("60.16952, 24.93545");
100
+ if (!cell) expect(result.getByTestId("bound-map").textContent).toBe("60.16952,24.93545");
101
+ },
102
+ );
103
+
104
+ it("shows the current pair while a new controlled value's address is pending", async () => {
105
+ const pending = deferred<GeocodeResult | null>();
106
+ const reverseGeocode = vi.fn(({ lat }: { lat: number }) =>
107
+ lat === place.lat ? Promise.resolve(place) : pending.promise,
108
+ );
109
+ const props = { value: helsinkiValue, readOnly: true, reverseGeocode, renderMap: boundMap };
110
+ const result = renderWithProviders(<Geolocation {...props} />);
111
+ await waitFor(() =>
112
+ expect(result.getByTestId("geolocation-readonly-address").textContent).toBe("Helsinki"),
113
+ );
114
+ result.rerender(<Geolocation {...props} value={sydneyValue} />);
115
+ expect(result.getByTestId("bound-map").textContent).toBe("-33.8688,151.2093");
116
+ expect(result.getByTestId("geolocation-readonly-address").textContent).toBe(
117
+ "-33.86880, 151.20930",
118
+ );
119
+ await waitFor(() => expect(reverseGeocode).toHaveBeenCalledTimes(2));
120
+ await act(async () => pending.resolve(sydney));
121
+ expect(result.getByTestId("geolocation-readonly-address").textContent).toBe("Sydney");
122
+ });
123
+
124
+ it("keeps the bound pair's resolved address when a different pick is rejected", async () => {
125
+ const props = {
126
+ value: helsinkiValue,
127
+ geocode: async () => [sydney],
128
+ reverseGeocode: async () => place,
129
+ renderMap: boundMap,
130
+ };
131
+ const result = renderWithProviders(<Geolocation {...props} />);
132
+ await waitFor(() => expect(input(result.container).value).toBe("Helsinki"));
133
+ fireEvent.change(input(result.container), { target: { value: "Sydney" } });
134
+ await waitFor(() =>
135
+ expect(document.querySelector("[data-testid='geolocation-result-0']")).not.toBeNull(),
136
+ );
137
+ fireEvent.click(document.querySelector("[data-testid='geolocation-result-0']") as Element);
138
+ result.rerender(<Geolocation {...props} readOnly />);
139
+ expect(result.getByTestId("geolocation-readonly-address").textContent).toBe("Helsinki");
140
+ expect(result.getByTestId("bound-map").textContent).toBe("60.16952,24.93545");
141
+ });
142
+
143
+ it("uses a picked address only after delayed acceptance and preserves a later typed draft", async () => {
144
+ const onChange = vi.fn();
145
+ const props = {
146
+ value: helsinkiValue,
147
+ geocode: async () => [sydney],
148
+ onChange,
149
+ renderMap: boundMap,
150
+ };
151
+ const result = renderWithProviders(<Geolocation {...props} />);
152
+ fireEvent.change(input(result.container), { target: { value: "Sydney" } });
153
+ await waitFor(() =>
154
+ expect(document.querySelector("[data-testid='geolocation-result-0']")).not.toBeNull(),
155
+ );
156
+ fireEvent.click(document.querySelector("[data-testid='geolocation-result-0']") as Element);
157
+ result.rerender(<Geolocation {...props} readOnly />);
158
+ expect(result.getByTestId("geolocation-readonly-address").textContent).toBe(
159
+ "60.16952, 24.93545",
160
+ );
161
+ result.rerender(<Geolocation {...props} />);
162
+ fireEvent.change(input(result.container), { target: { value: "another draft" } });
163
+ result.rerender(<Geolocation {...props} value={sydneyValue} />);
164
+ expect(input(result.container).value).toBe("another draft");
165
+ expect(result.getByTestId("bound-map").textContent).toBe("-33.8688,151.2093");
166
+ result.rerender(<Geolocation {...props} value={sydneyValue} readOnly />);
167
+ expect(result.getByTestId("geolocation-readonly-address").textContent).toBe("Sydney");
168
+ expect(onChange).toHaveBeenCalledExactlyOnceWith(sydneyValue);
169
+ });
170
+
171
+ it("preserves a typed draft across new bound coordinates and their reverse response", async () => {
172
+ const pending = deferred<GeocodeResult | null>();
173
+ const reverseGeocode = ({ lat }: { lat: number }) =>
174
+ lat === place.lat ? Promise.resolve(place) : pending.promise;
175
+ const props = {
176
+ value: helsinkiValue,
177
+ geocode: async () => [],
178
+ reverseGeocode,
179
+ renderMap: boundMap,
180
+ };
181
+ const result = renderWithProviders(<Geolocation {...props} />);
182
+ await waitFor(() => expect(input(result.container).value).toBe("Helsinki"));
183
+ fireEvent.change(input(result.container), { target: { value: "independent draft" } });
184
+ result.rerender(<Geolocation {...props} value={sydneyValue} />);
185
+ expect(input(result.container).value).toBe("independent draft");
186
+ await act(async () => pending.resolve(sydney));
187
+ expect(input(result.container).value).toBe("independent draft");
188
+ });
189
+
190
+ it.each(["Helsinki", "60.16952, 24.93545"])(
191
+ "preserves Frappe features when picking %s and pans the controlled map",
192
+ async (query) => {
193
+ const onChange = vi.fn();
194
+ const result = renderWithProviders(
195
+ <Controlled value={original} geocode={async () => [place]} onChange={onChange} />,
196
+ );
197
+ fireEvent.change(input(result.container), { target: { value: query } });
198
+ const selector = query === "Helsinki" ? "geolocation-result-0" : "geolocation-coord-result";
199
+ await waitFor(() =>
200
+ expect(document.querySelector(`[data-testid='${selector}']`)).not.toBeNull(),
201
+ );
202
+ fireEvent.click(document.querySelector(`[data-testid='${selector}']`) as Element);
203
+ await waitFor(() =>
204
+ expect(result.getByTestId("map-center").textContent).toBe("60.16952,24.93545"),
205
+ );
206
+ if (query === "Helsinki") expect(input(result.container).value).toBe("Helsinki");
207
+ const value = JSON.parse(onChange.mock.calls[0][0]);
208
+ expect(value.type).toBe("FeatureCollection");
209
+ expect(value.features[0].geometry.coordinates).toEqual([place.lng, place.lat]);
210
+ expect(value.features[0].properties).toEqual({ point_type: "circle", radius: 10 });
211
+ expect(value.features[1]).toEqual(JSON.parse(original).features[1]);
212
+ },
213
+ );
214
+
215
+ it("ignores search responses after the query is cleared", async () => {
216
+ const pending = deferred<GeocodeResult[]>();
217
+ const geocode = vi.fn(() => pending.promise);
218
+ const result = renderWithProviders(<Geolocation geocode={geocode} />);
219
+ fireEvent.change(input(result.container), { target: { value: "old" } });
220
+ await waitFor(() => expect(geocode).toHaveBeenCalled());
221
+ fireEvent.change(input(result.container), { target: { value: "" } });
222
+ await act(async () => pending.resolve([place]));
223
+ expect(document.querySelector("[data-testid='geolocation-result-0']")).toBeNull();
224
+ });
225
+
226
+ it("ignores reverse responses after clearing a controlled value", async () => {
227
+ const pending = deferred<GeocodeResult | null>();
228
+ const reverseGeocode = vi.fn(() => pending.promise);
229
+ const result = renderWithProviders(
230
+ <Controlled value={original} geocode={async () => []} reverseGeocode={reverseGeocode} />,
231
+ );
232
+ await waitFor(() => expect(reverseGeocode).toHaveBeenCalled());
233
+ fireEvent.change(input(result.container), { target: { value: "clear me" } });
234
+ fireEvent.click(result.container.querySelector("[aria-label='Clear location']") as Element);
235
+ await act(async () => pending.resolve(place));
236
+ expect(input(result.container).value).toBe("");
237
+ expect(result.container.textContent).toContain("No location set");
238
+ });
239
+
240
+ it("leaves a typed query alone when a reverse response arrives", async () => {
241
+ const pending = deferred<GeocodeResult | null>();
242
+ const result = renderWithProviders(
243
+ <Geolocation
244
+ value={original}
245
+ geocode={async () => []}
246
+ reverseGeocode={() => pending.promise}
247
+ />,
248
+ );
249
+ fireEvent.change(input(result.container), { target: { value: "Sydney" } });
250
+ await act(async () => pending.resolve(place));
251
+ expect(input(result.container).value).toBe("Sydney");
252
+ });
253
+
254
+ it("allows manual coordinates on an empty field without a provider", async () => {
255
+ const result = renderWithProviders(<Controlled />);
256
+ const trigger = result.container.querySelector("[aria-label='Edit coordinates']");
257
+ expect(trigger).not.toBeNull();
258
+ fireEvent.click(trigger as Element);
259
+ await waitFor(() => expect(document.querySelector("[aria-label='Latitude']")).not.toBeNull());
260
+ fireEvent.change(document.querySelector("[aria-label='Latitude']") as Element, {
261
+ target: { value: "10" },
262
+ });
263
+ expect(result.getByTestId("map-center").textContent).toBe("10,0");
264
+ });
265
+ it("opens a cell editor with manual coordinates and commits without a provider", async () => {
266
+ const onChange = vi.fn();
267
+ const result = renderWithProviders(
268
+ <TableCellContext.Provider value={{ inTableCell: true, isHeader: false, editable: true }}>
269
+ <Controlled value={original} onChange={onChange} />
270
+ </TableCellContext.Provider>,
271
+ );
272
+ expect(result.container.querySelector("[data-testid='geolocation-map']")).toBeNull();
273
+ expect(result.getByTestId("geolocation-cell-face").tabIndex).toBe(0);
274
+ fireEvent.keyDown(result.getByTestId("geolocation-cell-face"), { key: "Enter" });
275
+ await waitFor(() =>
276
+ expect(document.querySelector("[aria-label='Edit coordinates']")).not.toBeNull(),
277
+ );
278
+ fireEvent.click(document.querySelector("[aria-label='Edit coordinates']") as Element);
279
+ await waitFor(() => expect(document.querySelector("[aria-label='Latitude']")).not.toBeNull());
280
+ fireEvent.change(document.querySelector("[aria-label='Latitude']") as Element, {
281
+ target: { value: "11" },
282
+ });
283
+ expect(JSON.parse(onChange.mock.calls[0][0]).features[0].geometry.coordinates).toEqual([
284
+ 20, 11,
285
+ ]);
286
+ });
287
+
288
+ it("selects a search result with the keyboard", async () => {
289
+ const onChange = vi.fn();
290
+ const result = renderWithProviders(
291
+ <Controlled geocode={async () => [place]} onChange={onChange} />,
292
+ );
293
+ fireEvent.change(input(result.container), { target: { value: "Helsinki" } });
294
+ await waitFor(() =>
295
+ expect(document.querySelector("[data-testid='geolocation-result-0']")).not.toBeNull(),
296
+ );
297
+ const row = document.querySelector("[data-testid='geolocation-result-0']") as HTMLElement;
298
+ expect(row.tabIndex).toBe(0);
299
+ fireEvent.keyDown(row, { key: "Enter" });
300
+ expect(onChange).toHaveBeenCalledWith(JSON.stringify({ lat: place.lat, lng: place.lng }));
301
+ await waitFor(() =>
302
+ expect(document.querySelector("[data-testid='geolocation-results']")).toBeNull(),
303
+ );
304
+ expect(document.activeElement).toBe(input(result.container));
305
+ });
306
+ it.each(["Enter", " "])("clears the selected value from the keyboard with %s", async (key) => {
307
+ const onChange = vi.fn();
308
+ const result = renderWithProviders(
309
+ <Controlled value={original} geocode={async () => []} onChange={onChange} />,
310
+ );
311
+ fireEvent.change(input(result.container), { target: { value: "clear me" } });
312
+ const clear = result.container.querySelector("[aria-label='Clear location']") as HTMLElement;
313
+ expect(clear.tabIndex).toBe(0);
314
+ fireEvent.keyDown(clear, { key });
315
+ expect(onChange).toHaveBeenCalledExactlyOnceWith("");
316
+ expect(input(result.container).value).toBe("");
317
+ expect(result.getByTestId("map-center").textContent).toBe("0,0");
318
+ expect(document.activeElement).toBe(input(result.container));
319
+ await waitFor(() => expect(result.container.textContent).toContain("No location set"));
320
+ });
321
+
322
+ it("keeps the cell editor exposed when its input receives initial focus", async () => {
323
+ const result = renderWithProviders(
324
+ <TableCellContext.Provider value={{ inTableCell: true, isHeader: false, editable: true }}>
325
+ <Controlled value={original} geocode={async () => [place]} />
326
+ </TableCellContext.Provider>,
327
+ );
328
+ fireEvent.keyDown(result.getByTestId("geolocation-cell-face"), { key: "Enter" });
329
+ await waitFor(() =>
330
+ expect(document.querySelector("[aria-label='Search for a location']")).not.toBeNull(),
331
+ );
332
+ fireEvent.focus(document.querySelector("[aria-label='Search for a location']") as Element);
333
+ expect(document.querySelector("[data-testid='geolocation-results']")).toBeNull();
334
+ expect(document.querySelector("[data-testid='geolocation-map']")).not.toBeNull();
335
+ });
336
+ it("does not overwrite Clear with a pending Locate response", async () => {
337
+ let locate!: PositionCallback;
338
+ const getCurrentPosition = vi.fn((callback: PositionCallback) => {
339
+ locate = callback;
340
+ });
341
+ vi.stubGlobal("navigator", {
342
+ ...navigator,
343
+ geolocation: { getCurrentPosition },
344
+ permissions: { query: async () => ({ state: "granted" }) },
345
+ });
346
+ const onChange = vi.fn();
347
+ const result = renderWithProviders(
348
+ <Controlled value={original} geocode={async () => []} onChange={onChange} />,
349
+ );
350
+ fireEvent.click(result.container.querySelector("[aria-label='Locate']") as Element);
351
+ await waitFor(() => expect(getCurrentPosition).toHaveBeenCalled());
352
+ fireEvent.change(input(result.container), { target: { value: "clear" } });
353
+ fireEvent.click(result.container.querySelector("[aria-label='Clear location']") as Element);
354
+ await act(async () =>
355
+ locate({ coords: { latitude: 50, longitude: 30 } } as GeolocationPosition),
356
+ );
357
+ expect(onChange).toHaveBeenCalledTimes(1);
358
+ expect(onChange).toHaveBeenLastCalledWith("");
359
+ });
360
+
361
+ it("Locate retains the stock Frappe shape and existing features", async () => {
362
+ vi.stubGlobal("navigator", {
363
+ ...navigator,
364
+ geolocation: {
365
+ getCurrentPosition: (callback: PositionCallback) =>
366
+ callback({ coords: { latitude: 50, longitude: 30 } } as GeolocationPosition),
367
+ },
368
+ permissions: { query: async () => ({ state: "granted" }) },
369
+ });
370
+ const onChange = vi.fn();
371
+ const result = renderWithProviders(<Controlled value={original} onChange={onChange} />);
372
+ fireEvent.click(result.container.querySelector("[aria-label='Locate']") as Element);
373
+ await waitFor(() => expect(onChange).toHaveBeenCalled());
374
+ const value = JSON.parse(onChange.mock.calls[0][0]);
375
+ expect(value.type).toBe("FeatureCollection");
376
+ expect(value.features[0].geometry.coordinates).toEqual([30, 50]);
377
+ expect(value.features[0].properties).toEqual(JSON.parse(original).features[0].properties);
378
+ expect(value.features[1]).toEqual(JSON.parse(original).features[1]);
379
+ });
380
+ it.each([false, true])("pins have explicit theme ink (cell=%s)", (cell) => {
381
+ const field = <Geolocation value={original} readOnly />;
382
+ const result = renderWithProviders(
383
+ cell ? (
384
+ <TableCellContext.Provider value={{ inTableCell: true, isHeader: false, editable: false }}>
385
+ {field}
386
+ </TableCellContext.Provider>
387
+ ) : (
388
+ field
389
+ ),
390
+ );
391
+ const glyph = result.container.querySelector(
392
+ "[data-testid='geolocation-cell-face'] svg, [data-testid='geolocation-readonly-address'] svg",
393
+ );
394
+ expect(glyph).not.toBeNull();
395
+ expect(glyph?.getAttribute("fill")).toBeTruthy();
396
+ expect(glyph?.getAttribute("fill")).not.toBe("currentColor");
397
+ });
398
+ });
@@ -0,0 +1,44 @@
1
+ import { fireEvent, waitFor } from "@testing-library/react";
2
+ import { describe, expect, it } from "vitest";
3
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
4
+ import { Geolocation } from "./index";
5
+ import {
6
+ AddressWithFakeProvider,
7
+ FailedFakeProvider,
8
+ SearchWithFakeProvider,
9
+ } from "./Geolocation.stories";
10
+
11
+ describe("Geolocation fake-provider stories", () => {
12
+ it("searches and commits a place through the interactive story", async () => {
13
+ const story = SearchWithFakeProvider;
14
+ const result = renderWithProviders(<>{story.render!(story.args!, {} as never)}</>);
15
+ const input = result.container.querySelector(
16
+ "[aria-label='Search for a location']",
17
+ ) as HTMLInputElement;
18
+ fireEvent.change(input, { target: { value: "Sydney" } });
19
+ await waitFor(() =>
20
+ expect(document.querySelector("[data-testid='geolocation-result-0']")).not.toBeNull(),
21
+ );
22
+ fireEvent.click(document.querySelector("[data-testid='geolocation-result-0']") as Element);
23
+ await waitFor(() => expect(input.value).toBe("Sydney, New South Wales, Australia"));
24
+ expect(result.container.textContent).toContain("-33.86880, 151.20930");
25
+ });
26
+
27
+ it("renders the read-only address story", async () => {
28
+ const result = renderWithProviders(<Geolocation {...AddressWithFakeProvider.args} />);
29
+ await waitFor(() =>
30
+ expect(result.container.textContent).toContain("Mannerheimintie 3, Kamppi, Helsinki"),
31
+ );
32
+ });
33
+
34
+ it("renders honest failure from the failing story", async () => {
35
+ const story = FailedFakeProvider;
36
+ const result = renderWithProviders(<>{story.render!(story.args!, {} as never)}</>);
37
+ fireEvent.change(
38
+ result.container.querySelector("[aria-label='Search for a location']") as Element,
39
+ { target: { value: "Sydney" } },
40
+ );
41
+ await waitFor(() => expect(document.body.textContent).toContain("Search is unavailable"));
42
+ expect(result.container.querySelector("[aria-label='Edit coordinates']")).not.toBeNull();
43
+ });
44
+ });