react-popupkit
Version:
A lightweight and easy-to-use React component for creating functional popups without managing state or function. Just call the component, apply your styles, and enjoy optimized magical popups.
84 lines • 4.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useClosePopup = void 0;
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importStar(require("react"));
// create context
var PopupContext = (0, react_1.createContext)(null);
// popup root component
var Popup = function (_a) {
var children = _a.children, isOpen = _a.isOpen, setIsOpen = _a.setIsOpen, args = tslib_1.__rest(_a, ["children", "isOpen", "setIsOpen"]);
var _b = (0, react_1.useState)(isOpen || false), isPopupOpen = _b[0], setIsPopupOpen = _b[1];
// === REF ===
var popupRef = (0, react_1.useRef)(null);
var popupButtonRef = (0, react_1.useRef)(null);
// === HANDLING OUTSIDE CLOSE ===
var handleOutsideClose = (0, react_1.useCallback)(function (e) {
if (popupRef.current &&
!popupRef.current.contains(e.target) &&
popupButtonRef.current &&
!popupButtonRef.current.contains(e.target)) {
setIsPopupOpen(false);
setIsOpen && setIsOpen(false);
}
}, [setIsPopupOpen, setIsOpen]);
(0, react_1.useEffect)(function () {
setIsOpen && setIsOpen(isPopupOpen);
}, [isPopupOpen, setIsOpen]);
// Attach event listener when the component mounts
(0, react_1.useEffect)(function () {
document.addEventListener('mousedown', handleOutsideClose);
// Clean up the event listener when the component unmounts
return function () {
document.removeEventListener('mousedown', handleOutsideClose);
};
}, [handleOutsideClose]);
var contextValue = {
popupRef: popupRef,
popupButtonRef: popupButtonRef,
isPopupOpen: isPopupOpen,
setIsPopupOpen: setIsPopupOpen,
};
return (react_1.default.createElement(PopupContext.Provider, { value: contextValue },
react_1.default.createElement("div", tslib_1.__assign({}, args, { onClick: handleOutsideClose }), children)));
};
// make popup button component
var PopupButton = function (_a) {
var children = _a.children, customOnClick = _a.onClick, _b = _a.toggle, toggle = _b === void 0 ? true : _b, args = tslib_1.__rest(_a, ["children", "onClick", "toggle"]);
var _c = usePopupContext(), popupButtonRef = _c.popupButtonRef, setIsPopupOpen = _c.setIsPopupOpen;
return (react_1.default.createElement("button", tslib_1.__assign({}, args, { ref: popupButtonRef, onClick: function (e) {
e.stopPropagation();
setIsPopupOpen(function (prev) { return (toggle ? !prev : true); }), customOnClick && customOnClick(e);
} }), children));
};
Popup.Button = PopupButton;
// make popup body component
var PopupBody = function (_a) {
var children = _a.children, args = tslib_1.__rest(_a, ["children"]);
var _b = usePopupContext(), popupRef = _b.popupRef, isPopupOpen = _b.isPopupOpen, setIsPopupOpen = _b.setIsPopupOpen;
return (react_1.default.createElement(react_1.default.Fragment, null, isPopupOpen && (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("div", tslib_1.__assign({}, args, { ref: popupRef }), children),
react_1.default.createElement("span", { id: 'close-container', onClick: function () { return setIsPopupOpen(false); } })))));
};
Popup.Body = PopupBody;
// make a wrapper for close popup when click an item
var TriggerClose = function (_a) {
var children = _a.children;
var setIsPopupOpen = usePopupContext().setIsPopupOpen;
return (react_1.default.createElement("div", { id: 'trigger-close', onClick: function () { return setIsPopupOpen(false); } }, children));
};
Popup.TriggerClose = TriggerClose;
var useClosePopup = function () {
return function () { var _a; return (_a = document.getElementById('close-container')) === null || _a === void 0 ? void 0 : _a.click(); };
};
exports.useClosePopup = useClosePopup;
// make hooks for checking validity
var usePopupContext = function () {
var context = (0, react_1.useContext)(PopupContext);
if (!context) {
throw new Error('popup child component must be use inside popup component!');
}
return context;
};
exports.default = Popup;
//# sourceMappingURL=Popup.js.map