diff --git a/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.css b/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.css new file mode 100644 index 000000000..e077f3d5b --- /dev/null +++ b/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.css @@ -0,0 +1,8 @@ +.actionDropDown { + padding: 7px 3px; + background-color: #fff; + border-radius: 6px; + border: 1px solid #ccc; + box-shadow: 0 4px 32px rgba(0, 0, 0, 0.175); + pointer-events: all; +} diff --git a/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.js b/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.js index 3cd2a7d4b..ab0659669 100644 --- a/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.js +++ b/src/components/Loans/OpenLoans/components/ActionsDropdown/ActionsDropdown.js @@ -4,15 +4,16 @@ import { FormattedMessage } from 'react-intl'; import { Button, - UncontrolledDropdown, MenuItem, - DropdownMenu, IconButton, } from '@folio/stripes/components'; import { stripesShape, } from '@folio/stripes/core'; +import Popdown from './Popdown'; +import css from './ActionsDropdown.css'; + class ActionsDropdown extends React.Component { static propTypes = { stripes: stripesShape.isRequired, @@ -22,6 +23,14 @@ class ActionsDropdown extends React.Component { disableFeeFineDetails: PropTypes.bool, }; + itemClick = () => { + this.props.handleOptionsChange(); + } + + renderDropdownTrigger = (triggerRef, onToggle, aria) => ( + <IconButton icon="ellipsis" ref={triggerRef} onClick={onToggle} {...aria} /> + ); + render() { const { loan, @@ -36,23 +45,19 @@ class ActionsDropdown extends React.Component { const buttonDisabled = !this.props.stripes.hasPerm('ui-users.feesfines.actions.all'); return ( - <UncontrolledDropdown onSelectItem={handleOptionsChange}> - <IconButton - data-role="toggle" - icon="ellipsis" - size="small" - iconSize="medium" - /> - <DropdownMenu - data-role="menu" - overrideStyle={{ padding: '7px 3px' }} - > + <Popdown + renderTrigger={this.renderDropdownTrigger} + portal + > + <div className={css.actionDropDown}> { stripes.hasPerm('inventory.items.item.get') && - <MenuItem itemMeta={{ - loan, - action: 'itemDetails', - }} + <MenuItem + itemMeta={{ + loan, + action: 'itemDetails', + }} + onSelectItem={handleOptionsChange} > <Button buttonStyle="dropdownItem" @@ -62,10 +67,12 @@ class ActionsDropdown extends React.Component { </Button> </MenuItem> } - <MenuItem itemMeta={{ - loan, - action: 'renew', - }} + <MenuItem + itemMeta={{ + loan, + action: 'renew', + }} + onSelectItem={handleOptionsChange} > <Button buttonStyle="dropdownItem" @@ -74,10 +81,12 @@ class ActionsDropdown extends React.Component { <FormattedMessage id="ui-users.renew" /> </Button> </MenuItem> - <MenuItem itemMeta={{ - loan, - action: 'changeDueDate', - }} + <MenuItem + itemMeta={{ + loan, + action: 'changeDueDate', + }} + onSelectItem={handleOptionsChange} > <Button buttonStyle="dropdownItem" @@ -86,10 +95,12 @@ class ActionsDropdown extends React.Component { <FormattedMessage id="stripes-smart-components.cddd.changeDueDate" /> </Button> </MenuItem> - <MenuItem itemMeta={{ - loan, - action: 'showLoanPolicy', - }} + <MenuItem + itemMeta={{ + loan, + action: 'showLoanPolicy', + }} + onSelectItem={handleOptionsChange} > <Button buttonStyle="dropdownItem" @@ -98,29 +109,35 @@ class ActionsDropdown extends React.Component { <FormattedMessage id="ui-users.loans.details.loanPolicy" /> </Button> </MenuItem> - <MenuItem itemMeta={{ - loan, - action: 'feefine', - }} + <MenuItem + itemMeta={{ + loan, + action: 'feefine', + }} + onSelectItem={handleOptionsChange} > <Button buttonStyle="dropdownItem" disabled={buttonDisabled}> <FormattedMessage id="ui-users.loans.newFeeFine" /> </Button> </MenuItem> - <MenuItem itemMeta={{ - loan, - action: 'feefinedetails', - }} + <MenuItem + itemMeta={{ + loan, + action: 'feefinedetails', + }} + onSelectItem={handleOptionsChange} > <Button buttonStyle="dropdownItem" disabled={disableFeeFineDetails}> <FormattedMessage id="ui-users.loans.feeFineDetails" /> </Button> </MenuItem> { requestQueue && stripes.hasPerm('ui-requests.all') && - <MenuItem itemMeta={{ - loan, - action: 'discoverRequests', - }} + <MenuItem + itemMeta={{ + loan, + action: 'discoverRequests', + }} + onSelectItem={handleOptionsChange} > <div data-test-dropdown-content-request-queue> <Button buttonStyle="dropdownItem"> @@ -129,8 +146,8 @@ class ActionsDropdown extends React.Component { </div> </MenuItem> } - </DropdownMenu> - </UncontrolledDropdown> + </div> + </Popdown> ); } } diff --git a/src/components/Loans/OpenLoans/components/ActionsDropdown/Popdown.js b/src/components/Loans/OpenLoans/components/ActionsDropdown/Popdown.js new file mode 100644 index 000000000..6946a177b --- /dev/null +++ b/src/components/Loans/OpenLoans/components/ActionsDropdown/Popdown.js @@ -0,0 +1,82 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { + Button, +} from '@folio/stripes/components'; +/* eslint-disable */ +import Popper from '@folio/stripes-components/lib/Popper/Popper'; +import RootCloseWrapper from 'react-overlays/lib/RootCloseWrapper'; +/* eslint-enable */ + +class Popdown extends React.Component { + static propTypes = { + children: PropTypes.node, + buttonProps: PropTypes.object, + label: PropTypes.node, + renderTrigger: PropTypes.func, + portal: PropTypes.bool, + } + + constructor(props) { + super(props); + this.state = { + open: false + }; + + this.triggerRef = React.createRef(); + } + + toggleMenu = (e) => { + e.stopPropagation(); + this.setState((curState) => { + return { + open: !curState.open + }; + }); + }; + + renderTrigger = () => { + const { renderTrigger: renderTriggerProp, buttonProps, label } = this.props; + const ariaProps = { + 'aria-expanded': this.state.open, + 'aria-haspopup': true + }; + + if (renderTriggerProp) { + return renderTriggerProp(this.triggerRef, this.toggleMenu, ariaProps); + } + + return ( + <Button + buttonRef={this.triggerRef} + buttonStyle="none" + onClick={this.toggleMenu} + {...buttonProps} + {...ariaProps} + > + {label} + </Button> + ); + } + + render() { + const { children, portal } = this.props; + const portalEl = document.getElementById('OverlayContainer'); + return ( + <React.Fragment> + {this.renderTrigger()} + <Popper + isOpen={this.state.open} + anchorRef={this.triggerRef} + portal={portal ? portalEl : null} + > + <RootCloseWrapper onRootClose={this.toggleMenu}> + {children} + </RootCloseWrapper> + </Popper> + </React.Fragment> + ); + } +} + +export default Popdown;