Skip to content

Commit

Permalink
[Popper] Added collision strategies option
Browse files Browse the repository at this point in the history
Gives a way to control how popper placement collision is handled, either
using flip or shift middlewares from Floating UI. By default, it is set
to flip for backwards compatibility.

Fixes issue radix-ui#2842

* [Popper] Updated storybook
  • Loading branch information
mazei513 committed May 31, 2024
1 parent b32a933 commit 06d8663
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
46 changes: 46 additions & 0 deletions packages/react/popper/src/Popper.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,52 @@ export const Chromatic = () => {
};
Chromatic.parameters = { chromatic: { disable: false } };

export const CollisionStrategy = () => {
const [flipOpen, setFlipOpen] = React.useState(false);
const [shiftOpen, setShiftOpen] = React.useState(false);

return (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-around',
gap: '16px',
height: '200vh',
}}
>
<Popper.Root>
<Popper.Anchor className={anchorClass()} onClick={() => setFlipOpen(true)}>
open (flip)
</Popper.Anchor>

{flipOpen && (
<Portal asChild>
<Popper.Content className={contentClass()} sideOffset={5}>
<button onClick={() => setFlipOpen(false)}>close</button>
<Popper.Arrow className={arrowClass()} width={20} height={10} offset={25} />
</Popper.Content>
</Portal>
)}
</Popper.Root>
<Popper.Root>
<Popper.Anchor className={anchorClass()} onClick={() => setShiftOpen(true)}>
open (shift)
</Popper.Anchor>

{shiftOpen && (
<Portal asChild>
<Popper.Content className={contentClass()} sideOffset={5} collisionStrategy="shift">
<button onClick={() => setShiftOpen(false)}>close</button>
<Popper.Arrow className={arrowClass()} width={20} height={10} offset={25} />
</Popper.Content>
</Portal>
)}
</Popper.Root>
</div>
);
};

const Scrollable = (props: any) => (
<div
style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '200vh' }}
Expand Down
6 changes: 4 additions & 2 deletions packages/react/popper/src/Popper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ interface PopperContentProps extends PrimitiveDivProps {
avoidCollisions?: boolean;
collisionBoundary?: Boundary | Boundary[];
collisionPadding?: number | Partial<Record<Side, number>>;
collisionStrategy?: 'shift' | 'flip';
sticky?: 'partial' | 'always';
hideWhenDetached?: boolean;
updatePositionStrategy?: 'optimized' | 'always';
Expand All @@ -138,6 +139,7 @@ const PopperContent = React.forwardRef<PopperContentElement, PopperContentProps>
avoidCollisions = true,
collisionBoundary = [],
collisionPadding: collisionPaddingProp = 0,
collisionStrategy = 'flip',
sticky = 'partial',
hideWhenDetached = false,
updatePositionStrategy = 'optimized',
Expand Down Expand Up @@ -190,11 +192,11 @@ const PopperContent = React.forwardRef<PopperContentElement, PopperContentProps>
avoidCollisions &&
shift({
mainAxis: true,
crossAxis: false,
crossAxis: collisionStrategy === 'shift',
limiter: sticky === 'partial' ? limitShift() : undefined,
...detectOverflowOptions,
}),
avoidCollisions && flip({ ...detectOverflowOptions }),
avoidCollisions && collisionStrategy === 'flip' && flip({ ...detectOverflowOptions }),
size({
...detectOverflowOptions,
apply: ({ elements, rects, availableWidth, availableHeight }) => {
Expand Down

0 comments on commit 06d8663

Please sign in to comment.