UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

168 lines (167 loc) 7.46 kB
import * as React from 'react'; import { cloneElement, useRef } from 'react'; import join from '../utils/join'; import SimpleButton from '../SimpleButton'; import useExpanded from './useExpanded'; import renderItem from './renderItem'; import OverlayTrigger from '../OverlayTrigger'; export const DROPDOWN_ICON = (React.createElement("svg", { width: "20", height: "20", viewBox: "0 0 24 24" }, React.createElement("path", { d: "M7 10l5 5 5-5H7z" }))); const spacer = React.createElement("div", { style: { flex: 1 } }); const baseClassName = 'ab-DropdownButton'; const defaultListItemStyle = { padding: 'var(--ab-cmp-dropdownbutton-list-item__padding)', }; const DropdownButton = React.forwardRef((props, theRef) => { let { columns, overlayProps, listOffset = 10, collapseOnItemClick = true, focusOnClear = true, idProperty = 'id', isItemDisabled, items, children, listMinWidth = 100, listStyle, listItemStyle, listItemClassName, constrainTo, showClearButton = false, onClear, clearButtonProps, onExpand, onCollapse, showToggleIcon = true, ...domProps } = props; isItemDisabled = isItemDisabled || ((item) => item.disabled); if (!columns) { columns = ['icon', 'label']; } let content; if (Array.isArray(items)) { content = items.map((item, index) => { if (item.separator) { return (React.createElement("tr", { className: `${baseClassName}__separator`, key: index }, React.createElement("td", { colSpan: 2 }))); } if (typeof listItemStyle === 'function') { listItemStyle = listItemStyle(item, index); } const disabled = isItemDisabled(item); const itemStyle = { ...defaultListItemStyle, ...listItemStyle }; const itemClassName = join(`${baseClassName}__list-item`, item.clickable === false || disabled ? `${baseClassName}__list-item--not-clickable` : `${baseClassName}__list-item--clickable`, disabled ? `${baseClassName}__list-item--disabled` : '', listItemClassName); const getItemHandler = (eventName) => { return (e) => { if (!disabled) { if (item[eventName]) { item[eventName](e, item); } } if (collapseOnItemClick) { if (!disabled) { setExpanded(false); } buttonRef.current?.focus(); } else { e.nativeEvent.preventCollapse = true; } }; }; const domProps = {}; if (item.onChange) { domProps.onChange = getItemHandler('onChange'); } const itemDataName = item['dataName'] || (typeof item['label'] === 'string' ? item['label'] : undefined); if (itemDataName) { domProps['data-name'] = itemDataName; } return renderItem({ index, idProperty, onItemClick: getItemHandler('onClick'), domProps, className: itemClassName, style: itemStyle, item, columns: columns, }); }); content = (React.createElement("table", { className: `${baseClassName}__content` }, React.createElement("tbody", null, content))); } const dropdownButtonClassName = props.className; const className = join(props.className, baseClassName); const positionerRef = useRef(null); const { expanded, toggle, setExpanded, positionInfo } = useExpanded(props, positionerRef); const { maxHeight: maxListHeight, maxWidth: maxListWidth } = positionInfo; listStyle = { minWidth: typeof maxListWidth === 'number' ? Math.min(listMinWidth, maxListWidth) : listMinWidth, maxHeight: maxListHeight, maxWidth: maxListWidth, ...listStyle, }; let icon = expanded ? cloneElement(DROPDOWN_ICON, { style: { ...DROPDOWN_ICON.props.style, transform: 'rotate(180deg) translate3d(0px, -2px, 0px)', }, }) : DROPDOWN_ICON; const hasClearButton = onClear || showClearButton; const clearButton = hasClearButton ? (React.createElement(SimpleButton, { disabled: domProps.disabled, as: "div", onClick: (event) => { event.stopPropagation(); if (onClear) { onClear(); } buttonRef.current?.focus(); }, ml: 2, padding: 0, variant: 'text', icon: "close", ...clearButtonProps, style: { ...clearButtonProps?.style, visibility: showClearButton ? 'visible' : 'hidden', } })) : null; icon = (React.createElement(React.Fragment, null, spacer, hasClearButton ? clearButton : null, icon)); const buttonRef = useRef(null); return (React.createElement(OverlayTrigger, { visible: expanded, targetOffset: listOffset, render: () => { return (React.createElement("div", { "data-name": `${dropdownButtonClassName}`, style: listStyle, className: `${baseClassName}__list`, onMouseDownCapture: (e) => { /** * This stops popups register clicks inside the dropdown * This is needed for column filter dropdows when redenred * inside ag-grid column filter */ if (props.stopPropagationOnOverlay) { e.stopPropagation(); } } }, content)); }, ...overlayProps }, React.createElement(SimpleButton, { iconPosition: "end", ...(showToggleIcon && { icon, paddingRight: 0 }), ...domProps, ref: (btn) => { buttonRef.current = btn; if (!theRef) { return; } if (typeof theRef === 'function') { theRef(btn); } else { theRef.current = btn; } }, style: domProps.style, className: className, onClick: (e) => { if (domProps.onClick) { domProps.onClick(e); } if (e.nativeEvent.preventCollapse && expanded) { return; } toggle(); }, onKeyDown: (e) => { if (domProps.onKeyDown) { domProps.onKeyDown(e); } if (expanded && e.key === 'Escape') { toggle(); } }, onBlur: (e) => { if (domProps.onBlur) { domProps.onBlur(e); } setExpanded(false); } }, React.createElement("div", { ref: positionerRef, tabIndex: -1, style: { position: 'absolute', height: '100%', width: '100%', zIndex: -1, pointerEvents: 'none', opacity: 0, top: 0, left: 0, } }), children))); }); export default DropdownButton;