From a555a40478ec3e804b644461cdda49513f44f5d8 Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Fri, 27 Sep 2024 09:43:10 -0700 Subject: [PATCH] Select: Prevent negative starting position (#3149) --- .yarn/versions/9cbffb59.yml | 5 +++ packages/react/select/src/Select.stories.tsx | 39 ++++++++++++++++++++ packages/react/select/src/Select.tsx | 21 +++++++++-- 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 .yarn/versions/9cbffb59.yml diff --git a/.yarn/versions/9cbffb59.yml b/.yarn/versions/9cbffb59.yml new file mode 100644 index 0000000000..5179392316 --- /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 4c12fd976a..6fe46281e1 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 407c1f3181..9ad418f091 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 {