@multiplatform.one/forms 7.70.0 → 7.72.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 (333) hide show
  1. package/dist/cjs/Button/index.cjs +16 -0
  2. package/dist/cjs/Button/index.native.js +16 -0
  3. package/dist/cjs/Button/index.native.js.map +1 -1
  4. package/dist/cjs/FloatingPanel/echoContext.cjs +39 -0
  5. package/dist/cjs/FloatingPanel/echoContext.native.js +42 -0
  6. package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -0
  7. package/dist/cjs/FloatingPanel/index.cjs +212 -80
  8. package/dist/cjs/FloatingPanel/index.native.js +92 -17
  9. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  10. package/dist/cjs/FloatingPanel/panelWidth.cjs +92 -0
  11. package/dist/cjs/FloatingPanel/panelWidth.native.js +99 -0
  12. package/dist/cjs/FloatingPanel/panelWidth.native.js.map +1 -0
  13. package/dist/cjs/FloatingPanel/pointAnchor.cjs +15 -5
  14. package/dist/cjs/FloatingPanel/pointAnchor.native.js +15 -5
  15. package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
  16. package/dist/cjs/FloatingPanel/useFloatingPanel.cjs +58 -4
  17. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js +69 -4
  18. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  19. package/dist/cjs/InputParts/index.cjs +20 -1
  20. package/dist/cjs/InputParts/index.native.js +22 -2
  21. package/dist/cjs/InputParts/index.native.js.map +1 -1
  22. package/dist/cjs/Wheel/NativeWheel.native.js +1 -1
  23. package/dist/cjs/Wheel/NativeWheel.native.js.map +1 -1
  24. package/dist/cjs/Wheel/index.cjs +2 -1
  25. package/dist/cjs/Wheel/index.native.js +4 -1
  26. package/dist/cjs/Wheel/index.native.js.map +1 -1
  27. package/dist/cjs/Wheel/wheelShared.cjs +6 -1
  28. package/dist/cjs/Wheel/wheelShared.native.js +7 -1
  29. package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
  30. package/dist/cjs/fields/Combobox/index.cjs +1 -0
  31. package/dist/cjs/fields/Combobox/index.native.js +1 -0
  32. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  33. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +6 -30
  34. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
  35. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  36. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  37. package/dist/cjs/fields/DatePicker/catalog.cjs +2 -28
  38. package/dist/cjs/fields/DatePicker/catalog.native.js +2 -30
  39. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
  40. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  41. package/dist/cjs/fields/DatePicker/parts.cjs +11 -20
  42. package/dist/cjs/fields/DatePicker/parts.native.js +13 -22
  43. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  44. package/dist/cjs/fields/SearchInput/index.cjs +23 -1
  45. package/dist/cjs/fields/SearchInput/index.native.js +23 -1
  46. package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
  47. package/dist/cjs/fields/Select/index.cjs +65 -44
  48. package/dist/cjs/fields/Select/index.native.js +69 -47
  49. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  50. package/dist/cjs/fields/Select/shouldInlineChoices.cjs +3 -1
  51. package/dist/cjs/fields/Select/shouldInlineChoices.native.js +3 -1
  52. package/dist/cjs/fields/Select/shouldInlineChoices.native.js.map +1 -1
  53. package/dist/cjs/fields/TimePicker/catalog.cjs +4 -25
  54. package/dist/cjs/fields/TimePicker/catalog.native.js +7 -29
  55. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  56. package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
  57. package/dist/cjs/fields/TimePicker/parts.cjs +8 -21
  58. package/dist/cjs/fields/TimePicker/parts.native.js +8 -21
  59. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  60. package/dist/cjs/index.native.js.map +1 -1
  61. package/dist/cjs/shared/floatingList.cjs +13 -4
  62. package/dist/cjs/shared/floatingList.native.js +15 -4
  63. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  64. package/dist/esm/Button/index.mjs +17 -1
  65. package/dist/esm/Button/index.mjs.map +1 -1
  66. package/dist/esm/Button/index.native.js +17 -1
  67. package/dist/esm/Button/index.native.js.map +1 -1
  68. package/dist/esm/FloatingPanel/echoContext.mjs +11 -0
  69. package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -0
  70. package/dist/esm/FloatingPanel/echoContext.native.js +11 -0
  71. package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -0
  72. package/dist/esm/FloatingPanel/index.mjs +213 -83
  73. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  74. package/dist/esm/FloatingPanel/index.native.js +92 -19
  75. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  76. package/dist/esm/FloatingPanel/panelWidth.mjs +63 -0
  77. package/dist/esm/FloatingPanel/panelWidth.mjs.map +1 -0
  78. package/dist/esm/FloatingPanel/panelWidth.native.js +67 -0
  79. package/dist/esm/FloatingPanel/panelWidth.native.js.map +1 -0
  80. package/dist/esm/FloatingPanel/pointAnchor.mjs +15 -5
  81. package/dist/esm/FloatingPanel/pointAnchor.mjs.map +1 -1
  82. package/dist/esm/FloatingPanel/pointAnchor.native.js +15 -5
  83. package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
  84. package/dist/esm/FloatingPanel/useFloatingPanel.mjs +58 -5
  85. package/dist/esm/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  86. package/dist/esm/FloatingPanel/useFloatingPanel.native.js +69 -5
  87. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  88. package/dist/esm/InputParts/index.mjs +21 -2
  89. package/dist/esm/InputParts/index.mjs.map +1 -1
  90. package/dist/esm/InputParts/index.native.js +23 -3
  91. package/dist/esm/InputParts/index.native.js.map +1 -1
  92. package/dist/esm/Wheel/NativeWheel.native.js +1 -1
  93. package/dist/esm/Wheel/NativeWheel.native.js.map +1 -1
  94. package/dist/esm/Wheel/index.mjs +2 -1
  95. package/dist/esm/Wheel/index.mjs.map +1 -1
  96. package/dist/esm/Wheel/index.native.js +4 -1
  97. package/dist/esm/Wheel/index.native.js.map +1 -1
  98. package/dist/esm/Wheel/wheelShared.mjs +6 -1
  99. package/dist/esm/Wheel/wheelShared.mjs.map +1 -1
  100. package/dist/esm/Wheel/wheelShared.native.js +7 -1
  101. package/dist/esm/Wheel/wheelShared.native.js.map +1 -1
  102. package/dist/esm/fields/Combobox/index.mjs +1 -0
  103. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  104. package/dist/esm/fields/Combobox/index.native.js +1 -0
  105. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  106. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +6 -30
  107. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  108. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
  109. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  110. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  111. package/dist/esm/fields/DatePicker/catalog.mjs +2 -28
  112. package/dist/esm/fields/DatePicker/catalog.mjs.map +1 -1
  113. package/dist/esm/fields/DatePicker/catalog.native.js +2 -30
  114. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
  115. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  116. package/dist/esm/fields/DatePicker/parts.mjs +11 -20
  117. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  118. package/dist/esm/fields/DatePicker/parts.native.js +13 -22
  119. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  120. package/dist/esm/fields/SearchInput/index.mjs +25 -3
  121. package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
  122. package/dist/esm/fields/SearchInput/index.native.js +25 -3
  123. package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
  124. package/dist/esm/fields/Select/index.mjs +66 -45
  125. package/dist/esm/fields/Select/index.mjs.map +1 -1
  126. package/dist/esm/fields/Select/index.native.js +70 -48
  127. package/dist/esm/fields/Select/index.native.js.map +1 -1
  128. package/dist/esm/fields/Select/shouldInlineChoices.mjs +3 -1
  129. package/dist/esm/fields/Select/shouldInlineChoices.mjs.map +1 -1
  130. package/dist/esm/fields/Select/shouldInlineChoices.native.js +3 -1
  131. package/dist/esm/fields/Select/shouldInlineChoices.native.js.map +1 -1
  132. package/dist/esm/fields/TimePicker/catalog.mjs +4 -25
  133. package/dist/esm/fields/TimePicker/catalog.mjs.map +1 -1
  134. package/dist/esm/fields/TimePicker/catalog.native.js +7 -29
  135. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  136. package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
  137. package/dist/esm/fields/TimePicker/parts.mjs +8 -21
  138. package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
  139. package/dist/esm/fields/TimePicker/parts.native.js +8 -21
  140. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  141. package/dist/esm/index.mjs.map +1 -1
  142. package/dist/esm/index.native.js.map +1 -1
  143. package/dist/esm/shared/floatingList.mjs +14 -5
  144. package/dist/esm/shared/floatingList.mjs.map +1 -1
  145. package/dist/esm/shared/floatingList.native.js +16 -5
  146. package/dist/esm/shared/floatingList.native.js.map +1 -1
  147. package/dist/jsx/Button/index.mjs +17 -1
  148. package/dist/jsx/Button/index.mjs.map +1 -1
  149. package/dist/jsx/Button/index.native.js +16 -0
  150. package/dist/jsx/Button/index.native.js.map +1 -1
  151. package/dist/jsx/FloatingPanel/echoContext.mjs +11 -0
  152. package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -0
  153. package/dist/jsx/FloatingPanel/echoContext.native.js +42 -0
  154. package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -0
  155. package/dist/jsx/FloatingPanel/index.mjs +213 -83
  156. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  157. package/dist/jsx/FloatingPanel/index.native.js +92 -17
  158. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  159. package/dist/jsx/FloatingPanel/panelWidth.mjs +63 -0
  160. package/dist/jsx/FloatingPanel/panelWidth.mjs.map +1 -0
  161. package/dist/jsx/FloatingPanel/panelWidth.native.js +99 -0
  162. package/dist/jsx/FloatingPanel/panelWidth.native.js.map +1 -0
  163. package/dist/jsx/FloatingPanel/pointAnchor.mjs +15 -5
  164. package/dist/jsx/FloatingPanel/pointAnchor.mjs.map +1 -1
  165. package/dist/jsx/FloatingPanel/pointAnchor.native.js +15 -5
  166. package/dist/jsx/FloatingPanel/pointAnchor.native.js.map +1 -1
  167. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs +58 -5
  168. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  169. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js +69 -4
  170. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  171. package/dist/jsx/InputParts/index.mjs +21 -2
  172. package/dist/jsx/InputParts/index.mjs.map +1 -1
  173. package/dist/jsx/InputParts/index.native.js +22 -2
  174. package/dist/jsx/InputParts/index.native.js.map +1 -1
  175. package/dist/jsx/Wheel/NativeWheel.native.js +1 -1
  176. package/dist/jsx/Wheel/NativeWheel.native.js.map +1 -1
  177. package/dist/jsx/Wheel/index.mjs +2 -1
  178. package/dist/jsx/Wheel/index.mjs.map +1 -1
  179. package/dist/jsx/Wheel/index.native.js +4 -1
  180. package/dist/jsx/Wheel/index.native.js.map +1 -1
  181. package/dist/jsx/Wheel/wheelShared.mjs +6 -1
  182. package/dist/jsx/Wheel/wheelShared.mjs.map +1 -1
  183. package/dist/jsx/Wheel/wheelShared.native.js +7 -1
  184. package/dist/jsx/Wheel/wheelShared.native.js.map +1 -1
  185. package/dist/jsx/fields/Combobox/index.mjs +1 -0
  186. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  187. package/dist/jsx/fields/Combobox/index.native.js +1 -0
  188. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  189. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +6 -30
  190. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  191. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
  192. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  193. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  194. package/dist/jsx/fields/DatePicker/catalog.mjs +2 -28
  195. package/dist/jsx/fields/DatePicker/catalog.mjs.map +1 -1
  196. package/dist/jsx/fields/DatePicker/catalog.native.js +2 -30
  197. package/dist/jsx/fields/DatePicker/catalog.native.js.map +1 -1
  198. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  199. package/dist/jsx/fields/DatePicker/parts.mjs +11 -20
  200. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  201. package/dist/jsx/fields/DatePicker/parts.native.js +13 -22
  202. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  203. package/dist/jsx/fields/SearchInput/index.mjs +25 -3
  204. package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
  205. package/dist/jsx/fields/SearchInput/index.native.js +23 -1
  206. package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
  207. package/dist/jsx/fields/Select/index.mjs +66 -45
  208. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  209. package/dist/jsx/fields/Select/index.native.js +69 -47
  210. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  211. package/dist/jsx/fields/Select/shouldInlineChoices.mjs +3 -1
  212. package/dist/jsx/fields/Select/shouldInlineChoices.mjs.map +1 -1
  213. package/dist/jsx/fields/Select/shouldInlineChoices.native.js +3 -1
  214. package/dist/jsx/fields/Select/shouldInlineChoices.native.js.map +1 -1
  215. package/dist/jsx/fields/TimePicker/catalog.mjs +4 -25
  216. package/dist/jsx/fields/TimePicker/catalog.mjs.map +1 -1
  217. package/dist/jsx/fields/TimePicker/catalog.native.js +7 -29
  218. package/dist/jsx/fields/TimePicker/catalog.native.js.map +1 -1
  219. package/dist/jsx/fields/TimePicker/index.native.js.map +1 -1
  220. package/dist/jsx/fields/TimePicker/parts.mjs +8 -21
  221. package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
  222. package/dist/jsx/fields/TimePicker/parts.native.js +8 -21
  223. package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
  224. package/dist/jsx/index.js.map +1 -1
  225. package/dist/jsx/index.mjs.map +1 -1
  226. package/dist/jsx/index.native.js.map +1 -1
  227. package/dist/jsx/shared/floatingList.mjs +14 -5
  228. package/dist/jsx/shared/floatingList.mjs.map +1 -1
  229. package/dist/jsx/shared/floatingList.native.js +15 -4
  230. package/dist/jsx/shared/floatingList.native.js.map +1 -1
  231. package/package.json +8 -8
  232. package/src/Button/index.tsx +22 -0
  233. package/src/FloatingPanel/FloatingPanel.echoStretch.spec.tsx +67 -0
  234. package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +193 -2
  235. package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +237 -0
  236. package/src/FloatingPanel/echoContext.ts +22 -0
  237. package/src/FloatingPanel/index.native.tsx +106 -9
  238. package/src/FloatingPanel/index.tsx +310 -102
  239. package/src/FloatingPanel/panelWidth.spec.ts +158 -0
  240. package/src/FloatingPanel/panelWidth.ts +122 -0
  241. package/src/FloatingPanel/panelWidthContract.spec.ts +10 -10
  242. package/src/FloatingPanel/pointAnchor.spec.ts +64 -2
  243. package/src/FloatingPanel/pointAnchor.ts +28 -3
  244. package/src/FloatingPanel/useFloatingPanel.spec.tsx +124 -4
  245. package/src/FloatingPanel/useFloatingPanel.ts +106 -33
  246. package/src/InputParts/index.tsx +30 -1
  247. package/src/Wheel/NativeWheel.native.tsx +1 -1
  248. package/src/Wheel/Wheel.spec.tsx +9 -0
  249. package/src/Wheel/index.tsx +12 -3
  250. package/src/Wheel/wheelShared.ts +6 -2
  251. package/src/fields/Combobox/index.tsx +1 -0
  252. package/src/fields/DatePicker/DatePicker.stories.tsx +3 -3
  253. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +17 -45
  254. package/src/fields/DatePicker/DatetimePicker.native.tsx +3 -0
  255. package/src/fields/DatePicker/catalog.tsx +8 -39
  256. package/src/fields/DatePicker/index.native.tsx +3 -0
  257. package/src/fields/DatePicker/parts.tsx +13 -23
  258. package/src/fields/DatePicker/seamlessCover.spec.tsx +180 -0
  259. package/src/fields/DatePicker/touchWeb.spec.tsx +109 -167
  260. package/src/fields/SearchInput/SearchInput.spec.tsx +40 -0
  261. package/src/fields/SearchInput/index.tsx +47 -2
  262. package/src/fields/Select/Select.containingBlock.spec.tsx +191 -0
  263. package/src/fields/Select/Select.stories.tsx +43 -0
  264. package/src/fields/Select/index.tsx +109 -45
  265. package/src/fields/Select/shouldInlineChoices.spec.ts +13 -0
  266. package/src/fields/Select/shouldInlineChoices.ts +6 -0
  267. package/src/fields/TimePicker/catalog.tsx +12 -33
  268. package/src/fields/TimePicker/index.native.tsx +2 -0
  269. package/src/fields/TimePicker/parts.tsx +6 -20
  270. package/src/index.ts +1 -0
  271. package/src/shared/floatingList.tsx +21 -5
  272. package/types/Button/index.d.ts.map +1 -1
  273. package/types/FloatingPanel/echoContext.d.ts +14 -0
  274. package/types/FloatingPanel/echoContext.d.ts.map +1 -0
  275. package/types/FloatingPanel/index.d.ts +59 -0
  276. package/types/FloatingPanel/index.d.ts.map +1 -1
  277. package/types/FloatingPanel/index.native.d.ts +9 -1
  278. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  279. package/types/FloatingPanel/panelWidth.d.ts +71 -0
  280. package/types/FloatingPanel/panelWidth.d.ts.map +1 -0
  281. package/types/FloatingPanel/pointAnchor.d.ts +8 -1
  282. package/types/FloatingPanel/pointAnchor.d.ts.map +1 -1
  283. package/types/FloatingPanel/useFloatingPanel.d.ts +33 -2
  284. package/types/FloatingPanel/useFloatingPanel.d.ts.map +1 -1
  285. package/types/InputParts/index.d.ts +5 -1
  286. package/types/InputParts/index.d.ts.map +1 -1
  287. package/types/Wheel/index.d.ts.map +1 -1
  288. package/types/Wheel/wheelShared.d.ts +2 -1
  289. package/types/Wheel/wheelShared.d.ts.map +1 -1
  290. package/types/fields/Combobox/index.d.ts.map +1 -1
  291. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts +6 -0
  292. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
  293. package/types/fields/DatePicker/DatetimePicker.native.d.ts +3 -0
  294. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
  295. package/types/fields/DatePicker/catalog.d.ts +6 -0
  296. package/types/fields/DatePicker/catalog.d.ts.map +1 -1
  297. package/types/fields/DatePicker/index.native.d.ts +3 -0
  298. package/types/fields/DatePicker/index.native.d.ts.map +1 -1
  299. package/types/fields/DatePicker/parts.d.ts +5 -7
  300. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  301. package/types/fields/Input/index.d.ts +3 -1
  302. package/types/fields/Input/index.d.ts.map +1 -1
  303. package/types/fields/SearchInput/index.d.ts +11 -0
  304. package/types/fields/SearchInput/index.d.ts.map +1 -1
  305. package/types/fields/Select/index.d.ts +8 -1
  306. package/types/fields/Select/index.d.ts.map +1 -1
  307. package/types/fields/Select/shouldInlineChoices.d.ts +5 -1
  308. package/types/fields/Select/shouldInlineChoices.d.ts.map +1 -1
  309. package/types/fields/TimePicker/catalog.d.ts +7 -1
  310. package/types/fields/TimePicker/catalog.d.ts.map +1 -1
  311. package/types/fields/TimePicker/index.native.d.ts +2 -0
  312. package/types/fields/TimePicker/index.native.d.ts.map +1 -1
  313. package/types/fields/TimePicker/parts.d.ts +1 -3
  314. package/types/fields/TimePicker/parts.d.ts.map +1 -1
  315. package/types/index.d.ts +1 -0
  316. package/types/index.d.ts.map +1 -1
  317. package/types/shared/floatingList.d.ts +5 -1
  318. package/types/shared/floatingList.d.ts.map +1 -1
  319. package/dist/cjs/shared/touchWebPicker.cjs +0 -136
  320. package/dist/cjs/shared/touchWebPicker.native.js +0 -154
  321. package/dist/cjs/shared/touchWebPicker.native.js.map +0 -1
  322. package/dist/esm/shared/touchWebPicker.mjs +0 -105
  323. package/dist/esm/shared/touchWebPicker.mjs.map +0 -1
  324. package/dist/esm/shared/touchWebPicker.native.js +0 -120
  325. package/dist/esm/shared/touchWebPicker.native.js.map +0 -1
  326. package/dist/jsx/shared/touchWebPicker.mjs +0 -105
  327. package/dist/jsx/shared/touchWebPicker.mjs.map +0 -1
  328. package/dist/jsx/shared/touchWebPicker.native.js +0 -154
  329. package/dist/jsx/shared/touchWebPicker.native.js.map +0 -1
  330. package/src/shared/touchWebPicker.spec.ts +0 -98
  331. package/src/shared/touchWebPicker.tsx +0 -158
  332. package/types/shared/touchWebPicker.d.ts +0 -40
  333. package/types/shared/touchWebPicker.d.ts.map +0 -1
@@ -20,19 +20,26 @@ import {
20
20
  ensureKeyboardModalityTracking,
21
21
  motionDurationMs,
22
22
  } from "@multiplatform.one/theme";
23
- import { isWeb, Sheet, View, YStack } from "tamagui";
23
+ import { isWeb, Sheet, Theme, View, YStack } from "tamagui";
24
24
  import { useClick, useDismiss, useInteractions } from "@floating-ui/react";
25
25
  import { ScrollArrow } from "../shared/floatingList";
26
26
  import { TrailingActionOverlay, TriggerWithTrailingAction } from "./trailingAction";
27
27
  import { useReturnFocusOnClose, useSheetModalFocus } from "../shared/focusManagement";
28
28
  import { useSheetEscapeDismiss } from "../shared/useSheetEscapeDismiss";
29
- import { useFloatingPanel, panelViewportPadding } from "./useFloatingPanel";
29
+ import { useFloatingPanel, panelViewportPadding, paintedCornerBox } from "./useFloatingPanel";
30
+ import { fixedContainingBlockOrigin } from "./containingBlock";
30
31
  import type { PanelWidthMode } from "./useFloatingPanel";
32
+ import {
33
+ echoOffset,
34
+ type PanelWidth,
35
+ panelLeftForWidth,
36
+ screenBounds,
37
+ slidesAlongScreen,
38
+ } from "./panelWidth";
31
39
  import { OverlayStackProvider, useInsideOverlay, useOverlayZIndex } from "../shared/overlayStack";
32
40
  import { resolveCompactFace, type CompactFace } from "./compactFace";
33
41
  import { isNestedPanelAction, type PanelActionEvent } from "./nestedAction";
34
42
  import { PanelPortal } from "./PanelPortal";
35
- import { fixedContainingBlockOrigin } from "./containingBlock";
36
43
  import {
37
44
  contextMenuPoint,
38
45
  placeOverTrigger,
@@ -77,6 +84,14 @@ export interface FloatingPanelProps {
77
84
  triggerRow?: ReactNode;
78
85
  anchorRect?: { x: number; y: number; width: number; height: number };
79
86
  triggerEcho?: boolean;
87
+ /**
88
+ * Which top corner of the trigger a covering panel opens from. `"start"`
89
+ * (default) keeps the echo row in place. `"auto"` is for an icon trigger
90
+ * (LC-112, FZ-8438): the trailing corner when the leading one would run off
91
+ * the end edge, and a vertical collision slides the menu up over its button
92
+ * instead of handing it to a sheet, the way an iOS menu grows out of it.
93
+ */
94
+ coverAlign?: "start" | "auto";
80
95
  /**
81
96
  * Optional control rendered beside the trigger but OUTSIDE the native press
82
97
  * capture (e.g. DatePicker/ColorPicker clear). On native the trigger subtree
@@ -127,6 +142,14 @@ export interface FloatingPanelProps {
127
142
  * anything opened from a field-shaped trigger takes the floor.
128
143
  */
129
144
  widthMode?: PanelWidthMode;
145
+ /**
146
+ * How wide the panel opens over its trigger (LC-112, FZ-8438 r3):
147
+ * `"content"` hugs the content (never narrower than an echoed trigger),
148
+ * `"trigger"` is the trigger's width, `"screen"` fills the room between the
149
+ * screen's safe margins with its top edge still on the trigger's, and a
150
+ * number is a fixed width. Unset keeps each component's own default.
151
+ */
152
+ panelWidth?: PanelWidth;
130
153
  /**
131
154
  * @deprecated Pass `widthMode` instead — the boolean cannot express
132
155
  * `"match-trigger"`. `true` → `"fit-content"`, `false`/undefined →
@@ -277,6 +300,41 @@ const ECHO_STRIPPED_ATTRIBUTES = [
277
300
  "aria-activedescendant",
278
301
  ];
279
302
 
303
+ function childPath(root: Element, node: Element): number[] | null {
304
+ const path: number[] = [];
305
+ for (let at: Element | null = node; at && at !== root; at = at.parentElement) {
306
+ const parent: Element | null = at.parentElement;
307
+ if (!parent) return null;
308
+ path.unshift(Array.prototype.indexOf.call(parent.children, at));
309
+ }
310
+ return path;
311
+ }
312
+
313
+ function followPath(root: Element, path: number[]): HTMLElement | null {
314
+ let at: Element | undefined = root;
315
+ for (const index of path) at = at?.children[index];
316
+ return (at as HTMLElement | undefined) ?? null;
317
+ }
318
+
319
+ /**
320
+ * LC-112 seamless cover (FZ-8438): the echo keeps the trigger's geometry but
321
+ * not its chrome. Its frame's border, fill, shadow and outline go, so the
322
+ * panel's own edge and surface are the only ones drawn and nothing separates
323
+ * the echo from the body. Widths stay, so the content sits where it did.
324
+ */
325
+ function dropEchoChrome(source: HTMLElement, snapshot: HTMLElement) {
326
+ const painted = paintedCornerBox(source);
327
+ const path = painted ? childPath(source, painted) : null;
328
+ const frame = path ? followPath(snapshot, path) : null;
329
+ if (!frame) return;
330
+ frame.style.setProperty("border-color", "transparent", "important");
331
+ frame.style.setProperty("background-color", "transparent", "important");
332
+ frame.style.setProperty("background-image", "none", "important");
333
+ frame.style.setProperty("box-shadow", "none", "important");
334
+ frame.style.setProperty("outline", "none", "important");
335
+ frame.setAttribute("data-fp-echo-frame", "");
336
+ }
337
+
280
338
  /**
281
339
  * The panel's first row when it opens over its trigger: the trigger's own
282
340
  * label/value, drawn where the trigger sits, so the panel reads as the
@@ -287,18 +345,30 @@ const ECHO_STRIPPED_ATTRIBUTES = [
287
345
  * stops stripped so labels, forms and queries still resolve to the one real
288
346
  * trigger. Pressing it closes the panel, like pressing the trigger again.
289
347
  */
290
- function TriggerEchoRow({
348
+ export function TriggerEchoRow({
291
349
  sourceRef,
292
350
  onPress,
293
351
  children,
294
352
  anchorRect,
295
353
  source,
354
+ presentational = false,
355
+ edge = "top",
296
356
  }: {
297
357
  sourceRef: RefObject<HTMLElement | null>;
298
358
  onPress: () => void;
299
359
  children?: ReactNode;
300
360
  anchorRect?: FloatingPanelProps["anchorRect"];
301
361
  source: ReactNode;
362
+ /**
363
+ * Inside a listbox (Select) the echo is pointer-only and hidden from
364
+ * assistive tech: a button child would break the listbox's role contract.
365
+ */
366
+ presentational?: boolean;
367
+ /**
368
+ * `"bottom"` for a drop-up (FZ-8438 r3): the panel's bottom edge is the
369
+ * trigger's, so the echo is its last row, sticky at the bottom.
370
+ */
371
+ edge?: "top" | "bottom";
302
372
  }) {
303
373
  const rowRef = useRef<HTMLElement | null>(null);
304
374
  const visualRef = useRef<HTMLElement | null>(null);
@@ -320,17 +390,33 @@ function TriggerEchoRow({
320
390
  control?.textContent ||
321
391
  source.textContent ||
322
392
  "";
323
- row.setAttribute("aria-label", label);
393
+ if (!presentational) row.setAttribute("aria-label", label);
324
394
  const rect = anchorRect ?? source.getBoundingClientRect();
325
- row.style.width = `${rect.width}px`;
395
+ // A stretched echo (placeEchoOverTrigger) keeps its grown width.
396
+ const grown = Number(row.getAttribute("data-fp-echo-stretched")) || 0;
397
+ const stretched = grown > rect.width;
398
+ row.style.width = `${stretched ? grown : rect.width}px`;
326
399
  row.style.height = `${rect.height}px`;
327
400
  const rtl = isRtl(source);
328
401
  row.style.alignSelf = "flex-start";
329
402
  const frameStyle = row.parentElement ? getComputedStyle(row.parentElement) : null;
330
- row.style.marginTop = `${-(parseFloat(frameStyle?.borderTopWidth || "0") || 0)}px`;
331
403
  row.style.position = "sticky";
332
- row.style.top = row.style.marginTop;
404
+ if (edge === "bottom") {
405
+ row.style.order = "1";
406
+ row.style.marginTop = "";
407
+ row.style.top = "";
408
+ row.style.marginBottom = `${-(parseFloat(frameStyle?.borderBottomWidth || "0") || 0)}px`;
409
+ row.style.bottom = row.style.marginBottom;
410
+ } else {
411
+ row.style.order = "";
412
+ row.style.marginBottom = "";
413
+ row.style.bottom = "";
414
+ row.style.marginTop = `${-(parseFloat(frameStyle?.borderTopWidth || "0") || 0)}px`;
415
+ row.style.top = row.style.marginTop;
416
+ }
333
417
  row.style.zIndex = "1";
418
+ // Sticky over a scrolled body, so it carries the panel's own fill.
419
+ row.style.backgroundColor = frameStyle?.backgroundColor ?? "";
334
420
  row.style.marginLeft = rtl
335
421
  ? ""
336
422
  : `${-(parseFloat(frameStyle?.borderLeftWidth || "0") || 0)}px`;
@@ -352,8 +438,11 @@ function TriggerEchoRow({
352
438
  node.setAttribute("tabindex", "-1");
353
439
  }
354
440
  }
441
+ if (children == null) dropEchoChrome(source, snapshot);
355
442
  snapshot.setAttribute("inert", "");
356
443
  snapshot.setAttribute("aria-hidden", "true");
444
+ snapshot.style.width = stretched ? "100%" : "";
445
+ snapshot.style.maxWidth = stretched ? "none" : "";
357
446
  if (children == null) visualRef.current?.replaceChildren(snapshot);
358
447
  };
359
448
  sync();
@@ -361,13 +450,14 @@ function TriggerEchoRow({
361
450
  const observer = new ResizeObserver(sync);
362
451
  observer.observe(source);
363
452
  return () => observer.disconnect();
364
- }, [sourceRef, source, children, anchorRect]);
453
+ }, [sourceRef, source, children, anchorRect, presentational, edge]);
365
454
  return (
366
455
  <View
367
456
  ref={rowRef as any}
368
457
  data-fp-trigger-row=""
369
- role="button"
370
- aria-expanded={true}
458
+ {...(presentational
459
+ ? { "aria-hidden": true }
460
+ : { role: "button" as const, "aria-expanded": true })}
371
461
  tabIndex={-1}
372
462
  cursor="pointer"
373
463
  onPress={onPress}
@@ -381,6 +471,54 @@ function TriggerEchoRow({
381
471
  );
382
472
  }
383
473
 
474
+ const ECHO_FIELD = 'input, textarea, [role="combobox"], [aria-haspopup="listbox"]';
475
+
476
+ /**
477
+ * Keep the echo row on its trigger when the panel's start edge is not the
478
+ * trigger's (a `"screen"` or fixed `panelWidth`, or a panel slid back on
479
+ * screen). `translate` leaves the row's own margins and the panel's scale
480
+ * transform alone.
481
+ *
482
+ * With `stretch` (a consumer set `panelWidth`), a field's echo grows from the
483
+ * field's start edge to the panel's end edge: the value stays where it was,
484
+ * the chevron rides the panel's end, and the value is no longer cut short
485
+ * above rows that show it whole (LC-112 r3). A button echo keeps its box, so
486
+ * a centred label never moves.
487
+ */
488
+ export function placeEchoOverTrigger(
489
+ panelElement: HTMLElement,
490
+ geometry: Parameters<typeof echoOffset>[0],
491
+ { stretch = false }: { stretch?: boolean } = {},
492
+ ) {
493
+ const row = panelElement.querySelector<HTMLElement>("[data-fp-trigger-row]");
494
+ if (!row) return;
495
+ const offset = echoOffset(geometry);
496
+ const x = geometry.rtl ? -offset : offset;
497
+ row.style.translate = Math.abs(x) < 0.5 ? "" : `${x}px 0`;
498
+ const triggerWidth = geometry.triggerRight - geometry.triggerLeft;
499
+ const grown = geometry.panelWidth - offset;
500
+ const field = stretch && row.querySelector(ECHO_FIELD) != null;
501
+ const visual = row.firstElementChild as HTMLElement | null;
502
+ const snapshot = visual?.firstElementChild as HTMLElement | null;
503
+ if (field && grown > triggerWidth + 0.5) {
504
+ row.style.width = `${grown}px`;
505
+ row.setAttribute("data-fp-echo-stretched", String(grown));
506
+ for (const node of [visual, snapshot]) {
507
+ if (!node) continue;
508
+ node.style.width = "100%";
509
+ node.style.maxWidth = "none";
510
+ }
511
+ } else if (row.hasAttribute("data-fp-echo-stretched")) {
512
+ row.removeAttribute("data-fp-echo-stretched");
513
+ row.style.width = `${triggerWidth}px`;
514
+ for (const node of [visual, snapshot]) {
515
+ if (!node) continue;
516
+ node.style.width = "";
517
+ node.style.maxWidth = "";
518
+ }
519
+ }
520
+ }
521
+
384
522
  // ── FloatingPanel ─────────────────────────────────────────────
385
523
 
386
524
  // Canonical float↔sheet pivot (theme `layoutBreakpoints.medium` = Tamagui
@@ -623,10 +761,12 @@ function FloatingPanelWeb({
623
761
  sizing = "grow",
624
762
  widthMode,
625
763
  fitContent,
764
+ panelWidth,
626
765
  contentPadding = "default",
627
766
  openOn = "press",
628
767
  cover = true,
629
768
  triggerEcho = true,
769
+ coverAlign = "start",
630
770
  triggerRow,
631
771
  anchorRect,
632
772
  clampCollisions = false,
@@ -647,6 +787,7 @@ function FloatingPanelWeb({
647
787
  const contentRef = useRef<HTMLElement | null>(null);
648
788
  const anchorPointRef = useRef<PanelPoint | null>(null);
649
789
  const pointPlacementRef = useRef<{ dropup: boolean; alignEnd: boolean } | null>(null);
790
+ const coverAlignEndRef = useRef(false);
650
791
 
651
792
  const repositionFnRef = useRef<(() => void) | null>(null);
652
793
 
@@ -671,6 +812,8 @@ function FloatingPanelWeb({
671
812
  fitContent,
672
813
  freeOverlay: isContextMenu,
673
814
  cover,
815
+ panelWidth,
816
+ echo: cover && triggerEcho && !isContextMenu,
674
817
  onBeforeOpen: resetPosition,
675
818
  });
676
819
 
@@ -753,7 +896,48 @@ function FloatingPanelWeb({
753
896
  : 1;
754
897
  const layoutWidth = dropdownElement.getBoundingClientRect().width / (scale || 1);
755
898
  const width = Math.max(layoutWidth || dropdownElement.offsetWidth, measured.width);
756
- const left = rtl ? measured.right - width : measured.left;
899
+ const startLeft = rtl ? measured.right - width : measured.left;
900
+ const endLeft = rtl ? measured.left : measured.right - width;
901
+ // An icon trigger has no echo to keep in place, so its menu opens from
902
+ // whichever top corner keeps it on screen: the trailing one for a bar
903
+ // button at the end edge, the way an iOS menu grows out of its button.
904
+ // Only the free edge needs the padding; the aligned edge is the trigger's.
905
+ const iconCover = coverAlign === "auto";
906
+ const startFree = rtl
907
+ ? startLeft >= viewportLeft + panelViewportPadding
908
+ : startLeft + width <= viewportRight - panelViewportPadding;
909
+ const endFree = rtl
910
+ ? endLeft + width <= viewportRight - panelViewportPadding
911
+ : endLeft >= viewportLeft + panelViewportPadding;
912
+ let alignEnd = iconCover && !startFree && endFree;
913
+ // A screen-wide or fixed-width panel is not tied to the trigger's start
914
+ // edge: it slides inside the margins, and only its echo stays put.
915
+ const slides = slidesAlongScreen(panelWidth);
916
+ const margins = {
917
+ boundsLeft: viewportLeft + panelViewportPadding,
918
+ boundsRight: viewportRight - panelViewportPadding,
919
+ };
920
+ const room =
921
+ panelWidth === "screen"
922
+ ? screenBounds({
923
+ triggerLeft: measured.left,
924
+ triggerRight: measured.right,
925
+ ...margins,
926
+ rtl,
927
+ })
928
+ : { left: margins.boundsLeft, right: margins.boundsRight };
929
+ const left = slides
930
+ ? panelLeftForWidth({
931
+ triggerLeft: measured.left,
932
+ triggerRight: measured.right,
933
+ width,
934
+ boundsLeft: room.left,
935
+ boundsRight: room.right,
936
+ rtl,
937
+ })
938
+ : alignEnd
939
+ ? endLeft
940
+ : startLeft;
757
941
  const firstActionHeight =
758
942
  contentRef.current?.querySelector<HTMLElement>(PANEL_FOCUSABLE)?.getBoundingClientRect()
759
943
  .height ||
@@ -774,14 +958,15 @@ function FloatingPanelWeb({
774
958
  if (
775
959
  measured.width > 0 &&
776
960
  measured.height > 0 &&
777
- (left < viewportLeft ||
778
- left + width > Math.max(measured.right, viewportRight - panelViewportPadding) ||
961
+ ((!slides &&
962
+ (left < viewportLeft ||
963
+ left + width > Math.max(measured.right, viewportRight - panelViewportPadding))) ||
779
964
  measured.right > viewportRight ||
780
965
  measured.top < viewportTop ||
781
966
  measured.top + Math.max(neededHeight, measured.height) >
782
967
  viewportBottom - panelViewportPadding)
783
968
  ) {
784
- if (!clampCollisions) {
969
+ if (!clampCollisions && !iconCover) {
785
970
  dropdownElement.style.visibility = "hidden";
786
971
  setCollisionSheet(true);
787
972
  return;
@@ -804,10 +989,24 @@ function FloatingPanelWeb({
804
989
  bottom: viewportBottom - panelViewportPadding,
805
990
  },
806
991
  rtl,
992
+ align: coverAlign,
807
993
  });
808
994
  placedTop = placed.top;
809
- placedLeft = placed.left;
995
+ if (!slides) placedLeft = placed.left;
996
+ alignEnd = placed.end;
810
997
  }
998
+ coverAlignEndRef.current = alignEnd;
999
+ placeEchoOverTrigger(
1000
+ dropdownElement,
1001
+ {
1002
+ triggerLeft: measured.left,
1003
+ triggerRight: measured.right,
1004
+ panelLeft: placedLeft,
1005
+ panelWidth: width,
1006
+ rtl,
1007
+ },
1008
+ { stretch: panelWidth !== undefined },
1009
+ );
811
1010
  const top = placedTop - containingBlock.top;
812
1011
  const cssLeft = placedLeft - containingBlock.left;
813
1012
  const maxHeight = Math.max(0, viewportBottom - panelViewportPadding - placedTop);
@@ -815,7 +1014,7 @@ function FloatingPanelWeb({
815
1014
  dropdownElement.style.left = `${cssLeft}px`;
816
1015
  dropdownElement.style.maxHeight = `${maxHeight}px`;
817
1016
  dropdownElement.dir = rtl ? "rtl" : "ltr";
818
- dropdownElement.style.transformOrigin = rtl ? "top right" : "top left";
1017
+ dropdownElement.style.transformOrigin = rtl !== alignEnd ? "top right" : "top left";
819
1018
  dropdownElement.style.visibility = "visible";
820
1019
  overlayStyleRef.current = { top, left: cssLeft, maxHeight };
821
1020
  panel.initializingRef.current = false;
@@ -979,6 +1178,8 @@ function FloatingPanelWeb({
979
1178
  anchorRect,
980
1179
  clampCollisions,
981
1180
  sheetProps.scrollable,
1181
+ triggerEcho,
1182
+ coverAlign,
982
1183
  panel.placement,
983
1184
  panel.refs,
984
1185
  panel.triggerRef,
@@ -1201,92 +1402,99 @@ function FloatingPanelWeb({
1201
1402
  )}
1202
1403
  {panel.mounted && !collisionSheet && (
1203
1404
  <PanelPortal anchor={panel.triggerRef.current}>
1204
- <YStack
1205
- {...getFloatingProps({
1206
- ref: panel.refs.setFloating,
1207
- style: {
1208
- ...elevatedSurfaceStyle,
1209
- position: panel.strategy,
1210
- top: overlayStyleRef.current?.top ?? panel.y ?? 0,
1211
- left: overlayStyleRef.current?.left ?? panel.x ?? 0,
1212
- scrollbarWidth: "none" as any,
1213
- zIndex: panelZIndex,
1214
- overflow: "auto",
1215
- ...(cover && !isContextMenu ? { overflowX: "hidden" as const } : {}),
1216
- ...panel.floatingStyleRef.current,
1217
- ...(overlayStyleRef.current
1218
- ? { maxHeight: overlayStyleRef.current.maxHeight }
1219
- : {}),
1220
- opacity: panel.visible ? 1 : 0,
1221
- // `none`, not scale(1): any transform makes this panel the
1222
- // containing block of a nested panel's `position: fixed`, which
1223
- // then positions against this box and is clipped by its scroll.
1224
- transform: panel.visible ? "none" : "scale(0.96)",
1225
- transition: webTransition,
1226
- transformOrigin:
1227
- cover && !isContextMenu
1228
- ? isRtl(panel.triggerRef.current)
1229
- ? "top right"
1230
- : "top left"
1231
- : panelTransformOrigin(
1232
- pointPlacementRef.current
1233
- ? `${pointPlacementRef.current.dropup ? "top" : "bottom"}-${pointPlacementRef.current.alignEnd ? "end" : "start"}`
1234
- : panel.placement,
1235
- ),
1236
- },
1237
- onScroll: handleScroll,
1238
- onTransitionEnd: (event) => {
1239
- if (
1240
- event.target === event.currentTarget &&
1241
- (event.propertyName === "height" || event.propertyName === "max-height")
1242
- ) {
1243
- panel.updateArrows(event.currentTarget);
1244
- }
1245
- },
1246
- })}
1247
- data-testid="floating-panel-viewport"
1248
- data-fp-panel=""
1249
- {...panelChromeFocus}
1250
- pointerEvents={panel.visible ? "auto" : "none"}
1251
- {...elevatedSurfaceProps}
1252
- // Complete elevatedSurface fragment above is the ONLY surface source
1253
- // (SF-OVERLAY "including border and elevation", Round 2 docket).
1254
- // The one layered exception is anatomy, not surface: the dropdown
1255
- // radius clamp (same shape as Card's containerRadius over
1256
- // elevatedSurface) keeps list rows unclipped at large radius knobs.
1257
- borderRadius={panel.dropdownRadius}
1258
- paddingVertical={0}
1259
- >
1260
- {isContextMenu || !cover || !triggerEcho ? null : (
1261
- <TriggerEchoRow
1262
- sourceRef={panel.triggerRef}
1263
- source={trigger}
1264
- anchorRect={anchorRect}
1265
- onPress={() => onOpenChange(false)}
1266
- >
1267
- {triggerRow}
1268
- </TriggerEchoRow>
1269
- )}
1270
- <ScrollArrow
1271
- direction="up"
1272
- scrollRef={panel.refs.floating}
1273
- visible={panel.arrowUp}
1274
- arrowScrollDirRef={panel.arrowScrollDirRef}
1275
- />
1276
- <View
1277
- ref={contentRef as any}
1278
- {...(contentPadding !== "none" ? panel.knobProps.panelPadding : undefined)}
1279
- {...(contentPadding !== "none" ? panel.knobProps.gapLg : undefined)}
1405
+ {/* The grouped surface step (alt1), the one a field's own list already
1406
+ opens on: a light menu reads white over the page instead of the
1407
+ page's own grey, and a dark menu's hairlines clear its fill. */}
1408
+ <Theme name="alt1">
1409
+ <YStack
1410
+ {...getFloatingProps({
1411
+ ref: panel.refs.setFloating,
1412
+ style: {
1413
+ ...elevatedSurfaceStyle,
1414
+ position: panel.strategy,
1415
+ top: overlayStyleRef.current?.top ?? panel.y ?? 0,
1416
+ left: overlayStyleRef.current?.left ?? panel.x ?? 0,
1417
+ scrollbarWidth: "none" as any,
1418
+ zIndex: panelZIndex,
1419
+ overflow: "auto",
1420
+ ...(cover && !isContextMenu ? { overflowX: "hidden" as const } : {}),
1421
+ ...panel.floatingStyleRef.current,
1422
+ ...(overlayStyleRef.current
1423
+ ? { maxHeight: overlayStyleRef.current.maxHeight }
1424
+ : {}),
1425
+ opacity: panel.visible ? 1 : 0,
1426
+ // `none`, not scale(1): any transform makes this panel the
1427
+ // containing block of a nested panel's `position: fixed`, which
1428
+ // then positions against this box and is clipped by its scroll.
1429
+ transform: panel.visible ? "none" : "scale(0.96)",
1430
+ transition: webTransition,
1431
+ transformOrigin:
1432
+ cover && !isContextMenu
1433
+ ? isRtl(panel.triggerRef.current) !== coverAlignEndRef.current
1434
+ ? "top right"
1435
+ : "top left"
1436
+ : panelTransformOrigin(
1437
+ pointPlacementRef.current
1438
+ ? `${pointPlacementRef.current.dropup ? "top" : "bottom"}-${pointPlacementRef.current.alignEnd ? "end" : "start"}`
1439
+ : panel.placement,
1440
+ ),
1441
+ },
1442
+ onScroll: handleScroll,
1443
+ onTransitionEnd: (event) => {
1444
+ if (
1445
+ event.target === event.currentTarget &&
1446
+ (event.propertyName === "height" || event.propertyName === "max-height")
1447
+ ) {
1448
+ panel.updateArrows(event.currentTarget);
1449
+ }
1450
+ },
1451
+ })}
1452
+ data-testid="floating-panel-viewport"
1453
+ data-fp-panel=""
1454
+ {...panelChromeFocus}
1455
+ pointerEvents={panel.visible ? "auto" : "none"}
1456
+ {...elevatedSurfaceProps}
1457
+ // Complete elevatedSurface fragment above is the ONLY surface source
1458
+ // (SF-OVERLAY "including border and elevation", Round 2 docket).
1459
+ // The one layered exception is anatomy, not surface: the dropdown
1460
+ // radius (Card's containerRadius shape over elevatedSurface). A
1461
+ // covering panel takes its trigger's whole arc (LC-112 seamless
1462
+ // cover); past the cap it insets its bottom so rows stay unclipped.
1463
+ borderRadius={panel.dropdownRadius}
1464
+ paddingVertical={0}
1465
+ paddingBottom={panel.coverCornerInset || 0}
1280
1466
  >
1281
- <OverlayStackProvider zIndex={panelZIndex}>{children}</OverlayStackProvider>
1282
- </View>
1283
- <ScrollArrow
1284
- direction="down"
1285
- scrollRef={panel.refs.floating}
1286
- visible={panel.arrowDown}
1287
- arrowScrollDirRef={panel.arrowScrollDirRef}
1288
- />
1289
- </YStack>
1467
+ {isContextMenu || !cover || !triggerEcho ? null : (
1468
+ <TriggerEchoRow
1469
+ sourceRef={panel.triggerRef}
1470
+ source={trigger}
1471
+ anchorRect={anchorRect}
1472
+ onPress={() => onOpenChange(false)}
1473
+ >
1474
+ {triggerRow}
1475
+ </TriggerEchoRow>
1476
+ )}
1477
+ <ScrollArrow
1478
+ direction="up"
1479
+ scrollRef={panel.refs.floating}
1480
+ visible={panel.arrowUp}
1481
+ arrowScrollDirRef={panel.arrowScrollDirRef}
1482
+ />
1483
+ <View
1484
+ ref={contentRef as any}
1485
+ {...(contentPadding !== "none" ? panel.knobProps.panelPadding : undefined)}
1486
+ {...(contentPadding !== "none" ? panel.knobProps.gapLg : undefined)}
1487
+ >
1488
+ <OverlayStackProvider zIndex={panelZIndex}>{children}</OverlayStackProvider>
1489
+ </View>
1490
+ <ScrollArrow
1491
+ direction="down"
1492
+ scrollRef={panel.refs.floating}
1493
+ visible={panel.arrowDown}
1494
+ arrowScrollDirRef={panel.arrowScrollDirRef}
1495
+ />
1496
+ </YStack>
1497
+ </Theme>
1290
1498
  </PanelPortal>
1291
1499
  )}
1292
1500
  </>