diff options
Diffstat (limited to 'popperjs/package/lib/modifiers/offset.js.flow')
-rw-r--r-- | popperjs/package/lib/modifiers/offset.js.flow | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/popperjs/package/lib/modifiers/offset.js.flow b/popperjs/package/lib/modifiers/offset.js.flow new file mode 100644 index 0000000..b39edc4 --- /dev/null +++ b/popperjs/package/lib/modifiers/offset.js.flow @@ -0,0 +1,71 @@ +// @flow +import type { Placement } from '../enums'; +import type { ModifierArguments, Modifier, Rect, Offsets } from '../types'; +import getBasePlacement from '../utils/getBasePlacement'; +import { top, left, right, placements } from '../enums'; + +// eslint-disable-next-line import/no-unused-modules +export type OffsetsFunction = ({ + popper: Rect, + reference: Rect, + placement: Placement, +}) => [?number, ?number]; + +type Offset = OffsetsFunction | [?number, ?number]; + +// eslint-disable-next-line import/no-unused-modules +export type Options = { + offset: Offset, +}; + +export function distanceAndSkiddingToXY( + placement: Placement, + rects: { popper: Rect, reference: Rect }, + offset: Offset +): Offsets { + const basePlacement = getBasePlacement(placement); + const invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; + + let [skidding, distance] = + typeof offset === 'function' + ? offset({ + ...rects, + placement, + }) + : offset; + + skidding = skidding || 0; + distance = (distance || 0) * invertDistance; + + return [left, right].indexOf(basePlacement) >= 0 + ? { x: distance, y: skidding } + : { x: skidding, y: distance }; +} + +function offset({ state, options, name }: ModifierArguments<Options>) { + const { offset = [0, 0] } = options; + + const data = placements.reduce((acc, placement) => { + acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); + return acc; + }, {}); + + const { x, y } = data[state.placement]; + + if (state.modifiersData.popperOffsets != null) { + state.modifiersData.popperOffsets.x += x; + state.modifiersData.popperOffsets.y += y; + } + + state.modifiersData[name] = data; +} + +// eslint-disable-next-line import/no-unused-modules +export type OffsetModifier = Modifier<'offset', Options>; +export default ({ + name: 'offset', + enabled: true, + phase: 'main', + requires: ['popperOffsets'], + fn: offset, +}: OffsetModifier); |