@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
@@ -40,12 +40,16 @@ function Harness({
40
40
  sheet,
41
41
  onOpenChange,
42
42
  extra,
43
+ openOn,
44
+ sizing,
43
45
  }: {
44
46
  trigger: ReactNode;
45
47
  disabled?: boolean;
46
48
  sheet?: boolean;
47
49
  onOpenChange?: (open: boolean) => void;
48
50
  extra?: ReactNode;
51
+ openOn?: "press" | "contextmenu";
52
+ sizing?: "grow" | "fill";
49
53
  }) {
50
54
  const [open, setOpen] = useState(false);
51
55
  return (
@@ -64,6 +68,8 @@ function Harness({
64
68
  trigger={trigger}
65
69
  disabled={disabled}
66
70
  sheet={sheet}
71
+ openOn={openOn}
72
+ sizing={sizing}
67
73
  >
68
74
  <Text>panel body</Text>
69
75
  {extra}
@@ -79,6 +85,75 @@ const isOpen = (result: { container: HTMLElement }) =>
79
85
 
80
86
  const floatingViewport = () => document.querySelector('[data-testid="floating-panel-viewport"]');
81
87
 
88
+ describe("FloatingPanel nested actions", () => {
89
+ it("does not require a marked DOM button to stop propagation", () => {
90
+ const action = vi.fn();
91
+ const onOpenChange = vi.fn();
92
+ const result = renderWithProviders(
93
+ <Harness
94
+ onOpenChange={onOpenChange}
95
+ trigger={
96
+ <button type="button" data-floating-panel-action="true" onClick={action}>
97
+ Clear selection
98
+ </button>
99
+ }
100
+ />,
101
+ );
102
+ fireEvent.click(result.getByRole("button", { name: "Clear selection" }), { detail: 0 });
103
+ expect(action).toHaveBeenCalledOnce();
104
+ expect(onOpenChange).not.toHaveBeenCalled();
105
+ });
106
+
107
+ for (const sheet of [true, false]) {
108
+ for (const activation of ["pointer", "keyboard"] as const) {
109
+ it(`lets a marked ${activation} action run without opening ${sheet ? "sheet" : "float"}`, () => {
110
+ const action = vi.fn();
111
+ const onOpenChange = vi.fn();
112
+ const result = renderWithProviders(
113
+ <Harness
114
+ sheet={sheet}
115
+ onOpenChange={onOpenChange}
116
+ trigger={
117
+ <Button
118
+ data-floating-panel-action="true"
119
+ onPress={(event) => {
120
+ event.stopPropagation();
121
+ action();
122
+ }}
123
+ >
124
+ Clear selection
125
+ </Button>
126
+ }
127
+ />,
128
+ );
129
+ const button = result.getByRole("button", { name: "Clear selection" });
130
+ if (activation === "pointer") pointerPress(button);
131
+ else {
132
+ fireEvent.keyDown(button, { key: "Enter" });
133
+ fireEvent.keyUp(button, { key: "Enter" });
134
+ }
135
+ expect(action).toHaveBeenCalledOnce();
136
+ expect(onOpenChange).not.toHaveBeenCalled();
137
+ expect(isOpen(result)).toBe(false);
138
+ });
139
+ }
140
+
141
+ it(`preserves context-menu opening from a marked action in ${sheet ? "sheet" : "float"}`, () => {
142
+ const onOpenChange = vi.fn();
143
+ const result = renderWithProviders(
144
+ <Harness
145
+ sheet={sheet}
146
+ openOn="contextmenu"
147
+ onOpenChange={onOpenChange}
148
+ trigger={<Button data-floating-panel-action="true">Context action</Button>}
149
+ />,
150
+ );
151
+ fireEvent.contextMenu(result.getByRole("button", { name: "Context action" }));
152
+ expect(onOpenChange).toHaveBeenCalledWith(true);
153
+ });
154
+ }
155
+ });
156
+
82
157
  /** The DEEPEST node carrying the whole label — several ancestors report the
83
158
  * same `textContent`, and pressing one of those would sidestep the very
84
159
  * swallow these cases exist to catch. */
@@ -260,4 +335,38 @@ describe("FloatingPanel trigger — floating mode", () => {
260
335
  expect(document.activeElement).toBe(trigger);
261
336
  });
262
337
  });
338
+
339
+ it("disconnects fill content observation on close and unmount", async () => {
340
+ const observers: { target: Element; disconnected: boolean }[] = [];
341
+ class TrackingResizeObserver {
342
+ private tracked?: { target: Element; disconnected: boolean };
343
+ observe(target: Element) {
344
+ if (target.parentElement?.getAttribute("data-testid") !== "floating-panel-viewport") return;
345
+ this.tracked = { target, disconnected: false };
346
+ observers.push(this.tracked);
347
+ }
348
+ unobserve() {}
349
+ disconnect() {
350
+ if (this.tracked) this.tracked.disconnected = true;
351
+ }
352
+ }
353
+ vi.stubGlobal("ResizeObserver", TrackingResizeObserver);
354
+ const result = renderWithProviders(
355
+ <Harness sizing="fill" trigger={<Button>Open Panel</Button>} />,
356
+ );
357
+ try {
358
+ const trigger = result.container.querySelector("[role='button']") as HTMLElement;
359
+ pointerPress(trigger);
360
+ await waitFor(() => expect(observers.some((observer) => !observer.disconnected)).toBe(true));
361
+ fireEvent.keyDown(document, { key: "Escape" });
362
+ await waitFor(() => expect(observers.every((observer) => observer.disconnected)).toBe(true));
363
+ pointerPress(trigger);
364
+ await waitFor(() => expect(observers.some((observer) => !observer.disconnected)).toBe(true));
365
+ result.unmount();
366
+ expect(observers.every((observer) => observer.disconnected)).toBe(true);
367
+ } finally {
368
+ result.unmount();
369
+ vi.unstubAllGlobals();
370
+ }
371
+ });
263
372
  });
@@ -76,6 +76,7 @@ export {
76
76
  } from "./useFloatingPanel";
77
77
  export type { UseFloatingPanelOptions, UseFloatingPanelReturn } from "./useFloatingPanel";
78
78
  export type { FloatingPanelProps } from "./index";
79
+ export { floatingPanelActionProps, isNestedPanelAction } from "./nestedAction";
79
80
 
80
81
  /** Native never has a >sm web viewport; AdaptivePopup uses this to pick Sheet mode. */
81
82
  export function useViewportGtSm() {
@@ -103,8 +104,10 @@ const enterDuration = 280;
103
104
  export function FloatingPanel({
104
105
  open,
105
106
  onOpenChange,
107
+ onNativeShow,
106
108
  trigger,
107
109
  triggerEnd,
110
+ triggerSizing = "stretch",
108
111
  children,
109
112
  scrollable,
110
113
  disabled,
@@ -355,7 +358,13 @@ export function FloatingPanel({
355
358
 
356
359
  return (
357
360
  <>
358
- <RNView style={{ flexDirection: "row", alignItems: "center", width: "100%" }}>
361
+ <RNView
362
+ style={{
363
+ flexDirection: "row",
364
+ alignItems: "center",
365
+ width: triggerSizing === "content" ? undefined : "100%",
366
+ }}
367
+ >
359
368
  <Pressable
360
369
  {...(isContextMenu
361
370
  ? { onLongPress: handleTriggerLongPress, delayLongPress: 500 }
@@ -368,18 +377,22 @@ export function FloatingPanel({
368
377
  ? { accessibilityValue: { text: triggerA11y.value } }
369
378
  : undefined)}
370
379
  {...(triggerA11y?.hint ? { accessibilityHint: triggerA11y.hint } : undefined)}
371
- // Stretch to the cell/row width — content-sized triggers (~70pt) make
372
- // most of the edit box look tappable but miss the Pressable.
380
+ // Whole-field triggers stretch; composite adornments hug their
381
+ // content so sibling inputs retain their editable space.
373
382
  style={{
374
- flex: 1,
383
+ flex: triggerSizing === "content" ? undefined : 1,
375
384
  minWidth: 0,
376
385
  alignSelf: "stretch",
377
- width: "100%",
386
+ width: triggerSizing === "content" ? undefined : "100%",
378
387
  opacity: disabled ? 0.5 : 1,
379
388
  }}
380
389
  >
381
390
  {/* Own the hit target — see file header for why pointerEvents="none". */}
382
- <RNView pointerEvents="none" collapsable={false} style={{ width: "100%" }}>
391
+ <RNView
392
+ pointerEvents="none"
393
+ collapsable={false}
394
+ style={{ width: triggerSizing === "content" ? undefined : "100%" }}
395
+ >
383
396
  {trigger}
384
397
  </RNView>
385
398
  </Pressable>
@@ -391,7 +404,11 @@ export function FloatingPanel({
391
404
  animationType="fade"
392
405
  statusBarTranslucent
393
406
  onRequestClose={close}
394
- onShow={enter}
407
+ onShow={() => {
408
+ if (!activeRef.current) return;
409
+ enter();
410
+ onNativeShow?.();
411
+ }}
395
412
  >
396
413
  {/*
397
414
  A plain padded column, not KeyboardAvoidingView: inside a Modal the
@@ -1,4 +1,4 @@
1
- import type { ReactNode, UIEvent } from "react";
1
+ import type { ReactNode, RefObject, UIEvent } from "react";
2
2
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
3
3
  import {
4
4
  OVERLAY_ATTACH_GAP,
@@ -15,6 +15,9 @@ import { useSheetEscapeDismiss } from "../shared/useSheetEscapeDismiss";
15
15
  import { useFloatingPanel, panelTransition, panelViewportPadding } from "./useFloatingPanel";
16
16
  import type { PanelWidthMode } from "./useFloatingPanel";
17
17
  import { zIndex } from "../shared/zIndex";
18
+ import { isNestedPanelAction, type PanelActionEvent } from "./nestedAction";
19
+
20
+ export { floatingPanelActionProps, isNestedPanelAction } from "./nestedAction";
18
21
 
19
22
  // Re-export hook for Select / Combobox / external consumers
20
23
  export {
@@ -37,6 +40,10 @@ export type {
37
40
  export interface FloatingPanelProps {
38
41
  open: boolean;
39
42
  onOpenChange: (open: boolean) => void;
43
+ /** Native only: the modal is presented and its inputs can receive focus. */
44
+ onNativeShow?: () => void;
45
+ /** Suppress delayed trigger focus when a consumer handles close focus itself. Web only. */
46
+ skipReturnFocusRef?: RefObject<boolean>;
40
47
  trigger: ReactNode;
41
48
  /**
42
49
  * Optional control rendered beside the trigger but OUTSIDE the native press
@@ -120,6 +127,11 @@ export interface FloatingPanelProps {
120
127
  * the strings must live on the Pressable itself. Web ignores this.
121
128
  */
122
129
  triggerA11y?: { label?: string; value?: string; hint?: string };
130
+ /**
131
+ * Stretch keeps the whole field pressable by default. Content lets an
132
+ * adornment trigger hug its content inside a composite field.
133
+ */
134
+ triggerSizing?: "stretch" | "content";
123
135
  /**
124
136
  * How the trigger opens the panel. `"press"` (default) is click/tap.
125
137
  * `"contextmenu"` is the ContextMenu gesture: web `contextmenu` (right-click
@@ -231,8 +243,10 @@ export function FloatingPanel(props: FloatingPanelProps) {
231
243
  function FloatingPanelSheet({
232
244
  open,
233
245
  onOpenChange,
246
+ skipReturnFocusRef,
234
247
  trigger,
235
248
  triggerEnd,
249
+ triggerSizing = "stretch",
236
250
  children,
237
251
  scrollable,
238
252
  disabled,
@@ -260,7 +274,7 @@ function FloatingPanelSheet({
260
274
  // DG-A11Y-04 / Axiom 7: Sheet has no focus scope — move focus into the
261
275
  // frame on open, trap Tab while open, return focus to the trigger on close.
262
276
  const sheetFrameRef = useRef<HTMLElement | null>(null);
263
- useSheetModalFocus(open, sheetFrameRef);
277
+ useSheetModalFocus(open, sheetFrameRef, skipReturnFocusRef);
264
278
  useKeyboardFocusIntoPanel(open, sheetFrameRef);
265
279
 
266
280
  const framePadding = contentPadding === "none" ? "$0" : knobProps.panelPadding.padding;
@@ -283,7 +297,10 @@ function FloatingPanelSheet({
283
297
  // shut the sheet it had just opened. Nothing is lost: the sheet is modal, so
284
298
  // its overlay covers the trigger and the toggle could only ever have run
285
299
  // with `open === false`.
286
- const openFromTrigger = () => handleOpenChange(true);
300
+ const openFromTrigger = (event?: PanelActionEvent) => {
301
+ if (event && isNestedPanelAction(event)) return;
302
+ handleOpenChange(true);
303
+ };
287
304
  const isContextMenu = openOn === "contextmenu";
288
305
  const triggerActivation = isWeb
289
306
  ? isContextMenu
@@ -298,9 +315,13 @@ function FloatingPanelSheet({
298
315
 
299
316
  return (
300
317
  <>
301
- <View flexDirection="row" alignItems="center" width="100%">
318
+ <View
319
+ flexDirection="row"
320
+ alignItems="center"
321
+ width={triggerSizing === "content" ? "auto" : "100%"}
322
+ >
302
323
  <View
303
- flex={1}
324
+ flex={triggerSizing === "content" ? undefined : 1}
304
325
  minWidth={0}
305
326
  {...(isContextMenu ? undefined : { onPress: openFromTrigger })}
306
327
  cursor={disabled ? "not-allowed" : "pointer"}
@@ -361,6 +382,7 @@ function FloatingPanelSheet({
361
382
  function FloatingPanelWeb({
362
383
  open,
363
384
  onOpenChange,
385
+ skipReturnFocusRef,
364
386
  trigger,
365
387
  children,
366
388
  disabled,
@@ -379,6 +401,7 @@ function FloatingPanelWeb({
379
401
  const growDownOnlyRef = useRef(false);
380
402
  const lastScrollTopRef = useRef(0);
381
403
  const keyboardOpenRef = useRef(false);
404
+ const contentRef = useRef<HTMLElement | null>(null);
382
405
 
383
406
  const repositionFnRef = useRef<(() => void) | null>(null);
384
407
 
@@ -405,7 +428,7 @@ function FloatingPanelWeb({
405
428
  // Escape (or outside click on empty space) closes the panel while focus is
406
429
  // inside it, focus falls to <body>. Return it to the pre-open element
407
430
  // (the trigger's focusable). Deliberate focus moves elsewhere are kept.
408
- useReturnFocusOnClose(open);
431
+ useReturnFocusOnClose(open, skipReturnFocusRef);
409
432
  useKeyboardFocusIntoPanel(open && panel.mounted, panel.refs.floating, keyboardOpenRef);
410
433
  useEffect(() => {
411
434
  if (!open) keyboardOpenRef.current = false;
@@ -573,6 +596,29 @@ function FloatingPanelWeb({
573
596
  repositionOverlay();
574
597
  }, [open, panel.mounted, repositionOverlay, panel.y]);
575
598
 
599
+ useLayoutEffect(() => {
600
+ const content = contentRef.current;
601
+ if (!open || !panel.mounted || !isFill || !content || typeof ResizeObserver === "undefined") {
602
+ return;
603
+ }
604
+ // Matching the trigger width can rewrap content after the panel's first
605
+ // height measurement. Observe the content, not the clamped viewport, so a
606
+ // later open or result change uses its actual height without a resize loop.
607
+ let frame = 0;
608
+ const observer = new ResizeObserver(() => {
609
+ if (frame) cancelAnimationFrame(frame);
610
+ frame = requestAnimationFrame(() => {
611
+ frame = 0;
612
+ repositionOverlay();
613
+ });
614
+ });
615
+ observer.observe(content);
616
+ return () => {
617
+ observer.disconnect();
618
+ if (frame) cancelAnimationFrame(frame);
619
+ };
620
+ }, [open, panel.mounted, isFill, repositionOverlay]);
621
+
576
622
  const handleScroll = useCallback(
577
623
  (event: UIEvent) => {
578
624
  const el = event.target as HTMLElement;
@@ -633,8 +679,8 @@ function FloatingPanelWeb({
633
679
  // (`p-results/trigger-slot/detail.json`): a pointer click carries the click
634
680
  // count, `element.click()` and native keyboard activation carry 0.
635
681
  const openFromSynthesizedClick = useCallback(
636
- (event: { detail: number }) => {
637
- if (disabled || isContextMenu || event.detail !== 0) return;
682
+ (event: { detail: number } & PanelActionEvent) => {
683
+ if (disabled || isContextMenu || event.detail !== 0 || isNestedPanelAction(event)) return;
638
684
  // detail 0 is keyboard/programmatic activation (LC-50). Count it as
639
685
  // keyboard-origin so the first inner control rings (LC-71).
640
686
  keyboardOpenRef.current = true;
@@ -652,14 +698,26 @@ function FloatingPanelWeb({
652
698
  [disabled, onOpenChange],
653
699
  );
654
700
 
701
+ const referenceProps = getReferenceProps({
702
+ ref: panel.setReferenceRef,
703
+ onClickCapture: openFromSynthesizedClick,
704
+ ...(isContextMenu ? { onContextMenu: openFromContextMenu } : {}),
705
+ });
706
+ // Guard the composed floating-ui openers, after hook handlers are merged.
707
+ // Declining leaves each action's own events and focus defaults intact.
708
+ for (const name of ["onMouseDown", "onClick", "onKeyDown", "onKeyUp"] as const) {
709
+ const handler = referenceProps[name];
710
+ if (typeof handler === "function") {
711
+ referenceProps[name] = (event: PanelActionEvent) => {
712
+ if (!isNestedPanelAction(event)) handler(event);
713
+ };
714
+ }
715
+ }
716
+
655
717
  return (
656
718
  <>
657
719
  <View
658
- {...getReferenceProps({
659
- ref: panel.setReferenceRef,
660
- onClickCapture: openFromSynthesizedClick,
661
- ...(isContextMenu ? { onContextMenu: openFromContextMenu } : {}),
662
- })}
720
+ {...referenceProps}
663
721
  cursor={disabled ? "not-allowed" : "pointer"}
664
722
  opacity={disabled ? 0.5 : 1}
665
723
  // The cover contract is stated as a relation between the panel's top
@@ -693,6 +751,14 @@ function FloatingPanelWeb({
693
751
  transformOrigin: panelTransformOrigin(panel.placement),
694
752
  },
695
753
  onScroll: handleScroll,
754
+ onTransitionEnd: (event) => {
755
+ if (
756
+ event.target === event.currentTarget &&
757
+ (event.propertyName === "height" || event.propertyName === "max-height")
758
+ ) {
759
+ panel.updateArrows(event.currentTarget);
760
+ }
761
+ },
696
762
  })}
697
763
  data-testid="floating-panel-viewport"
698
764
  data-fp-panel=""
@@ -714,6 +780,7 @@ function FloatingPanelWeb({
714
780
  arrowScrollDirRef={panel.arrowScrollDirRef}
715
781
  />
716
782
  <View
783
+ ref={contentRef as any}
717
784
  {...(contentPadding !== "none" ? panel.knobProps.panelPadding : undefined)}
718
785
  {...(contentPadding !== "none" ? panel.knobProps.gapLg : undefined)}
719
786
  >
@@ -0,0 +1,36 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isNestedPanelAction } from "./nestedAction";
3
+
4
+ describe("independent actions inside panel triggers", () => {
5
+ it("recognizes an SVG descendant of a marked action", () => {
6
+ const wrapper = document.createElement("div");
7
+ wrapper.innerHTML = '<button data-floating-panel-action="true"><svg><path /></svg></button>';
8
+ expect(
9
+ isNestedPanelAction({
10
+ nativeEvent: { target: wrapper.querySelector("path") },
11
+ currentTarget: wrapper,
12
+ }),
13
+ ).toBe(true);
14
+ });
15
+
16
+ it("does not let a marker above the wrapper suppress an ordinary opener", () => {
17
+ const outer = document.createElement("div");
18
+ outer.setAttribute("data-floating-panel-action", "true");
19
+ outer.innerHTML = "<div><button>Open</button></div>";
20
+ expect(
21
+ isNestedPanelAction({
22
+ target: outer.querySelector("button"),
23
+ currentTarget: outer.firstElementChild,
24
+ }),
25
+ ).toBe(false);
26
+ });
27
+
28
+ it("keeps unmarked buttons and non-DOM events as ordinary trigger presses", () => {
29
+ const wrapper = document.createElement("div");
30
+ wrapper.innerHTML = "<button>Open</button>";
31
+ expect(isNestedPanelAction({ target: wrapper.firstElementChild, currentTarget: wrapper })).toBe(
32
+ false,
33
+ );
34
+ expect(isNestedPanelAction({})).toBe(false);
35
+ });
36
+ });
@@ -0,0 +1,15 @@
1
+ export const floatingPanelActionProps = { "data-floating-panel-action": "true" } as const;
2
+
3
+ export interface PanelActionEvent {
4
+ target?: unknown;
5
+ currentTarget?: unknown;
6
+ nativeEvent?: { target?: unknown };
7
+ }
8
+
9
+ /** Marked actions inside a trigger keep their own press and keyboard behavior. */
10
+ export function isNestedPanelAction(event: PanelActionEvent): boolean {
11
+ const target = (event.nativeEvent?.target ?? event.target) as Element | null;
12
+ const wrapper = event.currentTarget as Element | null;
13
+ const action = target?.closest?.('[data-floating-panel-action="true"]');
14
+ return !!action && !!wrapper?.contains?.(action);
15
+ }
@@ -1,6 +1,5 @@
1
1
  /**
2
- * MPO-38 AC: no FloatingPanel consumer renders a panel narrower than its
3
- * trigger.
2
+ * Text listboxes match the field width; intrinsic editors size to their content.
4
3
  *
5
4
  * The runtime half is covered in `useFloatingPanel.spec.tsx`. This is the
6
5
  * source half, and it exists because the defect it guards is invisible at
@@ -8,11 +7,9 @@
8
7
  * DatePicker measured 262px of calendar under a 289px trigger purely because
9
8
  * the call site said `fitContent`.
10
9
  *
11
- * A FIELD-shaped trigger (a control the user reads a value out of) takes
12
- * `at-least-trigger`. A BUTTON-shaped trigger — an icon, a toolbar chip —
13
- * legitimately keeps `fit-content`, because matching a 32px button would be
14
- * absurd; those are listed explicitly so the exemption is a decision rather
15
- * than an oversight.
10
+ * Calendar grids take fit-content (MPO-262): a full-width field wrapper is
11
+ * unrelated to seven day columns and must not create a mostly empty popup.
12
+ * Text listboxes retain at-least-trigger; icon/button launchers may also hug.
16
13
  */
17
14
  import { readFileSync } from "node:fs";
18
15
  import { dirname, resolve } from "node:path";
@@ -22,13 +19,9 @@ import { describe, expect, it } from "vitest";
22
19
  const fieldsDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "fields");
23
20
 
24
21
  /** Pickers whose trigger is a form FIELD: the panel may never be narrower. */
25
- const fieldShapedPickers = [
26
- "DatePicker/parts.tsx",
27
- "DatePicker/DatetimePicker.catalog.tsx",
28
- "TimePicker/catalog.tsx",
29
- "ColorPicker/parts.tsx",
30
- "Icon/index.tsx",
31
- ];
22
+ const fieldShapedPickers = ["TimePicker/catalog.tsx", "ColorPicker/parts.tsx", "Icon/index.tsx"];
23
+
24
+ const intrinsicGridPickers = ["DatePicker/parts.tsx", "DatePicker/DatetimePicker.catalog.tsx"];
32
25
 
33
26
  /** Panels opened from an icon/button trigger, where fit-content is correct. */
34
27
  const buttonShapedPickers = ["Geolocation/index.tsx"];
@@ -37,7 +30,11 @@ function read(relative: string): string {
37
30
  return readFileSync(resolve(fieldsDir, relative), "utf8");
38
31
  }
39
32
 
40
- describe("FloatingPanel width contract (MPO-38)", () => {
33
+ describe("FloatingPanel width contract (MPO-38, MPO-262)", () => {
34
+ it.each(intrinsicGridPickers)("%s hugs its calendar grid", (relative) => {
35
+ expect(read(relative)).toContain('widthMode="fit-content"');
36
+ });
37
+
41
38
  it.each(fieldShapedPickers)("%s declares at-least-trigger", (relative) => {
42
39
  const source = read(relative);
43
40
  expect(source).toContain('widthMode="at-least-trigger"');
@@ -212,9 +212,7 @@ export const multiStepRegistration: Story = {
212
212
  />
213
213
 
214
214
  <FormActions>
215
- <Button variant="outlined" onPress={() => setStep("personal")}>
216
- Back
217
- </Button>
215
+ <Button onPress={() => setStep("personal")}>Back</Button>
218
216
  <Button onPress={() => setStep("verification")}>Next: Verification</Button>
219
217
  </FormActions>
220
218
  </FormSection>
@@ -240,9 +238,7 @@ export const multiStepRegistration: Story = {
240
238
  />
241
239
 
242
240
  <FormActions>
243
- <Button variant="outlined" onPress={() => setStep("contact")}>
244
- Back
245
- </Button>
241
+ <Button onPress={() => setStep("contact")}>Back</Button>
246
242
  <form.Subscribe selector={(state) => [state.canSubmit, state.isSubmitting]}>
247
243
  {([canSubmit, isSubmitting]) => (
248
244
  <Button action="submit" disabled={!canSubmit || isSubmitting}>
@@ -1,6 +1,6 @@
1
1
  import { getFontSized } from "@tamagui/get-font-sized";
2
2
  import type { SizeVariantSpreadFunction } from "@tamagui/web";
3
- import { useEffect, useState, type ReactNode } from "react";
3
+ import { useCallback, useEffect, useState, type ReactNode } from "react";
4
4
  import type { ComponentProps, Ref, RefObject } from "react";
5
5
  import { Pressable as RNPressable } from "react-native";
6
6
  import type {
@@ -1035,6 +1035,16 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
1035
1035
  size: knobProps.controlIcon.width,
1036
1036
  color: paint as never,
1037
1037
  });
1038
+ const decorativeRef = useCallback(
1039
+ (node: TamaguiElement | null) => {
1040
+ // Tamagui 2.7.6 Button stamps tabIndex=0 after consumer props.
1041
+ // Correct the host at hydration; decorative caps share the field stop.
1042
+ if (isWeb && node && "tabIndex" in node) node.tabIndex = tabIndexProp ?? -1;
1043
+ if (typeof ref === "function") ref(node);
1044
+ else if (ref) ref.current = node;
1045
+ },
1046
+ [ref, tabIndexProp],
1047
+ );
1038
1048
 
1039
1049
  if (glyphRing) {
1040
1050
  // A real tab stop must square off the token it was HANDED, not the
@@ -1077,7 +1087,7 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
1077
1087
  const square = knobProps.control.height;
1078
1088
  return (
1079
1089
  <InputButton
1080
- ref={ref}
1090
+ ref={decorativeRef}
1081
1091
  size={size}
1082
1092
  height={square}
1083
1093
  width={square}
@@ -1166,9 +1176,8 @@ export const InputContainerFrame = styled(View, {
1166
1176
 
1167
1177
  variants: {
1168
1178
  size: {
1169
- "...size": (val, { tokens }) => ({
1170
- gap: (tokens.space[val] as any)?.val * 0.3,
1171
- }),
1179
+ // Size is shared with the child parts; layout spacing belongs to space.
1180
+ "...size": () => ({}),
1172
1181
  },
1173
1182
  color: {
1174
1183
  "...color": () => ({}),
@@ -1194,6 +1203,7 @@ const InputContainerImpl = InputContainerFrame.styleable((props, forwardedRef) =
1194
1203
  ref={forwardedRef}
1195
1204
  size={knobProps.sizeToken}
1196
1205
  {...knobProps.body}
1206
+ {...knobProps.gap}
1197
1207
  // LC-06/LC-10 (UX-P12): inside a table cell the field root must adopt
1198
1208
  // the cell width — the raw web <input> carries an intrinsic width that
1199
1209
  // otherwise floors the whole column at ~200px and lays out past the
@@ -0,0 +1,43 @@
1
+ import { createRef } from "react";
2
+ import { Preset } from "@multiplatform.one/theme";
3
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
4
+ import { cleanup } from "@testing-library/react";
5
+ import { afterEach, expect, it } from "vitest";
6
+ import { Input } from "./index";
7
+
8
+ afterEach(cleanup);
9
+
10
+ function measure(size: "small" | "medium", space: "small" | "large", gap?: number) {
11
+ const ref = createRef<HTMLElement>();
12
+ const { getByTestId } = renderWithProviders(
13
+ <Preset overrides={{ size, space }}>
14
+ <Input testID="root" ref={ref as never} {...(gap === undefined ? {} : { gap })}>
15
+ <Input.Label>Location</Input.Label>
16
+ <Input.Box>
17
+ <Input.Area placeholder="Location" />
18
+ </Input.Box>
19
+ </Input>
20
+ </Preset>,
21
+ );
22
+ const root = getByTestId("root");
23
+ expect(ref.current).toBe(root);
24
+ // Happy DOM leaves token-backed CSS gaps unresolved; browser coverage reads
25
+ // the actual pixels. Keep this test checking the rendered gap owner.
26
+ const value =
27
+ getComputedStyle(root).gap || [...root.classList].find((name) => name.startsWith("_gap-"));
28
+ expect(value).toBeTruthy();
29
+ cleanup();
30
+ return value;
31
+ }
32
+
33
+ it("lets space change the multi-slot layout gap at a fixed control size", () => {
34
+ expect(measure("medium", "small")).not.toBe(measure("medium", "large"));
35
+ });
36
+
37
+ it("keeps the layout gap stable when only control size changes", () => {
38
+ expect(measure("small", "small")).toBe(measure("medium", "small"));
39
+ });
40
+
41
+ it("preserves the consumer gap eject and forwarded root ref", () => {
42
+ expect(measure("medium", "large", 11)).toBe("11px");
43
+ });
@@ -7,6 +7,22 @@ import { Wheel } from "./index";
7
7
  afterEach(cleanup);
8
8
 
9
9
  describe("Wheel contrast contract", () => {
10
+ it("uses the selected-text weight and keeps rounding on the selection band", () => {
11
+ renderWithProviders(
12
+ <Preset overrides={{ borderRadius: "full" }}>
13
+ <Wheel items={[1, 2, 3, 4, 5]} value={3} visibleItems={5} />
14
+ </Preset>,
15
+ );
16
+ const wheel = screen.getByTestId("wheel");
17
+ const selected = wheel.querySelector('[data-selected="true"]')?.firstElementChild;
18
+ expect(selected).toBeTruthy();
19
+ expect(["700", "bold"]).toContain(getComputedStyle(selected as Element).fontWeight);
20
+ expect(["", "0px"]).toContain(getComputedStyle(wheel).borderTopLeftRadius);
21
+ expect(getComputedStyle(screen.getByTestId("wheel-selection")).borderStartStartRadius).not.toBe(
22
+ "0px",
23
+ );
24
+ });
25
+
10
26
  it("keeps inactive item text on the AA $color11 ramp (not opacity-dimmed)", () => {
11
27
  renderWithProviders(
12
28
  <Wheel items={[1, 2, 3, 4, 5]} value={3} onChange={() => {}} visibleItems={5} />,