@multiplatform.one/forms 7.42.0 → 7.44.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 (327) hide show
  1. package/dist/cjs/AdaptivePopup/index.native.js +1 -1
  2. package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
  3. package/dist/cjs/Button/index.native.js +1 -1
  4. package/dist/cjs/Button/index.native.js.map +1 -1
  5. package/dist/cjs/Chip/index.cjs +5 -2
  6. package/dist/cjs/Chip/index.native.js +2 -1
  7. package/dist/cjs/Chip/index.native.js.map +1 -1
  8. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js +1 -1
  9. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  10. package/dist/cjs/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  11. package/dist/cjs/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  12. package/dist/cjs/ContextualSaveBar/index.native.js +3 -3
  13. package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
  14. package/dist/cjs/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  15. package/dist/cjs/ControlGroup/index.native.js +1 -1
  16. package/dist/cjs/ControlGroup/index.native.js.map +1 -1
  17. package/dist/cjs/DescriptionList/index.native.js +2 -2
  18. package/dist/cjs/DescriptionList/index.native.js.map +1 -1
  19. package/dist/cjs/ErrorSummary.native.js.map +1 -1
  20. package/dist/cjs/FieldDisplay/editMode.native.js.map +1 -1
  21. package/dist/cjs/FieldDisplay/formatters.native.js.map +1 -1
  22. package/dist/cjs/FieldDisplay/index.native.js +1 -1
  23. package/dist/cjs/FieldDisplay/index.native.js.map +1 -1
  24. package/dist/cjs/FieldGroup.native.js.map +1 -1
  25. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -1
  26. package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
  27. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  28. package/dist/cjs/Form/index.native.js +1 -1
  29. package/dist/cjs/Form/index.native.js.map +1 -1
  30. package/dist/cjs/Form/submissionController.native.js.map +1 -1
  31. package/dist/cjs/Form/validateOn.native.js.map +1 -1
  32. package/dist/cjs/FormGrid.native.js.map +1 -1
  33. package/dist/cjs/FormSection.native.js.map +1 -1
  34. package/dist/cjs/InputParts/index.cjs +22 -116
  35. package/dist/cjs/InputParts/index.native.js +25 -121
  36. package/dist/cjs/InputParts/index.native.js.map +1 -1
  37. package/dist/cjs/Label/index.native.js.map +1 -1
  38. package/dist/cjs/MediaPicker/base64.native.js.map +1 -1
  39. package/dist/cjs/MediaPicker/payload.native.js.map +1 -1
  40. package/dist/cjs/MediaPicker/types.native.js.map +1 -1
  41. package/dist/cjs/MediaPicker/useMediaPicker.native.js.map +1 -1
  42. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  43. package/dist/cjs/Spinner/SpinnerGlyph.native.js.map +1 -1
  44. package/dist/cjs/Spinner/spinnerSize.native.js.map +1 -1
  45. package/dist/cjs/Table/index.native.js.map +1 -1
  46. package/dist/cjs/Wheel/haptic.native.js.map +1 -1
  47. package/dist/cjs/Wheel/index.native.js.map +1 -1
  48. package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
  49. package/dist/cjs/actionLabel.native.js.map +1 -1
  50. package/dist/cjs/fieldDefaults.native.js.map +1 -1
  51. package/dist/cjs/fieldLayout.native.js +1 -1
  52. package/dist/cjs/fieldLayout.native.js.map +1 -1
  53. package/dist/cjs/fields/Barcode/BarcodePreview.native.js.map +1 -1
  54. package/dist/cjs/fields/Barcode/BarcodeScanner.native.js +1 -1
  55. package/dist/cjs/fields/Barcode/code128.native.js.map +1 -1
  56. package/dist/cjs/fields/Barcode/index.native.js +2 -2
  57. package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
  58. package/dist/cjs/fields/Barcode/qr.native.js.map +1 -1
  59. package/dist/cjs/fields/Barcode/scannerTypes.native.js.map +1 -1
  60. package/dist/cjs/fields/Checkbox/Checkbox.native.js +1 -1
  61. package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
  62. package/dist/cjs/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  63. package/dist/cjs/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  64. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  65. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js +1 -1
  66. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  67. package/dist/cjs/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  68. package/dist/cjs/fields/Checkbox/index.native.js.map +1 -1
  69. package/dist/cjs/fields/ColorPicker/index.native.js +3 -3
  70. package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
  71. package/dist/cjs/fields/ColorPicker/parts.native.js +2 -2
  72. package/dist/cjs/fields/ColorPicker/parts.native.js.map +1 -1
  73. package/dist/cjs/fields/Combobox/authorOptions.native.js.map +1 -1
  74. package/dist/cjs/fields/Combobox/index.native.js +6 -6
  75. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  76. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  77. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  78. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  79. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +3 -3
  80. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  81. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +2 -2
  82. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +2 -2
  83. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  84. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  85. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  86. package/dist/cjs/fields/DatePicker/catalog.native.js +2 -2
  87. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
  88. package/dist/cjs/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  89. package/dist/cjs/fields/DatePicker/index.native.js +2 -2
  90. package/dist/cjs/fields/DatePicker/parts.native.js +2 -2
  91. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  92. package/dist/cjs/fields/DatePicker/utils.native.js.map +1 -1
  93. package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
  94. package/dist/cjs/fields/Duration/index.native.js +3 -3
  95. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  96. package/dist/cjs/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  97. package/dist/cjs/fields/FileUpload/index.native.js +2 -2
  98. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  99. package/dist/cjs/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  100. package/dist/cjs/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  101. package/dist/cjs/fields/Geolocation/geoValue.native.js.map +1 -1
  102. package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -1
  103. package/dist/cjs/fields/Geolocation/geocoderContext.native.js.map +1 -1
  104. package/dist/cjs/fields/Geolocation/index.native.js +5 -5
  105. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  106. package/dist/cjs/fields/Geolocation/mapMath.native.js.map +1 -1
  107. package/dist/cjs/fields/Geolocation/mapTypes.native.js.map +1 -1
  108. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
  109. package/dist/cjs/fields/Geolocation/photonGeocoder.native.js.map +1 -1
  110. package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
  111. package/dist/cjs/fields/Icon/index.native.js +3 -3
  112. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  113. package/dist/cjs/fields/ImageField/index.native.js +2 -2
  114. package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
  115. package/dist/cjs/fields/Input/index.cjs +1 -18
  116. package/dist/cjs/fields/Input/index.native.js +4 -21
  117. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  118. package/dist/cjs/fields/MentionInput/index.native.js +3 -3
  119. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  120. package/dist/cjs/fields/OTPInput/index.cjs +65 -82
  121. package/dist/cjs/fields/OTPInput/index.native.js +70 -87
  122. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  123. package/dist/cjs/fields/OTPInput/otpCellCss.cjs +1 -3
  124. package/dist/cjs/fields/OTPInput/otpCellCss.native.js +1 -3
  125. package/dist/cjs/fields/OTPInput/otpCellCss.native.js.map +1 -1
  126. package/dist/cjs/fields/PhoneInput/dialCodes.native.js.map +1 -1
  127. package/dist/cjs/fields/PhoneInput/index.cjs +1 -1
  128. package/dist/cjs/fields/PhoneInput/index.native.js +4 -4
  129. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  130. package/dist/cjs/fields/PhoneInput/phone.native.js.map +1 -1
  131. package/dist/cjs/fields/PhoneInput/regionNames.native.js.map +1 -1
  132. package/dist/cjs/fields/Progress/index.native.js +1 -1
  133. package/dist/cjs/fields/Progress/index.native.js.map +1 -1
  134. package/dist/cjs/fields/RadioGroup/index.native.js +1 -1
  135. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  136. package/dist/cjs/fields/Rating/index.native.js +1 -1
  137. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  138. package/dist/cjs/fields/Rating/ratingMath.native.js.map +1 -1
  139. package/dist/cjs/fields/Rating/types.native.js.map +1 -1
  140. package/dist/cjs/fields/SearchInput/index.cjs +5 -2
  141. package/dist/cjs/fields/SearchInput/index.native.js +4 -3
  142. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  143. package/dist/cjs/fields/Select/index.native.js +4 -4
  144. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  145. package/dist/cjs/fields/Signature/index.cjs +3 -11
  146. package/dist/cjs/fields/Signature/index.native.js +5 -13
  147. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  148. package/dist/cjs/fields/Slider/index.native.js +1 -1
  149. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  150. package/dist/cjs/fields/Slider/jumpMotion.native.js.map +1 -1
  151. package/dist/cjs/fields/Stepper/index.native.js +2 -2
  152. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  153. package/dist/cjs/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  154. package/dist/cjs/fields/Switch/footprint.native.js.map +1 -1
  155. package/dist/cjs/fields/Switch/index.native.js +2 -2
  156. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  157. package/dist/cjs/fields/TextArea/index.native.js +2 -2
  158. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  159. package/dist/cjs/fields/TimePicker/catalog.native.js +3 -3
  160. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  161. package/dist/cjs/fields/TimePicker/index.native.js +2 -2
  162. package/dist/cjs/fields/TimePicker/parts.native.js +1 -1
  163. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  164. package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  165. package/dist/cjs/fields/TimeRangeScrubber/index.native.js +2 -2
  166. package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
  167. package/dist/cjs/fields/ToggleGroup/index.native.js +1 -1
  168. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  169. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  170. package/dist/cjs/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
  171. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  172. package/dist/cjs/fields/nativeSelect.native.js.map +1 -1
  173. package/dist/cjs/fields/selectedOrder.native.js.map +1 -1
  174. package/dist/cjs/formSpacing.native.js.map +1 -1
  175. package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
  176. package/dist/cjs/index.native.js +44 -44
  177. package/dist/cjs/index.native.js.map +1 -1
  178. package/dist/cjs/keyboard/KeyboardDoneBar.native.js +1 -1
  179. package/dist/cjs/keyboard/chain.native.js.map +1 -1
  180. package/dist/cjs/keyboard/index.native.js.map +1 -1
  181. package/dist/cjs/keyboard/types.native.js.map +1 -1
  182. package/dist/cjs/requiredMarking.native.js.map +1 -1
  183. package/dist/cjs/shared/TimeColumn.native.js +1 -1
  184. package/dist/cjs/shared/TimeColumn.native.js.map +1 -1
  185. package/dist/cjs/shared/capabilityPreflight.native.js.map +1 -1
  186. package/dist/cjs/shared/colorRamps.native.js.map +1 -1
  187. package/dist/cjs/shared/devWarn.native.js.map +1 -1
  188. package/dist/cjs/shared/floatingList.native.js +1 -1
  189. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  190. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  191. package/dist/cjs/shared/groupContext.native.js.map +1 -1
  192. package/dist/cjs/shared/i18n.native.js.map +1 -1
  193. package/dist/cjs/shared/instantMotion.native.js.map +1 -1
  194. package/dist/cjs/shared/nativeA11y.native.js.map +1 -1
  195. package/dist/cjs/shared/nativeAutoFocus.cjs +37 -0
  196. package/dist/cjs/shared/nativeAutoFocus.native.js +41 -0
  197. package/dist/cjs/shared/nativeAutoFocus.native.js.map +1 -0
  198. package/dist/cjs/shared/panelPortal.native.js.map +1 -1
  199. package/dist/cjs/shared/pickerTriggerContract.native.js.map +1 -1
  200. package/dist/cjs/shared/pressSlopProps.native.js.map +1 -1
  201. package/dist/cjs/shared/t.native.js.map +1 -1
  202. package/dist/cjs/shared/tableCellContext.native.js.map +1 -1
  203. package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
  204. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  205. package/dist/cjs/shared/useSheetEscapeDismiss.native.js.map +1 -1
  206. package/dist/cjs/shared/useWheelIncrement.native.js.map +1 -1
  207. package/dist/cjs/shared/utils.native.js +1 -1
  208. package/dist/cjs/shared/utils.native.js.map +1 -1
  209. package/dist/cjs/shared/zIndex.native.js.map +1 -1
  210. package/dist/cjs/themedPrimitives.cjs +2 -0
  211. package/dist/cjs/themedPrimitives.native.js +2 -0
  212. package/dist/cjs/themedPrimitives.native.js.map +1 -1
  213. package/dist/cjs/types.native.js.map +1 -1
  214. package/dist/cjs/utils/LinkCell.native.js.map +1 -1
  215. package/dist/esm/Chip/index.mjs +5 -2
  216. package/dist/esm/Chip/index.mjs.map +1 -1
  217. package/dist/esm/Chip/index.native.js +2 -1
  218. package/dist/esm/Chip/index.native.js.map +1 -1
  219. package/dist/esm/InputParts/index.mjs +24 -116
  220. package/dist/esm/InputParts/index.mjs.map +1 -1
  221. package/dist/esm/InputParts/index.native.js +27 -121
  222. package/dist/esm/InputParts/index.native.js.map +1 -1
  223. package/dist/esm/fields/Input/index.mjs +2 -18
  224. package/dist/esm/fields/Input/index.mjs.map +1 -1
  225. package/dist/esm/fields/Input/index.native.js +2 -18
  226. package/dist/esm/fields/Input/index.native.js.map +1 -1
  227. package/dist/esm/fields/OTPInput/index.mjs +67 -84
  228. package/dist/esm/fields/OTPInput/index.mjs.map +1 -1
  229. package/dist/esm/fields/OTPInput/index.native.js +69 -86
  230. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  231. package/dist/esm/fields/OTPInput/otpCellCss.mjs +1 -3
  232. package/dist/esm/fields/OTPInput/otpCellCss.mjs.map +1 -1
  233. package/dist/esm/fields/OTPInput/otpCellCss.native.js +1 -3
  234. package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
  235. package/dist/esm/fields/PhoneInput/index.mjs +1 -1
  236. package/dist/esm/fields/PhoneInput/index.native.js +1 -1
  237. package/dist/esm/fields/SearchInput/index.mjs +5 -2
  238. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  239. package/dist/esm/fields/SearchInput/index.native.js +2 -1
  240. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  241. package/dist/esm/fields/Signature/index.mjs +4 -12
  242. package/dist/esm/fields/Signature/index.mjs.map +1 -1
  243. package/dist/esm/fields/Signature/index.native.js +4 -12
  244. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  245. package/dist/esm/shared/nativeAutoFocus.mjs +12 -0
  246. package/dist/esm/shared/nativeAutoFocus.mjs.map +1 -0
  247. package/dist/esm/shared/nativeAutoFocus.native.js +13 -0
  248. package/dist/esm/shared/nativeAutoFocus.native.js.map +1 -0
  249. package/dist/esm/themedPrimitives.mjs +2 -0
  250. package/dist/esm/themedPrimitives.mjs.map +1 -1
  251. package/dist/esm/themedPrimitives.native.js +2 -0
  252. package/dist/esm/themedPrimitives.native.js.map +1 -1
  253. package/dist/jsx/Chip/index.mjs +5 -2
  254. package/dist/jsx/Chip/index.mjs.map +1 -1
  255. package/dist/jsx/Chip/index.native.js +2 -1
  256. package/dist/jsx/Chip/index.native.js.map +1 -1
  257. package/dist/jsx/InputParts/index.mjs +24 -116
  258. package/dist/jsx/InputParts/index.mjs.map +1 -1
  259. package/dist/jsx/InputParts/index.native.js +25 -121
  260. package/dist/jsx/InputParts/index.native.js.map +1 -1
  261. package/dist/jsx/fields/Input/index.mjs +2 -18
  262. package/dist/jsx/fields/Input/index.mjs.map +1 -1
  263. package/dist/jsx/fields/Input/index.native.js +1 -18
  264. package/dist/jsx/fields/Input/index.native.js.map +1 -1
  265. package/dist/jsx/fields/OTPInput/index.mjs +67 -84
  266. package/dist/jsx/fields/OTPInput/index.mjs.map +1 -1
  267. package/dist/jsx/fields/OTPInput/index.native.js +67 -84
  268. package/dist/jsx/fields/OTPInput/index.native.js.map +1 -1
  269. package/dist/jsx/fields/OTPInput/otpCellCss.mjs +1 -3
  270. package/dist/jsx/fields/OTPInput/otpCellCss.mjs.map +1 -1
  271. package/dist/jsx/fields/OTPInput/otpCellCss.native.js +1 -3
  272. package/dist/jsx/fields/OTPInput/otpCellCss.native.js.map +1 -1
  273. package/dist/jsx/fields/PhoneInput/index.mjs +1 -1
  274. package/dist/jsx/fields/PhoneInput/index.native.js +1 -1
  275. package/dist/jsx/fields/SearchInput/index.mjs +5 -2
  276. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  277. package/dist/jsx/fields/SearchInput/index.native.js +2 -1
  278. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  279. package/dist/jsx/fields/Signature/index.mjs +4 -12
  280. package/dist/jsx/fields/Signature/index.mjs.map +1 -1
  281. package/dist/jsx/fields/Signature/index.native.js +3 -11
  282. package/dist/jsx/fields/Signature/index.native.js.map +1 -1
  283. package/dist/jsx/shared/nativeAutoFocus.mjs +12 -0
  284. package/dist/jsx/shared/nativeAutoFocus.mjs.map +1 -0
  285. package/dist/jsx/shared/nativeAutoFocus.native.js +41 -0
  286. package/dist/jsx/shared/nativeAutoFocus.native.js.map +1 -0
  287. package/dist/jsx/themedPrimitives.mjs +2 -0
  288. package/dist/jsx/themedPrimitives.mjs.map +1 -1
  289. package/dist/jsx/themedPrimitives.native.js +2 -0
  290. package/dist/jsx/themedPrimitives.native.js.map +1 -1
  291. package/package.json +8 -8
  292. package/src/Button/Button.disabledReasonInk.spec.tsx +7 -1
  293. package/src/Chip/index.tsx +2 -1
  294. package/src/InputParts/index.spec.tsx +11 -17
  295. package/src/InputParts/index.tsx +27 -147
  296. package/src/fieldFocus.spec.ts +44 -0
  297. package/src/fields/DatePicker/DatePicker.spec.tsx +1 -1
  298. package/src/fields/DatePicker/DateRangePicker.spec.tsx +1 -1
  299. package/src/fields/DatePicker/MultiDatePicker.spec.tsx +1 -1
  300. package/src/fields/Duration/Duration.spec.tsx +2 -2
  301. package/src/fields/Input/Input.copy.spec.tsx +1 -1
  302. package/src/fields/Input/Input.spec.tsx +7 -8
  303. package/src/fields/Input/index.tsx +1 -20
  304. package/src/fields/OTPInput/index.tsx +79 -98
  305. package/src/fields/OTPInput/otpCellCss.ts +4 -8
  306. package/src/fields/PhoneInput/PhoneInput.spec.tsx +3 -3
  307. package/src/fields/PhoneInput/index.tsx +1 -1
  308. package/src/fields/SearchInput/SearchInput.focusHold.native.spec.tsx +81 -0
  309. package/src/fields/SearchInput/SearchInput.spec.tsx +1 -1
  310. package/src/fields/SearchInput/index.tsx +2 -1
  311. package/src/fields/Signature/index.tsx +4 -10
  312. package/src/fields/TextArea/TextArea.spec.tsx +3 -3
  313. package/src/fields/TimePicker/TimePicker.spec.tsx +1 -1
  314. package/src/shared/nativeAutoFocus.ts +20 -0
  315. package/src/themedPrimitives.tsx +9 -1
  316. package/types/Chip/index.d.ts.map +1 -1
  317. package/types/InputParts/index.d.ts +29 -32
  318. package/types/InputParts/index.d.ts.map +1 -1
  319. package/types/fields/Input/index.d.ts +0 -1
  320. package/types/fields/Input/index.d.ts.map +1 -1
  321. package/types/fields/OTPInput/index.d.ts.map +1 -1
  322. package/types/fields/OTPInput/otpCellCss.d.ts.map +1 -1
  323. package/types/fields/SearchInput/index.d.ts.map +1 -1
  324. package/types/fields/Signature/index.d.ts.map +1 -1
  325. package/types/shared/nativeAutoFocus.d.ts +13 -0
  326. package/types/shared/nativeAutoFocus.d.ts.map +1 -0
  327. package/types/themedPrimitives.d.ts.map +1 -1
@@ -28,9 +28,9 @@ import {
28
28
  } from "tamagui";
29
29
  import {
30
30
  ensureCompositeFocusRing,
31
- ensureFocusVisibleRing,
32
- FOCUS_RING_CLIPPED_OFFSET,
33
- FOCUS_RING_HALO_OFFSET,
31
+ FIELD_FOCUS_REST,
32
+ FIELD_FOCUS_STYLE,
33
+ fieldFocusCss,
34
34
  useTouchSurface,
35
35
  isTouchSurface,
36
36
  recipeFamilies,
@@ -50,6 +50,7 @@ import {
50
50
  } from "@multiplatform.one/theme";
51
51
  import { formButtonColors, formCommonColors, formInputColors } from "../shared/colorRamps";
52
52
  import { useControlGrouped } from "../shared/groupContext";
53
+ import { nativeAutoFocus } from "../shared/nativeAutoFocus";
53
54
  import { useIsInTableCell } from "../shared/tableCellContext";
54
55
  import { useFieldA11y, useFieldDescribedBy } from "../fieldLayout";
55
56
 
@@ -159,22 +160,6 @@ export const useForwardFocus = (target: RefObject<TamaguiElement | null>) => {
159
160
  // Default group styles
160
161
  // ---------------------------------------------------------------------------
161
162
 
162
- /** Resting outline: transparent + 0 width so blur never lands on theme `$outlineColor`. */
163
- const inputOutlineRest = {
164
- outlineWidth: 0,
165
- outlineColor: "transparent",
166
- outlineStyle: "solid" as any,
167
- } as const;
168
-
169
- const inputOutlineFocus = {
170
- outlineColor: "$outlineColor",
171
- outlineWidth: 2,
172
- outlineStyle: "solid" as any,
173
- // Inset: Input.Box clips children with overflow:hidden; an outer +2px
174
- // ring is severed (LC-71 clipping carve-out).
175
- outlineOffset: -2,
176
- } as const;
177
-
178
163
  /**
179
164
  * LC-71 field anatomy (Polaris Connected / Primer TextInputWrapper / Spectrum):
180
165
  * one painted Box owns border + radius + ring; Icon/prefix/suffix live inside
@@ -191,37 +176,9 @@ const AREA_NO_OUTLINE = {
191
176
 
192
177
  type BoxOverflow = "hidden" | "visible";
193
178
 
194
- export function boxRingMode(
195
- overflow: BoxOverflow,
196
- paintsRing: boolean,
197
- ): "inset" | "outset" | undefined {
198
- if (!paintsRing) return undefined;
199
- return overflow === "hidden" ? "inset" : "outset";
200
- }
201
-
202
- export function boxRingOffset(mode: "inset" | "outset" | undefined): number {
203
- // Both branches are LC-71 §4 sanctioned offsets: the clipping inset when the
204
- // Box clips its adornments, the shape halo when it does not (MPO-92).
205
- return mode === "outset" ? FOCUS_RING_HALO_OFFSET : FOCUS_RING_CLIPPED_OFFSET;
206
- }
207
-
208
- export const inputPartsRingCss = `/* LC-71: ring on Box (adornments inside); Area never outlines.
209
- Inset iff the Box clips (overflow:hidden). Do not :has(:focus-visible) on
210
- every descendant — SearchInput clear ✕ is a second focusable. */
211
- [data-mp-input-box][data-mp-ring="inset"]:has(input:focus),
212
- [data-mp-input-box][data-mp-ring="inset"]:has(textarea:focus),
213
- [data-mp-input-box][data-mp-ring="inset"]:has([data-mp-input-area]:focus),
214
- [data-mp-input-box][data-mp-ring="inset"]:focus-visible {
215
- outline: 2px solid var(--outlineColor, var(--c-outlineColor, CanvasText)) !important;
216
- outline-offset: -2px !important;
217
- }
218
- [data-mp-input-box][data-mp-ring="outset"]:has(input:focus),
219
- [data-mp-input-box][data-mp-ring="outset"]:has(textarea:focus),
220
- [data-mp-input-box][data-mp-ring="outset"]:has([data-mp-input-area]:focus),
221
- [data-mp-input-box][data-mp-ring="outset"]:focus-visible {
222
- outline: 2px solid var(--outlineColor, var(--c-outlineColor, CanvasText)) !important;
223
- outline-offset: 2px !important;
224
- }
179
+ export const inputPartsRingCss = `/* FZ-7717: a focused Box takes the shared field focus look; Area never outlines. */
180
+ ${fieldFocusCss("[data-mp-input-box][data-mp-field-focus]")}
181
+ ${fieldFocusCss("[data-mp-input-box][data-mp-field-focus].mp-field-focus-deep", { deep: true })}
225
182
  [data-mp-input-area],
226
183
  [data-mp-input-area]:focus,
227
184
  [data-mp-input-area]:focus-visible,
@@ -249,19 +206,14 @@ export function ensureInputPartsFocusRing(): void {
249
206
  }
250
207
 
251
208
  function webBoxRingAttrs(
252
- overflow: BoxOverflow,
253
- paintsRing: boolean,
209
+ paintsFocus: boolean,
254
210
  extraClass?: string,
255
211
  ): Record<string, unknown> | undefined {
256
212
  if (!isWeb) return undefined;
257
- const mode = boxRingMode(overflow, paintsRing);
258
- const className = [paintsRing ? "mp-composite-ring" : undefined, extraClass]
259
- .filter(Boolean)
260
- .join(" ");
261
213
  return {
262
- ...(className ? { className } : undefined),
214
+ ...(extraClass ? { className: extraClass } : undefined),
263
215
  "data-mp-input-box": "true",
264
- ...(mode ? { "data-mp-ring": mode } : undefined),
216
+ ...(paintsFocus ? { "data-mp-field-focus": "true" } : undefined),
265
217
  };
266
218
  }
267
219
 
@@ -292,23 +244,14 @@ export const defaultInputGroupStyles = {
292
244
  backgroundColor: formInputColors.background.base,
293
245
 
294
246
  minWidth: 0,
295
- ...inputOutlineRest,
247
+ ...FIELD_FOCUS_REST,
296
248
 
297
249
  hoverStyle: {
298
250
  borderColor: formInputColors.border.hover,
299
251
  },
300
252
 
301
- // LC-71: any-focus only shifts the border. The ring lives on
302
- // `focusVisibleStyle` and on `[data-mp-ring]:has(input:focus)` so
303
- // button-like Boxes (Select, pagination) do not ring on mouse click.
304
- focusStyle: {
305
- borderColor: formInputColors.border.focus,
306
- },
307
-
308
- focusVisibleStyle: {
309
- borderColor: formInputColors.border.focus,
310
- ...inputOutlineFocus,
311
- },
253
+ focusStyle: FIELD_FOCUS_STYLE,
254
+ focusVisibleStyle: FIELD_FOCUS_STYLE,
312
255
  } as const;
313
256
 
314
257
  // ---------------------------------------------------------------------------
@@ -324,9 +267,6 @@ const InputGroupFrame = styled(XGroup, {
324
267
  alignItems: "center",
325
268
  context: InputContext,
326
269
  overflow: "hidden",
327
- // LC-71: className on XGroup is best-effort (often dropped). The styleable
328
- // spread stamps data-mp-input-box / data-mp-ring; CSS keys off those.
329
- ...(isWeb ? { className: "mp-composite-ring" } : {}),
330
270
 
331
271
  variants: {
332
272
  touch: { true: {}, false: {} },
@@ -375,11 +315,9 @@ function wrapNativePressable(
375
315
 
376
316
  const InputGroupImpl = InputGroupFrame.styleable<{
377
317
  /**
378
- * OVERLAY_ANCHOR_GAP rule (theme/layoutTokens) — one surface owner per
379
- * overlay: while a floating panel intentionally covers this box (Select's
380
- * macOS-style listbox), the box must not paint its focus ring. The ring
381
- * sits outside the border box (outline + offset), so a covering panel can
382
- * never hide it — it ghosts around the panel's corners as a doubled edge.
318
+ * Kept for callers. Since FZ-7717 the field focus look is the Box's own
319
+ * accent border, which a covering panel hides, so there is no ring left to
320
+ * suppress.
383
321
  */
384
322
  suppressFocusRing?: boolean;
385
323
  /**
@@ -398,7 +336,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
398
336
  children,
399
337
  onPress,
400
338
  disabled,
401
- suppressFocusRing,
339
+ suppressFocusRing: _suppressFocusRing,
402
340
  recipeFamily = "control",
403
341
  sizeRecipeEscape,
404
342
  height: heightProp,
@@ -417,27 +355,21 @@ const InputGroupImpl = InputGroupFrame.styleable<{
417
355
  const inTableCell = useIsInTableCell();
418
356
  // Native Pressable owns onPress; do not also pass it to XGroup (double-fire).
419
357
  const framePressProps = isWeb ? { onPress, disabled } : { disabled };
420
- // Standalone Box clips children to radius → inset ring. Grouped / in-cell
421
- // frames leave overflow visible and do not paint their own ring.
358
+ // Standalone Box clips children to radius. Grouped / in-cell frames leave
359
+ // overflow visible and leave focus to their container.
422
360
  // LC-85: on native, an elevation token must not share a clipsToBounds layer
423
- // with the shadow (iOS masks the layer's own drop shadow). Web box-shadow
424
- // paints outside overflow:hidden, so the ring clip can stay.
425
- const paintsRing = !grouped && !inTableCell;
361
+ // with the shadow (iOS masks the layer's own drop shadow).
362
+ const paintsFocus = !grouped && !inTableCell;
426
363
  const hasElevation = knobProps.elevation != null;
427
364
  const hasWebPressSlop =
428
365
  isWeb && (props as { "data-mp-press-slop"?: string })["data-mp-press-slop"] != null;
429
366
  const boxOverflow: BoxOverflow =
430
- paintsRing && !(hasElevation && !isWeb) && !hasWebPressSlop ? "hidden" : "visible";
431
- const ringMode = boxRingMode(boxOverflow, paintsRing);
367
+ paintsFocus && !(hasElevation && !isWeb) && !hasWebPressSlop ? "hidden" : "visible";
432
368
  if (isWeb) {
433
369
  ensureCompositeFocusRing();
434
370
  ensureInputPartsFocusRing();
435
371
  }
436
- const boxRingAttrs = webBoxRingAttrs(
437
- boxOverflow,
438
- paintsRing,
439
- (props as { className?: string }).className,
440
- );
372
+ const boxRingAttrs = webBoxRingAttrs(paintsFocus, (props as { className?: string }).className);
441
373
 
442
374
  // DG-A11Y-01 / DG-A11Y-03 — DEV guardrails (tree-shaken in production).
443
375
  warnPositiveTabIndex({
@@ -577,29 +509,6 @@ const InputGroupImpl = InputGroupFrame.styleable<{
577
509
  );
578
510
  }
579
511
 
580
- // Covered by an overlay panel (see prop doc): keep the focus border color
581
- // but draw no ring on either focus path. This is an intentional a11y
582
- // exception — the open panel is the focus affordance while it covers this
583
- // box. Hoisted (with `undefined` in the union) so the JSX spread does not
584
- // re-specify focusStyle/focusVisibleStyle literally (TS2783 under the
585
- // build tsconfig).
586
- const suppressedRingProps = suppressFocusRing
587
- ? {
588
- focusStyle: { borderColor: formInputColors.border.focus, ...inputOutlineRest },
589
- focusVisibleStyle: {
590
- borderColor: formInputColors.border.focus,
591
- ...inputOutlineRest,
592
- },
593
- }
594
- : undefined;
595
-
596
- const focusRing = ensureFocusVisibleRing({
597
- ...inputOutlineFocus,
598
- ...control.focusKnobProps,
599
- ...control.focusVisibleKnobProps,
600
- outlineOffset: boxRingOffset(ringMode),
601
- });
602
-
603
512
  return (
604
513
  <FocusContext.Provider focused={focused} setFocused={setFocused}>
605
514
  {wrapNativePressable(
@@ -623,45 +532,15 @@ const InputGroupImpl = InputGroupFrame.styleable<{
623
532
  pressStyle={{
624
533
  ...control.pressKnobProps,
625
534
  }}
626
- focusStyle={{
627
- borderColor: formInputColors.border.focus,
628
- ...control.focusKnobProps,
629
- }}
630
- focusVisibleStyle={ensureFocusVisibleRing({
631
- borderColor: formInputColors.border.focus,
632
- ...inputOutlineFocus,
633
- ...control.focusVisibleKnobProps,
634
- outlineOffset: boxRingOffset(ringMode),
635
- })}
535
+ focusStyle={FIELD_FOCUS_STYLE}
536
+ focusVisibleStyle={FIELD_FOCUS_STYLE}
636
537
  {...props}
637
538
  {...passthroughSizeProps}
638
539
  {...insetPadProps}
639
540
  {...sizeRecipeEscapeOverride}
640
541
  {...framePressProps}
641
542
  {...boxRingAttrs}
642
- {...(focused && !suppressFocusRing
643
- ? {
644
- // Text-entry carve-out (LC-71): inner Area focus means typing
645
- // is next, so the Box rings on any focus — including click.
646
- // CSS `[data-mp-ring]` is the sync path; this is the token-
647
- // resolved backup (and the native path). Button-like Boxes
648
- // (Select) do not set `focused` (no Area onFocus).
649
- borderColor: formInputColors.border.focus,
650
- ...focusRing,
651
- }
652
- : isWeb
653
- ? {
654
- // Explicit rest — avoid leaving theme `$outlineColor` (near-white in
655
- // dark) as the computed outline-color while width settles.
656
- // Keep outline-transparent rest (border-flicker fix); do not warn.
657
- ...inputOutlineRest,
658
- }
659
- : // FZ-7718: on iOS the outline's width and offset changing as
660
- // the field takes focus makes it resign first responder, so a
661
- // programmatic focus (Return to the next field) never sticks.
662
- // Native keeps the ring's geometry at rest and fades its color.
663
- { ...focusRing, outlineColor: "transparent" })}
664
- {...suppressedRingProps}
543
+ {...(focused ? FIELD_FOCUS_STYLE : FIELD_FOCUS_REST)}
665
544
  // LC-40 DISABLED-VISIBLE: the input frame is text-bearing chrome —
666
545
  // keepLabel washes fill/border (value text keeps >= AA) and
667
546
  // dimWhole leaves the dim to the FieldLayout assembly. Read-only
@@ -894,6 +773,7 @@ const InputAreaImpl = InputFrame.styleable<{
894
773
  : undefined
895
774
  }
896
775
  {...props}
776
+ {...nativeAutoFocus(props as { autoFocus?: boolean; autoFocusNative?: boolean })}
897
777
  {...(flexProp != null ? { flex: flexProp } : undefined)}
898
778
  {...(widthProp != null
899
779
  ? { width: widthProp, minWidth: minWidthProp, maxWidth: maxWidthProp }
@@ -0,0 +1,44 @@
1
+ import { readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { inspectDesign } from "@multiplatform.one/config/design-lint";
4
+ import { describe, expect, it } from "vitest";
5
+
6
+ const src = join(process.cwd(), "src");
7
+
8
+ function sources(dir: string): string[] {
9
+ return readdirSync(dir).flatMap((entry) => {
10
+ const path = join(dir, entry);
11
+ if (statSync(path).isDirectory()) return sources(path);
12
+ return /\.tsx?$/.test(entry) && !/\.(spec|stories|test)\./.test(entry) ? [path] : [];
13
+ });
14
+ }
15
+
16
+ describe("FZ-7717: every MPO field takes its focus look from FIELD_FOCUS_STYLE", () => {
17
+ const files = [...sources(join(src, "fields")), ...sources(join(src, "InputParts"))];
18
+
19
+ it("no field paints its own focus ring or shadow", () => {
20
+ const hits = files.flatMap((file) =>
21
+ (inspectDesign(readFileSync(file, "utf8"), file) as string[]).filter((error) =>
22
+ error.includes("[field-focus]"),
23
+ ),
24
+ );
25
+ expect(hits).toEqual([]);
26
+ });
27
+
28
+ it("Input.Box, the Box every text field renders, uses the shared look", () => {
29
+ const box = readFileSync(join(src, "InputParts", "index.tsx"), "utf8");
30
+ expect(box).toContain("focusStyle={FIELD_FOCUS_STYLE}");
31
+ expect(box).toContain("focusVisibleStyle={FIELD_FOCUS_STYLE}");
32
+ expect(box).not.toMatch(
33
+ /outlineOffset|FOCUS_RING_(?:HALO|CLIPPED)_OFFSET|ensureFocusVisibleRing/,
34
+ );
35
+ });
36
+
37
+ it("the detector catches a field that forks the look", () => {
38
+ const forked = inspectDesign(
39
+ "const x = <Input.Box focusStyle={{ outlineWidth: 2, outlineOffset: 2 }} />;",
40
+ "Forked.tsx",
41
+ ) as string[];
42
+ expect(forked.join("\n")).toMatch(/\[field-focus\]/);
43
+ });
44
+ });
@@ -51,7 +51,7 @@ describe("DatePicker", () => {
51
51
  const label = result.container.querySelector("label") as HTMLLabelElement;
52
52
  expect(trigger).toBeTruthy();
53
53
  expect(trigger.contains(input)).toBe(true);
54
- expect(trigger.className).toMatch(/mp-composite-ring/);
54
+ expect(trigger.getAttribute("data-mp-field-focus")).toBe("true");
55
55
  expect(trigger.getAttribute("tabindex")).toBe("0");
56
56
  expect(trigger.getAttribute("role")).toBe("combobox");
57
57
  expect(input.tabIndex).toBe(-1);
@@ -197,7 +197,7 @@ describe("DateRangePicker", () => {
197
197
  const result = renderWithProviders(<DateRangePicker label="Range" name="range" />);
198
198
  const input = result.container.querySelector("input");
199
199
  expect(input?.className).toMatch(/mp-input-area/);
200
- const box = result.container.querySelector(".mp-composite-ring");
200
+ const box = result.container.querySelector("[data-mp-field-focus]");
201
201
  expect(box).toBeTruthy();
202
202
  expect(box?.contains(input)).toBe(true);
203
203
  });
@@ -162,7 +162,7 @@ describe("MultiDatePicker", () => {
162
162
  const result = renderWithProviders(<MultiDatePicker label="Dates" name="dates" />);
163
163
  const input = result.container.querySelector("input");
164
164
  expect(input?.className).toMatch(/mp-input-area/);
165
- const box = result.container.querySelector(".mp-composite-ring");
165
+ const box = result.container.querySelector("[data-mp-field-focus]");
166
166
  expect(box).toBeTruthy();
167
167
  expect(box?.contains(input)).toBe(true);
168
168
  });
@@ -207,12 +207,12 @@ describe("Duration", () => {
207
207
  expect(sSize).not.toBe(lSize);
208
208
  });
209
209
 
210
- it("rings the outer box, never the inner segments (LC-71)", () => {
210
+ it("focuses the outer box, never the inner segments (FZ-7717)", () => {
211
211
  const result = renderWithProviders(<Duration label="Ring" value={3600} />);
212
212
  const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
213
213
  const hours = result.container.querySelector('input[aria-label="Hours"]') as HTMLInputElement;
214
214
  expect(box).toBeTruthy();
215
- expect(box.className).toMatch(/mp-composite-ring/);
215
+ expect(box.getAttribute("data-mp-field-focus")).toBe("true");
216
216
  expect(box.contains(hours)).toBe(true);
217
217
  expect(hours.className).toMatch(/mp-input-area/);
218
218
  });
@@ -30,7 +30,7 @@ describe("Input copy (CopyField slot)", () => {
30
30
  (el) => el !== input && el !== copy,
31
31
  );
32
32
  expect(extraStops).toHaveLength(0);
33
- expect(result.container.querySelector(".mp-composite-ring")).toBeTruthy();
33
+ expect(result.container.querySelector("[data-mp-field-focus]")).toBeTruthy();
34
34
  });
35
35
 
36
36
  it("empty omits the cap so there is one tab stop", () => {
@@ -250,7 +250,7 @@ describe("Input", () => {
250
250
  });
251
251
 
252
252
  describe("LC-71 RING-ANATOMY", () => {
253
- it("rings the Box (icons included), never the inner input", () => {
253
+ it("focuses the Box (icons included), never the inner input", () => {
254
254
  const result = renderWithProviders(
255
255
  <Input
256
256
  label="Search"
@@ -262,7 +262,7 @@ describe("Input", () => {
262
262
  const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
263
263
  const input = result.container.querySelector("input") as HTMLInputElement;
264
264
  expect(box).toBeTruthy();
265
- expect(box.className).toMatch(/mp-composite-ring/);
265
+ expect(box.getAttribute("data-mp-field-focus")).toBe("true");
266
266
  expect(box.contains(result.getByTestId("leading"))).toBe(true);
267
267
  expect(box.contains(result.getByTestId("trailing"))).toBe(true);
268
268
  expect(box.contains(input)).toBe(true);
@@ -282,7 +282,7 @@ describe("Input", () => {
282
282
  );
283
283
  const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
284
284
  const input = result.container.querySelector("input") as HTMLInputElement;
285
- expect(box.className).toMatch(/mp-composite-ring/);
285
+ expect(box.getAttribute("data-mp-field-focus")).toBe("true");
286
286
  expect(box.contains(result.getByTestId("leading"))).toBe(true);
287
287
  expect(input.className).toMatch(/mp-input-area/);
288
288
  });
@@ -451,13 +451,12 @@ describe("Input", () => {
451
451
  expect(box.className).toContain("_h-48px");
452
452
  });
453
453
 
454
- it("focus ring offset is 0 (F1 / reference §10 / cover-offset-0)", () => {
454
+ it("focus is the shared accent border, not an offset ring (FZ-7717)", () => {
455
455
  const result = renderWithProviders(<Input label="Name" name="n" />);
456
456
  const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
457
- expect(box.getAttribute("data-ring-offset")).toBe("0");
458
- expect(document.getElementById("mp-input-field-ring-offset")?.textContent).toContain(
459
- "outline-offset: 0",
460
- );
457
+ expect(box.getAttribute("data-mp-field-focus")).toBe("true");
458
+ expect(box.getAttribute("data-ring-offset")).toBeNull();
459
+ expect(document.getElementById("mp-input-field-ring-offset")).toBeNull();
461
460
  });
462
461
 
463
462
  it("paints the field label at weight 400 (R7 / §6.1)", () => {
@@ -11,7 +11,7 @@ import type {
11
11
  SizeTokens,
12
12
  TamaguiElement,
13
13
  } from "tamagui";
14
- import { isWeb, Text } from "tamagui";
14
+ import { Text } from "tamagui";
15
15
  import { Skeleton } from "../../Skeleton";
16
16
  import { resolveFieldInputProps } from "../../fieldDefaults";
17
17
  import { Field, FieldLayout } from "../../fieldLayout";
@@ -31,23 +31,6 @@ import { useKeyboardChain } from "../../keyboard";
31
31
 
32
32
  type InputAreaProps = ComponentProps<typeof InputParts.Area>;
33
33
 
34
- /** F1 / reference §10: standalone Input rings at offset 0, not the inset −2. */
35
- const INPUT_FIELD_RING_STYLE_ID = "mp-input-field-ring-offset";
36
-
37
- export function ensureInputFieldRingOffset(): void {
38
- if (typeof document === "undefined") return;
39
- if (document.getElementById(INPUT_FIELD_RING_STYLE_ID)) return;
40
- const tag = document.createElement("style");
41
- tag.id = INPUT_FIELD_RING_STYLE_ID;
42
- tag.textContent = `[data-mp-input-field][data-mp-ring="inset"]:has(input:focus),
43
- [data-mp-input-field][data-mp-ring="inset"]:has(textarea:focus),
44
- [data-mp-input-field][data-mp-ring="inset"]:has([data-mp-input-area]:focus),
45
- [data-mp-input-field][data-mp-ring="inset"]:focus-visible {
46
- outline-offset: 0px !important;
47
- }`;
48
- document.head.appendChild(tag);
49
- }
50
-
51
34
  export interface InputProps {
52
35
  name?: string;
53
36
  form?: AnyFormApi;
@@ -165,7 +148,6 @@ export function Input({
165
148
  });
166
149
  const inputRef = useRef<TamaguiElement>(null);
167
150
  const focusTrigger = useForwardFocus(inputRef);
168
- if (isWeb) ensureInputFieldRingOffset();
169
151
 
170
152
  const resolvedValidators = useResolvedValidators(required, validators, label, name);
171
153
 
@@ -199,7 +181,6 @@ export function Input({
199
181
  "data-ring-target": "box",
200
182
  "data-radius-class": "DEFAULT",
201
183
  "data-radius-part": "Input",
202
- "data-ring-offset": "0",
203
184
  "data-mp-input-field": "true",
204
185
  ...(belowFloor ? { hitSlop: pressTargetHitSlop(visualHeight) } : undefined),
205
186
  } as const;