@geneui/components
Version:
The Gene UI components library designed for BI tools
265 lines (261 loc) • 12.2 kB
JavaScript
import React__default, { useRef, useState, useEffect, useCallback, useMemo, Fragment } from 'react';
import PropTypes from 'prop-types';
import { c as clsx } from '../clsx.m-2bb6df4b.js';
import { n as noop } from '../index-a0e4e333.js';
import '../configs-00612ce0.js';
import useClickOutside from '../hooks/useClickOutside.js';
import Icon from '../Icon/index.js';
import { T as Tooltip } from '../index-6d7e99cd.js';
import { s as styleInject } from '../style-inject.es-746bb8ed.js';
import '../dateValidation-67caec66.js';
import '../_commonjsHelpers-24198af3.js';
import 'react-dom';
import '../_rollupPluginBabelHelpers-e8fb2e5c.js';
import '../index-031ff73c.js';
import '../tslib.es6-f211516f.js';
import '../hooks/useDeviceType.js';
import '../hooks/useWindowSize.js';
import '../hooks/useDebounce.js';
import '../GeneUIProvider/index.js';
var css_248z = "[data-gene-ui-version=\"2.16.5\"] .bc-drawer{--width:7.2rem;--head-justify:center;--item-width:4.2rem;--item-padding:0;--item-justify:center;--item-title-display:none;--item-icon-margin:0;background:var(--background);border-right:1px solid rgba(var(--background-sc-rgb),.1);left:0;overflow:hidden;top:0;transition:width .15s cubic-bezier(.4,0,.2,1);width:var(--width);z-index:200}[data-gene-ui-version=\"2.16.5\"] .bc-drawer.open{--width:30rem;--head-justify:space-between;--item-width:100%;--item-padding:0 14px;--item-justify:flex-start;--item-title-display:block;--item-icon-margin:17px}[data-gene-ui-version=\"2.16.5\"] .bc-drawer.open .bc-drawer-head:after{background-color:#1473e6;bottom:0;content:\"\";height:3px;left:20px;margin:17px 198px 0 0;position:absolute;width:34px}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-head{align-items:center;border-bottom:1px solid rgba(var(--background-sc-rgb),.1);display:flex;height:64px;justify-content:var(--head-justify);padding:20px;position:relative;width:var(--width)}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-head .bc-drawer-head-title{font-size:16px;font-weight:600}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-head .bc-drawer-head-icon{cursor:pointer}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-head .bc-drawer-head-icon:hover{color:#1473e6}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-content{display:flex;flex-direction:column;height:calc(100% - 64px);overflow-x:hidden;overflow-y:auto;padding:10px 12px;width:var(--width)}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item{align-items:center;border-radius:21px;cursor:pointer;display:flex;height:42px;justify-content:var(--item-justify);min-height:42px;overflow:hidden;padding:var(--item-padding);position:relative;transition:width .15s cubic-bezier(.4,0,.2,1);transition:color .3s,background .3s,opacity .2s;width:var(--item-width)}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item:hover{background-color:#00000008}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item.disabled{opacity:.5;pointer-events:none}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item.active:not(.nested){background-color:#1473e6;color:#fff}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item.active.nested{background-color:#1473e608;color:#1473e6}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item.nested{padding-left:57px}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item .bc-drawer-item-icon{margin-right:var(--item-icon-margin)}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item .bc-drawer-item-title{display:var(--item-title-display);font-weight:600}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item .bc-drawer-item-arrow{position:absolute;right:17px;transition:.15s cubic-bezier(.4,0,.2,1)}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item .bc-drawer-item-arrow.open{transform:rotate(-180deg)}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item-nested-list{max-height:0;overflow:hidden;transition:.15s cubic-bezier(.4,0,.2,1);width:100%}[data-gene-ui-version=\"2.16.5\"] .bc-drawer .bc-drawer-item-nested-list.open{max-height:100%}";
styleInject(css_248z);
function Drawer(_ref) {
let {
menu,
title,
value,
defaultValue,
className,
onOpen,
onClose,
onChange,
onOutsideClick,
defaultOpen,
height,
position,
isOpen,
closeAfterSelect,
closeWithOutsideClick
} = _ref;
const isOpenControlled = typeof isOpen === 'boolean';
const drawerRef = useRef(null);
const [isDrawerOpen, setIsDrawerOpen] = useState(defaultOpen);
const [selectedVaule, setSelectedValue] = useState(defaultValue);
const [openNested, setOpenNested] = useState(null);
useEffect(() => {
setSelectedValue(value);
}, [value]);
useEffect(() => {
isOpenControlled && setIsDrawerOpen(isOpen);
}, [isOpenControlled, isOpen]);
const handleOpen = useCallback(event => {
if (!isDrawerOpen) {
!isOpenControlled && setIsDrawerOpen(true);
onOpen(event);
}
}, [isDrawerOpen, isOpenControlled, onOpen]);
const handleClose = useCallback(event => {
if (isDrawerOpen) {
!isOpenControlled && setIsDrawerOpen(false);
onClose(event);
}
}, [isDrawerOpen, isOpenControlled, onClose]);
const selectedNestedParent = useMemo(() => {
const selectedItem = menu.find(item => item.id === selectedVaule || item.nested && item.nested.length && item.nested.findIndex(nestedItem => nestedItem.id === selectedVaule) > -1);
return selectedItem && selectedItem.id;
}, [selectedVaule, menu]);
const handleItemClick = useCallback((item, index, event) => {
if (!item.disabled) {
if (item.nested && item.nested.length > 0) {
if (isDrawerOpen) {
setOpenNested(prev => prev !== index && index);
} else {
setOpenNested(index);
handleOpen(event);
}
} else if (item.id !== selectedVaule) {
onChange(item);
setSelectedValue(item.id);
closeAfterSelect && handleClose(event);
}
}
}, [closeAfterSelect, handleClose, handleOpen, isDrawerOpen, onChange, selectedVaule]);
const handleNestedItemClick = useCallback((item, nested, event) => {
if (!item.disabled && !nested.disabled && nested.id !== selectedVaule) {
onChange(item, nested);
setSelectedValue(nested.id);
closeAfterSelect && handleClose(event);
}
}, [closeAfterSelect, handleClose, onChange, selectedVaule]);
const handleMenuIconClick = useCallback(event => {
isDrawerOpen ? handleClose(event) : handleOpen(event);
}, [isDrawerOpen, handleClose, handleOpen]);
const drawerStyles = useMemo(() => ({
position,
height
}), [position, height]);
const handleOutsideClick = useClickOutside(event => {
if (drawerRef && !drawerRef.current.contains(event.target)) {
closeWithOutsideClick && handleClose();
onOutsideClick(event);
}
});
const generateDrawerRef = useCallback(node => {
if (node && drawerRef) {
drawerRef.current = node;
handleOutsideClick(node);
}
}, [handleOutsideClick]);
return /*#__PURE__*/React__default.createElement("div", {
ref: generateDrawerRef,
className: clsx('bc-drawer', className, {
open: isDrawerOpen
}),
style: drawerStyles
}, /*#__PURE__*/React__default.createElement("div", {
className: "bc-drawer-head"
}, isDrawerOpen && /*#__PURE__*/React__default.createElement("span", {
className: "bc-drawer-head-title"
}, title), /*#__PURE__*/React__default.createElement(Icon, {
className: "bc-drawer-head-icon",
onClick: handleMenuIconClick,
type: isDrawerOpen ? 'bc-icon-menu-collapsed' : 'bc-icon-menu-expanded'
})), /*#__PURE__*/React__default.createElement("div", {
className: "bc-drawer-content"
}, menu && menu.length > 0 && menu.map((item, index) => {
const {
nested
} = item;
const hasNested = nested && nested.length;
const isNestedOpen = isDrawerOpen && openNested === index;
return /*#__PURE__*/React__default.createElement(Fragment, {
key: item.id
}, /*#__PURE__*/React__default.createElement("div", {
className: clsx('bc-drawer-item', {
active: selectedNestedParent === item.id,
disabled: item.disabled
}),
onClick: event => handleItemClick(item, index, event)
}, /*#__PURE__*/React__default.createElement(Tooltip, {
title: isDrawerOpen ? '' : item.title,
position: "right"
}, item.icon && /*#__PURE__*/React__default.createElement(Icon, {
className: "bc-drawer-item-icon",
type: item.icon
})), /*#__PURE__*/React__default.createElement("span", {
className: "bc-drawer-item-title"
}, item.title), isDrawerOpen && hasNested && /*#__PURE__*/React__default.createElement(Icon, {
type: "bc-icon-arrow-down",
className: clsx('bc-drawer-item-arrow', {
open: isNestedOpen
})
})), hasNested && /*#__PURE__*/React__default.createElement("div", {
className: clsx('bc-drawer-item-nested-list', {
open: isNestedOpen
})
}, nested.map(nestedItem => /*#__PURE__*/React__default.createElement("div", {
key: nestedItem.id,
className: clsx('bc-drawer-item nested', {
active: selectedVaule === nestedItem.id,
disabled: nestedItem.disabled
}),
onClick: event => handleNestedItemClick(item, nestedItem, event)
}, /*#__PURE__*/React__default.createElement("span", {
className: "bc-drawer-item-title"
}, nestedItem.title)))));
})));
}
Drawer.defaultProps = {
onOpen: noop,
onClose: noop,
onChange: noop,
defaultOpen: false,
height: '100vh',
position: 'relative'
};
Drawer.propTypes = {
/**
* Date for display the menu
*/
menu: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string,
icon: PropTypes.string,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
disabled: PropTypes.bool,
nested: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string,
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
disabled: PropTypes.bool
}))
})),
/**
* If you want to control the selected item in the menu, you must date id of one of the 'menu' items.
*/
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
* If you want not to control the menu from the top but have a default value, you can send it using defaultValue
*/
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
* Label is displayed at the top in the driver
*/
title: PropTypes.string,
/**
* Override or extend the className applied to the component.
*/
className: PropTypes.string,
/**
* Callback fired when a menu item is selected.
Signature:
function(item, nested) => void
item: Item is the element that was select from the menu
nested: If you select an item from the submenu, it will be sent as the second argument, and the first will be the item of its parent.
*/
onChange: PropTypes.func,
/**
* Callback fired when a drawer is opened.
Signature:
function(event: object) => void
event: The event source of the callback.
*/
onOpen: PropTypes.func,
/**
* Callback fired when a drawer is closed.
Signature:
function(event: object) => void
event: The event source of the callback.
*/
onClose: PropTypes.func,
/**
* If true, the component is shown by default.
*/
defaultOpen: PropTypes.bool,
/**
* Height for the component
by default: 100vh
*/
height: PropTypes.string,
/**
* The positioning type. The behavior of the different options is described in the MDN web docs.
'absolute' | 'fixed' | 'relative' | 'static' | 'sticky'
*/
position: PropTypes.string,
/**
* With this prop you can control Drawer opening and closing from parent component
*/
isOpen: PropTypes.bool,
/**
* Drawer to close after item select
*/
closeAfterSelect: PropTypes.bool,
/**
* Closes when click outside
*/
closeWithOutsideClick: PropTypes.bool,
/**
* Callback fired when a outside click.
* (event: MouseEvent) => void.
*/
onOutsideClick: PropTypes.func
};
export { Drawer as default };