@multiplatform.one/forms 7.80.0 → 7.81.1

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 (221) hide show
  1. package/dist/cjs/AdaptivePopup/index.cjs +2 -1
  2. package/dist/cjs/AdaptivePopup/index.native.js +2 -1
  3. package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
  4. package/dist/cjs/Button/index.cjs +12 -5
  5. package/dist/cjs/Button/index.native.js +14 -6
  6. package/dist/cjs/Button/index.native.js.map +1 -1
  7. package/dist/cjs/FloatingPanel/PanelHeader.cjs +3 -8
  8. package/dist/cjs/FloatingPanel/PanelHeader.native.js +3 -8
  9. package/dist/cjs/FloatingPanel/PanelHeader.native.js.map +1 -1
  10. package/dist/cjs/FloatingPanel/coverRect.cjs +0 -8
  11. package/dist/cjs/FloatingPanel/coverRect.native.js +0 -8
  12. package/dist/cjs/FloatingPanel/coverRect.native.js.map +1 -1
  13. package/dist/cjs/FloatingPanel/echoContext.cjs +5 -27
  14. package/dist/cjs/FloatingPanel/echoContext.native.js +5 -28
  15. package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -1
  16. package/dist/cjs/FloatingPanel/index.cjs +49 -131
  17. package/dist/cjs/FloatingPanel/index.native.js +216 -135
  18. package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
  19. package/dist/cjs/fields/Combobox/index.cjs +3 -10
  20. package/dist/cjs/fields/Combobox/index.native.js +3 -10
  21. package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
  22. package/dist/cjs/fields/Select/InlineChoices.cjs +4 -8
  23. package/dist/cjs/fields/Select/InlineChoices.native.js +4 -8
  24. package/dist/cjs/fields/Select/InlineChoices.native.js.map +1 -1
  25. package/dist/cjs/fields/Select/index.cjs +65 -201
  26. package/dist/cjs/fields/Select/index.native.js +74 -209
  27. package/dist/cjs/fields/Select/index.native.js.map +1 -1
  28. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +2 -2
  29. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
  30. package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  31. package/dist/cjs/index.cjs +4 -0
  32. package/dist/cjs/index.native.js +4 -0
  33. package/dist/cjs/index.native.js.map +1 -1
  34. package/dist/cjs/shared/CheckGlyph.cjs +40 -0
  35. package/dist/cjs/shared/CheckGlyph.native.js +44 -0
  36. package/dist/cjs/shared/CheckGlyph.native.js.map +1 -0
  37. package/dist/cjs/shared/checkedOnField.cjs +104 -0
  38. package/dist/cjs/shared/checkedOnField.native.js +117 -0
  39. package/dist/cjs/shared/checkedOnField.native.js.map +1 -0
  40. package/dist/cjs/shared/floatingList.cjs +12 -5
  41. package/dist/cjs/shared/floatingList.native.js +15 -7
  42. package/dist/cjs/shared/floatingList.native.js.map +1 -1
  43. package/dist/esm/AdaptivePopup/index.mjs +3 -2
  44. package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
  45. package/dist/esm/AdaptivePopup/index.native.js +3 -2
  46. package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
  47. package/dist/esm/Button/index.mjs +12 -5
  48. package/dist/esm/Button/index.mjs.map +1 -1
  49. package/dist/esm/Button/index.native.js +14 -6
  50. package/dist/esm/Button/index.native.js.map +1 -1
  51. package/dist/esm/FloatingPanel/PanelHeader.mjs +3 -8
  52. package/dist/esm/FloatingPanel/PanelHeader.mjs.map +1 -1
  53. package/dist/esm/FloatingPanel/PanelHeader.native.js +3 -8
  54. package/dist/esm/FloatingPanel/PanelHeader.native.js.map +1 -1
  55. package/dist/esm/FloatingPanel/coverRect.mjs +1 -8
  56. package/dist/esm/FloatingPanel/coverRect.mjs.map +1 -1
  57. package/dist/esm/FloatingPanel/coverRect.native.js +1 -8
  58. package/dist/esm/FloatingPanel/coverRect.native.js.map +1 -1
  59. package/dist/esm/FloatingPanel/echoContext.mjs +4 -24
  60. package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -1
  61. package/dist/esm/FloatingPanel/echoContext.native.js +4 -25
  62. package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -1
  63. package/dist/esm/FloatingPanel/index.mjs +53 -135
  64. package/dist/esm/FloatingPanel/index.mjs.map +1 -1
  65. package/dist/esm/FloatingPanel/index.native.js +180 -99
  66. package/dist/esm/FloatingPanel/index.native.js.map +1 -1
  67. package/dist/esm/fields/Combobox/index.mjs +4 -11
  68. package/dist/esm/fields/Combobox/index.mjs.map +1 -1
  69. package/dist/esm/fields/Combobox/index.native.js +4 -11
  70. package/dist/esm/fields/Combobox/index.native.js.map +1 -1
  71. package/dist/esm/fields/Select/InlineChoices.mjs +2 -6
  72. package/dist/esm/fields/Select/InlineChoices.mjs.map +1 -1
  73. package/dist/esm/fields/Select/InlineChoices.native.js +2 -6
  74. package/dist/esm/fields/Select/InlineChoices.native.js.map +1 -1
  75. package/dist/esm/fields/Select/index.mjs +68 -204
  76. package/dist/esm/fields/Select/index.mjs.map +1 -1
  77. package/dist/esm/fields/Select/index.native.js +77 -212
  78. package/dist/esm/fields/Select/index.native.js.map +1 -1
  79. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
  80. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  81. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
  82. package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  83. package/dist/esm/index.mjs +3 -1
  84. package/dist/esm/index.mjs.map +1 -1
  85. package/dist/esm/index.native.js +3 -1
  86. package/dist/esm/index.native.js.map +1 -1
  87. package/dist/esm/shared/CheckGlyph.mjs +15 -0
  88. package/dist/esm/shared/CheckGlyph.mjs.map +1 -0
  89. package/dist/esm/shared/CheckGlyph.native.js +16 -0
  90. package/dist/esm/shared/CheckGlyph.native.js.map +1 -0
  91. package/dist/esm/shared/checkedOnField.mjs +76 -0
  92. package/dist/esm/shared/checkedOnField.mjs.map +1 -0
  93. package/dist/esm/shared/checkedOnField.native.js +86 -0
  94. package/dist/esm/shared/checkedOnField.native.js.map +1 -0
  95. package/dist/esm/shared/floatingList.mjs +9 -5
  96. package/dist/esm/shared/floatingList.mjs.map +1 -1
  97. package/dist/esm/shared/floatingList.native.js +12 -7
  98. package/dist/esm/shared/floatingList.native.js.map +1 -1
  99. package/dist/jsx/AdaptivePopup/index.mjs +3 -2
  100. package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
  101. package/dist/jsx/AdaptivePopup/index.native.js +2 -1
  102. package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
  103. package/dist/jsx/Button/index.mjs +12 -5
  104. package/dist/jsx/Button/index.mjs.map +1 -1
  105. package/dist/jsx/Button/index.native.js +14 -6
  106. package/dist/jsx/Button/index.native.js.map +1 -1
  107. package/dist/jsx/FloatingPanel/PanelHeader.mjs +3 -8
  108. package/dist/jsx/FloatingPanel/PanelHeader.mjs.map +1 -1
  109. package/dist/jsx/FloatingPanel/PanelHeader.native.js +3 -8
  110. package/dist/jsx/FloatingPanel/PanelHeader.native.js.map +1 -1
  111. package/dist/jsx/FloatingPanel/coverRect.mjs +1 -8
  112. package/dist/jsx/FloatingPanel/coverRect.mjs.map +1 -1
  113. package/dist/jsx/FloatingPanel/coverRect.native.js +0 -8
  114. package/dist/jsx/FloatingPanel/coverRect.native.js.map +1 -1
  115. package/dist/jsx/FloatingPanel/echoContext.mjs +4 -24
  116. package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -1
  117. package/dist/jsx/FloatingPanel/echoContext.native.js +5 -28
  118. package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -1
  119. package/dist/jsx/FloatingPanel/index.mjs +53 -135
  120. package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
  121. package/dist/jsx/FloatingPanel/index.native.js +216 -135
  122. package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
  123. package/dist/jsx/fields/Combobox/index.mjs +4 -11
  124. package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
  125. package/dist/jsx/fields/Combobox/index.native.js +3 -10
  126. package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
  127. package/dist/jsx/fields/Select/InlineChoices.mjs +2 -6
  128. package/dist/jsx/fields/Select/InlineChoices.mjs.map +1 -1
  129. package/dist/jsx/fields/Select/InlineChoices.native.js +4 -8
  130. package/dist/jsx/fields/Select/InlineChoices.native.js.map +1 -1
  131. package/dist/jsx/fields/Select/index.mjs +68 -204
  132. package/dist/jsx/fields/Select/index.mjs.map +1 -1
  133. package/dist/jsx/fields/Select/index.native.js +74 -209
  134. package/dist/jsx/fields/Select/index.native.js.map +1 -1
  135. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
  136. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
  137. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
  138. package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
  139. package/dist/jsx/index.js +3 -1
  140. package/dist/jsx/index.js.map +1 -1
  141. package/dist/jsx/index.mjs +3 -1
  142. package/dist/jsx/index.mjs.map +1 -1
  143. package/dist/jsx/index.native.js +4 -0
  144. package/dist/jsx/index.native.js.map +1 -1
  145. package/dist/jsx/shared/CheckGlyph.mjs +15 -0
  146. package/dist/jsx/shared/CheckGlyph.mjs.map +1 -0
  147. package/dist/jsx/shared/CheckGlyph.native.js +44 -0
  148. package/dist/jsx/shared/CheckGlyph.native.js.map +1 -0
  149. package/dist/jsx/shared/checkedOnField.mjs +76 -0
  150. package/dist/jsx/shared/checkedOnField.mjs.map +1 -0
  151. package/dist/jsx/shared/checkedOnField.native.js +117 -0
  152. package/dist/jsx/shared/checkedOnField.native.js.map +1 -0
  153. package/dist/jsx/shared/floatingList.mjs +9 -5
  154. package/dist/jsx/shared/floatingList.mjs.map +1 -1
  155. package/dist/jsx/shared/floatingList.native.js +15 -7
  156. package/dist/jsx/shared/floatingList.native.js.map +1 -1
  157. package/package.json +8 -8
  158. package/src/AdaptivePopup/index.tsx +6 -3
  159. package/src/Button/Button.iconButton.spec.tsx +39 -0
  160. package/src/Button/index.tsx +20 -8
  161. package/src/FloatingPanel/FloatingPanel.iconCover.spec.tsx +279 -0
  162. package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +78 -69
  163. package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +12 -0
  164. package/src/FloatingPanel/PanelHeader.tsx +4 -12
  165. package/src/FloatingPanel/coverRect.ts +2 -15
  166. package/src/FloatingPanel/echoContext.ts +6 -40
  167. package/src/FloatingPanel/index.native.tsx +209 -144
  168. package/src/FloatingPanel/index.tsx +71 -187
  169. package/src/FloatingPanel/pointAnchor.spec.ts +1 -1
  170. package/src/FloatingPanel/pointAnchor.ts +4 -4
  171. package/src/FloatingPanel/sheetGrabber.spec.tsx +53 -0
  172. package/src/fields/Combobox/index.tsx +4 -9
  173. package/src/fields/Select/InlineChoices.tsx +2 -2
  174. package/src/fields/Select/Select.containingBlock.spec.tsx +131 -130
  175. package/src/fields/Select/Select.popUp.native.spec.tsx +276 -0
  176. package/src/fields/Select/Select.stories.tsx +26 -0
  177. package/src/fields/Select/index.tsx +84 -255
  178. package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +3 -3
  179. package/src/index.ts +2 -1
  180. package/src/shared/CheckGlyph.tsx +12 -0
  181. package/src/shared/checkedOnField.ts +116 -0
  182. package/src/shared/floatingList.spec.tsx +154 -1
  183. package/src/shared/floatingList.tsx +18 -9
  184. package/types/AdaptivePopup/index.d.ts.map +1 -1
  185. package/types/Button/index.d.ts.map +1 -1
  186. package/types/FloatingPanel/PanelHeader.d.ts +1 -6
  187. package/types/FloatingPanel/PanelHeader.d.ts.map +1 -1
  188. package/types/FloatingPanel/coverRect.d.ts +2 -11
  189. package/types/FloatingPanel/coverRect.d.ts.map +1 -1
  190. package/types/FloatingPanel/echoContext.d.ts +5 -22
  191. package/types/FloatingPanel/echoContext.d.ts.map +1 -1
  192. package/types/FloatingPanel/index.d.ts +22 -9
  193. package/types/FloatingPanel/index.d.ts.map +1 -1
  194. package/types/FloatingPanel/index.native.d.ts +8 -1
  195. package/types/FloatingPanel/index.native.d.ts.map +1 -1
  196. package/types/FloatingPanel/pointAnchor.d.ts +4 -4
  197. package/types/fields/Combobox/index.d.ts.map +1 -1
  198. package/types/fields/Select/index.d.ts.map +1 -1
  199. package/types/index.d.ts +2 -1
  200. package/types/index.d.ts.map +1 -1
  201. package/types/shared/CheckGlyph.d.ts +10 -0
  202. package/types/shared/CheckGlyph.d.ts.map +1 -0
  203. package/types/shared/checkedOnField.d.ts +54 -0
  204. package/types/shared/checkedOnField.d.ts.map +1 -0
  205. package/types/shared/floatingList.d.ts +5 -2
  206. package/types/shared/floatingList.d.ts.map +1 -1
  207. package/dist/cjs/FloatingPanel/iconEcho.cjs +0 -106
  208. package/dist/cjs/FloatingPanel/iconEcho.native.js +0 -116
  209. package/dist/cjs/FloatingPanel/iconEcho.native.js.map +0 -1
  210. package/dist/esm/FloatingPanel/iconEcho.mjs +0 -79
  211. package/dist/esm/FloatingPanel/iconEcho.mjs.map +0 -1
  212. package/dist/esm/FloatingPanel/iconEcho.native.js +0 -86
  213. package/dist/esm/FloatingPanel/iconEcho.native.js.map +0 -1
  214. package/dist/jsx/FloatingPanel/iconEcho.mjs +0 -79
  215. package/dist/jsx/FloatingPanel/iconEcho.mjs.map +0 -1
  216. package/dist/jsx/FloatingPanel/iconEcho.native.js +0 -116
  217. package/dist/jsx/FloatingPanel/iconEcho.native.js.map +0 -1
  218. package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +0 -357
  219. package/src/FloatingPanel/iconEcho.tsx +0 -124
  220. package/types/FloatingPanel/iconEcho.d.ts +0 -29
  221. package/types/FloatingPanel/iconEcho.d.ts.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { IconSlot, useTouchSurface } from "@multiplatform.one/theme";
2
+ import { CheckGlyph } from "../../shared/CheckGlyph.mjs";
2
3
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, memo } from "react";
3
- import { CaretDownIcon, CaretRightIcon, CheckIcon } from "@phosphor-icons/react";
4
+ import { CaretDownIcon, CaretRightIcon } from "@phosphor-icons/react";
4
5
  import { useClick, useDismiss, useInteractions, useListNavigation, useRole, useTypeahead, FloatingFocusManager } from "@floating-ui/react";
5
6
  import { ensureKeyboardModalityTracking, keyboardFocusRingProps, useMenuRowCheckInk, menuRowChecked, menuRowFrame, sizeRecipeForToken, useGlyphColor, wasKeyboardFocus, transitionProps, Text as HouseText } from "@multiplatform.one/theme";
6
7
  import * as ReactNative from "react-native-web";
@@ -15,8 +16,8 @@ import { Input as InputParts, FocusContext } from "../../InputParts/index.mjs";
15
16
  import { formCommonColors, formInputColors } from "../../shared/colorRamps.mjs";
16
17
  import { warnSelectTooFewOptions } from "../../shared/devWarn.mjs";
17
18
  import { getFieldError, getFieldHeight, mergeFieldHandler, useFormField, useResolvedValidators } from "../../shared/utils.mjs";
18
- import { ScrollArrow } from "../../shared/floatingList.mjs";
19
- import { FloatingPanel, TriggerEchoRow, placeEchoOverTrigger, useFloatingPanel, panelViewportPadding, useViewportGtSm } from "../../FloatingPanel/index.mjs";
19
+ import { growOnScroll, placeCheckedOnField, ScrollArrow, scrollArrowBand } from "../../shared/floatingList.mjs";
20
+ import { FloatingPanel, useFloatingPanel, panelViewportPadding, useViewportGtSm } from "../../FloatingPanel/index.mjs";
20
21
  import { pickerCompactFace, resolveCompactFace } from "../../FloatingPanel/compactFace.mjs";
21
22
  import { PanelPortal } from "../../FloatingPanel/PanelPortal.mjs";
22
23
  import { fixedContainingBlockOrigin } from "../../FloatingPanel/containingBlock.mjs";
@@ -326,11 +327,7 @@ const SelectItem = memo(function SelectItem2({
326
327
  numberOfLines: 1,
327
328
  flex: 1,
328
329
  children: option.label
329
- }), isSelected && /* @__PURE__ */jsx(CheckIcon, {
330
- size: 14,
331
- weight: "bold",
332
- color: ctx.markColor
333
- })]
330
+ }), isSelected && /* @__PURE__ */jsx(CheckGlyph, {})]
334
331
  });
335
332
  });
336
333
  function FloatingSelectCore({
@@ -417,38 +414,23 @@ function FloatingSelectCore({
417
414
  sortedOptionsRef.current = orderOptionsBySelected(options, selected, selectedOrder);
418
415
  }, [options, value, multiple, selectedOrder]);
419
416
  const programmaticScrollRef = useRef(0);
420
- const pinnedTopRef = useRef(0);
421
- const pinnedHeightRef = useRef(0);
422
- const grownRef = useRef(false);
423
- const growUpOnlyRef = useRef(false);
424
- const growDownOnlyRef = useRef(false);
425
417
  const lastScrollTopRef = useRef(0);
426
- const coverScrollRef = useRef(false);
427
- const [coverScroll, setCoverScroll] = useState(false);
428
- const growsUpRef = useRef(false);
429
- const coverTrimRef = useRef(0);
430
- const echoed = !beside && !coverScroll;
418
+ const onFieldRef = useRef(null);
419
+ const opensUpRef = useRef(false);
420
+ const arrowBand = scrollArrowBand(knobProps.menuRow.minHeight);
431
421
  const repositionRef = useRef(null);
432
422
  const panel = useFloatingPanel({
433
423
  open,
434
424
  onOpenChange: setOpen,
435
425
  disabled,
436
426
  repositionRef,
437
- wheelGrowRef: selectedIndex >= 0 ? grownRef : void 0,
438
427
  onBeforeOpen: () => {
439
428
  computeSortedOptions();
440
429
  overlayStyle.current = null;
441
- pinnedTopRef.current = 0;
442
- pinnedHeightRef.current = 0;
443
- grownRef.current = false;
444
- growUpOnlyRef.current = false;
445
- growDownOnlyRef.current = false;
446
430
  lastScrollTopRef.current = 0;
447
431
  programmaticScrollRef.current = 0;
448
- coverScrollRef.current = false;
449
- growsUpRef.current = false;
450
- coverTrimRef.current = 0;
451
- setCoverScroll(false);
432
+ onFieldRef.current = null;
433
+ opensUpRef.current = false;
452
434
  },
453
435
  panelWidth
454
436
  });
@@ -511,10 +493,6 @@ function FloatingSelectCore({
511
493
  if (!selectedItem) return;
512
494
  const isInitial = panel.initializingRef.current;
513
495
  if (isInitial) dropdownElement.style.transition = "none";
514
- if (pinnedTopRef.current === 0 && pinnedHeightRef.current === 0) {
515
- programmaticScrollRef.current++;
516
- dropdownElement.scrollTop = 0;
517
- }
518
496
  const triggerBounds = trigger.getBoundingClientRect();
519
497
  const viewportHeight = window.innerHeight;
520
498
  const originTop = fixedContainingBlockOrigin(dropdownElement).top;
@@ -523,126 +501,34 @@ function FloatingSelectCore({
523
501
  const borderBottomWidth = parseFloat(computedStyle.borderBottomWidth) || 0;
524
502
  const totalBorderWidth = borderTopWidth + borderBottomWidth;
525
503
  const scrollContentHeight = dropdownElement.scrollHeight;
526
- const totalContentHeight = scrollContentHeight + totalBorderWidth;
527
- const firstPlacement = pinnedTopRef.current === 0 && pinnedHeightRef.current === 0;
528
- const boundsTop = panelViewportPadding;
529
- const boundsBottom = viewportHeight - panelViewportPadding;
530
- const echoRow = dropdownElement.querySelector("[data-fp-trigger-row]");
531
- const echoHeight = echoRow ? triggerBounds.height : 0;
532
- const listHeight = totalContentHeight - echoHeight;
533
- const roomBelow = boundsBottom - triggerBounds.top;
534
- const roomAbove = triggerBounds.bottom - boundsTop;
535
- if (firstPlacement && totalContentHeight > roomBelow) {
536
- coverScrollRef.current = true;
537
- growsUpRef.current = roomAbove > roomBelow;
538
- setCoverScroll(true);
539
- }
540
- if (coverScrollRef.current) {
541
- const grown = grownRef.current || growUpOnlyRef.current || growDownOnlyRef.current;
542
- const room = grown ? boundsBottom - boundsTop : growsUpRef.current ? roomAbove : roomBelow;
543
- const trim = grown ? 0 : coverTrimRef.current;
544
- const height2 = Math.max(0, Math.min(listHeight, room - trim));
545
- const anchor = growsUpRef.current ? triggerBounds.bottom - height2 : triggerBounds.top;
546
- const top2 = Math.min(Math.max(anchor, boundsTop), boundsBottom - height2);
547
- const previousTop = pinnedTopRef.current;
548
- if (!overlayStyle.current || overlayStyle.current.top !== top2 - originTop || overlayStyle.current.maxHeight !== height2) {
549
- dropdownElement.style.top = `${top2 - originTop}px`;
550
- dropdownElement.style.maxHeight = `${height2}px`;
551
- dropdownElement.style.height = "";
552
- overlayStyle.current = {
553
- top: top2 - originTop,
554
- maxHeight: height2
555
- };
556
- void dropdownElement.offsetHeight;
557
- }
558
- pinnedTopRef.current = top2;
559
- pinnedHeightRef.current = height2;
560
- if (grown && previousTop > top2 && dropdownElement.scrollTop > 0) {
561
- programmaticScrollRef.current++;
562
- dropdownElement.scrollTop = Math.max(0, dropdownElement.scrollTop - (previousTop - top2));
563
- }
564
- if (echoRow) return;
565
- const rowHeight = selectedItem.offsetHeight || 1;
566
- if (isInitial && selectedIndex >= 0) {
567
- const maxScrollTop = dropdownElement.scrollHeight - dropdownElement.clientHeight;
568
- let scrollTop;
569
- if (growsUpRef.current) {
570
- scrollTop = selectedItem.offsetTop + rowHeight - (triggerBounds.bottom - top2);
571
- } else {
572
- const short = Math.max(0, selectedItem.offsetTop - maxScrollTop - 2);
573
- scrollTop = selectedItem.offsetTop - Math.ceil(short / rowHeight) * rowHeight;
574
- }
575
- programmaticScrollRef.current++;
576
- dropdownElement.scrollTop = Math.min(maxScrollTop, Math.max(0, scrollTop));
577
- }
578
- if (isInitial && !grown) {
579
- const firstRow = listItemsRef.current[0];
580
- const visibleBottom = dropdownElement.scrollTop + dropdownElement.clientHeight;
581
- if (firstRow && visibleBottom < dropdownElement.scrollHeight - 2) {
582
- const cut = (visibleBottom - firstRow.offsetTop) % rowHeight;
583
- if (cut > 3 && cut < rowHeight - 3) {
584
- coverTrimRef.current = cut;
585
- const trimmedHeight = height2 - cut;
586
- const trimmedTop = growsUpRef.current ? top2 + cut : top2;
587
- dropdownElement.style.top = `${trimmedTop - originTop}px`;
588
- dropdownElement.style.maxHeight = `${trimmedHeight}px`;
589
- overlayStyle.current = {
590
- top: trimmedTop - originTop,
591
- maxHeight: trimmedHeight
592
- };
593
- pinnedTopRef.current = trimmedTop;
594
- pinnedHeightRef.current = trimmedHeight;
595
- }
596
- }
597
- }
598
- panel.initializingRef.current = false;
599
- void dropdownElement.offsetHeight;
600
- if (isInitial) dropdownElement.style.transition = panel.panelTransition;
601
- requestAnimationFrame(() => {
602
- if (dropdownElement) panel.updateArrows(dropdownElement);
504
+ const boundsTop = panelViewportPadding + borderTopWidth;
505
+ const boundsBottom = viewportHeight - panelViewportPadding - borderBottomWidth;
506
+ if (!onFieldRef.current) {
507
+ const fit = placeCheckedOnField({
508
+ fieldTop: triggerBounds.top,
509
+ fieldBottom: triggerBounds.bottom,
510
+ rowTop: selectedItem.offsetTop,
511
+ rowHeight: selectedItem.offsetHeight || 1,
512
+ contentHeight: scrollContentHeight,
513
+ boundsTop,
514
+ boundsBottom,
515
+ band: arrowBand
516
+ });
517
+ onFieldRef.current = fit;
518
+ opensUpRef.current = fit.top + fit.height / 2 < (triggerBounds.top + triggerBounds.bottom) / 2;
519
+ } else if (!isInitial) {
520
+ onFieldRef.current = growOnScroll({
521
+ ...onFieldRef.current,
522
+ scrollTop: dropdownElement.scrollTop,
523
+ contentHeight: scrollContentHeight,
524
+ boundsTop,
525
+ boundsBottom
603
526
  });
604
- return;
605
- }
606
- const idealTop = triggerBounds.top;
607
- const idealBottom = idealTop + totalContentHeight;
608
- const pinnedTop = Math.max(panelViewportPadding, idealTop);
609
- const pinnedBottom = Math.min(viewportHeight - panelViewportPadding, idealBottom);
610
- const pinnedHeight = Math.max(120, pinnedBottom - pinnedTop);
611
- if (firstPlacement) {
612
- pinnedTopRef.current = pinnedTop;
613
- pinnedHeightRef.current = pinnedHeight;
614
- }
615
- let top = pinnedTopRef.current;
616
- let height = pinnedHeightRef.current;
617
- if (grownRef.current) {
618
- const canGrowDown = Math.max(0, viewportHeight - panelViewportPadding - (top + height));
619
- height += canGrowDown;
620
- const canGrowUp = Math.max(0, top - panelViewportPadding);
621
- top -= canGrowUp;
622
- height += canGrowUp;
623
- }
624
- if (growUpOnlyRef.current) {
625
- const canGrowUp = Math.max(0, top - panelViewportPadding);
626
- top -= canGrowUp;
627
- height += canGrowUp;
628
- }
629
- if (growDownOnlyRef.current) {
630
- const canGrowDown = Math.max(0, viewportHeight - panelViewportPadding - (top + height));
631
- height += canGrowDown;
632
- }
633
- height = Math.min(height, viewportHeight - top - panelViewportPadding);
634
- height = Math.min(height, totalContentHeight);
635
- height = Math.max(120, height);
636
- const availableViewport = viewportHeight - 2 * panelViewportPadding;
637
- if ((grownRef.current || growUpOnlyRef.current || growDownOnlyRef.current) && height < availableViewport) {
638
- if (panel.placement.startsWith("top")) {
639
- top = panelViewportPadding;
640
- } else {
641
- top = viewportHeight - panelViewportPadding - height;
642
- }
643
527
  }
644
- const cachedOverlayStyle = overlayStyle.current;
645
- if (!cachedOverlayStyle || cachedOverlayStyle.top !== top - originTop || cachedOverlayStyle.maxHeight !== height) {
528
+ const placed = onFieldRef.current;
529
+ const top = placed.top - borderTopWidth;
530
+ const height = placed.height + totalBorderWidth;
531
+ if (!overlayStyle.current || overlayStyle.current.top !== top - originTop || overlayStyle.current.maxHeight !== height) {
646
532
  dropdownElement.style.top = `${top - originTop}px`;
647
533
  dropdownElement.style.maxHeight = `${height}px`;
648
534
  dropdownElement.style.height = "";
@@ -652,35 +538,17 @@ function FloatingSelectCore({
652
538
  };
653
539
  void dropdownElement.offsetHeight;
654
540
  }
655
- if (isInitial && selectedIndex >= 0 && !grownRef.current && !growUpOnlyRef.current && !growDownOnlyRef.current) {
656
- const rowBottom = selectedItem.offsetTop + selectedItem.offsetHeight;
657
- if (rowBottom > dropdownElement.clientHeight) {
658
- const maxScrollTop = dropdownElement.scrollHeight - dropdownElement.clientHeight;
659
- programmaticScrollRef.current++;
660
- dropdownElement.scrollTop = Math.max(0, Math.min(selectedItem.offsetTop - echoHeight, maxScrollTop));
661
- }
541
+ if (Math.abs(dropdownElement.scrollTop - placed.scrollTop) >= 0.5) {
542
+ programmaticScrollRef.current++;
543
+ dropdownElement.scrollTop = placed.scrollTop;
662
544
  }
663
- placeEchoOverTrigger(dropdownElement, {
664
- triggerLeft: triggerBounds.left,
665
- triggerRight: triggerBounds.right,
666
- panelLeft: dropdownElement.getBoundingClientRect().left,
667
- panelWidth: dropdownElement.offsetWidth,
668
- rtl: getComputedStyle(trigger).direction === "rtl"
669
- }, {
670
- stretch: panelWidth !== void 0
671
- });
672
545
  panel.initializingRef.current = false;
673
546
  void dropdownElement.offsetHeight;
674
547
  if (isInitial) dropdownElement.style.transition = panel.panelTransition;
675
548
  requestAnimationFrame(() => {
676
- if (dropdownElement) {
677
- panel.updateArrows(dropdownElement);
678
- requestAnimationFrame(() => {
679
- if (dropdownElement) panel.updateArrows(dropdownElement);
680
- });
681
- }
549
+ if (dropdownElement) panel.updateArrows(dropdownElement);
682
550
  });
683
- }, [selectedIndex, panel.refs, panel.updateArrows, panel.placement, panel.panelTransition, options.length, beside, coverScroll, panelWidth]);
551
+ }, [selectedIndex, panel.refs, panel.updateArrows, panel.panelTransition, options.length, beside, arrowBand]);
684
552
  repositionRef.current = repositionOverlay;
685
553
  useLayoutEffect(() => {
686
554
  if (!open || !panel.mounted) return;
@@ -848,23 +716,10 @@ function FloatingSelectCore({
848
716
  return;
849
717
  }
850
718
  const arrowDir = panel.arrowScrollDirRef.current;
851
- if (arrowDir) {
852
- panel.arrowScrollDirRef.current = null;
853
- lastScrollTopRef.current = el.scrollTop;
854
- if (arrowDir === "down") {
855
- growUpOnlyRef.current = true;
856
- } else {
857
- growDownOnlyRef.current = true;
858
- }
859
- repositionOverlay();
860
- return;
861
- }
719
+ if (arrowDir) panel.arrowScrollDirRef.current = null;
862
720
  const delta = el.scrollTop - lastScrollTopRef.current;
863
721
  lastScrollTopRef.current = el.scrollTop;
864
- if (delta !== 0) {
865
- grownRef.current = true;
866
- repositionOverlay();
867
- }
722
+ if (delta !== 0) repositionOverlay();
868
723
  }, [panel.updateArrows, repositionOverlay]);
869
724
  return /* @__PURE__ */jsxs(Fragment, {
870
725
  children: [/* @__PURE__ */jsxs(InputParts.Box, {
@@ -967,7 +822,7 @@ function FloatingSelectCore({
967
822
  opacity: panel.visible ? 1 : 0,
968
823
  transform: panel.visible ? "scale(1)" : "scale(0.96)",
969
824
  transition: panel.panelTransition,
970
- transformOrigin: coverScroll && growsUpRef.current || panel.placement.startsWith("top") ? "bottom left" : "top left",
825
+ transformOrigin: opensUpRef.current ? "bottom left" : "top left",
971
826
  ...dragProps.style
972
827
  },
973
828
  onPointerDown: dragProps.onPointerDown,
@@ -1007,17 +862,12 @@ function FloatingSelectCore({
1007
862
  "data-testid": "select-dropdown",
1008
863
  paddingVertical: 0,
1009
864
  paddingBottom: panel.coverCornerInset || 0,
1010
- children: [echoed ? /* @__PURE__ */jsx(TriggerEchoRow, {
1011
- sourceRef: panel.triggerRef,
1012
- source: selectedOption?.label ?? placeholder,
1013
- onPress: () => setOpen(false),
1014
- presentational: true
1015
- }) : null, /* @__PURE__ */jsx(ScrollArrow, {
865
+ children: [/* @__PURE__ */jsx(ScrollArrow, {
1016
866
  direction: "up",
1017
867
  scrollRef: panel.refs.floating,
1018
868
  visible: panel.arrowUp,
1019
869
  arrowScrollDirRef: panel.arrowScrollDirRef,
1020
- topOffset: echoed ? panel.triggerRef.current?.getBoundingClientRect().height ?? 0 : 0
870
+ band: arrowBand
1021
871
  }), groupLabel && /* @__PURE__ */jsx(GroupHeader, {
1022
872
  color: textColor,
1023
873
  paddingHorizontal: knobProps.panelPadding.padding,
@@ -1050,7 +900,8 @@ function FloatingSelectCore({
1050
900
  direction: "down",
1051
901
  scrollRef: panel.refs.floating,
1052
902
  visible: panel.arrowDown,
1053
- arrowScrollDirRef: panel.arrowScrollDirRef
903
+ arrowScrollDirRef: panel.arrowScrollDirRef,
904
+ band: arrowBand
1054
905
  })]
1055
906
  })
1056
907
  })
@@ -1078,6 +929,7 @@ function NativeSelectCore({
1078
929
  const insideOverlay = useInsideOverlay();
1079
930
  const compactFace = pickerCompactFace(options.length);
1080
931
  const asMenu = resolveCompactFace(compactFace, insideOverlay) === "menu";
932
+ const beside = asMenu && insideOverlay && opensBesideTrigger(options.length);
1081
933
  const hydrationTouch = useTouchSurface();
1082
934
  const describedBy = useFieldDescribedBy();
1083
935
  const fieldA11y = useFieldA11y();
@@ -1128,6 +980,10 @@ function NativeSelectCore({
1128
980
  requestAnimationFrame(() => listRef.current?.focus());
1129
981
  }
1130
982
  }, [open, selectedIndex]);
983
+ const [onFieldRow, setOnFieldRow] = useState(null);
984
+ useEffect(() => {
985
+ if (!open) setOnFieldRow(null);
986
+ }, [open]);
1131
987
  const handleSelect = useCallback(optionValue => {
1132
988
  if (multiple) {
1133
989
  const current = Array.isArray(value) ? value : value ? [value] : [];
@@ -1238,11 +1094,7 @@ function NativeSelectCore({
1238
1094
  numberOfLines: 1,
1239
1095
  flex: 1,
1240
1096
  children: option.label
1241
- }), selected && /* @__PURE__ */jsx(CheckIcon, {
1242
- size: 14,
1243
- weight: "bold",
1244
- color: markColor
1245
- })]
1097
+ }), selected && /* @__PURE__ */jsx(CheckGlyph, {})]
1246
1098
  }, isWeb ? option.value : void 0);
1247
1099
  if (isWeb) return row;
1248
1100
  return /* @__PURE__ */jsx(RNPressable, {
@@ -1252,6 +1104,14 @@ function NativeSelectCore({
1252
1104
  accessibilityState: {
1253
1105
  selected
1254
1106
  },
1107
+ onLayout: i === Math.max(selectedIndex, 0) ? ({
1108
+ nativeEvent: {
1109
+ layout
1110
+ }
1111
+ }) => setOnFieldRow({
1112
+ top: layout.y,
1113
+ height: layout.height
1114
+ }) : void 0,
1255
1115
  children: row
1256
1116
  }, option.value);
1257
1117
  })]
@@ -1336,10 +1196,14 @@ function NativeSelectCore({
1336
1196
  sheet: true,
1337
1197
  compactFace,
1338
1198
  panelWidth,
1339
- ...(asMenu && insideOverlay && opensBesideTrigger(options.length) ? {
1199
+ ...(beside ? {
1340
1200
  anchorMode: "attach",
1341
1201
  triggerEcho: false
1342
- } : null),
1202
+ } : isWeb || displayOptions.length === 0 ? null : {
1203
+ popUp: {
1204
+ row: onFieldRow
1205
+ }
1206
+ }),
1343
1207
  triggerA11y: {
1344
1208
  label: ariaLabel ?? fieldA11y?.label,
1345
1209
  value: triggerValueText,