[useAnchorPositioning] Add `collisionAvoidance` prop
Closes #1546
New options in the demo: https://deploy-preview-1849--base-ui.netlify.app/experiments/anchor-positioning
The collisionAvoidance prop allows users to control the collision preference. The default setting is:
{
side: 'flip',
align: 'flip',
fallbackAxisSide: 'end',
}
This means:
- For
sidecollision avoidance, prefer to flip e.g. frombottomtotop. - For
aligncollision avoidance, prefer to flip e.g. fromendtostart. - If the chosen side axis doesn't fit (e.g.
left/righton narrow viewports), choose the logicalendside. So if you specifyside="left", there's no need to worry about it overflowing on narrow viewports since it will flip tobottom(end) by default.@floating-ui/[email protected]solves the viewport size scenario in #1769 when you specifycrossAxis: 'alignment', which works better ifshift()is being used.
If you specify:
{
align: 'shift',
}
That solves #1546, since it will shift on the align axis instead.
If you want Select in the alignItemWithTrigger=false mode to work like Material UI's, then you can specify:
{
side: 'shift',
}
So it won't flip, but rather overlap the trigger
Deploy Preview for base-ui ready!
| Name | Link |
|---|---|
| Latest commit | 5cd5ebba1e589bfaaf6b701485c8b112da1f59f7 |
| Latest deploy log | https://app.netlify.com/projects/base-ui/deploys/683541e8bb31fb0008094d01 |
| Deploy Preview | https://deploy-preview-1849--base-ui.netlify.app |
| Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify project configuration.
This config object has one impossible state:
{
side: 'shift',
align: 'flip',
}
align can't flip when side prefers shift, though the reverse is possible (align=shift, side=flip). I don't think that setting is useful, but the API shouldn't allow such states
A discriminated union can handle this by preventing some strings from being set in combination with others:
interface SideFlipMode {
side?: 'flip' | 'none';
align?: 'flip' | 'shift' | 'none';
fallbackAxisSide?: 'start' | 'end' | 'none';
}
interface SideShiftMode {
side?: 'shift' | 'none';
align?: 'shift' | 'none';
fallbackAxisSide?: 'start' | 'end' | 'none';
}
export type CollisionAvoidance = SideFlipMode | SideShiftMode;
@atomiks – I finally got to test this and it's more than I could ask for, thank you so much! 🫶 Only issue is the docs don't specify the default:
@benface we're overhauling the props tables to be way more user friendly soon, so this will be fixed (it's not possible to display long defaults/types/examples etc in the current setup.)