@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.
@@ -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
 
@@ -263,7 +273,7 @@ var Dropdown = (props) => {
263
273
  const [visible, setVisible] = import_react4.default.useState(false);
264
274
  const triggerRef = import_react4.default.useRef(null);
265
275
  const menuRef = import_react4.default.useRef(null);
266
- const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
276
+ useAutoPosition_default(triggerRef, menuRef, mounted);
267
277
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
268
278
  useCloseOnContainerScroll(isOpen, menuRef, () => setIsOpen(false));
269
279
  useEscapeKey(isOpen, () => {
@@ -299,7 +309,7 @@ var Dropdown = (props) => {
299
309
  "div",
300
310
  {
301
311
  ref: menuRef,
302
- className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
312
+ className: clsx_default("lib-xplat-dropdown-menu", { visible }),
303
313
  role: "menu",
304
314
  children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
305
315
  "button",
@@ -19,11 +19,11 @@
19
19
  box-shadow: var(--semantic-shadow-md);
20
20
  padding: var(--spacing-space-1) 0;
21
21
  opacity: 0;
22
- transform: translateY(-4px);
22
+ transform: translateY(4px);
23
23
  transition: opacity 0.15s ease, transform 0.15s ease;
24
24
  }
25
25
  .lib-xplat-dropdown-menu.bottom {
26
- transform: translateY(4px);
26
+ transform: translateY(-4px);
27
27
  }
28
28
  .lib-xplat-dropdown-menu.visible {
29
29
  opacity: 1;
@@ -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
 
@@ -227,7 +237,7 @@ var Dropdown = (props) => {
227
237
  const [visible, setVisible] = React4.useState(false);
228
238
  const triggerRef = React4.useRef(null);
229
239
  const menuRef = React4.useRef(null);
230
- const { direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
240
+ useAutoPosition_default(triggerRef, menuRef, mounted);
231
241
  useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
232
242
  useCloseOnContainerScroll(isOpen, menuRef, () => setIsOpen(false));
233
243
  useEscapeKey(isOpen, () => {
@@ -263,7 +273,7 @@ var Dropdown = (props) => {
263
273
  "div",
264
274
  {
265
275
  ref: menuRef,
266
- className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
276
+ className: clsx_default("lib-xplat-dropdown-menu", { visible }),
267
277
  role: "menu",
268
278
  children: items.map((item) => /* @__PURE__ */ jsx(
269
279
  "button",
@@ -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
 
@@ -268,7 +278,7 @@ var PopOver = (props) => {
268
278
  onClose();
269
279
  triggerRef.current?.focus({ preventScroll: true });
270
280
  });
271
- const position = useAutoPosition_default(triggerRef, popRef, localOpen);
281
+ useAutoPosition_default(triggerRef, popRef, localOpen);
272
282
  import_react4.default.useEffect(() => {
273
283
  if (isOpen) {
274
284
  setLocalOpen(isOpen);
@@ -297,7 +307,6 @@ var PopOver = (props) => {
297
307
  {
298
308
  className: clsx_default(
299
309
  "lib-xplat-pop-over-content",
300
- position.direction,
301
310
  eventTrigger && "visible"
302
311
  ),
303
312
  ref: popRef,
@@ -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
 
@@ -232,7 +242,7 @@ var PopOver = (props) => {
232
242
  onClose();
233
243
  triggerRef.current?.focus({ preventScroll: true });
234
244
  });
235
- const position = useAutoPosition_default(triggerRef, popRef, localOpen);
245
+ useAutoPosition_default(triggerRef, popRef, localOpen);
236
246
  React4.useEffect(() => {
237
247
  if (isOpen) {
238
248
  setLocalOpen(isOpen);
@@ -261,7 +271,6 @@ var PopOver = (props) => {
261
271
  {
262
272
  className: clsx_default(
263
273
  "lib-xplat-pop-over-content",
264
- position.direction,
265
274
  eventTrigger && "visible"
266
275
  ),
267
276
  ref: popRef,
@@ -56,26 +56,27 @@ var findScrollParent = (el) => {
56
56
  }
57
57
  return null;
58
58
  };
59
+ var TRIGGER_GAP = 8;
59
60
  var computePlacement = (triggerRect, popW, popH, clip) => {
60
- const roomBelow = clip.bottom - triggerRect.bottom;
61
- const roomAbove = triggerRect.top - clip.top;
61
+ const roomBelow = clip.bottom - triggerRect.bottom - TRIGGER_GAP;
62
+ const roomAbove = triggerRect.top - clip.top - TRIGGER_GAP;
62
63
  let direction;
63
64
  let top;
64
65
  let maxHeight = null;
65
66
  if (popH <= roomBelow) {
66
67
  direction = "bottom";
67
- top = triggerRect.bottom;
68
+ top = triggerRect.bottom + TRIGGER_GAP;
68
69
  } else if (popH <= roomAbove) {
69
70
  direction = "top";
70
- top = triggerRect.top - popH;
71
+ top = triggerRect.top - TRIGGER_GAP - popH;
71
72
  } else {
72
73
  const room = Math.max(roomBelow, roomAbove, 0);
73
74
  if (roomBelow >= roomAbove) {
74
75
  direction = "bottom";
75
- top = triggerRect.bottom;
76
+ top = triggerRect.bottom + TRIGGER_GAP;
76
77
  } else {
77
78
  direction = "top";
78
- top = triggerRect.top - room;
79
+ top = triggerRect.top - TRIGGER_GAP - room;
79
80
  }
80
81
  maxHeight = room;
81
82
  }
@@ -99,15 +100,18 @@ var computePlacement = (triggerRect, popW, popH, clip) => {
99
100
  };
100
101
  };
101
102
  var useAutoPosition = (triggerRef, popRef, enabled = true) => {
102
- const [direction, setDirection] = import_react.default.useState("bottom");
103
103
  const directionRef = import_react.default.useRef("bottom");
104
104
  const sizeRef = import_react.default.useRef(null);
105
105
  const scrollParentRef = import_react.default.useRef(null);
106
+ const placedRef = import_react.default.useRef(false);
106
107
  const calculatePosition = import_react.default.useCallback((remeasure = false) => {
107
108
  const pop = popRef.current;
108
109
  if (!triggerRef.current || !pop) return;
109
110
  if (remeasure || !sizeRef.current) {
110
- sizeRef.current = { w: pop.offsetWidth, h: pop.offsetHeight };
111
+ sizeRef.current = {
112
+ w: pop.offsetWidth,
113
+ h: Math.max(pop.offsetHeight, pop.scrollHeight)
114
+ };
111
115
  }
112
116
  const { w: popW, h: popH } = sizeRef.current;
113
117
  const triggerRect = triggerRef.current.getBoundingClientRect();
@@ -122,6 +126,8 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
122
126
  left: Math.max(parentRect?.left ?? 0, 0),
123
127
  right: Math.min(parentRect?.right ?? window.innerWidth, window.innerWidth)
124
128
  };
129
+ const first = !placedRef.current;
130
+ if (first) pop.style.transition = "none";
125
131
  const { direction: next, top, left, over, maxHeight } = computePlacement(
126
132
  triggerRect,
127
133
  popW,
@@ -132,15 +138,20 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
132
138
  pop.style.left = `${left + window.scrollX}px`;
133
139
  pop.style.maxHeight = maxHeight === null ? "" : `${maxHeight}px`;
134
140
  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";
135
- if (next !== directionRef.current) {
136
- directionRef.current = next;
137
- setDirection(next);
141
+ directionRef.current = next;
142
+ pop.classList.toggle("top", next === "top");
143
+ pop.classList.toggle("bottom", next === "bottom");
144
+ if (first) {
145
+ void pop.offsetHeight;
146
+ pop.style.transition = "";
147
+ placedRef.current = true;
138
148
  }
139
149
  }, [triggerRef, popRef]);
140
150
  import_react.default.useLayoutEffect(() => {
141
151
  if (!enabled) {
142
152
  sizeRef.current = null;
143
153
  scrollParentRef.current = null;
154
+ placedRef.current = false;
144
155
  return;
145
156
  }
146
157
  if (triggerRef.current) {
@@ -169,7 +180,6 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
169
180
  window.removeEventListener("scroll", onScroll, true);
170
181
  };
171
182
  }, [calculatePosition, enabled]);
172
- return { direction };
173
183
  };
174
184
  var useAutoPosition_default = useAutoPosition;
175
185
 
@@ -1399,7 +1409,7 @@ var SelectRoot = (props) => {
1399
1409
  close();
1400
1410
  triggerRef.current?.focus({ preventScroll: true });
1401
1411
  });
1402
- const position = useAutoPosition_default(triggerRef, contentRef, mounted);
1412
+ useAutoPosition_default(triggerRef, contentRef, mounted);
1403
1413
  const setSelected = import_react6.default.useCallback(
1404
1414
  (label2, itemValue) => {
1405
1415
  if (!isControlled) {
@@ -1492,7 +1502,7 @@ var SelectRoot = (props) => {
1492
1502
  mounted && /* @__PURE__ */ (0, import_jsx_runtime297.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime297.jsxs)(
1493
1503
  "div",
1494
1504
  {
1495
- className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
1505
+ className: clsx_default("lib-xplat-select-content", size, stateClass),
1496
1506
  ref: contentRef,
1497
1507
  style: { width: triggerRef.current?.offsetWidth },
1498
1508
  role: "listbox",
@@ -212,7 +212,7 @@
212
212
  transition: transform 0.2s ease, opacity 0.2s ease;
213
213
  }
214
214
  .lib-xplat-select-content.bottom {
215
- transform: translateY(8px);
215
+ transform: translateY(-4px);
216
216
  }
217
217
  .lib-xplat-select-content.bottom.visible {
218
218
  opacity: 1;
@@ -220,12 +220,12 @@
220
220
  }
221
221
  .lib-xplat-select-content.bottom.exit {
222
222
  opacity: 0;
223
- transform: translateY(8px);
223
+ transform: translateY(-4px);
224
224
  }
225
225
  .lib-xplat-select-content {
226
226
  }
227
227
  .lib-xplat-select-content.top {
228
- transform: translateY(-8px);
228
+ transform: translateY(4px);
229
229
  }
230
230
  .lib-xplat-select-content.top.visible {
231
231
  opacity: 1;
@@ -233,7 +233,7 @@
233
233
  }
234
234
  .lib-xplat-select-content.top.exit {
235
235
  opacity: 0;
236
- transform: translateY(-8px);
236
+ transform: translateY(4px);
237
237
  }
238
238
  .lib-xplat-select-content.sm .select-item {
239
239
  padding: var(--spacing-space-2) var(--spacing-space-2);