@multiplatform.one/forms 7.7.6 → 7.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/dist/cjs/Button/index.cjs +1 -4
  2. package/dist/cjs/Button/index.native.js +5 -6
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/Chip/index.cjs +1 -1
  5. package/dist/cjs/Chip/index.native.js +1 -1
  6. package/dist/cjs/Chip/index.native.js.map +1 -1
  7. package/dist/cjs/FloatingPanel/index.cjs +59 -14
  8. package/dist/cjs/FloatingPanel/index.native.js +16 -7
  9. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  10. package/dist/cjs/FloatingPanel/nestedAction.cjs +37 -0
  11. package/dist/cjs/FloatingPanel/nestedAction.native.js +42 -0
  12. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -0
  13. package/dist/cjs/InputParts/index.cjs +19 -8
  14. package/dist/cjs/InputParts/index.native.js +20 -11
  15. package/dist/cjs/InputParts/index.native.js.map +1 -1
  16. package/dist/cjs/Wheel/index.cjs +3 -3
  17. package/dist/cjs/Wheel/index.native.js +3 -3
  18. package/dist/cjs/Wheel/index.native.js.map +1 -1
  19. package/dist/cjs/fieldLayout.cjs +3 -3
  20. package/dist/cjs/fieldLayout.native.js +3 -3
  21. package/dist/cjs/fieldLayout.native.js.map +1 -1
  22. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.cjs +9 -2
  23. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  24. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  25. package/dist/cjs/fields/Combobox/index.cjs +36 -29
  26. package/dist/cjs/fields/Combobox/index.native.js +38 -38
  27. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  28. package/dist/cjs/fields/DatePicker/Calendar.cjs +6 -1
  29. package/dist/cjs/fields/DatePicker/Calendar.native.js +6 -1
  30. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  31. package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +2 -2
  32. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  33. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  34. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +15 -12
  35. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  36. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  37. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +39 -14
  38. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  39. package/dist/cjs/fields/DatePicker/MonthPicker.cjs +10 -3
  40. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +10 -3
  41. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  42. package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +2 -2
  43. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  44. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  45. package/dist/cjs/fields/DatePicker/index.native.js +3 -0
  46. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  47. package/dist/cjs/fields/DatePicker/parts.cjs +26 -14
  48. package/dist/cjs/fields/DatePicker/parts.native.js +28 -14
  49. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  50. package/dist/cjs/fields/FileUpload/index.cjs +6 -0
  51. package/dist/cjs/fields/FileUpload/index.native.js +6 -0
  52. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  53. package/dist/cjs/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  54. package/dist/cjs/fields/Geolocation/geocoder.cjs +63 -0
  55. package/dist/cjs/fields/Geolocation/geocoder.native.js +68 -0
  56. package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -0
  57. package/dist/cjs/fields/Geolocation/index.cjs +801 -152
  58. package/dist/cjs/fields/Geolocation/index.native.js +856 -167
  59. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  60. package/dist/cjs/fields/Geolocation/nativeSearchFocus.cjs +44 -0
  61. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  62. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  63. package/dist/cjs/fields/Icon/drawnSet.cjs +16 -3
  64. package/dist/cjs/fields/Icon/drawnSet.native.js +20 -3
  65. package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
  66. package/dist/cjs/fields/Icon/index.cjs +102 -27
  67. package/dist/cjs/fields/Icon/index.native.js +115 -31
  68. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  69. package/dist/cjs/fields/Input/index.cjs +5 -12
  70. package/dist/cjs/fields/Input/index.native.js +5 -13
  71. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  72. package/dist/cjs/fields/PhoneInput/index.cjs +2 -2
  73. package/dist/cjs/fields/PhoneInput/index.native.js +2 -2
  74. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  75. package/dist/cjs/fields/RadioGroup/index.cjs +34 -5
  76. package/dist/cjs/fields/RadioGroup/index.native.js +49 -7
  77. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  78. package/dist/cjs/fields/SearchInput/index.cjs +8 -9
  79. package/dist/cjs/fields/SearchInput/index.native.js +8 -9
  80. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  81. package/dist/cjs/fields/Select/index.cjs +42 -11
  82. package/dist/cjs/fields/Select/index.native.js +52 -20
  83. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  84. package/dist/cjs/fields/Stepper/index.cjs +144 -31
  85. package/dist/cjs/fields/Stepper/index.native.js +151 -31
  86. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  87. package/dist/cjs/fields/ToggleGroup/index.cjs +35 -2
  88. package/dist/cjs/fields/ToggleGroup/index.native.js +42 -2
  89. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  90. package/dist/cjs/index.cjs +2 -0
  91. package/dist/cjs/index.native.js +2 -0
  92. package/dist/cjs/index.native.js.map +1 -1
  93. package/dist/cjs/shared/focusManagement.cjs +24 -11
  94. package/dist/cjs/shared/focusManagement.native.js +24 -11
  95. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  96. package/dist/cjs/shared/nativeA11y.cjs +57 -0
  97. package/dist/cjs/shared/nativeA11y.native.js +61 -0
  98. package/dist/cjs/shared/nativeA11y.native.js.map +1 -0
  99. package/dist/esm/Button/index.mjs +1 -4
  100. package/dist/esm/Button/index.mjs.map +1 -1
  101. package/dist/esm/Button/index.native.js +5 -6
  102. package/dist/esm/Button/index.native.js.map +1 -1
  103. package/dist/esm/Chip/index.mjs +1 -1
  104. package/dist/esm/Chip/index.mjs.map +1 -1
  105. package/dist/esm/Chip/index.native.js +1 -1
  106. package/dist/esm/Chip/index.native.js.map +1 -1
  107. package/dist/esm/FloatingPanel/index.mjs +58 -15
  108. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  109. package/dist/esm/FloatingPanel/index.native.js +15 -8
  110. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  111. package/dist/esm/FloatingPanel/nestedAction.mjs +11 -0
  112. package/dist/esm/FloatingPanel/nestedAction.mjs.map +1 -0
  113. package/dist/esm/FloatingPanel/nestedAction.native.js +13 -0
  114. package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -0
  115. package/dist/esm/InputParts/index.mjs +20 -9
  116. package/dist/esm/InputParts/index.mjs.map +1 -1
  117. package/dist/esm/InputParts/index.native.js +21 -12
  118. package/dist/esm/InputParts/index.native.js.map +1 -1
  119. package/dist/esm/Wheel/index.mjs +3 -3
  120. package/dist/esm/Wheel/index.mjs.map +1 -1
  121. package/dist/esm/Wheel/index.native.js +3 -3
  122. package/dist/esm/Wheel/index.native.js.map +1 -1
  123. package/dist/esm/fieldLayout.mjs +3 -3
  124. package/dist/esm/fieldLayout.mjs.map +1 -1
  125. package/dist/esm/fieldLayout.native.js +3 -3
  126. package/dist/esm/fieldLayout.native.js.map +1 -1
  127. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  128. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  129. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  130. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  131. package/dist/esm/fields/Combobox/index.mjs +36 -29
  132. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  133. package/dist/esm/fields/Combobox/index.native.js +38 -38
  134. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  135. package/dist/esm/fields/DatePicker/Calendar.mjs +6 -1
  136. package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
  137. package/dist/esm/fields/DatePicker/Calendar.native.js +6 -1
  138. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  139. package/dist/esm/fields/DatePicker/DateRangePicker.mjs +2 -2
  140. package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  141. package/dist/esm/fields/DatePicker/DateRangePicker.native.js +2 -2
  142. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  143. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  144. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  145. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  146. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  147. package/dist/esm/fields/DatePicker/DatetimePicker.native.js +39 -14
  148. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  149. package/dist/esm/fields/DatePicker/MonthPicker.mjs +10 -3
  150. package/dist/esm/fields/DatePicker/MonthPicker.mjs.map +1 -1
  151. package/dist/esm/fields/DatePicker/MonthPicker.native.js +10 -3
  152. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  153. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +2 -2
  154. package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  155. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +2 -2
  156. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  157. package/dist/esm/fields/DatePicker/index.native.js +3 -0
  158. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  159. package/dist/esm/fields/DatePicker/parts.mjs +28 -16
  160. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  161. package/dist/esm/fields/DatePicker/parts.native.js +30 -16
  162. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  163. package/dist/esm/fields/FileUpload/index.mjs +6 -0
  164. package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
  165. package/dist/esm/fields/FileUpload/index.native.js +6 -0
  166. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  167. package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  168. package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  169. package/dist/esm/fields/Geolocation/geocoder.mjs +33 -0
  170. package/dist/esm/fields/Geolocation/geocoder.mjs.map +1 -0
  171. package/dist/esm/fields/Geolocation/geocoder.native.js +35 -0
  172. package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -0
  173. package/dist/esm/fields/Geolocation/index.mjs +792 -149
  174. package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
  175. package/dist/esm/fields/Geolocation/index.native.js +847 -164
  176. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  177. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  178. package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  179. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js +19 -0
  180. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  181. package/dist/esm/fields/Icon/drawnSet.mjs +16 -3
  182. package/dist/esm/fields/Icon/drawnSet.mjs.map +1 -1
  183. package/dist/esm/fields/Icon/drawnSet.native.js +20 -3
  184. package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
  185. package/dist/esm/fields/Icon/index.mjs +93 -18
  186. package/dist/esm/fields/Icon/index.mjs.map +1 -1
  187. package/dist/esm/fields/Icon/index.native.js +106 -22
  188. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  189. package/dist/esm/fields/Input/index.mjs +5 -12
  190. package/dist/esm/fields/Input/index.mjs.map +1 -1
  191. package/dist/esm/fields/Input/index.native.js +5 -13
  192. package/dist/esm/fields/Input/index.native.js.map +1 -1
  193. package/dist/esm/fields/PhoneInput/index.mjs +2 -2
  194. package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
  195. package/dist/esm/fields/PhoneInput/index.native.js +2 -2
  196. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  197. package/dist/esm/fields/RadioGroup/index.mjs +34 -5
  198. package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
  199. package/dist/esm/fields/RadioGroup/index.native.js +49 -7
  200. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  201. package/dist/esm/fields/SearchInput/index.mjs +9 -10
  202. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  203. package/dist/esm/fields/SearchInput/index.native.js +9 -10
  204. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  205. package/dist/esm/fields/Select/index.mjs +42 -11
  206. package/dist/esm/fields/Select/index.mjs.map +1 -1
  207. package/dist/esm/fields/Select/index.native.js +52 -20
  208. package/dist/esm/fields/Select/index.native.js.map +1 -1
  209. package/dist/esm/fields/Stepper/index.mjs +145 -32
  210. package/dist/esm/fields/Stepper/index.mjs.map +1 -1
  211. package/dist/esm/fields/Stepper/index.native.js +152 -32
  212. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  213. package/dist/esm/fields/ToggleGroup/index.mjs +35 -2
  214. package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
  215. package/dist/esm/fields/ToggleGroup/index.native.js +42 -2
  216. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  217. package/dist/esm/index.mjs +2 -1
  218. package/dist/esm/index.mjs.map +1 -1
  219. package/dist/esm/index.native.js +2 -1
  220. package/dist/esm/index.native.js.map +1 -1
  221. package/dist/esm/shared/focusManagement.mjs +24 -11
  222. package/dist/esm/shared/focusManagement.mjs.map +1 -1
  223. package/dist/esm/shared/focusManagement.native.js +24 -11
  224. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  225. package/dist/esm/shared/nativeA11y.mjs +31 -0
  226. package/dist/esm/shared/nativeA11y.mjs.map +1 -0
  227. package/dist/esm/shared/nativeA11y.native.js +32 -0
  228. package/dist/esm/shared/nativeA11y.native.js.map +1 -0
  229. package/dist/jsx/Button/index.mjs +1 -4
  230. package/dist/jsx/Button/index.mjs.map +1 -1
  231. package/dist/jsx/Button/index.native.js +5 -6
  232. package/dist/jsx/Button/index.native.js.map +1 -1
  233. package/dist/jsx/Chip/index.mjs +1 -1
  234. package/dist/jsx/Chip/index.mjs.map +1 -1
  235. package/dist/jsx/Chip/index.native.js +1 -1
  236. package/dist/jsx/Chip/index.native.js.map +1 -1
  237. package/dist/jsx/FloatingPanel/index.mjs +58 -15
  238. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  239. package/dist/jsx/FloatingPanel/index.native.js +16 -7
  240. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  241. package/dist/jsx/FloatingPanel/nestedAction.mjs +11 -0
  242. package/dist/jsx/FloatingPanel/nestedAction.mjs.map +1 -0
  243. package/dist/jsx/FloatingPanel/nestedAction.native.js +42 -0
  244. package/dist/jsx/FloatingPanel/nestedAction.native.js.map +1 -0
  245. package/dist/jsx/InputParts/index.mjs +20 -9
  246. package/dist/jsx/InputParts/index.mjs.map +1 -1
  247. package/dist/jsx/InputParts/index.native.js +20 -11
  248. package/dist/jsx/InputParts/index.native.js.map +1 -1
  249. package/dist/jsx/Wheel/index.mjs +3 -3
  250. package/dist/jsx/Wheel/index.mjs.map +1 -1
  251. package/dist/jsx/Wheel/index.native.js +3 -3
  252. package/dist/jsx/Wheel/index.native.js.map +1 -1
  253. package/dist/jsx/fieldLayout.mjs +3 -3
  254. package/dist/jsx/fieldLayout.mjs.map +1 -1
  255. package/dist/jsx/fieldLayout.native.js +3 -3
  256. package/dist/jsx/fieldLayout.native.js.map +1 -1
  257. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
  258. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
  259. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
  260. package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  261. package/dist/jsx/fields/Combobox/index.mjs +36 -29
  262. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  263. package/dist/jsx/fields/Combobox/index.native.js +38 -38
  264. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  265. package/dist/jsx/fields/DatePicker/Calendar.mjs +6 -1
  266. package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
  267. package/dist/jsx/fields/DatePicker/Calendar.native.js +6 -1
  268. package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
  269. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +2 -2
  270. package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
  271. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +2 -2
  272. package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  273. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
  274. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  275. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
  276. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  277. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +39 -14
  278. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  279. package/dist/jsx/fields/DatePicker/MonthPicker.mjs +10 -3
  280. package/dist/jsx/fields/DatePicker/MonthPicker.mjs.map +1 -1
  281. package/dist/jsx/fields/DatePicker/MonthPicker.native.js +10 -3
  282. package/dist/jsx/fields/DatePicker/MonthPicker.native.js.map +1 -1
  283. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +2 -2
  284. package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
  285. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +2 -2
  286. package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  287. package/dist/jsx/fields/DatePicker/index.native.js +3 -0
  288. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  289. package/dist/jsx/fields/DatePicker/parts.mjs +28 -16
  290. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  291. package/dist/jsx/fields/DatePicker/parts.native.js +28 -14
  292. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  293. package/dist/jsx/fields/FileUpload/index.mjs +6 -0
  294. package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
  295. package/dist/jsx/fields/FileUpload/index.native.js +6 -0
  296. package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
  297. package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
  298. package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
  299. package/dist/jsx/fields/Geolocation/geocoder.mjs +33 -0
  300. package/dist/jsx/fields/Geolocation/geocoder.mjs.map +1 -0
  301. package/dist/jsx/fields/Geolocation/geocoder.native.js +68 -0
  302. package/dist/jsx/fields/Geolocation/geocoder.native.js.map +1 -0
  303. package/dist/jsx/fields/Geolocation/index.mjs +792 -149
  304. package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
  305. package/dist/jsx/fields/Geolocation/index.native.js +856 -167
  306. package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
  307. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs +19 -0
  308. package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
  309. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js +47 -0
  310. package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
  311. package/dist/jsx/fields/Icon/drawnSet.mjs +16 -3
  312. package/dist/jsx/fields/Icon/drawnSet.mjs.map +1 -1
  313. package/dist/jsx/fields/Icon/drawnSet.native.js +20 -3
  314. package/dist/jsx/fields/Icon/drawnSet.native.js.map +1 -1
  315. package/dist/jsx/fields/Icon/index.mjs +93 -18
  316. package/dist/jsx/fields/Icon/index.mjs.map +1 -1
  317. package/dist/jsx/fields/Icon/index.native.js +115 -31
  318. package/dist/jsx/fields/Icon/index.native.js.map +1 -1
  319. package/dist/jsx/fields/Input/index.mjs +5 -12
  320. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  321. package/dist/jsx/fields/Input/index.native.js +5 -13
  322. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  323. package/dist/jsx/fields/PhoneInput/index.mjs +2 -2
  324. package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
  325. package/dist/jsx/fields/PhoneInput/index.native.js +2 -2
  326. package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
  327. package/dist/jsx/fields/RadioGroup/index.mjs +34 -5
  328. package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
  329. package/dist/jsx/fields/RadioGroup/index.native.js +49 -7
  330. package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
  331. package/dist/jsx/fields/SearchInput/index.mjs +9 -10
  332. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  333. package/dist/jsx/fields/SearchInput/index.native.js +8 -9
  334. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  335. package/dist/jsx/fields/Select/index.mjs +42 -11
  336. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  337. package/dist/jsx/fields/Select/index.native.js +52 -20
  338. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  339. package/dist/jsx/fields/Stepper/index.mjs +145 -32
  340. package/dist/jsx/fields/Stepper/index.mjs.map +1 -1
  341. package/dist/jsx/fields/Stepper/index.native.js +151 -31
  342. package/dist/jsx/fields/Stepper/index.native.js.map +1 -1
  343. package/dist/jsx/fields/ToggleGroup/index.mjs +35 -2
  344. package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
  345. package/dist/jsx/fields/ToggleGroup/index.native.js +42 -2
  346. package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
  347. package/dist/jsx/index.js +2 -1
  348. package/dist/jsx/index.js.map +1 -1
  349. package/dist/jsx/index.mjs +2 -1
  350. package/dist/jsx/index.mjs.map +1 -1
  351. package/dist/jsx/index.native.js +2 -0
  352. package/dist/jsx/index.native.js.map +1 -1
  353. package/dist/jsx/shared/focusManagement.mjs +24 -11
  354. package/dist/jsx/shared/focusManagement.mjs.map +1 -1
  355. package/dist/jsx/shared/focusManagement.native.js +24 -11
  356. package/dist/jsx/shared/focusManagement.native.js.map +1 -1
  357. package/dist/jsx/shared/nativeA11y.mjs +31 -0
  358. package/dist/jsx/shared/nativeA11y.mjs.map +1 -0
  359. package/dist/jsx/shared/nativeA11y.native.js +61 -0
  360. package/dist/jsx/shared/nativeA11y.native.js.map +1 -0
  361. package/package.json +9 -7
  362. package/src/Button/Button.fontWeight.spec.tsx +75 -0
  363. package/src/Button/Button.labelInk.spec.tsx +21 -18
  364. package/src/Button/Button.outlinedChannel.spec.tsx +46 -0
  365. package/src/Button/Button.sizeLadder.spec.tsx +4 -3
  366. package/src/Button/Button.stories.tsx +20 -0
  367. package/src/Button/index.tsx +30 -7
  368. package/src/Chip/Chip.spec.tsx +3 -1
  369. package/src/Chip/index.tsx +1 -5
  370. package/src/FieldGroup.stories.tsx +3 -7
  371. package/src/FieldLayout.stories.tsx +75 -12
  372. package/src/Fieldset.stories.tsx +3 -7
  373. package/src/FloatingPanel/FloatingPanel.native.spec.tsx +54 -0
  374. package/src/FloatingPanel/FloatingPanel.spec.tsx +109 -0
  375. package/src/FloatingPanel/index.native.tsx +24 -7
  376. package/src/FloatingPanel/index.tsx +80 -13
  377. package/src/FloatingPanel/nestedAction.spec.ts +36 -0
  378. package/src/FloatingPanel/nestedAction.ts +15 -0
  379. package/src/FloatingPanel/panelWidthContract.spec.ts +12 -15
  380. package/src/FormGrid.stories.tsx +5 -11
  381. package/src/FormsIntegration.stories.tsx +2 -6
  382. package/src/InputParts/InputButton.spec.tsx +16 -0
  383. package/src/InputParts/index.tsx +34 -7
  384. package/src/InputParts/layoutGap.spec.tsx +43 -0
  385. package/src/Wheel/Wheel.spec.tsx +16 -0
  386. package/src/Wheel/index.tsx +3 -3
  387. package/src/fieldFamilyStories.radius.spec.tsx +118 -0
  388. package/src/fieldLayout.spec.tsx +42 -1
  389. package/src/fieldLayout.tsx +9 -9
  390. package/src/fields/Barcode/Barcode.spec.tsx +2 -0
  391. package/src/fields/Checkbox/CheckboxFieldFrame.spec.tsx +18 -0
  392. package/src/fields/Checkbox/CheckboxFieldFrame.tsx +6 -1
  393. package/src/fields/Combobox/Combobox.spec.tsx +48 -1
  394. package/src/fields/Combobox/index.tsx +53 -39
  395. package/src/fields/DatePicker/Calendar.tsx +4 -1
  396. package/src/fields/DatePicker/DatePicker.stories.tsx +22 -1
  397. package/src/fields/DatePicker/DateRangePicker.tsx +4 -2
  398. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +21 -19
  399. package/src/fields/DatePicker/DatetimePicker.native.spec.tsx +144 -0
  400. package/src/fields/DatePicker/DatetimePicker.native.tsx +57 -32
  401. package/src/fields/DatePicker/DatetimePicker.stories.tsx +22 -0
  402. package/src/fields/DatePicker/MonthPicker.tsx +8 -3
  403. package/src/fields/DatePicker/MultiDatePicker.tsx +4 -2
  404. package/src/fields/DatePicker/index.native.tsx +1 -0
  405. package/src/fields/DatePicker/parts.spec.tsx +56 -0
  406. package/src/fields/DatePicker/parts.tsx +33 -12
  407. package/src/fields/FileUpload/FileUpload.spec.tsx +29 -0
  408. package/src/fields/FileUpload/index.tsx +6 -0
  409. package/src/fields/Geolocation/Geolocation.spec.tsx +287 -35
  410. package/src/fields/Geolocation/Geolocation.stories.tsx +141 -7
  411. package/src/fields/Geolocation/GeolocationMap.native.tsx +3 -0
  412. package/src/fields/Geolocation/GeolocationMap.tsx +4 -0
  413. package/src/fields/Geolocation/geocoder.spec.ts +59 -0
  414. package/src/fields/Geolocation/geocoder.ts +84 -0
  415. package/src/fields/Geolocation/geocoderSeam.spec.tsx +203 -0
  416. package/src/fields/Geolocation/index.tsx +912 -180
  417. package/src/fields/Geolocation/nativeSearchFocus.spec.ts +34 -0
  418. package/src/fields/Geolocation/nativeSearchFocus.ts +19 -0
  419. package/src/fields/Geolocation/salvage.spec.tsx +398 -0
  420. package/src/fields/Geolocation/storyProviders.spec.tsx +44 -0
  421. package/src/fields/Icon/Icon.spec.tsx +215 -1
  422. package/src/fields/Icon/Icon.stories.tsx +9 -1
  423. package/src/fields/Icon/drawnSet.tsx +44 -4
  424. package/src/fields/Icon/index.tsx +118 -18
  425. package/src/fields/Input/Input.copy.spec.tsx +1 -0
  426. package/src/fields/Input/Input.spec.tsx +50 -0
  427. package/src/fields/Input/Input.stories.tsx +1 -1
  428. package/src/fields/Input/index.tsx +7 -13
  429. package/src/fields/PhoneInput/index.tsx +2 -2
  430. package/src/fields/RadioGroup/RadioGroup.native.spec.tsx +67 -0
  431. package/src/fields/RadioGroup/index.tsx +82 -8
  432. package/src/fields/SearchInput/SearchInput.spec.tsx +14 -0
  433. package/src/fields/SearchInput/index.tsx +5 -6
  434. package/src/fields/Select/Select.spec.tsx +54 -0
  435. package/src/fields/Select/index.tsx +52 -17
  436. package/src/fields/Stepper/Stepper.spec.tsx +34 -1
  437. package/src/fields/Stepper/index.tsx +193 -33
  438. package/src/fields/ToggleGroup/ToggleGroup.native.spec.tsx +73 -0
  439. package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +49 -0
  440. package/src/fields/ToggleGroup/index.tsx +76 -1
  441. package/src/index.ts +9 -0
  442. package/src/shared/focusManagement.spec.tsx +68 -0
  443. package/src/shared/focusManagement.ts +20 -10
  444. package/src/shared/nativeA11y.spec.ts +64 -0
  445. package/src/shared/nativeA11y.ts +80 -0
  446. package/types/Button/index.d.ts +22 -3
  447. package/types/Button/index.d.ts.map +1 -1
  448. package/types/Chip/index.d.ts.map +1 -1
  449. package/types/FloatingPanel/index.d.ts +11 -1
  450. package/types/FloatingPanel/index.d.ts.map +1 -1
  451. package/types/FloatingPanel/index.native.d.ts +2 -1
  452. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  453. package/types/FloatingPanel/nestedAction.d.ts +13 -0
  454. package/types/FloatingPanel/nestedAction.d.ts.map +1 -0
  455. package/types/InputParts/index.d.ts.map +1 -1
  456. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts +46 -2
  457. package/types/fields/Checkbox/CheckboxFieldFrame.d.ts.map +1 -1
  458. package/types/fields/Checkbox/index.d.ts +3 -3
  459. package/types/fields/Combobox/index.d.ts +3 -1
  460. package/types/fields/Combobox/index.d.ts.map +1 -1
  461. package/types/fields/DatePicker/Calendar.d.ts.map +1 -1
  462. package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
  463. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
  464. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
  465. package/types/fields/DatePicker/MonthPicker.d.ts.map +1 -1
  466. package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
  467. package/types/fields/DatePicker/index.native.d.ts.map +1 -1
  468. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  469. package/types/fields/FileUpload/index.d.ts.map +1 -1
  470. package/types/fields/Geolocation/GeolocationMap.d.ts +4 -0
  471. package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
  472. package/types/fields/Geolocation/GeolocationMap.native.d.ts +3 -0
  473. package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
  474. package/types/fields/Geolocation/geocoder.d.ts +53 -0
  475. package/types/fields/Geolocation/geocoder.d.ts.map +1 -0
  476. package/types/fields/Geolocation/index.d.ts +18 -2
  477. package/types/fields/Geolocation/index.d.ts.map +1 -1
  478. package/types/fields/Geolocation/nativeSearchFocus.d.ts +8 -0
  479. package/types/fields/Geolocation/nativeSearchFocus.d.ts.map +1 -0
  480. package/types/fields/Icon/drawnSet.d.ts.map +1 -1
  481. package/types/fields/Icon/index.d.ts.map +1 -1
  482. package/types/fields/Input/index.d.ts.map +1 -1
  483. package/types/fields/PhoneInput/index.d.ts.map +1 -1
  484. package/types/fields/RadioGroup/index.d.ts +30 -3
  485. package/types/fields/RadioGroup/index.d.ts.map +1 -1
  486. package/types/fields/SearchInput/index.d.ts.map +1 -1
  487. package/types/fields/Select/index.d.ts.map +1 -1
  488. package/types/fields/Stepper/index.d.ts.map +1 -1
  489. package/types/fields/ToggleGroup/index.d.ts +31 -2
  490. package/types/fields/ToggleGroup/index.d.ts.map +1 -1
  491. package/types/index.d.ts +2 -0
  492. package/types/index.d.ts.map +1 -1
  493. package/types/shared/focusManagement.d.ts +2 -2
  494. package/types/shared/focusManagement.d.ts.map +1 -1
  495. package/types/shared/nativeA11y.d.ts +61 -0
  496. package/types/shared/nativeA11y.d.ts.map +1 -0
  497. package/src/router.d.ts +0 -16
@@ -1,5 +1,5 @@
1
1
  import { act, fireEvent } from "@testing-library/react";
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
3
  import { renderWithProviders } from "@multiplatform.one/test-utils";
4
4
  import { Form } from "../../Form";
5
5
  import { Combobox } from "./index";
@@ -11,6 +11,53 @@ const options = [
11
11
  ];
12
12
 
13
13
  describe("Combobox", () => {
14
+ describe("custom sheet trigger", () => {
15
+ const initialWidth = window.innerWidth;
16
+ afterEach(() => {
17
+ window.innerWidth = initialWidth;
18
+ });
19
+
20
+ it("keeps the same name and keyboard opener on narrow and wide screens", async () => {
21
+ for (const width of [500, 1200]) {
22
+ window.innerWidth = width;
23
+ const result = renderWithProviders(
24
+ <Combobox
25
+ options={options}
26
+ aria-label="Country code"
27
+ trigger={() => <span>Country</span>}
28
+ />,
29
+ );
30
+ const trigger = result.container.querySelector('[role="combobox"]');
31
+ expect(trigger?.getAttribute("aria-label")).toBe("Country code");
32
+ expect(trigger?.getAttribute("tabindex")).toBe("0");
33
+ expect(trigger?.getAttribute("aria-expanded")).toBe("false");
34
+ await act(async () => fireEvent.keyDown(trigger!, { key: "Enter" }));
35
+ expect(trigger?.getAttribute("aria-expanded")).toBe("true");
36
+ result.unmount();
37
+ }
38
+ });
39
+
40
+ it("lets a custom adornment hug its content while ordinary triggers keep stretching", () => {
41
+ for (const width of [500, 1200]) {
42
+ window.innerWidth = width;
43
+ for (const triggerSizing of [undefined, "content"] as const) {
44
+ const result = renderWithProviders(
45
+ <Combobox
46
+ options={options}
47
+ triggerSizing={triggerSizing}
48
+ trigger={() => <span>Country</span>}
49
+ />,
50
+ );
51
+ const trigger = result.container.querySelector<HTMLElement>(
52
+ '[data-testid="combobox-trigger"]',
53
+ );
54
+ expect(trigger?.style.width).toBe(triggerSizing === "content" ? "auto" : "100%");
55
+ result.unmount();
56
+ }
57
+ }
58
+ });
59
+ });
60
+
14
61
  describe("without form context", () => {
15
62
  it("renders with label", () => {
16
63
  const result = renderWithProviders(<Combobox label="Fruit" name="fruit" options={options} />);
@@ -191,6 +191,8 @@ export interface ComboboxProps {
191
191
  /** Whether more pages are available. Shows a spinner at the bottom when loading more. */
192
192
  hasMore?: boolean;
193
193
  trigger?: (selected: ComboboxOption | ComboboxOption[] | undefined, open: boolean) => ReactNode;
194
+ /** Custom triggers stretch by default; content hugs a composite-field adornment. */
195
+ triggerSizing?: "stretch" | "content";
194
196
  name?: string;
195
197
  form?: AnyFormApi;
196
198
  validators?: Record<string, unknown>;
@@ -458,6 +460,7 @@ interface FloatingComboboxCoreProps {
458
460
  tabIndexOverride?: number;
459
461
  popoverWidth?: number;
460
462
  trigger?: (selected: ComboboxOption | ComboboxOption[] | undefined, open: boolean) => ReactNode;
463
+ triggerSizing?: "stretch" | "content";
461
464
  knobProps: KnobProps;
462
465
  multiple?: boolean;
463
466
  selectedOrder?: SelectedOrder;
@@ -493,6 +496,7 @@ function FloatingComboboxCore({
493
496
  tabIndexOverride,
494
497
  popoverWidth,
495
498
  trigger: triggerRender,
499
+ triggerSizing = "stretch",
496
500
  knobProps,
497
501
  multiple,
498
502
  selectedOrder,
@@ -1351,12 +1355,16 @@ function FloatingComboboxCore({
1351
1355
  <View
1352
1356
  {...boxEventProps}
1353
1357
  data-testid="combobox-trigger"
1354
- width="100%"
1358
+ width={triggerSizing === "content" ? "auto" : "100%"}
1355
1359
  alignSelf="stretch"
1356
1360
  flexShrink={0}
1357
1361
  outlineWidth={0}
1358
1362
  focusVisibleStyle={ensureFocusVisibleRing({ outlineOffset: -2 })}
1359
- style={{ display: "flex", alignItems: "stretch", width: "100%" }}
1363
+ style={{
1364
+ display: "flex",
1365
+ alignItems: "stretch",
1366
+ width: triggerSizing === "content" ? "auto" : "100%",
1367
+ }}
1360
1368
  >
1361
1369
  {triggerRender(multiple ? selectedOptions : selectedOption, open)}
1362
1370
  </View>
@@ -1785,6 +1793,7 @@ function NativeComboboxCore({
1785
1793
  "aria-label": ariaLabel,
1786
1794
  hasLabel,
1787
1795
  trigger: triggerRender,
1796
+ triggerSizing = "stretch",
1788
1797
  knobProps,
1789
1798
  multiple,
1790
1799
  selectedOrder,
@@ -2369,15 +2378,51 @@ function NativeComboboxCore({
2369
2378
  </View>
2370
2379
  );
2371
2380
 
2381
+ // Both trigger shapes share one accessible control. The sheet wrapper's
2382
+ // capture handler also opens it, so pointer activation is idempotent.
2383
+ const triggerProps = {
2384
+ id,
2385
+ ...(isWeb
2386
+ ? {
2387
+ role: "combobox" as const,
2388
+ "aria-haspopup": "listbox" as const,
2389
+ "aria-expanded": open,
2390
+ "aria-controls": listboxId,
2391
+ "aria-activedescendant": hideSearch ? activeDescendant : undefined,
2392
+ "aria-autocomplete": hideSearch ? ("list" as const) : undefined,
2393
+ "aria-label": ariaLabel ?? (!hasLabel ? placeholder : undefined),
2394
+ "aria-describedby": describedBy,
2395
+ tabIndex: disabled ? -1 : 0,
2396
+ }
2397
+ : { importantForAccessibility: "no" as const }),
2398
+ onPress: isWeb && !disabled ? () => handleOpenChange(true) : undefined,
2399
+ onKeyDown: (event: React.KeyboardEvent) => {
2400
+ if (disabled) return;
2401
+ if (
2402
+ ["Enter", " ", "ArrowDown", "ArrowUp", "j", "k"].includes(event.key) ||
2403
+ event.code === "Space"
2404
+ ) {
2405
+ event.preventDefault();
2406
+ setKeyboardNav(true);
2407
+ if (!open) handleOpenChange(true);
2408
+ }
2409
+ },
2410
+ };
2411
+
2372
2412
  const triggerContent = triggerRender ? (
2373
2413
  <View
2374
2414
  data-testid="combobox-trigger"
2375
- width="100%"
2415
+ width={triggerSizing === "content" ? "auto" : "100%"}
2376
2416
  alignSelf="stretch"
2377
2417
  flexShrink={0}
2378
2418
  outlineWidth={0}
2379
2419
  focusVisibleStyle={ensureFocusVisibleRing({ outlineOffset: -2 })}
2380
- style={{ display: "flex", alignItems: "stretch", width: "100%" }}
2420
+ style={{
2421
+ display: "flex",
2422
+ alignItems: "stretch",
2423
+ width: triggerSizing === "content" ? "auto" : "100%",
2424
+ }}
2425
+ {...triggerProps}
2381
2426
  >
2382
2427
  {triggerRender(multiple ? selectedOptions : selectedOption, open)}
2383
2428
  </View>
@@ -2402,41 +2447,7 @@ function NativeComboboxCore({
2402
2447
  borderRadius: knobProps.borderRadius.borderRadius,
2403
2448
  borderWidth: knobProps.borderRadius.borderWidth,
2404
2449
  })}
2405
- id={id}
2406
- // Web: the box is the combobox control (ARIA + keyboard). Native:
2407
- // FloatingPanel's trigger Pressable (triggerA11y) is the single
2408
- // accessible node — role/aria props here surface the box as a
2409
- // duplicate TalkBack stop on Android, so exclude it from the tree
2410
- // (descendants stay reachable; "no", not "no-hide-descendants").
2411
- {...(isWeb
2412
- ? {
2413
- role: "combobox" as const,
2414
- "aria-haspopup": "listbox",
2415
- "aria-expanded": open,
2416
- "aria-controls": listboxId,
2417
- "aria-activedescendant": hideSearch ? activeDescendant : undefined,
2418
- "aria-autocomplete": hideSearch ? ("list" as const) : undefined,
2419
- // Standalone (no label): fall back to placeholder for the name.
2420
- // Labelled: the sibling Label wires `aria-labelledby` onto this id
2421
- // itself — naming it here too doubles the spoken name.
2422
- "aria-label": ariaLabel ?? (!hasLabel ? placeholder : undefined),
2423
- "aria-describedby": describedBy,
2424
- tabIndex: disabled ? -1 : 0,
2425
- }
2426
- : { importantForAccessibility: "no" as const })}
2427
- // Sheet capture opens first on web, so this opener is idempotent.
2428
- // Native delegates the gesture to FloatingPanel.
2429
- onPress={isWeb && !disabled ? () => handleOpenChange(true) : undefined}
2430
- onKeyDown={(e: React.KeyboardEvent) => {
2431
- if (
2432
- ["Enter", " ", "ArrowDown", "ArrowUp", "j", "k"].includes(e.key) ||
2433
- e.code === "Space"
2434
- ) {
2435
- e.preventDefault();
2436
- setKeyboardNav(true);
2437
- if (!open) handleOpenChange(true);
2438
- }
2439
- }}
2450
+ {...triggerProps}
2440
2451
  >
2441
2452
  <View
2442
2453
  flex={1}
@@ -2506,6 +2517,7 @@ function NativeComboboxCore({
2506
2517
  // the user types, so a content-fit sheet would open as a sliver.
2507
2518
  sheetFill={Boolean(onSearch)}
2508
2519
  trigger={triggerContent}
2520
+ triggerSizing={triggerSizing}
2509
2521
  triggerEnd={
2510
2522
  clearable && !multiple && !disabled && typeof value === "string" && value !== "" ? (
2511
2523
  <Button
@@ -2564,6 +2576,7 @@ export function Combobox({
2564
2576
  onLoadMore,
2565
2577
  hasMore,
2566
2578
  trigger,
2579
+ triggerSizing,
2567
2580
  name,
2568
2581
  form: formProp,
2569
2582
  validators,
@@ -2696,6 +2709,7 @@ export function Combobox({
2696
2709
  tabIndexOverride={tabIndexProp}
2697
2710
  popoverWidth={popoverWidth}
2698
2711
  trigger={trigger}
2712
+ triggerSizing={triggerSizing}
2699
2713
  knobProps={knobProps}
2700
2714
  multiple={multiple}
2701
2715
  selectedOrder={selectedOrder}
@@ -80,6 +80,7 @@ function CalendarDayGrid({
80
80
  maxDate,
81
81
  selectionCapped,
82
82
  }: CalendarDayGridProps) {
83
+ const { knobProps } = useCalendarKnobs();
83
84
  return (
84
85
  <CalendarDays
85
86
  calendarData={calendarData}
@@ -110,7 +111,7 @@ function CalendarDayGrid({
110
111
  }
111
112
  return (
112
113
  <View
113
- transition="quick"
114
+ transition={knobProps.transition}
114
115
  position="absolute"
115
116
  height="100%"
116
117
  zIndex={0}
@@ -297,6 +298,7 @@ export function Calendar({
297
298
  const handleSetDisplayForPrev = useCallback(
298
299
  (date: Date) => {
299
300
  const next = new Date(date);
301
+ next.setDate(1);
300
302
  next.setMonth(next.getMonth() + 1);
301
303
  setDisplayDate(next);
302
304
  },
@@ -305,6 +307,7 @@ export function Calendar({
305
307
 
306
308
  const prevMonthDate = useMemo(() => {
307
309
  const date = new Date(displayDate);
310
+ date.setDate(1);
308
311
  date.setMonth(date.getMonth() - 1);
309
312
  return date;
310
313
  }, [displayDate]);
@@ -4,7 +4,7 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
4
4
  import { useForm } from "@tanstack/react-form";
5
5
  import type { ComponentProps } from "react";
6
6
  import { useState } from "react";
7
- import { YStack } from "tamagui";
7
+ import { Text, YStack } from "tamagui";
8
8
  import { Button } from "../../Button";
9
9
  import { Form } from "../../Form";
10
10
  import { Calendar } from "./Calendar";
@@ -103,6 +103,27 @@ export const Standalone: Story = {
103
103
  render: (args) => <DatePicker {...args} />,
104
104
  };
105
105
 
106
+ export const StateContract: Story = {
107
+ render: () => {
108
+ const [value, setValue] = useState<string | null>(null);
109
+ const [edits, setEdits] = useState(0);
110
+ return (
111
+ <YStack gap="$4" maxWidth={400}>
112
+ <DatePicker label="Saved date" defaultValue="1990-01-01" />
113
+ <DatePicker
114
+ label="Programmatic date"
115
+ value={value}
116
+ onChange={() => setEdits((count) => count + 1)}
117
+ />
118
+ <Button onPress={() => setValue("2026-03-05")}>Load date</Button>
119
+ <Text>{`User edits: ${edits}`}</Text>
120
+ <DatePicker label="Read-only date" value="1990-01-01" readOnly />
121
+ <DatePicker label="Disabled date" value="1990-01-01" disabled />
122
+ </YStack>
123
+ );
124
+ },
125
+ };
126
+
106
127
  export const Basic: Story = {
107
128
  render: (args) => <DatePicker {...args} />,
108
129
  args: {
@@ -261,6 +261,7 @@ function DualCalendarBody({
261
261
 
262
262
  const prevMonthDate = useMemo(() => {
263
263
  const date = new Date(displayDate);
264
+ date.setDate(1);
264
265
  date.setMonth(date.getMonth() - 1);
265
266
  return date;
266
267
  }, [displayDate]);
@@ -273,6 +274,7 @@ function DualCalendarBody({
273
274
  const handleSetDisplayForPrev = useCallback(
274
275
  (date: Date) => {
275
276
  const next = new Date(date);
277
+ next.setDate(1);
276
278
  next.setMonth(next.getMonth() + 1);
277
279
  setDisplayDate(next);
278
280
  },
@@ -281,7 +283,7 @@ function DualCalendarBody({
281
283
 
282
284
  if (!fullWidthMode) {
283
285
  return (
284
- <View {...knobProps.panelPadding}>
286
+ <View>
285
287
  <SingleCalendar
286
288
  displayDate={displayDate}
287
289
  rangeStart={rangeStart}
@@ -297,7 +299,7 @@ function DualCalendarBody({
297
299
  }
298
300
 
299
301
  return (
300
- <View flexDirection="row" {...knobProps.gap} {...knobProps.panelPadding}>
302
+ <View flexDirection="row" {...knobProps.gap}>
301
303
  <SingleCalendar
302
304
  displayDate={prevMonthDate}
303
305
  rangeStart={rangeStart}
@@ -246,15 +246,14 @@ function DatetimePickerBody({
246
246
  );
247
247
 
248
248
  return (
249
- <View
250
- flexDirection="column"
251
- alignItems="center"
252
- {...knobProps.gap}
253
- width={activeTab === "date" ? px * 7 : "100%"}
254
- minWidth={px * 7}
255
- alignSelf={activeTab === "date" ? "center" : "stretch"}
256
- >
257
- <View flexDirection="row" width="100%">
249
+ <View flexDirection="column" alignItems="center" minWidth={px * 7} alignSelf="stretch">
250
+ <View
251
+ flexDirection="row"
252
+ width="100%"
253
+ {...knobProps.panelPadding}
254
+ // The active content frame owns the space below this strip.
255
+ paddingBottom={0}
256
+ >
258
257
  {(["date", "time"] as const).map((tab) => {
259
258
  const active = activeTab === tab;
260
259
  const tabDisabled = tab === "time" && !selectedDatetime;
@@ -319,15 +318,17 @@ function DatetimePickerBody({
319
318
  </CalendarViewSwitcher>
320
319
  ) : (
321
320
  selectedDatetime && (
322
- <View width="100%">
323
- <TimeSection
324
- selectedDate={selectedDatetime}
325
- onTimeChange={handleTimeChange}
326
- timeFormat={timeFormat}
327
- minuteStep={minuteStep}
328
- showSeconds={showSeconds}
329
- />
330
- </View>
321
+ <CalendarPanelFrame>
322
+ <View width={px * 7}>
323
+ <TimeSection
324
+ selectedDate={selectedDatetime}
325
+ onTimeChange={handleTimeChange}
326
+ timeFormat={timeFormat}
327
+ minuteStep={minuteStep}
328
+ showSeconds={showSeconds}
329
+ />
330
+ </View>
331
+ </CalendarPanelFrame>
331
332
  )
332
333
  )}
333
334
  </View>
@@ -505,7 +506,8 @@ export function DatetimePicker<
505
506
  }
506
507
  disabled={disabled}
507
508
  sizing="grow"
508
- widthMode="at-least-trigger"
509
+ contentPadding="none"
510
+ widthMode="fit-content"
509
511
  >
510
512
  {pickerContent(fieldChange)}
511
513
  </FloatingPanel>
@@ -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
  };