UNPKG

@kubit-ui-web/react-components

Version:

Kubit React Components is a customizable, accessible library of React web components, designed to enhance your application's user experience

61 lines 3.15 kB
import { getCssDimensions } from '../utils/getCssDimensions'; import { getLengthFromAxis } from '../utils/getLengthFromAxis'; import { getMainAxisFromPlacement } from '../utils/getMainAxisFromPlacement'; import { getOffsetParent } from '../utils/getOffsetParent'; import { getSideObjectFromPadding } from '../utils/getPaddingObject'; import { isElement } from '../utils/is.utils'; import { within } from '../utils/within'; export const arrow = (options) => ({ name: 'arrow', options, fn(state) { // Since `element` is required, we don't Partial<> the type. const { element, padding = 0 } = options || {}; const { x, y, placement, rects, elements } = state; if (element === null) { return {}; } const paddingObject = getSideObjectFromPadding(padding); const coords = { x, y }; const axis = getMainAxisFromPlacement(placement); const length = getLengthFromAxis(axis); const arrowDimensions = getCssDimensions(element); const isYAxis = axis === 'y'; const minProp = isYAxis ? 'top' : 'left'; const maxProp = isYAxis ? 'bottom' : 'right'; const clientProp = isYAxis ? 'clientHeight' : 'clientWidth'; const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length]; const startDiff = coords[axis] - rects.reference[axis]; const arrowOffsetParent = getOffsetParent(element); let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0; // DOM platform can return `window` as the `offsetParent`. if (!clientSize || !isElement(arrowOffsetParent)) { clientSize = elements.floating[clientProp] || rects.floating[length]; } const centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the floating element if the center // point is outside the floating element's bounds. const min = paddingObject[minProp]; const max = clientSize - arrowDimensions[length] - paddingObject[maxProp]; const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference; const offset = within(min, center, max); // If the reference is small enough that the arrow's padding causes it to // to point to nothing for an aligned placement, adjust the offset of the // floating element itself. This stops `shift()` from taking action, but can // be worked around by calling it again after the `arrow()` if desired. const shouldAddOffset = center !== offset && rects.reference[length] / 2 - (center < min ? paddingObject[minProp] : paddingObject[maxProp]) - arrowDimensions[length] / 2 < 0; const alignmentOffset = shouldAddOffset ? (center < min ? min - center : max - center) : 0; return { [axis]: coords[axis] - alignmentOffset, data: { [axis]: offset, centerOffset: center - offset, }, }; }, }); //# sourceMappingURL=arrow.js.map