@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
@@ -112,7 +112,7 @@ function ensureWheelFocusStyles() {
112
112
  const style = document.createElement("style");
113
113
  style.id = WHEEL_FOCUS_STYLE_ID;
114
114
  style.textContent =
115
- ".mp1-wheel-wrapper:focus-visible { outline: 2px solid var(--outlineColor, rgba(0,0,0,0.5)); outline-offset: -2px; }";
115
+ ".mp1-wheel-wrapper:focus-visible { outline: 2px solid var(--outlineColor, var(--c-outlineColor, CanvasText)); outline-offset: -2px; }";
116
116
  document.head.appendChild(style);
117
117
  }
118
118
 
@@ -847,7 +847,7 @@ export function Wheel<T = string | number>({
847
847
  <Text
848
848
  {...knobProps.body}
849
849
  fontSize={size}
850
- fontWeight={isSelected && !disabled ? "600" : "400"}
850
+ fontWeight={isSelected && !disabled ? "bold" : knobProps.textWeight.fontWeight}
851
851
  color={itemColor(isSelected)}
852
852
  numberOfLines={1}
853
853
  ellipsizeMode="tail"
@@ -865,7 +865,7 @@ export function Wheel<T = string | number>({
865
865
  width={flex ? "100%" : columnWidth}
866
866
  minWidth={flex ? 0 : columnWidth}
867
867
  flex={flex}
868
- {...knobProps.containerRadius}
868
+ borderRadius={0}
869
869
  data-testid="wheel"
870
870
  data-disabled={disabled ? true : undefined}
871
871
  aria-disabled={disabled || undefined}
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
2
  import { renderWithProviders } from "@multiplatform.one/test-utils";
3
3
  import { Preset } from "@multiplatform.one/theme";
4
4
  import { Input as TamaguiInput } from "tamagui";
5
- import { FieldLayout } from "./fieldLayout";
5
+ import { FieldLayout, useFieldDescribedBy } from "./fieldLayout";
6
6
  import { __resetDevWarnSeen } from "./shared/devWarn";
7
7
 
8
8
  function classIncludes(container: HTMLElement, fragment: string): boolean {
@@ -188,6 +188,47 @@ describe("FieldLayout error precedence (Axiom 5 eject-last)", () => {
188
188
  });
189
189
  });
190
190
 
191
+ describe("FieldLayout message-before-control anatomy", () => {
192
+ function Control() {
193
+ return <input id="ordered" aria-describedby={useFieldDescribedBy()} />;
194
+ }
195
+
196
+ for (const mode of ["top", "side", "compact"] as const) {
197
+ it(`${mode}: helper and replacement error precede the control and describe only the rendered slot`, () => {
198
+ const renderField = (error?: string) => (
199
+ <Preset overrides={{ fieldLabelPlacement: mode === "side" ? "side" : "top" }}>
200
+ <FieldLayout
201
+ id="ordered"
202
+ label="Email"
203
+ compactSpacing={mode === "compact"}
204
+ helperText="Use your work address"
205
+ error={error}
206
+ >
207
+ <Control />
208
+ </FieldLayout>
209
+ </Preset>
210
+ );
211
+ const result = renderWithProviders(renderField());
212
+ const assertSlot = (id: string, text: string) => {
213
+ const input = result.container.querySelector("input")!;
214
+ const message = result.container.querySelector(`#${id}`)!;
215
+ expect(message.textContent).toBe(text);
216
+ expect(
217
+ message.compareDocumentPosition(input) & Node.DOCUMENT_POSITION_FOLLOWING,
218
+ ).toBeTruthy();
219
+ expect(input.getAttribute("aria-describedby")).toBe(id);
220
+ expect(
221
+ result.container.querySelectorAll("[id$='-description'], [id$='-error']"),
222
+ ).toHaveLength(1);
223
+ };
224
+ assertSlot("ordered-description", "Use your work address");
225
+ result.rerender(renderField("Enter an email address"));
226
+ assertSlot("ordered-error", "Enter an email address");
227
+ expect(result.container.textContent).not.toContain("Use your work address");
228
+ });
229
+ }
230
+ });
231
+
191
232
  describe("FieldLayout banned-error-word DEV warn", () => {
192
233
  let warnSpy: ReturnType<typeof vi.spyOn>;
193
234
 
@@ -218,13 +218,13 @@ export function FieldLayout({
218
218
  ...(width !== undefined ? { width } : {}),
219
219
  };
220
220
 
221
- const describedBy =
222
- [
223
- helperText && id ? `${id}-description` : undefined,
224
- errorMessage && id ? `${id}-error` : undefined,
225
- ]
226
- .filter(Boolean)
227
- .join(" ") || undefined;
221
+ const describedBy = id
222
+ ? errorMessage
223
+ ? `${id}-error`
224
+ : helperText
225
+ ? `${id}-description`
226
+ : undefined
227
+ : undefined;
228
228
 
229
229
  const a11yLabel = typeof label === "string" ? `${label}${requiredSuffix}` : ariaLabel;
230
230
  const a11yDescription = errorMessage ?? helperText;
@@ -293,9 +293,9 @@ export function FieldLayout({
293
293
 
294
294
  const controlColumn = (
295
295
  <YStack flex={sideLabel ? 1 : undefined} {...gapProps}>
296
- {children}
297
296
  {helperNode}
298
297
  {errorNode}
298
+ {children}
299
299
  </YStack>
300
300
  );
301
301
 
@@ -330,9 +330,9 @@ export function FieldLayout({
330
330
  ) : (
331
331
  <>
332
332
  {labelNode}
333
- {children}
334
333
  {helperNode}
335
334
  {errorNode}
335
+ {children}
336
336
  </>
337
337
  )}
338
338
  </YStack>
@@ -11,6 +11,8 @@
11
11
  import { cleanup } from "@testing-library/react";
12
12
  import { renderWithProviders } from "@multiplatform.one/test-utils";
13
13
  import { afterEach, describe, expect, it } from "vitest";
14
+ import { createRef } from "react";
15
+ import { FieldLayout } from "../../fieldLayout";
14
16
  import { CheckboxFieldFrame } from "./CheckboxFieldFrame";
15
17
 
16
18
  afterEach(cleanup);
@@ -31,6 +33,22 @@ function frame(container: HTMLElement): HTMLElement {
31
33
  }
32
34
 
33
35
  describe("CheckboxFieldFrame", () => {
36
+ it("links the rendered field message, forwards its ref, and preserves an explicit description", () => {
37
+ const ref = createRef<any>();
38
+ const fixture = (override?: { "aria-describedby": string | undefined }) => (
39
+ <FieldLayout id="consent" helperText="Read the terms" error="Accept the terms">
40
+ <CheckboxFieldFrame id="consent" checked={false} ref={ref} {...override} />
41
+ </FieldLayout>
42
+ );
43
+ const result = renderWithProviders(fixture());
44
+ expect(frame(result.container).getAttribute("aria-describedby")).toBe("consent-error");
45
+ expect(ref.current).toBe(frame(result.container));
46
+ result.rerender(fixture({ "aria-describedby": "consumer-description" }));
47
+ expect(frame(result.container).getAttribute("aria-describedby")).toBe("consumer-description");
48
+ result.rerender(fixture({ "aria-describedby": undefined }));
49
+ expect(frame(result.container).getAttribute("aria-describedby")).toBeNull();
50
+ });
51
+
34
52
  it("still renders a real role=checkbox, so the styling never costs the semantics", () => {
35
53
  const { container } = renderWithProviders(<CheckboxFieldFrame checked={false} />);
36
54
  expect(frame(container)).toBeTruthy();
@@ -1,7 +1,8 @@
1
1
  import { Checkbox as TamaguiCheckbox, styled } from "tamagui";
2
+ import { useFieldDescribedBy } from "../../fieldLayout";
2
3
 
3
4
  /** Hit-target frame. The painted box is CheckboxGlyphBox (LC-71). */
4
- export const CheckboxFieldFrame = styled(TamaguiCheckbox, {
5
+ const CheckboxFieldFrameBase = styled(TamaguiCheckbox, {
5
6
  backgroundColor: "transparent",
6
7
  borderColor: "transparent",
7
8
  borderWidth: 0,
@@ -21,3 +22,7 @@ export const CheckboxFieldFrame = styled(TamaguiCheckbox, {
21
22
  },
22
23
  activeStyle: { backgroundColor: "transparent", borderColor: "transparent" },
23
24
  });
25
+
26
+ export const CheckboxFieldFrame = CheckboxFieldFrameBase.styleable((props, ref) => (
27
+ <CheckboxFieldFrameBase aria-describedby={useFieldDescribedBy()} {...props} ref={ref} />
28
+ ));
@@ -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>