From a350ed1dcb8cce77c5754a8ddf955be537b3f5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grabowski?= Date: Wed, 29 Nov 2023 13:33:26 +0100 Subject: [PATCH] IBX-7183: [Sub-items] For a small number of items column popup is not fully visible --- .../sub-items-list/_view.columns.toggler.scss | 8 +- .../view.columns.toggler.js | 77 +++++++++---------- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_view.columns.toggler.scss b/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_view.columns.toggler.scss index 14c3637398..fbe969ae5c 100644 --- a/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_view.columns.toggler.scss +++ b/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_view.columns.toggler.scss @@ -10,12 +10,10 @@ padding: calculateRem(12px) calculateRem(16px); &__panel { - top: calculateRem(36px); - right: calculateRem(17px); + min-width: calculateRem(200px); - &--above-btn { - bottom: calculateRem(36px); - top: auto; + &--hidden { + display: none; } } } diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/view-columns-toggler/view.columns.toggler.js b/src/bundle/ui-dev/src/modules/sub-items/components/view-columns-toggler/view.columns.toggler.js index 9e82c37585..b7029c423b 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/view-columns-toggler/view.columns.toggler.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/view-columns-toggler/view.columns.toggler.js @@ -1,4 +1,5 @@ import React, { Component, createRef } from 'react'; +import { createPortal } from 'react-dom'; import PropTypes from 'prop-types'; import Icon from '../../../common/icon/icon'; @@ -6,9 +7,7 @@ import ViewColumnsTogglerListElement from './view.columns.toggler.list.element'; import { columnsLabels } from '../../sub.items.module'; import { createCssClassNames } from '../../../common/helpers/css.class.names'; -const { Translator } = window; - -const DEFAULT_PANEL_HEIGHT = 450; +const { document, Translator, Popper } = window; export default class ViewColumnsTogglerComponent extends Component { constructor(props) { @@ -22,37 +21,37 @@ export default class ViewColumnsTogglerComponent extends Component { this.state = { isOpen: false, - buttonBottomDocumentOffset: null, - panelHeight: null, }; } componentDidMount() { document.addEventListener('click', this.hidePanel, false); - this.setState(() => ({ - buttonBottomDocumentOffset: this.getBtnBottomDocumentOffset(), - })); - } - - componentDidUpdate() { - const { isOpen, panelHeight } = this.state; - - if (isOpen && panelHeight === null) { - this.setState({ - panelHeight: this._refPanel.current.offsetHeight, - }); - } + this.popperInstance = new Popper.createPopper(this._refTogglerButton.current, this._refPanel.current, { + placement: 'bottom-end', + modifiers: [ + { + name: 'flip', + enabled: true, + options: { + fallbackPlacements: ['top-end'], + boundary: document.body, + }, + }, + { + name: 'offset', + options: { + offset: [0, 12], + }, + }, + ], + }); } componentWillUnmount() { document.removeEventListener('click', this.hidePanel); - } - getBtnBottomDocumentOffset() { - const buttonTopOffset = this._refTogglerButton.current.getBoundingClientRect().top; - - return window.innerHeight - buttonTopOffset; + this.popperInstance.destroy(); } hidePanel({ target }) { @@ -60,9 +59,10 @@ export default class ViewColumnsTogglerComponent extends Component { return; } - const isClickInsideToggler = target.closest('.c-view-columns-toggler'); + const isClickInsideToggler = this._refTogglerButton.current.contains(target); + const isClickInsidePopup = this._refPanel.current.contains(target); - if (!isClickInsideToggler) { + if (!isClickInsideToggler && !isClickInsidePopup) { this.setState(() => ({ isOpen: false, })); @@ -70,28 +70,26 @@ export default class ViewColumnsTogglerComponent extends Component { } togglePanel() { - this.setState((state) => ({ - buttonBottomDocumentOffset: this.getBtnBottomDocumentOffset(), - isOpen: !state.isOpen, - })); + this.setState( + (state) => ({ + isOpen: !state.isOpen, + }), + () => { + this.popperInstance.update(); + }, + ); } renderPanel() { - if (!this.state.isOpen) { - return null; - } - const { columnsVisibility, toggleColumnVisibility } = this.props; - const { buttonBottomDocumentOffset, panelHeight: measuredPanelHeight } = this.state; - const panelHeight = measuredPanelHeight ?? DEFAULT_PANEL_HEIGHT; - const showAboveBtn = buttonBottomDocumentOffset < panelHeight; + const { isOpen } = this.state; const className = createCssClassNames({ 'ibexa-popup-menu': true, 'c-view-columns-toggler__panel': true, - 'c-view-columns-toggler__panel--above-btn': showAboveBtn, + 'c-view-columns-toggler__panel--hidden': !isOpen, }); - return ( + return createPortal( + , + document.body, ); }