@multiplatform.one/forms 7.7.6 → 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 (533) hide show
  1. package/dist/cjs/Button/index.cjs +0 -3
  2. package/dist/cjs/Button/index.native.js +0 -3
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/Chip/index.cjs +1 -1
  5. package/dist/cjs/Chip/index.native.js +1 -1
  6. package/dist/cjs/Chip/index.native.js.map +1 -1
  7. package/dist/cjs/FloatingPanel/index.cjs +59 -14
  8. package/dist/cjs/FloatingPanel/index.native.js +16 -7
  9. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  10. package/dist/cjs/FloatingPanel/nestedAction.cjs +37 -0
  11. package/dist/cjs/FloatingPanel/nestedAction.native.js +42 -0
  12. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -0
  13. package/dist/cjs/InputParts/index.cjs +8 -6
  14. package/dist/cjs/InputParts/index.native.js +9 -9
  15. package/dist/cjs/InputParts/index.native.js.map +1 -1
  16. package/dist/cjs/Wheel/index.cjs +3 -3
  17. package/dist/cjs/Wheel/index.native.js +3 -3
  18. package/dist/cjs/Wheel/index.native.js.map +1 -1
  19. package/dist/cjs/fieldLayout.cjs +3 -3
  20. package/dist/cjs/fieldLayout.native.js +3 -3
  21. package/dist/cjs/fieldLayout.native.js.map +1 -1
  22. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.cjs +9 -2
  23. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  24. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  25. package/dist/cjs/fields/Combobox/index.cjs +36 -29
  26. package/dist/cjs/fields/Combobox/index.native.js +38 -38
  27. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  28. package/dist/cjs/fields/DatePicker/Calendar.cjs +6 -1
  29. package/dist/cjs/fields/DatePicker/Calendar.native.js +6 -1
  30. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  31. package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +2 -2
  32. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  33. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  34. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +15 -12
  35. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  36. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  37. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +39 -14
  38. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  39. package/dist/cjs/fields/DatePicker/MonthPicker.cjs +10 -3
  40. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +10 -3
  41. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  42. package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +2 -2
  43. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  44. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  45. package/dist/cjs/fields/DatePicker/index.native.js +3 -0
  46. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  47. package/dist/cjs/fields/DatePicker/parts.cjs +26 -14
  48. package/dist/cjs/fields/DatePicker/parts.native.js +28 -14
  49. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  50. package/dist/cjs/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  51. package/dist/cjs/fields/Geolocation/geocoder.cjs +63 -0
  52. package/dist/cjs/fields/Geolocation/geocoder.native.js +68 -0
  53. package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -0
  54. package/dist/cjs/fields/Geolocation/index.cjs +801 -152
  55. package/dist/cjs/fields/Geolocation/index.native.js +856 -167
  56. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  57. package/dist/cjs/fields/Geolocation/nativeSearchFocus.cjs +44 -0
  58. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  59. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  60. package/dist/cjs/fields/Icon/drawnSet.cjs +14 -3
  61. package/dist/cjs/fields/Icon/drawnSet.native.js +18 -3
  62. package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
  63. package/dist/cjs/fields/Icon/index.cjs +102 -27
  64. package/dist/cjs/fields/Icon/index.native.js +115 -31
  65. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  66. package/dist/cjs/fields/Input/index.cjs +5 -12
  67. package/dist/cjs/fields/Input/index.native.js +5 -13
  68. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  69. package/dist/cjs/fields/PhoneInput/index.cjs +2 -2
  70. package/dist/cjs/fields/PhoneInput/index.native.js +2 -2
  71. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  72. package/dist/cjs/fields/SearchInput/index.cjs +8 -9
  73. package/dist/cjs/fields/SearchInput/index.native.js +8 -9
  74. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  75. package/dist/cjs/fields/Select/index.cjs +42 -11
  76. package/dist/cjs/fields/Select/index.native.js +52 -20
  77. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  78. package/dist/cjs/fields/Stepper/index.cjs +144 -31
  79. package/dist/cjs/fields/Stepper/index.native.js +151 -31
  80. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  81. package/dist/cjs/index.cjs +2 -0
  82. package/dist/cjs/index.native.js +2 -0
  83. package/dist/cjs/index.native.js.map +1 -1
  84. package/dist/cjs/shared/focusManagement.cjs +24 -11
  85. package/dist/cjs/shared/focusManagement.native.js +24 -11
  86. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  87. package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
  88. package/dist/esm/Button/index.mjs +0 -3
  89. package/dist/esm/Button/index.mjs.map +1 -1
  90. package/dist/esm/Button/index.native.js +0 -3
  91. package/dist/esm/Button/index.native.js.map +1 -1
  92. package/dist/esm/Chip/index.mjs +1 -1
  93. package/dist/esm/Chip/index.mjs.map +1 -1
  94. package/dist/esm/Chip/index.native.js +1 -1
  95. package/dist/esm/Chip/index.native.js.map +1 -1
  96. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  97. package/dist/esm/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  98. package/dist/esm/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  99. package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
  100. package/dist/esm/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  101. package/dist/esm/ControlGroup/index.native.js.map +1 -1
  102. package/dist/esm/DescriptionList/index.native.js.map +1 -1
  103. package/dist/esm/ErrorSummary.native.js.map +1 -1
  104. package/dist/esm/FieldDisplay/editMode.native.js.map +1 -1
  105. package/dist/esm/FieldDisplay/formatters.native.js.map +1 -1
  106. package/dist/esm/FieldDisplay/index.native.js.map +1 -1
  107. package/dist/esm/FieldGroup.native.js.map +1 -1
  108. package/dist/esm/FloatingPanel/index.mjs +58 -15
  109. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  110. package/dist/esm/FloatingPanel/index.native.js +15 -8
  111. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  112. package/dist/esm/FloatingPanel/nestedAction.mjs +11 -0
  113. package/dist/esm/FloatingPanel/nestedAction.mjs.map +1 -0
  114. package/dist/esm/FloatingPanel/nestedAction.native.js +13 -0
  115. package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -0
  116. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  117. package/dist/esm/Form/index.native.js.map +1 -1
  118. package/dist/esm/Form/validateOn.native.js.map +1 -1
  119. package/dist/esm/FormGrid.native.js.map +1 -1
  120. package/dist/esm/FormSection.native.js.map +1 -1
  121. package/dist/esm/InputParts/index.mjs +9 -7
  122. package/dist/esm/InputParts/index.mjs.map +1 -1
  123. package/dist/esm/InputParts/index.native.js +10 -10
  124. package/dist/esm/InputParts/index.native.js.map +1 -1
  125. package/dist/esm/Label/index.native.js.map +1 -1
  126. package/dist/esm/Skeleton/index.native.js.map +1 -1
  127. package/dist/esm/Spinner/SpinnerGlyph.native.js.map +1 -1
  128. package/dist/esm/Spinner/spinnerSize.native.js.map +1 -1
  129. package/dist/esm/Table/index.native.js.map +1 -1
  130. package/dist/esm/Wheel/haptic.native.js.map +1 -1
  131. package/dist/esm/Wheel/index.mjs +3 -3
  132. package/dist/esm/Wheel/index.mjs.map +1 -1
  133. package/dist/esm/Wheel/index.native.js +3 -3
  134. package/dist/esm/Wheel/index.native.js.map +1 -1
  135. package/dist/esm/actionLabel.native.js.map +1 -1
  136. package/dist/esm/fieldDefaults.native.js.map +1 -1
  137. package/dist/esm/fieldLayout.mjs +3 -3
  138. package/dist/esm/fieldLayout.mjs.map +1 -1
  139. package/dist/esm/fieldLayout.native.js +3 -3
  140. package/dist/esm/fieldLayout.native.js.map +1 -1
  141. package/dist/esm/fields/Barcode/BarcodePreview.native.js.map +1 -1
  142. package/dist/esm/fields/Barcode/code128.native.js.map +1 -1
  143. package/dist/esm/fields/Barcode/index.native.js.map +1 -1
  144. package/dist/esm/fields/Barcode/qr.native.js.map +1 -1
  145. package/dist/esm/fields/Barcode/scannerTypes.native.js.map +1 -1
  146. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  147. package/dist/esm/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  148. package/dist/esm/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  149. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  150. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  151. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  152. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  153. package/dist/esm/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  154. package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  155. package/dist/esm/fields/Checkbox/index.native.js.map +1 -1
  156. package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
  157. package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
  158. package/dist/esm/fields/Combobox/authorOptions.native.js.map +1 -1
  159. package/dist/esm/fields/Combobox/index.mjs +36 -29
  160. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  161. package/dist/esm/fields/Combobox/index.native.js +38 -38
  162. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  163. package/dist/esm/fields/DatePicker/Calendar.mjs +6 -1
  164. package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
  165. package/dist/esm/fields/DatePicker/Calendar.native.js +6 -1
  166. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  167. package/dist/esm/fields/DatePicker/DateRangePicker.mjs +2 -2
  168. package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  169. package/dist/esm/fields/DatePicker/DateRangePicker.native.js +2 -2
  170. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  171. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  172. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  173. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  174. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  175. package/dist/esm/fields/DatePicker/DatetimePicker.native.js +39 -14
  176. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  177. package/dist/esm/fields/DatePicker/MonthPicker.mjs +10 -3
  178. package/dist/esm/fields/DatePicker/MonthPicker.mjs.map +1 -1
  179. package/dist/esm/fields/DatePicker/MonthPicker.native.js +10 -3
  180. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  181. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +2 -2
  182. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  183. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +2 -2
  184. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  185. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
  186. package/dist/esm/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  187. package/dist/esm/fields/DatePicker/index.native.js +3 -0
  188. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  189. package/dist/esm/fields/DatePicker/parts.mjs +28 -16
  190. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  191. package/dist/esm/fields/DatePicker/parts.native.js +30 -16
  192. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  193. package/dist/esm/fields/DatePicker/utils.native.js.map +1 -1
  194. package/dist/esm/fields/Duration/durationMath.native.js.map +1 -1
  195. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  196. package/dist/esm/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  197. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  198. package/dist/esm/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  199. package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  200. package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  201. package/dist/esm/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  202. package/dist/esm/fields/Geolocation/geoValue.native.js.map +1 -1
  203. package/dist/esm/fields/Geolocation/geocoder.mjs +33 -0
  204. package/dist/esm/fields/Geolocation/geocoder.mjs.map +1 -0
  205. package/dist/esm/fields/Geolocation/geocoder.native.js +35 -0
  206. package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -0
  207. package/dist/esm/fields/Geolocation/index.mjs +792 -149
  208. package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
  209. package/dist/esm/fields/Geolocation/index.native.js +847 -164
  210. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  211. package/dist/esm/fields/Geolocation/mapMath.native.js.map +1 -1
  212. package/dist/esm/fields/Geolocation/mapTypes.native.js.map +1 -1
  213. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  214. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  215. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js +19 -0
  216. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  217. package/dist/esm/fields/Icon/drawnSet.mjs +14 -3
  218. package/dist/esm/fields/Icon/drawnSet.mjs.map +1 -1
  219. package/dist/esm/fields/Icon/drawnSet.native.js +18 -3
  220. package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
  221. package/dist/esm/fields/Icon/index.mjs +93 -18
  222. package/dist/esm/fields/Icon/index.mjs.map +1 -1
  223. package/dist/esm/fields/Icon/index.native.js +106 -22
  224. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  225. package/dist/esm/fields/ImageField/index.native.js.map +1 -1
  226. package/dist/esm/fields/Input/index.mjs +5 -12
  227. package/dist/esm/fields/Input/index.mjs.map +1 -1
  228. package/dist/esm/fields/Input/index.native.js +5 -13
  229. package/dist/esm/fields/Input/index.native.js.map +1 -1
  230. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  231. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  232. package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
  233. package/dist/esm/fields/PhoneInput/dialCodes.native.js.map +1 -1
  234. package/dist/esm/fields/PhoneInput/index.mjs +2 -2
  235. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  236. package/dist/esm/fields/PhoneInput/index.native.js +2 -2
  237. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  238. package/dist/esm/fields/PhoneInput/phone.native.js.map +1 -1
  239. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  240. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  241. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  242. package/dist/esm/fields/Rating/ratingMath.native.js.map +1 -1
  243. package/dist/esm/fields/Rating/types.native.js.map +1 -1
  244. package/dist/esm/fields/SearchInput/index.mjs +9 -10
  245. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  246. package/dist/esm/fields/SearchInput/index.native.js +9 -10
  247. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  248. package/dist/esm/fields/Select/index.mjs +42 -11
  249. package/dist/esm/fields/Select/index.mjs.map +1 -1
  250. package/dist/esm/fields/Select/index.native.js +52 -20
  251. package/dist/esm/fields/Select/index.native.js.map +1 -1
  252. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  253. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  254. package/dist/esm/fields/Slider/jumpMotion.native.js.map +1 -1
  255. package/dist/esm/fields/Stepper/index.mjs +145 -32
  256. package/dist/esm/fields/Stepper/index.mjs.map +1 -1
  257. package/dist/esm/fields/Stepper/index.native.js +152 -32
  258. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  259. package/dist/esm/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  260. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  261. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  262. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  263. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  264. package/dist/esm/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  265. package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
  266. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  267. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  268. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  269. package/dist/esm/fields/nativeSelect.native.js.map +1 -1
  270. package/dist/esm/fields/selectedOrder.native.js.map +1 -1
  271. package/dist/esm/formSpacing.native.js.map +1 -1
  272. package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
  273. package/dist/esm/index.mjs +2 -1
  274. package/dist/esm/index.mjs.map +1 -1
  275. package/dist/esm/index.native.js +2 -1
  276. package/dist/esm/index.native.js.map +1 -1
  277. package/dist/esm/requiredMarking.native.js.map +1 -1
  278. package/dist/esm/shared/TimeColumn.native.js.map +1 -1
  279. package/dist/esm/shared/capabilityPreflight.native.js.map +1 -1
  280. package/dist/esm/shared/colorRamps.native.js.map +1 -1
  281. package/dist/esm/shared/devWarn.native.js.map +1 -1
  282. package/dist/esm/shared/floatingList.native.js.map +1 -1
  283. package/dist/esm/shared/focusManagement.mjs +24 -11
  284. package/dist/esm/shared/focusManagement.mjs.map +1 -1
  285. package/dist/esm/shared/focusManagement.native.js +24 -11
  286. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  287. package/dist/esm/shared/groupContext.native.js.map +1 -1
  288. package/dist/esm/shared/i18n.native.js.map +1 -1
  289. package/dist/esm/shared/pickerTriggerContract.native.js.map +1 -1
  290. package/dist/esm/shared/pressSlopProps.native.js.map +1 -1
  291. package/dist/esm/shared/t.native.js.map +1 -1
  292. package/dist/esm/shared/tableCellContext.native.js.map +1 -1
  293. package/dist/esm/shared/useDragScroll.native.js.map +1 -1
  294. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  295. package/dist/esm/shared/useSheetEscapeDismiss.native.js.map +1 -1
  296. package/dist/esm/shared/useWheelIncrement.native.js.map +1 -1
  297. package/dist/esm/shared/utils.native.js.map +1 -1
  298. package/dist/esm/shared/zIndex.native.js.map +1 -1
  299. package/dist/esm/themedPrimitives.native.js.map +1 -1
  300. package/dist/esm/types.native.js.map +1 -1
  301. package/dist/esm/utils/LinkCell.native.js.map +1 -1
  302. package/dist/jsx/Button/index.mjs +0 -3
  303. package/dist/jsx/Button/index.mjs.map +1 -1
  304. package/dist/jsx/Button/index.native.js +0 -3
  305. package/dist/jsx/Button/index.native.js.map +1 -1
  306. package/dist/jsx/Chip/index.mjs +1 -1
  307. package/dist/jsx/Chip/index.mjs.map +1 -1
  308. package/dist/jsx/Chip/index.native.js +1 -1
  309. package/dist/jsx/Chip/index.native.js.map +1 -1
  310. package/dist/jsx/FloatingPanel/index.mjs +58 -15
  311. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  312. package/dist/jsx/FloatingPanel/index.native.js +16 -7
  313. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  314. package/dist/jsx/FloatingPanel/nestedAction.mjs +11 -0
  315. package/dist/jsx/FloatingPanel/nestedAction.mjs.map +1 -0
  316. package/dist/jsx/FloatingPanel/nestedAction.native.js +42 -0
  317. package/dist/jsx/FloatingPanel/nestedAction.native.js.map +1 -0
  318. package/dist/jsx/InputParts/index.mjs +9 -7
  319. package/dist/jsx/InputParts/index.mjs.map +1 -1
  320. package/dist/jsx/InputParts/index.native.js +9 -9
  321. package/dist/jsx/InputParts/index.native.js.map +1 -1
  322. package/dist/jsx/Wheel/index.mjs +3 -3
  323. package/dist/jsx/Wheel/index.mjs.map +1 -1
  324. package/dist/jsx/Wheel/index.native.js +3 -3
  325. package/dist/jsx/Wheel/index.native.js.map +1 -1
  326. package/dist/jsx/fieldLayout.mjs +3 -3
  327. package/dist/jsx/fieldLayout.mjs.map +1 -1
  328. package/dist/jsx/fieldLayout.native.js +3 -3
  329. package/dist/jsx/fieldLayout.native.js.map +1 -1
  330. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  331. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  332. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  333. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  334. package/dist/jsx/fields/Combobox/index.mjs +36 -29
  335. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  336. package/dist/jsx/fields/Combobox/index.native.js +38 -38
  337. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  338. package/dist/jsx/fields/DatePicker/Calendar.mjs +6 -1
  339. package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
  340. package/dist/jsx/fields/DatePicker/Calendar.native.js +6 -1
  341. package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
  342. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +2 -2
  343. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  344. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +2 -2
  345. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  346. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  347. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  348. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  349. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  350. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +39 -14
  351. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  352. package/dist/jsx/fields/DatePicker/MonthPicker.mjs +10 -3
  353. package/dist/jsx/fields/DatePicker/MonthPicker.mjs.map +1 -1
  354. package/dist/jsx/fields/DatePicker/MonthPicker.native.js +10 -3
  355. package/dist/jsx/fields/DatePicker/MonthPicker.native.js.map +1 -1
  356. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +2 -2
  357. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  358. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +2 -2
  359. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  360. package/dist/jsx/fields/DatePicker/index.native.js +3 -0
  361. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  362. package/dist/jsx/fields/DatePicker/parts.mjs +28 -16
  363. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  364. package/dist/jsx/fields/DatePicker/parts.native.js +28 -14
  365. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  366. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  367. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  368. package/dist/jsx/fields/Geolocation/geocoder.mjs +33 -0
  369. package/dist/jsx/fields/Geolocation/geocoder.mjs.map +1 -0
  370. package/dist/jsx/fields/Geolocation/geocoder.native.js +68 -0
  371. package/dist/jsx/fields/Geolocation/geocoder.native.js.map +1 -0
  372. package/dist/jsx/fields/Geolocation/index.mjs +792 -149
  373. package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
  374. package/dist/jsx/fields/Geolocation/index.native.js +856 -167
  375. package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
  376. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  377. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  378. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  379. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  380. package/dist/jsx/fields/Icon/drawnSet.mjs +14 -3
  381. package/dist/jsx/fields/Icon/drawnSet.mjs.map +1 -1
  382. package/dist/jsx/fields/Icon/drawnSet.native.js +18 -3
  383. package/dist/jsx/fields/Icon/drawnSet.native.js.map +1 -1
  384. package/dist/jsx/fields/Icon/index.mjs +93 -18
  385. package/dist/jsx/fields/Icon/index.mjs.map +1 -1
  386. package/dist/jsx/fields/Icon/index.native.js +115 -31
  387. package/dist/jsx/fields/Icon/index.native.js.map +1 -1
  388. package/dist/jsx/fields/Input/index.mjs +5 -12
  389. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  390. package/dist/jsx/fields/Input/index.native.js +5 -13
  391. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  392. package/dist/jsx/fields/PhoneInput/index.mjs +2 -2
  393. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  394. package/dist/jsx/fields/PhoneInput/index.native.js +2 -2
  395. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  396. package/dist/jsx/fields/SearchInput/index.mjs +9 -10
  397. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  398. package/dist/jsx/fields/SearchInput/index.native.js +8 -9
  399. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  400. package/dist/jsx/fields/Select/index.mjs +42 -11
  401. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  402. package/dist/jsx/fields/Select/index.native.js +52 -20
  403. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  404. package/dist/jsx/fields/Stepper/index.mjs +145 -32
  405. package/dist/jsx/fields/Stepper/index.mjs.map +1 -1
  406. package/dist/jsx/fields/Stepper/index.native.js +151 -31
  407. package/dist/jsx/fields/Stepper/index.native.js.map +1 -1
  408. package/dist/jsx/index.js +2 -1
  409. package/dist/jsx/index.js.map +1 -1
  410. package/dist/jsx/index.mjs +2 -1
  411. package/dist/jsx/index.mjs.map +1 -1
  412. package/dist/jsx/index.native.js +2 -0
  413. package/dist/jsx/index.native.js.map +1 -1
  414. package/dist/jsx/shared/focusManagement.mjs +24 -11
  415. package/dist/jsx/shared/focusManagement.mjs.map +1 -1
  416. package/dist/jsx/shared/focusManagement.native.js +24 -11
  417. package/dist/jsx/shared/focusManagement.native.js.map +1 -1
  418. package/package.json +8 -7
  419. package/src/Button/Button.labelInk.spec.tsx +21 -18
  420. package/src/Button/Button.outlinedChannel.spec.tsx +46 -0
  421. package/src/Button/Button.sizeLadder.spec.tsx +4 -3
  422. package/src/Button/Button.stories.tsx +20 -0
  423. package/src/Button/index.tsx +25 -4
  424. package/src/Chip/Chip.spec.tsx +3 -1
  425. package/src/Chip/index.tsx +1 -5
  426. package/src/FieldLayout.stories.tsx +41 -0
  427. package/src/FloatingPanel/FloatingPanel.native.spec.tsx +54 -0
  428. package/src/FloatingPanel/FloatingPanel.spec.tsx +109 -0
  429. package/src/FloatingPanel/index.native.tsx +24 -7
  430. package/src/FloatingPanel/index.tsx +80 -13
  431. package/src/FloatingPanel/nestedAction.spec.ts +36 -0
  432. package/src/FloatingPanel/nestedAction.ts +15 -0
  433. package/src/FloatingPanel/panelWidthContract.spec.ts +12 -15
  434. package/src/FormsIntegration.stories.tsx +2 -6
  435. package/src/InputParts/index.tsx +15 -5
  436. package/src/InputParts/layoutGap.spec.tsx +43 -0
  437. package/src/Wheel/Wheel.spec.tsx +16 -0
  438. package/src/Wheel/index.tsx +3 -3
  439. package/src/fieldLayout.spec.tsx +42 -1
  440. package/src/fieldLayout.tsx +9 -9
  441. package/src/fields/Checkbox/CheckboxFieldFrame.spec.tsx +18 -0
  442. package/src/fields/Checkbox/CheckboxFieldFrame.tsx +6 -1
  443. package/src/fields/Combobox/Combobox.spec.tsx +48 -1
  444. package/src/fields/Combobox/index.tsx +53 -39
  445. package/src/fields/DatePicker/Calendar.tsx +4 -1
  446. package/src/fields/DatePicker/DatePicker.stories.tsx +22 -1
  447. package/src/fields/DatePicker/DateRangePicker.tsx +4 -2
  448. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +21 -19
  449. package/src/fields/DatePicker/DatetimePicker.native.spec.tsx +144 -0
  450. package/src/fields/DatePicker/DatetimePicker.native.tsx +57 -32
  451. package/src/fields/DatePicker/DatetimePicker.stories.tsx +22 -0
  452. package/src/fields/DatePicker/MonthPicker.tsx +8 -3
  453. package/src/fields/DatePicker/MultiDatePicker.tsx +4 -2
  454. package/src/fields/DatePicker/index.native.tsx +1 -0
  455. package/src/fields/DatePicker/parts.spec.tsx +56 -0
  456. package/src/fields/DatePicker/parts.tsx +33 -12
  457. package/src/fields/Geolocation/Geolocation.spec.tsx +287 -35
  458. package/src/fields/Geolocation/Geolocation.stories.tsx +141 -7
  459. package/src/fields/Geolocation/GeolocationMap.native.tsx +3 -0
  460. package/src/fields/Geolocation/GeolocationMap.tsx +4 -0
  461. package/src/fields/Geolocation/geocoder.spec.ts +59 -0
  462. package/src/fields/Geolocation/geocoder.ts +84 -0
  463. package/src/fields/Geolocation/geocoderSeam.spec.tsx +203 -0
  464. package/src/fields/Geolocation/index.tsx +912 -180
  465. package/src/fields/Geolocation/nativeSearchFocus.spec.ts +34 -0
  466. package/src/fields/Geolocation/nativeSearchFocus.ts +19 -0
  467. package/src/fields/Geolocation/salvage.spec.tsx +398 -0
  468. package/src/fields/Geolocation/storyProviders.spec.tsx +44 -0
  469. package/src/fields/Icon/Icon.spec.tsx +215 -1
  470. package/src/fields/Icon/Icon.stories.tsx +9 -1
  471. package/src/fields/Icon/drawnSet.tsx +39 -4
  472. package/src/fields/Icon/index.tsx +118 -18
  473. package/src/fields/Input/Input.copy.spec.tsx +1 -0
  474. package/src/fields/Input/Input.spec.tsx +50 -0
  475. package/src/fields/Input/Input.stories.tsx +1 -1
  476. package/src/fields/Input/index.tsx +7 -13
  477. package/src/fields/PhoneInput/index.tsx +2 -2
  478. package/src/fields/SearchInput/SearchInput.spec.tsx +14 -0
  479. package/src/fields/SearchInput/index.tsx +5 -6
  480. package/src/fields/Select/Select.spec.tsx +54 -0
  481. package/src/fields/Select/index.tsx +52 -17
  482. package/src/fields/Stepper/Stepper.spec.tsx +34 -1
  483. package/src/fields/Stepper/index.tsx +193 -33
  484. package/src/index.ts +9 -0
  485. package/src/shared/focusManagement.spec.tsx +68 -0
  486. package/src/shared/focusManagement.ts +20 -10
  487. package/types/Button/index.d.ts +22 -3
  488. package/types/Button/index.d.ts.map +1 -1
  489. package/types/Chip/index.d.ts.map +1 -1
  490. package/types/FloatingPanel/index.d.ts +11 -1
  491. package/types/FloatingPanel/index.d.ts.map +1 -1
  492. package/types/FloatingPanel/index.native.d.ts +2 -1
  493. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  494. package/types/FloatingPanel/nestedAction.d.ts +13 -0
  495. package/types/FloatingPanel/nestedAction.d.ts.map +1 -0
  496. package/types/InputParts/index.d.ts.map +1 -1
  497. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts +46 -2
  498. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts.map +1 -1
  499. package/types/fields/Checkbox/index.d.ts +3 -3
  500. package/types/fields/Combobox/index.d.ts +3 -1
  501. package/types/fields/Combobox/index.d.ts.map +1 -1
  502. package/types/fields/DatePicker/Calendar.d.ts.map +1 -1
  503. package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
  504. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
  505. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
  506. package/types/fields/DatePicker/MonthPicker.d.ts.map +1 -1
  507. package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
  508. package/types/fields/DatePicker/index.native.d.ts.map +1 -1
  509. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  510. package/types/fields/Geolocation/GeolocationMap.d.ts +4 -0
  511. package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
  512. package/types/fields/Geolocation/GeolocationMap.native.d.ts +3 -0
  513. package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
  514. package/types/fields/Geolocation/geocoder.d.ts +53 -0
  515. package/types/fields/Geolocation/geocoder.d.ts.map +1 -0
  516. package/types/fields/Geolocation/index.d.ts +18 -2
  517. package/types/fields/Geolocation/index.d.ts.map +1 -1
  518. package/types/fields/Geolocation/nativeSearchFocus.d.ts +8 -0
  519. package/types/fields/Geolocation/nativeSearchFocus.d.ts.map +1 -0
  520. package/types/fields/Icon/drawnSet.d.ts.map +1 -1
  521. package/types/fields/Icon/index.d.ts.map +1 -1
  522. package/types/fields/Input/index.d.ts.map +1 -1
  523. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  524. package/types/fields/RadioGroup/index.d.ts +2 -2
  525. package/types/fields/SearchInput/index.d.ts.map +1 -1
  526. package/types/fields/Select/index.d.ts.map +1 -1
  527. package/types/fields/Stepper/index.d.ts.map +1 -1
  528. package/types/fields/ToggleGroup/index.d.ts +1 -1
  529. package/types/index.d.ts +2 -0
  530. package/types/index.d.ts.map +1 -1
  531. package/types/shared/focusManagement.d.ts +2 -2
  532. package/types/shared/focusManagement.d.ts.map +1 -1
  533. package/src/router.d.ts +0 -16
@@ -0,0 +1,144 @@
1
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
2
+ import { useForm } from "@tanstack/react-form";
3
+ import { act, fireEvent, waitFor } from "@testing-library/react";
4
+ import { describe, expect, it, vi } from "vitest";
5
+ import { Form } from "../../Form";
6
+ import { DatetimePicker } from "./DatetimePicker.native";
7
+ import { DatePicker } from "./index.native";
8
+
9
+ vi.mock("tamagui", async (importOriginal) => ({
10
+ ...(await importOriginal<typeof import("tamagui")>()),
11
+ isWeb: false,
12
+ }));
13
+
14
+ // RNW omits React Native's accessibilityValue object. Bridge that native
15
+ // contract for this harness; the actual iOS AX tree remains the runtime gate.
16
+ vi.mock("react-native-web", async (importOriginal) => {
17
+ const native = await importOriginal<typeof import("react-native")>();
18
+ return {
19
+ ...native,
20
+ Pressable: ({ accessibilityValue, ...props }: import("react-native").PressableProps) => (
21
+ <native.Pressable {...props} aria-valuetext={accessibilityValue?.text} />
22
+ ),
23
+ };
24
+ });
25
+
26
+ const picked = new Date(2026, 2, 5, 14, 30);
27
+ vi.mock("../nativeDateTime/OsDateTimeSheet", () => ({
28
+ OsDateTimeSheet: ({ open, onConfirm }: { open: boolean; onConfirm: (date: Date) => void }) =>
29
+ open ? (
30
+ <div role="dialog" aria-label="OS date and time">
31
+ <button onClick={() => onConfirm(new Date(2026, 2, 5, 14, 30))}>
32
+ Confirm OS selection
33
+ </button>
34
+ </div>
35
+ ) : null,
36
+ }));
37
+
38
+ describe("native DatetimePicker ownership", () => {
39
+ it.each([
40
+ { Control: DatePicker, name: "Date" },
41
+ { Control: DatetimePicker, name: "Date and time" },
42
+ ])(
43
+ "keeps $name paint inert and exposes its current value on the press owner",
44
+ ({ Control, name }) => {
45
+ const result = renderWithProviders(<Control value={picked} />);
46
+ const trigger = result.getByRole("button", { name });
47
+ expect(trigger.getAttribute("aria-valuetext")).toContain("Mar 5, 2026");
48
+ const painted = result.getByTestId("date-picker-trigger");
49
+ const paintAncestors: HTMLElement[] = [];
50
+ for (let el = painted.parentElement; el && el !== trigger; el = el.parentElement) {
51
+ paintAncestors.push(el);
52
+ }
53
+ expect(paintAncestors.some((el) => getComputedStyle(el).pointerEvents === "none")).toBe(true);
54
+ },
55
+ );
56
+
57
+ it("opens from its full-width native target and commits exactly once", () => {
58
+ const onChange = vi.fn();
59
+ const onValueChange = vi.fn();
60
+ const result = renderWithProviders(
61
+ <DatetimePicker onChange={onChange} onValueChange={onValueChange} />,
62
+ );
63
+ const trigger = result.getByRole("button", { name: "Date and time" });
64
+ expect(getComputedStyle(trigger).width).toBe("100%");
65
+ fireEvent.click(trigger);
66
+ expect(result.getAllByRole("dialog")).toHaveLength(1);
67
+ fireEvent.click(result.getByRole("button", { name: "Confirm OS selection" }));
68
+ expect(result.queryByRole("dialog")).toBeNull();
69
+ expect(onChange).toHaveBeenCalledExactlyOnceWith(picked);
70
+ expect(onValueChange).toHaveBeenCalledExactlyOnceWith(picked);
71
+ expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026");
72
+ });
73
+
74
+ it("keeps native read-only text undimmed, without a picker press target", () => {
75
+ const result = renderWithProviders(<DatetimePicker value={picked} readOnly />);
76
+ const input = result.container.querySelector("input")!;
77
+ expect(input.value).toContain("Mar 5, 2026");
78
+ expect(input.disabled).toBe(false);
79
+ expect(input.readOnly).toBe(true);
80
+ expect(result.queryByRole("button")).toBeNull();
81
+ fireEvent.click(input);
82
+ expect(result.queryByRole("dialog")).toBeNull();
83
+ for (let el: HTMLElement | null = input; el && el !== result.container; el = el.parentElement) {
84
+ const opacity = getComputedStyle(el).opacity;
85
+ expect(opacity === "" || Number(opacity) === 1).toBe(true);
86
+ }
87
+ });
88
+
89
+ it("keeps a disabled value visible while declining activation", () => {
90
+ const result = renderWithProviders(<DatetimePicker value={picked} disabled />);
91
+ const trigger = result.getByRole("button", { name: "Date and time" });
92
+ expect(trigger.getAttribute("aria-disabled")).toBe("true");
93
+ expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026");
94
+ fireEvent.click(trigger);
95
+ expect(result.queryByRole("dialog")).toBeNull();
96
+ });
97
+
98
+ it("adopts controlled values after mount without emitting changes or opening", async () => {
99
+ const onChange = vi.fn();
100
+ const onValueChange = vi.fn();
101
+ const result = renderWithProviders(
102
+ <DatetimePicker value={null} onChange={onChange} onValueChange={onValueChange} />,
103
+ );
104
+ expect(result.container.querySelector("input")?.value).toBe("");
105
+ result.rerender(
106
+ <DatetimePicker value={picked} onChange={onChange} onValueChange={onValueChange} />,
107
+ );
108
+ await waitFor(() =>
109
+ expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026"),
110
+ );
111
+ expect(onChange).not.toHaveBeenCalled();
112
+ expect(onValueChange).not.toHaveBeenCalled();
113
+ expect(result.queryByRole("dialog")).toBeNull();
114
+ });
115
+
116
+ it("adopts form values after mount without emitting changes or opening", async () => {
117
+ const onChange = vi.fn();
118
+ let update: ((date: Date) => void) | undefined;
119
+ function Example() {
120
+ const form = useForm({ defaultValues: { when: null as Date | null } });
121
+ update = (date) => form.setFieldValue("when", date);
122
+ return (
123
+ <Form form={form}>
124
+ <DatetimePicker name="when" onChange={onChange} />
125
+ </Form>
126
+ );
127
+ }
128
+ const result = renderWithProviders(<Example />);
129
+ expect(result.container.querySelector("input")?.value).toBe("");
130
+ await act(async () => update?.(picked));
131
+ await waitFor(() =>
132
+ expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026"),
133
+ );
134
+ expect(onChange).not.toHaveBeenCalled();
135
+ expect(result.queryByRole("dialog")).toBeNull();
136
+ });
137
+
138
+ it("gives the native trigger box the row width its text section needs", () => {
139
+ const result = renderWithProviders(<DatetimePicker value={picked} />);
140
+ const box = result.getByTestId("date-picker-trigger");
141
+ expect(getComputedStyle(box).flexGrow).toBe("1");
142
+ expect(getComputedStyle(box).minWidth).toBe("0px");
143
+ });
144
+ });
@@ -142,38 +142,63 @@ export function DatetimePicker<
142
142
  hasError?: boolean,
143
143
  blurHandler?: (...args: unknown[]) => void,
144
144
  fieldChange?: (value: unknown) => void,
145
- ) => (
146
- <>
147
- <DatePickerInputTrigger
148
- value={display}
149
- placeholder={placeholder}
150
- disabled={disabled || readOnly}
151
- open={open}
152
- onReset={() => commit(null, fieldChange)}
153
- onButtonPress={() => !disabled && !readOnly && setOpen(true)}
154
- error={!!hasError}
155
- id={id}
156
- aria-label={hasLabel ? undefined : t("Date and time")}
157
- aria-required={required || undefined}
158
- aria-invalid={hasError || undefined}
159
- />
160
- <OsDateTimeSheet
161
- open={open}
162
- value={selected ?? new Date()}
163
- mode="datetime"
164
- minDate={minDate}
165
- maxDate={maxDate}
166
- onCancel={() => {
167
- setOpen(false);
168
- blurHandler?.();
169
- }}
170
- onConfirm={(date) => {
171
- commit(date, fieldChange);
172
- blurHandler?.();
173
- }}
174
- />
175
- </>
176
- );
145
+ ) => {
146
+ if (readOnly) {
147
+ return (
148
+ <InputParts.Box>
149
+ <InputParts.Area
150
+ value={display}
151
+ readOnly
152
+ aria-readonly="true"
153
+ aria-required={required || undefined}
154
+ aria-invalid={hasError || undefined}
155
+ placeholder={placeholder}
156
+ />
157
+ </InputParts.Box>
158
+ );
159
+ }
160
+ return (
161
+ <>
162
+ <RNPressable
163
+ onPress={() => !disabled && setOpen(true)}
164
+ disabled={disabled}
165
+ accessibilityRole="button"
166
+ accessibilityLabel={hasLabel ? undefined : t("Date and time")}
167
+ accessibilityValue={{ text: display || placeholder }}
168
+ style={{ width: "100%" }}
169
+ >
170
+ <DatePickerInputTrigger
171
+ value={display}
172
+ placeholder={placeholder}
173
+ disabled={disabled}
174
+ open={open}
175
+ onReset={() => commit(null, fieldChange)}
176
+ onButtonPress={() => {}}
177
+ error={!!hasError}
178
+ id={id}
179
+ aria-label={hasLabel ? undefined : t("Date and time")}
180
+ aria-required={required || undefined}
181
+ aria-invalid={hasError || undefined}
182
+ />
183
+ </RNPressable>
184
+ <OsDateTimeSheet
185
+ open={open}
186
+ value={selected ?? new Date()}
187
+ mode="datetime"
188
+ minDate={minDate}
189
+ maxDate={maxDate}
190
+ onCancel={() => {
191
+ setOpen(false);
192
+ blurHandler?.();
193
+ }}
194
+ onConfirm={(date) => {
195
+ commit(date, fieldChange);
196
+ blurHandler?.();
197
+ }}
198
+ />
199
+ </>
200
+ );
201
+ };
177
202
 
178
203
  if (skeleton) {
179
204
  return (
@@ -50,6 +50,28 @@ export const Baseline: Story = {
50
50
  ),
51
51
  };
52
52
 
53
+ export const StateContract: Story = {
54
+ render: () => {
55
+ const [value, setValue] = useState<Date | null>(null);
56
+ const [edits, setEdits] = useState(0);
57
+ const saved = new Date(2026, 0, 15, 9, 30);
58
+ return (
59
+ <YStack gap="$4" maxWidth={400}>
60
+ <DatetimePicker label="Saved date and time" defaultValue={saved} />
61
+ <DatetimePicker
62
+ label="Programmatic date and time"
63
+ value={value}
64
+ onChange={() => setEdits((count) => count + 1)}
65
+ />
66
+ <Button onPress={() => setValue(new Date(2026, 2, 5, 14, 30))}>Load date and time</Button>
67
+ <Text>{`User edits: ${edits}`}</Text>
68
+ <DatetimePicker label="Read-only date and time" value={saved} readOnly />
69
+ <DatetimePicker label="Disabled date and time" value={saved} disabled />
70
+ </YStack>
71
+ );
72
+ },
73
+ };
74
+
53
75
  export const TwentyFourHour: Story = {
54
76
  args: { timeFormat: "24h", helperText: "24-hour format" },
55
77
  };
@@ -2,6 +2,7 @@ import type { DeepKeys, DeepValue } from "@tanstack/form-core";
2
2
  import { ChevronLeft, ChevronRight } from "@tamagui/lucide-icons-2";
3
3
  import { type ComponentProps, useCallback, useEffect, useRef, useState } from "react";
4
4
  import { Text, View, useProps, type Popover } from "tamagui";
5
+ import { useGlyphColor } from "@multiplatform.one/theme";
5
6
 
6
7
  import { Field, FieldLayout } from "../../fieldLayout";
7
8
  import { t } from "../../shared/t";
@@ -107,6 +108,7 @@ function MonthPickerBody({
107
108
  maxYear,
108
109
  }: MonthPickerBodyProps) {
109
110
  const { knobProps } = useCalendarKnobs();
111
+ const glyphColor = useGlyphColor();
110
112
  const { px } = knobProps.nestedControl;
111
113
  const [viewMode, setViewMode] = useState<ViewMode>("month");
112
114
  const year = displayDate.getFullYear();
@@ -122,6 +124,7 @@ function MonthPickerBody({
122
124
  const handleSelectYear = useCallback(
123
125
  (selectedYear: number) => {
124
126
  const newDate = new Date(displayDate);
127
+ newDate.setDate(1);
125
128
  newDate.setFullYear(selectedYear);
126
129
  onSetDisplayDate(newDate);
127
130
  setViewMode("month");
@@ -131,6 +134,7 @@ function MonthPickerBody({
131
134
 
132
135
  const handlePrevYear = useCallback(() => {
133
136
  const newDate = new Date(displayDate);
137
+ newDate.setDate(1);
134
138
  newDate.setFullYear(newDate.getFullYear() - 1);
135
139
  if (minYear && newDate.getFullYear() < minYear) return;
136
140
  onSetDisplayDate(newDate);
@@ -138,6 +142,7 @@ function MonthPickerBody({
138
142
 
139
143
  const handleNextYear = useCallback(() => {
140
144
  const newDate = new Date(displayDate);
145
+ newDate.setDate(1);
141
146
  newDate.setFullYear(newDate.getFullYear() + 1);
142
147
  if (maxYear && newDate.getFullYear() > maxYear) return;
143
148
  onSetDisplayDate(newDate);
@@ -171,7 +176,7 @@ function MonthPickerBody({
171
176
  {...knobProps.gap}
172
177
  width={px * 7}
173
178
  {...animation}
174
- transition="medium"
179
+ transition={knobProps.transition}
175
180
  >
176
181
  <View flexDirection="row" width={px * 7} alignItems="center" justifyContent="space-between">
177
182
  <CalendarChromeButton
@@ -181,7 +186,7 @@ function MonthPickerBody({
181
186
  label={t("Previous year")}
182
187
  >
183
188
  <View opacity={prevDisabled ? 0.4 : 1}>
184
- <ChevronLeft size={16} />
189
+ <ChevronLeft size={knobProps.controlIcon.width} color={glyphColor} />
185
190
  </View>
186
191
  </CalendarChromeButton>
187
192
 
@@ -198,7 +203,7 @@ function MonthPickerBody({
198
203
  label={t("Next year")}
199
204
  >
200
205
  <View opacity={nextDisabled ? 0.4 : 1}>
201
- <ChevronRight size={16} />
206
+ <ChevronRight size={knobProps.controlIcon.width} color={glyphColor} />
202
207
  </View>
203
208
  </CalendarChromeButton>
204
209
  </View>
@@ -209,6 +209,7 @@ function DualCalendarBody({
209
209
 
210
210
  const prevMonthDate = useMemo(() => {
211
211
  const date = new Date(displayDate);
212
+ date.setDate(1);
212
213
  date.setMonth(date.getMonth() - 1);
213
214
  return date;
214
215
  }, [displayDate]);
@@ -223,6 +224,7 @@ function DualCalendarBody({
223
224
  const handleSetDisplayForPrev = useCallback(
224
225
  (date: Date) => {
225
226
  const next = new Date(date);
227
+ next.setDate(1);
226
228
  next.setMonth(next.getMonth() + 1);
227
229
  setDisplayDate(next);
228
230
  },
@@ -231,7 +233,7 @@ function DualCalendarBody({
231
233
 
232
234
  if (!fullWidthMode) {
233
235
  return (
234
- <View {...knobProps.panelPadding}>
236
+ <View>
235
237
  <SingleCalendar
236
238
  displayDate={displayDate}
237
239
  selectedDates={selectedDates}
@@ -247,7 +249,7 @@ function DualCalendarBody({
247
249
  }
248
250
 
249
251
  return (
250
- <View flexDirection="row" {...knobProps.gap} {...knobProps.panelPadding}>
252
+ <View flexDirection="row" {...knobProps.gap}>
251
253
  <SingleCalendar
252
254
  displayDate={prevMonthDate}
253
255
  selectedDates={selectedDates}
@@ -158,6 +158,7 @@ export function DatePicker<
158
158
  disabled={disabled}
159
159
  accessibilityRole="button"
160
160
  accessibilityLabel={hasLabel ? undefined : t("Date")}
161
+ accessibilityValue={{ text: formatDateDisplay(selectedDate) || placeholder }}
161
162
  style={{ width: "100%" }}
162
163
  >
163
164
  <DatePickerInputTrigger
@@ -0,0 +1,56 @@
1
+ import { act, fireEvent, renderHook } from "@testing-library/react";
2
+ import { useState } from "react";
3
+ import { describe, expect, it } from "vitest";
4
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
5
+ import { CalendarViewSwitcher, useCalendarData, useDateNavigation, type ViewMode } from "./parts";
6
+
7
+ function MonthCursor({ initial, view }: { initial: Date; view: ViewMode }) {
8
+ const [date, setDate] = useState(initial);
9
+ const [viewMode, setViewMode] = useState(view);
10
+ const [yearPageStart, setYearPageStart] = useState(2020);
11
+ const calendarData = useCalendarData(date);
12
+ return (
13
+ <>
14
+ <output data-testid="display-month">{`${date.getFullYear()}-${date.getMonth() + 1}`}</output>
15
+ <CalendarViewSwitcher
16
+ calendarData={calendarData}
17
+ displayDate={date}
18
+ onSetDisplayDate={setDate}
19
+ viewMode={viewMode}
20
+ setViewMode={setViewMode}
21
+ yearPageStart={yearPageStart}
22
+ setYearPageStart={setYearPageStart}
23
+ >
24
+ <span>Day view</span>
25
+ </CalendarViewSwitcher>
26
+ </>
27
+ );
28
+ }
29
+
30
+ describe("calendar display-month navigation", () => {
31
+ it.each([
32
+ ["next", 3],
33
+ ["prev", 1],
34
+ ] as const)("moves %s from March 31 without skipping a month", (direction, month) => {
35
+ const initial = new Date(2024, 2, 31);
36
+ const { result } = renderHook(() => useDateNavigation(initial));
37
+ act(() => result.current.navigateMonth(direction));
38
+ expect(result.current.displayDate.getFullYear()).toBe(2024);
39
+ expect(result.current.displayDate.getMonth()).toBe(month);
40
+ expect(initial.getDate()).toBe(31);
41
+ });
42
+
43
+ it("selects February from a January 31 display cursor", async () => {
44
+ const result = renderWithProviders(
45
+ <MonthCursor initial={new Date(2024, 0, 31)} view="month" />,
46
+ );
47
+ await act(async () => fireEvent.click(result.getByText("Feb")));
48
+ expect(result.getByTestId("display-month").textContent).toBe("2024-2");
49
+ });
50
+
51
+ it("keeps February when switching a leap-day cursor to a non-leap year", async () => {
52
+ const result = renderWithProviders(<MonthCursor initial={new Date(2024, 1, 29)} view="year" />);
53
+ await act(async () => fireEvent.click(result.getByText("2025")));
54
+ expect(result.getByTestId("display-month").textContent).toBe("2025-2");
55
+ });
56
+ });
@@ -10,6 +10,7 @@ import {
10
10
  formatAbsoluteDate,
11
11
  getMonthNames,
12
12
  useAccentOnSurface,
13
+ useGlyphColor,
13
14
  useResolvedKnobs,
14
15
  } from "@multiplatform.one/theme";
15
16
  import {
@@ -23,7 +24,8 @@ import {
23
24
  } from "react";
24
25
  import { AnimatePresence, Text, View, isWeb } from "tamagui";
25
26
 
26
- import { FloatingPanel } from "../../FloatingPanel";
27
+ import { FloatingPanel, floatingPanelActionProps, isNestedPanelAction } from "../../FloatingPanel";
28
+ import type { PanelActionEvent } from "../../FloatingPanel/nestedAction";
27
29
  import { Input as InputParts } from "../../InputParts";
28
30
  import { formCommonColors } from "../../shared/colorRamps";
29
31
  import { t } from "../../shared/t";
@@ -141,6 +143,7 @@ export function useDateNavigation(initialDate?: Date) {
141
143
  const navigateMonth = useCallback((direction: "prev" | "next") => {
142
144
  setDisplayDate((prev) => {
143
145
  const next = new Date(prev);
146
+ next.setDate(1);
144
147
  next.setMonth(next.getMonth() + (direction === "prev" ? -1 : 1));
145
148
  return next;
146
149
  });
@@ -199,7 +202,7 @@ export function CalendarPanelFrame({ children }: { children: ReactNode }) {
199
202
  flexDirection="column"
200
203
  alignItems="center"
201
204
  {...knobProps.gap}
202
- width={px * 7}
205
+ minWidth={px * 7}
203
206
  alignSelf="center"
204
207
  {...knobProps.panelPadding}
205
208
  data-testid="date-picker-calendar"
@@ -484,7 +487,7 @@ export function CalendarDays({
484
487
  return (
485
488
  <AnimatePresence key={animationKey}>
486
489
  <View
487
- transition="medium"
490
+ transition={knobProps.transition}
488
491
  {...animation}
489
492
  alignSelf="center"
490
493
  gap="$1"
@@ -616,6 +619,7 @@ export function CalendarHeader({
616
619
  showNext = true,
617
620
  }: CalendarHeaderProps) {
618
621
  const { knobProps } = useCalendarKnobs();
622
+ const glyphColor = useGlyphColor();
619
623
  const { px } = knobProps.nestedControl;
620
624
  return (
621
625
  <View
@@ -627,7 +631,7 @@ export function CalendarHeader({
627
631
  >
628
632
  {showPrev && onPrevMonth ? (
629
633
  <CalendarChromeButton onPress={onPrevMonth} label={t("Previous month")}>
630
- <CaretLeftIcon size={16} color="currentColor" />
634
+ <CaretLeftIcon size={knobProps.controlIcon.width} color={glyphColor} />
631
635
  </CalendarChromeButton>
632
636
  ) : (
633
637
  <View width={px} height={px} />
@@ -648,7 +652,7 @@ export function CalendarHeader({
648
652
 
649
653
  {showNext && onNextMonth ? (
650
654
  <CalendarChromeButton onPress={onNextMonth} label={t("Next month")}>
651
- <CaretRightIcon size={16} color="currentColor" />
655
+ <CaretRightIcon size={knobProps.controlIcon.width} color={glyphColor} />
652
656
  </CalendarChromeButton>
653
657
  ) : (
654
658
  <View width={px} height={px} />
@@ -677,7 +681,7 @@ export function MonthGrid({ currentYear, selectedMonth, onSelectMonth }: MonthGr
677
681
  <AnimatePresence key={animationKey}>
678
682
  <View
679
683
  {...animation}
680
- transition="quick"
684
+ transition={knobProps.transition}
681
685
  flexDirection="row"
682
686
  flexWrap="wrap"
683
687
  width={px * 7}
@@ -752,6 +756,7 @@ export function YearGrid({
752
756
  onNextPage,
753
757
  }: YearGridProps) {
754
758
  const { knobProps } = useCalendarKnobs();
759
+ const glyphColor = useGlyphColor();
755
760
  const { px, hitSlop, box } = splitNestedControl(knobProps.nestedControl);
756
761
  const cellW = (px * 7) / 3;
757
762
  const years = useMemo(() => {
@@ -768,18 +773,24 @@ export function YearGrid({
768
773
  <View width={px * 7} alignSelf="center" {...knobProps.gap}>
769
774
  <View flexDirection="row" width={px * 7} alignItems="center" justifyContent="space-between">
770
775
  <CalendarChromeButton onPress={onPrevPage} label={t("Previous years")}>
771
- <CaretLeftIcon size={16} color="currentColor" />
776
+ <CaretLeftIcon size={knobProps.controlIcon.width} color={glyphColor} />
772
777
  </CalendarChromeButton>
773
778
  <Text {...knobProps.label} {...knobProps.textWeight}>
774
779
  {years[0]} – {years[years.length - 1]}
775
780
  </Text>
776
781
  <CalendarChromeButton onPress={onNextPage} label={t("Next years")}>
777
- <CaretRightIcon size={16} color="currentColor" />
782
+ <CaretRightIcon size={knobProps.controlIcon.width} color={glyphColor} />
778
783
  </CalendarChromeButton>
779
784
  </View>
780
785
 
781
786
  <AnimatePresence key={animationKey}>
782
- <View {...animation} transition="quick" flexDirection="row" flexWrap="wrap" width={px * 7}>
787
+ <View
788
+ {...animation}
789
+ transition={knobProps.transition}
790
+ flexDirection="row"
791
+ flexWrap="wrap"
792
+ width={px * 7}
793
+ >
783
794
  {years.map((year) => {
784
795
  const isSelected = year === selectedYear;
785
796
  return (
@@ -863,6 +874,7 @@ export function DatePickerClearButton({
863
874
  }) {
864
875
  return (
865
876
  <InputParts.Button
877
+ {...floatingPanelActionProps}
866
878
  data-testid="date-picker-clear"
867
879
  aria-label={label ?? t("Clear date")}
868
880
  disabled={disabled}
@@ -894,8 +906,10 @@ export function DatePickerInputTrigger({
894
906
  "aria-required": ariaRequired,
895
907
  "aria-invalid": ariaInvalid,
896
908
  }: DatePickerInputTriggerProps) {
897
- const handleTriggerKey = (e: { key?: string; code?: string; preventDefault?: () => void }) => {
898
- if (disabled) return;
909
+ const handleTriggerKey = (
910
+ e: PanelActionEvent & { key?: string; code?: string; preventDefault?: () => void },
911
+ ) => {
912
+ if (disabled || isNestedPanelAction(e)) return;
899
913
  const key = e.key;
900
914
  if (key === "Enter" || key === " " || key === "ArrowDown" || e.code === "Space") {
901
915
  e.preventDefault?.();
@@ -920,9 +934,13 @@ export function DatePickerInputTrigger({
920
934
  alignItems="center"
921
935
  width="100%"
922
936
  cursor={disabled ? "not-allowed" : "pointer"}
937
+ // Native parents own the tap; expanded field paint must not consume it.
938
+ pointerEvents={isWeb ? undefined : "none"}
923
939
  >
924
940
  <InputParts.Box
925
941
  theme={error ? "red" : undefined}
942
+ // Yoga has no intrinsic TextInput width to size this row child.
943
+ {...(isWeb ? undefined : { flex: 1, minWidth: 0 })}
926
944
  // Elevation is an overlay recipe: it belongs on the open panel, never
927
945
  // on the closed text-field trigger.
928
946
  elevation={undefined}
@@ -1014,7 +1032,8 @@ export function DatePickerPopoverShell({
1014
1032
  triggerEnd={triggerEnd ?? nativeClear}
1015
1033
  disabled={disabled}
1016
1034
  sizing="grow"
1017
- widthMode="at-least-trigger"
1035
+ contentPadding="none"
1036
+ widthMode="fit-content"
1018
1037
  triggerA11y={triggerA11y}
1019
1038
  >
1020
1039
  {children}
@@ -1051,6 +1070,7 @@ export function CalendarViewSwitcher({
1051
1070
  const handleSelectMonth = useCallback(
1052
1071
  (month: number) => {
1053
1072
  const newDate = new Date(displayDate);
1073
+ newDate.setDate(1);
1054
1074
  newDate.setMonth(month);
1055
1075
  onSetDisplayDate(newDate);
1056
1076
  setViewMode("day");
@@ -1061,6 +1081,7 @@ export function CalendarViewSwitcher({
1061
1081
  const handleSelectYear = useCallback(
1062
1082
  (year: number) => {
1063
1083
  const newDate = new Date(displayDate);
1084
+ newDate.setDate(1);
1064
1085
  newDate.setFullYear(year);
1065
1086
  onSetDisplayDate(newDate);
1066
1087
  setViewMode("month");