// @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, }; type OverflowsMap = { [ComputedPlacement]: number }; export default function computeAutoPlacement( state: $Shape, options: Options = {} ): Array { 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]); }