react-tiny-popover
Advanced tools
Comparing version 5.1.0 to 6.0.0-beta.0
@@ -28,4 +28,4 @@ "use strict"; | ||
var arrowWidth = arrowSize * 2; | ||
var top = (targetRect.top - popoverRect.top) + (targetRect.height / 2) - (arrowWidth / 2); | ||
var left = (targetRect.left - popoverRect.left) + (targetRect.width / 2) - (arrowWidth / 2); | ||
var top = targetRect.top - popoverRect.top + targetRect.height / 2 - arrowWidth / 2; | ||
var left = targetRect.left - popoverRect.left + targetRect.width / 2 - arrowWidth / 2; | ||
left = left < 0 ? 0 : left; | ||
@@ -74,1 +74,2 @@ left = left + arrowWidth > popoverRect.width ? popoverRect.width - arrowWidth : left; | ||
exports.ArrowContainer = ArrowContainer; | ||
//# sourceMappingURL=ArrowContainer.js.map |
@@ -8,18 +8,20 @@ import * as React from 'react'; | ||
export interface PopoverInfo { | ||
position: Position; | ||
align: Align; | ||
export interface PopoverState { | ||
isPositioned: boolean; | ||
position: PopoverPosition | undefined; | ||
nudgedLeft: number; | ||
nudgedTop: number; | ||
targetRect: ClientRect; | ||
childRect: ClientRect; | ||
popoverRect: ClientRect; | ||
padding?: number; | ||
align: PopoverAlign; | ||
} | ||
export type ContentRenderer = (args: PopoverInfo) => JSX.Element; | ||
export type ContentLocationGetter = (args: PopoverInfo) => ContentLocation; | ||
export type ContentRenderer = (args: PopoverState) => JSX.Element; | ||
export type ContentLocationGetter = (args: PopoverState) => ContentLocation; | ||
export declare type Position = 'left' | 'right' | 'top' | 'bottom'; | ||
export declare type Align = 'start' | 'center' | 'end'; | ||
export declare type PopoverPosition = 'left' | 'right' | 'top' | 'bottom'; | ||
export declare type PopoverAlign = 'start' | 'center' | 'end'; | ||
export declare interface PopoverProps { | ||
export declare interface DepricatedPopoverProps { | ||
children: JSX.Element | ((ref: React.Ref<any>) => JSX.Element); | ||
@@ -31,3 +33,3 @@ isOpen: boolean; | ||
padding?: number; | ||
position?: Position | Position[]; | ||
position?: PopoverPosition | PopoverPosition[]; | ||
onClickOutside?: (e: MouseEvent) => void; | ||
@@ -37,3 +39,3 @@ disableReposition?: boolean; | ||
containerStyle?: Partial<CSSStyleDeclaration>; | ||
align?: Align; | ||
align?: PopoverAlign; | ||
transitionDuration?: number; | ||
@@ -45,3 +47,3 @@ windowBorderPadding?: number; | ||
children: JSX.Element; | ||
position: Position; | ||
position: PopoverPosition; | ||
targetRect: ClientRect; | ||
@@ -57,4 +59,4 @@ popoverRect: ClientRect; | ||
export declare interface PopoverState { | ||
popoverInfo: PopoverInfo; | ||
export declare interface DepricatedPopoverComponentState { | ||
popoverState: PopoverState; | ||
isTransitioningToClosed: boolean; | ||
@@ -64,2 +66,22 @@ internalisOpen: boolean; | ||
export default class Popover extends React.Component<PopoverProps, PopoverState> {} | ||
export default class DepricatedPopover extends React.Component< | ||
DepricatedPopoverProps, | ||
DepricatedPopoverComponentState | ||
> {} | ||
export interface PopoverProps { | ||
isOpen: boolean; | ||
children: JSX.Element; | ||
content: ContentRenderer | JSX.Element; | ||
reposition?: boolean; | ||
containerClassName?: string; | ||
containerStyle?: Partial<CSSStyleDeclaration>; | ||
containerParent?: HTMLElement; | ||
positions?: PopoverPosition[]; | ||
align?: PopoverAlign; | ||
padding?: number; | ||
windowPadding?: number; | ||
onClickOutside?: (e: MouseEvent) => void; | ||
} | ||
export declare const Popover: React.FC<PopoverProps>; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __spreadArrays = (this && this.__spreadArrays) || function () { | ||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; | ||
for (var r = Array(s), k = 0, i = 0; i < il; i++) | ||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) | ||
r[k] = a[j]; | ||
return r; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var react_1 = __importDefault(require("react")); | ||
var ArrowContainer_1 = require("./ArrowContainer"); | ||
exports.ArrowContainer = ArrowContainer_1.ArrowContainer; | ||
var react_1 = __importStar(require("react")); | ||
var PopoverPortal_1 = require("./PopoverPortal"); | ||
var util_1 = require("./util"); | ||
var DEFAULT_POSITION_ORDER = ['top', 'right', 'left', 'bottom']; | ||
var Popover = /** @class */ (function (_super) { | ||
__extends(Popover, _super); | ||
function Popover(props) { | ||
var _this = _super.call(this, props) || this; | ||
_this.targetRef = react_1.default.createRef(); | ||
_this.targetRect = undefined; | ||
_this.targetPositionIntervalHandler = undefined; | ||
_this.popoverDiv = undefined; | ||
_this.positionOrder = undefined; | ||
_this.willUnmount = false; | ||
_this.willMount = false; | ||
_this.onClick = function (e) { | ||
var _a = _this.props, onClickOutside = _a.onClickOutside, isOpen = _a.isOpen; | ||
if (!_this.willUnmount && | ||
!_this.willMount && | ||
!_this.popoverDiv.contains(e.target) && | ||
!_this.targetRef.current.contains(e.target) && | ||
onClickOutside && | ||
isOpen) { | ||
onClickOutside(e); | ||
} | ||
}; | ||
_this.onResize = function () { | ||
_this.renderPopover(); | ||
}; | ||
_this.state = { | ||
popoverInfo: undefined, | ||
isTransitioningToClosed: false, | ||
internalisOpen: false, | ||
}; | ||
_this.willUnmount = false; | ||
_this.willMount = true; | ||
return _this; | ||
} | ||
Popover.getDerivedStateFromProps = function (props, state) { | ||
var internalisOpen = state.internalisOpen, isTransitioningToClosed = state.isTransitioningToClosed; | ||
var isOpen = props.isOpen; | ||
if (internalisOpen === true && isOpen === false && !isTransitioningToClosed) { | ||
return { | ||
internalisOpen: false, | ||
isTransitioningToClosed: true, | ||
}; | ||
} | ||
// eslint-disable-next-line no-restricted-syntax | ||
return null; | ||
}; | ||
Popover.prototype.componentDidMount = function () { | ||
var _this = this; | ||
window.setTimeout(function () { return (_this.willMount = false); }); | ||
var _a = this.props, position = _a.position, isOpen = _a.isOpen; | ||
this.positionOrder = this.getPositionPriorityOrder(position); | ||
this.updatePopover(isOpen); | ||
}; | ||
Popover.prototype.componentDidUpdate = function (prevProps) { | ||
var prevIsOpen = prevProps.isOpen, prevAlign = prevProps.align, prevPosition = prevProps.position, prevTransitionDuration = prevProps.transitionDuration, prevPadding = prevProps.padding, prevWindowBorderPadding = prevProps.windowBorderPadding; | ||
var _a = this.props, isOpen = _a.isOpen, position = _a.position, transitionDuration = _a.transitionDuration, align = _a.align, contentDestination = _a.contentDestination, padding = _a.padding, windowBorderPadding = _a.windowBorderPadding; | ||
this.positionOrder = this.getPositionPriorityOrder(position); | ||
var hasNewDestination = prevProps.contentDestination !== contentDestination; | ||
if (prevIsOpen !== isOpen || | ||
prevAlign !== align || | ||
prevPosition !== position || | ||
prevPadding !== padding || | ||
prevWindowBorderPadding !== windowBorderPadding || | ||
hasNewDestination) { | ||
this.updatePopover(isOpen); | ||
} | ||
if (prevTransitionDuration !== transitionDuration) { | ||
this.popoverDiv.style.transition = "opacity " + transitionDuration + "s"; | ||
} | ||
}; | ||
Popover.prototype.componentWillUnmount = function () { | ||
this.willUnmount = true; | ||
window.clearTimeout(this.removePopoverTimeout); | ||
window.clearInterval(this.targetPositionIntervalHandler); | ||
window.removeEventListener('resize', this.onResize); | ||
window.removeEventListener('click', this.onClick); | ||
this.removePopover(); | ||
}; | ||
Popover.prototype.getNudgedPopoverPosition = function (_a) { | ||
var top = _a.top, left = _a.left, width = _a.width, height = _a.height; | ||
var padding = this.props.windowBorderPadding; | ||
top = top < padding ? padding : top; | ||
top = top + height > window.innerHeight - padding ? window.innerHeight - padding - height : top; | ||
left = left < padding ? padding : left; | ||
left = left + width > window.innerWidth - padding ? window.innerWidth - padding - width : left; | ||
return { top: top, left: left }; | ||
}; | ||
Popover.prototype.getPositionPriorityOrder = function (position) { | ||
if (position && typeof position !== 'string') { | ||
if (util_1.Constants.DEFAULT_POSITIONS.every(function (defaultPosition) { return position.find(function (p) { return p === defaultPosition; }) !== undefined; })) { | ||
return util_1.arrayUnique(position); | ||
} | ||
var remainingPositions = util_1.Constants.DEFAULT_POSITIONS.filter(function (defaultPosition) { return position.find(function (p) { return p === defaultPosition; }) === undefined; }); | ||
return util_1.arrayUnique(__spreadArrays(position, remainingPositions)); | ||
} | ||
if (position && typeof position === 'string') { | ||
var remainingPositions = util_1.Constants.DEFAULT_POSITIONS.filter(function (defaultPosition) { return defaultPosition !== position; }); | ||
return util_1.arrayUnique(__spreadArrays([position], remainingPositions)); | ||
} | ||
return DEFAULT_POSITION_ORDER; | ||
}; | ||
Popover.prototype.getLocationForPosition = function (position, newTargetRect, popoverRect) { | ||
var _a = this.props, padding = _a.padding, align = _a.align; | ||
var targetMidX = newTargetRect.left + newTargetRect.width / 2; | ||
var targetMidY = newTargetRect.top + newTargetRect.height / 2; | ||
var top; | ||
var left; | ||
switch (position) { | ||
case 'top': | ||
top = newTargetRect.top - popoverRect.height - padding; | ||
left = targetMidX - popoverRect.width / 2; | ||
if (align === 'start') { | ||
left = newTargetRect.left; | ||
var usePopover_1 = require("./usePopover"); | ||
var useMemoizedArray_1 = require("./useMemoizedArray"); | ||
exports.Popover = function (_a) { | ||
var isOpen = _a.isOpen, children = _a.children, content = _a.content, _b = _a.reposition, reposition = _b === void 0 ? true : _b, containerStyle = _a.containerStyle, _c = _a.containerClassName, containerClassName = _c === void 0 ? 'react-tiny-popover-container' : _c, _d = _a.positions, externalPositions = _d === void 0 ? util_1.Constants.DEFAULT_POSITIONS : _d, _e = _a.padding, padding = _e === void 0 ? util_1.Constants.DEFAULT_PADDING : _e, _f = _a.align, align = _f === void 0 ? util_1.Constants.DEFAULT_ALIGN : _f, _g = _a.windowPadding, windowPadding = _g === void 0 ? util_1.Constants.DEFAULT_WINDOW_PADDING : _g, onClickOutside = _a.onClickOutside; | ||
var positions = useMemoizedArray_1.useMemoizedArray(externalPositions); | ||
var childRef = react_1.useRef(); | ||
var _h = react_1.useState({ | ||
isPositioned: false, | ||
align: align, | ||
nudgedLeft: 0, | ||
nudgedTop: 0, | ||
position: positions[0], | ||
padding: padding, | ||
childRect: util_1.Constants.EMPTY_CLIENT_RECT, | ||
popoverRect: util_1.Constants.EMPTY_CLIENT_RECT, | ||
}), popoverState = _h[0], setPopoverState = _h[1]; | ||
var onPositionPopover = react_1.useCallback(function (popoverState) { return setPopoverState(popoverState); }, []); | ||
var _j = usePopover_1.usePopover({ | ||
childRef: childRef, | ||
containerClassName: containerClassName, | ||
containerStyle: containerStyle, | ||
positions: positions, | ||
align: align, | ||
padding: padding, | ||
windowPadding: windowPadding, | ||
reposition: reposition, | ||
onPositionPopover: onPositionPopover, | ||
}), positionPopover = _j[0], popoverRef = _j[1]; | ||
react_1.useLayoutEffect(function () { | ||
var shouldUpdatePopover = true; | ||
var updatePopover = function () { | ||
if (isOpen) { | ||
var childRect = childRef.current.getBoundingClientRect(); | ||
var popoverRect = popoverRef.current.getBoundingClientRect(); | ||
if (!util_1.rectsAreEqual(childRect, { | ||
top: popoverState.childRect.top, | ||
left: popoverState.childRect.left, | ||
width: popoverState.childRect.width, | ||
height: popoverState.childRect.height, | ||
bottom: popoverState.childRect.top + popoverState.childRect.height, | ||
right: popoverState.childRect.left + popoverState.childRect.width, | ||
}) || | ||
popoverRect.width !== popoverState.popoverRect.width || | ||
popoverRect.height !== popoverState.popoverRect.height) { | ||
positionPopover(); | ||
} | ||
if (align === 'end') { | ||
left = newTargetRect.right - popoverRect.width; | ||
if (shouldUpdatePopover) { | ||
window.requestAnimationFrame(updatePopover); | ||
} | ||
break; | ||
case 'left': | ||
top = targetMidY - popoverRect.height / 2; | ||
left = newTargetRect.left - padding - popoverRect.width; | ||
if (align === 'start') { | ||
top = newTargetRect.top; | ||
} | ||
if (align === 'end') { | ||
top = newTargetRect.bottom - popoverRect.height; | ||
} | ||
break; | ||
case 'bottom': | ||
top = newTargetRect.bottom + padding; | ||
left = targetMidX - popoverRect.width / 2; | ||
if (align === 'start') { | ||
left = newTargetRect.left; | ||
} | ||
if (align === 'end') { | ||
left = newTargetRect.right - popoverRect.width; | ||
} | ||
break; | ||
case 'right': | ||
top = targetMidY - popoverRect.height / 2; | ||
left = newTargetRect.right + padding; | ||
if (align === 'start') { | ||
top = newTargetRect.top; | ||
} | ||
if (align === 'end') { | ||
top = newTargetRect.bottom - popoverRect.height; | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
return { top: top, left: left }; | ||
}; | ||
Popover.prototype.createContainer = function () { | ||
var _a = this.props, containerStyle = _a.containerStyle, containerClassName = _a.containerClassName; | ||
var container = window.document.createElement('div'); | ||
container.style.overflow = 'hidden'; | ||
if (containerStyle) { | ||
Object.keys(containerStyle).forEach(function (key) { | ||
return (container.style[key] = containerStyle[key]); | ||
}); | ||
} | ||
container.className = containerClassName; | ||
container.style.position = 'absolute'; | ||
container.style.top = '0'; | ||
container.style.left = '0'; | ||
return container; | ||
}; | ||
Popover.prototype.updatePopover = function (isOpen) { | ||
if (isOpen && this.targetRef) { | ||
if (!this.popoverDiv || !this.popoverDiv.parentNode) { | ||
var transitionDuration = this.props.transitionDuration; | ||
this.popoverDiv = this.createContainer(); | ||
this.popoverDiv.style.opacity = '0'; | ||
this.popoverDiv.style.transition = "opacity " + transitionDuration + "s"; | ||
} | ||
window.addEventListener('resize', this.onResize); | ||
window.addEventListener('click', this.onClick); | ||
this.renderPopover(); | ||
} | ||
else { | ||
this.removePopover(); | ||
} | ||
}; | ||
Popover.prototype.startTargetPositionListener = function (checkInterval) { | ||
var _this = this; | ||
if (!this.targetPositionIntervalHandler) { | ||
this.targetPositionIntervalHandler = window.setInterval(function () { | ||
var newTargetRect = _this.targetRef.current.getBoundingClientRect(); | ||
if (util_1.targetPositionHasChanged(_this.targetRect, newTargetRect)) { | ||
_this.renderPopover(); | ||
} | ||
_this.targetRect = newTargetRect; | ||
}, checkInterval); | ||
} | ||
}; | ||
Popover.prototype.removePopover = function () { | ||
var _this = this; | ||
// this should now be a callback to handle event listening upon portal disappearance | ||
var _a = this.props, transitionDuration = _a.transitionDuration, isOpen = _a.isOpen; | ||
if (this.popoverDiv) { | ||
this.popoverDiv.style.opacity = '0'; | ||
} | ||
var remove = function () { | ||
if (_this.willUnmount || !isOpen || !_this.popoverDiv.parentNode) { | ||
window.clearInterval(_this.targetPositionIntervalHandler); | ||
window.removeEventListener('resize', _this.onResize); | ||
window.removeEventListener('click', _this.onClick); | ||
_this.targetPositionIntervalHandler = undefined; | ||
_this.setState({ isTransitioningToClosed: false }); | ||
else { | ||
setPopoverState(function (prev) { return (__assign(__assign({}, prev), { isPositioned: false })); }); | ||
} | ||
}; | ||
if (!this.willUnmount) { | ||
this.removePopoverTimeout = window.setTimeout(remove, (transitionDuration || util_1.Constants.FADE_TRANSITION) * 1000); | ||
window.requestAnimationFrame(updatePopover); | ||
return function () { | ||
shouldUpdatePopover = false; | ||
}; | ||
}, [ | ||
isOpen, | ||
popoverRef, | ||
popoverState.childRect.width, | ||
popoverState.childRect.height, | ||
popoverState.childRect.top, | ||
popoverState.childRect.left, | ||
popoverState.popoverRect.width, | ||
popoverState.popoverRect.height, | ||
positionPopover, | ||
align, | ||
padding, | ||
positions, | ||
reposition, | ||
windowPadding, | ||
]); | ||
react_1.useEffect(function () { | ||
var popoverElement = popoverRef.current; | ||
var style = __assign(__assign({}, util_1.Constants.DEFAULT_CONTAINER_STYLE), containerStyle); | ||
if (popoverState.isPositioned) { | ||
Object.assign(popoverElement.style, style); | ||
} | ||
else { | ||
remove(); | ||
return function () { | ||
Object.keys(style).forEach(function (key) { return (popoverElement.style[key] = null); }); | ||
}; | ||
}, [popoverState.isPositioned, containerStyle, popoverRef]); | ||
var handleOnClickOutside = react_1.useCallback(function (e) { | ||
if (isOpen && | ||
!popoverRef.current.contains(e.target) && | ||
!childRef.current.contains(e.target)) { | ||
onClickOutside === null || onClickOutside === void 0 ? void 0 : onClickOutside(e); | ||
} | ||
}; | ||
Popover.prototype.renderPopover = function (positionIndex) { | ||
var _this = this; | ||
if (positionIndex === void 0) { positionIndex = 0; } | ||
if (positionIndex >= this.positionOrder.length) { | ||
return; | ||
} | ||
this.renderWithPosition({ | ||
position: this.positionOrder[positionIndex], | ||
targetRect: this.targetRef.current.getBoundingClientRect(), | ||
}, function (violation, rect) { | ||
var _a; | ||
var _b = _this.props, disableReposition = _b.disableReposition, contentLocation = _b.contentLocation, contentDestination = _b.contentDestination; | ||
if (violation && !disableReposition && !(typeof contentLocation === 'object')) { | ||
_this.renderPopover(positionIndex + 1); | ||
} | ||
else { | ||
var _c = _this.props, contentLocation_1 = _c.contentLocation, align = _c.align; | ||
var _d = _this.getNudgedPopoverPosition(rect), nudgedTop = _d.top, nudgedLeft = _d.left; | ||
var rectTop = rect.top, rectLeft = rect.left; | ||
var position = _this.positionOrder[positionIndex]; | ||
var _e = disableReposition | ||
? { top: rectTop, left: rectLeft } | ||
: { top: nudgedTop, left: nudgedLeft }, top_1 = _e.top, left = _e.left; | ||
if (contentLocation_1) { | ||
var targetRect = _this.targetRef.current.getBoundingClientRect(); | ||
var popoverRect = _this.popoverDiv.getBoundingClientRect(); | ||
(_a = typeof contentLocation_1 === 'function' | ||
? contentLocation_1({ | ||
targetRect: targetRect, | ||
popoverRect: popoverRect, | ||
position: position, | ||
align: align, | ||
nudgedLeft: nudgedLeft, | ||
nudgedTop: nudgedTop, | ||
}) | ||
: contentLocation_1, top_1 = _a.top, left = _a.left); | ||
_this.popoverDiv.style.left = left.toFixed() + "px"; | ||
_this.popoverDiv.style.top = top_1.toFixed() + "px"; | ||
} | ||
else { | ||
var destinationTopOffset = 0; | ||
var destinationLeftOffset = 0; | ||
if (contentDestination) { | ||
var destRect = contentDestination.getBoundingClientRect(); | ||
destinationTopOffset = -destRect.top; | ||
destinationLeftOffset = -destRect.left; | ||
} | ||
var absoluteTop = top_1 + window.pageYOffset; | ||
var absoluteLeft = left + window.pageXOffset; | ||
var finalLeft = absoluteLeft + destinationTopOffset; | ||
var finalTop = absoluteTop + destinationLeftOffset; | ||
_this.popoverDiv.style.left = finalLeft.toFixed() + "px"; | ||
_this.popoverDiv.style.top = finalTop.toFixed() + "px"; | ||
} | ||
_this.popoverDiv.style.width = undefined; | ||
_this.popoverDiv.style.height = undefined; | ||
_this.renderWithPosition({ | ||
position: position, | ||
nudgedTop: nudgedTop - rect.top, | ||
nudgedLeft: nudgedLeft - rect.left, | ||
targetRect: _this.targetRef.current.getBoundingClientRect(), | ||
popoverRect: _this.popoverDiv.getBoundingClientRect(), | ||
}, function () { | ||
_this.startTargetPositionListener(10); | ||
if (_this.popoverDiv.style.opacity !== '1' && !_this.state.isTransitioningToClosed) { | ||
_this.popoverDiv.style.opacity = '1'; | ||
} | ||
}); | ||
} | ||
}, [isOpen, onClickOutside, popoverRef]); | ||
react_1.useEffect(function () { | ||
window.addEventListener('click', handleOnClickOutside); | ||
return function () { | ||
window.removeEventListener('click', handleOnClickOutside); | ||
}; | ||
}, [handleOnClickOutside]); | ||
var renderChild = function () { | ||
return react_1.default.cloneElement(children, { | ||
ref: childRef, | ||
}); | ||
}; | ||
Popover.prototype.renderPopoverContent = function () { | ||
var _a = this.props, content = _a.content, isOpen = _a.isOpen, contentDestination = _a.contentDestination; | ||
var _b = this.state, popoverInfo = _b.popoverInfo, isTransitioningToClosed = _b.isTransitioningToClosed; | ||
if ((isOpen || isTransitioningToClosed) && this.popoverDiv && popoverInfo) { | ||
var getContent = function (args) { | ||
return typeof content === 'function' ? content(args) : content; | ||
}; | ||
return (react_1.default.createElement(PopoverPortal_1.PopoverPortal, { element: this.popoverDiv, container: contentDestination || window.document.body }, getContent(popoverInfo))); | ||
} | ||
return null; | ||
var renderPopover = function () { | ||
if (!isOpen) | ||
return null; | ||
return (react_1.default.createElement(PopoverPortal_1.PopoverPortal, { element: popoverRef.current, container: window.document.body }, typeof content === 'function' ? content(popoverState) : content)); | ||
}; | ||
Popover.prototype.renderChildContent = function () { | ||
var children = this.props.children; | ||
return typeof children === 'function' | ||
? children(this.targetRef) | ||
: react_1.default.cloneElement(children, { | ||
ref: this.targetRef, | ||
}); | ||
}; | ||
Popover.prototype.renderWithPosition = function (_a, callback) { | ||
var _this = this; | ||
var position = _a.position, _b = _a.nudgedLeft, nudgedLeft = _b === void 0 ? 0 : _b, _c = _a.nudgedTop, nudgedTop = _c === void 0 ? 0 : _c, _d = _a.targetRect, targetRect = _d === void 0 ? util_1.Constants.EMPTY_CLIENT_RECT : _d, _e = _a.popoverRect, popoverRect = _e === void 0 ? util_1.Constants.EMPTY_CLIENT_RECT : _e; | ||
var _f = this.props, padding = _f.windowBorderPadding, align = _f.align; | ||
var popoverInfo = { position: position, nudgedLeft: nudgedLeft, nudgedTop: nudgedTop, targetRect: targetRect, popoverRect: popoverRect, align: align }; | ||
if (!util_1.popoverInfosAreEqual(this.state.popoverInfo, popoverInfo)) { | ||
window.clearTimeout(this.removePopoverTimeout); | ||
this.setState({ popoverInfo: popoverInfo, isTransitioningToClosed: false, internalisOpen: true }, function () { | ||
if (_this.willUnmount) { | ||
return; | ||
} | ||
targetRect = _this.targetRef.current.getBoundingClientRect(); | ||
popoverRect = _this.popoverDiv.getBoundingClientRect(); | ||
var _a = _this.getLocationForPosition(position, targetRect, popoverRect), top = _a.top, left = _a.left; | ||
callback((position === 'top' && top < padding) || | ||
(position === 'left' && left < padding) || | ||
(position === 'right' && left + popoverRect.width > window.innerWidth - padding) || | ||
(position === 'bottom' && top + popoverRect.height > window.innerHeight - padding), { width: popoverRect.width, height: popoverRect.height, top: top, left: left }); | ||
}); | ||
} | ||
}; | ||
Popover.prototype.render = function () { | ||
return (react_1.default.createElement(react_1.default.Fragment, null, | ||
this.renderChildContent(), | ||
this.renderPopoverContent())); | ||
}; | ||
Popover.defaultProps = { | ||
padding: util_1.Constants.DEFAULT_PADDING, | ||
windowBorderPadding: util_1.Constants.DEFAULT_WINDOW_PADDING, | ||
position: DEFAULT_POSITION_ORDER, | ||
align: 'center', | ||
containerClassName: util_1.Constants.POPOVER_CONTAINER_CLASS_NAME, | ||
transitionDuration: util_1.Constants.FADE_TRANSITION, | ||
}; | ||
return Popover; | ||
}(react_1.default.Component)); | ||
exports.default = Popover; | ||
return (react_1.default.createElement(react_1.default.Fragment, null, | ||
renderChild(), | ||
renderPopover())); | ||
}; | ||
//# sourceMappingURL=Popover.js.map |
@@ -10,5 +10,6 @@ "use strict"; | ||
return function () { return container.removeChild(element); }; | ||
}, [container]); | ||
}, [container, element]); | ||
return react_dom_1.createPortal(children, element); | ||
}; | ||
exports.PopoverPortal = PopoverPortal; | ||
//# sourceMappingURL=PopoverPortal.js.map |
166
dist/util.js
@@ -7,3 +7,12 @@ "use strict"; | ||
DEFAULT_WINDOW_PADDING: 6, | ||
DEFAULT_ALIGN: 'center', | ||
DEFAULT_CONTAINER_STYLE: { | ||
transition: 'transform 0.04s ease-in', | ||
}, | ||
FADE_TRANSITION: 0.35, | ||
TRACKER_PADDING: 0, | ||
OBSERVER_THRESHOLDS: Array(1000) | ||
.fill(null) | ||
.map(function (_, i) { return i / 1000; }) | ||
.reverse(), | ||
DEFAULT_ARROW_COLOR: 'black', | ||
@@ -32,17 +41,146 @@ DEFAULT_POSITIONS: ['top', 'left', 'right', 'bottom'], | ||
}; | ||
exports.popoverInfosAreEqual = function (infoA, infoB) { | ||
return infoA === infoB || | ||
((infoA === null || infoA === void 0 ? void 0 : infoA.align) === (infoB === null || infoB === void 0 ? void 0 : infoB.align) && | ||
(infoA === null || infoA === void 0 ? void 0 : infoA.nudgedLeft) === (infoB === null || infoB === void 0 ? void 0 : infoB.nudgedLeft) && | ||
(infoA === null || infoA === void 0 ? void 0 : infoA.nudgedTop) === (infoB === null || infoB === void 0 ? void 0 : infoB.nudgedTop) && | ||
exports.rectsAreEqual(infoA === null || infoA === void 0 ? void 0 : infoA.popoverRect, infoB === null || infoB === void 0 ? void 0 : infoB.popoverRect) && | ||
exports.rectsAreEqual(infoA === null || infoA === void 0 ? void 0 : infoA.targetRect, infoB === null || infoB === void 0 ? void 0 : infoB.targetRect) && | ||
(infoA === null || infoA === void 0 ? void 0 : infoA.position) === (infoB === null || infoB === void 0 ? void 0 : infoB.position)); | ||
exports.popoverStatesAreEqual = function (stateA, stateB) { | ||
return stateA === stateB || | ||
((stateA === null || stateA === void 0 ? void 0 : stateA.align) === (stateB === null || stateB === void 0 ? void 0 : stateB.align) && | ||
(stateA === null || stateA === void 0 ? void 0 : stateA.nudgedLeft) === (stateB === null || stateB === void 0 ? void 0 : stateB.nudgedLeft) && | ||
(stateA === null || stateA === void 0 ? void 0 : stateA.nudgedTop) === (stateB === null || stateB === void 0 ? void 0 : stateB.nudgedTop) && | ||
stateA.padding === stateB.padding && | ||
exports.rectsAreEqual(stateA === null || stateA === void 0 ? void 0 : stateA.popoverRect, stateB === null || stateB === void 0 ? void 0 : stateB.popoverRect) && | ||
exports.rectsAreEqual(stateA === null || stateA === void 0 ? void 0 : stateA.childRect, stateB === null || stateB === void 0 ? void 0 : stateB.childRect) && | ||
(stateA === null || stateA === void 0 ? void 0 : stateA.position) === (stateB === null || stateB === void 0 ? void 0 : stateB.position)); | ||
}; | ||
exports.targetPositionHasChanged = function (oldTargetRect, newTargetRect) { | ||
return oldTargetRect === undefined || | ||
oldTargetRect.left !== newTargetRect.left || | ||
oldTargetRect.top !== newTargetRect.top || | ||
oldTargetRect.width !== newTargetRect.width || | ||
oldTargetRect.height !== newTargetRect.height; | ||
exports.targetPositionHasChanged = function (oldRect, newRect) { | ||
return oldRect === undefined || | ||
oldRect.left !== newRect.left || | ||
oldRect.top !== newRect.top || | ||
oldRect.width !== newRect.width || | ||
oldRect.height !== newRect.height; | ||
}; | ||
exports.createContainer = function (containerStyle, containerClassName) { | ||
var container = window.document.createElement('div'); | ||
if (containerClassName) | ||
container.className = containerClassName; | ||
Object.assign(container.style, containerStyle); | ||
return container; | ||
}; | ||
exports.popoverRectForPosition = function (position, childRect, popoverRect, padding, align) { | ||
var targetMidX = childRect.left + childRect.width / 2; | ||
var targetMidY = childRect.top + childRect.height / 2; | ||
var width = popoverRect.width, height = popoverRect.height; | ||
var top; | ||
var left; | ||
switch (position) { | ||
case 'top': | ||
top = childRect.top - height - padding; | ||
left = targetMidX - width / 2; | ||
if (align === 'start') { | ||
left = childRect.left; | ||
} | ||
if (align === 'end') { | ||
left = childRect.right - width; | ||
} | ||
break; | ||
case 'left': | ||
top = targetMidY - height / 2; | ||
left = childRect.left - padding - width; | ||
if (align === 'start') { | ||
top = childRect.top; | ||
} | ||
if (align === 'end') { | ||
top = childRect.bottom - height; | ||
} | ||
break; | ||
case 'bottom': | ||
top = childRect.bottom + padding; | ||
left = targetMidX - width / 2; | ||
if (align === 'start') { | ||
left = childRect.left; | ||
} | ||
if (align === 'end') { | ||
left = childRect.right - width; | ||
} | ||
break; | ||
case 'right': | ||
top = targetMidY - height / 2; | ||
left = childRect.right + padding; | ||
if (align === 'start') { | ||
top = childRect.top; | ||
} | ||
if (align === 'end') { | ||
top = childRect.bottom - height; | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
return { top: top, left: left, width: width, height: height, right: left + width, bottom: top + height }; | ||
}; | ||
exports.getNewPopoverRect = function (_a, windowBorderPadding) { | ||
var position = _a.position, childRect = _a.childRect, popoverRect = _a.popoverRect, padding = _a.padding, align = _a.align; | ||
var rect = exports.popoverRectForPosition(position, childRect, popoverRect, padding, align); | ||
var boundaryViolation = windowBorderPadding != null && | ||
((position === 'top' && rect.top < windowBorderPadding) || | ||
(position === 'left' && rect.left < windowBorderPadding) || | ||
(position === 'right' && | ||
rect.left + popoverRect.width > window.innerWidth - windowBorderPadding) || | ||
(position === 'bottom' && | ||
rect.top + popoverRect.height > window.innerHeight - windowBorderPadding)); | ||
return { | ||
rect: rect, | ||
boundaryViolation: boundaryViolation, | ||
}; | ||
}; | ||
exports.positionTrackerElements = function (trackerTuples, _a) { | ||
var childRect = _a.childRect, popoverRect = _a.popoverRect, currentPosition = _a.position, padding = _a.padding, align = _a.align, nudgedLeft = _a.nudgedLeft, nudgedTop = _a.nudgedTop; | ||
return window.requestAnimationFrame(function () { | ||
trackerTuples.forEach(function (_a) { | ||
var element = _a[0], position = _a[1]; | ||
var rect = exports.getNewPopoverRect({ padding: padding, align: align, popoverRect: popoverRect, childRect: childRect, position: position }).rect; | ||
var externalOffsetTop = window.pageYOffset - childRect.top; | ||
var externalOffsetLeft = window.pageXOffset - childRect.left; | ||
var top = rect.top + externalOffsetTop - exports.Constants.TRACKER_PADDING; | ||
var left = rect.left + externalOffsetLeft - exports.Constants.TRACKER_PADDING; | ||
var width = rect.width + exports.Constants.TRACKER_PADDING * 2; | ||
var height = rect.height + exports.Constants.TRACKER_PADDING * 2; | ||
if (currentPosition === position) { | ||
if (nudgedLeft < 0) { | ||
left = popoverRect.left - exports.Constants.TRACKER_PADDING; | ||
width = rect.left + externalOffsetLeft - exports.Constants.TRACKER_PADDING + width - left; | ||
} | ||
if (nudgedLeft > 0) { | ||
width = popoverRect.right + exports.Constants.TRACKER_PADDING - left; | ||
} | ||
if (nudgedTop < 0) { | ||
top = popoverRect.top - exports.Constants.TRACKER_PADDING; | ||
height = rect.top + externalOffsetTop - exports.Constants.TRACKER_PADDING + height - top; | ||
} | ||
if (nudgedTop > 0) { | ||
height = popoverRect.bottom + exports.Constants.TRACKER_PADDING - top; | ||
} | ||
} | ||
Object.assign(element.style, { | ||
top: top + "px", | ||
left: left + "px", | ||
width: width + "px", | ||
height: height + "px", | ||
'background-color': 'red', | ||
opacity: '0.2', | ||
}); | ||
}); | ||
}); | ||
}; | ||
exports.getNudgedPopoverRect = function (_a, windowPadding) { | ||
var rectTop = _a.top, rectLeft = _a.left, width = _a.width, height = _a.height; | ||
var top = rectTop < windowPadding ? windowPadding : rectTop; | ||
top = | ||
top + height > window.innerHeight - windowPadding | ||
? window.innerHeight - windowPadding - height | ||
: top; | ||
var left = rectLeft < windowPadding ? windowPadding : rectLeft; | ||
left = | ||
left + width > window.innerWidth - windowPadding | ||
? window.innerWidth - windowPadding - width | ||
: left; | ||
return { top: top, left: left, width: width, height: height, right: left + width, bottom: top + height }; | ||
}; | ||
//# sourceMappingURL=util.js.map |
{ | ||
"name": "react-tiny-popover", | ||
"version": "5.1.0", | ||
"version": "6.0.0-beta.0", | ||
"description": "A simple and highly customizable popover react higher order component with no other dependencies! Typescript friendly.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
122619
29
1215
2
1