@multiplatform.one/forms 7.80.0 → 7.81.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 (587) hide show
  1. package/dist/cjs/AdaptivePopup/index.cjs +1 -1
  2. package/dist/cjs/AdaptivePopup/index.native.js +3 -3
  3. package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
  4. package/dist/cjs/Button/IconButtonGroup.native.js.map +1 -1
  5. package/dist/cjs/Button/circleGlyph.native.js.map +1 -1
  6. package/dist/cjs/Button/iconButtonGroupContext.native.js.map +1 -1
  7. package/dist/cjs/Button/index.cjs +12 -5
  8. package/dist/cjs/Button/index.native.js +16 -8
  9. package/dist/cjs/Button/index.native.js.map +1 -1
  10. package/dist/cjs/Button/webGlass.native.js.map +1 -1
  11. package/dist/cjs/Chip/index.native.js.map +1 -1
  12. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js +1 -1
  13. package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  14. package/dist/cjs/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  15. package/dist/cjs/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  16. package/dist/cjs/ContextualSaveBar/index.native.js +3 -3
  17. package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
  18. package/dist/cjs/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  19. package/dist/cjs/ControlGroup/index.native.js +1 -1
  20. package/dist/cjs/ControlGroup/index.native.js.map +1 -1
  21. package/dist/cjs/DescriptionList/index.native.js +2 -2
  22. package/dist/cjs/DescriptionList/index.native.js.map +1 -1
  23. package/dist/cjs/ErrorSummary.native.js.map +1 -1
  24. package/dist/cjs/FieldDisplay/editMode.native.js.map +1 -1
  25. package/dist/cjs/FieldDisplay/formatters.native.js.map +1 -1
  26. package/dist/cjs/FieldDisplay/index.native.js +1 -1
  27. package/dist/cjs/FieldDisplay/index.native.js.map +1 -1
  28. package/dist/cjs/FieldGroup.native.js.map +1 -1
  29. package/dist/cjs/FloatingPanel/PanelHeader.cjs +3 -8
  30. package/dist/cjs/FloatingPanel/PanelHeader.native.js +3 -8
  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.cjs +0 -8
  36. package/dist/cjs/FloatingPanel/coverRect.native.js +0 -8
  37. package/dist/cjs/FloatingPanel/coverRect.native.js.map +1 -1
  38. package/dist/cjs/FloatingPanel/echoContext.cjs +5 -27
  39. package/dist/cjs/FloatingPanel/echoContext.native.js +5 -28
  40. package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -1
  41. package/dist/cjs/FloatingPanel/index.cjs +49 -131
  42. package/dist/cjs/FloatingPanel/index.native.js +26 -91
  43. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  44. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -1
  45. package/dist/cjs/FloatingPanel/paintedBox.native.js.map +1 -1
  46. package/dist/cjs/FloatingPanel/panelWidth.native.js.map +1 -1
  47. package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
  48. package/dist/cjs/FloatingPanel/regularPlacement.native.js.map +1 -1
  49. package/dist/cjs/FloatingPanel/trailingAction.native.js +1 -1
  50. package/dist/cjs/FloatingPanel/trailingAction.native.js.map +1 -1
  51. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  52. package/dist/cjs/Form/index.native.js +1 -1
  53. package/dist/cjs/Form/index.native.js.map +1 -1
  54. package/dist/cjs/Form/submissionController.native.js.map +1 -1
  55. package/dist/cjs/Form/validateOn.native.js.map +1 -1
  56. package/dist/cjs/FormGrid.native.js.map +1 -1
  57. package/dist/cjs/FormSection.native.js.map +1 -1
  58. package/dist/cjs/InputParts/PasswordReveal.native.js.map +1 -1
  59. package/dist/cjs/InputParts/index.native.js.map +1 -1
  60. package/dist/cjs/InputParts/keyboardAppearance.native.js.map +1 -1
  61. package/dist/cjs/Label/index.native.js.map +1 -1
  62. package/dist/cjs/MediaPicker/base64.native.js.map +1 -1
  63. package/dist/cjs/MediaPicker/payload.native.js.map +1 -1
  64. package/dist/cjs/MediaPicker/types.native.js.map +1 -1
  65. package/dist/cjs/MediaPicker/useMediaPicker.native.js.map +1 -1
  66. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  67. package/dist/cjs/Spinner/SpinnerGlyph.native.js.map +1 -1
  68. package/dist/cjs/Spinner/spinnerSize.native.js.map +1 -1
  69. package/dist/cjs/Table/index.native.js.map +1 -1
  70. package/dist/cjs/Wheel/haptic.native.js.map +1 -1
  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.cjs +3 -10
  101. package/dist/cjs/fields/Combobox/index.native.js +8 -15
  102. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  103. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  104. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  105. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  106. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +3 -3
  107. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  108. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +2 -2
  109. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +2 -2
  110. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  111. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  112. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  113. package/dist/cjs/fields/DatePicker/catalog.native.js +2 -2
  114. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
  115. package/dist/cjs/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  116. package/dist/cjs/fields/DatePicker/index.native.js +2 -2
  117. package/dist/cjs/fields/DatePicker/parts.native.js +2 -2
  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.native.js +2 -2
  127. package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
  128. package/dist/cjs/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  129. package/dist/cjs/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  130. package/dist/cjs/fields/Geolocation/geoValue.native.js.map +1 -1
  131. package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -1
  132. package/dist/cjs/fields/Geolocation/geocoderContext.native.js.map +1 -1
  133. package/dist/cjs/fields/Geolocation/index.native.js +5 -5
  134. package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
  135. package/dist/cjs/fields/Geolocation/mapMath.native.js.map +1 -1
  136. package/dist/cjs/fields/Geolocation/mapTypes.native.js.map +1 -1
  137. package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
  138. package/dist/cjs/fields/Geolocation/photonGeocoder.native.js.map +1 -1
  139. package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
  140. package/dist/cjs/fields/Icon/index.native.js +3 -3
  141. package/dist/cjs/fields/Icon/index.native.js.map +1 -1
  142. package/dist/cjs/fields/ImageField/index.native.js +2 -2
  143. package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
  144. package/dist/cjs/fields/Input/index.native.js +3 -3
  145. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  146. package/dist/cjs/fields/MentionInput/index.native.js +3 -3
  147. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  148. package/dist/cjs/fields/OTPInput/index.native.js +3 -3
  149. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  150. package/dist/cjs/fields/OTPInput/otpCellCss.native.js.map +1 -1
  151. package/dist/cjs/fields/PhoneInput/dialCodes.native.js.map +1 -1
  152. package/dist/cjs/fields/PhoneInput/index.native.js +3 -3
  153. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  154. package/dist/cjs/fields/PhoneInput/phone.native.js.map +1 -1
  155. package/dist/cjs/fields/PhoneInput/regionNames.native.js.map +1 -1
  156. package/dist/cjs/fields/Progress/index.native.js +1 -1
  157. package/dist/cjs/fields/Progress/index.native.js.map +1 -1
  158. package/dist/cjs/fields/RadioGroup/index.native.js +1 -1
  159. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  160. package/dist/cjs/fields/Rating/index.native.js +1 -1
  161. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  162. package/dist/cjs/fields/Rating/ratingMath.native.js.map +1 -1
  163. package/dist/cjs/fields/Rating/types.native.js.map +1 -1
  164. package/dist/cjs/fields/SearchInput/index.native.js +2 -2
  165. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  166. package/dist/cjs/fields/Select/InlineChoices.cjs +4 -8
  167. package/dist/cjs/fields/Select/InlineChoices.native.js +4 -8
  168. package/dist/cjs/fields/Select/InlineChoices.native.js.map +1 -1
  169. package/dist/cjs/fields/Select/SheetPickerRow.native.js.map +1 -1
  170. package/dist/cjs/fields/Select/index.cjs +46 -199
  171. package/dist/cjs/fields/Select/index.native.js +56 -211
  172. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  173. package/dist/cjs/fields/Select/shouldInlineChoices.native.js.map +1 -1
  174. package/dist/cjs/fields/Signature/index.native.js +2 -2
  175. package/dist/cjs/fields/Signature/index.native.js.map +1 -1
  176. package/dist/cjs/fields/Slider/index.native.js +1 -1
  177. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  178. package/dist/cjs/fields/Slider/jumpMotion.native.js.map +1 -1
  179. package/dist/cjs/fields/Stepper/index.native.js +2 -2
  180. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  181. package/dist/cjs/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  182. package/dist/cjs/fields/Switch/footprint.native.js.map +1 -1
  183. package/dist/cjs/fields/Switch/index.native.js +2 -2
  184. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  185. package/dist/cjs/fields/TextArea/index.native.js +2 -2
  186. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  187. package/dist/cjs/fields/TimePicker/catalog.native.js +3 -3
  188. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  189. package/dist/cjs/fields/TimePicker/index.native.js +2 -2
  190. package/dist/cjs/fields/TimePicker/parts.native.js +1 -1
  191. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  192. package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  193. package/dist/cjs/fields/TimeRangeScrubber/index.native.js +2 -2
  194. package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
  195. package/dist/cjs/fields/ToggleGroup/index.native.js +1 -1
  196. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  197. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +2 -2
  198. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
  199. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  200. package/dist/cjs/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
  201. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  202. package/dist/cjs/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
  203. package/dist/cjs/fields/nativeSelect.native.js.map +1 -1
  204. package/dist/cjs/fields/selectedOrder.native.js.map +1 -1
  205. package/dist/cjs/formSpacing.native.js.map +1 -1
  206. package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
  207. package/dist/cjs/index.cjs +4 -0
  208. package/dist/cjs/index.native.js +49 -45
  209. package/dist/cjs/index.native.js.map +1 -1
  210. package/dist/cjs/keyboard/KeyboardDoneBar.native.js +1 -1
  211. package/dist/cjs/keyboard/chain.native.js.map +1 -1
  212. package/dist/cjs/keyboard/index.native.js.map +1 -1
  213. package/dist/cjs/keyboard/types.native.js.map +1 -1
  214. package/dist/cjs/requiredMarking.native.js.map +1 -1
  215. package/dist/cjs/shared/CheckGlyph.cjs +40 -0
  216. package/dist/cjs/shared/CheckGlyph.native.js +44 -0
  217. package/dist/cjs/shared/CheckGlyph.native.js.map +1 -0
  218. package/dist/cjs/shared/TimeColumn.native.js +1 -1
  219. package/dist/cjs/shared/TimeColumn.native.js.map +1 -1
  220. package/dist/cjs/shared/capabilityPreflight.native.js.map +1 -1
  221. package/dist/cjs/shared/choiceRowPress.native.js.map +1 -1
  222. package/dist/cjs/shared/colorRamps.native.js.map +1 -1
  223. package/dist/cjs/shared/devWarn.native.js.map +1 -1
  224. package/dist/cjs/shared/fieldRowContext.native.js.map +1 -1
  225. package/dist/cjs/shared/floatingList.cjs +82 -3
  226. package/dist/cjs/shared/floatingList.native.js +96 -6
  227. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  228. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  229. package/dist/cjs/shared/groupContext.native.js.map +1 -1
  230. package/dist/cjs/shared/i18n.native.js.map +1 -1
  231. package/dist/cjs/shared/instantMotion.native.js.map +1 -1
  232. package/dist/cjs/shared/nativeA11y.native.js.map +1 -1
  233. package/dist/cjs/shared/nativeAutoFocus.native.js.map +1 -1
  234. package/dist/cjs/shared/overlaySizeClass.native.js.map +1 -1
  235. package/dist/cjs/shared/overlayStack.native.js.map +1 -1
  236. package/dist/cjs/shared/panelPortal.native.js.map +1 -1
  237. package/dist/cjs/shared/pickerTriggerContract.native.js.map +1 -1
  238. package/dist/cjs/shared/pressSlopProps.native.js.map +1 -1
  239. package/dist/cjs/shared/restoreRetries.native.js.map +1 -1
  240. package/dist/cjs/shared/sheetNavigation.native.js.map +1 -1
  241. package/dist/cjs/shared/systemControlModules.gnome.native.js.map +1 -1
  242. package/dist/cjs/shared/systemControls.native.js.map +1 -1
  243. package/dist/cjs/shared/t.native.js.map +1 -1
  244. package/dist/cjs/shared/tableCellContext.native.js.map +1 -1
  245. package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
  246. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  247. package/dist/cjs/shared/useSheetEscapeDismiss.native.js.map +1 -1
  248. package/dist/cjs/shared/useWheelIncrement.native.js.map +1 -1
  249. package/dist/cjs/shared/utils.native.js +1 -1
  250. package/dist/cjs/shared/utils.native.js.map +1 -1
  251. package/dist/cjs/shared/zIndex.native.js.map +1 -1
  252. package/dist/cjs/standardActions.native.js.map +1 -1
  253. package/dist/cjs/themedPrimitives.native.js.map +1 -1
  254. package/dist/cjs/types.native.js.map +1 -1
  255. package/dist/cjs/utils/LinkCell.native.js.map +1 -1
  256. package/dist/esm/AdaptivePopup/index.mjs +2 -2
  257. package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
  258. package/dist/esm/AdaptivePopup/index.native.js +2 -2
  259. package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
  260. package/dist/esm/Button/IconButtonGroup.native.js.map +1 -1
  261. package/dist/esm/Button/circleGlyph.native.js.map +1 -1
  262. package/dist/esm/Button/iconButtonGroupContext.native.js.map +1 -1
  263. package/dist/esm/Button/index.mjs +12 -5
  264. package/dist/esm/Button/index.mjs.map +1 -1
  265. package/dist/esm/Button/index.native.js +14 -6
  266. package/dist/esm/Button/index.native.js.map +1 -1
  267. package/dist/esm/Button/webGlass.native.js.map +1 -1
  268. package/dist/esm/Chip/index.native.js.map +1 -1
  269. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  270. package/dist/esm/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  271. package/dist/esm/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  272. package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
  273. package/dist/esm/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  274. package/dist/esm/ControlGroup/index.native.js.map +1 -1
  275. package/dist/esm/DescriptionList/index.native.js.map +1 -1
  276. package/dist/esm/ErrorSummary.native.js.map +1 -1
  277. package/dist/esm/FieldDisplay/editMode.native.js.map +1 -1
  278. package/dist/esm/FieldDisplay/formatters.native.js.map +1 -1
  279. package/dist/esm/FieldDisplay/index.native.js.map +1 -1
  280. package/dist/esm/FieldGroup.native.js.map +1 -1
  281. package/dist/esm/FloatingPanel/PanelHeader.mjs +3 -8
  282. package/dist/esm/FloatingPanel/PanelHeader.mjs.map +1 -1
  283. package/dist/esm/FloatingPanel/PanelHeader.native.js +3 -8
  284. package/dist/esm/FloatingPanel/PanelHeader.native.js.map +1 -1
  285. package/dist/esm/FloatingPanel/RegularPanel.native.js.map +1 -1
  286. package/dist/esm/FloatingPanel/compactFace.native.js.map +1 -1
  287. package/dist/esm/FloatingPanel/containingBlock.native.js.map +1 -1
  288. package/dist/esm/FloatingPanel/coverRect.mjs +1 -8
  289. package/dist/esm/FloatingPanel/coverRect.mjs.map +1 -1
  290. package/dist/esm/FloatingPanel/coverRect.native.js +1 -8
  291. package/dist/esm/FloatingPanel/coverRect.native.js.map +1 -1
  292. package/dist/esm/FloatingPanel/echoContext.mjs +4 -24
  293. package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -1
  294. package/dist/esm/FloatingPanel/echoContext.native.js +4 -25
  295. package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -1
  296. package/dist/esm/FloatingPanel/index.mjs +53 -135
  297. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  298. package/dist/esm/FloatingPanel/index.native.js +30 -95
  299. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  300. package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -1
  301. package/dist/esm/FloatingPanel/paintedBox.native.js.map +1 -1
  302. package/dist/esm/FloatingPanel/panelWidth.native.js.map +1 -1
  303. package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
  304. package/dist/esm/FloatingPanel/regularPlacement.native.js.map +1 -1
  305. package/dist/esm/FloatingPanel/trailingAction.native.js.map +1 -1
  306. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  307. package/dist/esm/Form/index.native.js.map +1 -1
  308. package/dist/esm/Form/submissionController.native.js.map +1 -1
  309. package/dist/esm/Form/validateOn.native.js.map +1 -1
  310. package/dist/esm/FormGrid.native.js.map +1 -1
  311. package/dist/esm/FormSection.native.js.map +1 -1
  312. package/dist/esm/InputParts/PasswordReveal.native.js.map +1 -1
  313. package/dist/esm/InputParts/index.native.js.map +1 -1
  314. package/dist/esm/InputParts/keyboardAppearance.native.js.map +1 -1
  315. package/dist/esm/Label/index.native.js.map +1 -1
  316. package/dist/esm/MediaPicker/base64.native.js.map +1 -1
  317. package/dist/esm/MediaPicker/payload.native.js.map +1 -1
  318. package/dist/esm/MediaPicker/types.native.js.map +1 -1
  319. package/dist/esm/MediaPicker/useMediaPicker.native.js.map +1 -1
  320. package/dist/esm/Skeleton/index.native.js.map +1 -1
  321. package/dist/esm/Spinner/SpinnerGlyph.native.js.map +1 -1
  322. package/dist/esm/Spinner/spinnerSize.native.js.map +1 -1
  323. package/dist/esm/Table/index.native.js.map +1 -1
  324. package/dist/esm/Wheel/haptic.native.js.map +1 -1
  325. package/dist/esm/Wheel/index.native.js.map +1 -1
  326. package/dist/esm/Wheel/wheelShared.native.js.map +1 -1
  327. package/dist/esm/actionLabel.native.js.map +1 -1
  328. package/dist/esm/fieldDefaults.native.js.map +1 -1
  329. package/dist/esm/fieldLayout.native.js.map +1 -1
  330. package/dist/esm/fields/Barcode/BarcodePreview.native.js.map +1 -1
  331. package/dist/esm/fields/Barcode/code128.native.js.map +1 -1
  332. package/dist/esm/fields/Barcode/index.native.js.map +1 -1
  333. package/dist/esm/fields/Barcode/qr.native.js.map +1 -1
  334. package/dist/esm/fields/Barcode/scannerTypes.native.js.map +1 -1
  335. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  336. package/dist/esm/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  337. package/dist/esm/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  338. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  339. package/dist/esm/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  340. package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  341. package/dist/esm/fields/Checkbox/index.native.js.map +1 -1
  342. package/dist/esm/fields/ColorPicker/SystemColorField.native.js.map +1 -1
  343. package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
  344. package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
  345. package/dist/esm/fields/ColorPicker/systemColorWell.gnome.native.js.map +1 -1
  346. package/dist/esm/fields/Combobox/authorOptions.native.js.map +1 -1
  347. package/dist/esm/fields/Combobox/index.mjs +4 -11
  348. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  349. package/dist/esm/fields/Combobox/index.native.js +4 -11
  350. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  351. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  352. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  353. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  354. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  355. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  356. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
  357. package/dist/esm/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  358. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  359. package/dist/esm/fields/DatePicker/utils.native.js.map +1 -1
  360. package/dist/esm/fields/Duration/durationMath.native.js.map +1 -1
  361. package/dist/esm/fields/Duration/durationWheelTypes.native.js.map +1 -1
  362. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  363. package/dist/esm/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  364. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  365. package/dist/esm/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  366. package/dist/esm/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  367. package/dist/esm/fields/Geolocation/geoValue.native.js.map +1 -1
  368. package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -1
  369. package/dist/esm/fields/Geolocation/geocoderContext.native.js.map +1 -1
  370. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  371. package/dist/esm/fields/Geolocation/mapMath.native.js.map +1 -1
  372. package/dist/esm/fields/Geolocation/mapTypes.native.js.map +1 -1
  373. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
  374. package/dist/esm/fields/Geolocation/photonGeocoder.native.js.map +1 -1
  375. package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
  376. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  377. package/dist/esm/fields/ImageField/index.native.js.map +1 -1
  378. package/dist/esm/fields/Input/index.native.js.map +1 -1
  379. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  380. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  381. package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
  382. package/dist/esm/fields/PhoneInput/dialCodes.native.js.map +1 -1
  383. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  384. package/dist/esm/fields/PhoneInput/phone.native.js.map +1 -1
  385. package/dist/esm/fields/PhoneInput/regionNames.native.js.map +1 -1
  386. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  387. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  388. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  389. package/dist/esm/fields/Rating/ratingMath.native.js.map +1 -1
  390. package/dist/esm/fields/Rating/types.native.js.map +1 -1
  391. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  392. package/dist/esm/fields/Select/InlineChoices.mjs +2 -6
  393. package/dist/esm/fields/Select/InlineChoices.mjs.map +1 -1
  394. package/dist/esm/fields/Select/InlineChoices.native.js +2 -6
  395. package/dist/esm/fields/Select/InlineChoices.native.js.map +1 -1
  396. package/dist/esm/fields/Select/SheetPickerRow.native.js.map +1 -1
  397. package/dist/esm/fields/Select/index.mjs +49 -202
  398. package/dist/esm/fields/Select/index.mjs.map +1 -1
  399. package/dist/esm/fields/Select/index.native.js +55 -210
  400. package/dist/esm/fields/Select/index.native.js.map +1 -1
  401. package/dist/esm/fields/Select/shouldInlineChoices.native.js.map +1 -1
  402. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  403. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  404. package/dist/esm/fields/Slider/jumpMotion.native.js.map +1 -1
  405. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  406. package/dist/esm/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  407. package/dist/esm/fields/Switch/footprint.native.js.map +1 -1
  408. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  409. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  410. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  411. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  412. package/dist/esm/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  413. package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
  414. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  415. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
  416. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  417. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
  418. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  419. package/dist/esm/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
  420. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  421. package/dist/esm/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
  422. package/dist/esm/fields/nativeSelect.native.js.map +1 -1
  423. package/dist/esm/fields/selectedOrder.native.js.map +1 -1
  424. package/dist/esm/formSpacing.native.js.map +1 -1
  425. package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
  426. package/dist/esm/index.mjs +3 -1
  427. package/dist/esm/index.mjs.map +1 -1
  428. package/dist/esm/index.native.js +3 -1
  429. package/dist/esm/index.native.js.map +1 -1
  430. package/dist/esm/keyboard/chain.native.js.map +1 -1
  431. package/dist/esm/keyboard/index.native.js.map +1 -1
  432. package/dist/esm/keyboard/types.native.js.map +1 -1
  433. package/dist/esm/requiredMarking.native.js.map +1 -1
  434. package/dist/esm/shared/CheckGlyph.mjs +15 -0
  435. package/dist/esm/shared/CheckGlyph.mjs.map +1 -0
  436. package/dist/esm/shared/CheckGlyph.native.js +16 -0
  437. package/dist/esm/shared/CheckGlyph.native.js.map +1 -0
  438. package/dist/esm/shared/TimeColumn.native.js.map +1 -1
  439. package/dist/esm/shared/capabilityPreflight.native.js.map +1 -1
  440. package/dist/esm/shared/choiceRowPress.native.js.map +1 -1
  441. package/dist/esm/shared/colorRamps.native.js.map +1 -1
  442. package/dist/esm/shared/devWarn.native.js.map +1 -1
  443. package/dist/esm/shared/fieldRowContext.native.js.map +1 -1
  444. package/dist/esm/shared/floatingList.mjs +80 -4
  445. package/dist/esm/shared/floatingList.mjs.map +1 -1
  446. package/dist/esm/shared/floatingList.native.js +93 -6
  447. package/dist/esm/shared/floatingList.native.js.map +1 -1
  448. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  449. package/dist/esm/shared/groupContext.native.js.map +1 -1
  450. package/dist/esm/shared/i18n.native.js.map +1 -1
  451. package/dist/esm/shared/instantMotion.native.js.map +1 -1
  452. package/dist/esm/shared/nativeA11y.native.js.map +1 -1
  453. package/dist/esm/shared/nativeAutoFocus.native.js.map +1 -1
  454. package/dist/esm/shared/overlaySizeClass.native.js.map +1 -1
  455. package/dist/esm/shared/overlayStack.native.js.map +1 -1
  456. package/dist/esm/shared/panelPortal.native.js.map +1 -1
  457. package/dist/esm/shared/pickerTriggerContract.native.js.map +1 -1
  458. package/dist/esm/shared/pressSlopProps.native.js.map +1 -1
  459. package/dist/esm/shared/restoreRetries.native.js.map +1 -1
  460. package/dist/esm/shared/sheetNavigation.native.js.map +1 -1
  461. package/dist/esm/shared/systemControlModules.gnome.native.js.map +1 -1
  462. package/dist/esm/shared/systemControls.native.js.map +1 -1
  463. package/dist/esm/shared/t.native.js.map +1 -1
  464. package/dist/esm/shared/tableCellContext.native.js.map +1 -1
  465. package/dist/esm/shared/useDragScroll.native.js.map +1 -1
  466. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  467. package/dist/esm/shared/useSheetEscapeDismiss.native.js.map +1 -1
  468. package/dist/esm/shared/useWheelIncrement.native.js.map +1 -1
  469. package/dist/esm/shared/utils.native.js.map +1 -1
  470. package/dist/esm/shared/zIndex.native.js.map +1 -1
  471. package/dist/esm/standardActions.native.js.map +1 -1
  472. package/dist/esm/themedPrimitives.native.js.map +1 -1
  473. package/dist/esm/types.native.js.map +1 -1
  474. package/dist/esm/utils/LinkCell.native.js.map +1 -1
  475. package/dist/jsx/AdaptivePopup/index.mjs +2 -2
  476. package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
  477. package/dist/jsx/AdaptivePopup/index.native.js +1 -1
  478. package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
  479. package/dist/jsx/Button/index.mjs +12 -5
  480. package/dist/jsx/Button/index.mjs.map +1 -1
  481. package/dist/jsx/Button/index.native.js +14 -6
  482. package/dist/jsx/Button/index.native.js.map +1 -1
  483. package/dist/jsx/FloatingPanel/PanelHeader.mjs +3 -8
  484. package/dist/jsx/FloatingPanel/PanelHeader.mjs.map +1 -1
  485. package/dist/jsx/FloatingPanel/PanelHeader.native.js +3 -8
  486. package/dist/jsx/FloatingPanel/PanelHeader.native.js.map +1 -1
  487. package/dist/jsx/FloatingPanel/coverRect.mjs +1 -8
  488. package/dist/jsx/FloatingPanel/coverRect.mjs.map +1 -1
  489. package/dist/jsx/FloatingPanel/coverRect.native.js +0 -8
  490. package/dist/jsx/FloatingPanel/coverRect.native.js.map +1 -1
  491. package/dist/jsx/FloatingPanel/echoContext.mjs +4 -24
  492. package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -1
  493. package/dist/jsx/FloatingPanel/echoContext.native.js +5 -28
  494. package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -1
  495. package/dist/jsx/FloatingPanel/index.mjs +53 -135
  496. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  497. package/dist/jsx/FloatingPanel/index.native.js +26 -91
  498. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  499. package/dist/jsx/fields/Combobox/index.mjs +4 -11
  500. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  501. package/dist/jsx/fields/Combobox/index.native.js +3 -10
  502. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  503. package/dist/jsx/fields/Select/InlineChoices.mjs +2 -6
  504. package/dist/jsx/fields/Select/InlineChoices.mjs.map +1 -1
  505. package/dist/jsx/fields/Select/InlineChoices.native.js +4 -8
  506. package/dist/jsx/fields/Select/InlineChoices.native.js.map +1 -1
  507. package/dist/jsx/fields/Select/index.mjs +49 -202
  508. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  509. package/dist/jsx/fields/Select/index.native.js +52 -207
  510. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  511. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
  512. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  513. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
  514. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  515. package/dist/jsx/index.js +3 -1
  516. package/dist/jsx/index.js.map +1 -1
  517. package/dist/jsx/index.mjs +3 -1
  518. package/dist/jsx/index.mjs.map +1 -1
  519. package/dist/jsx/index.native.js +4 -0
  520. package/dist/jsx/index.native.js.map +1 -1
  521. package/dist/jsx/shared/CheckGlyph.mjs +15 -0
  522. package/dist/jsx/shared/CheckGlyph.mjs.map +1 -0
  523. package/dist/jsx/shared/CheckGlyph.native.js +44 -0
  524. package/dist/jsx/shared/CheckGlyph.native.js.map +1 -0
  525. package/dist/jsx/shared/floatingList.mjs +80 -4
  526. package/dist/jsx/shared/floatingList.mjs.map +1 -1
  527. package/dist/jsx/shared/floatingList.native.js +95 -5
  528. package/dist/jsx/shared/floatingList.native.js.map +1 -1
  529. package/package.json +8 -8
  530. package/src/AdaptivePopup/index.tsx +2 -2
  531. package/src/Button/Button.iconButton.spec.tsx +39 -0
  532. package/src/Button/index.tsx +20 -8
  533. package/src/FloatingPanel/FloatingPanel.iconCover.spec.tsx +279 -0
  534. package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +78 -69
  535. package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +12 -0
  536. package/src/FloatingPanel/PanelHeader.tsx +4 -12
  537. package/src/FloatingPanel/coverRect.ts +2 -15
  538. package/src/FloatingPanel/echoContext.ts +6 -40
  539. package/src/FloatingPanel/index.native.tsx +36 -145
  540. package/src/FloatingPanel/index.tsx +61 -187
  541. package/src/FloatingPanel/pointAnchor.spec.ts +1 -1
  542. package/src/FloatingPanel/pointAnchor.ts +4 -4
  543. package/src/fields/Combobox/index.tsx +4 -9
  544. package/src/fields/Select/InlineChoices.tsx +2 -2
  545. package/src/fields/Select/Select.containingBlock.spec.tsx +131 -130
  546. package/src/fields/Select/Select.stories.tsx +10 -0
  547. package/src/fields/Select/index.tsx +66 -253
  548. package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +3 -3
  549. package/src/index.ts +2 -1
  550. package/src/shared/CheckGlyph.tsx +12 -0
  551. package/src/shared/floatingList.spec.tsx +154 -1
  552. package/src/shared/floatingList.tsx +125 -8
  553. package/types/Button/index.d.ts.map +1 -1
  554. package/types/FloatingPanel/PanelHeader.d.ts +1 -6
  555. package/types/FloatingPanel/PanelHeader.d.ts.map +1 -1
  556. package/types/FloatingPanel/coverRect.d.ts +2 -11
  557. package/types/FloatingPanel/coverRect.d.ts.map +1 -1
  558. package/types/FloatingPanel/echoContext.d.ts +5 -22
  559. package/types/FloatingPanel/echoContext.d.ts.map +1 -1
  560. package/types/FloatingPanel/index.d.ts +6 -8
  561. package/types/FloatingPanel/index.d.ts.map +1 -1
  562. package/types/FloatingPanel/index.native.d.ts +1 -1
  563. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  564. package/types/FloatingPanel/pointAnchor.d.ts +4 -4
  565. package/types/fields/Combobox/index.d.ts.map +1 -1
  566. package/types/fields/Select/index.d.ts.map +1 -1
  567. package/types/index.d.ts +2 -1
  568. package/types/index.d.ts.map +1 -1
  569. package/types/shared/CheckGlyph.d.ts +10 -0
  570. package/types/shared/CheckGlyph.d.ts.map +1 -0
  571. package/types/shared/floatingList.d.ts +55 -1
  572. package/types/shared/floatingList.d.ts.map +1 -1
  573. package/dist/cjs/FloatingPanel/iconEcho.cjs +0 -106
  574. package/dist/cjs/FloatingPanel/iconEcho.native.js +0 -116
  575. package/dist/cjs/FloatingPanel/iconEcho.native.js.map +0 -1
  576. package/dist/esm/FloatingPanel/iconEcho.mjs +0 -79
  577. package/dist/esm/FloatingPanel/iconEcho.mjs.map +0 -1
  578. package/dist/esm/FloatingPanel/iconEcho.native.js +0 -86
  579. package/dist/esm/FloatingPanel/iconEcho.native.js.map +0 -1
  580. package/dist/jsx/FloatingPanel/iconEcho.mjs +0 -79
  581. package/dist/jsx/FloatingPanel/iconEcho.mjs.map +0 -1
  582. package/dist/jsx/FloatingPanel/iconEcho.native.js +0 -116
  583. package/dist/jsx/FloatingPanel/iconEcho.native.js.map +0 -1
  584. package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +0 -357
  585. package/src/FloatingPanel/iconEcho.tsx +0 -124
  586. package/types/FloatingPanel/iconEcho.d.ts +0 -29
  587. package/types/FloatingPanel/iconEcho.d.ts.map +0 -1
@@ -1,7 +1,8 @@
1
1
  import { IconSlot, useTouchSurface } from "@multiplatform.one/theme";
2
+ import { CheckGlyph } from "../../shared/CheckGlyph";
2
3
  import type { KeyboardEvent, MouseEvent, ReactNode, RefObject, UIEvent } from "react";
3
4
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, memo } from "react";
4
- import { CaretDownIcon, CaretRightIcon, CheckIcon } from "@phosphor-icons/react";
5
+ import { CaretDownIcon, CaretRightIcon } from "@phosphor-icons/react";
5
6
  import {
6
7
  useClick,
7
8
  useDismiss,
@@ -50,11 +51,14 @@ import {
50
51
  useFormField,
51
52
  useResolvedValidators,
52
53
  } from "../../shared/utils";
53
- import { ScrollArrow } from "../../shared/floatingList";
54
+ import {
55
+ growOnScroll,
56
+ placeCheckedOnField,
57
+ ScrollArrow,
58
+ scrollArrowBand,
59
+ } from "../../shared/floatingList";
54
60
  import {
55
61
  FloatingPanel,
56
- TriggerEchoRow,
57
- placeEchoOverTrigger,
58
62
  useFloatingPanel,
59
63
  panelViewportPadding,
60
64
  useViewportGtSm,
@@ -349,8 +353,8 @@ function selectItemRingProps(isActive: boolean, kbNav: boolean) {
349
353
  * row. On native the shim can only resolve a token the theme in scope actually
350
354
  * carries, and the component sub-themes carry no accent solid at all.
351
355
  * Resolve it here, where the value becomes a paint — the same shape as
352
- * `mutedColor` in Combobox. Keyed off `useMenuRowCheckInk` (`menuRowCheckInk`, ink when hue-less), the selection tint's
353
- * own ink, so the tick holds 4.5:1 on the chosen row (FZ-8355 r6), degrading
356
+ * `mutedColor` in Combobox. Keyed off `useMenuRowCheckInk` (the accent, ink when hue-less), so the tick
357
+ * holds 4.5:1 on the chosen row (FZ-8355 r6, FZ-8557), degrading
354
358
  * to `$color` ink rather than black when a narrow sub-theme lacks the key.
355
359
  */
356
360
  function useSelectedMarkColor(): string {
@@ -506,7 +510,7 @@ const SelectItem = memo(function SelectItem({
506
510
  >
507
511
  {option.label}
508
512
  </Text>
509
- {isSelected && <CheckIcon size={14} weight="bold" color={ctx.markColor} />}
513
+ {isSelected && <CheckGlyph />}
510
514
  </SelectRow>
511
515
  );
512
516
  });
@@ -624,20 +628,13 @@ function FloatingSelectCore({
624
628
  }, [options, value, multiple, selectedOrder]);
625
629
 
626
630
  const programmaticScrollRef = useRef(0);
627
- const pinnedTopRef = useRef(0);
628
- const pinnedHeightRef = useRef(0);
629
- const grownRef = useRef(false);
630
- const growUpOnlyRef = useRef(false);
631
- const growDownOnlyRef = useRef(false);
632
631
  const lastScrollTopRef = useRef(0);
633
- // LC-112 cover and scroll (FZ-8463): a list that doesn't fit below its
634
- // field covers the field with no echo row and grows toward the side with
635
- // more room, then scrolls.
636
- const coverScrollRef = useRef(false);
637
- const [coverScroll, setCoverScroll] = useState(false);
638
- const growsUpRef = useRef(false);
639
- const coverTrimRef = useRef(0);
640
- const echoed = !beside && !coverScroll;
632
+ // The panel's box with the checked row on the field (FZ-8557), in the
633
+ // padding box's viewport coordinates.
634
+ const onFieldRef = useRef<{ top: number; height: number; scrollTop: number } | null>(null);
635
+ const opensUpRef = useRef(false);
636
+ // One band for the layout and the arrows that draw it (FZ-8557).
637
+ const arrowBand = scrollArrowBand(knobProps.menuRow.minHeight);
641
638
 
642
639
  const repositionRef = useRef<(() => void) | null>(null);
643
640
 
@@ -646,21 +643,13 @@ function FloatingSelectCore({
646
643
  onOpenChange: setOpen,
647
644
  disabled,
648
645
  repositionRef,
649
- wheelGrowRef: selectedIndex >= 0 ? grownRef : undefined,
650
646
  onBeforeOpen: () => {
651
647
  computeSortedOptions();
652
648
  overlayStyle.current = null;
653
- pinnedTopRef.current = 0;
654
- pinnedHeightRef.current = 0;
655
- grownRef.current = false;
656
- growUpOnlyRef.current = false;
657
- growDownOnlyRef.current = false;
658
649
  lastScrollTopRef.current = 0;
659
650
  programmaticScrollRef.current = 0;
660
- coverScrollRef.current = false;
661
- growsUpRef.current = false;
662
- coverTrimRef.current = 0;
663
- setCoverScroll(false);
651
+ onFieldRef.current = null;
652
+ opensUpRef.current = false;
664
653
  },
665
654
  panelWidth,
666
655
  });
@@ -728,11 +717,6 @@ function FloatingSelectCore({
728
717
  const isInitial = panel.initializingRef.current;
729
718
  if (isInitial) dropdownElement.style.transition = "none";
730
719
 
731
- if (pinnedTopRef.current === 0 && pinnedHeightRef.current === 0) {
732
- programmaticScrollRef.current++;
733
- dropdownElement.scrollTop = 0;
734
- }
735
-
736
720
  const triggerBounds = trigger.getBoundingClientRect();
737
721
  const viewportHeight = window.innerHeight;
738
722
  // The math runs in viewport coordinates; a panel hosted in a transformed
@@ -744,153 +728,46 @@ function FloatingSelectCore({
744
728
  const borderBottomWidth = parseFloat(computedStyle.borderBottomWidth) || 0;
745
729
  const totalBorderWidth = borderTopWidth + borderBottomWidth;
746
730
  const scrollContentHeight = dropdownElement.scrollHeight;
747
- const totalContentHeight = scrollContentHeight + totalBorderWidth;
748
-
749
- // LC-112 seamless cover (FZ-8438): the panel's top edge is the trigger's,
750
- // the trigger echoed as its first row, the list below it. A list that
751
- // doesn't fit below its field covers the field with no echo row and
752
- // grows toward the side with more room: down from the field's top edge,
753
- // or up from its bottom edge. Past the safe screen edge it scrolls, and
754
- // scrolling grows it to fill the screen (FZ-8463).
755
- const firstPlacement = pinnedTopRef.current === 0 && pinnedHeightRef.current === 0;
756
- const boundsTop = panelViewportPadding;
757
- const boundsBottom = viewportHeight - panelViewportPadding;
758
- const echoRow = dropdownElement.querySelector<HTMLElement>("[data-fp-trigger-row]");
759
- const echoHeight = echoRow ? triggerBounds.height : 0;
760
- const listHeight = totalContentHeight - echoHeight;
761
- const roomBelow = boundsBottom - triggerBounds.top;
762
- const roomAbove = triggerBounds.bottom - boundsTop;
763
- if (firstPlacement && totalContentHeight > roomBelow) {
764
- coverScrollRef.current = true;
765
- growsUpRef.current = roomAbove > roomBelow;
766
- setCoverScroll(true);
767
- }
768
731
 
769
- if (coverScrollRef.current) {
770
- const grown = grownRef.current || growUpOnlyRef.current || growDownOnlyRef.current;
771
- const room = grown ? boundsBottom - boundsTop : growsUpRef.current ? roomAbove : roomBelow;
772
- const trim = grown ? 0 : coverTrimRef.current;
773
- const height = Math.max(0, Math.min(listHeight, room - trim));
774
- const anchor = growsUpRef.current ? triggerBounds.bottom - height : triggerBounds.top;
775
- const top = Math.min(Math.max(anchor, boundsTop), boundsBottom - height);
776
- const previousTop = pinnedTopRef.current;
777
- if (
778
- !overlayStyle.current ||
779
- overlayStyle.current.top !== top - originTop ||
780
- overlayStyle.current.maxHeight !== height
781
- ) {
782
- dropdownElement.style.top = `${top - originTop}px`;
783
- dropdownElement.style.maxHeight = `${height}px`;
784
- dropdownElement.style.height = "";
785
- overlayStyle.current = { top: top - originTop, maxHeight: height };
786
- void dropdownElement.offsetHeight;
787
- }
788
- pinnedTopRef.current = top;
789
- pinnedHeightRef.current = height;
790
- // Rows stay under the pointer while the panel grows upward.
791
- if (grown && previousTop > top && dropdownElement.scrollTop > 0) {
792
- programmaticScrollRef.current++;
793
- dropdownElement.scrollTop = Math.max(0, dropdownElement.scrollTop - (previousTop - top));
794
- }
795
- if (echoRow) return;
796
- const rowHeight = selectedItem.offsetHeight || 1;
797
- if (isInitial && selectedIndex >= 0) {
798
- // The checked row lands on the field when the list can scroll that
799
- // far. Opening down, short of that it stops a whole row short, so the
800
- // top row isn't cut in half. Two pixels of rounding are not a row.
801
- const maxScrollTop = dropdownElement.scrollHeight - dropdownElement.clientHeight;
802
- let scrollTop: number;
803
- if (growsUpRef.current) {
804
- scrollTop = selectedItem.offsetTop + rowHeight - (triggerBounds.bottom - top);
805
- } else {
806
- const short = Math.max(0, selectedItem.offsetTop - maxScrollTop - 2);
807
- scrollTop = selectedItem.offsetTop - Math.ceil(short / rowHeight) * rowHeight;
808
- }
809
- programmaticScrollRef.current++;
810
- dropdownElement.scrollTop = Math.min(maxScrollTop, Math.max(0, scrollTop));
811
- }
812
- if (isInitial && !grown) {
813
- // The far edge ends on a whole row: growing up, the row on the field
814
- // isn't cut in half; growing down, no sliver sits at the screen edge.
815
- const firstRow = listItemsRef.current[0];
816
- const visibleBottom = dropdownElement.scrollTop + dropdownElement.clientHeight;
817
- if (firstRow && visibleBottom < dropdownElement.scrollHeight - 2) {
818
- const cut = (visibleBottom - firstRow.offsetTop) % rowHeight;
819
- if (cut > 3 && cut < rowHeight - 3) {
820
- coverTrimRef.current = cut;
821
- const trimmedHeight = height - cut;
822
- const trimmedTop = growsUpRef.current ? top + cut : top;
823
- dropdownElement.style.top = `${trimmedTop - originTop}px`;
824
- dropdownElement.style.maxHeight = `${trimmedHeight}px`;
825
- overlayStyle.current = { top: trimmedTop - originTop, maxHeight: trimmedHeight };
826
- pinnedTopRef.current = trimmedTop;
827
- pinnedHeightRef.current = trimmedHeight;
828
- }
829
- }
830
- }
831
- panel.initializingRef.current = false;
832
- void dropdownElement.offsetHeight;
833
- if (isInitial) dropdownElement.style.transition = panel.panelTransition;
834
- requestAnimationFrame(() => {
835
- if (dropdownElement) panel.updateArrows(dropdownElement);
732
+ // LC-112 (FZ-8557 r3): a covering Select opens the way a macOS pop-up
733
+ // does. Its checked row sits on the field (the first row when nothing is
734
+ // checked), so the value never shows twice. A list that fits the safe
735
+ // viewport shows whole, slid the least distance to stay on screen; a
736
+ // taller one clips at the safe edges and scrolls under its arrow bands.
737
+ // Scrolling grows a panel that stops short of a safe edge toward it,
738
+ // the rows staying under the pointer.
739
+ const boundsTop = panelViewportPadding + borderTopWidth;
740
+ const boundsBottom = viewportHeight - panelViewportPadding - borderBottomWidth;
741
+ if (!onFieldRef.current) {
742
+ const fit = placeCheckedOnField({
743
+ fieldTop: triggerBounds.top,
744
+ fieldBottom: triggerBounds.bottom,
745
+ rowTop: selectedItem.offsetTop,
746
+ rowHeight: selectedItem.offsetHeight || 1,
747
+ contentHeight: scrollContentHeight,
748
+ boundsTop,
749
+ boundsBottom,
750
+ band: arrowBand,
751
+ });
752
+ onFieldRef.current = fit;
753
+ opensUpRef.current =
754
+ fit.top + fit.height / 2 < (triggerBounds.top + triggerBounds.bottom) / 2;
755
+ } else if (!isInitial) {
756
+ onFieldRef.current = growOnScroll({
757
+ ...onFieldRef.current,
758
+ scrollTop: dropdownElement.scrollTop,
759
+ contentHeight: scrollContentHeight,
760
+ boundsTop,
761
+ boundsBottom,
836
762
  });
837
- return;
838
- }
839
- const idealTop = triggerBounds.top;
840
- const idealBottom = idealTop + totalContentHeight;
841
- const pinnedTop = Math.max(panelViewportPadding, idealTop);
842
- const pinnedBottom = Math.min(viewportHeight - panelViewportPadding, idealBottom);
843
- const pinnedHeight = Math.max(120, pinnedBottom - pinnedTop);
844
-
845
- if (firstPlacement) {
846
- pinnedTopRef.current = pinnedTop;
847
- pinnedHeightRef.current = pinnedHeight;
848
- }
849
-
850
- let top = pinnedTopRef.current;
851
- let height = pinnedHeightRef.current;
852
-
853
- if (grownRef.current) {
854
- const canGrowDown = Math.max(0, viewportHeight - panelViewportPadding - (top + height));
855
- height += canGrowDown;
856
- const canGrowUp = Math.max(0, top - panelViewportPadding);
857
- top -= canGrowUp;
858
- height += canGrowUp;
859
- }
860
-
861
- if (growUpOnlyRef.current) {
862
- const canGrowUp = Math.max(0, top - panelViewportPadding);
863
- top -= canGrowUp;
864
- height += canGrowUp;
865
- }
866
- if (growDownOnlyRef.current) {
867
- const canGrowDown = Math.max(0, viewportHeight - panelViewportPadding - (top + height));
868
- height += canGrowDown;
869
- }
870
-
871
- height = Math.min(height, viewportHeight - top - panelViewportPadding);
872
- height = Math.min(height, totalContentHeight);
873
- height = Math.max(120, height);
874
-
875
- // When grown but content is shorter than viewport: anchor dropdown to bottom (gap above), dropup to top (gap below)
876
- const availableViewport = viewportHeight - 2 * panelViewportPadding;
877
- if (
878
- (grownRef.current || growUpOnlyRef.current || growDownOnlyRef.current) &&
879
- height < availableViewport
880
- ) {
881
- if (panel.placement.startsWith("top")) {
882
- top = panelViewportPadding;
883
- } else {
884
- top = viewportHeight - panelViewportPadding - height;
885
- }
886
763
  }
887
-
888
- const cachedOverlayStyle = overlayStyle.current;
889
-
764
+ const placed = onFieldRef.current;
765
+ const top = placed.top - borderTopWidth;
766
+ const height = placed.height + totalBorderWidth;
890
767
  if (
891
- !cachedOverlayStyle ||
892
- cachedOverlayStyle.top !== top - originTop ||
893
- cachedOverlayStyle.maxHeight !== height
768
+ !overlayStyle.current ||
769
+ overlayStyle.current.top !== top - originTop ||
770
+ overlayStyle.current.maxHeight !== height
894
771
  ) {
895
772
  dropdownElement.style.top = `${top - originTop}px`;
896
773
  dropdownElement.style.maxHeight = `${height}px`;
@@ -898,63 +775,24 @@ function FloatingSelectCore({
898
775
  overlayStyle.current = { top: top - originTop, maxHeight: height };
899
776
  void dropdownElement.offsetHeight;
900
777
  }
901
-
902
- if (
903
- isInitial &&
904
- selectedIndex >= 0 &&
905
- !grownRef.current &&
906
- !growUpOnlyRef.current &&
907
- !growDownOnlyRef.current
908
- ) {
909
- // The selected row starts in view, just under the sticky echo row.
910
- const rowBottom = selectedItem.offsetTop + selectedItem.offsetHeight;
911
- if (rowBottom > dropdownElement.clientHeight) {
912
- const maxScrollTop = dropdownElement.scrollHeight - dropdownElement.clientHeight;
913
- programmaticScrollRef.current++;
914
- dropdownElement.scrollTop = Math.max(
915
- 0,
916
- Math.min(selectedItem.offsetTop - echoHeight, maxScrollTop),
917
- );
918
- }
778
+ if (Math.abs(dropdownElement.scrollTop - placed.scrollTop) >= 0.5) {
779
+ programmaticScrollRef.current++;
780
+ dropdownElement.scrollTop = placed.scrollTop;
919
781
  }
920
-
921
- // A screen-wide or fixed-width list slides inside the margins; its echo
922
- // stays on the field (LC-112 r3). The scale origin is the left edge, so
923
- // the client rect's left is the layout left.
924
- placeEchoOverTrigger(
925
- dropdownElement,
926
- {
927
- triggerLeft: triggerBounds.left,
928
- triggerRight: triggerBounds.right,
929
- panelLeft: dropdownElement.getBoundingClientRect().left,
930
- panelWidth: dropdownElement.offsetWidth,
931
- rtl: getComputedStyle(trigger).direction === "rtl",
932
- },
933
- { stretch: panelWidth !== undefined },
934
- );
935
-
936
782
  panel.initializingRef.current = false;
937
-
938
783
  void dropdownElement.offsetHeight;
939
784
  if (isInitial) dropdownElement.style.transition = panel.panelTransition;
940
785
  requestAnimationFrame(() => {
941
- if (dropdownElement) {
942
- panel.updateArrows(dropdownElement);
943
- requestAnimationFrame(() => {
944
- if (dropdownElement) panel.updateArrows(dropdownElement);
945
- });
946
- }
786
+ if (dropdownElement) panel.updateArrows(dropdownElement);
947
787
  });
948
788
  }, [
949
789
  selectedIndex,
950
790
  panel.refs,
951
791
  panel.updateArrows,
952
- panel.placement,
953
792
  panel.panelTransition,
954
793
  options.length,
955
794
  beside,
956
- coverScroll,
957
- panelWidth,
795
+ arrowBand,
958
796
  ]);
959
797
 
960
798
  repositionRef.current = repositionOverlay;
@@ -1156,23 +994,10 @@ function FloatingSelectCore({
1156
994
  return;
1157
995
  }
1158
996
  const arrowDir = panel.arrowScrollDirRef.current;
1159
- if (arrowDir) {
1160
- panel.arrowScrollDirRef.current = null;
1161
- lastScrollTopRef.current = el.scrollTop;
1162
- if (arrowDir === "down") {
1163
- growUpOnlyRef.current = true;
1164
- } else {
1165
- growDownOnlyRef.current = true;
1166
- }
1167
- repositionOverlay();
1168
- return;
1169
- }
997
+ if (arrowDir) panel.arrowScrollDirRef.current = null;
1170
998
  const delta = el.scrollTop - lastScrollTopRef.current;
1171
999
  lastScrollTopRef.current = el.scrollTop;
1172
- if (delta !== 0) {
1173
- grownRef.current = true;
1174
- repositionOverlay();
1175
- }
1000
+ if (delta !== 0) repositionOverlay();
1176
1001
  },
1177
1002
  [panel.updateArrows, repositionOverlay],
1178
1003
  );
@@ -1290,10 +1115,7 @@ function FloatingSelectCore({
1290
1115
  opacity: panel.visible ? 1 : 0,
1291
1116
  transform: panel.visible ? "scale(1)" : "scale(0.96)",
1292
1117
  transition: panel.panelTransition,
1293
- transformOrigin:
1294
- (coverScroll && growsUpRef.current) || panel.placement.startsWith("top")
1295
- ? "bottom left"
1296
- : "top left",
1118
+ transformOrigin: opensUpRef.current ? "bottom left" : "top left",
1297
1119
  ...dragProps.style,
1298
1120
  },
1299
1121
  onPointerDown: dragProps.onPointerDown,
@@ -1336,22 +1158,12 @@ function FloatingSelectCore({
1336
1158
  paddingVertical={0}
1337
1159
  paddingBottom={panel.coverCornerInset || 0}
1338
1160
  >
1339
- {echoed ? (
1340
- <TriggerEchoRow
1341
- sourceRef={panel.triggerRef}
1342
- source={selectedOption?.label ?? placeholder}
1343
- onPress={() => setOpen(false)}
1344
- presentational
1345
- />
1346
- ) : null}
1347
1161
  <ScrollArrow
1348
1162
  direction="up"
1349
1163
  scrollRef={panel.refs.floating}
1350
1164
  visible={panel.arrowUp}
1351
1165
  arrowScrollDirRef={panel.arrowScrollDirRef}
1352
- topOffset={
1353
- echoed ? (panel.triggerRef.current?.getBoundingClientRect().height ?? 0) : 0
1354
- }
1166
+ band={arrowBand}
1355
1167
  />
1356
1168
  {groupLabel && (
1357
1169
  <GroupHeader color={textColor} paddingHorizontal={knobProps.panelPadding.padding}>
@@ -1402,6 +1214,7 @@ function FloatingSelectCore({
1402
1214
  scrollRef={panel.refs.floating}
1403
1215
  visible={panel.arrowDown}
1404
1216
  arrowScrollDirRef={panel.arrowScrollDirRef}
1217
+ band={arrowBand}
1405
1218
  />
1406
1219
  </YStack>
1407
1220
  </FloatingFocusManager>
@@ -1629,7 +1442,7 @@ function NativeSelectCore({
1629
1442
  >
1630
1443
  {option.label}
1631
1444
  </Text>
1632
- {selected && <CheckIcon size={14} weight="bold" color={markColor} />}
1445
+ {selected && <CheckGlyph />}
1633
1446
  </View>
1634
1447
  );
1635
1448
  if (isWeb) return row;
@@ -21,7 +21,7 @@ import {
21
21
  } from "react-native";
22
22
  import { platform } from "@multiplatform.one/platform";
23
23
  import { SafeAreaInsetsContext, initialWindowMetrics } from "react-native-safe-area-context";
24
- import { useResolvedKnobs, Text } from "@multiplatform.one/theme";
24
+ import { useResolvedKnobs, Text, overlayScrim } from "@multiplatform.one/theme";
25
25
  import { View, XStack, YStack, useTheme, useThemeName } from "tamagui";
26
26
  import { ArrowRightIcon } from "@phosphor-icons/react";
27
27
  import { IconButton } from "../../Button";
@@ -159,7 +159,7 @@ export function OsDateTimeSheet({
159
159
  right={0}
160
160
  bottom={0}
161
161
  left={0}
162
- backgroundColor="$shadow6"
162
+ backgroundColor={overlayScrim}
163
163
  />
164
164
  <YStack
165
165
  testID="os-date-time-sheet-unavailable"
@@ -205,7 +205,7 @@ export function OsDateTimeSheet({
205
205
  */}
206
206
  <RNView style={[styles.modalOverlay, { paddingBottom: keyboardInset }]}>
207
207
  <Pressable style={StyleSheet.absoluteFill} onPress={onCancel}>
208
- <View pointerEvents="none" flex={1} backgroundColor="$shadow6" />
208
+ <View pointerEvents="none" flex={1} backgroundColor={overlayScrim} />
209
209
  </Pressable>
210
210
  <Pressable onPress={(e) => e.stopPropagation()}>
211
211
  <YStack
package/src/index.ts CHANGED
@@ -310,6 +310,8 @@ export { PanelHeader } from "./FloatingPanel/PanelHeader";
310
310
  export { PanelPortal } from "./FloatingPanel/PanelPortal";
311
311
  export type { PanelPortalProps } from "./FloatingPanel/PanelPortal";
312
312
  export { containsAcrossPanels } from "./shared/panelPortal";
313
+ export { CheckGlyph } from "./shared/CheckGlyph";
314
+ export { useInPanelSheet } from "./FloatingPanel/echoContext";
313
315
  export type {
314
316
  FloatingPanelProps,
315
317
  PanelWidthMode,
@@ -317,7 +319,6 @@ export type {
317
319
  UseFloatingPanelReturn,
318
320
  } from "./FloatingPanel";
319
321
  export type { PanelWidth } from "./FloatingPanel/panelWidth";
320
- export type { IconEcho } from "./FloatingPanel/iconEcho";
321
322
 
322
323
  // ── Adaptive Popup (Dialog / Drawer on desktop, Sheet on mobile) ─
323
324
  export { AdaptivePopup, pickAdaptivePopupFace } from "./AdaptivePopup";
@@ -0,0 +1,12 @@
1
+ import { CheckIcon } from "@phosphor-icons/react";
2
+ import { menuRowCheckGlyph, type MenuRowGlyph, useMenuRowCheckInk } from "@multiplatform.one/theme";
3
+
4
+ /**
5
+ * The check on a checked menu or picker row (LC-262, FZ-8557): the theme's
6
+ * `menuRowCheckGlyph` recipe in the check ink. A row with an icon passes
7
+ * `menuRowIconGlyph`, so the check takes the icons' stroke (FZ-8557 r3). Components draws the same glyph through its own twin, and a spec keeps the two equal.
8
+ */
9
+ export function CheckGlyph({ glyph = menuRowCheckGlyph }: { glyph?: MenuRowGlyph }) {
10
+ const ink = useMenuRowCheckInk();
11
+ return <CheckIcon size={glyph.size} weight={glyph.weight} color={ink} />;
12
+ }
@@ -7,7 +7,13 @@ import { Preset, Surface } from "@multiplatform.one/theme";
7
7
  import { renderWithProviders } from "@multiplatform.one/test-utils";
8
8
  import { cleanup } from "@testing-library/react";
9
9
  import { afterEach, describe, expect, it } from "vitest";
10
- import { ScrollArrow } from "./floatingList";
10
+ import {
11
+ growOnScroll,
12
+ placeCheckedOnField,
13
+ ScrollArrow,
14
+ scrollArrowBand,
15
+ scrollArrowThreshold,
16
+ } from "./floatingList";
11
17
 
12
18
  afterEach(cleanup);
13
19
 
@@ -59,3 +65,150 @@ describe("ScrollArrow design-law (MPO-60)", () => {
59
65
  expect(style).not.toMatch(/160ms/);
60
66
  });
61
67
  });
68
+
69
+ describe("ScrollArrow band (FZ-8557)", () => {
70
+ it("is an opaque band half a menu row tall, never a fade over rows", () => {
71
+ const result = renderArrow();
72
+ const well = result.container.querySelector("[data-mpo-scroll-arrow]") as HTMLElement | null;
73
+ expect(well?.getAttribute("data-band")).toBe(String(scrollArrowBand(36)));
74
+ expect(well?.getAttribute("style") ?? "").not.toMatch(/gradient/);
75
+ });
76
+ });
77
+
78
+ /** The bands a fit shows: an up band once it has scrolled, a down band while rows remain below. */
79
+ function bandsOf(
80
+ fit: { top: number; height: number; scrollTop: number },
81
+ list: { contentHeight: number; band: number },
82
+ ) {
83
+ const bands: [number, number][] = [];
84
+ if (fit.scrollTop > scrollArrowThreshold) bands.push([fit.top, fit.top + list.band]);
85
+ if (fit.scrollTop + fit.height < list.contentHeight - scrollArrowThreshold)
86
+ bands.push([fit.top + fit.height - list.band, fit.top + fit.height]);
87
+ return bands;
88
+ }
89
+
90
+ describe("placeCheckedOnField: the checked row opens on the field (FZ-8557 r3)", () => {
91
+ const rowHeight = 36;
92
+ const firstRowTop = 4;
93
+ const band = 18;
94
+ const contentOf = (count: number) => firstRowTop * 2 + count * rowHeight;
95
+ const place = (fieldBottom: number, row: number, count = 40, boundsBottom = 1356) =>
96
+ placeCheckedOnField({
97
+ fieldTop: fieldBottom - rowHeight,
98
+ fieldBottom,
99
+ rowTop: firstRowTop + row * rowHeight,
100
+ rowHeight,
101
+ contentHeight: contentOf(count),
102
+ boundsTop: 10,
103
+ boundsBottom,
104
+ band,
105
+ });
106
+ const checkedRect = (fit: { top: number; scrollTop: number }, row: number) => {
107
+ const top = fit.top + firstRowTop + row * rowHeight - fit.scrollTop;
108
+ return { top, bottom: top + rowHeight };
109
+ };
110
+
111
+ it("a list that fits shows every row with no scrolling (the iPad's 37 rows)", () => {
112
+ const fit = place(700, 20, 37);
113
+ expect(fit.scrollTop).toBe(0);
114
+ expect(fit.height).toBe(contentOf(37));
115
+ expect(fit.top).toBeGreaterThanOrEqual(10);
116
+ expect(fit.top + fit.height).toBeLessThanOrEqual(1356);
117
+ });
118
+
119
+ it("a short list by the edge slides the least distance instead of scrolling (select-low-390)", () => {
120
+ // The phone's low field (735 to 775) with Denver (row 3) of 7 checked.
121
+ const low = placeCheckedOnField({
122
+ fieldTop: 735,
123
+ fieldBottom: 775,
124
+ rowTop: firstRowTop + 3 * rowHeight,
125
+ rowHeight,
126
+ contentHeight: contentOf(7),
127
+ boundsTop: 10,
128
+ boundsBottom: 834,
129
+ band,
130
+ });
131
+ expect(low.scrollTop).toBe(0);
132
+ expect(low.height).toBe(contentOf(7));
133
+ expect(low.top + low.height).toBe(834);
134
+ });
135
+
136
+ it("where it fits on the field, the checked row centres on it", () => {
137
+ const fit = place(400, 3, 7);
138
+ expect(checkedRect(fit, 3).bottom).toBe(400);
139
+ expect(fit.scrollTop).toBe(0);
140
+ });
141
+
142
+ it("a list taller than the screen keeps the checked row on the field and clips at the safe edges", () => {
143
+ const fit = place(1115, 38, 60);
144
+ expect(checkedRect(fit, 38).bottom).toBe(1115);
145
+ expect(fit.top).toBe(10);
146
+ expect(fit.scrollTop).toBeGreaterThan(0);
147
+ });
148
+
149
+ it("a scrolling list's far edge reaches the safe edge: no whole-row trim", () => {
150
+ for (const fieldBottom of [200, 517, 900, 1300]) {
151
+ for (const row of [0, 10, 30, 59]) {
152
+ const fit = place(fieldBottom, row, 60);
153
+ const content = contentOf(60);
154
+ if (fit.scrollTop > scrollArrowThreshold) expect(fit.top, `${fieldBottom}/${row}`).toBe(10);
155
+ if (fit.scrollTop + fit.height < content - scrollArrowThreshold)
156
+ expect(fit.top + fit.height, `${fieldBottom}/${row}`).toBe(1356);
157
+ }
158
+ }
159
+ });
160
+
161
+ it("across fields and rows, the checked row overlaps the field and no band covers it", () => {
162
+ for (let fieldBottom = 60; fieldBottom <= 1356; fieldBottom += 13) {
163
+ for (const count of [7, 40, 60]) {
164
+ for (const row of [0, 1, 5, 20, 30, 39].filter((r) => r < count)) {
165
+ const fit = place(fieldBottom, row, count);
166
+ const checked = checkedRect(fit, row);
167
+ const label = `field ${fieldBottom} row ${row} of ${count}`;
168
+ expect(fit.top, label).toBeGreaterThanOrEqual(10);
169
+ expect(fit.top + fit.height, label).toBeLessThanOrEqual(1356);
170
+ expect(checked.top, label).toBeGreaterThanOrEqual(fit.top);
171
+ expect(checked.bottom, label).toBeLessThanOrEqual(fit.top + fit.height);
172
+ if (contentOf(count) > 1346) {
173
+ const overlap =
174
+ Math.min(checked.bottom, fieldBottom) - Math.max(checked.top, fieldBottom - 40);
175
+ expect(overlap, label).toBeGreaterThan(0);
176
+ }
177
+ for (const [bandTop, bandBottom] of bandsOf(fit, {
178
+ contentHeight: contentOf(count),
179
+ band,
180
+ })) {
181
+ const shared = Math.min(checked.bottom, bandBottom) - Math.max(checked.top, bandTop);
182
+ expect(shared, label).toBeLessThanOrEqual(0);
183
+ }
184
+ }
185
+ }
186
+ }
187
+ });
188
+ });
189
+
190
+ describe("growOnScroll: a short scrolling panel grows toward the safe edge (FZ-8557 r3)", () => {
191
+ const bounds = { boundsTop: 10, boundsBottom: 1356, contentHeight: 2000 };
192
+
193
+ it("scrolling down lifts the top edge with the rows until it meets the safe edge", () => {
194
+ const grown = growOnScroll({ top: 600, height: 756, scrollTop: 120, ...bounds });
195
+ expect(grown).toEqual({ top: 480, height: 876, scrollTop: 0 });
196
+ const full = growOnScroll({ top: 600, height: 756, scrollTop: 900, ...bounds });
197
+ expect(full.top).toBe(10);
198
+ expect(full.top - full.scrollTop).toBe(600 - 900);
199
+ });
200
+
201
+ it("scrolling up drops a short bottom edge with the rows", () => {
202
+ const grown = growOnScroll({ top: 10, height: 600, scrollTop: 1300, ...bounds });
203
+ expect(grown.top).toBe(10);
204
+ expect(grown.scrollTop).toBe(1300);
205
+ expect(grown.top + grown.height).toBe(Math.min(1356, 10 - 1300 + 2000));
206
+ });
207
+
208
+ it("a panel at rest stays as it is, and one already at both edges never shrinks", () => {
209
+ const rest = { top: 118, height: 1238, scrollTop: 0 };
210
+ expect(growOnScroll({ ...rest, ...bounds })).toEqual(rest);
211
+ const full = { top: 10, height: 1346, scrollTop: 400 };
212
+ expect(growOnScroll({ ...full, ...bounds })).toEqual(full);
213
+ });
214
+ });