12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // @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]);
- }
|