|
|
// @flow import type { State, Padding } from '../types'; import type { Placement, ComputedPlacement, Boundary, RootBoundary, } from '../enums'; import getVariation from './getVariation'; import { variationPlacements, basePlacements, placements as allPlacements, } from '../enums'; import detectOverflow from './detectOverflow'; import getBasePlacement from './getBasePlacement';
type Options = { placement: Placement, padding: Padding, boundary: Boundary, rootBoundary: RootBoundary, flipVariations: boolean, allowedAutoPlacements?: Array<Placement>, };
type OverflowsMap = { [ComputedPlacement]: number };
export default function computeAutoPlacement( state: $Shape<State>, options: Options = {} ): Array<ComputedPlacement> { const { placement, boundary, rootBoundary, padding, flipVariations, allowedAutoPlacements = allPlacements, } = options;
const variation = getVariation(placement);
const placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter( (placement) => getVariation(placement) === variation ) : basePlacements;
let allowedPlacements = placements.filter( (placement) => allowedAutoPlacements.indexOf(placement) >= 0 );
if (allowedPlacements.length === 0) { allowedPlacements = placements;
if (false) { console.error( [ 'Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.', ].join(' ') ); } }
// $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... const overflows: OverflowsMap = allowedPlacements.reduce((acc, placement) => { acc[placement] = detectOverflow(state, { placement, boundary, rootBoundary, padding, })[getBasePlacement(placement)];
return acc; }, {});
return Object.keys(overflows).sort((a, b) => overflows[a] - overflows[b]); }
|