@multiplatform.one/forms 8.3.0 → 8.5.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 (520) hide show
  1. package/dist/cjs/AdaptivePopup/index.native.js +2 -2
  2. package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
  3. package/dist/cjs/Button/IconButtonGroup.native.js.map +1 -1
  4. package/dist/cjs/Button/circleGlyph.native.js.map +1 -1
  5. package/dist/cjs/Button/iconButtonGroupContext.native.js.map +1 -1
  6. package/dist/cjs/Button/index.native.js +2 -2
  7. package/dist/cjs/Button/index.native.js.map +1 -1
  8. package/dist/cjs/Button/webGlass.native.js.map +1 -1
  9. package/dist/cjs/Chip/index.native.js.map +1 -1
  10. package/dist/cjs/Composer/index.cjs +10 -4
  11. package/dist/cjs/Composer/index.native.js +15 -9
  12. package/dist/cjs/Composer/index.native.js.map +1 -1
  13. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js +1 -1
  14. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  15. package/dist/cjs/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  16. package/dist/cjs/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  17. package/dist/cjs/ContextualSaveBar/index.native.js +3 -3
  18. package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
  19. package/dist/cjs/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  20. package/dist/cjs/ControlGroup/index.cjs +2 -1
  21. package/dist/cjs/ControlGroup/index.native.js +3 -2
  22. package/dist/cjs/ControlGroup/index.native.js.map +1 -1
  23. package/dist/cjs/DescriptionList/index.native.js +2 -2
  24. package/dist/cjs/DescriptionList/index.native.js.map +1 -1
  25. package/dist/cjs/ErrorSummary.native.js.map +1 -1
  26. package/dist/cjs/FieldDisplay/editMode.native.js.map +1 -1
  27. package/dist/cjs/FieldDisplay/formatters.native.js.map +1 -1
  28. package/dist/cjs/FieldDisplay/index.native.js +1 -1
  29. package/dist/cjs/FieldDisplay/index.native.js.map +1 -1
  30. package/dist/cjs/FieldGroup.native.js.map +1 -1
  31. package/dist/cjs/FloatingPanel/PanelHeader.native.js.map +1 -1
  32. package/dist/cjs/FloatingPanel/RegularPanel.native.js.map +1 -1
  33. package/dist/cjs/FloatingPanel/compactFace.native.js.map +1 -1
  34. package/dist/cjs/FloatingPanel/containingBlock.native.js.map +1 -1
  35. package/dist/cjs/FloatingPanel/coverRect.native.js.map +1 -1
  36. package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -1
  37. package/dist/cjs/FloatingPanel/index.cjs +11 -2
  38. package/dist/cjs/FloatingPanel/index.native.js +32 -17
  39. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  40. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -1
  41. package/dist/cjs/FloatingPanel/paintedBox.native.js.map +1 -1
  42. package/dist/cjs/FloatingPanel/panelWidth.native.js.map +1 -1
  43. package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
  44. package/dist/cjs/FloatingPanel/regularPlacement.native.js.map +1 -1
  45. package/dist/cjs/FloatingPanel/trailingAction.native.js +1 -1
  46. package/dist/cjs/FloatingPanel/trailingAction.native.js.map +1 -1
  47. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  48. package/dist/cjs/Form/index.native.js +1 -1
  49. package/dist/cjs/Form/index.native.js.map +1 -1
  50. package/dist/cjs/Form/submissionController.native.js.map +1 -1
  51. package/dist/cjs/Form/validateOn.native.js.map +1 -1
  52. package/dist/cjs/FormGrid.native.js.map +1 -1
  53. package/dist/cjs/FormSection.native.js.map +1 -1
  54. package/dist/cjs/InputParts/PasswordReveal.native.js.map +1 -1
  55. package/dist/cjs/InputParts/index.cjs +1 -0
  56. package/dist/cjs/InputParts/index.native.js +1 -0
  57. package/dist/cjs/InputParts/index.native.js.map +1 -1
  58. package/dist/cjs/InputParts/keyboardAppearance.native.js.map +1 -1
  59. package/dist/cjs/Label/index.native.js.map +1 -1
  60. package/dist/cjs/MediaPicker/base64.native.js.map +1 -1
  61. package/dist/cjs/MediaPicker/payload.native.js.map +1 -1
  62. package/dist/cjs/MediaPicker/types.native.js.map +1 -1
  63. package/dist/cjs/MediaPicker/useMediaPicker.native.js.map +1 -1
  64. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  65. package/dist/cjs/Spinner/SpinnerGlyph.native.js.map +1 -1
  66. package/dist/cjs/Spinner/spinnerSize.native.js.map +1 -1
  67. package/dist/cjs/Table/index.native.js.map +1 -1
  68. package/dist/cjs/Wheel/haptic.native.js.map +1 -1
  69. package/dist/cjs/Wheel/index.cjs +22 -6
  70. package/dist/cjs/Wheel/index.native.js +26 -8
  71. package/dist/cjs/Wheel/index.native.js.map +1 -1
  72. package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
  73. package/dist/cjs/actionLabel.native.js.map +1 -1
  74. package/dist/cjs/fieldDefaults.native.js.map +1 -1
  75. package/dist/cjs/fieldLayout.native.js +1 -1
  76. package/dist/cjs/fieldLayout.native.js.map +1 -1
  77. package/dist/cjs/fields/Barcode/BarcodePreview.native.js.map +1 -1
  78. package/dist/cjs/fields/Barcode/BarcodeScanner.native.js +1 -1
  79. package/dist/cjs/fields/Barcode/code128.native.js.map +1 -1
  80. package/dist/cjs/fields/Barcode/index.native.js +2 -2
  81. package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
  82. package/dist/cjs/fields/Barcode/qr.native.js.map +1 -1
  83. package/dist/cjs/fields/Barcode/scannerTypes.native.js.map +1 -1
  84. package/dist/cjs/fields/Checkbox/Checkbox.native.js +1 -1
  85. package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
  86. package/dist/cjs/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  87. package/dist/cjs/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  88. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  89. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js +1 -1
  90. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  91. package/dist/cjs/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  92. package/dist/cjs/fields/Checkbox/index.native.js.map +1 -1
  93. package/dist/cjs/fields/ColorPicker/SystemColorField.native.js.map +1 -1
  94. package/dist/cjs/fields/ColorPicker/index.native.js +2 -2
  95. package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
  96. package/dist/cjs/fields/ColorPicker/parts.native.js +2 -2
  97. package/dist/cjs/fields/ColorPicker/parts.native.js.map +1 -1
  98. package/dist/cjs/fields/ColorPicker/systemColorWell.gnome.native.js.map +1 -1
  99. package/dist/cjs/fields/Combobox/authorOptions.native.js.map +1 -1
  100. package/dist/cjs/fields/Combobox/index.native.js +5 -5
  101. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  102. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  103. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  104. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  105. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +3 -3
  106. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  107. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +2 -2
  108. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +2 -2
  109. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  110. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  111. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  112. package/dist/cjs/fields/DatePicker/catalog.native.js +2 -2
  113. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
  114. package/dist/cjs/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  115. package/dist/cjs/fields/DatePicker/index.native.js +2 -2
  116. package/dist/cjs/fields/DatePicker/parts.cjs +33 -30
  117. package/dist/cjs/fields/DatePicker/parts.native.js +36 -32
  118. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  119. package/dist/cjs/fields/DatePicker/utils.native.js.map +1 -1
  120. package/dist/cjs/fields/Duration/DurationWheel.native.js +1 -1
  121. package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
  122. package/dist/cjs/fields/Duration/durationWheelTypes.native.js.map +1 -1
  123. package/dist/cjs/fields/Duration/index.native.js +3 -3
  124. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  125. package/dist/cjs/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  126. package/dist/cjs/fields/FileUpload/index.cjs +32 -15
  127. package/dist/cjs/fields/FileUpload/index.native.js +42 -21
  128. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  129. package/dist/cjs/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  130. package/dist/cjs/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  131. package/dist/cjs/fields/Geolocation/geoValue.native.js.map +1 -1
  132. package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -1
  133. package/dist/cjs/fields/Geolocation/geocoderContext.native.js.map +1 -1
  134. package/dist/cjs/fields/Geolocation/index.native.js +5 -5
  135. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  136. package/dist/cjs/fields/Geolocation/mapMath.native.js.map +1 -1
  137. package/dist/cjs/fields/Geolocation/mapTypes.native.js.map +1 -1
  138. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
  139. package/dist/cjs/fields/Geolocation/photonGeocoder.native.js.map +1 -1
  140. package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
  141. package/dist/cjs/fields/Icon/index.native.js +3 -3
  142. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  143. package/dist/cjs/fields/ImageField/index.cjs +35 -20
  144. package/dist/cjs/fields/ImageField/index.native.js +39 -22
  145. package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
  146. package/dist/cjs/fields/Input/index.native.js +3 -3
  147. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  148. package/dist/cjs/fields/MentionInput/index.native.js +3 -3
  149. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  150. package/dist/cjs/fields/OTPInput/index.native.js +3 -3
  151. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  152. package/dist/cjs/fields/OTPInput/otpCellCss.native.js.map +1 -1
  153. package/dist/cjs/fields/OTPInput/otpCellEdge.native.js.map +1 -1
  154. package/dist/cjs/fields/PhoneInput/dialCodes.native.js.map +1 -1
  155. package/dist/cjs/fields/PhoneInput/index.native.js +3 -3
  156. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  157. package/dist/cjs/fields/PhoneInput/phone.native.js.map +1 -1
  158. package/dist/cjs/fields/PhoneInput/regionNames.native.js.map +1 -1
  159. package/dist/cjs/fields/Progress/index.cjs +5 -0
  160. package/dist/cjs/fields/Progress/index.native.js +6 -1
  161. package/dist/cjs/fields/Progress/index.native.js.map +1 -1
  162. package/dist/cjs/fields/RadioGroup/index.native.js +1 -1
  163. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  164. package/dist/cjs/fields/Rating/index.native.js +1 -1
  165. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  166. package/dist/cjs/fields/Rating/ratingMath.native.js.map +1 -1
  167. package/dist/cjs/fields/Rating/types.native.js.map +1 -1
  168. package/dist/cjs/fields/SearchInput/index.native.js +2 -2
  169. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  170. package/dist/cjs/fields/Select/InlineChoices.native.js.map +1 -1
  171. package/dist/cjs/fields/Select/SheetPickerRow.native.js.map +1 -1
  172. package/dist/cjs/fields/Select/index.native.js +4 -4
  173. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  174. package/dist/cjs/fields/Select/shouldInlineChoices.native.js.map +1 -1
  175. package/dist/cjs/fields/Signature/index.native.js +2 -2
  176. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  177. package/dist/cjs/fields/Slider/index.cjs +38 -12
  178. package/dist/cjs/fields/Slider/index.native.js +40 -12
  179. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  180. package/dist/cjs/fields/Slider/jumpMotion.native.js.map +1 -1
  181. package/dist/cjs/fields/Stepper/index.native.js +2 -2
  182. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  183. package/dist/cjs/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  184. package/dist/cjs/fields/Switch/footprint.native.js.map +1 -1
  185. package/dist/cjs/fields/Switch/index.cjs +10 -6
  186. package/dist/cjs/fields/Switch/index.native.js +12 -8
  187. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  188. package/dist/cjs/fields/TextArea/index.native.js +2 -2
  189. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  190. package/dist/cjs/fields/TimePicker/catalog.native.js +3 -3
  191. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  192. package/dist/cjs/fields/TimePicker/index.native.js +2 -2
  193. package/dist/cjs/fields/TimePicker/parts.cjs +9 -10
  194. package/dist/cjs/fields/TimePicker/parts.native.js +10 -11
  195. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  196. package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  197. package/dist/cjs/fields/TimeRangeScrubber/index.native.js +2 -2
  198. package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
  199. package/dist/cjs/fields/ToggleGroup/index.cjs +1 -0
  200. package/dist/cjs/fields/ToggleGroup/index.native.js +2 -1
  201. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  202. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +1 -1
  203. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  204. package/dist/cjs/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
  205. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  206. package/dist/cjs/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
  207. package/dist/cjs/fields/nativeSelect.native.js.map +1 -1
  208. package/dist/cjs/fields/pickerHandle.cjs +18 -0
  209. package/dist/cjs/fields/pickerHandle.native.js +21 -0
  210. package/dist/cjs/fields/pickerHandle.native.js.map +1 -0
  211. package/dist/cjs/fields/selectedOrder.native.js.map +1 -1
  212. package/dist/cjs/formSpacing.native.js.map +1 -1
  213. package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
  214. package/dist/cjs/hooks/useHoldCue.cjs +54 -0
  215. package/dist/cjs/hooks/useHoldCue.native.js +62 -0
  216. package/dist/cjs/hooks/useHoldCue.native.js.map +1 -0
  217. package/dist/cjs/index.cjs +15 -0
  218. package/dist/cjs/index.gnome.cjs +15 -0
  219. package/dist/cjs/index.gnome.native.js +52 -37
  220. package/dist/cjs/index.gnome.native.js.map +1 -1
  221. package/dist/cjs/index.native.js +61 -46
  222. package/dist/cjs/index.native.js.map +1 -1
  223. package/dist/cjs/keyboard/KeyboardDoneBar.native.js +1 -1
  224. package/dist/cjs/keyboard/chain.native.js.map +1 -1
  225. package/dist/cjs/keyboard/index.native.js.map +1 -1
  226. package/dist/cjs/keyboard/types.native.js.map +1 -1
  227. package/dist/cjs/nativeTwins.native.js.map +1 -1
  228. package/dist/cjs/requiredMarking.native.js.map +1 -1
  229. package/dist/cjs/shared/CheckGlyph.native.js.map +1 -1
  230. package/dist/cjs/shared/TimeColumn.native.js +1 -1
  231. package/dist/cjs/shared/TimeColumn.native.js.map +1 -1
  232. package/dist/cjs/shared/capabilityPreflight.native.js.map +1 -1
  233. package/dist/cjs/shared/checkedOnField.native.js.map +1 -1
  234. package/dist/cjs/shared/choiceRowPress.native.js.map +1 -1
  235. package/dist/cjs/shared/colorRamps.cjs +9 -7
  236. package/dist/cjs/shared/colorRamps.native.js +9 -7
  237. package/dist/cjs/shared/colorRamps.native.js.map +1 -1
  238. package/dist/cjs/shared/controlTrack.cjs +32 -0
  239. package/dist/cjs/shared/controlTrack.native.js +35 -0
  240. package/dist/cjs/shared/controlTrack.native.js.map +1 -0
  241. package/dist/cjs/shared/devWarn.native.js.map +1 -1
  242. package/dist/cjs/shared/fieldRowContext.native.js.map +1 -1
  243. package/dist/cjs/shared/floatingList.native.js +1 -1
  244. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  245. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  246. package/dist/cjs/shared/groupContext.native.js.map +1 -1
  247. package/dist/cjs/shared/i18n.native.js.map +1 -1
  248. package/dist/cjs/shared/instantMotion.native.js.map +1 -1
  249. package/dist/cjs/shared/nativeA11y.native.js.map +1 -1
  250. package/dist/cjs/shared/nativeAutoFocus.native.js.map +1 -1
  251. package/dist/cjs/shared/nativeOverlayWindow.native.js.map +1 -1
  252. package/dist/cjs/shared/overlaySizeClass.native.js.map +1 -1
  253. package/dist/cjs/shared/overlayStack.native.js.map +1 -1
  254. package/dist/cjs/shared/panelPortal.native.js.map +1 -1
  255. package/dist/cjs/shared/pickerTriggerContract.native.js.map +1 -1
  256. package/dist/cjs/shared/pressSlopProps.native.js.map +1 -1
  257. package/dist/cjs/shared/restoreRetries.native.js.map +1 -1
  258. package/dist/cjs/shared/sheetDetents.cjs +109 -0
  259. package/dist/cjs/shared/sheetDetents.native.js +125 -0
  260. package/dist/cjs/shared/sheetDetents.native.js.map +1 -0
  261. package/dist/cjs/shared/sheetNavigation.native.js.map +1 -1
  262. package/dist/cjs/shared/systemControlModules.gnome.native.js.map +1 -1
  263. package/dist/cjs/shared/systemControls.native.js.map +1 -1
  264. package/dist/cjs/shared/t.native.js.map +1 -1
  265. package/dist/cjs/shared/tableCellContext.native.js.map +1 -1
  266. package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
  267. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  268. package/dist/cjs/shared/useSheetEscapeDismiss.native.js.map +1 -1
  269. package/dist/cjs/shared/useWheelIncrement.native.js.map +1 -1
  270. package/dist/cjs/shared/utils.native.js +1 -1
  271. package/dist/cjs/shared/utils.native.js.map +1 -1
  272. package/dist/cjs/shared/zIndex.native.js.map +1 -1
  273. package/dist/cjs/standardActions.native.js.map +1 -1
  274. package/dist/cjs/themedPrimitives.native.js.map +1 -1
  275. package/dist/cjs/types.native.js.map +1 -1
  276. package/dist/cjs/utils/LinkCell.native.js.map +1 -1
  277. package/dist/esm/Composer/index.mjs +10 -4
  278. package/dist/esm/Composer/index.mjs.map +1 -1
  279. package/dist/esm/Composer/index.native.js +14 -8
  280. package/dist/esm/Composer/index.native.js.map +1 -1
  281. package/dist/esm/ControlGroup/index.mjs +2 -1
  282. package/dist/esm/ControlGroup/index.mjs.map +1 -1
  283. package/dist/esm/ControlGroup/index.native.js +2 -1
  284. package/dist/esm/ControlGroup/index.native.js.map +1 -1
  285. package/dist/esm/FloatingPanel/index.mjs +12 -3
  286. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  287. package/dist/esm/FloatingPanel/index.native.js +31 -16
  288. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  289. package/dist/esm/InputParts/index.mjs +1 -0
  290. package/dist/esm/InputParts/index.mjs.map +1 -1
  291. package/dist/esm/InputParts/index.native.js +1 -0
  292. package/dist/esm/InputParts/index.native.js.map +1 -1
  293. package/dist/esm/Wheel/index.mjs +23 -7
  294. package/dist/esm/Wheel/index.mjs.map +1 -1
  295. package/dist/esm/Wheel/index.native.js +27 -9
  296. package/dist/esm/Wheel/index.native.js.map +1 -1
  297. package/dist/esm/fields/DatePicker/parts.mjs +35 -32
  298. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  299. package/dist/esm/fields/DatePicker/parts.native.js +36 -32
  300. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  301. package/dist/esm/fields/FileUpload/index.mjs +33 -16
  302. package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
  303. package/dist/esm/fields/FileUpload/index.native.js +41 -20
  304. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  305. package/dist/esm/fields/ImageField/index.mjs +36 -21
  306. package/dist/esm/fields/ImageField/index.mjs.map +1 -1
  307. package/dist/esm/fields/ImageField/index.native.js +38 -21
  308. package/dist/esm/fields/ImageField/index.native.js.map +1 -1
  309. package/dist/esm/fields/Progress/index.mjs +5 -0
  310. package/dist/esm/fields/Progress/index.mjs.map +1 -1
  311. package/dist/esm/fields/Progress/index.native.js +5 -0
  312. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  313. package/dist/esm/fields/Slider/index.mjs +38 -12
  314. package/dist/esm/fields/Slider/index.mjs.map +1 -1
  315. package/dist/esm/fields/Slider/index.native.js +39 -11
  316. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  317. package/dist/esm/fields/Switch/index.mjs +10 -6
  318. package/dist/esm/fields/Switch/index.mjs.map +1 -1
  319. package/dist/esm/fields/Switch/index.native.js +10 -6
  320. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  321. package/dist/esm/fields/TimePicker/parts.mjs +9 -10
  322. package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
  323. package/dist/esm/fields/TimePicker/parts.native.js +9 -10
  324. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  325. package/dist/esm/fields/ToggleGroup/index.mjs +2 -1
  326. package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
  327. package/dist/esm/fields/ToggleGroup/index.native.js +2 -1
  328. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  329. package/dist/esm/fields/pickerHandle.mjs +2 -0
  330. package/dist/esm/fields/pickerHandle.mjs.map +1 -0
  331. package/dist/esm/fields/pickerHandle.native.js +2 -0
  332. package/dist/esm/fields/pickerHandle.native.js.map +1 -0
  333. package/dist/esm/hooks/useHoldCue.mjs +27 -0
  334. package/dist/esm/hooks/useHoldCue.mjs.map +1 -0
  335. package/dist/esm/hooks/useHoldCue.native.js +32 -0
  336. package/dist/esm/hooks/useHoldCue.native.js.map +1 -0
  337. package/dist/esm/index.gnome.mjs +3 -1
  338. package/dist/esm/index.gnome.mjs.map +1 -1
  339. package/dist/esm/index.gnome.native.js +3 -1
  340. package/dist/esm/index.gnome.native.js.map +1 -1
  341. package/dist/esm/index.mjs +3 -1
  342. package/dist/esm/index.mjs.map +1 -1
  343. package/dist/esm/index.native.js +3 -1
  344. package/dist/esm/index.native.js.map +1 -1
  345. package/dist/esm/shared/colorRamps.mjs +9 -7
  346. package/dist/esm/shared/colorRamps.mjs.map +1 -1
  347. package/dist/esm/shared/colorRamps.native.js +9 -7
  348. package/dist/esm/shared/colorRamps.native.js.map +1 -1
  349. package/dist/esm/shared/controlTrack.mjs +7 -0
  350. package/dist/esm/shared/controlTrack.mjs.map +1 -0
  351. package/dist/esm/shared/controlTrack.native.js +7 -0
  352. package/dist/esm/shared/controlTrack.native.js.map +1 -0
  353. package/dist/esm/shared/nativeOverlayWindow.mjs.map +1 -1
  354. package/dist/esm/shared/sheetDetents.mjs +75 -0
  355. package/dist/esm/shared/sheetDetents.mjs.map +1 -0
  356. package/dist/esm/shared/sheetDetents.native.js +88 -0
  357. package/dist/esm/shared/sheetDetents.native.js.map +1 -0
  358. package/dist/esm/shared/systemControls.mjs.map +1 -1
  359. package/dist/esm/shared/systemControls.native.js.map +1 -1
  360. package/dist/jsx/Composer/index.mjs +10 -4
  361. package/dist/jsx/Composer/index.mjs.map +1 -1
  362. package/dist/jsx/Composer/index.native.js +14 -8
  363. package/dist/jsx/Composer/index.native.js.map +1 -1
  364. package/dist/jsx/ControlGroup/index.mjs +2 -1
  365. package/dist/jsx/ControlGroup/index.mjs.map +1 -1
  366. package/dist/jsx/ControlGroup/index.native.js +2 -1
  367. package/dist/jsx/ControlGroup/index.native.js.map +1 -1
  368. package/dist/jsx/FloatingPanel/index.mjs +12 -3
  369. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  370. package/dist/jsx/FloatingPanel/index.native.js +32 -17
  371. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  372. package/dist/jsx/InputParts/index.mjs +1 -0
  373. package/dist/jsx/InputParts/index.mjs.map +1 -1
  374. package/dist/jsx/InputParts/index.native.js +1 -0
  375. package/dist/jsx/InputParts/index.native.js.map +1 -1
  376. package/dist/jsx/Wheel/index.mjs +23 -7
  377. package/dist/jsx/Wheel/index.mjs.map +1 -1
  378. package/dist/jsx/Wheel/index.native.js +26 -8
  379. package/dist/jsx/Wheel/index.native.js.map +1 -1
  380. package/dist/jsx/fields/DatePicker/parts.mjs +35 -32
  381. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  382. package/dist/jsx/fields/DatePicker/parts.native.js +34 -30
  383. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  384. package/dist/jsx/fields/FileUpload/index.mjs +33 -16
  385. package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
  386. package/dist/jsx/fields/FileUpload/index.native.js +40 -19
  387. package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
  388. package/dist/jsx/fields/ImageField/index.mjs +36 -21
  389. package/dist/jsx/fields/ImageField/index.mjs.map +1 -1
  390. package/dist/jsx/fields/ImageField/index.native.js +37 -20
  391. package/dist/jsx/fields/ImageField/index.native.js.map +1 -1
  392. package/dist/jsx/fields/Progress/index.mjs +5 -0
  393. package/dist/jsx/fields/Progress/index.mjs.map +1 -1
  394. package/dist/jsx/fields/Progress/index.native.js +5 -0
  395. package/dist/jsx/fields/Progress/index.native.js.map +1 -1
  396. package/dist/jsx/fields/Slider/index.mjs +38 -12
  397. package/dist/jsx/fields/Slider/index.mjs.map +1 -1
  398. package/dist/jsx/fields/Slider/index.native.js +39 -11
  399. package/dist/jsx/fields/Slider/index.native.js.map +1 -1
  400. package/dist/jsx/fields/Switch/index.mjs +10 -6
  401. package/dist/jsx/fields/Switch/index.mjs.map +1 -1
  402. package/dist/jsx/fields/Switch/index.native.js +10 -6
  403. package/dist/jsx/fields/Switch/index.native.js.map +1 -1
  404. package/dist/jsx/fields/TimePicker/parts.mjs +9 -10
  405. package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
  406. package/dist/jsx/fields/TimePicker/parts.native.js +9 -10
  407. package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
  408. package/dist/jsx/fields/ToggleGroup/index.mjs +2 -1
  409. package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
  410. package/dist/jsx/fields/ToggleGroup/index.native.js +1 -0
  411. package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
  412. package/dist/jsx/fields/pickerHandle.mjs +2 -0
  413. package/dist/jsx/fields/pickerHandle.mjs.map +1 -0
  414. package/dist/jsx/fields/pickerHandle.native.js +21 -0
  415. package/dist/jsx/fields/pickerHandle.native.js.map +1 -0
  416. package/dist/jsx/hooks/useHoldCue.mjs +27 -0
  417. package/dist/jsx/hooks/useHoldCue.mjs.map +1 -0
  418. package/dist/jsx/hooks/useHoldCue.native.js +62 -0
  419. package/dist/jsx/hooks/useHoldCue.native.js.map +1 -0
  420. package/dist/jsx/index.gnome.mjs +3 -1
  421. package/dist/jsx/index.gnome.mjs.map +1 -1
  422. package/dist/jsx/index.gnome.native.js +15 -0
  423. package/dist/jsx/index.gnome.native.js.map +1 -1
  424. package/dist/jsx/index.js +3 -1
  425. package/dist/jsx/index.js.map +1 -1
  426. package/dist/jsx/index.mjs +3 -1
  427. package/dist/jsx/index.mjs.map +1 -1
  428. package/dist/jsx/index.native.js +15 -0
  429. package/dist/jsx/index.native.js.map +1 -1
  430. package/dist/jsx/shared/colorRamps.mjs +9 -7
  431. package/dist/jsx/shared/colorRamps.mjs.map +1 -1
  432. package/dist/jsx/shared/colorRamps.native.js +9 -7
  433. package/dist/jsx/shared/colorRamps.native.js.map +1 -1
  434. package/dist/jsx/shared/controlTrack.mjs +7 -0
  435. package/dist/jsx/shared/controlTrack.mjs.map +1 -0
  436. package/dist/jsx/shared/controlTrack.native.js +35 -0
  437. package/dist/jsx/shared/controlTrack.native.js.map +1 -0
  438. package/dist/jsx/shared/nativeOverlayWindow.mjs.map +1 -1
  439. package/dist/jsx/shared/nativeOverlayWindow.native.js.map +1 -1
  440. package/dist/jsx/shared/sheetDetents.mjs +75 -0
  441. package/dist/jsx/shared/sheetDetents.mjs.map +1 -0
  442. package/dist/jsx/shared/sheetDetents.native.js +125 -0
  443. package/dist/jsx/shared/sheetDetents.native.js.map +1 -0
  444. package/dist/jsx/shared/systemControls.mjs.map +1 -1
  445. package/package.json +11 -10
  446. package/src/Button/Button.controlTiers.spec.tsx +2 -2
  447. package/src/Composer/Composer.glass.spec.tsx +106 -0
  448. package/src/Composer/Composer.spec.tsx +11 -2
  449. package/src/Composer/index.tsx +11 -8
  450. package/src/ControlGroup/index.tsx +2 -1
  451. package/src/FloatingPanel/FloatingPanel.holdCue.native.spec.tsx +72 -0
  452. package/src/FloatingPanel/index.native.tsx +18 -19
  453. package/src/FloatingPanel/index.tsx +24 -2
  454. package/src/InputParts/index.tsx +1 -0
  455. package/src/Wheel/Wheel.edgeFade.spec.tsx +74 -0
  456. package/src/Wheel/index.tsx +25 -11
  457. package/src/fields/DatePicker/dateFieldMarks.spec.tsx +154 -0
  458. package/src/fields/DatePicker/parts.tsx +33 -30
  459. package/src/fields/FileUpload/index.tsx +45 -16
  460. package/src/fields/ImageField/index.tsx +42 -19
  461. package/src/fields/Progress/index.tsx +3 -0
  462. package/src/fields/Slider/Slider.system.native.spec.tsx +44 -0
  463. package/src/fields/Slider/index.tsx +40 -12
  464. package/src/fields/Stepper/Stepper.stories.tsx +42 -0
  465. package/src/fields/Switch/Switch.spec.tsx +14 -10
  466. package/src/fields/Switch/index.tsx +11 -7
  467. package/src/fields/TimePicker/parts.tsx +8 -8
  468. package/src/fields/ToggleGroup/index.tsx +7 -1
  469. package/src/fields/fieldTriggerSlot.spec.tsx +89 -0
  470. package/src/fields/pickerHandle.ts +13 -0
  471. package/src/hooks/useHoldCue.ts +26 -0
  472. package/src/index.gnome.ts +19 -0
  473. package/src/index.ts +20 -0
  474. package/src/overlayGround.spec.ts +5 -3
  475. package/src/shared/OverlayWindow.tsx +2 -2
  476. package/src/shared/colorRamps.ts +9 -6
  477. package/src/shared/controlTrack.ts +7 -0
  478. package/src/shared/nativeOverlayWindow.tsx +1 -1
  479. package/src/shared/sheetDetents.spec.ts +117 -0
  480. package/src/shared/sheetDetents.ts +183 -0
  481. package/src/shared/systemControls.ts +10 -2
  482. package/types/Composer/index.d.ts.map +1 -1
  483. package/types/ControlGroup/index.d.ts.map +1 -1
  484. package/types/FloatingPanel/index.d.ts +9 -0
  485. package/types/FloatingPanel/index.d.ts.map +1 -1
  486. package/types/FloatingPanel/index.native.d.ts +1 -1
  487. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  488. package/types/InputParts/index.d.ts +4 -4
  489. package/types/InputParts/index.d.ts.map +1 -1
  490. package/types/Wheel/index.d.ts.map +1 -1
  491. package/types/fields/DatePicker/parts.d.ts +4 -3
  492. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  493. package/types/fields/FileUpload/index.d.ts +6 -1
  494. package/types/fields/FileUpload/index.d.ts.map +1 -1
  495. package/types/fields/ImageField/index.d.ts +7 -2
  496. package/types/fields/ImageField/index.d.ts.map +1 -1
  497. package/types/fields/Progress/index.d.ts.map +1 -1
  498. package/types/fields/Slider/index.d.ts.map +1 -1
  499. package/types/fields/Switch/index.d.ts.map +1 -1
  500. package/types/fields/ToggleGroup/index.d.ts.map +1 -1
  501. package/types/fields/pickerHandle.d.ts +12 -0
  502. package/types/fields/pickerHandle.d.ts.map +1 -0
  503. package/types/hooks/useHoldCue.d.ts +10 -0
  504. package/types/hooks/useHoldCue.d.ts.map +1 -0
  505. package/types/index.d.ts +4 -0
  506. package/types/index.d.ts.map +1 -1
  507. package/types/index.gnome.d.ts +3 -0
  508. package/types/index.gnome.d.ts.map +1 -1
  509. package/types/shared/OverlayWindow.d.ts +2 -2
  510. package/types/shared/OverlayWindow.d.ts.map +1 -1
  511. package/types/shared/colorRamps.d.ts +8 -6
  512. package/types/shared/colorRamps.d.ts.map +1 -1
  513. package/types/shared/controlTrack.d.ts +3 -0
  514. package/types/shared/controlTrack.d.ts.map +1 -0
  515. package/types/shared/nativeOverlayWindow.d.ts +1 -1
  516. package/types/shared/nativeOverlayWindow.d.ts.map +1 -1
  517. package/types/shared/sheetDetents.d.ts +122 -0
  518. package/types/shared/sheetDetents.d.ts.map +1 -0
  519. package/types/shared/systemControls.d.ts +2 -1
  520. package/types/shared/systemControls.d.ts.map +1 -1
@@ -499,16 +499,20 @@ describe("Switch thumb and pointer paint", () => {
499
499
  expect(paint(track, "_bg-")).toBe("var(--switchTrackOff)");
500
500
  });
501
501
 
502
- it.each([false, true])("grown=%s changes only the outlined ring on hover", (grown) => {
503
- const { frame, track } = mount({ grown, outlined: true });
504
- expect(track.className).toContain("_bg-transparent");
505
- expect(paint(track, "_btc-")).toBe("var(--switchTrackOff)");
506
- fireEvent.mouseEnter(frame);
507
- expect(track.className).toContain("_bg-transparent");
508
- expect(paint(track, "_btc-")).toBe("var(--switchTrackOffHover)");
509
- fireEvent.mouseLeave(frame);
510
- expect(paint(track, "_btc-")).toBe("var(--switchTrackOff)");
511
- });
502
+ it.each([false, true])(
503
+ "grown=%s keeps the outlined ring on its 3:1 edge and washes the track on hover (LC-299)",
504
+ (grown) => {
505
+ const { frame, track } = mount({ grown, outlined: true });
506
+ expect(track.className).toContain("_bg-transparent");
507
+ expect(paint(track, "_btc-")).toBe("var(--switchTrackOffBorder)");
508
+ fireEvent.mouseEnter(frame);
509
+ expect(paint(track, "_bg-")).toBe("var(--switchTrackOffHover)");
510
+ expect(paint(track, "_btc-")).toBe("var(--switchTrackOffBorder)");
511
+ fireEvent.mouseLeave(frame);
512
+ expect(track.className).toContain("_bg-transparent");
513
+ expect(paint(track, "_btc-")).toBe("var(--switchTrackOffBorder)");
514
+ },
515
+ );
512
516
 
513
517
  it("composes the caller's mouse handlers once", () => {
514
518
  const onMouseEnter = vi.fn();
@@ -198,7 +198,7 @@ const SwitchFrameStyled = styled(View, {
198
198
  borderRadius: 1000,
199
199
  backgroundColor: formSwitchColors.track.off,
200
200
  borderWidth: 0,
201
- borderColor: formSwitchColors.track.off,
201
+ borderColor: formSwitchColors.track.offBorder,
202
202
  outlineWidth: 0,
203
203
  focusStyle: { outlineWidth: 0 },
204
204
  // LC-71: ring is painted from keyboard modality on the track, never
@@ -214,7 +214,7 @@ const SwitchFrameStyled = styled(View, {
214
214
  },
215
215
  false: {
216
216
  backgroundColor: formSwitchColors.track.off,
217
- borderColor: formSwitchColors.track.off,
217
+ borderColor: formSwitchColors.track.offBorder,
218
218
  },
219
219
  },
220
220
 
@@ -406,6 +406,8 @@ function SwitchControl({
406
406
  : hovered
407
407
  ? formSwitchColors.track.offHover
408
408
  : formSwitchColors.track.off;
409
+ const offFill = outlined && !hovered && !pressed ? "transparent" : offPaint;
410
+ const offRing = outlined ? undefined : knobProps.trackRing;
409
411
  const { thumbInset, thumbSize, travel: dragDistance } = footprint;
410
412
  const motion = resolveSwitchMotion(transition);
411
413
  const [dragX, setDragX] = useState<number | null>(null);
@@ -562,8 +564,9 @@ function SwitchControl({
562
564
  borderColor: formSwitchColors.track.on,
563
565
  }
564
566
  : {
565
- backgroundColor: outlined ? "transparent" : offPaint,
566
- borderColor: offPaint,
567
+ backgroundColor: offFill,
568
+ borderColor: formSwitchColors.track.offBorder,
569
+ ...offRing,
567
570
  })}
568
571
  {...(kbFocus ? { "data-kb-focus": "true" } : undefined)}
569
572
  {...(frameClassName ? { className: frameClassName } : undefined)}
@@ -653,10 +656,11 @@ function SwitchControl({
653
656
  borderRadius={cellTrack.borderRadius}
654
657
  {...radiusResolution}
655
658
  borderWidth={cellTrack.borderWidth}
656
- borderColor={displayChecked ? formSwitchColors.track.on : offPaint}
657
- backgroundColor={
658
- displayChecked ? formSwitchColors.track.on : outlined ? "transparent" : offPaint
659
+ borderColor={
660
+ displayChecked ? formSwitchColors.track.on : formSwitchColors.track.offBorder
659
661
  }
662
+ backgroundColor={displayChecked ? formSwitchColors.track.on : offFill}
663
+ {...(displayChecked ? undefined : offRing)}
660
664
  {...transitionProps({ ...knobProps.motion.control, transition: motion }, ["borderWidth"])}
661
665
  pointerEvents="none"
662
666
  className={kbFocus ? SWITCH_KB_RING_CLASS : undefined}
@@ -160,11 +160,6 @@ export function TimePickerInputTrigger({
160
160
  onPress={isWeb && interactive ? onOpen : undefined}
161
161
  {...(disabled ? { opacity: 0.5, pointerEvents: "none" as const } : undefined)}
162
162
  >
163
- <InputParts.Section data-testid="time-picker-glyph">
164
- <InputParts.Icon adornment="leading" color={formCommonColors.muted}>
165
- {clockIcon ?? <ClockIcon />}
166
- </InputParts.Icon>
167
- </InputParts.Section>
168
163
  <InputParts.Section>
169
164
  <InputParts.Area
170
165
  readOnly
@@ -174,7 +169,6 @@ export function TimePickerInputTrigger({
174
169
  placeholder={placeholder}
175
170
  disabled={disabled}
176
171
  color={formCommonColors.text}
177
- placeholderTextColor={formCommonColors.muted}
178
172
  aria-label={ariaLabel}
179
173
  aria-required={ariaRequired}
180
174
  aria-invalid={ariaInvalid}
@@ -196,11 +190,17 @@ export function TimePickerInputTrigger({
196
190
  }
197
191
  />
198
192
  </InputParts.Section>
199
- {value && isWeb && !readOnly ? (
193
+ {value && isWeb && !readOnly && !disabled ? (
200
194
  <InputParts.Section>
201
195
  <TimePickerClearButton onClear={onClear} disabled={disabled} />
202
196
  </InputParts.Section>
203
- ) : null}
197
+ ) : (
198
+ <InputParts.Section data-testid="time-picker-glyph">
199
+ <InputParts.Icon adornment="trailing" color={formCommonColors.muted}>
200
+ {clockIcon ?? <ClockIcon />}
201
+ </InputParts.Icon>
202
+ </InputParts.Section>
203
+ )}
204
204
  </InputParts.Box>
205
205
  </View>
206
206
  );
@@ -25,7 +25,12 @@ import {
25
25
  } from "tamagui";
26
26
  import { Skeleton } from "../../Skeleton";
27
27
  import { Field, FieldLayout } from "../../fieldLayout";
28
- import { formButtonColors, formCommonColors, formInputColors } from "../../shared/colorRamps";
28
+ import {
29
+ formButtonColors,
30
+ formCommonColors,
31
+ formControlColors,
32
+ formInputColors,
33
+ } from "../../shared/colorRamps";
29
34
  import { warnBareDisabled } from "../../shared/devWarn";
30
35
  import { choiceItemA11y, composeA11yName } from "../../shared/nativeA11y";
31
36
  import { loadSystemSegmentedControl } from "../../shared/systemControlModules";
@@ -693,6 +698,7 @@ export function ToggleGroup({
693
698
  {...toggleProps}
694
699
  {...knobProps.borderRadius}
695
700
  {...knobProps.inputSurface}
701
+ borderColor={formControlColors.edge}
696
702
  overflow="hidden"
697
703
  backgroundColor={knobProps.outlined ? "transparent" : formInputColors.background.base}
698
704
  {...(isWeb
@@ -0,0 +1,89 @@
1
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
2
+ import { act, cleanup, fireEvent } from "@testing-library/react";
3
+ import { createRef } from "react";
4
+ import { afterEach, describe, expect, it, vi } from "vitest";
5
+ import { Button } from "../Button";
6
+ import { FileUpload } from "./FileUpload";
7
+ import { ImageField } from "./ImageField";
8
+ import type { FieldPickerHandle } from "./pickerHandle";
9
+
10
+ afterEach(() => {
11
+ cleanup();
12
+ vi.restoreAllMocks();
13
+ });
14
+
15
+ function fileInput(container: HTMLElement) {
16
+ return container.querySelector("input[type='file']") as HTMLInputElement;
17
+ }
18
+
19
+ function pick(input: HTMLInputElement, file: File) {
20
+ fireEvent.change(input, { target: { files: [file] } });
21
+ }
22
+
23
+ describe("LC-290 FIELD-TRIGGER-SLOT", () => {
24
+ it("FileUpload opens its picker from an imperative open()", () => {
25
+ const click = vi.spyOn(HTMLInputElement.prototype, "click").mockImplementation(() => {});
26
+ const handle = createRef<FieldPickerHandle>();
27
+ renderWithProviders(<FileUpload ref={handle} />);
28
+ act(() => handle.current?.open());
29
+ expect(click).toHaveBeenCalledTimes(1);
30
+ });
31
+
32
+ it("FileUpload draws a consumer trigger instead of its dropzone, and a pick from it reaches onChange", () => {
33
+ const click = vi.spyOn(HTMLInputElement.prototype, "click").mockImplementation(() => {});
34
+ const onChange = vi.fn();
35
+ const { container, getByRole } = renderWithProviders(
36
+ <FileUpload
37
+ onChange={onChange}
38
+ trigger={(open) => (
39
+ <Button onPress={open} aria-label="Choose from library">
40
+ Library
41
+ </Button>
42
+ )}
43
+ />,
44
+ );
45
+ expect(container.querySelector("[data-file-upload='trigger']")).toBeTruthy();
46
+ expect(container.textContent).not.toContain("Choose File");
47
+ fireEvent.click(getByRole("button", { name: "Choose from library" }));
48
+ expect(click).toHaveBeenCalledTimes(1);
49
+ pick(fileInput(container), new File(["x"], "receipt.pdf", { type: "application/pdf" }));
50
+ expect(onChange).toHaveBeenCalledTimes(1);
51
+ });
52
+
53
+ it("FileUpload's open() does nothing while disabled", () => {
54
+ const click = vi.spyOn(HTMLInputElement.prototype, "click").mockImplementation(() => {});
55
+ const handle = createRef<FieldPickerHandle>();
56
+ renderWithProviders(<FileUpload ref={handle} disabled />);
57
+ act(() => handle.current?.open());
58
+ expect(click).not.toHaveBeenCalled();
59
+ });
60
+
61
+ it("ImageField opens its picker from an imperative open()", () => {
62
+ const click = vi.spyOn(HTMLInputElement.prototype, "click").mockImplementation(() => {});
63
+ const handle = createRef<FieldPickerHandle>();
64
+ renderWithProviders(<ImageField ref={handle} label="Avatar" />);
65
+ act(() => handle.current?.open());
66
+ expect(click).toHaveBeenCalledTimes(1);
67
+ });
68
+
69
+ it("ImageField draws a consumer trigger instead of its frame, and a pick from it reaches onChange", () => {
70
+ const click = vi.spyOn(HTMLInputElement.prototype, "click").mockImplementation(() => {});
71
+ const onChange = vi.fn();
72
+ const { container, getByRole } = renderWithProviders(
73
+ <ImageField
74
+ label="Receipt"
75
+ onChange={onChange}
76
+ trigger={(open) => (
77
+ <Button onPress={open} aria-label="Photo library">
78
+ Library
79
+ </Button>
80
+ )}
81
+ />,
82
+ );
83
+ expect(container.querySelector("[data-media-tile]")).toBeNull();
84
+ fireEvent.click(getByRole("button", { name: "Photo library" }));
85
+ expect(click).toHaveBeenCalledTimes(1);
86
+ pick(fileInput(container), new File(["x"], "receipt.png", { type: "image/png" }));
87
+ expect(onChange).toHaveBeenCalledTimes(1);
88
+ });
89
+ });
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ /**
4
+ * LC-290 FIELD-TRIGGER-SLOT: a picking field (FileUpload, ImageField) opens
5
+ * from the app's own control. `ref` takes this handle; `open()` runs the same
6
+ * press the field's own surface runs, through the same validation.
7
+ */
8
+ export interface FieldPickerHandle {
9
+ open: () => void;
10
+ }
11
+
12
+ /** Draws the app's own control in place of the field's surface; call `open` from its press. */
13
+ export type FieldPickerTrigger = (open: () => void) => ReactNode;
@@ -0,0 +1,26 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+
3
+ /** LC-197 HOLD-CUE: how far into a hold the press cue starts. */
4
+ export const holdCueStartMs = 150;
5
+
6
+ /** LC-197: how far a held control shrinks while its long press builds. */
7
+ export const holdCueScale = 0.97;
8
+
9
+ export function useHoldCue(cueStartMs: number = holdCueStartMs) {
10
+ const [holding, setHolding] = useState(false);
11
+ const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
12
+ const clear = () => {
13
+ if (timer.current) clearTimeout(timer.current);
14
+ timer.current = null;
15
+ };
16
+ const stop = useCallback(() => {
17
+ clear();
18
+ setHolding(false);
19
+ }, []);
20
+ const start = useCallback(() => {
21
+ clear();
22
+ timer.current = setTimeout(() => setHolding(true), cueStartMs);
23
+ }, [cueStartMs]);
24
+ useEffect(() => clear, []);
25
+ return { holding, start, stop };
26
+ }
@@ -48,6 +48,24 @@ export {
48
48
  useOverlaySizeClass,
49
49
  } from "./shared/overlaySizeClass";
50
50
  export type { OverlaySizeClass } from "./shared/overlaySizeClass";
51
+ export {
52
+ fillSnapPoint,
53
+ largeDetentRatio,
54
+ mediumDetent,
55
+ minSheetHeight,
56
+ openingDetentIndex,
57
+ resolveDetentPercents,
58
+ resolveSheetDetents,
59
+ resolveWebSnap,
60
+ sheetDetent,
61
+ sheetDismissThreshold,
62
+ } from "./shared/sheetDetents";
63
+ export type {
64
+ DetentSetOptions,
65
+ ResolveSheetDetentsOptions,
66
+ ResolveWebSnapOptions,
67
+ WebSnap,
68
+ } from "./shared/sheetDetents";
51
69
  export { pressSlopOutsetProps, pressSlopProps } from "./shared/pressSlopProps";
52
70
  export { Skeleton, SkeletonCircle, SkeletonGroup, SkeletonText } from "./Skeleton";
53
71
  export type {
@@ -101,6 +119,7 @@ export {
101
119
  } from "./shared/utils";
102
120
  export { TableCellContext, useIsInTableCell, useTableCellContext } from "./shared/tableCellContext";
103
121
  export { useControlGrouped } from "./shared/groupContext";
122
+ export { holdCueScale, holdCueStartMs, useHoldCue } from "./hooks/useHoldCue";
104
123
  export { formFieldGap, formReadableMaxWidth, formSectionGap } from "./formSpacing";
105
124
  export type {
106
125
  AnyFormApi,
package/src/index.ts CHANGED
@@ -264,6 +264,7 @@ export type { PhotonGeocoderOptions } from "./fields/Geolocation/photonGeocoder"
264
264
 
265
265
  export { ImageField } from "./fields/ImageField";
266
266
  export type { ImageFieldProps } from "./fields/ImageField";
267
+ export type { FieldPickerHandle, FieldPickerTrigger } from "./fields/pickerHandle";
267
268
 
268
269
  export {
269
270
  Icon,
@@ -386,6 +387,7 @@ export {
386
387
  focusFieldTarget,
387
388
  } from "./hooks/useFocusManagement";
388
389
  export type { FocusManagementOptions, FocusManagementReturn } from "./hooks/useFocusManagement";
390
+ export { holdCueScale, holdCueStartMs, useHoldCue } from "./hooks/useHoldCue";
389
391
 
390
392
  // ── Shared Utilities ──────────────────────────────────────────
391
393
  export {
@@ -461,6 +463,24 @@ export {
461
463
  useOverlaySizeClass,
462
464
  } from "./shared/overlaySizeClass";
463
465
  export type { OverlaySizeClass } from "./shared/overlaySizeClass";
466
+ export {
467
+ fillSnapPoint,
468
+ largeDetentRatio,
469
+ mediumDetent,
470
+ minSheetHeight,
471
+ openingDetentIndex,
472
+ resolveDetentPercents,
473
+ resolveSheetDetents,
474
+ resolveWebSnap,
475
+ sheetDetent,
476
+ sheetDismissThreshold,
477
+ } from "./shared/sheetDetents";
478
+ export type {
479
+ DetentSetOptions,
480
+ ResolveSheetDetentsOptions,
481
+ ResolveWebSnapOptions,
482
+ WebSnap,
483
+ } from "./shared/sheetDetents";
464
484
 
465
485
  // ── TanStack Form re-exports ─────────────────────────────────
466
486
  export {
@@ -10,6 +10,7 @@
10
10
  import * as themePackage from "@multiplatform.one/theme";
11
11
  import {
12
12
  controlTierPaint,
13
+ controlTrackFill,
13
14
  createDefaultThemeConfig,
14
15
  holdInkFloor,
15
16
  measureContrast,
@@ -21,7 +22,7 @@ import { readFileSync } from "node:fs";
21
22
  import { dirname, join } from "node:path";
22
23
  import { fileURLToPath } from "node:url";
23
24
  import { describe, expect, it } from "vitest";
24
- import { formControlColors, formSelectedColors, formSwitchColors } from "./shared/colorRamps";
25
+ import { formSelectedColors, formSwitchColors } from "./shared/colorRamps";
25
26
 
26
27
  /** The card's floor: the console's "a plain Button on an overlay's ground" asks the same. */
27
28
  const plateFloor = 1.1;
@@ -141,7 +142,8 @@ describe("FZ-7944: a control on an overlay has a plate distinct from the overlay
141
142
 
142
143
  it("Slider and Progress tracks read on the ground", () => {
143
144
  for (const component of ["Slider", "Progress"]) {
144
- const track = resolve(c.scope, formControlColors.background, component);
145
+ // On an overlay the track takes the elevated fill (FZ-8400).
146
+ const track = resolve(c.scope, controlTrackFill(true, true), component);
145
147
  expect(
146
148
  ratio(track, ground),
147
149
  `${component} track ${track} on ${ground}`,
@@ -170,7 +172,7 @@ describe("FZ-7944: a control on an overlay has a plate distinct from the overlay
170
172
  const knobs = themePackage.defaultPreset.knobs;
171
173
  const ground = (scheme: "light" | "dark") =>
172
174
  resolveKnobs(knobs, undefined, scheme).knobProps.elevatedSurface.backgroundColor;
173
- expect(ground("dark")).toBe("$color4");
175
+ expect(ground("dark")).toBe("$color5");
174
176
  expect(ground("light")).toBe("$background");
175
177
  expect(controlTierPaint("tinted", false, true)).toEqual(controlTierPaint("tinted", false));
176
178
  });
@@ -3,8 +3,8 @@ import { OverlayStackProvider } from "./overlayStack";
3
3
 
4
4
  export interface OverlayWindowProps {
5
5
  /** The z the window's own overlay binds; nested overlays stack above it. */
6
- zIndex: number;
7
- children?: ReactNode;
6
+ readonly zIndex: number;
7
+ readonly children?: ReactNode;
8
8
  }
9
9
 
10
10
  /**
@@ -30,9 +30,9 @@ export const formInputColors = {
30
30
  focus: "$color4",
31
31
  },
32
32
  border: {
33
- base: "$borderColor",
34
- hover: "$borderColorHover",
35
- focus: "$borderColorFocus",
33
+ base: "$borderColorField",
34
+ hover: "$borderColorFieldHover",
35
+ focus: "$borderColorField",
36
36
  },
37
37
  } as const;
38
38
 
@@ -41,6 +41,7 @@ export const formControlColors = {
41
41
  border: "$borderColor",
42
42
  /** DF-06 / WCAG 1.4.11: the build holds ≥3:1 on page, surface1 and control well. */
43
43
  boundary: "$boundaryColor",
44
+ edge: "$borderColorControl",
44
45
  thumb: {
45
46
  base: "$color10",
46
47
  hover: "$color9",
@@ -49,10 +50,11 @@ export const formControlColors = {
49
50
  } as const;
50
51
 
51
52
  // LC-05: the neutral selection tier, shared with componentColors.selection.
53
+ // Theme keys, so a row on a dark card steps off the card's fill (FZ-8400).
52
54
  export const formSelectionColors = {
53
- background: "$color4",
54
- hover: "$color5",
55
- press: "$color5",
55
+ background: "$selectFill",
56
+ hover: "$selectPress",
57
+ press: "$selectPress",
56
58
  ink: "$color12",
57
59
  ring: "$color8",
58
60
  } as const;
@@ -81,6 +83,7 @@ export const formSwitchColors = {
81
83
  off: "$switchTrackOff",
82
84
  offHover: "$switchTrackOffHover",
83
85
  offPress: "$switchTrackOffPress",
86
+ offBorder: "$switchTrackOffBorder",
84
87
  },
85
88
  thumb: "$switchThumb",
86
89
  } as const;
@@ -0,0 +1,7 @@
1
+ import { controlTrackFill, isDarkThemeName, useElevatedSurface } from "@multiplatform.one/theme";
2
+ import { useThemeName } from "tamagui";
3
+
4
+ /** The track fill for this control's ground: a step above an elevated dark overlay. */
5
+ export function useControlTrackFill(): string {
6
+ return controlTrackFill(isDarkThemeName(useThemeName()), useElevatedSurface());
7
+ }
@@ -16,7 +16,7 @@ export type { OverlayWindowProps } from "./OverlayWindow";
16
16
  * content, and those overlays open inside it. A PortalItem in here aimed at
17
17
  * any other app-level host finds no host, since this provider owns none.
18
18
  */
19
- export function OverlayWindow({ zIndex, children }: OverlayWindowProps) {
19
+ export function OverlayWindow({ zIndex, children }: Readonly<OverlayWindowProps>) {
20
20
  return (
21
21
  <PortalProvider shouldAddRootHost={false}>
22
22
  <OverlayStackProvider zIndex={zIndex}>{children}</OverlayStackProvider>
@@ -0,0 +1,117 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ mediumDetent,
4
+ minSheetHeight,
5
+ openingDetentIndex,
6
+ resolveDetentPercents,
7
+ resolveSheetDetents,
8
+ resolveWebSnap,
9
+ sheetDetent,
10
+ sheetDismissThreshold,
11
+ } from "./sheetDetents";
12
+
13
+ describe("FZ-455 a sheet takes a set of detents, not one snap point", () => {
14
+ it("resolves a caller's declared set, largest first, whatever order it was written in", () => {
15
+ expect(resolveDetentPercents({ detents: [40, 100, 70] })).toEqual([100, 70, 40]);
16
+ });
17
+
18
+ it("clamps a declared detent to full height and drops a non-positive one", () => {
19
+ expect(resolveDetentPercents({ detents: [140, 55, 0, -10, Number.NaN] })).toEqual([100, 55]);
20
+ });
21
+
22
+ it("lets a declared set own the sheet, so snapPoint does not add to it", () => {
23
+ expect(resolveDetentPercents({ detents: [100, 45], snapPoint: 85 })).toEqual([100, 45]);
24
+ });
25
+
26
+ it("keeps full height in the set a bare snapPoint implies, so a lowered sheet drags back up", () => {
27
+ expect(resolveDetentPercents({ snapPoint: 85 })).toEqual([100, 85]);
28
+ });
29
+
30
+ it("puts the half-open rest in a scrollable sheet's set on both twins", () => {
31
+ expect(resolveDetentPercents({ scrollable: true })).toEqual([
32
+ sheetDetent.large,
33
+ sheetDetent.medium,
34
+ ]);
35
+ expect(resolveDetentPercents({ scrollable: true, snapPoint: 85 })).toEqual([100, 85, 55]);
36
+ });
37
+
38
+ it("names the HIG detents and keeps the native fraction in step with the percent", () => {
39
+ expect(sheetDetent).toEqual({ medium: 55, large: 100 });
40
+ expect(mediumDetent).toBe(0.55);
41
+ });
42
+ });
43
+
44
+ describe("FZ-455 the opening detent", () => {
45
+ it("opens at the detent snapPoint names", () => {
46
+ expect(openingDetentIndex([100, 85], 85)).toBe(1);
47
+ expect(openingDetentIndex([100, 70, 40], 40)).toBe(2);
48
+ });
49
+
50
+ it("opens at the largest detent with no snapPoint, or one outside the set", () => {
51
+ expect(openingDetentIndex([100, 55])).toBe(0);
52
+ expect(openingDetentIndex([100, 55], 33)).toBe(0);
53
+ });
54
+ });
55
+
56
+ describe("FZ-455 the web sheet drags between detents", () => {
57
+ it("hands the whole set to the Sheet, not the single percent it used to get", () => {
58
+ const snap = resolveWebSnap({ snapPoint: 85 });
59
+ expect(snap).toEqual({ snapPointsMode: "percent", snapPoints: [100, 85], defaultPosition: 1 });
60
+ });
61
+
62
+ it("opens at the same percent it opened at before, so no sheet moves on load", () => {
63
+ for (const snapPoint of [70, 85, 92, 94, 100]) {
64
+ const snap = resolveWebSnap({ snapPoint });
65
+ if (snap.snapPointsMode !== "percent") throw new Error("expected percent mode");
66
+ expect(snap.snapPoints[snap.defaultPosition]).toBe(snapPoint);
67
+ }
68
+ });
69
+
70
+ it("carries a declared set through, opening at the detent snapPoint names", () => {
71
+ expect(resolveWebSnap({ detents: [100, 60], snapPoint: 60 })).toEqual({
72
+ snapPointsMode: "percent",
73
+ snapPoints: [100, 60],
74
+ defaultPosition: 1,
75
+ });
76
+ });
77
+
78
+ it("keeps FZ-7977's content height when nothing declares a detent", () => {
79
+ expect(resolveWebSnap({})).toEqual({ snapPointsMode: "fit" });
80
+ expect(resolveWebSnap({ scrollable: true })).toEqual({ snapPointsMode: "fit" });
81
+ });
82
+
83
+ it("keeps a fill sheet's percent rest and makes it draggable", () => {
84
+ const snap = resolveWebSnap({ fill: true });
85
+ expect(snap).toEqual({ snapPointsMode: "percent", snapPoints: [100, 60], defaultPosition: 1 });
86
+ });
87
+
88
+ it("gives every percent-mode sheet something to drag between", () => {
89
+ for (const options of [{ snapPoint: 85 }, { fill: true }, { detents: [80, 40] }]) {
90
+ const snap = resolveWebSnap(options);
91
+ if (snap.snapPointsMode !== "percent") throw new Error("expected percent mode");
92
+ expect(snap.snapPoints.length).toBeGreaterThan(1);
93
+ }
94
+ });
95
+ });
96
+
97
+ describe("FZ-455 native detent heights", () => {
98
+ it("resolves a declared set into heights, largest first", () => {
99
+ expect(resolveSheetDetents({ travel: 800, detents: [100, 50] })).toEqual([800, 400]);
100
+ });
101
+
102
+ it("matches the heights the shipped native sheet already rests at", () => {
103
+ expect(resolveSheetDetents({ travel: 700, snapPoint: 85 })).toEqual([700, 595]);
104
+ expect(resolveSheetDetents({ travel: 700 })).toEqual([700]);
105
+ expect(resolveSheetDetents({ travel: 600, scrollable: true })).toEqual([600, 330]);
106
+ });
107
+
108
+ it("drops a detent shorter than the floor, and keeps a short sheet's own height", () => {
109
+ expect(resolveSheetDetents({ travel: 800, detents: [100, 10] })).toEqual([800]);
110
+ expect(resolveSheetDetents({ travel: 120, detents: [100] })).toEqual([120]);
111
+ expect(minSheetHeight).toBe(180);
112
+ });
113
+
114
+ it("keeps the dismiss threshold with the geometry it belongs to", () => {
115
+ expect(sheetDismissThreshold).toBe(56);
116
+ });
117
+ });