86 lines
2.1 KiB
Text
86 lines
2.1 KiB
Text
|
// @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]);
|
||
|
}
|