diff --git a/.yarn/versions/9cbffb59.yml b/.yarn/versions/9cbffb59.yml
new file mode 100644
index 000000000..517939231
--- /dev/null
+++ b/.yarn/versions/9cbffb59.yml
@@ -0,0 +1,5 @@
+releases:
+ "@radix-ui/react-select": patch
+
+declined:
+ - primitives
diff --git a/packages/react/select/src/Select.stories.tsx b/packages/react/select/src/Select.stories.tsx
index 4c12fd976..6fe46281e 100644
--- a/packages/react/select/src/Select.stories.tsx
+++ b/packages/react/select/src/Select.stories.tsx
@@ -679,6 +679,44 @@ export const WithinDialog = () => (
);
+export const WithVeryLongSelectItems = () => (
+
+
+
+);
+
export const ChromaticShortOptionsPaddedContent = () => (
);
@@ -1055,6 +1093,7 @@ const triggerClass = css({
fontFamily: '-apple-system, BlinkMacSystemFont, helvetica, arial, sans-serif',
fontSize: 13,
lineHeight: 1,
+ overflow: 'hidden',
'&:focus': {
outline: 'none',
diff --git a/packages/react/select/src/Select.tsx b/packages/react/select/src/Select.tsx
index 407c1f318..9ad418f09 100644
--- a/packages/react/select/src/Select.tsx
+++ b/packages/react/select/src/Select.tsx
@@ -827,7 +827,15 @@ const SelectItemAlignedPosition = React.forwardRef<
const minContentWidth = triggerRect.width + leftDelta;
const contentWidth = Math.max(minContentWidth, contentRect.width);
const rightEdge = window.innerWidth - CONTENT_MARGIN;
- const clampedLeft = clamp(left, [CONTENT_MARGIN, rightEdge - contentWidth]);
+ const clampedLeft = clamp(left, [
+ CONTENT_MARGIN,
+ // Prevents the content from going off the starting edge of the
+ // viewport. It may still go off the ending edge, but this can be
+ // controlled by the user since they may want to manage overflow in a
+ // specific way.
+ // https://github.com/radix-ui/primitives/issues/2049
+ Math.max(CONTENT_MARGIN, rightEdge - contentWidth),
+ ]);
contentWrapper.style.minWidth = minContentWidth + 'px';
contentWrapper.style.left = clampedLeft + 'px';
@@ -838,7 +846,10 @@ const SelectItemAlignedPosition = React.forwardRef<
const minContentWidth = triggerRect.width + rightDelta;
const contentWidth = Math.max(minContentWidth, contentRect.width);
const leftEdge = window.innerWidth - CONTENT_MARGIN;
- const clampedRight = clamp(right, [CONTENT_MARGIN, leftEdge - contentWidth]);
+ const clampedRight = clamp(right, [
+ CONTENT_MARGIN,
+ Math.max(CONTENT_MARGIN, leftEdge - contentWidth),
+ ]);
contentWrapper.style.minWidth = minContentWidth + 'px';
contentWrapper.style.right = clampedRight + 'px';
@@ -1083,7 +1094,11 @@ const SelectViewport = React.forwardRef {