@multiplatform.one/forms 7.71.0 → 7.73.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 (381) hide show
  1. package/dist/cjs/Button/circleGlyph.cjs +28 -0
  2. package/dist/cjs/Button/circleGlyph.native.js +31 -0
  3. package/dist/cjs/Button/circleGlyph.native.js.map +1 -0
  4. package/dist/cjs/Button/index.cjs +19 -3
  5. package/dist/cjs/Button/index.native.js +19 -3
  6. package/dist/cjs/Button/index.native.js.map +1 -1
  7. package/dist/cjs/FloatingPanel/PanelHeader.cjs +49 -0
  8. package/dist/cjs/FloatingPanel/PanelHeader.native.js +53 -0
  9. package/dist/cjs/FloatingPanel/PanelHeader.native.js.map +1 -0
  10. package/dist/cjs/FloatingPanel/echoContext.cjs +67 -0
  11. package/dist/cjs/FloatingPanel/echoContext.native.js +71 -0
  12. package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -0
  13. package/dist/cjs/FloatingPanel/iconEcho.cjs +104 -0
  14. package/dist/cjs/FloatingPanel/iconEcho.native.js +114 -0
  15. package/dist/cjs/FloatingPanel/iconEcho.native.js.map +1 -0
  16. package/dist/cjs/FloatingPanel/index.cjs +371 -86
  17. package/dist/cjs/FloatingPanel/index.native.js +164 -20
  18. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  19. package/dist/cjs/FloatingPanel/paintedBox.cjs +80 -0
  20. package/dist/cjs/FloatingPanel/paintedBox.native.js +85 -0
  21. package/dist/cjs/FloatingPanel/paintedBox.native.js.map +1 -0
  22. package/dist/cjs/FloatingPanel/panelWidth.cjs +92 -0
  23. package/dist/cjs/FloatingPanel/panelWidth.native.js +99 -0
  24. package/dist/cjs/FloatingPanel/panelWidth.native.js.map +1 -0
  25. package/dist/cjs/FloatingPanel/pointAnchor.cjs +34 -5
  26. package/dist/cjs/FloatingPanel/pointAnchor.native.js +37 -8
  27. package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
  28. package/dist/cjs/FloatingPanel/useFloatingPanel.cjs +60 -5
  29. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js +72 -5
  30. package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  31. package/dist/cjs/InputParts/index.cjs +18 -0
  32. package/dist/cjs/InputParts/index.native.js +19 -1
  33. package/dist/cjs/InputParts/index.native.js.map +1 -1
  34. package/dist/cjs/Wheel/NativeWheel.native.js +1 -1
  35. package/dist/cjs/Wheel/NativeWheel.native.js.map +1 -1
  36. package/dist/cjs/Wheel/index.cjs +2 -1
  37. package/dist/cjs/Wheel/index.native.js +4 -1
  38. package/dist/cjs/Wheel/index.native.js.map +1 -1
  39. package/dist/cjs/Wheel/wheelShared.cjs +6 -1
  40. package/dist/cjs/Wheel/wheelShared.native.js +7 -1
  41. package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
  42. package/dist/cjs/fields/Combobox/index.cjs +1 -0
  43. package/dist/cjs/fields/Combobox/index.native.js +1 -0
  44. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  45. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +6 -30
  46. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
  47. package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  48. package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  49. package/dist/cjs/fields/DatePicker/catalog.cjs +2 -28
  50. package/dist/cjs/fields/DatePicker/catalog.native.js +2 -30
  51. package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
  52. package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
  53. package/dist/cjs/fields/DatePicker/parts.cjs +11 -20
  54. package/dist/cjs/fields/DatePicker/parts.native.js +13 -22
  55. package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
  56. package/dist/cjs/fields/Select/index.cjs +65 -44
  57. package/dist/cjs/fields/Select/index.native.js +69 -47
  58. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  59. package/dist/cjs/fields/Select/shouldInlineChoices.cjs +3 -1
  60. package/dist/cjs/fields/Select/shouldInlineChoices.native.js +3 -1
  61. package/dist/cjs/fields/Select/shouldInlineChoices.native.js.map +1 -1
  62. package/dist/cjs/fields/TimePicker/catalog.cjs +4 -25
  63. package/dist/cjs/fields/TimePicker/catalog.native.js +7 -29
  64. package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
  65. package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
  66. package/dist/cjs/fields/TimePicker/parts.cjs +8 -21
  67. package/dist/cjs/fields/TimePicker/parts.native.js +8 -21
  68. package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
  69. package/dist/cjs/index.cjs +2 -0
  70. package/dist/cjs/index.native.js +2 -0
  71. package/dist/cjs/index.native.js.map +1 -1
  72. package/dist/cjs/shared/floatingList.cjs +13 -4
  73. package/dist/cjs/shared/floatingList.native.js +15 -4
  74. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  75. package/dist/esm/Button/circleGlyph.mjs +3 -0
  76. package/dist/esm/Button/circleGlyph.mjs.map +1 -0
  77. package/dist/esm/Button/circleGlyph.native.js +3 -0
  78. package/dist/esm/Button/circleGlyph.native.js.map +1 -0
  79. package/dist/esm/Button/index.mjs +18 -2
  80. package/dist/esm/Button/index.mjs.map +1 -1
  81. package/dist/esm/Button/index.native.js +18 -2
  82. package/dist/esm/Button/index.native.js.map +1 -1
  83. package/dist/esm/FloatingPanel/PanelHeader.mjs +24 -0
  84. package/dist/esm/FloatingPanel/PanelHeader.mjs.map +1 -0
  85. package/dist/esm/FloatingPanel/PanelHeader.native.js +25 -0
  86. package/dist/esm/FloatingPanel/PanelHeader.native.js.map +1 -0
  87. package/dist/esm/FloatingPanel/echoContext.mjs +35 -0
  88. package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -0
  89. package/dist/esm/FloatingPanel/echoContext.native.js +36 -0
  90. package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -0
  91. package/dist/esm/FloatingPanel/iconEcho.mjs +77 -0
  92. package/dist/esm/FloatingPanel/iconEcho.mjs.map +1 -0
  93. package/dist/esm/FloatingPanel/iconEcho.native.js +84 -0
  94. package/dist/esm/FloatingPanel/iconEcho.native.js.map +1 -0
  95. package/dist/esm/FloatingPanel/index.mjs +373 -90
  96. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  97. package/dist/esm/FloatingPanel/index.native.js +165 -23
  98. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  99. package/dist/esm/FloatingPanel/paintedBox.mjs +52 -0
  100. package/dist/esm/FloatingPanel/paintedBox.mjs.map +1 -0
  101. package/dist/esm/FloatingPanel/paintedBox.native.js +54 -0
  102. package/dist/esm/FloatingPanel/paintedBox.native.js.map +1 -0
  103. package/dist/esm/FloatingPanel/panelWidth.mjs +63 -0
  104. package/dist/esm/FloatingPanel/panelWidth.mjs.map +1 -0
  105. package/dist/esm/FloatingPanel/panelWidth.native.js +67 -0
  106. package/dist/esm/FloatingPanel/panelWidth.native.js.map +1 -0
  107. package/dist/esm/FloatingPanel/pointAnchor.mjs +34 -5
  108. package/dist/esm/FloatingPanel/pointAnchor.mjs.map +1 -1
  109. package/dist/esm/FloatingPanel/pointAnchor.native.js +37 -8
  110. package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
  111. package/dist/esm/FloatingPanel/useFloatingPanel.mjs +60 -6
  112. package/dist/esm/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  113. package/dist/esm/FloatingPanel/useFloatingPanel.native.js +72 -6
  114. package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  115. package/dist/esm/InputParts/index.mjs +19 -1
  116. package/dist/esm/InputParts/index.mjs.map +1 -1
  117. package/dist/esm/InputParts/index.native.js +20 -2
  118. package/dist/esm/InputParts/index.native.js.map +1 -1
  119. package/dist/esm/Wheel/NativeWheel.native.js +1 -1
  120. package/dist/esm/Wheel/NativeWheel.native.js.map +1 -1
  121. package/dist/esm/Wheel/index.mjs +2 -1
  122. package/dist/esm/Wheel/index.mjs.map +1 -1
  123. package/dist/esm/Wheel/index.native.js +4 -1
  124. package/dist/esm/Wheel/index.native.js.map +1 -1
  125. package/dist/esm/Wheel/wheelShared.mjs +6 -1
  126. package/dist/esm/Wheel/wheelShared.mjs.map +1 -1
  127. package/dist/esm/Wheel/wheelShared.native.js +7 -1
  128. package/dist/esm/Wheel/wheelShared.native.js.map +1 -1
  129. package/dist/esm/fields/Combobox/index.mjs +1 -0
  130. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  131. package/dist/esm/fields/Combobox/index.native.js +1 -0
  132. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  133. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +6 -30
  134. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  135. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
  136. package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  137. package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  138. package/dist/esm/fields/DatePicker/catalog.mjs +2 -28
  139. package/dist/esm/fields/DatePicker/catalog.mjs.map +1 -1
  140. package/dist/esm/fields/DatePicker/catalog.native.js +2 -30
  141. package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
  142. package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
  143. package/dist/esm/fields/DatePicker/parts.mjs +11 -20
  144. package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
  145. package/dist/esm/fields/DatePicker/parts.native.js +13 -22
  146. package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
  147. package/dist/esm/fields/Select/index.mjs +66 -45
  148. package/dist/esm/fields/Select/index.mjs.map +1 -1
  149. package/dist/esm/fields/Select/index.native.js +70 -48
  150. package/dist/esm/fields/Select/index.native.js.map +1 -1
  151. package/dist/esm/fields/Select/shouldInlineChoices.mjs +3 -1
  152. package/dist/esm/fields/Select/shouldInlineChoices.mjs.map +1 -1
  153. package/dist/esm/fields/Select/shouldInlineChoices.native.js +3 -1
  154. package/dist/esm/fields/Select/shouldInlineChoices.native.js.map +1 -1
  155. package/dist/esm/fields/TimePicker/catalog.mjs +4 -25
  156. package/dist/esm/fields/TimePicker/catalog.mjs.map +1 -1
  157. package/dist/esm/fields/TimePicker/catalog.native.js +7 -29
  158. package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
  159. package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
  160. package/dist/esm/fields/TimePicker/parts.mjs +8 -21
  161. package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
  162. package/dist/esm/fields/TimePicker/parts.native.js +8 -21
  163. package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
  164. package/dist/esm/index.mjs +2 -1
  165. package/dist/esm/index.mjs.map +1 -1
  166. package/dist/esm/index.native.js +2 -1
  167. package/dist/esm/index.native.js.map +1 -1
  168. package/dist/esm/shared/floatingList.mjs +14 -5
  169. package/dist/esm/shared/floatingList.mjs.map +1 -1
  170. package/dist/esm/shared/floatingList.native.js +16 -5
  171. package/dist/esm/shared/floatingList.native.js.map +1 -1
  172. package/dist/jsx/Button/circleGlyph.mjs +3 -0
  173. package/dist/jsx/Button/circleGlyph.mjs.map +1 -0
  174. package/dist/jsx/Button/circleGlyph.native.js +31 -0
  175. package/dist/jsx/Button/circleGlyph.native.js.map +1 -0
  176. package/dist/jsx/Button/index.mjs +18 -2
  177. package/dist/jsx/Button/index.mjs.map +1 -1
  178. package/dist/jsx/Button/index.native.js +19 -3
  179. package/dist/jsx/Button/index.native.js.map +1 -1
  180. package/dist/jsx/FloatingPanel/PanelHeader.mjs +24 -0
  181. package/dist/jsx/FloatingPanel/PanelHeader.mjs.map +1 -0
  182. package/dist/jsx/FloatingPanel/PanelHeader.native.js +53 -0
  183. package/dist/jsx/FloatingPanel/PanelHeader.native.js.map +1 -0
  184. package/dist/jsx/FloatingPanel/echoContext.mjs +35 -0
  185. package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -0
  186. package/dist/jsx/FloatingPanel/echoContext.native.js +71 -0
  187. package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -0
  188. package/dist/jsx/FloatingPanel/iconEcho.mjs +77 -0
  189. package/dist/jsx/FloatingPanel/iconEcho.mjs.map +1 -0
  190. package/dist/jsx/FloatingPanel/iconEcho.native.js +114 -0
  191. package/dist/jsx/FloatingPanel/iconEcho.native.js.map +1 -0
  192. package/dist/jsx/FloatingPanel/index.mjs +373 -90
  193. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  194. package/dist/jsx/FloatingPanel/index.native.js +164 -20
  195. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  196. package/dist/jsx/FloatingPanel/paintedBox.mjs +52 -0
  197. package/dist/jsx/FloatingPanel/paintedBox.mjs.map +1 -0
  198. package/dist/jsx/FloatingPanel/paintedBox.native.js +85 -0
  199. package/dist/jsx/FloatingPanel/paintedBox.native.js.map +1 -0
  200. package/dist/jsx/FloatingPanel/panelWidth.mjs +63 -0
  201. package/dist/jsx/FloatingPanel/panelWidth.mjs.map +1 -0
  202. package/dist/jsx/FloatingPanel/panelWidth.native.js +99 -0
  203. package/dist/jsx/FloatingPanel/panelWidth.native.js.map +1 -0
  204. package/dist/jsx/FloatingPanel/pointAnchor.mjs +34 -5
  205. package/dist/jsx/FloatingPanel/pointAnchor.mjs.map +1 -1
  206. package/dist/jsx/FloatingPanel/pointAnchor.native.js +37 -8
  207. package/dist/jsx/FloatingPanel/pointAnchor.native.js.map +1 -1
  208. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs +60 -6
  209. package/dist/jsx/FloatingPanel/useFloatingPanel.mjs.map +1 -1
  210. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js +72 -5
  211. package/dist/jsx/FloatingPanel/useFloatingPanel.native.js.map +1 -1
  212. package/dist/jsx/InputParts/index.mjs +19 -1
  213. package/dist/jsx/InputParts/index.mjs.map +1 -1
  214. package/dist/jsx/InputParts/index.native.js +19 -1
  215. package/dist/jsx/InputParts/index.native.js.map +1 -1
  216. package/dist/jsx/Wheel/NativeWheel.native.js +1 -1
  217. package/dist/jsx/Wheel/NativeWheel.native.js.map +1 -1
  218. package/dist/jsx/Wheel/index.mjs +2 -1
  219. package/dist/jsx/Wheel/index.mjs.map +1 -1
  220. package/dist/jsx/Wheel/index.native.js +4 -1
  221. package/dist/jsx/Wheel/index.native.js.map +1 -1
  222. package/dist/jsx/Wheel/wheelShared.mjs +6 -1
  223. package/dist/jsx/Wheel/wheelShared.mjs.map +1 -1
  224. package/dist/jsx/Wheel/wheelShared.native.js +7 -1
  225. package/dist/jsx/Wheel/wheelShared.native.js.map +1 -1
  226. package/dist/jsx/fields/Combobox/index.mjs +1 -0
  227. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  228. package/dist/jsx/fields/Combobox/index.native.js +1 -0
  229. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  230. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +6 -30
  231. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
  232. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
  233. package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
  234. package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
  235. package/dist/jsx/fields/DatePicker/catalog.mjs +2 -28
  236. package/dist/jsx/fields/DatePicker/catalog.mjs.map +1 -1
  237. package/dist/jsx/fields/DatePicker/catalog.native.js +2 -30
  238. package/dist/jsx/fields/DatePicker/catalog.native.js.map +1 -1
  239. package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
  240. package/dist/jsx/fields/DatePicker/parts.mjs +11 -20
  241. package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
  242. package/dist/jsx/fields/DatePicker/parts.native.js +13 -22
  243. package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
  244. package/dist/jsx/fields/Select/index.mjs +66 -45
  245. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  246. package/dist/jsx/fields/Select/index.native.js +69 -47
  247. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  248. package/dist/jsx/fields/Select/shouldInlineChoices.mjs +3 -1
  249. package/dist/jsx/fields/Select/shouldInlineChoices.mjs.map +1 -1
  250. package/dist/jsx/fields/Select/shouldInlineChoices.native.js +3 -1
  251. package/dist/jsx/fields/Select/shouldInlineChoices.native.js.map +1 -1
  252. package/dist/jsx/fields/TimePicker/catalog.mjs +4 -25
  253. package/dist/jsx/fields/TimePicker/catalog.mjs.map +1 -1
  254. package/dist/jsx/fields/TimePicker/catalog.native.js +7 -29
  255. package/dist/jsx/fields/TimePicker/catalog.native.js.map +1 -1
  256. package/dist/jsx/fields/TimePicker/index.native.js.map +1 -1
  257. package/dist/jsx/fields/TimePicker/parts.mjs +8 -21
  258. package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
  259. package/dist/jsx/fields/TimePicker/parts.native.js +8 -21
  260. package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
  261. package/dist/jsx/index.js +2 -1
  262. package/dist/jsx/index.js.map +1 -1
  263. package/dist/jsx/index.mjs +2 -1
  264. package/dist/jsx/index.mjs.map +1 -1
  265. package/dist/jsx/index.native.js +2 -0
  266. package/dist/jsx/index.native.js.map +1 -1
  267. package/dist/jsx/shared/floatingList.mjs +14 -5
  268. package/dist/jsx/shared/floatingList.mjs.map +1 -1
  269. package/dist/jsx/shared/floatingList.native.js +15 -4
  270. package/dist/jsx/shared/floatingList.native.js.map +1 -1
  271. package/package.json +8 -8
  272. package/src/Button/circleGlyph.ts +6 -0
  273. package/src/Button/index.tsx +25 -7
  274. package/src/FloatingPanel/FloatingPanel.echoStretch.spec.tsx +67 -0
  275. package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +297 -0
  276. package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +280 -3
  277. package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +237 -0
  278. package/src/FloatingPanel/PanelHeader.tsx +26 -0
  279. package/src/FloatingPanel/echoContext.ts +67 -0
  280. package/src/FloatingPanel/iconEcho.tsx +118 -0
  281. package/src/FloatingPanel/index.native.tsx +220 -12
  282. package/src/FloatingPanel/index.tsx +539 -109
  283. package/src/FloatingPanel/paintedBox.spec.ts +95 -0
  284. package/src/FloatingPanel/paintedBox.ts +75 -0
  285. package/src/FloatingPanel/panelWidth.spec.ts +158 -0
  286. package/src/FloatingPanel/panelWidth.ts +122 -0
  287. package/src/FloatingPanel/panelWidthContract.spec.ts +10 -10
  288. package/src/FloatingPanel/pointAnchor.spec.ts +111 -2
  289. package/src/FloatingPanel/pointAnchor.ts +56 -3
  290. package/src/FloatingPanel/useFloatingPanel.spec.tsx +124 -4
  291. package/src/FloatingPanel/useFloatingPanel.ts +112 -34
  292. package/src/InputParts/index.tsx +26 -0
  293. package/src/Wheel/NativeWheel.native.tsx +1 -1
  294. package/src/Wheel/Wheel.spec.tsx +9 -0
  295. package/src/Wheel/index.tsx +12 -3
  296. package/src/Wheel/wheelShared.ts +6 -2
  297. package/src/fields/Combobox/index.tsx +1 -0
  298. package/src/fields/DatePicker/DatePicker.stories.tsx +3 -3
  299. package/src/fields/DatePicker/DatetimePicker.catalog.tsx +17 -45
  300. package/src/fields/DatePicker/DatetimePicker.native.tsx +3 -0
  301. package/src/fields/DatePicker/catalog.tsx +8 -39
  302. package/src/fields/DatePicker/index.native.tsx +3 -0
  303. package/src/fields/DatePicker/parts.tsx +13 -23
  304. package/src/fields/DatePicker/seamlessCover.spec.tsx +180 -0
  305. package/src/fields/DatePicker/touchWeb.spec.tsx +109 -167
  306. package/src/fields/Select/Select.containingBlock.spec.tsx +191 -0
  307. package/src/fields/Select/Select.stories.tsx +43 -0
  308. package/src/fields/Select/index.tsx +109 -45
  309. package/src/fields/Select/shouldInlineChoices.spec.ts +13 -0
  310. package/src/fields/Select/shouldInlineChoices.ts +6 -0
  311. package/src/fields/TimePicker/catalog.tsx +12 -33
  312. package/src/fields/TimePicker/index.native.tsx +2 -0
  313. package/src/fields/TimePicker/parts.tsx +6 -20
  314. package/src/index.ts +3 -0
  315. package/src/shared/floatingList.tsx +21 -5
  316. package/types/Button/circleGlyph.d.ts +7 -0
  317. package/types/Button/circleGlyph.d.ts.map +1 -0
  318. package/types/Button/index.d.ts +2 -6
  319. package/types/Button/index.d.ts.map +1 -1
  320. package/types/FloatingPanel/PanelHeader.d.ts +9 -0
  321. package/types/FloatingPanel/PanelHeader.d.ts.map +1 -0
  322. package/types/FloatingPanel/echoContext.d.ts +38 -0
  323. package/types/FloatingPanel/echoContext.d.ts.map +1 -0
  324. package/types/FloatingPanel/iconEcho.d.ts +29 -0
  325. package/types/FloatingPanel/iconEcho.d.ts.map +1 -0
  326. package/types/FloatingPanel/index.d.ts +69 -0
  327. package/types/FloatingPanel/index.d.ts.map +1 -1
  328. package/types/FloatingPanel/index.native.d.ts +9 -1
  329. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  330. package/types/FloatingPanel/paintedBox.d.ts +29 -0
  331. package/types/FloatingPanel/paintedBox.d.ts.map +1 -0
  332. package/types/FloatingPanel/panelWidth.d.ts +71 -0
  333. package/types/FloatingPanel/panelWidth.d.ts.map +1 -0
  334. package/types/FloatingPanel/pointAnchor.d.ts +17 -1
  335. package/types/FloatingPanel/pointAnchor.d.ts.map +1 -1
  336. package/types/FloatingPanel/useFloatingPanel.d.ts +33 -2
  337. package/types/FloatingPanel/useFloatingPanel.d.ts.map +1 -1
  338. package/types/InputParts/index.d.ts.map +1 -1
  339. package/types/Wheel/index.d.ts.map +1 -1
  340. package/types/Wheel/wheelShared.d.ts +2 -1
  341. package/types/Wheel/wheelShared.d.ts.map +1 -1
  342. package/types/fields/Combobox/index.d.ts.map +1 -1
  343. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts +6 -0
  344. package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
  345. package/types/fields/DatePicker/DatetimePicker.native.d.ts +3 -0
  346. package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
  347. package/types/fields/DatePicker/catalog.d.ts +6 -0
  348. package/types/fields/DatePicker/catalog.d.ts.map +1 -1
  349. package/types/fields/DatePicker/index.native.d.ts +3 -0
  350. package/types/fields/DatePicker/index.native.d.ts.map +1 -1
  351. package/types/fields/DatePicker/parts.d.ts +5 -7
  352. package/types/fields/DatePicker/parts.d.ts.map +1 -1
  353. package/types/fields/Select/index.d.ts +8 -1
  354. package/types/fields/Select/index.d.ts.map +1 -1
  355. package/types/fields/Select/shouldInlineChoices.d.ts +5 -1
  356. package/types/fields/Select/shouldInlineChoices.d.ts.map +1 -1
  357. package/types/fields/TimePicker/catalog.d.ts +7 -1
  358. package/types/fields/TimePicker/catalog.d.ts.map +1 -1
  359. package/types/fields/TimePicker/index.native.d.ts +2 -0
  360. package/types/fields/TimePicker/index.native.d.ts.map +1 -1
  361. package/types/fields/TimePicker/parts.d.ts +1 -3
  362. package/types/fields/TimePicker/parts.d.ts.map +1 -1
  363. package/types/index.d.ts +3 -0
  364. package/types/index.d.ts.map +1 -1
  365. package/types/shared/floatingList.d.ts +5 -1
  366. package/types/shared/floatingList.d.ts.map +1 -1
  367. package/dist/cjs/shared/touchWebPicker.cjs +0 -136
  368. package/dist/cjs/shared/touchWebPicker.native.js +0 -154
  369. package/dist/cjs/shared/touchWebPicker.native.js.map +0 -1
  370. package/dist/esm/shared/touchWebPicker.mjs +0 -105
  371. package/dist/esm/shared/touchWebPicker.mjs.map +0 -1
  372. package/dist/esm/shared/touchWebPicker.native.js +0 -120
  373. package/dist/esm/shared/touchWebPicker.native.js.map +0 -1
  374. package/dist/jsx/shared/touchWebPicker.mjs +0 -105
  375. package/dist/jsx/shared/touchWebPicker.mjs.map +0 -1
  376. package/dist/jsx/shared/touchWebPicker.native.js +0 -154
  377. package/dist/jsx/shared/touchWebPicker.native.js.map +0 -1
  378. package/src/shared/touchWebPicker.spec.ts +0 -98
  379. package/src/shared/touchWebPicker.tsx +0 -158
  380. package/types/shared/touchWebPicker.d.ts +0 -40
  381. package/types/shared/touchWebPicker.d.ts.map +0 -1
@@ -7,6 +7,7 @@ import { Text, View, useProps, isWeb } from "tamagui";
7
7
 
8
8
  import { Field, FieldLayout } from "../../fieldLayout";
9
9
  import { FloatingPanel } from "../../FloatingPanel";
10
+ import type { PanelWidth } from "../../FloatingPanel/panelWidth";
10
11
  import { t } from "../../shared/t";
11
12
  import { TimeWheels } from "../../shared/TimeColumn";
12
13
  import {
@@ -19,12 +20,6 @@ import type { FormFieldProps } from "../../fieldLayout";
19
20
  import { Input as InputParts } from "../../InputParts";
20
21
  import { Skeleton } from "../../Skeleton";
21
22
  import type { FieldComponentProps, Validator } from "../../types";
22
- import {
23
- fromNativeDateValue,
24
- toDatetimeLocalValue,
25
- TouchWebPickerInput,
26
- useCoarsePointer,
27
- } from "../../shared/touchWebPicker";
28
23
 
29
24
  import {
30
25
  CalendarDays,
@@ -87,6 +82,11 @@ export type DatetimePickerProps<
87
82
  onValueChange?: (value: Date | null) => void;
88
83
  /** Native only. `false` keeps the catalog overlay; omit for the OS picker. */
89
84
  native?: boolean;
85
+ /**
86
+ * How wide the open picker is (LC-112, FZ-8438 r3): `"content"`,
87
+ * `"trigger"`, `"screen"` or a fixed width. Unset: at least the field.
88
+ */
89
+ panelWidth?: PanelWidth;
90
90
  };
91
91
 
92
92
  // ---------------------------------------------------------------------------
@@ -273,8 +273,10 @@ function DatetimePickerBody({
273
273
  justifyContent="center"
274
274
  cursor={tabDisabled ? "default" : "pointer"}
275
275
  opacity={tabDisabled ? 0.5 : 1}
276
- theme={active ? ("accent" as any) : undefined}
277
- backgroundColor={active ? "$background" : "transparent"}
276
+ // LC-131 / FZ-8355: the chosen tab is the selection tint with a
277
+ // rounded arc, not an inverted accent slab (FZ-8438 critique).
278
+ backgroundColor={active ? "$selectedBackground" : "transparent"}
279
+ borderRadius={knobProps.borderRadius.borderRadius}
278
280
  onPress={() => {
279
281
  if (!tabDisabled) setActiveTab(tab);
280
282
  }}
@@ -381,12 +383,12 @@ export function DatetimePicker<
381
383
  showSeconds = false,
382
384
  skeleton,
383
385
  id: idProp,
386
+ panelWidth,
384
387
  ..._restProps
385
388
  } = useProps(props);
386
389
 
387
390
  const { resolvedForm, knobProps, id } = useFormField({ form, id: idProp });
388
391
  const resolvedValidators = useResolvedValidators(required, validators, label, name);
389
- const touchWeb = useCoarsePointer();
390
392
 
391
393
  const [open, setOpen] = useState(false);
392
394
  const [selectedDatetime, setSelectedDatetime] = useState<Date | null>(() =>
@@ -470,40 +472,6 @@ export function DatetimePicker<
470
472
  />
471
473
  );
472
474
 
473
- const renderTouchTrigger = (
474
- hasError?: boolean,
475
- blurHandler?: (...args: any[]) => void,
476
- fieldChange?: (value: any) => void,
477
- ) => (
478
- <DatePickerInputTrigger
479
- value={displayValue}
480
- placeholder={placeholder}
481
- disabled={disabled}
482
- onReset={() => handleClearDatetime(fieldChange)}
483
- onButtonPress={() => {}}
484
- touchInput={
485
- <TouchWebPickerInput
486
- kind="datetime-local"
487
- id={id}
488
- value={toDatetimeLocalValue(selectedDatetime, showSeconds)}
489
- min={toDatetimeLocalValue(minDate, showSeconds)}
490
- max={toDatetimeLocalValue(maxDate, showSeconds)}
491
- showSeconds={showSeconds}
492
- disabled={disabled}
493
- required={required}
494
- invalid={hasError}
495
- aria-label={label ? undefined : t("Date and time")}
496
- onValue={(next) => {
497
- const date = fromNativeDateValue(next);
498
- if (date) handleDatetimeSelect(date, fieldChange);
499
- else handleClearDatetime(fieldChange);
500
- }}
501
- onBlur={blurHandler}
502
- />
503
- }
504
- />
505
- );
506
-
507
475
  const renderPopover = (
508
476
  hasError?: boolean,
509
477
  blurHandler?: (...args: any[]) => void,
@@ -521,7 +489,6 @@ export function DatetimePicker<
521
489
  />
522
490
  );
523
491
  }
524
- if (touchWeb) return renderTouchTrigger(hasError, blurHandler, fieldChange);
525
492
  const handleOpenChange = (isOpen: boolean) => {
526
493
  // Re-seed the visible month from the current value on every open.
527
494
  if (isOpen && selectedDatetimeRef.current) setDisplayDate(selectedDatetimeRef.current);
@@ -544,7 +511,12 @@ export function DatetimePicker<
544
511
  disabled={disabled}
545
512
  sizing="grow"
546
513
  contentPadding="none"
547
- widthMode="fit-content"
514
+ widthMode="at-least-trigger"
515
+ panelWidth={panelWidth}
516
+ // LC-112 seamless cover (FZ-8438): touch and narrow web open the same
517
+ // panel over the field, never the browser's own popover; a field too
518
+ // low for the panel takes MPO's bottom sheet (LC-105 collision).
519
+ compactFace={isWeb ? "menu" : undefined}
548
520
  >
549
521
  {pickerContent(fieldChange)}
550
522
  </FloatingPanel>
@@ -2,6 +2,7 @@
2
2
  * Native DatetimePicker — iOS calendar then time wheel; Android date then time.
3
3
  */
4
4
  import type { DeepKeys, DeepValue } from "@tanstack/form-core";
5
+ import type { PanelWidth } from "../../FloatingPanel/panelWidth";
5
6
  import { formatAbsoluteDateTime } from "@multiplatform.one/theme";
6
7
  import { useCallback, useEffect, useMemo, useState } from "react";
7
8
  import { Pressable as RNPressable } from "react-native";
@@ -56,6 +57,8 @@ export type DatetimePickerProps<
56
57
  onChange?: (value: Date | null) => void;
57
58
  onValueChange?: (value: Date | null) => void;
58
59
  native?: boolean;
60
+ /** How wide the catalog picker opens (`native={false}`), LC-112. */
61
+ panelWidth?: PanelWidth;
59
62
  };
60
63
 
61
64
  function formatDatetimeDisplay(
@@ -16,12 +16,6 @@ import type { FormFieldProps } from "../../fieldLayout";
16
16
  import { Input as InputParts } from "../../InputParts";
17
17
  import { Skeleton } from "../../Skeleton";
18
18
  import type { FieldComponentProps, Validator } from "../../types";
19
- import {
20
- fromNativeDateValue,
21
- toDateInputValue,
22
- TouchWebPickerInput,
23
- useCoarsePointer,
24
- } from "../../shared/touchWebPicker";
25
19
 
26
20
  import {
27
21
  CalendarDays,
@@ -39,6 +33,7 @@ import {
39
33
  } from "./parts";
40
34
 
41
35
  import type { ViewMode } from "./parts";
36
+ import type { PanelWidth } from "../../FloatingPanel/panelWidth";
42
37
 
43
38
  export type { ViewMode } from "./parts";
44
39
 
@@ -84,6 +79,11 @@ export type DatePickerProps<
84
79
  onValueChange?: (value: Date | null) => void;
85
80
  /** Native only. `false` keeps the catalog calendar; omit for the OS picker. */
86
81
  native?: boolean;
82
+ /**
83
+ * How wide the open picker is (LC-112, FZ-8438 r3): `"content"`,
84
+ * `"trigger"`, `"screen"` or a fixed width. Unset: at least the field.
85
+ */
86
+ panelWidth?: PanelWidth;
87
87
  };
88
88
 
89
89
  // ---------------------------------------------------------------------------
@@ -211,13 +211,13 @@ export function DatePicker<
211
211
  onBlur,
212
212
  skeleton,
213
213
  id: idProp,
214
+ panelWidth,
214
215
  ..._restProps
215
216
  } = useProps(props);
216
217
 
217
218
  const { resolvedForm, knobProps, id } = useFormField({ form, id: idProp });
218
219
  const resolvedValidators = useResolvedValidators(required, validators, label, name);
219
220
  const hasLabel = Boolean(label);
220
- const touchWeb = useCoarsePointer();
221
221
 
222
222
  const [open, setOpen] = useState(false);
223
223
  const [selectedDate, setSelectedDate] = useState<Date | null>(() =>
@@ -308,38 +308,6 @@ export function DatePicker<
308
308
  .filter(Boolean)
309
309
  .join(" ") || undefined;
310
310
 
311
- if (touchWeb) {
312
- return (
313
- <DatePickerInputTrigger
314
- value={formatDateDisplay(selectedDate)}
315
- placeholder={placeholder}
316
- disabled={disabled}
317
- onReset={() => handleClearDate(fieldChange)}
318
- onButtonPress={() => {}}
319
- touchInput={
320
- <TouchWebPickerInput
321
- kind="date"
322
- id={id}
323
- value={toDateInputValue(selectedDate)}
324
- min={toDateInputValue(minDate)}
325
- max={toDateInputValue(maxDate)}
326
- disabled={disabled}
327
- required={required}
328
- invalid={hasError}
329
- aria-label={hasLabel ? undefined : t("Date")}
330
- aria-describedby={describedBy}
331
- onValue={(next) => {
332
- const date = fromNativeDateValue(next);
333
- if (date) handleDateSelect(date, fieldChange);
334
- else handleClearDate(fieldChange);
335
- }}
336
- onBlur={blurHandler}
337
- />
338
- }
339
- />
340
- );
341
- }
342
-
343
311
  const handleOpenChange = (isOpen: boolean) => {
344
312
  // Re-seed the visible month from the current value on every open —
345
313
  // the value may have changed (externally or by a pick) since mount.
@@ -361,6 +329,7 @@ export function DatePicker<
361
329
  // TimePicker already pass it.
362
330
  disabled={disabled}
363
331
  popoverRef={popoverRef}
332
+ panelWidth={panelWidth}
364
333
  // "Date, Jul 15 2026": VO gets the field name + current value on the
365
334
  // native trigger (the web trigger announces via aria on the Area).
366
335
  triggerA11y={{
@@ -5,6 +5,7 @@
5
5
  * calendar) stay the catalog implementations.
6
6
  */
7
7
  import type { DeepKeys, DeepValue } from "@tanstack/form-core";
8
+ import type { PanelWidth } from "../../FloatingPanel/panelWidth";
8
9
  import { useCallback, useEffect, useState } from "react";
9
10
  import { Pressable as RNPressable } from "react-native";
10
11
  import { useProps } from "tamagui";
@@ -58,6 +59,8 @@ export type DatePickerProps<
58
59
  * native is the OS picker (iOS calendar / time wheel).
59
60
  */
60
61
  native?: boolean;
62
+ /** How wide the catalog picker opens (`native={false}`), LC-112. */
63
+ panelWidth?: PanelWidth;
61
64
  };
62
65
 
63
66
  export type { ViewMode } from "./parts";
@@ -27,6 +27,7 @@ import { AnimatePresence, SizableText, Text, View, isWeb } from "tamagui";
27
27
 
28
28
  import { FloatingPanel, floatingPanelActionProps, isNestedPanelAction } from "../../FloatingPanel";
29
29
  import type { PanelActionEvent } from "../../FloatingPanel/nestedAction";
30
+ import type { PanelWidth } from "../../FloatingPanel/panelWidth";
30
31
  import { Input as InputParts } from "../../InputParts";
31
32
  import { formCommonColors } from "../../shared/colorRamps";
32
33
  import { t } from "../../shared/t";
@@ -861,11 +862,6 @@ interface DatePickerInputTriggerProps {
861
862
  "aria-describedby"?: string;
862
863
  "aria-required"?: boolean;
863
864
  "aria-invalid"?: boolean;
864
- /**
865
- * Touch web (LC-266): the browser's own picker input, laid over the box.
866
- * The input then owns the tap, the focus and the field's a11y name.
867
- */
868
- touchInput?: ReactNode;
869
865
  }
870
866
 
871
867
  export function DatePickerClearButton({
@@ -905,7 +901,6 @@ export function DatePickerInputTrigger({
905
901
  "aria-describedby": ariaDescribedBy,
906
902
  "aria-required": ariaRequired,
907
903
  "aria-invalid": ariaInvalid,
908
- touchInput,
909
904
  }: DatePickerInputTriggerProps) {
910
905
  const handleTriggerKey = (
911
906
  e: PanelActionEvent & { key?: string; code?: string; preventDefault?: () => void },
@@ -948,13 +943,10 @@ export function DatePickerInputTrigger({
948
943
  // on the closed text-field trigger.
949
944
  elevation={undefined}
950
945
  data-testid="date-picker-trigger"
951
- // The touch input is laid absolutely over this box; without a
952
- // positioning context it covers the whole page and takes every tap.
953
- position={touchInput ? "relative" : undefined}
954
- id={touchInput ? undefined : id}
955
- onPress={isWeb && !disabled && !touchInput ? onButtonPress : undefined}
946
+ id={id}
947
+ onPress={isWeb && !disabled ? onButtonPress : undefined}
956
948
  {...(disabled ? { opacity: 0.5, pointerEvents: "none" } : undefined)}
957
- {...(isWeb && !touchInput
949
+ {...(isWeb
958
950
  ? {
959
951
  role: "combobox" as const,
960
952
  "aria-haspopup": "dialog",
@@ -969,7 +961,6 @@ export function DatePickerInputTrigger({
969
961
  }
970
962
  : undefined)}
971
963
  >
972
- {touchInput}
973
964
  <InputParts.Section data-testid="date-picker-glyph">
974
965
  <InputParts.Icon adornment="leading" color={formCommonColors.muted}>
975
966
  <Glyph />
@@ -980,7 +971,6 @@ export function DatePickerInputTrigger({
980
971
  readOnly
981
972
  pointerEvents="none"
982
973
  tabIndex={-1}
983
- aria-hidden={touchInput ? true : undefined}
984
974
  value={value}
985
975
  placeholder={placeholder}
986
976
  disabled={disabled}
@@ -990,14 +980,7 @@ export function DatePickerInputTrigger({
990
980
  </InputParts.Section>
991
981
  {value && isWeb ? (
992
982
  <InputParts.Section>
993
- {touchInput ? (
994
- // Above the touch input, so Clear stays reachable on the box.
995
- <View zIndex={2}>
996
- <DatePickerClearButton onReset={onReset} disabled={disabled} />
997
- </View>
998
- ) : (
999
- <DatePickerClearButton onReset={onReset} disabled={disabled} />
1000
- )}
983
+ <DatePickerClearButton onReset={onReset} disabled={disabled} />
1001
984
  </InputParts.Section>
1002
985
  ) : null}
1003
986
  </InputParts.Box>
@@ -1078,6 +1061,8 @@ interface DatePickerPopoverShellProps {
1078
1061
  /** When set, native hosts render Clear outside the pointerEvents-none trigger. */
1079
1062
  clearValue?: string;
1080
1063
  onClear?: () => void;
1064
+ /** How wide the open picker is (LC-112, FZ-8438 r3). Unset: at least the field. */
1065
+ panelWidth?: PanelWidth;
1081
1066
  }
1082
1067
 
1083
1068
  export function DatePickerPopoverShell({
@@ -1090,6 +1075,7 @@ export function DatePickerPopoverShell({
1090
1075
  triggerA11y,
1091
1076
  clearValue,
1092
1077
  onClear,
1078
+ panelWidth,
1093
1079
  }: DatePickerPopoverShellProps) {
1094
1080
  const nativeClear =
1095
1081
  !isWeb && clearValue && onClear ? (
@@ -1104,7 +1090,11 @@ export function DatePickerPopoverShell({
1104
1090
  disabled={disabled}
1105
1091
  sizing="grow"
1106
1092
  contentPadding="none"
1107
- widthMode="fit-content"
1093
+ // LC-112 seamless cover (FZ-8438): the panel is the field grown open,
1094
+ // at least its width, on every web width and pointer.
1095
+ widthMode="at-least-trigger"
1096
+ panelWidth={panelWidth}
1097
+ compactFace={isWeb ? "menu" : undefined}
1108
1098
  triggerA11y={triggerA11y}
1109
1099
  >
1110
1100
  {children}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * LC-112 seamless cover for the DatePicker family (FZ-8438). Clay rated deck
3
+ * rv_a07d4308a6c445b6 0 good: the date, time and date-and-time panels must
4
+ * open as one surface exactly over their field, at desktop and phone width,
5
+ * on a fine pointer and on touch alike.
6
+ *
7
+ * The browser half is emulated where happy-dom has no layout: the field's
8
+ * rect, and the arc its Box draws (read off the Box's own radius atom, the
9
+ * value a browser would compute from it).
10
+ */
11
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
12
+ import { act, fireEvent, waitFor } from "@testing-library/react";
13
+ import { getTokens, getVariableValue } from "tamagui";
14
+ import type { ReactElement } from "react";
15
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
16
+ import { TimePicker } from "../TimePicker";
17
+ import { DatePicker, DatetimePicker } from "./index";
18
+
19
+ type Rect = { x: number; y: number; width: number; height: number };
20
+
21
+ const viewports: Record<string, { width: number; height: number; field: Rect }> = {
22
+ "1440": { width: 1440, height: 900, field: { x: 16, y: 42, width: 400, height: 40 } },
23
+ "390": { width: 390, height: 844, field: { x: 16, y: 42, width: 358, height: 44 } },
24
+ };
25
+
26
+ const pickers: [string, () => ReactElement][] = [
27
+ ["DatePicker", () => <DatePicker label="Date" name="date" value={new Date(2026, 2, 5)} />],
28
+ ["TimePicker", () => <TimePicker label="Time" name="time" value="14:30" />],
29
+ [
30
+ "DatetimePicker",
31
+ () => (
32
+ <DatetimePicker label="Date and time" name="starts" value={new Date(2026, 2, 5, 14, 30)} />
33
+ ),
34
+ ],
35
+ ];
36
+
37
+ const originalWidth = window.innerWidth;
38
+ const originalHeight = window.innerHeight;
39
+
40
+ function setViewport(width: number, height: number) {
41
+ Object.defineProperty(window, "innerWidth", { configurable: true, value: width });
42
+ Object.defineProperty(window, "innerHeight", { configurable: true, value: height });
43
+ act(() => {
44
+ window.dispatchEvent(new Event("resize"));
45
+ });
46
+ }
47
+
48
+ /** The painted Box of each picker's trigger (the field the user sees). */
49
+ function isFieldBox(el: Element): boolean {
50
+ return (
51
+ el.matches('[data-testid="date-picker-trigger"]') ||
52
+ !!el.parentElement?.matches('[data-testid="time-picker-trigger"]')
53
+ );
54
+ }
55
+
56
+ function atomRadius(el: Element): number {
57
+ for (const c of Array.from(el.classList)) {
58
+ const px = c.match(/^_btlr-(\d+(?:\.\d+)?)px$/);
59
+ if (px) return Number(px[1]);
60
+ const token = c.match(/^_btlr-t-radius-(.+)$/);
61
+ if (token) {
62
+ const value = (getTokens().radius as Record<string, unknown>)[`$${token[1]}`];
63
+ return Number(getVariableValue(value));
64
+ }
65
+ }
66
+ return 0;
67
+ }
68
+
69
+ function emulateBrowser(field: Rect) {
70
+ const rect = {
71
+ ...field,
72
+ top: field.y,
73
+ left: field.x,
74
+ right: field.x + field.width,
75
+ bottom: field.y + field.height,
76
+ toJSON: () => ({}),
77
+ };
78
+ const originalRect = HTMLElement.prototype.getBoundingClientRect;
79
+ vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(
80
+ function (this: HTMLElement) {
81
+ if (this.hasAttribute("data-fp-reference") || isFieldBox(this)) return rect;
82
+ return originalRect.call(this);
83
+ },
84
+ );
85
+ const original = globalThis.getComputedStyle.bind(globalThis);
86
+ const computed = (el: Element, pseudo?: string | null) => {
87
+ const style = original(el, pseudo);
88
+ if (!isFieldBox(el)) return style;
89
+ const radius = `${atomRadius(el)}px`;
90
+ return new Proxy(style, {
91
+ get(target, key) {
92
+ if (key === "borderTopLeftRadius") return radius;
93
+ const value = Reflect.get(target, key, target);
94
+ return typeof value === "function" ? value.bind(target) : value;
95
+ },
96
+ });
97
+ };
98
+ vi.spyOn(globalThis, "getComputedStyle").mockImplementation(computed as typeof getComputedStyle);
99
+ if ((window as unknown) !== globalThis) {
100
+ vi.spyOn(window, "getComputedStyle").mockImplementation(computed as typeof getComputedStyle);
101
+ }
102
+ }
103
+
104
+ function fieldBox(root: ParentNode): HTMLElement {
105
+ const box = Array.from(root.querySelectorAll<HTMLElement>("*")).find(isFieldBox);
106
+ expect(box).toBeTruthy();
107
+ return box as HTMLElement;
108
+ }
109
+
110
+ const corners = (el: Element) =>
111
+ Array.from(el.classList)
112
+ .filter((c) => /^_b[tb][lr]r-/.test(c))
113
+ .sort();
114
+
115
+ beforeEach(() => {
116
+ setViewport(1440, 900);
117
+ });
118
+
119
+ afterEach(() => {
120
+ vi.restoreAllMocks();
121
+ setViewport(originalWidth, originalHeight);
122
+ });
123
+
124
+ describe("DatePicker family: one surface over the field (LC-112, FZ-8438)", () => {
125
+ for (const [size, viewport] of Object.entries(viewports)) {
126
+ for (const [name, render] of pickers) {
127
+ it(`${name} at ${size}: top, start, width and all four arcs are the field's`, async () => {
128
+ setViewport(viewport.width, viewport.height);
129
+ emulateBrowser(viewport.field);
130
+ const result = renderWithProviders(render());
131
+ const box = fieldBox(result.container);
132
+ const drawn = Math.min(atomRadius(box), viewport.field.height / 2);
133
+ expect(drawn).toBeGreaterThan(0);
134
+
135
+ fireEvent.click(box, { detail: 0 });
136
+ const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
137
+ expect(result.queryByTestId("floating-panel-sheet")).toBeNull();
138
+ expect(document.querySelector('input[type="date"], input[type="time"]')).toBeNull();
139
+
140
+ await waitFor(() => expect(panel.style.top).toBe(`${viewport.field.y}px`));
141
+ expect(panel.style.left).toBe(`${viewport.field.x}px`);
142
+ await waitFor(() =>
143
+ expect(parseFloat(panel.style.minWidth)).toBeGreaterThanOrEqual(viewport.field.width),
144
+ );
145
+ await waitFor(() =>
146
+ expect(corners(panel)).toEqual(
147
+ [`_bblr-${drawn}px`, `_bbrr-${drawn}px`, `_btlr-${drawn}px`, `_btrr-${drawn}px`].sort(),
148
+ ),
149
+ );
150
+ });
151
+
152
+ it(`${name} at ${size}: the echo draws no border or divider and sits above the field`, async () => {
153
+ setViewport(viewport.width, viewport.height);
154
+ emulateBrowser(viewport.field);
155
+ const result = renderWithProviders(render());
156
+ const live = fieldBox(result.container);
157
+ fireEvent.click(live, { detail: 0 });
158
+ const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
159
+ const frame = await waitFor(() => {
160
+ const found = panel.querySelector<HTMLElement>("[data-fp-echo-frame]");
161
+ expect(found).not.toBeNull();
162
+ return found as HTMLElement;
163
+ });
164
+ for (const property of ["border-color", "background-color"]) {
165
+ expect(frame.style.getPropertyValue(property)).toBe("transparent");
166
+ expect(frame.style.getPropertyPriority(property)).toBe("important");
167
+ }
168
+ expect(frame.style.getPropertyValue("box-shadow")).toBe("none");
169
+ const row = panel.querySelector<HTMLElement>("[data-fp-trigger-row]") as HTMLElement;
170
+ expect(row.style.width).toBe(`${viewport.field.width}px`);
171
+ expect(row.style.height).toBe(`${viewport.field.height}px`);
172
+ expect(row.style.backgroundColor).toBe(getComputedStyle(panel).backgroundColor);
173
+ expect(panel.style.position).toBe("fixed");
174
+ expect(Number(panel.style.zIndex)).toBeGreaterThan(0);
175
+ expect(live.compareDocumentPosition(panel) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
176
+ expect(live.contains(panel)).toBe(false);
177
+ });
178
+ }
179
+ }
180
+ });