Commit 6cc198bf authored by Sangjune Bae's avatar Sangjune Bae
Browse files

first commit

parent 81c6da4b
// @flow
import getNodeName from './getNodeName';
export default function isTableElement(element: Element): boolean {
return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
}
import { Window, VisualViewport } from "../types";
export default function listScrollParents(element: Node, list?: Array<Element | Window>): Array<Element | Window | VisualViewport>;
import getScrollParent from "./getScrollParent.js";
import getParentNode from "./getParentNode.js";
import getNodeName from "./getNodeName.js";
import getWindow from "./getWindow.js";
import isScrollParent from "./isScrollParent.js";
/*
given a DOM element, return the list of all scroll parents, up the list of ancesors
until we get to the top window object. This list is what we attach scroll listeners
to, because if any of these parent elements scroll, we'll need to re-calculate the
reference element's position.
*/
export default function listScrollParents(element, list) {
if (list === void 0) {
list = [];
}
var scrollParent = getScrollParent(element);
var isBody = getNodeName(scrollParent) === 'body';
var win = getWindow(scrollParent);
var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
var updatedList = list.concat(target);
return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
updatedList.concat(listScrollParents(getParentNode(target)));
}
\ No newline at end of file
// @flow
import getScrollParent from './getScrollParent';
import getParentNode from './getParentNode';
import getNodeName from './getNodeName';
import getWindow from './getWindow';
import type { Window, VisualViewport } from '../types';
import isScrollParent from './isScrollParent';
/*
given a DOM element, return the list of all scroll parents, up the list of ancesors
until we get to the top window object. This list is what we attach scroll listeners
to, because if any of these parent elements scroll, we'll need to re-calculate the
reference element's position.
*/
export default function listScrollParents(
element: Node,
list: Array<Element | Window> = []
): Array<Element | Window | VisualViewport> {
const scrollParent = getScrollParent(element);
const isBody = getNodeName(scrollParent) === 'body';
const win = getWindow(scrollParent);
const target = isBody
? [win].concat(
win.visualViewport || [],
isScrollParent(scrollParent) ? scrollParent : []
)
: scrollParent;
const updatedList = list.concat(target);
return isBody
? updatedList
: // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
updatedList.concat(listScrollParents(getParentNode(target)));
}
export declare const top: "top";
export declare const bottom: "bottom";
export declare const right: "right";
export declare const left: "left";
export declare const auto: "auto";
export declare type BasePlacement = typeof top | typeof bottom | typeof right | typeof left;
export declare const basePlacements: Array<BasePlacement>;
export declare const start: "start";
export declare const end: "end";
export declare type Variation = typeof start | typeof end;
export declare const clippingParents: "clippingParents";
export declare const viewport: "viewport";
export declare type Boundary = HTMLElement | Array<HTMLElement> | typeof clippingParents;
export declare type RootBoundary = typeof viewport | "document";
export declare const popper: "popper";
export declare const reference: "reference";
export declare type Context = typeof popper | typeof reference;
export declare type VariationPlacement = "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end";
export declare type AutoPlacement = "auto" | "auto-start" | "auto-end";
export declare type ComputedPlacement = VariationPlacement | BasePlacement;
export declare type Placement = AutoPlacement | BasePlacement | VariationPlacement;
export declare const variationPlacements: Array<VariationPlacement>;
export declare const placements: Array<Placement>;
export declare const beforeRead: "beforeRead";
export declare const read: "read";
export declare const afterRead: "afterRead";
export declare const beforeMain: "beforeMain";
export declare const main: "main";
export declare const afterMain: "afterMain";
export declare const beforeWrite: "beforeWrite";
export declare const write: "write";
export declare const afterWrite: "afterWrite";
export declare const modifierPhases: Array<ModifierPhases>;
export declare type ModifierPhases = typeof beforeRead | typeof read | typeof afterRead | typeof beforeMain | typeof main | typeof afterMain | typeof beforeWrite | typeof write | typeof afterWrite;
export var top = 'top';
export var bottom = 'bottom';
export var right = 'right';
export var left = 'left';
export var auto = 'auto';
export var basePlacements = [top, bottom, right, left];
export var start = 'start';
export var end = 'end';
export var clippingParents = 'clippingParents';
export var viewport = 'viewport';
export var popper = 'popper';
export var reference = 'reference';
export var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {
return acc.concat([placement + "-" + start, placement + "-" + end]);
}, []);
export var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {
return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
}, []); // modifiers that need to read the DOM
export var beforeRead = 'beforeRead';
export var read = 'read';
export var afterRead = 'afterRead'; // pure-logic modifiers
export var beforeMain = 'beforeMain';
export var main = 'main';
export var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)
export var beforeWrite = 'beforeWrite';
export var write = 'write';
export var afterWrite = 'afterWrite';
export var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
\ No newline at end of file
// @flow
export const top: 'top' = 'top';
export const bottom: 'bottom' = 'bottom';
export const right: 'right' = 'right';
export const left: 'left' = 'left';
export const auto: 'auto' = 'auto';
export type BasePlacement =
| typeof top
| typeof bottom
| typeof right
| typeof left;
export const basePlacements: Array<BasePlacement> = [top, bottom, right, left];
export const start: 'start' = 'start';
export const end: 'end' = 'end';
export type Variation = typeof start | typeof end;
export const clippingParents: 'clippingParents' = 'clippingParents';
export const viewport: 'viewport' = 'viewport';
export type Boundary =
| HTMLElement
| Array<HTMLElement>
| typeof clippingParents;
export type RootBoundary = typeof viewport | 'document';
export const popper: 'popper' = 'popper';
export const reference: 'reference' = 'reference';
export type Context = typeof popper | typeof reference;
export type VariationPlacement =
| 'top-start'
| 'top-end'
| 'bottom-start'
| 'bottom-end'
| 'right-start'
| 'right-end'
| 'left-start'
| 'left-end';
export type AutoPlacement = 'auto' | 'auto-start' | 'auto-end';
export type ComputedPlacement = VariationPlacement | BasePlacement;
export type Placement = AutoPlacement | BasePlacement | VariationPlacement;
export const variationPlacements: Array<VariationPlacement> = basePlacements.reduce(
(acc: Array<VariationPlacement>, placement: BasePlacement) =>
acc.concat([(`${placement}-${start}`: any), (`${placement}-${end}`: any)]),
[]
);
export const placements: Array<Placement> = [...basePlacements, auto].reduce(
(
acc: Array<Placement>,
placement: BasePlacement | typeof auto
): Array<Placement> =>
acc.concat([
placement,
(`${placement}-${start}`: any),
(`${placement}-${end}`: any),
]),
[]
);
// modifiers that need to read the DOM
export const beforeRead: 'beforeRead' = 'beforeRead';
export const read: 'read' = 'read';
export const afterRead: 'afterRead' = 'afterRead';
// pure-logic modifiers
export const beforeMain: 'beforeMain' = 'beforeMain';
export const main: 'main' = 'main';
export const afterMain: 'afterMain' = 'afterMain';
// modifier with the purpose to write to the DOM (or write into a framework state)
export const beforeWrite: 'beforeWrite' = 'beforeWrite';
export const write: 'write' = 'write';
export const afterWrite: 'afterWrite' = 'afterWrite';
export const modifierPhases: Array<ModifierPhases> = [
beforeRead,
read,
afterRead,
beforeMain,
main,
afterMain,
beforeWrite,
write,
afterWrite,
];
export type ModifierPhases =
| typeof beforeRead
| typeof read
| typeof afterRead
| typeof beforeMain
| typeof main
| typeof afterMain
| typeof beforeWrite
| typeof write
| typeof afterWrite;
export * from "./types";
export * from "./enums";
export * from "./modifiers";
export { popperGenerator, detectOverflow, createPopper as createPopperBase } from "./createPopper";
export { createPopper } from "./popper";
export { createPopper as createPopperLite } from "./popper-lite";
export * from "./enums.js";
export * from "./modifiers/index.js"; // eslint-disable-next-line import/no-unused-modules
export { popperGenerator, detectOverflow, createPopper as createPopperBase } from "./createPopper.js"; // eslint-disable-next-line import/no-unused-modules
export { createPopper } from "./popper.js"; // eslint-disable-next-line import/no-unused-modules
export { createPopper as createPopperLite } from "./popper-lite.js";
\ No newline at end of file
// @flow
export type * from './types';
export * from './enums';
export * from './modifiers';
// eslint-disable-next-line import/no-unused-modules
export { popperGenerator, detectOverflow, createPopper as createPopperBase } from './createPopper';
// eslint-disable-next-line import/no-unused-modules
export { createPopper } from './popper';
// eslint-disable-next-line import/no-unused-modules
export { createPopper as createPopperLite } from './popper-lite';
import { Modifier } from "../types";
export declare type ApplyStylesModifier = Modifier<"applyStyles", {}>;
declare const _default: Modifier<"applyStyles", {}>;
export default _default;
import getNodeName from "../dom-utils/getNodeName.js";
import { isHTMLElement } from "../dom-utils/instanceOf.js"; // This modifier takes the styles prepared by the `computeStyles` modifier
// and applies them to the HTMLElements such as popper and arrow
function applyStyles(_ref) {
var state = _ref.state;
Object.keys(state.elements).forEach(function (name) {
var style = state.styles[name] || {};
var attributes = state.attributes[name] || {};
var element = state.elements[name]; // arrow is optional + virtual elements
if (!isHTMLElement(element) || !getNodeName(element)) {
return;
} // Flow doesn't support to extend this property, but it's the most
// effective way to apply styles to an HTMLElement
// $FlowFixMe[cannot-write]
Object.assign(element.style, style);
Object.keys(attributes).forEach(function (name) {
var value = attributes[name];
if (value === false) {
element.removeAttribute(name);
} else {
element.setAttribute(name, value === true ? '' : value);
}
});
});
}
function effect(_ref2) {
var state = _ref2.state;
var initialStyles = {
popper: {
position: state.options.strategy,
left: '0',
top: '0',
margin: '0'
},
arrow: {
position: 'absolute'
},
reference: {}
};
Object.assign(state.elements.popper.style, initialStyles.popper);
if (state.elements.arrow) {
Object.assign(state.elements.arrow.style, initialStyles.arrow);
}
return function () {
Object.keys(state.elements).forEach(function (name) {
var element = state.elements[name];
var attributes = state.attributes[name] || {};
var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them
var style = styleProperties.reduce(function (style, property) {
style[property] = '';
return style;
}, {}); // arrow is optional + virtual elements
if (!isHTMLElement(element) || !getNodeName(element)) {
return;
}
Object.assign(element.style, style);
Object.keys(attributes).forEach(function (attribute) {
element.removeAttribute(attribute);
});
});
};
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'applyStyles',
enabled: true,
phase: 'write',
fn: applyStyles,
effect: effect,
requires: ['computeStyles']
};
\ No newline at end of file
// @flow
import type { Modifier, ModifierArguments } from '../types';
import getNodeName from '../dom-utils/getNodeName';
import { isHTMLElement } from '../dom-utils/instanceOf';
// This modifier takes the styles prepared by the `computeStyles` modifier
// and applies them to the HTMLElements such as popper and arrow
function applyStyles({ state }: ModifierArguments<{||}>) {
Object.keys(state.elements).forEach((name) => {
const style = state.styles[name] || {};
const attributes = state.attributes[name] || {};
const element = state.elements[name];
// arrow is optional + virtual elements
if (!isHTMLElement(element) || !getNodeName(element)) {
return;
}
// Flow doesn't support to extend this property, but it's the most
// effective way to apply styles to an HTMLElement
// $FlowFixMe[cannot-write]
Object.assign(element.style, style);
Object.keys(attributes).forEach((name) => {
const value = attributes[name];
if (value === false) {
element.removeAttribute(name);
} else {
element.setAttribute(name, value === true ? '' : value);
}
});
});
}
function effect({ state }: ModifierArguments<{||}>) {
const initialStyles = {
popper: {
position: state.options.strategy,
left: '0',
top: '0',
margin: '0',
},
arrow: {
position: 'absolute',
},
reference: {},
};
Object.assign(state.elements.popper.style, initialStyles.popper);
if (state.elements.arrow) {
Object.assign(state.elements.arrow.style, initialStyles.arrow);
}
return () => {
Object.keys(state.elements).forEach((name) => {
const element = state.elements[name];
const attributes = state.attributes[name] || {};
const styleProperties = Object.keys(
state.styles.hasOwnProperty(name)
? state.styles[name]
: initialStyles[name]
);
// Set all values to an empty string to unset them
const style = styleProperties.reduce((style, property) => {
style[property] = '';
return style;
}, {});
// arrow is optional + virtual elements
if (!isHTMLElement(element) || !getNodeName(element)) {
return;
}
Object.assign(element.style, style);
Object.keys(attributes).forEach((attribute) => {
element.removeAttribute(attribute);
});
});
};
}
// eslint-disable-next-line import/no-unused-modules
export type ApplyStylesModifier = Modifier<'applyStyles', {||}>;
export default ({
name: 'applyStyles',
enabled: true,
phase: 'write',
fn: applyStyles,
effect,
requires: ['computeStyles'],
}: ApplyStylesModifier);
import { Modifier, Padding } from "../types";
export declare type Options = {
element: HTMLElement | string | null;
padding: Padding;
};
export declare type ArrowModifier = Modifier<"arrow", Options>;
declare const _default: Modifier<"arrow", Options>;
export default _default;
import getBasePlacement from "../utils/getBasePlacement.js";
import getLayoutRect from "../dom-utils/getLayoutRect.js";
import contains from "../dom-utils/contains.js";
import getOffsetParent from "../dom-utils/getOffsetParent.js";
import getMainAxisFromPlacement from "../utils/getMainAxisFromPlacement.js";
import within from "../utils/within.js";
import mergePaddingObject from "../utils/mergePaddingObject.js";
import expandToHashMap from "../utils/expandToHashMap.js";
import { left, right, basePlacements, top, bottom } from "../enums.js";
import { isHTMLElement } from "../dom-utils/instanceOf.js"; // eslint-disable-next-line import/no-unused-modules
function arrow(_ref) {
var _state$modifiersData$;
var state = _ref.state,
name = _ref.name;
var arrowElement = state.elements.arrow;
var popperOffsets = state.modifiersData.popperOffsets;
var basePlacement = getBasePlacement(state.placement);
var axis = getMainAxisFromPlacement(basePlacement);
var isVertical = [left, right].indexOf(basePlacement) >= 0;
var len = isVertical ? 'height' : 'width';
if (!arrowElement || !popperOffsets) {
return;
}
var paddingObject = state.modifiersData[name + "#persistent"].padding;
var arrowRect = getLayoutRect(arrowElement);
var minProp = axis === 'y' ? top : left;
var maxProp = axis === 'y' ? bottom : right;
var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
var startDiff = popperOffsets[axis] - state.rects.reference[axis];
var arrowOffsetParent = getOffsetParent(arrowElement);
var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
// outside of the popper bounds
var min = paddingObject[minProp];
var max = clientSize - arrowRect[len] - paddingObject[maxProp];
var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
var offset = within(min, center, max); // Prevents breaking syntax highlighting...
var axisProp = axis;
state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
}
function effect(_ref2) {
var state = _ref2.state,
options = _ref2.options,
name = _ref2.name;
var _options$element = options.element,
arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element,
_options$padding = options.padding,
padding = _options$padding === void 0 ? 0 : _options$padding;
if (arrowElement == null) {
return;
} // CSS selector
if (typeof arrowElement === 'string') {
arrowElement = state.elements.popper.querySelector(arrowElement);
if (!arrowElement) {
return;
}
}
if (process.env.NODE_ENV !== "production") {
if (!isHTMLElement(arrowElement)) {
console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));
}
}
if (!contains(state.elements.popper, arrowElement)) {
if (process.env.NODE_ENV !== "production") {
console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' '));
}
return;
}
state.elements.arrow = arrowElement;
state.modifiersData[name + "#persistent"] = {
padding: mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements))
};
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'arrow',
enabled: true,
phase: 'main',
fn: arrow,
effect: effect,
requires: ['popperOffsets'],
requiresIfExists: ['preventOverflow']
};
\ No newline at end of file
// @flow
import type { Modifier, ModifierArguments, Padding } from '../types';
import getBasePlacement from '../utils/getBasePlacement';
import getLayoutRect from '../dom-utils/getLayoutRect';
import contains from '../dom-utils/contains';
import getOffsetParent from '../dom-utils/getOffsetParent';
import getMainAxisFromPlacement from '../utils/getMainAxisFromPlacement';
import within from '../utils/within';
import mergePaddingObject from '../utils/mergePaddingObject';
import expandToHashMap from '../utils/expandToHashMap';
import { left, right, basePlacements, top, bottom } from '../enums';
import { isHTMLElement } from '../dom-utils/instanceOf';
// eslint-disable-next-line import/no-unused-modules
export type Options = {
element: HTMLElement | string | null,
padding: Padding,
};
function arrow({ state, name }: ModifierArguments<Options>) {
const arrowElement = state.elements.arrow;
const popperOffsets = state.modifiersData.popperOffsets;
const basePlacement = getBasePlacement(state.placement);
const axis = getMainAxisFromPlacement(basePlacement);
const isVertical = [left, right].indexOf(basePlacement) >= 0;
const len = isVertical ? 'height' : 'width';
if (!arrowElement || !popperOffsets) {
return;
}
const paddingObject = state.modifiersData[`${name}#persistent`].padding;
const arrowRect = getLayoutRect(arrowElement);
const minProp = axis === 'y' ? top : left;
const maxProp = axis === 'y' ? bottom : right;
const endDiff =
state.rects.reference[len] +
state.rects.reference[axis] -
popperOffsets[axis] -
state.rects.popper[len];
const startDiff = popperOffsets[axis] - state.rects.reference[axis];
const arrowOffsetParent = getOffsetParent(arrowElement);
const clientSize = arrowOffsetParent
? axis === 'y'
? arrowOffsetParent.clientHeight || 0
: arrowOffsetParent.clientWidth || 0
: 0;
const centerToReference = endDiff / 2 - startDiff / 2;
// Make sure the arrow doesn't overflow the popper if the center point is
// outside of the popper bounds
const min = paddingObject[minProp];
const max = clientSize - arrowRect[len] - paddingObject[maxProp];
const center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
const offset = within(min, center, max);
// Prevents breaking syntax highlighting...
const axisProp: string = axis;
state.modifiersData[name] = {
[axisProp]: offset,
centerOffset: offset - center,
};
}
function effect({ state, options, name }: ModifierArguments<Options>) {
let { element: arrowElement = '[data-popper-arrow]', padding = 0 } = options;
if (arrowElement == null) {
return;
}
// CSS selector
if (typeof arrowElement === 'string') {
arrowElement = state.elements.popper.querySelector(arrowElement);
if (!arrowElement) {
return;
}
}
if (false) {
if (!isHTMLElement(arrowElement)) {
console.error(
[
'Popper: "arrow" element must be an HTMLElement (not an SVGElement).',
'To use an SVG arrow, wrap it in an HTMLElement that will be used as',
'the arrow.',
].join(' ')
);
}
}
if (!contains(state.elements.popper, arrowElement)) {
if (false) {
console.error(
[
'Popper: "arrow" modifier\'s `element` must be a child of the popper',
'element.',
].join(' ')
);
}
return;
}
state.elements.arrow = arrowElement;
state.modifiersData[`${name}#persistent`] = {
padding: mergePaddingObject(
typeof padding !== 'number'
? padding
: expandToHashMap(padding, basePlacements)
),
};
}
// eslint-disable-next-line import/no-unused-modules
export type ArrowModifier = Modifier<'arrow', Options>;
export default ({
name: 'arrow',
enabled: true,
phase: 'main',
fn: arrow,
effect,
requires: ['popperOffsets'],
requiresIfExists: ['preventOverflow'],
}: ArrowModifier);
import { PositioningStrategy, Modifier, Rect } from "../types";
import { BasePlacement } from "../enums";
export declare type Options = {
gpuAcceleration: boolean;
adaptive: boolean;
roundOffsets: boolean;
};
export declare function mapToStyles({ popper, popperRect, placement, offsets, position, gpuAcceleration, adaptive, roundOffsets }: {
popper: HTMLElement;
popperRect: Rect;
placement: BasePlacement;
offsets: Partial<{
x: number;
y: number;
centerOffset: number;
}>;
position: PositioningStrategy;
gpuAcceleration: boolean;
adaptive: boolean;
roundOffsets: boolean;
}): {
transform: string;
top: string;
right: string;
bottom: string;
left: string;
position: PositioningStrategy;
};
export declare type ComputeStylesModifier = Modifier<"computeStyles", Options>;
declare const _default: Modifier<"computeStyles", Options>;
export default _default;
import { top, left, right, bottom } from "../enums.js";
import getOffsetParent from "../dom-utils/getOffsetParent.js";
import getWindow from "../dom-utils/getWindow.js";
import getDocumentElement from "../dom-utils/getDocumentElement.js";
import getComputedStyle from "../dom-utils/getComputedStyle.js";
import getBasePlacement from "../utils/getBasePlacement.js"; // eslint-disable-next-line import/no-unused-modules
var unsetSides = {
top: 'auto',
right: 'auto',
bottom: 'auto',
left: 'auto'
}; // Round the offsets to the nearest suitable subpixel based on the DPR.
// Zooming can change the DPR, but it seems to report a value that will
// cleanly divide the values into the appropriate subpixels.
function roundOffsetsByDPR(_ref) {
var x = _ref.x,
y = _ref.y;
var win = window;
var dpr = win.devicePixelRatio || 1;
return {
x: Math.round(x * dpr) / dpr || 0,
y: Math.round(y * dpr) / dpr || 0
};
}
export function mapToStyles(_ref2) {
var _Object$assign2;
var popper = _ref2.popper,
popperRect = _ref2.popperRect,
placement = _ref2.placement,
offsets = _ref2.offsets,
position = _ref2.position,
gpuAcceleration = _ref2.gpuAcceleration,
adaptive = _ref2.adaptive,
roundOffsets = _ref2.roundOffsets;
var _ref3 = roundOffsets ? roundOffsetsByDPR(offsets) : offsets,
_ref3$x = _ref3.x,
x = _ref3$x === void 0 ? 0 : _ref3$x,
_ref3$y = _ref3.y,
y = _ref3$y === void 0 ? 0 : _ref3$y;
var hasX = offsets.hasOwnProperty('x');
var hasY = offsets.hasOwnProperty('y');
var sideX = left;
var sideY = top;
var win = window;
if (adaptive) {
var offsetParent = getOffsetParent(popper);
if (offsetParent === getWindow(popper)) {
offsetParent = getDocumentElement(popper);
} // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
/*:: offsetParent = (offsetParent: Element); */
if (placement === top) {
sideY = bottom;
y -= offsetParent.clientHeight - popperRect.height;
y *= gpuAcceleration ? 1 : -1;
}
if (placement === left) {
sideX = right;
x -= offsetParent.clientWidth - popperRect.width;
x *= gpuAcceleration ? 1 : -1;
}
}
var commonStyles = Object.assign({
position: position
}, adaptive && unsetSides);
if (gpuAcceleration) {
var _Object$assign;
return Object.assign(Object.assign({}, commonStyles), {}, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
}
return Object.assign(Object.assign({}, commonStyles), {}, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
}
function computeStyles(_ref4) {
var state = _ref4.state,
options = _ref4.options;
var _options$gpuAccelerat = options.gpuAcceleration,
gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
_options$adaptive = options.adaptive,
adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
_options$roundOffsets = options.roundOffsets,
roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
if (process.env.NODE_ENV !== "production") {
var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';
if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {
return transitionProperty.indexOf(property) >= 0;
})) {
console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));
}
}
var commonStyles = {
placement: getBasePlacement(state.placement),
popper: state.elements.popper,
popperRect: state.rects.popper,
gpuAcceleration: gpuAcceleration
};
if (state.modifiersData.popperOffsets != null) {
state.styles.popper = Object.assign(Object.assign({}, state.styles.popper), mapToStyles(Object.assign(Object.assign({}, commonStyles), {}, {
offsets: state.modifiersData.popperOffsets,
position: state.options.strategy,
adaptive: adaptive,
roundOffsets: roundOffsets
})));
}
if (state.modifiersData.arrow != null) {
state.styles.arrow = Object.assign(Object.assign({}, state.styles.arrow), mapToStyles(Object.assign(Object.assign({}, commonStyles), {}, {
offsets: state.modifiersData.arrow,
position: 'absolute',
adaptive: false,
roundOffsets: roundOffsets
})));
}
state.attributes.popper = Object.assign(Object.assign({}, state.attributes.popper), {}, {
'data-popper-placement': state.placement
});
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'computeStyles',
enabled: true,
phase: 'beforeWrite',
fn: computeStyles,
data: {}
};
\ No newline at end of file
// @flow
import type {
PositioningStrategy,
Offsets,
Modifier,
ModifierArguments,
Rect,
Window,
} from '../types';
import { type BasePlacement, top, left, right, bottom } from '../enums';
import getOffsetParent from '../dom-utils/getOffsetParent';
import getWindow from '../dom-utils/getWindow';
import getDocumentElement from '../dom-utils/getDocumentElement';
import getComputedStyle from '../dom-utils/getComputedStyle';
import getBasePlacement from '../utils/getBasePlacement';
// eslint-disable-next-line import/no-unused-modules
export type Options = {
gpuAcceleration: boolean,
adaptive: boolean,
roundOffsets: boolean,
};
const unsetSides = {
top: 'auto',
right: 'auto',
bottom: 'auto',
left: 'auto',
};
// Round the offsets to the nearest suitable subpixel based on the DPR.
// Zooming can change the DPR, but it seems to report a value that will
// cleanly divide the values into the appropriate subpixels.
function roundOffsetsByDPR({ x, y }): Offsets {
const win: Window = window;
const dpr = win.devicePixelRatio || 1;
return {
x: Math.round(x * dpr) / dpr || 0,
y: Math.round(y * dpr) / dpr || 0,
};
}
export function mapToStyles({
popper,
popperRect,
placement,
offsets,
position,
gpuAcceleration,
adaptive,
roundOffsets,
}: {
popper: HTMLElement,
popperRect: Rect,
placement: BasePlacement,
offsets: $Shape<{ x: number, y: number, centerOffset: number }>,
position: PositioningStrategy,
gpuAcceleration: boolean,
adaptive: boolean,
roundOffsets: boolean,
}) {
let { x = 0, y = 0 } = roundOffsets ? roundOffsetsByDPR(offsets) : offsets;
const hasX = offsets.hasOwnProperty('x');
const hasY = offsets.hasOwnProperty('y');
let sideX: string = left;
let sideY: string = top;
const win: Window = window;
if (adaptive) {
let offsetParent = getOffsetParent(popper);
if (offsetParent === getWindow(popper)) {
offsetParent = getDocumentElement(popper);
}
// $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
/*:: offsetParent = (offsetParent: Element); */
if (placement === top) {
sideY = bottom;
y -= offsetParent.clientHeight - popperRect.height;
y *= gpuAcceleration ? 1 : -1;
}
if (placement === left) {
sideX = right;
x -= offsetParent.clientWidth - popperRect.width;
x *= gpuAcceleration ? 1 : -1;
}
}
const commonStyles = {
position,
...(adaptive && unsetSides),
};
if (gpuAcceleration) {
return {
...commonStyles,
[sideY]: hasY ? '0' : '',
[sideX]: hasX ? '0' : '',
// Layer acceleration can disable subpixel rendering which causes slightly
// blurry text on low PPI displays, so we want to use 2D transforms
// instead
transform:
(win.devicePixelRatio || 1) < 2
? `translate(${x}px, ${y}px)`
: `translate3d(${x}px, ${y}px, 0)`,
};
}
return {
...commonStyles,
[sideY]: hasY ? `${y}px` : '',
[sideX]: hasX ? `${x}px` : '',
transform: '',
};
}
function computeStyles({ state, options }: ModifierArguments<Options>) {
const {
gpuAcceleration = true,
adaptive = true,
roundOffsets = true,
} = options;
if (false) {
const transitionProperty =
getComputedStyle(state.elements.popper).transitionProperty || '';
if (
adaptive &&
['transform', 'top', 'right', 'bottom', 'left'].some(
(property) => transitionProperty.indexOf(property) >= 0
)
) {
console.warn(
[
'Popper: Detected CSS transitions on at least one of the following',
'CSS properties: "transform", "top", "right", "bottom", "left".',
'\n\n',
'Disable the "computeStyles" modifier\'s `adaptive` option to allow',
'for smooth transitions, or remove these properties from the CSS',
'transition declaration on the popper element if only transitioning',
'opacity or background-color for example.',
'\n\n',
'We recommend using the popper element as a wrapper around an inner',
'element that can have any CSS property transitioned for animations.',
].join(' ')
);
}
}
const commonStyles = {
placement: getBasePlacement(state.placement),
popper: state.elements.popper,
popperRect: state.rects.popper,
gpuAcceleration,
};
if (state.modifiersData.popperOffsets != null) {
state.styles.popper = {
...state.styles.popper,
...mapToStyles({
...commonStyles,
offsets: state.modifiersData.popperOffsets,
position: state.options.strategy,
adaptive,
roundOffsets,
}),
};
}
if (state.modifiersData.arrow != null) {
state.styles.arrow = {
...state.styles.arrow,
...mapToStyles({
...commonStyles,
offsets: state.modifiersData.arrow,
position: 'absolute',
adaptive: false,
roundOffsets,
}),
};
}
state.attributes.popper = {
...state.attributes.popper,
'data-popper-placement': state.placement,
};
}
// eslint-disable-next-line import/no-unused-modules
export type ComputeStylesModifier = Modifier<'computeStyles', Options>;
export default ({
name: 'computeStyles',
enabled: true,
phase: 'beforeWrite',
fn: computeStyles,
data: {},
}: ComputeStylesModifier);
import { Modifier } from "../types";
export declare type Options = {
scroll: boolean;
resize: boolean;
};
export declare type EventListenersModifier = Modifier<"eventListeners", Options>;
declare const _default: Modifier<"eventListeners", Options>;
export default _default;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment