@multiplatform.one/forms 7.79.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 (604) 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/glass.cjs +1 -2
  7. package/dist/cjs/Button/iconButtonGroupContext.native.js.map +1 -1
  8. package/dist/cjs/Button/index.cjs +12 -5
  9. package/dist/cjs/Button/index.native.js +16 -8
  10. package/dist/cjs/Button/index.native.js.map +1 -1
  11. package/dist/cjs/Button/webGlass.native.js.map +1 -1
  12. package/dist/cjs/Chip/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.native.js +1 -1
  21. package/dist/cjs/ControlGroup/index.native.js.map +1 -1
  22. package/dist/cjs/DescriptionList/index.native.js +2 -2
  23. package/dist/cjs/DescriptionList/index.native.js.map +1 -1
  24. package/dist/cjs/ErrorSummary.native.js.map +1 -1
  25. package/dist/cjs/FieldDisplay/editMode.native.js.map +1 -1
  26. package/dist/cjs/FieldDisplay/formatters.native.js.map +1 -1
  27. package/dist/cjs/FieldDisplay/index.native.js +1 -1
  28. package/dist/cjs/FieldDisplay/index.native.js.map +1 -1
  29. package/dist/cjs/FieldGroup.native.js.map +1 -1
  30. package/dist/cjs/FloatingPanel/PanelHeader.cjs +3 -8
  31. package/dist/cjs/FloatingPanel/PanelHeader.native.js +3 -8
  32. package/dist/cjs/FloatingPanel/PanelHeader.native.js.map +1 -1
  33. package/dist/cjs/FloatingPanel/RegularPanel.native.js.map +1 -1
  34. package/dist/cjs/FloatingPanel/compactFace.native.js.map +1 -1
  35. package/dist/cjs/FloatingPanel/containingBlock.native.js.map +1 -1
  36. package/dist/cjs/FloatingPanel/coverRect.cjs +0 -8
  37. package/dist/cjs/FloatingPanel/coverRect.native.js +0 -8
  38. package/dist/cjs/FloatingPanel/coverRect.native.js.map +1 -1
  39. package/dist/cjs/FloatingPanel/echoContext.cjs +5 -27
  40. package/dist/cjs/FloatingPanel/echoContext.native.js +5 -28
  41. package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -1
  42. package/dist/cjs/FloatingPanel/index.cjs +49 -131
  43. package/dist/cjs/FloatingPanel/index.native.js +26 -91
  44. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  45. package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -1
  46. package/dist/cjs/FloatingPanel/paintedBox.native.js.map +1 -1
  47. package/dist/cjs/FloatingPanel/panelWidth.native.js.map +1 -1
  48. package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
  49. package/dist/cjs/FloatingPanel/regularPlacement.native.js.map +1 -1
  50. package/dist/cjs/FloatingPanel/trailingAction.native.js +1 -1
  51. package/dist/cjs/FloatingPanel/trailingAction.native.js.map +1 -1
  52. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  53. package/dist/cjs/Form/index.native.js +1 -1
  54. package/dist/cjs/Form/index.native.js.map +1 -1
  55. package/dist/cjs/Form/submissionController.native.js.map +1 -1
  56. package/dist/cjs/Form/validateOn.native.js.map +1 -1
  57. package/dist/cjs/FormGrid.native.js.map +1 -1
  58. package/dist/cjs/FormSection.native.js.map +1 -1
  59. package/dist/cjs/InputParts/PasswordReveal.native.js.map +1 -1
  60. package/dist/cjs/InputParts/index.native.js.map +1 -1
  61. package/dist/cjs/InputParts/keyboardAppearance.native.js.map +1 -1
  62. package/dist/cjs/Label/index.native.js.map +1 -1
  63. package/dist/cjs/MediaPicker/base64.native.js.map +1 -1
  64. package/dist/cjs/MediaPicker/payload.native.js.map +1 -1
  65. package/dist/cjs/MediaPicker/types.native.js.map +1 -1
  66. package/dist/cjs/MediaPicker/useMediaPicker.native.js.map +1 -1
  67. package/dist/cjs/Skeleton/index.native.js.map +1 -1
  68. package/dist/cjs/Spinner/SpinnerGlyph.native.js.map +1 -1
  69. package/dist/cjs/Spinner/spinnerSize.native.js.map +1 -1
  70. package/dist/cjs/Table/index.native.js.map +1 -1
  71. package/dist/cjs/Wheel/haptic.native.js.map +1 -1
  72. package/dist/cjs/Wheel/index.native.js.map +1 -1
  73. package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
  74. package/dist/cjs/actionLabel.native.js.map +1 -1
  75. package/dist/cjs/fieldDefaults.native.js.map +1 -1
  76. package/dist/cjs/fieldLayout.native.js +1 -1
  77. package/dist/cjs/fieldLayout.native.js.map +1 -1
  78. package/dist/cjs/fields/Barcode/BarcodePreview.native.js.map +1 -1
  79. package/dist/cjs/fields/Barcode/BarcodeScanner.native.js +1 -1
  80. package/dist/cjs/fields/Barcode/code128.native.js.map +1 -1
  81. package/dist/cjs/fields/Barcode/index.native.js +2 -2
  82. package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
  83. package/dist/cjs/fields/Barcode/qr.native.js.map +1 -1
  84. package/dist/cjs/fields/Barcode/scannerTypes.native.js.map +1 -1
  85. package/dist/cjs/fields/Checkbox/Checkbox.native.js +1 -1
  86. package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
  87. package/dist/cjs/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  88. package/dist/cjs/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  89. package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  90. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js +1 -1
  91. package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  92. package/dist/cjs/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  93. package/dist/cjs/fields/Checkbox/index.native.js.map +1 -1
  94. package/dist/cjs/fields/ColorPicker/SystemColorField.native.js.map +1 -1
  95. package/dist/cjs/fields/ColorPicker/index.native.js +2 -2
  96. package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
  97. package/dist/cjs/fields/ColorPicker/parts.native.js +2 -2
  98. package/dist/cjs/fields/ColorPicker/parts.native.js.map +1 -1
  99. package/dist/cjs/fields/ColorPicker/systemColorWell.gnome.native.js.map +1 -1
  100. package/dist/cjs/fields/Combobox/authorOptions.native.js.map +1 -1
  101. package/dist/cjs/fields/Combobox/index.cjs +3 -10
  102. package/dist/cjs/fields/Combobox/index.native.js +8 -15
  103. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  104. package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
  105. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
  106. package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  107. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +3 -3
  108. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  109. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +2 -2
  110. package/dist/cjs/fields/DatePicker/MonthPicker.native.js +2 -2
  111. package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
  112. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
  113. package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  114. package/dist/cjs/fields/DatePicker/catalog.native.js +2 -2
  115. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
  116. package/dist/cjs/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  117. package/dist/cjs/fields/DatePicker/index.native.js +2 -2
  118. package/dist/cjs/fields/DatePicker/parts.native.js +2 -2
  119. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  120. package/dist/cjs/fields/DatePicker/utils.native.js.map +1 -1
  121. package/dist/cjs/fields/Duration/DurationWheel.native.js +1 -1
  122. package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
  123. package/dist/cjs/fields/Duration/durationWheelTypes.native.js.map +1 -1
  124. package/dist/cjs/fields/Duration/index.native.js +3 -3
  125. package/dist/cjs/fields/Duration/index.native.js.map +1 -1
  126. package/dist/cjs/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  127. package/dist/cjs/fields/FileUpload/index.native.js +2 -2
  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.native.js +2 -2
  144. package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
  145. package/dist/cjs/fields/Input/index.native.js +3 -3
  146. package/dist/cjs/fields/Input/index.native.js.map +1 -1
  147. package/dist/cjs/fields/MentionInput/index.native.js +3 -3
  148. package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
  149. package/dist/cjs/fields/OTPInput/index.native.js +3 -3
  150. package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
  151. package/dist/cjs/fields/OTPInput/otpCellCss.native.js.map +1 -1
  152. package/dist/cjs/fields/PhoneInput/dialCodes.native.js.map +1 -1
  153. package/dist/cjs/fields/PhoneInput/index.native.js +3 -3
  154. package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
  155. package/dist/cjs/fields/PhoneInput/phone.native.js.map +1 -1
  156. package/dist/cjs/fields/PhoneInput/regionNames.native.js.map +1 -1
  157. package/dist/cjs/fields/Progress/index.native.js +1 -1
  158. package/dist/cjs/fields/Progress/index.native.js.map +1 -1
  159. package/dist/cjs/fields/RadioGroup/index.native.js +1 -1
  160. package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
  161. package/dist/cjs/fields/Rating/index.native.js +1 -1
  162. package/dist/cjs/fields/Rating/index.native.js.map +1 -1
  163. package/dist/cjs/fields/Rating/ratingMath.native.js.map +1 -1
  164. package/dist/cjs/fields/Rating/types.native.js.map +1 -1
  165. package/dist/cjs/fields/SearchInput/index.native.js +2 -2
  166. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  167. package/dist/cjs/fields/Select/InlineChoices.cjs +4 -8
  168. package/dist/cjs/fields/Select/InlineChoices.native.js +4 -8
  169. package/dist/cjs/fields/Select/InlineChoices.native.js.map +1 -1
  170. package/dist/cjs/fields/Select/SheetPickerRow.native.js.map +1 -1
  171. package/dist/cjs/fields/Select/index.cjs +46 -199
  172. package/dist/cjs/fields/Select/index.native.js +56 -211
  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.native.js +1 -1
  178. package/dist/cjs/fields/Slider/index.native.js.map +1 -1
  179. package/dist/cjs/fields/Slider/jumpMotion.native.js.map +1 -1
  180. package/dist/cjs/fields/Stepper/index.native.js +2 -2
  181. package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
  182. package/dist/cjs/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  183. package/dist/cjs/fields/Switch/footprint.native.js.map +1 -1
  184. package/dist/cjs/fields/Switch/index.native.js +2 -2
  185. package/dist/cjs/fields/Switch/index.native.js.map +1 -1
  186. package/dist/cjs/fields/TextArea/index.native.js +2 -2
  187. package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
  188. package/dist/cjs/fields/TimePicker/catalog.native.js +3 -3
  189. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  190. package/dist/cjs/fields/TimePicker/index.native.js +2 -2
  191. package/dist/cjs/fields/TimePicker/parts.native.js +1 -1
  192. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  193. package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  194. package/dist/cjs/fields/TimeRangeScrubber/index.native.js +2 -2
  195. package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
  196. package/dist/cjs/fields/ToggleGroup/index.native.js +1 -1
  197. package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
  198. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +2 -2
  199. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
  200. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  201. package/dist/cjs/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
  202. package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  203. package/dist/cjs/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
  204. package/dist/cjs/fields/nativeSelect.native.js.map +1 -1
  205. package/dist/cjs/fields/selectedOrder.native.js.map +1 -1
  206. package/dist/cjs/formSpacing.native.js.map +1 -1
  207. package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
  208. package/dist/cjs/index.cjs +4 -0
  209. package/dist/cjs/index.native.js +49 -45
  210. package/dist/cjs/index.native.js.map +1 -1
  211. package/dist/cjs/keyboard/KeyboardDoneBar.native.js +1 -1
  212. package/dist/cjs/keyboard/chain.native.js.map +1 -1
  213. package/dist/cjs/keyboard/index.native.js.map +1 -1
  214. package/dist/cjs/keyboard/types.native.js.map +1 -1
  215. package/dist/cjs/requiredMarking.native.js.map +1 -1
  216. package/dist/cjs/shared/CheckGlyph.cjs +40 -0
  217. package/dist/cjs/shared/CheckGlyph.native.js +44 -0
  218. package/dist/cjs/shared/CheckGlyph.native.js.map +1 -0
  219. package/dist/cjs/shared/TimeColumn.native.js +1 -1
  220. package/dist/cjs/shared/TimeColumn.native.js.map +1 -1
  221. package/dist/cjs/shared/capabilityPreflight.native.js.map +1 -1
  222. package/dist/cjs/shared/choiceRowPress.native.js.map +1 -1
  223. package/dist/cjs/shared/colorRamps.native.js.map +1 -1
  224. package/dist/cjs/shared/devWarn.native.js.map +1 -1
  225. package/dist/cjs/shared/fieldRowContext.native.js.map +1 -1
  226. package/dist/cjs/shared/floatingList.cjs +82 -3
  227. package/dist/cjs/shared/floatingList.native.js +96 -6
  228. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  229. package/dist/cjs/shared/focusManagement.native.js.map +1 -1
  230. package/dist/cjs/shared/groupContext.native.js.map +1 -1
  231. package/dist/cjs/shared/i18n.native.js.map +1 -1
  232. package/dist/cjs/shared/instantMotion.native.js.map +1 -1
  233. package/dist/cjs/shared/nativeA11y.native.js.map +1 -1
  234. package/dist/cjs/shared/nativeAutoFocus.native.js.map +1 -1
  235. package/dist/cjs/shared/overlaySizeClass.native.js.map +1 -1
  236. package/dist/cjs/shared/overlayStack.native.js.map +1 -1
  237. package/dist/cjs/shared/panelPortal.native.js.map +1 -1
  238. package/dist/cjs/shared/pickerTriggerContract.native.js.map +1 -1
  239. package/dist/cjs/shared/pressSlopProps.native.js.map +1 -1
  240. package/dist/cjs/shared/restoreRetries.native.js.map +1 -1
  241. package/dist/cjs/shared/sheetNavigation.native.js.map +1 -1
  242. package/dist/cjs/shared/systemControlModules.gnome.native.js.map +1 -1
  243. package/dist/cjs/shared/systemControls.native.js.map +1 -1
  244. package/dist/cjs/shared/t.native.js.map +1 -1
  245. package/dist/cjs/shared/tableCellContext.native.js.map +1 -1
  246. package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
  247. package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
  248. package/dist/cjs/shared/useSheetEscapeDismiss.native.js.map +1 -1
  249. package/dist/cjs/shared/useWheelIncrement.native.js.map +1 -1
  250. package/dist/cjs/shared/utils.native.js +1 -1
  251. package/dist/cjs/shared/utils.native.js.map +1 -1
  252. package/dist/cjs/shared/zIndex.native.js.map +1 -1
  253. package/dist/cjs/standardActions.native.js.map +1 -1
  254. package/dist/cjs/themedPrimitives.native.js.map +1 -1
  255. package/dist/cjs/types.native.js.map +1 -1
  256. package/dist/cjs/utils/LinkCell.native.js.map +1 -1
  257. package/dist/esm/AdaptivePopup/index.mjs +2 -2
  258. package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
  259. package/dist/esm/AdaptivePopup/index.native.js +2 -2
  260. package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
  261. package/dist/esm/Button/IconButtonGroup.native.js.map +1 -1
  262. package/dist/esm/Button/circleGlyph.native.js.map +1 -1
  263. package/dist/esm/Button/glass.mjs +1 -2
  264. package/dist/esm/Button/glass.mjs.map +1 -1
  265. package/dist/esm/Button/iconButtonGroupContext.native.js.map +1 -1
  266. package/dist/esm/Button/index.mjs +12 -5
  267. package/dist/esm/Button/index.mjs.map +1 -1
  268. package/dist/esm/Button/index.native.js +14 -6
  269. package/dist/esm/Button/index.native.js.map +1 -1
  270. package/dist/esm/Button/webGlass.mjs.map +1 -1
  271. package/dist/esm/Button/webGlass.native.js.map +1 -1
  272. package/dist/esm/Chip/index.native.js.map +1 -1
  273. package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
  274. package/dist/esm/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
  275. package/dist/esm/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
  276. package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
  277. package/dist/esm/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
  278. package/dist/esm/ControlGroup/index.native.js.map +1 -1
  279. package/dist/esm/DescriptionList/index.native.js.map +1 -1
  280. package/dist/esm/ErrorSummary.native.js.map +1 -1
  281. package/dist/esm/FieldDisplay/editMode.native.js.map +1 -1
  282. package/dist/esm/FieldDisplay/formatters.native.js.map +1 -1
  283. package/dist/esm/FieldDisplay/index.native.js.map +1 -1
  284. package/dist/esm/FieldGroup.native.js.map +1 -1
  285. package/dist/esm/FloatingPanel/PanelHeader.mjs +3 -8
  286. package/dist/esm/FloatingPanel/PanelHeader.mjs.map +1 -1
  287. package/dist/esm/FloatingPanel/PanelHeader.native.js +3 -8
  288. package/dist/esm/FloatingPanel/PanelHeader.native.js.map +1 -1
  289. package/dist/esm/FloatingPanel/RegularPanel.native.js.map +1 -1
  290. package/dist/esm/FloatingPanel/compactFace.native.js.map +1 -1
  291. package/dist/esm/FloatingPanel/containingBlock.native.js.map +1 -1
  292. package/dist/esm/FloatingPanel/coverRect.mjs +1 -8
  293. package/dist/esm/FloatingPanel/coverRect.mjs.map +1 -1
  294. package/dist/esm/FloatingPanel/coverRect.native.js +1 -8
  295. package/dist/esm/FloatingPanel/coverRect.native.js.map +1 -1
  296. package/dist/esm/FloatingPanel/echoContext.mjs +4 -24
  297. package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -1
  298. package/dist/esm/FloatingPanel/echoContext.native.js +4 -25
  299. package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -1
  300. package/dist/esm/FloatingPanel/index.mjs +53 -135
  301. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  302. package/dist/esm/FloatingPanel/index.native.js +30 -95
  303. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  304. package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -1
  305. package/dist/esm/FloatingPanel/paintedBox.native.js.map +1 -1
  306. package/dist/esm/FloatingPanel/panelWidth.native.js.map +1 -1
  307. package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
  308. package/dist/esm/FloatingPanel/regularPlacement.native.js.map +1 -1
  309. package/dist/esm/FloatingPanel/trailingAction.native.js.map +1 -1
  310. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  311. package/dist/esm/Form/index.native.js.map +1 -1
  312. package/dist/esm/Form/submissionController.native.js.map +1 -1
  313. package/dist/esm/Form/validateOn.native.js.map +1 -1
  314. package/dist/esm/FormGrid.native.js.map +1 -1
  315. package/dist/esm/FormSection.native.js.map +1 -1
  316. package/dist/esm/InputParts/PasswordReveal.native.js.map +1 -1
  317. package/dist/esm/InputParts/index.native.js.map +1 -1
  318. package/dist/esm/InputParts/keyboardAppearance.native.js.map +1 -1
  319. package/dist/esm/Label/index.native.js.map +1 -1
  320. package/dist/esm/MediaPicker/base64.native.js.map +1 -1
  321. package/dist/esm/MediaPicker/payload.native.js.map +1 -1
  322. package/dist/esm/MediaPicker/types.native.js.map +1 -1
  323. package/dist/esm/MediaPicker/useMediaPicker.native.js.map +1 -1
  324. package/dist/esm/Skeleton/index.native.js.map +1 -1
  325. package/dist/esm/Spinner/SpinnerGlyph.native.js.map +1 -1
  326. package/dist/esm/Spinner/spinnerSize.native.js.map +1 -1
  327. package/dist/esm/Table/index.native.js.map +1 -1
  328. package/dist/esm/Wheel/haptic.native.js.map +1 -1
  329. package/dist/esm/Wheel/index.native.js.map +1 -1
  330. package/dist/esm/Wheel/wheelShared.native.js.map +1 -1
  331. package/dist/esm/actionLabel.native.js.map +1 -1
  332. package/dist/esm/fieldDefaults.native.js.map +1 -1
  333. package/dist/esm/fieldLayout.native.js.map +1 -1
  334. package/dist/esm/fields/Barcode/BarcodePreview.native.js.map +1 -1
  335. package/dist/esm/fields/Barcode/code128.native.js.map +1 -1
  336. package/dist/esm/fields/Barcode/index.native.js.map +1 -1
  337. package/dist/esm/fields/Barcode/qr.native.js.map +1 -1
  338. package/dist/esm/fields/Barcode/scannerTypes.native.js.map +1 -1
  339. package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
  340. package/dist/esm/fields/Checkbox/CheckboxBox.native.js.map +1 -1
  341. package/dist/esm/fields/Checkbox/CheckboxCard.native.js.map +1 -1
  342. package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
  343. package/dist/esm/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
  344. package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
  345. package/dist/esm/fields/Checkbox/index.native.js.map +1 -1
  346. package/dist/esm/fields/ColorPicker/SystemColorField.native.js.map +1 -1
  347. package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
  348. package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
  349. package/dist/esm/fields/ColorPicker/systemColorWell.gnome.native.js.map +1 -1
  350. package/dist/esm/fields/Combobox/authorOptions.native.js.map +1 -1
  351. package/dist/esm/fields/Combobox/index.mjs +4 -11
  352. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  353. package/dist/esm/fields/Combobox/index.native.js +4 -11
  354. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  355. package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
  356. package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
  357. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  358. package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
  359. package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
  360. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
  361. package/dist/esm/fields/DatePicker/fieldValueSync.native.js.map +1 -1
  362. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  363. package/dist/esm/fields/DatePicker/utils.native.js.map +1 -1
  364. package/dist/esm/fields/Duration/durationMath.native.js.map +1 -1
  365. package/dist/esm/fields/Duration/durationWheelTypes.native.js.map +1 -1
  366. package/dist/esm/fields/Duration/index.native.js.map +1 -1
  367. package/dist/esm/fields/FileUpload/filePickerTypes.native.js.map +1 -1
  368. package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
  369. package/dist/esm/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
  370. package/dist/esm/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
  371. package/dist/esm/fields/Geolocation/geoValue.native.js.map +1 -1
  372. package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -1
  373. package/dist/esm/fields/Geolocation/geocoderContext.native.js.map +1 -1
  374. package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
  375. package/dist/esm/fields/Geolocation/mapMath.native.js.map +1 -1
  376. package/dist/esm/fields/Geolocation/mapTypes.native.js.map +1 -1
  377. package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
  378. package/dist/esm/fields/Geolocation/photonGeocoder.native.js.map +1 -1
  379. package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
  380. package/dist/esm/fields/Icon/index.native.js.map +1 -1
  381. package/dist/esm/fields/ImageField/index.native.js.map +1 -1
  382. package/dist/esm/fields/Input/index.native.js.map +1 -1
  383. package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
  384. package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
  385. package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
  386. package/dist/esm/fields/PhoneInput/dialCodes.native.js.map +1 -1
  387. package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
  388. package/dist/esm/fields/PhoneInput/phone.native.js.map +1 -1
  389. package/dist/esm/fields/PhoneInput/regionNames.native.js.map +1 -1
  390. package/dist/esm/fields/Progress/index.native.js.map +1 -1
  391. package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
  392. package/dist/esm/fields/Rating/index.native.js.map +1 -1
  393. package/dist/esm/fields/Rating/ratingMath.native.js.map +1 -1
  394. package/dist/esm/fields/Rating/types.native.js.map +1 -1
  395. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  396. package/dist/esm/fields/Select/InlineChoices.mjs +2 -6
  397. package/dist/esm/fields/Select/InlineChoices.mjs.map +1 -1
  398. package/dist/esm/fields/Select/InlineChoices.native.js +2 -6
  399. package/dist/esm/fields/Select/InlineChoices.native.js.map +1 -1
  400. package/dist/esm/fields/Select/SheetPickerRow.native.js.map +1 -1
  401. package/dist/esm/fields/Select/index.mjs +49 -202
  402. package/dist/esm/fields/Select/index.mjs.map +1 -1
  403. package/dist/esm/fields/Select/index.native.js +55 -210
  404. package/dist/esm/fields/Select/index.native.js.map +1 -1
  405. package/dist/esm/fields/Select/shouldInlineChoices.native.js.map +1 -1
  406. package/dist/esm/fields/Signature/index.native.js.map +1 -1
  407. package/dist/esm/fields/Slider/index.native.js.map +1 -1
  408. package/dist/esm/fields/Slider/jumpMotion.native.js.map +1 -1
  409. package/dist/esm/fields/Stepper/index.native.js.map +1 -1
  410. package/dist/esm/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
  411. package/dist/esm/fields/Switch/footprint.native.js.map +1 -1
  412. package/dist/esm/fields/Switch/index.native.js.map +1 -1
  413. package/dist/esm/fields/TextArea/index.native.js.map +1 -1
  414. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  415. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  416. package/dist/esm/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
  417. package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
  418. package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
  419. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
  420. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  421. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
  422. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  423. package/dist/esm/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
  424. package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
  425. package/dist/esm/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
  426. package/dist/esm/fields/nativeSelect.native.js.map +1 -1
  427. package/dist/esm/fields/selectedOrder.native.js.map +1 -1
  428. package/dist/esm/formSpacing.native.js.map +1 -1
  429. package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
  430. package/dist/esm/index.mjs +3 -1
  431. package/dist/esm/index.mjs.map +1 -1
  432. package/dist/esm/index.native.js +3 -1
  433. package/dist/esm/index.native.js.map +1 -1
  434. package/dist/esm/keyboard/chain.native.js.map +1 -1
  435. package/dist/esm/keyboard/index.native.js.map +1 -1
  436. package/dist/esm/keyboard/types.native.js.map +1 -1
  437. package/dist/esm/requiredMarking.native.js.map +1 -1
  438. package/dist/esm/shared/CheckGlyph.mjs +15 -0
  439. package/dist/esm/shared/CheckGlyph.mjs.map +1 -0
  440. package/dist/esm/shared/CheckGlyph.native.js +16 -0
  441. package/dist/esm/shared/CheckGlyph.native.js.map +1 -0
  442. package/dist/esm/shared/TimeColumn.native.js.map +1 -1
  443. package/dist/esm/shared/capabilityPreflight.native.js.map +1 -1
  444. package/dist/esm/shared/choiceRowPress.native.js.map +1 -1
  445. package/dist/esm/shared/colorRamps.native.js.map +1 -1
  446. package/dist/esm/shared/devWarn.native.js.map +1 -1
  447. package/dist/esm/shared/fieldRowContext.native.js.map +1 -1
  448. package/dist/esm/shared/floatingList.mjs +80 -4
  449. package/dist/esm/shared/floatingList.mjs.map +1 -1
  450. package/dist/esm/shared/floatingList.native.js +93 -6
  451. package/dist/esm/shared/floatingList.native.js.map +1 -1
  452. package/dist/esm/shared/focusManagement.native.js.map +1 -1
  453. package/dist/esm/shared/groupContext.native.js.map +1 -1
  454. package/dist/esm/shared/i18n.native.js.map +1 -1
  455. package/dist/esm/shared/instantMotion.native.js.map +1 -1
  456. package/dist/esm/shared/nativeA11y.native.js.map +1 -1
  457. package/dist/esm/shared/nativeAutoFocus.native.js.map +1 -1
  458. package/dist/esm/shared/overlaySizeClass.native.js.map +1 -1
  459. package/dist/esm/shared/overlayStack.native.js.map +1 -1
  460. package/dist/esm/shared/panelPortal.native.js.map +1 -1
  461. package/dist/esm/shared/pickerTriggerContract.native.js.map +1 -1
  462. package/dist/esm/shared/pressSlopProps.native.js.map +1 -1
  463. package/dist/esm/shared/restoreRetries.native.js.map +1 -1
  464. package/dist/esm/shared/sheetNavigation.native.js.map +1 -1
  465. package/dist/esm/shared/systemControlModules.gnome.native.js.map +1 -1
  466. package/dist/esm/shared/systemControls.native.js.map +1 -1
  467. package/dist/esm/shared/t.native.js.map +1 -1
  468. package/dist/esm/shared/tableCellContext.native.js.map +1 -1
  469. package/dist/esm/shared/useDragScroll.native.js.map +1 -1
  470. package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
  471. package/dist/esm/shared/useSheetEscapeDismiss.native.js.map +1 -1
  472. package/dist/esm/shared/useWheelIncrement.native.js.map +1 -1
  473. package/dist/esm/shared/utils.native.js.map +1 -1
  474. package/dist/esm/shared/zIndex.native.js.map +1 -1
  475. package/dist/esm/standardActions.native.js.map +1 -1
  476. package/dist/esm/themedPrimitives.native.js.map +1 -1
  477. package/dist/esm/types.native.js.map +1 -1
  478. package/dist/esm/utils/LinkCell.native.js.map +1 -1
  479. package/dist/jsx/AdaptivePopup/index.mjs +2 -2
  480. package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
  481. package/dist/jsx/AdaptivePopup/index.native.js +1 -1
  482. package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
  483. package/dist/jsx/Button/glass.mjs +1 -2
  484. package/dist/jsx/Button/glass.mjs.map +1 -1
  485. package/dist/jsx/Button/index.mjs +12 -5
  486. package/dist/jsx/Button/index.mjs.map +1 -1
  487. package/dist/jsx/Button/index.native.js +14 -6
  488. package/dist/jsx/Button/index.native.js.map +1 -1
  489. package/dist/jsx/Button/webGlass.mjs.map +1 -1
  490. package/dist/jsx/Button/webGlass.native.js.map +1 -1
  491. package/dist/jsx/FloatingPanel/PanelHeader.mjs +3 -8
  492. package/dist/jsx/FloatingPanel/PanelHeader.mjs.map +1 -1
  493. package/dist/jsx/FloatingPanel/PanelHeader.native.js +3 -8
  494. package/dist/jsx/FloatingPanel/PanelHeader.native.js.map +1 -1
  495. package/dist/jsx/FloatingPanel/coverRect.mjs +1 -8
  496. package/dist/jsx/FloatingPanel/coverRect.mjs.map +1 -1
  497. package/dist/jsx/FloatingPanel/coverRect.native.js +0 -8
  498. package/dist/jsx/FloatingPanel/coverRect.native.js.map +1 -1
  499. package/dist/jsx/FloatingPanel/echoContext.mjs +4 -24
  500. package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -1
  501. package/dist/jsx/FloatingPanel/echoContext.native.js +5 -28
  502. package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -1
  503. package/dist/jsx/FloatingPanel/index.mjs +53 -135
  504. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  505. package/dist/jsx/FloatingPanel/index.native.js +26 -91
  506. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  507. package/dist/jsx/fields/Combobox/index.mjs +4 -11
  508. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  509. package/dist/jsx/fields/Combobox/index.native.js +3 -10
  510. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  511. package/dist/jsx/fields/Select/InlineChoices.mjs +2 -6
  512. package/dist/jsx/fields/Select/InlineChoices.mjs.map +1 -1
  513. package/dist/jsx/fields/Select/InlineChoices.native.js +4 -8
  514. package/dist/jsx/fields/Select/InlineChoices.native.js.map +1 -1
  515. package/dist/jsx/fields/Select/index.mjs +49 -202
  516. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  517. package/dist/jsx/fields/Select/index.native.js +52 -207
  518. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  519. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
  520. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  521. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
  522. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  523. package/dist/jsx/index.js +3 -1
  524. package/dist/jsx/index.js.map +1 -1
  525. package/dist/jsx/index.mjs +3 -1
  526. package/dist/jsx/index.mjs.map +1 -1
  527. package/dist/jsx/index.native.js +4 -0
  528. package/dist/jsx/index.native.js.map +1 -1
  529. package/dist/jsx/shared/CheckGlyph.mjs +15 -0
  530. package/dist/jsx/shared/CheckGlyph.mjs.map +1 -0
  531. package/dist/jsx/shared/CheckGlyph.native.js +44 -0
  532. package/dist/jsx/shared/CheckGlyph.native.js.map +1 -0
  533. package/dist/jsx/shared/floatingList.mjs +80 -4
  534. package/dist/jsx/shared/floatingList.mjs.map +1 -1
  535. package/dist/jsx/shared/floatingList.native.js +95 -5
  536. package/dist/jsx/shared/floatingList.native.js.map +1 -1
  537. package/package.json +8 -8
  538. package/src/AdaptivePopup/index.tsx +2 -2
  539. package/src/Button/Button.glassPress.spec.tsx +117 -0
  540. package/src/Button/Button.iconButton.spec.tsx +39 -0
  541. package/src/Button/IconButtonGroup.spec.tsx +1 -1
  542. package/src/Button/glass.spec.ts +48 -18
  543. package/src/Button/glass.ts +5 -12
  544. package/src/Button/index.tsx +22 -10
  545. package/src/Button/webGlass.ts +5 -4
  546. package/src/FloatingPanel/FloatingPanel.iconCover.spec.tsx +279 -0
  547. package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +78 -69
  548. package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +12 -0
  549. package/src/FloatingPanel/PanelHeader.tsx +4 -12
  550. package/src/FloatingPanel/coverRect.ts +2 -15
  551. package/src/FloatingPanel/echoContext.ts +6 -40
  552. package/src/FloatingPanel/index.native.tsx +36 -145
  553. package/src/FloatingPanel/index.tsx +61 -187
  554. package/src/FloatingPanel/pointAnchor.spec.ts +1 -1
  555. package/src/FloatingPanel/pointAnchor.ts +4 -4
  556. package/src/fields/Combobox/index.tsx +4 -9
  557. package/src/fields/Select/InlineChoices.tsx +2 -2
  558. package/src/fields/Select/Select.containingBlock.spec.tsx +131 -130
  559. package/src/fields/Select/Select.stories.tsx +10 -0
  560. package/src/fields/Select/index.tsx +66 -253
  561. package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +3 -3
  562. package/src/index.ts +2 -1
  563. package/src/shared/CheckGlyph.tsx +12 -0
  564. package/src/shared/floatingList.spec.tsx +154 -1
  565. package/src/shared/floatingList.tsx +125 -8
  566. package/types/Button/glass.d.ts +4 -3
  567. package/types/Button/glass.d.ts.map +1 -1
  568. package/types/Button/index.d.ts.map +1 -1
  569. package/types/Button/webGlass.d.ts +5 -4
  570. package/types/Button/webGlass.d.ts.map +1 -1
  571. package/types/FloatingPanel/PanelHeader.d.ts +1 -6
  572. package/types/FloatingPanel/PanelHeader.d.ts.map +1 -1
  573. package/types/FloatingPanel/coverRect.d.ts +2 -11
  574. package/types/FloatingPanel/coverRect.d.ts.map +1 -1
  575. package/types/FloatingPanel/echoContext.d.ts +5 -22
  576. package/types/FloatingPanel/echoContext.d.ts.map +1 -1
  577. package/types/FloatingPanel/index.d.ts +6 -8
  578. package/types/FloatingPanel/index.d.ts.map +1 -1
  579. package/types/FloatingPanel/index.native.d.ts +1 -1
  580. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  581. package/types/FloatingPanel/pointAnchor.d.ts +4 -4
  582. package/types/fields/Combobox/index.d.ts.map +1 -1
  583. package/types/fields/Select/index.d.ts.map +1 -1
  584. package/types/index.d.ts +2 -1
  585. package/types/index.d.ts.map +1 -1
  586. package/types/shared/CheckGlyph.d.ts +10 -0
  587. package/types/shared/CheckGlyph.d.ts.map +1 -0
  588. package/types/shared/floatingList.d.ts +55 -1
  589. package/types/shared/floatingList.d.ts.map +1 -1
  590. package/dist/cjs/FloatingPanel/iconEcho.cjs +0 -106
  591. package/dist/cjs/FloatingPanel/iconEcho.native.js +0 -116
  592. package/dist/cjs/FloatingPanel/iconEcho.native.js.map +0 -1
  593. package/dist/esm/FloatingPanel/iconEcho.mjs +0 -79
  594. package/dist/esm/FloatingPanel/iconEcho.mjs.map +0 -1
  595. package/dist/esm/FloatingPanel/iconEcho.native.js +0 -86
  596. package/dist/esm/FloatingPanel/iconEcho.native.js.map +0 -1
  597. package/dist/jsx/FloatingPanel/iconEcho.mjs +0 -79
  598. package/dist/jsx/FloatingPanel/iconEcho.mjs.map +0 -1
  599. package/dist/jsx/FloatingPanel/iconEcho.native.js +0 -116
  600. package/dist/jsx/FloatingPanel/iconEcho.native.js.map +0 -1
  601. package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +0 -357
  602. package/src/FloatingPanel/iconEcho.tsx +0 -124
  603. package/types/FloatingPanel/iconEcho.d.ts +0 -29
  604. package/types/FloatingPanel/iconEcho.d.ts.map +0 -1
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @vitest-environment jsdom
3
+ *
4
+ * LC-176 (FZ-8666): on native iOS a bar button's press is the system's. Clay
5
+ * on rv_c6369c2bab2ffea0: "Like actually use liquid glass it should have the
6
+ * same animated you know when you push it resizes like don't try to
7
+ * re-implement that let the native API do it." The glass is interactive and
8
+ * holds the glyph, and MPO layers no press fade, scale or resize on it. A bar
9
+ * glyph with no glass keeps MPO's press dim, which proves the instrument.
10
+ */
11
+
12
+ import { createDefaultThemeConfig, Surface } from "@multiplatform.one/theme";
13
+ import { cleanup, render, screen } from "@testing-library/react";
14
+ import type { ReactElement } from "react";
15
+ import { TamaguiProvider } from "tamagui";
16
+ import { afterEach, describe, expect, it, vi } from "vitest";
17
+ import { IconButton, IconButtonGroup } from "./index";
18
+
19
+ const platform = vi.hoisted(() => ({ web: false }));
20
+ vi.mock("tamagui", async (importOriginal) => ({
21
+ ...(await importOriginal<typeof import("tamagui")>()),
22
+ get isWeb() {
23
+ return platform.web;
24
+ },
25
+ }));
26
+
27
+ const glass = vi.hoisted(() => ({ available: true }));
28
+ vi.mock("./glass", () => {
29
+ function FakeGlassView({
30
+ glassEffectStyle,
31
+ isInteractive,
32
+ colorScheme: _colorScheme,
33
+ children,
34
+ ...props
35
+ }: Record<string, unknown>) {
36
+ return (
37
+ <div
38
+ data-glass=""
39
+ data-effect={glassEffectStyle as string}
40
+ data-interactive={String(isInteractive)}
41
+ {...props}
42
+ >
43
+ {children as never}
44
+ </div>
45
+ );
46
+ }
47
+ function FakeGlassContainer({ children }: { children?: unknown }) {
48
+ return <div data-glass-container="">{children as never}</div>;
49
+ }
50
+ return {
51
+ loadGlassView: () => (glass.available ? FakeGlassView : null),
52
+ loadGlassContainer: () => (glass.available ? FakeGlassContainer : null),
53
+ };
54
+ });
55
+
56
+ afterEach(() => {
57
+ cleanup();
58
+ glass.available = true;
59
+ });
60
+
61
+ const houseConfig = createDefaultThemeConfig();
62
+
63
+ /** A press class that fades, scales or resizes the button. */
64
+ const PRESS_MOTION = /^_(o|opacity|transform|scale|w|width|h|height)-0active-/;
65
+
66
+ function Glyph({ size }: { size?: number }) {
67
+ return <svg data-glyph="" width={size} height={size} />;
68
+ }
69
+
70
+ function barRender(ui: ReactElement) {
71
+ return render(
72
+ <TamaguiProvider config={houseConfig.tamagui} defaultTheme="light" disableInjectCSS>
73
+ <Surface bar>{ui}</Surface>
74
+ </TamaguiProvider>,
75
+ );
76
+ }
77
+
78
+ function pressMotion(el: Element): string[] {
79
+ return Array.from(el.classList).filter((c) => PRESS_MOTION.test(c));
80
+ }
81
+
82
+ describe("LC-176: native glass answers its own press (FZ-8666)", () => {
83
+ it("a lone bar button sits in interactive glass with no MPO press motion", () => {
84
+ barRender(<IconButton icon={Glyph} aria-label="Search" />);
85
+ const button = screen.getByLabelText("Search");
86
+ expect(button.getAttribute("data-mp-icon-button")).toBe("glass");
87
+ const glassView = button.querySelector("[data-glass]")!;
88
+ expect(glassView.getAttribute("data-interactive")).toBe("true");
89
+ expect(glassView.querySelector("[data-glyph]")).not.toBeNull();
90
+ expect(pressMotion(button)).toEqual([]);
91
+ });
92
+
93
+ it("a bar group's buttons sit in one interactive capsule with no MPO press motion", () => {
94
+ barRender(
95
+ <IconButtonGroup>
96
+ <IconButton icon={Glyph} aria-label="Archive" />
97
+ <IconButton icon={Glyph} aria-label="Delete" />
98
+ </IconButtonGroup>,
99
+ );
100
+ const capsule = document.querySelector("[data-glass-container] [data-glass]")!;
101
+ expect(capsule.getAttribute("data-effect")).toBe("regular");
102
+ expect(capsule.getAttribute("data-interactive")).toBe("true");
103
+ for (const name of ["Archive", "Delete"]) {
104
+ const button = screen.getByLabelText(name);
105
+ expect(capsule.contains(button)).toBe(true);
106
+ expect(pressMotion(button)).toEqual([]);
107
+ }
108
+ });
109
+
110
+ it("without the glass module the bar glyph keeps MPO's press dim", () => {
111
+ glass.available = false;
112
+ barRender(<IconButton icon={Glyph} aria-label="Search" />);
113
+ const button = screen.getByLabelText("Search");
114
+ expect(button.getAttribute("data-mp-icon-button")).not.toBe("glass");
115
+ expect(pressMotion(button).some((c) => /^_(o|opacity)-0active-/.test(c))).toBe(true);
116
+ });
117
+ });
@@ -112,6 +112,45 @@ function rest(el: Element, prefix: string): string[] {
112
112
  .sort();
113
113
  }
114
114
 
115
+ describe("LC-176: one ink on a bold glyph (FZ-8649)", () => {
116
+ function Inked({ color, stroke }: { color?: string; stroke?: string }) {
117
+ return <svg data-glyph="" data-color={color} data-stroke={stroke} />;
118
+ }
119
+
120
+ it.each(SCHEMES)("%s: a bar glyph takes the bar tint on its fill and its stroke", (scheme) => {
121
+ houseRender(
122
+ <Surface bar>
123
+ <Button chromeless icon={Inked} aria-label="Menu" />
124
+ <Button chromeless icon={<Inked />} aria-label="Bell" />
125
+ </Surface>,
126
+ scheme,
127
+ );
128
+ for (const label of ["Menu", "Bell"]) {
129
+ const ink = glyphOf(label).getAttribute("data-color");
130
+ expect(ink).toBeTruthy();
131
+ expect(ink).not.toBe("currentColor");
132
+ expect(glyphOf(label).getAttribute("data-stroke")).toBe(ink);
133
+ }
134
+ });
135
+
136
+ it("a caller's colour stays on the fill and the stroke", () => {
137
+ houseRender(
138
+ <Surface bar>
139
+ <Button chromeless icon={<Inked color="red" />} aria-label="Bell" />
140
+ </Surface>,
141
+ "light",
142
+ );
143
+ expect(glyphOf("Bell").getAttribute("data-color")).toBe("red");
144
+ expect(glyphOf("Bell").getAttribute("data-stroke")).toBe("red");
145
+ });
146
+
147
+ it("a content glyph has no bar tint to pass, so it keeps currentColor", () => {
148
+ houseRender(<Button icon={Inked} aria-label="More" />, "light");
149
+ expect(glyphOf("More").hasAttribute("data-color")).toBe(false);
150
+ expect(glyphOf("More").getAttribute("data-stroke")).toBe("currentColor");
151
+ });
152
+ });
153
+
115
154
  describe("LC-176: an icon-only Button is a bare glyph", () => {
116
155
  it.each(SCHEMES)("%s: in a bar, no fill and no border at rest, the bar tint as ink", (scheme) => {
117
156
  houseRender(
@@ -76,7 +76,7 @@ function houseRender(ui: ReactElement) {
76
76
  }
77
77
 
78
78
  describe("LC-176: IconButtonGroup", () => {
79
- it("with the web face switched on, iOS Safari's bar group is one capsule behind bare glyphs", () => {
79
+ it("iOS Safari's bar group is one capsule behind bare glyphs", () => {
80
80
  vi.stubGlobal("navigator", { userAgent: IPHONE, platform: "iPhone", maxTouchPoints: 5 });
81
81
  glass.available = true;
82
82
  houseRender(
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * @vitest-environment jsdom
3
3
  *
4
- * LC-176 / LC-266 (FZ-8666): no browser can draw Liquid Glass, so no browser
5
- * draws glass, iOS Safari included. The drawn face stays behind one switch in
6
- * `glass.ts` until Clay answers the compare.
4
+ * LC-176 / LC-266 (FZ-8666): iOS Safari keeps the drawn glass face (Clay's
5
+ * pick A on rv_c6369c2bab2ffea0); every other browser draws plain glyphs.
7
6
  */
8
7
 
9
8
  import { createDefaultThemeConfig, Surface } from "@multiplatform.one/theme";
@@ -20,6 +19,8 @@ const IPHONE =
20
19
  const MAC_SAFARI =
21
20
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15";
22
21
  const houseConfig = createDefaultThemeConfig();
22
+ /** A press class that fades, scales or resizes the button. */
23
+ const PRESS_MOTION = /^_(o|opacity|transform|scale|w|width|h|height)-0active-/;
23
24
  const PIXEL =
24
25
  "Mozilla/5.0 (Linux; Android 15; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Mobile Safari/537.36";
25
26
 
@@ -61,7 +62,23 @@ function renderBar(ui: ReturnType<typeof createElement>) {
61
62
  );
62
63
  }
63
64
 
64
- describe("no glass on the web (LC-176)", () => {
65
+ function renderBarRow() {
66
+ renderBar(
67
+ createElement(
68
+ "div",
69
+ null,
70
+ createElement(
71
+ IconButtonGroup,
72
+ null,
73
+ createElement(IconButton, { icon: Glyph, "aria-label": "Search" }),
74
+ createElement(IconButton, { icon: Glyph, "aria-label": "More" }),
75
+ ),
76
+ createElement(IconButton, { icon: Glyph, "aria-label": "Back" }),
77
+ ),
78
+ );
79
+ }
80
+
81
+ describe("glass on the web (LC-176)", () => {
65
82
  afterEach(() => {
66
83
  cleanup();
67
84
  vi.unstubAllGlobals();
@@ -70,25 +87,38 @@ describe("no glass on the web (LC-176)", () => {
70
87
  it.each([
71
88
  ["iOS Safari", { userAgent: IPHONE, platform: "iPhone", maxTouchPoints: 5 }],
72
89
  ["iPadOS Safari", { userAgent: MAC_SAFARI, platform: "MacIntel", maxTouchPoints: 5 }],
90
+ ])(
91
+ "%s draws the glass face: one capsule for a bar group, a circle for a lone button",
92
+ (_browser, nav) => {
93
+ vi.stubGlobal("navigator", nav);
94
+ expect(loadGlassView()).toBe(WebGlassFace);
95
+ expect(loadGlassContainer()).toBeNull();
96
+ renderBarRow();
97
+ const capsule = document.querySelector("[data-mp-glass-capsule]");
98
+ expect(capsule).not.toBeNull();
99
+ expect(capsule!.querySelectorAll('[data-mp-glass="web"]')).toHaveLength(1);
100
+ expect(document.querySelectorAll('[data-mp-glass="web"]')).toHaveLength(2);
101
+ for (const name of ["Search", "More"])
102
+ expect(screen.getByLabelText(name).getAttribute("data-mp-icon-button")).not.toBe("glass");
103
+ const back = screen.getByLabelText("Back");
104
+ expect(back.getAttribute("data-mp-icon-button")).toBe("glass");
105
+ expect(back.querySelector('[data-mp-glass="web"]')).not.toBeNull();
106
+ // WebKit gives web content no system press: the face takes the web press
107
+ // plate, and nothing resizes or fades it.
108
+ const pressed = Array.from(back.classList).filter((c) => c.includes("0active-"));
109
+ expect(pressed.some((c) => c.startsWith("_bg-0active-"))).toBe(true);
110
+ expect(pressed.filter((c) => PRESS_MOTION.test(c))).toEqual([]);
111
+ },
112
+ );
113
+
114
+ it.each([
73
115
  ["desktop Safari", { userAgent: MAC_SAFARI, platform: "MacIntel", maxTouchPoints: 0 }],
74
116
  ["Android Chrome", { userAgent: PIXEL, platform: "Linux armv8l", maxTouchPoints: 5 }],
75
117
  ])("%s loads no glass and draws the plain glyph", (_browser, nav) => {
76
118
  vi.stubGlobal("navigator", nav);
77
119
  expect(loadGlassView()).toBeNull();
78
120
  expect(loadGlassContainer()).toBeNull();
79
- renderBar(
80
- createElement(
81
- "div",
82
- null,
83
- createElement(
84
- IconButtonGroup,
85
- null,
86
- createElement(IconButton, { icon: Glyph, "aria-label": "Search" }),
87
- createElement(IconButton, { icon: Glyph, "aria-label": "More" }),
88
- ),
89
- createElement(IconButton, { icon: Glyph, "aria-label": "Back" }),
90
- ),
91
- );
121
+ renderBarRow();
92
122
  expect(document.querySelector("[data-mp-glass]")).toBeNull();
93
123
  expect(document.querySelector("[data-mp-glass-capsule]")).toBeNull();
94
124
  expect(document.querySelector('[data-mp-icon-button-group="bar"]')).not.toBeNull();
@@ -97,7 +127,7 @@ describe("no glass on the web (LC-176)", () => {
97
127
  });
98
128
  });
99
129
 
100
- describe("the drawn web face behind the switch", () => {
130
+ describe("the drawn web face", () => {
101
131
  afterEach(cleanup);
102
132
 
103
133
  it("sits under the glyph it backs, which stays its sibling", () => {
@@ -20,20 +20,13 @@ export type GlassContainerComponent = ComponentType<{
20
20
  export { isAppleTouchWeb } from "./webGlass";
21
21
 
22
22
  /**
23
- * LC-176 (FZ-8666): iOS Safari cannot draw Liquid Glass, so it draws no glass.
24
- * This is the one switch for the drawn face Clay asked for on
25
- * rv_3bb3f1f65d6b981f, off since his note on rv_d481d34557e702ef, until he
26
- * answers rv_c6369c2bab2ffea0.
27
- */
28
- const iosSafariGlassFace = false;
29
-
30
- /**
31
- * LC-176: the system Liquid Glass an icon button sits in on a bar. Only native
32
- * iOS 26 has it, from expo-glass-effect (`glass.native.ts`; Android probes
33
- * null), so the web draws the plain glyph.
23
+ * LC-176: the Liquid Glass an icon button sits in on a bar. Native iOS 26 has
24
+ * the system's, from expo-glass-effect (`glass.native.ts`; Android probes
25
+ * null). On the web only iOS Safari takes the drawn glass face (Clay's pick A
26
+ * on rv_c6369c2bab2ffea0, FZ-8666); every other browser draws the plain glyph.
34
27
  */
35
28
  export function loadGlassView(): GlassViewComponent | null {
36
- return iosSafariGlassFace && isAppleTouchWeb() ? (WebGlassFace as GlassViewComponent) : null;
29
+ return isAppleTouchWeb() ? (WebGlassFace as GlassViewComponent) : null;
37
30
  }
38
31
 
39
32
  /** LC-176: the system's Liquid Glass container. Only iOS has it. */
@@ -465,28 +465,40 @@ export function iconButtonGlyphPx(rowLinePx: number | undefined): number {
465
465
  /** LC-176: an inline glyph is the text's size; Phosphor's 256 grid pads ~12%. */
466
466
  const INLINE_GLYPH_RATIO = 1.2;
467
467
 
468
+ /**
469
+ * `ink` is the bar tint. It goes to the glyph as well as to its stroke, because
470
+ * a `themed` glyph fills with the theme's text colour unless told otherwise and
471
+ * the stroke would then outline it in a second colour (FZ-8649).
472
+ */
468
473
  function withGlyphWeight(
469
474
  icon: IconLike | undefined,
470
475
  size: number,
471
476
  weight: "regular" | "bold",
472
477
  floor = false,
478
+ ink?: string | null,
473
479
  ): IconLike | undefined {
474
480
  if (icon == null || icon === false) return icon;
481
+ const tint = ink ?? undefined;
475
482
  if (isValidElement<{ size?: number; weight?: string; color?: string }>(icon)) {
476
483
  const resolved = (icon.props.weight ?? weight) as "regular" | "bold";
477
484
  const own = icon.props.size;
478
485
  return cloneElement(icon, {
479
486
  ...(own == null || (floor && typeof own === "number" && own < size) ? { size } : undefined),
480
487
  ...(icon.props.weight == null ? { weight } : undefined),
481
- ...boldStroke(resolved, icon.props.color),
488
+ ...(icon.props.color == null && tint ? { color: tint } : undefined),
489
+ ...boldStroke(resolved, icon.props.color ?? tint),
482
490
  });
483
491
  }
484
492
  if (typeof icon === "function" || (typeof icon === "object" && "$$typeof" in icon)) {
485
- return createElement(icon as ComponentType<{ size?: number; weight?: string }>, {
486
- size,
487
- weight,
488
- ...boldStroke(weight),
489
- });
493
+ return createElement(
494
+ icon as ComponentType<{ size?: number; weight?: string; color?: string }>,
495
+ {
496
+ size,
497
+ weight,
498
+ ...(tint ? { color: tint } : undefined),
499
+ ...boldStroke(weight, tint),
500
+ },
501
+ );
490
502
  }
491
503
  return icon;
492
504
  }
@@ -850,8 +862,8 @@ export function Button({
850
862
  const labelLine = labelLinePx(knobProps.body.fontFamily);
851
863
  const glyphFloor = iconButtonGlyphPx(labelLine);
852
864
  // LC-176: on iOS 26 a bar's icon button sits in system Liquid Glass, the
853
- // native bar button. Elsewhere, and on a binary without the module, it stays
854
- // the bare tinted glyph; nothing re-creates the glass (FZ-8666).
865
+ // native bar button, and iOS Safari draws its web face. Elsewhere, and on a
866
+ // binary without the module, it stays the bare tinted glyph (FZ-8666).
855
867
  const glassGroup = groupGround === "glass";
856
868
  const GlassView =
857
869
  iconButton && !inlineGlyph && !nested && accentInk && barSurface && !selectedFill && !glassGroup
@@ -911,7 +923,7 @@ export function Button({
911
923
  const barGlyphFloor = barGlyph && !framedCircle && !inlineGlyph && !nested;
912
924
  const glyph =
913
925
  barGlyph || inlineGlyph || framedCircle
914
- ? withGlyphWeight(icon, iconSize, resolvedGlyphWeight, barGlyphFloor)
926
+ ? withGlyphWeight(icon, iconSize, resolvedGlyphWeight, barGlyphFloor, barInk)
915
927
  : icon;
916
928
 
917
929
  // LC-158: the frame keeps its recipe height under Dynamic Type, so the
@@ -998,7 +1010,7 @@ export function Button({
998
1010
  ) : null;
999
1011
  const glyphAfter =
1000
1012
  iconAfter && (barGlyph || inlineGlyph || framedCircle)
1001
- ? withGlyphWeight(iconAfter, iconSize, resolvedGlyphWeight, barGlyphFloor)
1013
+ ? withGlyphWeight(iconAfter, iconSize, resolvedGlyphWeight, barGlyphFloor, barInk)
1002
1014
  : iconAfter;
1003
1015
  const iconAfterElement = glyphAfter ? (
1004
1016
  <View flexShrink={0}>
@@ -24,10 +24,11 @@ const webGlassBlur = {
24
24
  } as const;
25
25
 
26
26
  /**
27
- * LC-176: the drawn face `loadGlassView` can give iOS Safari, one circle for a
28
- * lone button or one capsule for an `IconButtonGroup`. Off by default: the
29
- * compare in `glass.ts` decides whether it stays. Its children stay siblings
30
- * above the layer (absolute, z -1 in the button's stacking context).
27
+ * LC-176: the drawn face `loadGlassView` gives iOS Safari, one circle for a
28
+ * lone button or one capsule for an `IconButtonGroup`. WebKit gives web content
29
+ * no system glass and no system press, so it takes the web press plate and
30
+ * nothing animates its size. Its children stay siblings above the layer
31
+ * (absolute, z -1 in the button's stacking context).
31
32
  */
32
33
  export function WebGlassFace({ style, children }: { style?: unknown; children?: ReactNode }) {
33
34
  const dark = isDarkThemeName(useThemeName());
@@ -0,0 +1,279 @@
1
+ /**
2
+ * LC-112 icon trigger cover (FZ-8665 Round 45, reversing Round 37's X): a
3
+ * panel that covers the icon button it opened from sits exactly over the
4
+ * surface that button is seen on and repeats nothing. Its content starts at
5
+ * its top edge, a press outside closes it, and Escape closes it on the web.
6
+ */
7
+ import { PlusIcon } from "@phosphor-icons/react";
8
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
9
+ import { fireEvent, waitFor, within } from "@testing-library/react";
10
+ import { useState } from "react";
11
+ import { MIN_PRESS_TARGET } from "@multiplatform.one/theme";
12
+ import { afterEach, describe, expect, it, vi } from "vitest";
13
+ import { Text, XStack } from "tamagui";
14
+ import { Button } from "../Button";
15
+ import { FloatingPanel } from "./index";
16
+ import { PanelHeader } from "./PanelHeader";
17
+
18
+ type Rect = { x: number; y: number; width: number; height: number };
19
+
20
+ function measure(trigger: Rect, panelWidth = 240, panelHeight = 160, surface?: Rect) {
21
+ const original = HTMLElement.prototype.getBoundingClientRect;
22
+ const rect = {
23
+ ...trigger,
24
+ top: trigger.y,
25
+ left: trigger.x,
26
+ right: trigger.x + trigger.width,
27
+ bottom: trigger.y + trigger.height,
28
+ toJSON: () => ({}),
29
+ };
30
+ vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(
31
+ function (this: HTMLElement) {
32
+ if (this.hasAttribute("data-fp-reference")) return rect;
33
+ if (surface && this.hasAttribute("data-fp-cover-surface")) {
34
+ return {
35
+ ...surface,
36
+ top: surface.y,
37
+ left: surface.x,
38
+ right: surface.x + surface.width,
39
+ bottom: surface.y + surface.height,
40
+ toJSON: () => ({}),
41
+ };
42
+ }
43
+ return original.call(this);
44
+ },
45
+ );
46
+ vi.spyOn(HTMLElement.prototype, "offsetWidth", "get").mockImplementation(
47
+ function (this: HTMLElement) {
48
+ return this.hasAttribute("data-fp-panel") ? panelWidth : 0;
49
+ },
50
+ );
51
+ vi.spyOn(HTMLElement.prototype, "scrollHeight", "get").mockImplementation(
52
+ function (this: HTMLElement) {
53
+ return this.hasAttribute("data-fp-panel") ? panelHeight : 0;
54
+ },
55
+ );
56
+ }
57
+
58
+ function AddPanel({ header = false }: { header?: boolean }) {
59
+ const [open, setOpen] = useState(false);
60
+ return (
61
+ <FloatingPanel
62
+ open={open}
63
+ onOpenChange={setOpen}
64
+ anchorMode="cover-trigger"
65
+ compactFace="menu"
66
+ triggerEcho={false}
67
+ iconCover
68
+ coverAlign="auto"
69
+ widthMode="fit-content"
70
+ triggerSizing="content"
71
+ contentPadding="none"
72
+ trigger={<Button icon={PlusIcon} aria-label="Add node" />}
73
+ >
74
+ {header ? (
75
+ <PanelHeader>
76
+ <Text>Add a node</Text>
77
+ </PanelHeader>
78
+ ) : (
79
+ <Text>Add a node</Text>
80
+ )}
81
+ <Button>Copy</Button>
82
+ </FloatingPanel>
83
+ );
84
+ }
85
+
86
+ /** An account menu opened from a 32pt avatar: a trigger with no `icon`. */
87
+ function AvatarPanel() {
88
+ return (
89
+ <FloatingPanel
90
+ open
91
+ onOpenChange={() => {}}
92
+ anchorMode="cover-trigger"
93
+ compactFace="menu"
94
+ triggerEcho={false}
95
+ iconCover
96
+ coverAlign="auto"
97
+ widthMode="fit-content"
98
+ triggerSizing="content"
99
+ contentPadding="none"
100
+ trigger={
101
+ <span role="button" aria-label="Account">
102
+ AD
103
+ </span>
104
+ }
105
+ >
106
+ <Text>Sign out</Text>
107
+ </FloatingPanel>
108
+ );
109
+ }
110
+
111
+ async function open(result: ReturnType<typeof renderWithProviders>) {
112
+ fireEvent.click(result.getByRole("button", { name: "Add node" }), { detail: 0 });
113
+ const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
114
+ await waitFor(() => expect(panel.style.visibility).toBe("visible"));
115
+ return panel;
116
+ }
117
+
118
+ afterEach(() => {
119
+ vi.restoreAllMocks();
120
+ });
121
+
122
+ const buttonsIn = (panel: HTMLElement) =>
123
+ within(panel)
124
+ .getAllByRole("button")
125
+ .map((button) => button.textContent || button.getAttribute("aria-label"));
126
+
127
+ /** Whatever sits above the content in the panel: a hidden scroll arrow at most. */
128
+ const aboveContent = (panel: HTMLElement) => {
129
+ const children = [...panel.children] as HTMLElement[];
130
+ const content = children.findIndex((child) => child.textContent?.includes("Add a node"));
131
+ expect(content).toBeGreaterThanOrEqual(0);
132
+ return children.slice(0, content);
133
+ };
134
+
135
+ describe("LC-112 icon trigger cover on the web (FZ-8665)", () => {
136
+ const viewportWidth = () => document.documentElement.clientWidth || window.innerWidth;
137
+
138
+ it("covers the + from the button's top trailing corner and repeats nothing", async () => {
139
+ const button = { x: viewportWidth() - 16 - 44, y: 12, width: 44, height: 44 };
140
+ measure(button, 240);
141
+ const result = renderWithProviders(<AddPanel />);
142
+ const panel = await open(result);
143
+ expect(panel.style.top).toBe(`${button.y}px`);
144
+ expect(panel.style.left).toBe(`${button.x + button.width - 240}px`);
145
+ expect(within(panel).queryByRole("button", { name: "Close" })).toBeNull();
146
+ expect(within(panel).queryByRole("button", { name: "Add node" })).toBeNull();
147
+ expect(panel.querySelector("[data-fp-trigger-row]")).toBeNull();
148
+ expect(panel.querySelector("[data-fp-icon-echo]")).toBeNull();
149
+ });
150
+
151
+ it("starts the content at the panel's top edge, with no band above it", async () => {
152
+ measure({ x: 16, y: 12, width: 44, height: 44 });
153
+ const result = renderWithProviders(<AddPanel />);
154
+ const panel = await open(result);
155
+ for (const element of aboveContent(panel)) {
156
+ expect(element.textContent).toBe("");
157
+ expect(element.querySelector("button, [role='button']")).toBeNull();
158
+ expect(element.style.height).toBe("");
159
+ }
160
+ });
161
+
162
+ it("covers a grouped trigger's whole plate, with both edges, and shows none of its buttons", async () => {
163
+ const button = { x: viewportWidth() - 16 - 44, y: 12, width: 44, height: 44 };
164
+ const plate = { x: button.x - 100, y: 12, width: 144, height: 44 };
165
+ measure(button, 120, 160, plate);
166
+ const result = renderWithProviders(
167
+ <div data-fp-cover-surface="">
168
+ <Button icon={PlusIcon} aria-label="Search" />
169
+ <AddPanel />
170
+ </div>,
171
+ );
172
+ const panel = await open(result);
173
+ // The plate is wider than the menu, so the menu takes the plate's width
174
+ // and both edges.
175
+ expect(panel.style.left).toBe(`${plate.x}px`);
176
+ expect(panel.style.top).toBe(`${plate.y}px`);
177
+ expect(panel.style.minWidth).toBe(`${plate.width}px`);
178
+ expect(buttonsIn(panel)).toEqual(["Copy"]);
179
+ });
180
+
181
+ it("closes on a press outside the panel", async () => {
182
+ measure({ x: 16, y: 12, width: 44, height: 44 });
183
+ const result = renderWithProviders(<AddPanel />);
184
+ await open(result);
185
+ fireEvent.click(document.body);
186
+ await waitFor(() => expect(result.queryByTestId("floating-panel-viewport")).toBeNull());
187
+ });
188
+
189
+ it("closes on Escape and hands focus back to the button", async () => {
190
+ measure({ x: 16, y: 12, width: 44, height: 44 });
191
+ const result = renderWithProviders(<AddPanel />);
192
+ const trigger = result.getByRole("button", { name: "Add node" });
193
+ trigger.focus();
194
+ await open(result);
195
+ fireEvent.keyDown(document, { key: "Escape" });
196
+ await waitFor(() => expect(result.queryByTestId("floating-panel-viewport")).toBeNull());
197
+ await waitFor(() => expect(document.activeElement).toBe(trigger));
198
+ });
199
+
200
+ it("puts a panel's title on the panel's normal padding, keeping clear of nothing", async () => {
201
+ const button = { x: viewportWidth() - 16 - 44, y: 12, width: 44, height: 44 };
202
+ measure(button, 240);
203
+ const result = renderWithProviders(
204
+ <>
205
+ <AddPanel header />
206
+ <XStack
207
+ data-testid="normal-padding"
208
+ alignItems="center"
209
+ gap="$2"
210
+ paddingLeft="$4"
211
+ paddingRight="$4"
212
+ paddingTop="$4"
213
+ />
214
+ </>,
215
+ );
216
+ const panel = await open(result);
217
+ const header = panel.querySelector<HTMLElement>("[data-fp-panel-header]") as HTMLElement;
218
+ expect(header.className).toBe(result.getByTestId("normal-padding").className);
219
+ expect(header.style.minHeight).toBe("");
220
+ });
221
+
222
+ it("keeps a content-sized trigger on a centring row's line", async () => {
223
+ measure({ x: 16, y: 12, width: 44, height: 44 });
224
+ const centred = renderWithProviders(
225
+ <div style={{ display: "flex", flexDirection: "row", alignItems: "center", height: 60 }}>
226
+ <AddPanel />
227
+ </div>,
228
+ );
229
+ const inRow = centred.container.querySelector<HTMLElement>(
230
+ "[data-fp-reference]",
231
+ ) as HTMLElement;
232
+ await waitFor(() => expect(getComputedStyle(inRow).alignSelf).not.toBe("flex-start"));
233
+ centred.unmount();
234
+ const column = renderWithProviders(
235
+ <div style={{ display: "flex", flexDirection: "column", alignItems: "stretch" }}>
236
+ <AddPanel />
237
+ </div>,
238
+ );
239
+ const inColumn = column.container.querySelector<HTMLElement>(
240
+ "[data-fp-reference]",
241
+ ) as HTMLElement;
242
+ expect(getComputedStyle(inColumn).alignSelf).toBe("flex-start");
243
+ });
244
+
245
+ it("gives a keyboard its content and no extra stop", async () => {
246
+ measure({ x: 16, y: 12, width: 44, height: 44 });
247
+ const result = renderWithProviders(<AddPanel />);
248
+ const panel = await open(result);
249
+ expect(buttonsIn(panel)).toEqual(["Copy"]);
250
+ });
251
+
252
+ it("opens up from the button's bottom edge near the bottom, still covering it", async () => {
253
+ const button = { x: 16, y: window.innerHeight - 60, width: 44, height: 44 };
254
+ measure(button, 240, 300);
255
+ const result = renderWithProviders(<AddPanel />);
256
+ const panel = await open(result);
257
+ const frame = getComputedStyle(panel);
258
+ const borders =
259
+ (parseFloat(frame.borderTopWidth) || 0) + (parseFloat(frame.borderBottomWidth) || 0);
260
+ expect(parseFloat(panel.style.top) + 300 + borders).toBe(button.y + button.height);
261
+ expect(panel.style.left).toBe(`${button.x}px`);
262
+ expect(panel.style.transformOrigin).toBe("bottom left");
263
+ expect(result.queryByTestId("floating-panel-sheet")).toBeNull();
264
+ });
265
+
266
+ it("covers a 32pt avatar at its 44pt target, its centre on the row-icon column (FZ-8480 GAP)", async () => {
267
+ const avatar = { x: 100, y: 18, width: 32, height: 32 };
268
+ measure(avatar, 240);
269
+ const result = renderWithProviders(<AvatarPanel />);
270
+ const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
271
+ await waitFor(() => expect(panel.style.visibility).toBe("visible"));
272
+ const inset = (MIN_PRESS_TARGET - avatar.width) / 2;
273
+ expect(panel.style.left).toBe(`${avatar.x - inset}px`);
274
+ expect(panel.style.top).toBe(`${avatar.y - inset}px`);
275
+ // The avatar's centre sits half a press target in, the centre of a menu
276
+ // row's leading glyph slot.
277
+ expect(inset + avatar.width / 2).toBe(MIN_PRESS_TARGET / 2);
278
+ });
279
+ });