react-tiny-popover
Advanced tools
Comparing version 3.4.5 to 4.0.0
@@ -19,3 +19,3 @@ "use strict"; | ||
return (React.createElement("div", { style: __assign({ paddingLeft: position === 'right' ? arrowSize : 0, paddingTop: position === 'bottom' ? arrowSize : 0, paddingBottom: position === 'top' ? arrowSize : 0, paddingRight: position === 'left' ? arrowSize : 0 }, style) }, | ||
React.createElement("div", { style: __assign({ position: 'absolute' }, (function () { | ||
React.createElement("div", { style: __assign(__assign({ position: 'absolute' }, (function () { | ||
var arrowWidth = arrowSize * 2; | ||
@@ -63,3 +63,3 @@ var top = (targetRect.top - popoverRect.top) + (targetRect.height / 2) - (arrowWidth / 2); | ||
} | ||
})(), arrowStyle) }), | ||
})()), arrowStyle) }), | ||
children)); | ||
@@ -66,0 +66,0 @@ }; |
@@ -8,3 +8,3 @@ import * as React from 'react'; | ||
export interface ContentRendererArgs { | ||
export interface PopoverInfo { | ||
position: Position; | ||
@@ -18,14 +18,5 @@ align: Align; | ||
export interface ContentLocationGetterArgs { | ||
position: Position; | ||
align: Align; | ||
nudgedLeft: number; | ||
nudgedTop: number; | ||
targetRect: ClientRect; | ||
popoverRect: ClientRect; | ||
} | ||
export type ContentRenderer = (args: PopoverInfo) => JSX.Element; | ||
export type ContentLocationGetter = (args: PopoverInfo) => ContentLocation; | ||
export type ContentRenderer = (args: ContentRendererArgs) => JSX.Element; | ||
export type ContentLocationGetter = (args: ContentLocationGetterArgs) => ContentLocation; | ||
export declare type Position = 'left' | 'right' | 'top' | 'bottom'; | ||
@@ -63,2 +54,9 @@ export declare type Align = 'start' | 'center' | 'end'; | ||
export declare const ArrowContainer: React.StatelessComponent<ArrowContainerProps>; | ||
export default class Popover extends React.Component<PopoverProps> { } | ||
export declare interface PopoverState { | ||
popoverInfo: PopoverInfo; | ||
isTransitioningToClosed: boolean; | ||
internalisOpen: boolean; | ||
} | ||
export default class Popover extends React.Component<PopoverProps, PopoverState> { } |
@@ -15,2 +15,9 @@ "use strict"; | ||
})(); | ||
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; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -22,14 +29,15 @@ var React = require("react"); | ||
exports.ArrowContainer = ArrowContainer_1.ArrowContainer; | ||
var PopoverPortal_1 = require("./PopoverPortal"); | ||
var Popover = /** @class */ (function (_super) { | ||
__extends(Popover, _super); | ||
function Popover() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
function Popover(props) { | ||
var _this = _super.call(this, props) || this; | ||
_this.target = null; | ||
_this.targetRect = null; | ||
_this.targetPositionIntervalHandler = null; | ||
_this.popoverDiv = null; | ||
_this.popoverDiv = null; // TODO: potentially move this inside of PopoverPortal? | ||
_this.positionOrder = null; | ||
_this.willUnmount = false; | ||
_this.willMount = false; | ||
_this.onResize = function (e) { | ||
_this.onResize = function () { | ||
_this.renderPopover(); | ||
@@ -43,4 +51,22 @@ }; | ||
}; | ||
_this.state = { | ||
popoverInfo: null, | ||
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, | ||
}; | ||
} | ||
return null; | ||
}; | ||
Popover.prototype.componentDidMount = function () { | ||
@@ -54,2 +80,10 @@ var _this = this; | ||
}; | ||
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.componentDidUpdate = function (prevProps) { | ||
@@ -59,27 +93,31 @@ if (this.target == null) { | ||
} | ||
var prevIsOpen = prevProps.isOpen, prevPosition = prevProps.position, prevBody = prevProps.content; | ||
var _a = this.props, isOpen = _a.isOpen, content = _a.content, position = _a.position; | ||
var prevIsOpen = prevProps.isOpen, prevAlign = prevProps.align, prevPosition = prevProps.position, prevTransitionDuration = prevProps.transitionDuration; | ||
var _a = this.props, isOpen = _a.isOpen, position = _a.position, transitionDuration = _a.transitionDuration, align = _a.align; | ||
this.positionOrder = this.getPositionPriorityOrder(this.props.position); | ||
var hasNewDestination = prevProps.contentDestination !== this.props.contentDestination; | ||
if (prevIsOpen !== isOpen || | ||
prevBody !== content || | ||
prevAlign !== align || | ||
prevPosition !== position || | ||
hasNewDestination) { | ||
if (hasNewDestination) { | ||
this.removePopover(); | ||
this.popoverDiv.remove(); | ||
} | ||
this.updatePopover(isOpen); | ||
} | ||
if (prevTransitionDuration !== transitionDuration) { | ||
this.popoverDiv.style.transition = "opacity " + transitionDuration + "s"; | ||
} | ||
}; | ||
Popover.prototype.componentWillMount = function () { | ||
this.willUnmount = false; | ||
this.willMount = true; | ||
}; | ||
Popover.prototype.componentWillUnmount = function () { | ||
this.willUnmount = true; | ||
this.removePopover(); | ||
}; | ||
Popover.prototype.render = function () { | ||
return this.props.children; | ||
var content = this.props.content; | ||
var _a = this.state, popoverInfo = _a.popoverInfo, isTransitioningToClosed = _a.isTransitioningToClosed; | ||
var popoverContent = null; | ||
if ((this.props.isOpen || isTransitioningToClosed) && this.popoverDiv && popoverInfo) { | ||
var getContent = function (args) { | ||
return typeof content === 'function' | ||
? content(args) | ||
: content; | ||
}; | ||
popoverContent = (React.createElement(PopoverPortal_1.PopoverPortal, { element: this.popoverDiv, container: this.props.contentDestination || window.document.body, children: getContent(popoverInfo) })); | ||
} | ||
return (React.createElement(React.Fragment, null, | ||
this.props.children, | ||
popoverContent)); | ||
}; | ||
@@ -92,10 +130,9 @@ Popover.prototype.updatePopover = function (isOpen) { | ||
this.popoverDiv.style.opacity = '0'; | ||
this.popoverDiv.style.transition = "opacity " + (transitionDuration || util_1.Constants.FADE_TRANSITION) + "s"; | ||
(this.props.contentDestination || window.document.body).appendChild(this.popoverDiv); | ||
window.addEventListener('resize', this.onResize); | ||
window.addEventListener('click', this.onClick); | ||
this.popoverDiv.style.transition = "opacity " + transitionDuration + "s"; | ||
} | ||
window.addEventListener('resize', this.onResize); | ||
window.addEventListener('click', this.onClick); | ||
this.renderPopover(); | ||
} | ||
else if (this.popoverDiv && this.popoverDiv.parentNode) { | ||
else { | ||
this.removePopover(); | ||
@@ -108,3 +145,2 @@ } | ||
if (positionIndex >= this.positionOrder.length) { | ||
this.removePopover(); | ||
return; | ||
@@ -155,3 +191,3 @@ } | ||
_this.startTargetPositionListener(10); | ||
if (_this.popoverDiv.style.opacity !== '1') { | ||
if (_this.popoverDiv.style.opacity !== '1' && !_this.state.isTransitioningToClosed) { | ||
_this.popoverDiv.style.opacity = '1'; | ||
@@ -163,2 +199,23 @@ } | ||
}; | ||
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.target.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.startTargetPositionListener = function (checkInterval) { | ||
@@ -169,3 +226,3 @@ var _this = this; | ||
var newTargetRect = _this.target.getBoundingClientRect(); | ||
if (_this.targetPositionHasChanged(_this.targetRect, newTargetRect)) { | ||
if (util_1.targetPositionHasChanged(_this.targetRect, newTargetRect)) { | ||
_this.renderPopover(); | ||
@@ -177,24 +234,2 @@ } | ||
}; | ||
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, content = _f.content, align = _f.align; | ||
var getContent = function (args) { | ||
return typeof content === 'function' | ||
? content(args) | ||
: content; | ||
}; | ||
react_dom_1.unstable_renderSubtreeIntoContainer(this, getContent({ position: position, nudgedLeft: nudgedLeft, nudgedTop: nudgedTop, targetRect: targetRect, popoverRect: popoverRect, align: align }), this.popoverDiv, function () { | ||
if (_this.willUnmount) { | ||
return; | ||
} | ||
var targetRect = _this.target.getBoundingClientRect(); | ||
var 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.getNudgedPopoverPosition = function (_a) { | ||
@@ -211,23 +246,21 @@ var top = _a.top, left = _a.left, width = _a.width, height = _a.height; | ||
var _this = this; | ||
if (this.popoverDiv) { | ||
var transitionDuration = this.props.transitionDuration; | ||
var transitionDuration = this.props.transitionDuration; | ||
if (this.popoverDiv != null) { | ||
this.popoverDiv.style.opacity = '0'; | ||
var remove = function () { | ||
if (_this.willUnmount || !_this.props.isOpen || !_this.popoverDiv.parentNode) { | ||
window.clearInterval(_this.targetPositionIntervalHandler); | ||
window.removeEventListener('resize', _this.onResize); | ||
window.removeEventListener('click', _this.onClick); | ||
_this.targetPositionIntervalHandler = null; | ||
if (_this.popoverDiv.parentNode) { | ||
_this.popoverDiv.parentNode.removeChild(_this.popoverDiv); | ||
} | ||
} | ||
}; | ||
if (!this.willUnmount) { | ||
window.setTimeout(remove, (transitionDuration || util_1.Constants.FADE_TRANSITION) * 1000); | ||
} | ||
var remove = function () { | ||
if (_this.willUnmount || !_this.props.isOpen || !_this.popoverDiv.parentNode) { | ||
window.clearInterval(_this.targetPositionIntervalHandler); | ||
window.removeEventListener('resize', _this.onResize); | ||
window.removeEventListener('click', _this.onClick); | ||
_this.targetPositionIntervalHandler = null; | ||
_this.setState({ isTransitioningToClosed: false }); | ||
} | ||
else { | ||
remove(); | ||
} | ||
}; | ||
if (!this.willUnmount) { | ||
this.removePopoverTimeout = window.setTimeout(remove, (transitionDuration || util_1.Constants.FADE_TRANSITION) * 1000); | ||
} | ||
else { | ||
remove(); | ||
} | ||
}; | ||
@@ -241,3 +274,3 @@ Popover.prototype.getPositionPriorityOrder = function (position) { | ||
var remainingPositions = util_1.Constants.DEFAULT_POSITIONS.filter(function (defaultPosition) { return position.find(function (p) { return p === defaultPosition; }) === undefined; }); | ||
return util_1.arrayUnique(position.concat(remainingPositions)); | ||
return util_1.arrayUnique(__spreadArrays(position, remainingPositions)); | ||
} | ||
@@ -247,3 +280,3 @@ } | ||
var remainingPositions = util_1.Constants.DEFAULT_POSITIONS.filter(function (defaultPosition) { return defaultPosition !== position; }); | ||
return util_1.arrayUnique([position].concat(remainingPositions)); | ||
return util_1.arrayUnique(__spreadArrays([position], remainingPositions)); | ||
} | ||
@@ -314,9 +347,2 @@ }; | ||
}; | ||
Popover.prototype.targetPositionHasChanged = function (oldTargetRect, newTargetRect) { | ||
return oldTargetRect === null | ||
|| oldTargetRect.left !== newTargetRect.left | ||
|| oldTargetRect.top !== newTargetRect.top | ||
|| oldTargetRect.width !== newTargetRect.width | ||
|| oldTargetRect.height !== newTargetRect.height; | ||
}; | ||
Popover.defaultProps = { | ||
@@ -328,2 +354,3 @@ padding: util_1.Constants.DEFAULT_PADDING, | ||
containerClassName: util_1.Constants.POPOVER_CONTAINER_CLASS_NAME, | ||
transitionDuration: util_1.Constants.FADE_TRANSITION, | ||
}; | ||
@@ -330,0 +357,0 @@ return Popover; |
@@ -20,2 +20,29 @@ "use strict"; | ||
exports.arrayUnique = function (array) { return array.filter(function (value, index, self) { return self.indexOf(value) === index; }); }; | ||
exports.rectsAreEqual = function (rectA, rectB) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; | ||
return rectA === rectB || | ||
((_a = rectA) === null || _a === void 0 ? void 0 : _a.bottom) === ((_b = rectB) === null || _b === void 0 ? void 0 : _b.bottom) && | ||
((_c = rectA) === null || _c === void 0 ? void 0 : _c.height) === ((_d = rectB) === null || _d === void 0 ? void 0 : _d.height) && | ||
((_e = rectA) === null || _e === void 0 ? void 0 : _e.left) === ((_f = rectB) === null || _f === void 0 ? void 0 : _f.left) && | ||
((_g = rectA) === null || _g === void 0 ? void 0 : _g.right) === ((_h = rectB) === null || _h === void 0 ? void 0 : _h.right) && | ||
((_j = rectA) === null || _j === void 0 ? void 0 : _j.top) === ((_k = rectB) === null || _k === void 0 ? void 0 : _k.top) && | ||
((_l = rectA) === null || _l === void 0 ? void 0 : _l.width) === ((_m = rectB) === null || _m === void 0 ? void 0 : _m.width); | ||
}; | ||
exports.popoverInfosAreEqual = function (infoA, infoB) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; | ||
return infoA === infoB || | ||
((_a = infoA) === null || _a === void 0 ? void 0 : _a.align) === ((_b = infoB) === null || _b === void 0 ? void 0 : _b.align) && | ||
((_c = infoA) === null || _c === void 0 ? void 0 : _c.nudgedLeft) === ((_d = infoB) === null || _d === void 0 ? void 0 : _d.nudgedLeft) && | ||
((_e = infoA) === null || _e === void 0 ? void 0 : _e.nudgedTop) === ((_f = infoB) === null || _f === void 0 ? void 0 : _f.nudgedTop) && | ||
exports.rectsAreEqual((_g = infoA) === null || _g === void 0 ? void 0 : _g.popoverRect, (_h = infoB) === null || _h === void 0 ? void 0 : _h.popoverRect) && | ||
exports.rectsAreEqual((_j = infoA) === null || _j === void 0 ? void 0 : _j.targetRect, (_k = infoB) === null || _k === void 0 ? void 0 : _k.targetRect) && | ||
((_l = infoA) === null || _l === void 0 ? void 0 : _l.position) === ((_m = infoB) === null || _m === void 0 ? void 0 : _m.position); | ||
}; | ||
exports.targetPositionHasChanged = function (oldTargetRect, newTargetRect) { | ||
return oldTargetRect === null | ||
|| oldTargetRect.left !== newTargetRect.left | ||
|| oldTargetRect.top !== newTargetRect.top | ||
|| oldTargetRect.width !== newTargetRect.width | ||
|| oldTargetRect.height !== newTargetRect.height; | ||
}; | ||
//# sourceMappingURL=util.js.map |
{ | ||
"name": "react-tiny-popover", | ||
"version": "3.4.5", | ||
"version": "4.0.0", | ||
"repository": { | ||
@@ -22,4 +22,5 @@ "type": "git", | ||
"scripts": { | ||
"build": "tsc -p .", | ||
"watch": "webpack --watch --mode=development", | ||
"build": "tsc -p . && yarn copy-types", | ||
"watch": "tsc-watch -p . --onSuccess 'yarn copy-types'", | ||
"copy-types": "cp src/index.d.ts dist/index.d.ts", | ||
"start-demo": "cd docs && yarn start" | ||
@@ -30,17 +31,13 @@ }, | ||
"@types/react-dom": "^16.8.4", | ||
"awesome-typescript-loader": "^5.2.1", | ||
"copy-webpack-plugin": "^5.0.3", | ||
"react": "^16.2.0", | ||
"react-dom": "^16.2.0", | ||
"source-map-loader": "^0.2.2", | ||
"tsc-watch": "^4.0.0", | ||
"tslint": "^5.18.0", | ||
"tslint-react": "^4.0.0", | ||
"typescript": "^3.5.3", | ||
"webpack": "^4", | ||
"webpack-cli": "^3.3.6" | ||
"typescript": "^3.7.2" | ||
}, | ||
"peerDependencies": { | ||
"react": "^15.6.1 || ^16.0.0", | ||
"react-dom": "^15.6.1 || ^16.0.0" | ||
"react": "^16.0.0", | ||
"react-dom": "^16.0.0" | ||
} | ||
} |
@@ -108,3 +108,3 @@ # react-tiny-popover | ||
|position|```string``` or ```string[]``` ||You may provide a preferred position for your popover content in relation to its target. Valid values are ```'top', 'bottom', 'left', 'right'```. The default is ```'top'```. If you'd like, you can supply an array of preferred positions ranked in priority order. If the popover reaches the edge of the window, it will attempt to render in the order you specify. The default order is ```['top', 'right', 'left', 'bottom']```. If you'd like, you can provide a shorter array like ```['top', 'left']```. The remaining positions will be automatically filled in. If you provide any duplicate or other values in the array, they will be ignored.| | ||
|contentDestination|```HTMLElement```||Allows for the popover contents to be rendered somewhere other than `document.body`.| | ||
|contentDestination|```HTMLElement```|| Provide an HTML element here to have your popover content rendered within it rather than `document.body`. Window boundary violations are not affected by this element's position.| | ||
|contentLocation|```object``` or ```Function```||If you'd like to hook directly into the positioning process, you may do so here! You can provide an object of type ```{ top: number, left: number }``` to completely override the popover content's (```popoverRect```) location. You can also provide a function that looks like this: ```({ targetRect, popoverRect, position, align, nudgedLeft, nudgedTop }) => { top: number, left: number }``` (The arguments to this function are the same as the content renderer function above). Note that if repositioning is enabled, it happens before this step, so within here you'll be responsible for keeping ```popoverRect``` within the window's bounds if that matters to you!| | ||
@@ -111,0 +111,0 @@ |align|```string```||Possible values are ```start```, ```center```, and ```end```. If ```start``` is specified, the popover content's top or left location is aligned with its target's. With ```end``` specified, the content's bottom or right location is aligned with its target's. If ```center``` is specified, the popover content and target's centers are aligned. Defaults to ```center```.| |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
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
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
218207
8
5130
1
1