Replies: 19 comments
-
|
Just ran into this issue today as well and found myself here after some googling. Would love to be able to either style it directly, or pass a prop to make it |
Beta Was this translation helpful? Give feedback.
-
|
+1 on this, give us some control on |
Beta Was this translation helpful? Give feedback.
-
|
+1 on this, I want to be able to style the options like a popover, so it behaves kinda like a native mobile dropdown |
Beta Was this translation helpful? Give feedback.
-
|
if anybody cares I wrote this patch (with patch-package) to allow me to set a className to the wrapper (because I use Tailwind, same could be done with style). I also added a position mode called "modal" that takes the whole screen and centers the options. This could be done cleaner for sure, I just need a fix quickly for now. :) diff --git a/node_modules/@radix-ui/react-select/dist/index.d.ts b/node_modules/@radix-ui/react-select/dist/index.d.ts
index 9775d79..11c7cdf 100644
--- a/node_modules/@radix-ui/react-select/dist/index.d.ts
+++ b/node_modules/@radix-ui/react-select/dist/index.d.ts
@@ -78,7 +78,8 @@ interface SelectContentImplProps extends Omit<SelectPopperPositionProps, keyof S
* Can be prevented.
*/
onPointerDownOutside?: DismissableLayerProps['onPointerDownOutside'];
- position?: 'item-aligned' | 'popper';
+ wrapperClassName?: string;
+ position?: 'item-aligned' | 'popper' | 'modal';
}
interface SelectItemAlignedPositionProps extends PrimitiveDivProps, SelectPopperPrivateProps {
}
diff --git a/node_modules/@radix-ui/react-select/dist/index.js b/node_modules/@radix-ui/react-select/dist/index.js
index 25d9296..603225c 100644
--- a/node_modules/@radix-ui/react-select/dist/index.js
+++ b/node_modules/@radix-ui/react-select/dist/index.js
@@ -461,7 +461,7 @@ var SelectContentImpl = React.forwardRef(
},
[context.value]
);
- const SelectPosition = position === "popper" ? SelectPopperPosition : SelectItemAlignedPosition;
+ const SelectPosition = position === "popper" ? SelectPopperPosition : position === "modal" ? SelectModalPosition : SelectItemAlignedPosition;
const popperContentProps = SelectPosition === SelectPopperPosition ? {
side,
sideOffset,
@@ -563,7 +563,7 @@ var SelectContentImpl = React.forwardRef(
SelectContentImpl.displayName = CONTENT_IMPL_NAME;
var ITEM_ALIGNED_POSITION_NAME = "SelectItemAlignedPosition";
var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
- const { __scopeSelect, onPlaced, ...popperProps } = props;
+ const { __scopeSelect, onPlaced, wrapperClassName, ...popperProps } = props;
const context = useSelectContext(CONTENT_NAME, __scopeSelect);
const contentContext = useSelectContentContext(CONTENT_NAME, __scopeSelect);
const [contentWrapper, setContentWrapper] = React.useState(null);
@@ -693,6 +693,7 @@ var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
position: "fixed",
zIndex: contentZIndex
},
+ className: wrapperClassName,
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_react_primitive.Primitive.div,
{
@@ -714,12 +715,58 @@ var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
);
});
SelectItemAlignedPosition.displayName = ITEM_ALIGNED_POSITION_NAME;
+var MODAL_POSITION_NAME = "SelectModalPosition";
+var SelectModalPosition = React.forwardRef((props, forwardedRef) => {
+ const { __scopeSelect, onPlaced, wrapperClassName, ...popperProps } = props;
+ const [contentWrapper, setContentWrapper] = React.useState(null);
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
+ SelectViewportProvider,
+ {
+ scope: __scopeSelect,
+ contentWrapper,
+ shouldExpandOnScrollRef,
+ onScrollButtonChange: handleScrollButtonChange,
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
+ "div",
+ {
+ ref: setContentWrapper,
+ style: {
+ display: "flex",
+ flexDirection: "column",
+ justifyContent: "center",
+ alignItems: "center",
+ position: "fixed",
+ left: 0,
+ top: 0,
+ width: "100vw",
+ height: "100vh",
+ zIndex: 100,
+ },
+ className: wrapperClassName,
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
+ import_react_primitive.Primitive.div,
+ {
+ ...popperProps,
+ ref: composedRefs,
+ style: popperProps.style,
+ }
+ )
+ }
+ )
+ }
+ );
+});
+SelectModalPosition.displayName = MODAL_POSITION_NAME;
+
+
var POPPER_POSITION_NAME = "SelectPopperPosition";
var SelectPopperPosition = React.forwardRef((props, forwardedRef) => {
const {
__scopeSelect,
align = "start",
collisionPadding = CONTENT_MARGIN,
+ wrapperClassName,
+ className,
...popperProps
} = props;
const popperScope = usePopperScope(__scopeSelect);
@@ -730,6 +777,7 @@ var SelectPopperPosition = React.forwardRef((props, forwardedRef) => {
...popperProps,
ref: forwardedRef,
align,
+ className: [className, wrapperClassName].filter(Boolean).join(" "),
collisionPadding,
style: {
// Ensure border-box for floating-ui calculations
diff --git a/node_modules/@radix-ui/react-select/dist/index.mjs b/node_modules/@radix-ui/react-select/dist/index.mjs
index 5d874b7..d8cc59c 100644
--- a/node_modules/@radix-ui/react-select/dist/index.mjs
+++ b/node_modules/@radix-ui/react-select/dist/index.mjs
@@ -394,7 +394,7 @@ var SelectContentImpl = React.forwardRef(
},
[context.value]
);
- const SelectPosition = position === "popper" ? SelectPopperPosition : SelectItemAlignedPosition;
+ const SelectPosition = position === "popper" ? SelectPopperPosition : position === "modal" ? SelectModalPosition : SelectItemAlignedPosition;
const popperContentProps = SelectPosition === SelectPopperPosition ? {
side,
sideOffset,
@@ -496,7 +496,7 @@ var SelectContentImpl = React.forwardRef(
SelectContentImpl.displayName = CONTENT_IMPL_NAME;
var ITEM_ALIGNED_POSITION_NAME = "SelectItemAlignedPosition";
var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
- const { __scopeSelect, onPlaced, ...popperProps } = props;
+ const { __scopeSelect, onPlaced, wrapperClassName, ...popperProps } = props;
const context = useSelectContext(CONTENT_NAME, __scopeSelect);
const contentContext = useSelectContentContext(CONTENT_NAME, __scopeSelect);
const [contentWrapper, setContentWrapper] = React.useState(null);
@@ -624,7 +624,8 @@ var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
display: "flex",
flexDirection: "column",
position: "fixed",
- zIndex: contentZIndex
+ zIndex: contentZIndex,
+ className: wrapperClassName,
},
children: /* @__PURE__ */ jsx(
Primitive.div,
@@ -647,12 +648,58 @@ var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
);
});
SelectItemAlignedPosition.displayName = ITEM_ALIGNED_POSITION_NAME;
+var MODAL_POSITION_NAME = "SelectModalPosition";
+var SelectModalPosition = React.forwardRef((props, forwardedRef) => {
+ const { __scopeSelect, onPlaced, wrapperClassName, ...popperProps } = props;
+ const [content, setContent] = React.useState(null);
+ const [contentWrapper, setContentWrapper] = React.useState(null);
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
+ return /* @__PURE__ */ jsx(
+ SelectViewportProvider,
+ {
+ scope: __scopeSelect,
+ contentWrapper,
+ shouldExpandOnScrollRef: false,
+ onScrollButtonChange: () => {},
+ children: /* @__PURE__ */ jsx(
+ "div",
+ {
+ ref: setContentWrapper,
+ style: {
+ display: "flex",
+ flexDirection: "column",
+ justifyContent: "center",
+ alignItems: "center",
+ position: "fixed",
+ left: 0,
+ top: 0,
+ width: "100vw",
+ height: "100vh",
+ zIndex: 100,
+ },
+ className: wrapperClassName,
+ children: /* @__PURE__ */ jsx(
+ Primitive.div,
+ {
+ ...popperProps,
+ ref: composedRefs,
+ style: popperProps.style,
+ }
+ )
+ }
+ )
+ }
+ );
+});
+SelectModalPosition.displayName = MODAL_POSITION_NAME;
var POPPER_POSITION_NAME = "SelectPopperPosition";
var SelectPopperPosition = React.forwardRef((props, forwardedRef) => {
const {
__scopeSelect,
align = "start",
collisionPadding = CONTENT_MARGIN,
+ wrapperClassName,
+ className,
...popperProps
} = props;
const popperScope = usePopperScope(__scopeSelect);
@@ -661,6 +708,7 @@ var SelectPopperPosition = React.forwardRef((props, forwardedRef) => {
{
...popperScope,
...popperProps,
+ className: [className, wrapperClassName].filter(Boolean).join(" "),
ref: forwardedRef,
align,
collisionPadding,
|
Beta Was this translation helpful? Give feedback.
-
|
Facing the same issue |
Beta Was this translation helpful? Give feedback.
-
|
a possible workaround (here it changes the wrapper's styles on small screens): PS: but this will change all your popovers in your react component: |
Beta Was this translation helpful? Give feedback.
-
|
A workaround using tailwind: tailwind.config.js: The component: |
Beta Was this translation helpful? Give feedback.
-
|
Is there a reason it's not exposed? It seems like a very obvious change... Is there some implementation detail that's hidden to keep folks out of trouble? |
Beta Was this translation helpful? Give feedback.
-
|
I need to add some classes to this wrapper, what seems not possible too, thats weird |
Beta Was this translation helpful? Give feedback.
-
|
Alright I got a solution for this (workaround). I'm still testing the coverage of effect of this solution but to minimize the effect of it I had to introduce a class: // css
.DropdownTbody
[data-radix-popper-content-wrapper] {
position: absolute !important;
}
// jsx
<tbody className='relative DropdownTbody'> {/* placing class here /*}
<DropdownMenu open={filterMenuOpen} onOpenChange={setFilterMenuOpen}>
<DropdownMenuContent
className="DropdownMenuContent outline-none drop-shadow-2xl shadow-2xl bg-[#1A1A1A] z-50"
alignOffset={9}
sideOffset={10}
align="end"
side='bottom'
>
<DropdownMenuItem className="outline-none">
<div className="flex gap-2 text-xs items-center p-4 bg-[#1A1A1A] text-white hover:cursor-pointer hover:bg-[#333] absolute z-50 min-w-fit w-[250px]" >
Filter menu
</div> {/* making this div absolute to the tbody of a table which is now relative /*}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</tbody> |
Beta Was this translation helpful? Give feedback.
-
|
If you are using tailwind, I have found this workaround for now, by wrapping the element using the //Replace 'my-0' by the style you want to apply
<div className='[&_[data-radix-popper-content-wrapper]]:my-0'>
{/*... your popper element*/}
</div>Example with Popover (i'm using shadcn): <div className='[&_[data-radix-popper-content-wrapper]]:my-0'>
<Popover>
<PopoverTrigger asChild>
<Button
variant='outline'
role='combobox'
aria-expanded={false}
className='w-full justify-between'
>
Open Popover
</Button>
</PopoverTrigger>
<PopoverContent className='mt-0 w-[var(--radix-popover-trigger-width)] p-0'>
Blah blah blah
</PopoverContent>
</Popover>
</div> |
Beta Was this translation helpful? Give feedback.
-
I've found a alternative that don't require a top level <div className="[[data-radix-popper-content-wrapper]:has(&)]:min-w-56">
{/*... your popper element*/}
</div>Replace |
Beta Was this translation helpful? Give feedback.
-
|
Agree with this |
Beta Was this translation helpful? Give feedback.
-
|
Somewhat related, but apparently a different flavor required for shadcn: <DropdownMenuContent align="end" className="w-[var(--radix-popper-anchor-width)]">
{/* ... */}
</DropdownMenuContent> |
Beta Was this translation helpful? Give feedback.
-
|
Still an issue. |
Beta Was this translation helpful? Give feedback.
-
|
I found this to be a problem especially with dropdowns. |
Beta Was this translation helpful? Give feedback.
-
|
Still an issue, and would be good to be able to change |
Beta Was this translation helpful? Give feedback.
-
|
I also find this to be an issue on Popovers, they move around slightly on scroll and can completely overlap the trigger on elastic scroll / rubber banding (quickly scrolling on trackpad or touch devices) It does not happen on position absolute, so I wonder why fixed is used. |
Beta Was this translation helpful? Give feedback.
-
|
I added this on a parent element to add styling on it. (with tailwind)
|
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Feature request
Mainly I would like to request the support for using Popper while using an "absolute" floating strategy rather than fixed.
Eventually, the popper-content-wrapper will get styled with "position: fixed;" and there is no straight-forward way to change it.
Overview
In the codebase you can see that the strategy is hardcoded
strategy: 'fixed',which is the cause of the "position: fixed;" style.
So all components that use the popper must use this "fixed" strategy and it would be quite hard to choose the "absolute" strategy.
The main reason I had this need is due to the following issue:
Popover inside a scrollable container will appear outside of the container when exceeding its boundaries, even if its anchor is in the hidden overflown section of the container:
Issue Example on Codesandbox

Who does this impact? Who is this for?
I think it might impact everyone
Additional context
In order to solve that issue I had to add {absolute: !important} to css because the data-radix-popper-content-wrapper's fixed position is set as a style:
Hack Solution Example in Codesandbox

Beta Was this translation helpful? Give feedback.
All reactions