@appbuckets/react-ui
Version:
Just Another React UI Framework
278 lines (275 loc) • 7.09 kB
JavaScript
import { __rest, __read, __spreadArray, __assign } from 'tslib';
import * as React from 'react';
import clsx from 'clsx';
import EventStack, { instance } from '@semantic-ui-react/event-stack';
import { usePopper } from 'react-popper';
import {
useElementType,
childrenUtils,
Portal,
} from '@appbuckets/react-ui-core';
import { useSharedClassName } from '../utils/customHook.js';
import '../BucketTheme/BucketTheme.js';
import { useWithDefaultProps } from '../BucketTheme/BucketContext.js';
import {
usePopperModifiers,
usePopperPlacementMapping,
usePortalProps,
} from './lib/internalHooks.js';
var Header = null;
import('../Header/Header.js').then(function (_a) {
var importedHeader = _a.default;
Header = importedHeader;
});
/* --------
* Component Render
* -------- */
var Popup = function (receivedProps) {
var _a;
var props = useWithDefaultProps('popup', receivedProps);
// ----
// Destructuring Props
// ----
var _b = useSharedClassName(props),
className = _b.className,
_c = _b.rest,
children = _c.children,
content = _c.content,
basic = _c.basic,
disabled = _c.disabled,
hideOnScroll = _c.hideOnScroll,
hideOnScrollDelay = _c.hideOnScrollDelay,
hoverable = _c.hoverable,
inverted = _c.inverted,
offset = _c.offset,
onClose = _c.onClose,
onMount = _c.onMount,
onOpen = _c.onOpen;
_c.onOutsideClick;
var onUnmount = _c.onUnmount;
_c.openOn;
var position = _c.position,
userDefinedPopperModifiers = _c.popperModifiers,
userDefinedPortalProps = _c.portalProps,
updateDependencies = _c.updateDependencies,
trigger = _c.trigger,
userDefinedStyle = _c.style,
rest = __rest(_c, [
'children',
'content',
'basic',
'disabled',
'hideOnScroll',
'hideOnScrollDelay',
'hoverable',
'inverted',
'offset',
'onClose',
'onMount',
'onOpen',
'onOutsideClick',
'onUnmount',
'openOn',
'position',
'popperModifiers',
'portalProps',
'updateDependencies',
'trigger',
'style',
]);
// ----
// Reference Handling
// ----
var _d = __read(React.useState(), 2),
referenceElement = _d[0],
setReferenceElement = _d[1];
var _e = __read(React.useState(), 2),
popperElement = _e[0],
setPopperElement = _e[1];
// ----
// Internal State Definition
// ----
var _f = __read(React.useState(false), 2),
closed = _f[0],
setClosed = _f[1];
var _g = __read(React.useState(), 2),
closeTimeout = _g[0],
setCloseTimeout = _g[1];
// ----
// Popper Building
// ----
var popperModifiers = usePopperModifiers(
[
{ name: 'arrow', enabled: false },
{ name: 'offset', enabled: !!offset, options: { offset: offset } },
{ name: 'preventOverflow', enabled: true, options: { padding: 8 } },
],
userDefinedPopperModifiers !== null && userDefinedPopperModifiers !== void 0
? userDefinedPopperModifiers
: [],
[offset]
);
/** Get Popper Placement using Position */
var popperPlacement = usePopperPlacementMapping(position);
var _h = usePopper(referenceElement, popperElement, {
modifiers: popperModifiers,
placement: popperPlacement,
}),
popperStyle = _h.styles,
attributes = _h.attributes,
scheduleUpdate = _h.update,
state = _h.state;
// ----
// Component LifeCycle Hooks
// ----
var updateSchedulerDependencies = React.useMemo(
function () {
return updateDependencies
? __spreadArray(
[scheduleUpdate, state],
__read(updateDependencies),
false
)
: [scheduleUpdate, state];
},
[updateDependencies, scheduleUpdate, state]
);
React.useEffect(
function () {
/** On Dependencies Update, reload Position */
if (scheduleUpdate) {
scheduleUpdate();
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[updateSchedulerDependencies]
);
React.useEffect(
function () {
return function () {
/** On Component Unmount, clear close Timer */
if (closeTimeout) {
clearTimeout(closeTimeout);
}
};
},
[closeTimeout]
);
// ----
// Component Internal Hooks
// ----
var ElementType = useElementType(Popup, receivedProps, props);
var portalProps = usePortalProps(userDefinedPortalProps, props);
// ----
// Avoid Component Render if Popup is Closed or Disabled
// ----
if (closed || disabled) {
return trigger !== null && trigger !== void 0 ? trigger : null;
}
// ----
// Portal Event Handling
// ----
var handlePortalClose = function (event) {
if (typeof onClose === 'function') {
onClose(event, props);
}
};
var handlePortalMount = function () {
if (typeof onMount === 'function') {
onMount(null, props);
}
};
var handlePortalOpen = function (event) {
if (typeof onOpen === 'function') {
onOpen(event, props);
}
};
var handlePortalUnmount = function () {
if (typeof onUnmount === 'function') {
onUnmount(null, props);
}
};
var handlePopupClick = (
(_a = props.openOn) === null || _a === void 0
? void 0
: _a.includes('click')
)
? function (event) {
if (!basic && !inverted) {
event.stopPropagation();
}
}
: undefined;
// ----
// Scroll Handler
// ----
var handleHideOnScroll = function (event) {
setClosed(true);
instance.unsub('scroll', handleHideOnScroll, { target: 'window' });
setCloseTimeout(
setTimeout(function () {
setClosed(false);
}, hideOnScrollDelay)
);
handlePortalClose(event);
};
// ----
// Popup Content Build
// ----
var style = __assign(
__assign({ left: 'auto', right: 'auto' }, popperStyle.popper),
userDefinedStyle
);
var classes = clsx(
'visible',
{ inverted: inverted, basic: basic, hoverable: hoverable },
position,
'popup',
className
);
/** Build Content */
var popupContent = React.createElement(
ElementType,
__assign(
{},
rest,
{
ref: setPopperElement,
className: classes,
style: style,
onClick: handlePopupClick,
},
attributes.popper
),
React.createElement(
'div',
{ className: 'content' },
childrenUtils.isNil(children)
? Header && Header.create(content, { autoGenerateKey: false })
: children
),
hideOnScroll &&
React.createElement(EventStack, {
on: handleHideOnScroll,
name: 'scroll',
target: 'window',
})
);
// ----
// Component Render
// ----
return React.createElement(
Portal,
__assign({}, portalProps, {
trigger: trigger,
triggerRef: setReferenceElement,
onClose: handlePortalClose,
onMount: handlePortalMount,
onOpen: handlePortalOpen,
onUnmount: handlePortalUnmount,
}),
popupContent
);
};
Popup.displayName = 'Popup';
export { Popup as default };