@x-plat/design-system 0.14.12 → 0.14.14

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.
@@ -19,26 +19,27 @@ var findScrollParent = (el) => {
19
19
  }
20
20
  return null;
21
21
  };
22
+ var TRIGGER_GAP = 8;
22
23
  var computePlacement = (triggerRect, popW, popH, clip) => {
23
- const roomBelow = clip.bottom - triggerRect.bottom;
24
- const roomAbove = triggerRect.top - clip.top;
24
+ const roomBelow = clip.bottom - triggerRect.bottom - TRIGGER_GAP;
25
+ const roomAbove = triggerRect.top - clip.top - TRIGGER_GAP;
25
26
  let direction;
26
27
  let top;
27
28
  let maxHeight = null;
28
29
  if (popH <= roomBelow) {
29
30
  direction = "bottom";
30
- top = triggerRect.bottom;
31
+ top = triggerRect.bottom + TRIGGER_GAP;
31
32
  } else if (popH <= roomAbove) {
32
33
  direction = "top";
33
- top = triggerRect.top - popH;
34
+ top = triggerRect.top - TRIGGER_GAP - popH;
34
35
  } else {
35
36
  const room = Math.max(roomBelow, roomAbove, 0);
36
37
  if (roomBelow >= roomAbove) {
37
38
  direction = "bottom";
38
- top = triggerRect.bottom;
39
+ top = triggerRect.bottom + TRIGGER_GAP;
39
40
  } else {
40
41
  direction = "top";
41
- top = triggerRect.top - room;
42
+ top = triggerRect.top - TRIGGER_GAP - room;
42
43
  }
43
44
  maxHeight = room;
44
45
  }
@@ -62,15 +63,18 @@ var computePlacement = (triggerRect, popW, popH, clip) => {
62
63
  };
63
64
  };
64
65
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
65
- const [direction, setDirection] = React.useState("bottom");
66
66
  const directionRef = React.useRef("bottom");
67
67
  const sizeRef = React.useRef(null);
68
68
  const scrollParentRef = React.useRef(null);
69
+ const placedRef = React.useRef(false);
69
70
  const calculatePosition = React.useCallback((remeasure = false) => {
70
71
  const pop = popRef.current;
71
72
  if (!triggerRef.current || !pop) return;
72
73
  if (remeasure || !sizeRef.current) {
73
- sizeRef.current = { w: pop.offsetWidth, h: pop.offsetHeight };
74
+ sizeRef.current = {
75
+ w: pop.offsetWidth,
76
+ h: Math.max(pop.offsetHeight, pop.scrollHeight)
77
+ };
74
78
  }
75
79
  const { w: popW, h: popH } = sizeRef.current;
76
80
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -85,6 +89,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
85
89
  left: Math.max(parentRect?.left ?? 0, 0),
86
90
  right: Math.min(parentRect?.right ?? window.innerWidth, window.innerWidth)
87
91
  };
92
+ const first = !placedRef.current;
93
+ if (first) pop.style.transition = "none";
88
94
  const { direction: next, top, left, over, maxHeight } = computePlacement(
89
95
  triggerRect,
90
96
  popW,
@@ -95,15 +101,20 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
95
101
  pop.style.left = `${left + window.scrollX}px`;
96
102
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
97
103
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
98
- if (next !== directionRef.current) {
99
- directionRef.current = next;
100
- setDirection(next);
104
+ directionRef.current = next;
105
+ pop.classList.toggle("top", next === "top");
106
+ pop.classList.toggle("bottom", next === "bottom");
107
+ if (first) {
108
+ void pop.offsetHeight;
109
+ pop.style.transition = "";
110
+ placedRef.current = true;
101
111
  }
102
112
  }, [triggerRef, popRef]);
103
113
  React.useLayoutEffect(() => {
104
114
  if (!enabled) {
105
115
  sizeRef.current = null;
106
116
  scrollParentRef.current = null;
117
+ placedRef.current = false;
107
118
  return;
108
119
  }
109
120
  if (triggerRef.current) {
@@ -132,7 +143,6 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
132
143
  window.removeEventListener("scroll", onScroll, true);
133
144
  };
134
145
  }, [calculatePosition, enabled]);
135
- return { direction };
136
146
  };
137
147
  var useAutoPosition_default = useAutoPosition;
138
148
 
@@ -1362,7 +1372,7 @@ var SelectRoot = (props) => {
1362
1372
  close();
1363
1373
  triggerRef.current?.focus({ preventScroll: true });
1364
1374
  });
1365
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
1375
+ useAutoPosition_default(triggerRef, contentRef, mounted);
1366
1376
  const setSelected = React6.useCallback(
1367
1377
  (label2, itemValue) => {
1368
1378
  if (!isControlled) {
@@ -1455,7 +1465,7 @@ var SelectRoot = (props) => {
1455
1465
  mounted && /* @__PURE__ */ jsx297(Portal_default, { children: /* @__PURE__ */ jsxs190(
1456
1466
  "div",
1457
1467
  {
1458
- className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
1468
+ className: clsx_default("lib-xplat-select-content", size, stateClass),
1459
1469
  ref: contentRef,
1460
1470
  style: { width: triggerRef.current?.offsetWidth },
1461
1471
  role: "listbox",
@@ -55,26 +55,27 @@ var findScrollParent = (el) => {
55
55
  }
56
56
  return null;
57
57
  };
58
+ var TRIGGER_GAP = 8;
58
59
  var computePlacement = (triggerRect, popW, popH, clip) => {
59
- const roomBelow = clip.bottom - triggerRect.bottom;
60
- const roomAbove = triggerRect.top - clip.top;
60
+ const roomBelow = clip.bottom - triggerRect.bottom - TRIGGER_GAP;
61
+ const roomAbove = triggerRect.top - clip.top - TRIGGER_GAP;
61
62
  let direction;
62
63
  let top;
63
64
  let maxHeight = null;
64
65
  if (popH <= roomBelow) {
65
66
  direction = "bottom";
66
- top = triggerRect.bottom;
67
+ top = triggerRect.bottom + TRIGGER_GAP;
67
68
  } else if (popH <= roomAbove) {
68
69
  direction = "top";
69
- top = triggerRect.top - popH;
70
+ top = triggerRect.top - TRIGGER_GAP - popH;
70
71
  } else {
71
72
  const room = Math.max(roomBelow, roomAbove, 0);
72
73
  if (roomBelow >= roomAbove) {
73
74
  direction = "bottom";
74
- top = triggerRect.bottom;
75
+ top = triggerRect.bottom + TRIGGER_GAP;
75
76
  } else {
76
77
  direction = "top";
77
- top = triggerRect.top - room;
78
+ top = triggerRect.top - TRIGGER_GAP - room;
78
79
  }
79
80
  maxHeight = room;
80
81
  }
@@ -98,15 +99,18 @@ var computePlacement = (triggerRect, popW, popH, clip) => {
98
99
  };
99
100
  };
100
101
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
101
- const [direction, setDirection] = import_react.default.useState("bottom");
102
102
  const directionRef = import_react.default.useRef("bottom");
103
103
  const sizeRef = import_react.default.useRef(null);
104
104
  const scrollParentRef = import_react.default.useRef(null);
105
+ const placedRef = import_react.default.useRef(false);
105
106
  const calculatePosition = import_react.default.useCallback((remeasure = false) => {
106
107
  const pop = popRef.current;
107
108
  if (!triggerRef.current || !pop) return;
108
109
  if (remeasure || !sizeRef.current) {
109
- sizeRef.current = { w: pop.offsetWidth, h: pop.offsetHeight };
110
+ sizeRef.current = {
111
+ w: pop.offsetWidth,
112
+ h: Math.max(pop.offsetHeight, pop.scrollHeight)
113
+ };
110
114
  }
111
115
  const { w: popW, h: popH } = sizeRef.current;
112
116
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -121,6 +125,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
121
125
  left: Math.max(parentRect?.left ?? 0, 0),
122
126
  right: Math.min(parentRect?.right ?? window.innerWidth, window.innerWidth)
123
127
  };
128
+ const first = !placedRef.current;
129
+ if (first) pop.style.transition = "none";
124
130
  const { direction: next, top, left, over, maxHeight } = computePlacement(
125
131
  triggerRect,
126
132
  popW,
@@ -131,15 +137,20 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
131
137
  pop.style.left = `${left + window.scrollX}px`;
132
138
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
133
139
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
134
- if (next !== directionRef.current) {
135
- directionRef.current = next;
136
- setDirection(next);
140
+ directionRef.current = next;
141
+ pop.classList.toggle("top", next === "top");
142
+ pop.classList.toggle("bottom", next === "bottom");
143
+ if (first) {
144
+ void pop.offsetHeight;
145
+ pop.style.transition = "";
146
+ placedRef.current = true;
137
147
  }
138
148
  }, [triggerRef, popRef]);
139
149
  import_react.default.useLayoutEffect(() => {
140
150
  if (!enabled) {
141
151
  sizeRef.current = null;
142
152
  scrollParentRef.current = null;
153
+ placedRef.current = false;
143
154
  return;
144
155
  }
145
156
  if (triggerRef.current) {
@@ -168,7 +179,6 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
168
179
  window.removeEventListener("scroll", onScroll, true);
169
180
  };
170
181
  }, [calculatePosition, enabled]);
171
- return { direction };
172
182
  };
173
183
  var useAutoPosition_default = useAutoPosition;
174
184
 
@@ -19,26 +19,27 @@ var findScrollParent = (el) => {
19
19
  }
20
20
  return null;
21
21
  };
22
+ var TRIGGER_GAP = 8;
22
23
  var computePlacement = (triggerRect, popW, popH, clip) => {
23
- const roomBelow = clip.bottom - triggerRect.bottom;
24
- const roomAbove = triggerRect.top - clip.top;
24
+ const roomBelow = clip.bottom - triggerRect.bottom - TRIGGER_GAP;
25
+ const roomAbove = triggerRect.top - clip.top - TRIGGER_GAP;
25
26
  let direction;
26
27
  let top;
27
28
  let maxHeight = null;
28
29
  if (popH <= roomBelow) {
29
30
  direction = "bottom";
30
- top = triggerRect.bottom;
31
+ top = triggerRect.bottom + TRIGGER_GAP;
31
32
  } else if (popH <= roomAbove) {
32
33
  direction = "top";
33
- top = triggerRect.top - popH;
34
+ top = triggerRect.top - TRIGGER_GAP - popH;
34
35
  } else {
35
36
  const room = Math.max(roomBelow, roomAbove, 0);
36
37
  if (roomBelow >= roomAbove) {
37
38
  direction = "bottom";
38
- top = triggerRect.bottom;
39
+ top = triggerRect.bottom + TRIGGER_GAP;
39
40
  } else {
40
41
  direction = "top";
41
- top = triggerRect.top - room;
42
+ top = triggerRect.top - TRIGGER_GAP - room;
42
43
  }
43
44
  maxHeight = room;
44
45
  }
@@ -62,15 +63,18 @@ var computePlacement = (triggerRect, popW, popH, clip) => {
62
63
  };
63
64
  };
64
65
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
65
- const [direction, setDirection] = React.useState("bottom");
66
66
  const directionRef = React.useRef("bottom");
67
67
  const sizeRef = React.useRef(null);
68
68
  const scrollParentRef = React.useRef(null);
69
+ const placedRef = React.useRef(false);
69
70
  const calculatePosition = React.useCallback((remeasure = false) => {
70
71
  const pop = popRef.current;
71
72
  if (!triggerRef.current || !pop) return;
72
73
  if (remeasure || !sizeRef.current) {
73
- sizeRef.current = { w: pop.offsetWidth, h: pop.offsetHeight };
74
+ sizeRef.current = {
75
+ w: pop.offsetWidth,
76
+ h: Math.max(pop.offsetHeight, pop.scrollHeight)
77
+ };
74
78
  }
75
79
  const { w: popW, h: popH } = sizeRef.current;
76
80
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -85,6 +89,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
85
89
  left: Math.max(parentRect?.left ?? 0, 0),
86
90
  right: Math.min(parentRect?.right ?? window.innerWidth, window.innerWidth)
87
91
  };
92
+ const first = !placedRef.current;
93
+ if (first) pop.style.transition = "none";
88
94
  const { direction: next, top, left, over, maxHeight } = computePlacement(
89
95
  triggerRect,
90
96
  popW,
@@ -95,15 +101,20 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
95
101
  pop.style.left = `${left + window.scrollX}px`;
96
102
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
97
103
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
98
- if (next !== directionRef.current) {
99
- directionRef.current = next;
100
- setDirection(next);
104
+ directionRef.current = next;
105
+ pop.classList.toggle("top", next === "top");
106
+ pop.classList.toggle("bottom", next === "bottom");
107
+ if (first) {
108
+ void pop.offsetHeight;
109
+ pop.style.transition = "";
110
+ placedRef.current = true;
101
111
  }
102
112
  }, [triggerRef, popRef]);
103
113
  React.useLayoutEffect(() => {
104
114
  if (!enabled) {
105
115
  sizeRef.current = null;
106
116
  scrollParentRef.current = null;
117
+ placedRef.current = false;
107
118
  return;
108
119
  }
109
120
  if (triggerRef.current) {
@@ -132,7 +143,6 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
132
143
  window.removeEventListener("scroll", onScroll, true);
133
144
  };
134
145
  }, [calculatePosition, enabled]);
135
- return { direction };
136
146
  };
137
147
  var useAutoPosition_default = useAutoPosition;
138
148
 
@@ -3999,26 +3999,27 @@ var findScrollParent = (el) => {
3999
3999
  }
4000
4000
  return null;
4001
4001
  };
4002
+ var TRIGGER_GAP = 8;
4002
4003
  var computePlacement = (triggerRect, popW, popH, clip) => {
4003
- const roomBelow = clip.bottom - triggerRect.bottom;
4004
- const roomAbove = triggerRect.top - clip.top;
4004
+ const roomBelow = clip.bottom - triggerRect.bottom - TRIGGER_GAP;
4005
+ const roomAbove = triggerRect.top - clip.top - TRIGGER_GAP;
4005
4006
  let direction;
4006
4007
  let top;
4007
4008
  let maxHeight = null;
4008
4009
  if (popH <= roomBelow) {
4009
4010
  direction = "bottom";
4010
- top = triggerRect.bottom;
4011
+ top = triggerRect.bottom + TRIGGER_GAP;
4011
4012
  } else if (popH <= roomAbove) {
4012
4013
  direction = "top";
4013
- top = triggerRect.top - popH;
4014
+ top = triggerRect.top - TRIGGER_GAP - popH;
4014
4015
  } else {
4015
4016
  const room = Math.max(roomBelow, roomAbove, 0);
4016
4017
  if (roomBelow >= roomAbove) {
4017
4018
  direction = "bottom";
4018
- top = triggerRect.bottom;
4019
+ top = triggerRect.bottom + TRIGGER_GAP;
4019
4020
  } else {
4020
4021
  direction = "top";
4021
- top = triggerRect.top - room;
4022
+ top = triggerRect.top - TRIGGER_GAP - room;
4022
4023
  }
4023
4024
  maxHeight = room;
4024
4025
  }
@@ -4042,15 +4043,18 @@ var computePlacement = (triggerRect, popW, popH, clip) => {
4042
4043
  };
4043
4044
  };
4044
4045
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
4045
- const [direction, setDirection] = import_react19.default.useState("bottom");
4046
4046
  const directionRef = import_react19.default.useRef("bottom");
4047
4047
  const sizeRef = import_react19.default.useRef(null);
4048
4048
  const scrollParentRef = import_react19.default.useRef(null);
4049
+ const placedRef = import_react19.default.useRef(false);
4049
4050
  const calculatePosition = import_react19.default.useCallback((remeasure = false) => {
4050
4051
  const pop = popRef.current;
4051
4052
  if (!triggerRef.current || !pop) return;
4052
4053
  if (remeasure || !sizeRef.current) {
4053
- sizeRef.current = { w: pop.offsetWidth, h: pop.offsetHeight };
4054
+ sizeRef.current = {
4055
+ w: pop.offsetWidth,
4056
+ h: Math.max(pop.offsetHeight, pop.scrollHeight)
4057
+ };
4054
4058
  }
4055
4059
  const { w: popW, h: popH } = sizeRef.current;
4056
4060
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -4065,6 +4069,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
4065
4069
  left: Math.max(parentRect?.left ?? 0, 0),
4066
4070
  right: Math.min(parentRect?.right ?? window.innerWidth, window.innerWidth)
4067
4071
  };
4072
+ const first = !placedRef.current;
4073
+ if (first) pop.style.transition = "none";
4068
4074
  const { direction: next, top, left, over, maxHeight } = computePlacement(
4069
4075
  triggerRect,
4070
4076
  popW,
@@ -4075,15 +4081,20 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
4075
4081
  pop.style.left = `${left + window.scrollX}px`;
4076
4082
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
4077
4083
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
4078
- if (next !== directionRef.current) {
4079
- directionRef.current = next;
4080
- setDirection(next);
4084
+ directionRef.current = next;
4085
+ pop.classList.toggle("top", next === "top");
4086
+ pop.classList.toggle("bottom", next === "bottom");
4087
+ if (first) {
4088
+ void pop.offsetHeight;
4089
+ pop.style.transition = "";
4090
+ placedRef.current = true;
4081
4091
  }
4082
4092
  }, [triggerRef, popRef]);
4083
4093
  import_react19.default.useLayoutEffect(() => {
4084
4094
  if (!enabled) {
4085
4095
  sizeRef.current = null;
4086
4096
  scrollParentRef.current = null;
4097
+ placedRef.current = false;
4087
4098
  return;
4088
4099
  }
4089
4100
  if (triggerRef.current) {
@@ -4112,7 +4123,6 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
4112
4123
  window.removeEventListener("scroll", onScroll, true);
4113
4124
  };
4114
4125
  }, [calculatePosition, enabled]);
4115
- return { direction };
4116
4126
  };
4117
4127
  var useAutoPosition_default = useAutoPosition;
4118
4128
 
@@ -4150,7 +4160,7 @@ var Dropdown = (props) => {
4150
4160
  const [visible, setVisible] = import_react21.default.useState(false);
4151
4161
  const triggerRef = import_react21.default.useRef(null);
4152
4162
  const menuRef = import_react21.default.useRef(null);
4153
- const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
4163
+ useAutoPosition_default(triggerRef, menuRef, mounted);
4154
4164
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
4155
4165
  useCloseOnContainerScroll(isOpen, menuRef, () => setIsOpen(false));
4156
4166
  useEscapeKey(isOpen, () => {
@@ -4186,7 +4196,7 @@ var Dropdown = (props) => {
4186
4196
  "div",
4187
4197
  {
4188
4198
  ref: menuRef,
4189
- className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
4199
+ className: clsx_default("lib-xplat-dropdown-menu", { visible }),
4190
4200
  role: "menu",
4191
4201
  children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime322.jsx)(
4192
4202
  "button",
@@ -6088,7 +6098,7 @@ var PopOver = (props) => {
6088
6098
  onClose();
6089
6099
  triggerRef.current?.focus({ preventScroll: true });
6090
6100
  });
6091
- const position = useAutoPosition_default(triggerRef, popRef, localOpen);
6101
+ useAutoPosition_default(triggerRef, popRef, localOpen);
6092
6102
  import_react27.default.useEffect(() => {
6093
6103
  if (isOpen) {
6094
6104
  setLocalOpen(isOpen);
@@ -6117,7 +6127,6 @@ var PopOver = (props) => {
6117
6127
  {
6118
6128
  className: clsx_default(
6119
6129
  "lib-xplat-pop-over-content",
6120
- position.direction,
6121
6130
  eventTrigger && "visible"
6122
6131
  ),
6123
6132
  ref: popRef,
@@ -6369,7 +6378,7 @@ var SelectRoot = (props) => {
6369
6378
  close();
6370
6379
  triggerRef.current?.focus({ preventScroll: true });
6371
6380
  });
6372
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
6381
+ useAutoPosition_default(triggerRef, contentRef, mounted);
6373
6382
  const setSelected = import_react31.default.useCallback(
6374
6383
  (label2, itemValue) => {
6375
6384
  if (!isControlled) {
@@ -6462,7 +6471,7 @@ var SelectRoot = (props) => {
6462
6471
  mounted && /* @__PURE__ */ (0, import_jsx_runtime337.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime337.jsxs)(
6463
6472
  "div",
6464
6473
  {
6465
- className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
6474
+ className: clsx_default("lib-xplat-select-content", size, stateClass),
6466
6475
  ref: contentRef,
6467
6476
  style: { width: triggerRef.current?.offsetWidth },
6468
6477
  role: "listbox",
@@ -3282,11 +3282,11 @@
3282
3282
  box-shadow: var(--semantic-shadow-md);
3283
3283
  padding: var(--spacing-space-1) 0;
3284
3284
  opacity: 0;
3285
- transform: translateY(-4px);
3285
+ transform: translateY(4px);
3286
3286
  transition: opacity 0.15s ease, transform 0.15s ease;
3287
3287
  }
3288
3288
  .lib-xplat-dropdown-menu.bottom {
3289
- transform: translateY(4px);
3289
+ transform: translateY(-4px);
3290
3290
  }
3291
3291
  .lib-xplat-dropdown-menu.visible {
3292
3292
  opacity: 1;
@@ -4513,7 +4513,7 @@
4513
4513
  transition: transform 0.2s ease, opacity 0.2s ease;
4514
4514
  }
4515
4515
  .lib-xplat-select-content.bottom {
4516
- transform: translateY(8px);
4516
+ transform: translateY(-4px);
4517
4517
  }
4518
4518
  .lib-xplat-select-content.bottom.visible {
4519
4519
  opacity: 1;
@@ -4521,12 +4521,12 @@
4521
4521
  }
4522
4522
  .lib-xplat-select-content.bottom.exit {
4523
4523
  opacity: 0;
4524
- transform: translateY(8px);
4524
+ transform: translateY(-4px);
4525
4525
  }
4526
4526
  .lib-xplat-select-content {
4527
4527
  }
4528
4528
  .lib-xplat-select-content.top {
4529
- transform: translateY(-8px);
4529
+ transform: translateY(4px);
4530
4530
  }
4531
4531
  .lib-xplat-select-content.top.visible {
4532
4532
  opacity: 1;
@@ -4534,7 +4534,7 @@
4534
4534
  }
4535
4535
  .lib-xplat-select-content.top.exit {
4536
4536
  opacity: 0;
4537
- transform: translateY(-8px);
4537
+ transform: translateY(4px);
4538
4538
  }
4539
4539
  .lib-xplat-select-content.sm .select-item {
4540
4540
  padding: var(--spacing-space-2) var(--spacing-space-2);
@@ -3897,26 +3897,27 @@ var findScrollParent = (el) => {
3897
3897
  }
3898
3898
  return null;
3899
3899
  };
3900
+ var TRIGGER_GAP = 8;
3900
3901
  var computePlacement = (triggerRect, popW, popH, clip) => {
3901
- const roomBelow = clip.bottom - triggerRect.bottom;
3902
- const roomAbove = triggerRect.top - clip.top;
3902
+ const roomBelow = clip.bottom - triggerRect.bottom - TRIGGER_GAP;
3903
+ const roomAbove = triggerRect.top - clip.top - TRIGGER_GAP;
3903
3904
  let direction;
3904
3905
  let top;
3905
3906
  let maxHeight = null;
3906
3907
  if (popH <= roomBelow) {
3907
3908
  direction = "bottom";
3908
- top = triggerRect.bottom;
3909
+ top = triggerRect.bottom + TRIGGER_GAP;
3909
3910
  } else if (popH <= roomAbove) {
3910
3911
  direction = "top";
3911
- top = triggerRect.top - popH;
3912
+ top = triggerRect.top - TRIGGER_GAP - popH;
3912
3913
  } else {
3913
3914
  const room = Math.max(roomBelow, roomAbove, 0);
3914
3915
  if (roomBelow >= roomAbove) {
3915
3916
  direction = "bottom";
3916
- top = triggerRect.bottom;
3917
+ top = triggerRect.bottom + TRIGGER_GAP;
3917
3918
  } else {
3918
3919
  direction = "top";
3919
- top = triggerRect.top - room;
3920
+ top = triggerRect.top - TRIGGER_GAP - room;
3920
3921
  }
3921
3922
  maxHeight = room;
3922
3923
  }
@@ -3940,15 +3941,18 @@ var computePlacement = (triggerRect, popW, popH, clip) => {
3940
3941
  };
3941
3942
  };
3942
3943
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3943
- const [direction, setDirection] = React19.useState("bottom");
3944
3944
  const directionRef = React19.useRef("bottom");
3945
3945
  const sizeRef = React19.useRef(null);
3946
3946
  const scrollParentRef = React19.useRef(null);
3947
+ const placedRef = React19.useRef(false);
3947
3948
  const calculatePosition = React19.useCallback((remeasure = false) => {
3948
3949
  const pop = popRef.current;
3949
3950
  if (!triggerRef.current || !pop) return;
3950
3951
  if (remeasure || !sizeRef.current) {
3951
- sizeRef.current = { w: pop.offsetWidth, h: pop.offsetHeight };
3952
+ sizeRef.current = {
3953
+ w: pop.offsetWidth,
3954
+ h: Math.max(pop.offsetHeight, pop.scrollHeight)
3955
+ };
3952
3956
  }
3953
3957
  const { w: popW, h: popH } = sizeRef.current;
3954
3958
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -3963,6 +3967,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3963
3967
  left: Math.max(parentRect?.left ?? 0, 0),
3964
3968
  right: Math.min(parentRect?.right ?? window.innerWidth, window.innerWidth)
3965
3969
  };
3970
+ const first = !placedRef.current;
3971
+ if (first) pop.style.transition = "none";
3966
3972
  const { direction: next, top, left, over, maxHeight } = computePlacement(
3967
3973
  triggerRect,
3968
3974
  popW,
@@ -3973,15 +3979,20 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
3973
3979
  pop.style.left = `${left + window.scrollX}px`;
3974
3980
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
3975
3981
  pop.style.clipPath = over.top || over.right || over.bottom || over.left ? `inset(${over.top}px ${over.right}px ${over.bottom}px ${over.left}px)` : "none";
3976
- if (next !== directionRef.current) {
3977
- directionRef.current = next;
3978
- setDirection(next);
3982
+ directionRef.current = next;
3983
+ pop.classList.toggle("top", next === "top");
3984
+ pop.classList.toggle("bottom", next === "bottom");
3985
+ if (first) {
3986
+ void pop.offsetHeight;
3987
+ pop.style.transition = "";
3988
+ placedRef.current = true;
3979
3989
  }
3980
3990
  }, [triggerRef, popRef]);
3981
3991
  React19.useLayoutEffect(() => {
3982
3992
  if (!enabled) {
3983
3993
  sizeRef.current = null;
3984
3994
  scrollParentRef.current = null;
3995
+ placedRef.current = false;
3985
3996
  return;
3986
3997
  }
3987
3998
  if (triggerRef.current) {
@@ -4010,7 +4021,6 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
4010
4021
  window.removeEventListener("scroll", onScroll, true);
4011
4022
  };
4012
4023
  }, [calculatePosition, enabled]);
4013
- return { direction };
4014
4024
  };
4015
4025
  var useAutoPosition_default = useAutoPosition;
4016
4026
 
@@ -4048,7 +4058,7 @@ var Dropdown = (props) => {
4048
4058
  const [visible, setVisible] = React21.useState(false);
4049
4059
  const triggerRef = React21.useRef(null);
4050
4060
  const menuRef = React21.useRef(null);
4051
- const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
4061
+ useAutoPosition_default(triggerRef, menuRef, mounted);
4052
4062
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
4053
4063
  useCloseOnContainerScroll(isOpen, menuRef, () => setIsOpen(false));
4054
4064
  useEscapeKey(isOpen, () => {
@@ -4084,7 +4094,7 @@ var Dropdown = (props) => {
4084
4094
  "div",
4085
4095
  {
4086
4096
  ref: menuRef,
4087
- className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
4097
+ className: clsx_default("lib-xplat-dropdown-menu", { visible }),
4088
4098
  role: "menu",
4089
4099
  children: items.map((item) => /* @__PURE__ */ jsx322(
4090
4100
  "button",
@@ -5986,7 +5996,7 @@ var PopOver = (props) => {
5986
5996
  onClose();
5987
5997
  triggerRef.current?.focus({ preventScroll: true });
5988
5998
  });
5989
- const position = useAutoPosition_default(triggerRef, popRef, localOpen);
5999
+ useAutoPosition_default(triggerRef, popRef, localOpen);
5990
6000
  React27.useEffect(() => {
5991
6001
  if (isOpen) {
5992
6002
  setLocalOpen(isOpen);
@@ -6015,7 +6025,6 @@ var PopOver = (props) => {
6015
6025
  {
6016
6026
  className: clsx_default(
6017
6027
  "lib-xplat-pop-over-content",
6018
- position.direction,
6019
6028
  eventTrigger && "visible"
6020
6029
  ),
6021
6030
  ref: popRef,
@@ -6267,7 +6276,7 @@ var SelectRoot = (props) => {
6267
6276
  close();
6268
6277
  triggerRef.current?.focus({ preventScroll: true });
6269
6278
  });
6270
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
6279
+ useAutoPosition_default(triggerRef, contentRef, mounted);
6271
6280
  const setSelected = React31.useCallback(
6272
6281
  (label2, itemValue) => {
6273
6282
  if (!isControlled) {
@@ -6360,7 +6369,7 @@ var SelectRoot = (props) => {
6360
6369
  mounted && /* @__PURE__ */ jsx337(Portal_default, { children: /* @__PURE__ */ jsxs216(
6361
6370
  "div",
6362
6371
  {
6363
- className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
6372
+ className: clsx_default("lib-xplat-select-content", size, stateClass),
6364
6373
  ref: contentRef,
6365
6374
  style: { width: triggerRef.current?.offsetWidth },
6366
6375
  role: "listbox",