Skip to content

Commit cf62254

Browse files
authored
IBX-7183: [Sub-items] For a small number of items column popup is not fully visible (#1013)
1 parent 354f7e6 commit cf62254

File tree

2 files changed

+41
-44
lines changed

2 files changed

+41
-44
lines changed

src/bundle/Resources/public/scss/ui/modules/sub-items-list/_view.columns.toggler.scss

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
padding: calculateRem(12px) calculateRem(16px);
1111

1212
&__panel {
13-
top: calculateRem(36px);
14-
right: calculateRem(17px);
13+
min-width: calculateRem(200px);
1514

16-
&--above-btn {
17-
bottom: calculateRem(36px);
18-
top: auto;
15+
&--hidden {
16+
display: none;
1917
}
2018
}
2119
}

src/bundle/ui-dev/src/modules/sub-items/components/view-columns-toggler/view.columns.toggler.js

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import React, { Component, createRef } from 'react';
2+
import { createPortal } from 'react-dom';
23
import PropTypes from 'prop-types';
34

45
import Icon from '../../../common/icon/icon';
56
import ViewColumnsTogglerListElement from './view.columns.toggler.list.element';
67
import { columnsLabels } from '../../sub.items.module';
78
import { createCssClassNames } from '../../../common/helpers/css.class.names';
89

9-
const { Translator } = window;
10-
11-
const DEFAULT_PANEL_HEIGHT = 450;
10+
const { document, Translator, Popper } = window;
1211

1312
export default class ViewColumnsTogglerComponent extends Component {
1413
constructor(props) {
@@ -22,76 +21,75 @@ export default class ViewColumnsTogglerComponent extends Component {
2221

2322
this.state = {
2423
isOpen: false,
25-
buttonBottomDocumentOffset: null,
26-
panelHeight: null,
2724
};
2825
}
2926

3027
componentDidMount() {
3128
document.addEventListener('click', this.hidePanel, false);
3229

33-
this.setState(() => ({
34-
buttonBottomDocumentOffset: this.getBtnBottomDocumentOffset(),
35-
}));
36-
}
37-
38-
componentDidUpdate() {
39-
const { isOpen, panelHeight } = this.state;
40-
41-
if (isOpen && panelHeight === null) {
42-
this.setState({
43-
panelHeight: this._refPanel.current.offsetHeight,
44-
});
45-
}
30+
this.popperInstance = new Popper.createPopper(this._refTogglerButton.current, this._refPanel.current, {
31+
placement: 'bottom-end',
32+
modifiers: [
33+
{
34+
name: 'flip',
35+
enabled: true,
36+
options: {
37+
fallbackPlacements: ['top-end'],
38+
boundary: document.body,
39+
},
40+
},
41+
{
42+
name: 'offset',
43+
options: {
44+
offset: [0, 12],
45+
},
46+
},
47+
],
48+
});
4649
}
4750

4851
componentWillUnmount() {
4952
document.removeEventListener('click', this.hidePanel);
50-
}
5153

52-
getBtnBottomDocumentOffset() {
53-
const buttonTopOffset = this._refTogglerButton.current.getBoundingClientRect().top;
54-
55-
return window.innerHeight - buttonTopOffset;
54+
this.popperInstance.destroy();
5655
}
5756

5857
hidePanel({ target }) {
5958
if (!this.state.isOpen) {
6059
return;
6160
}
6261

63-
const isClickInsideToggler = target.closest('.c-view-columns-toggler');
62+
const isClickInsideToggler = this._refTogglerButton.current.contains(target);
63+
const isClickInsidePopup = this._refPanel.current.contains(target);
6464

65-
if (!isClickInsideToggler) {
65+
if (!isClickInsideToggler && !isClickInsidePopup) {
6666
this.setState(() => ({
6767
isOpen: false,
6868
}));
6969
}
7070
}
7171

7272
togglePanel() {
73-
this.setState((state) => ({
74-
buttonBottomDocumentOffset: this.getBtnBottomDocumentOffset(),
75-
isOpen: !state.isOpen,
76-
}));
73+
this.setState(
74+
(state) => ({
75+
isOpen: !state.isOpen,
76+
}),
77+
() => {
78+
this.popperInstance.update();
79+
},
80+
);
7781
}
7882

7983
renderPanel() {
80-
if (!this.state.isOpen) {
81-
return null;
82-
}
83-
8484
const { columnsVisibility, toggleColumnVisibility } = this.props;
85-
const { buttonBottomDocumentOffset, panelHeight: measuredPanelHeight } = this.state;
86-
const panelHeight = measuredPanelHeight ?? DEFAULT_PANEL_HEIGHT;
87-
const showAboveBtn = buttonBottomDocumentOffset < panelHeight;
85+
const { isOpen } = this.state;
8886
const className = createCssClassNames({
8987
'ibexa-popup-menu': true,
9088
'c-view-columns-toggler__panel': true,
91-
'c-view-columns-toggler__panel--above-btn': showAboveBtn,
89+
'c-view-columns-toggler__panel--hidden': !isOpen,
9290
});
9391

94-
return (
92+
return createPortal(
9593
<ul className={className} ref={this._refPanel}>
9694
{Object.entries(columnsVisibility).map(([columnKey, isColumnVisible]) => {
9795
const label = columnsLabels[columnKey];
@@ -106,7 +104,8 @@ export default class ViewColumnsTogglerComponent extends Component {
106104
/>
107105
);
108106
})}
109-
</ul>
107+
</ul>,
108+
document.body,
110109
);
111110
}
112111

0 commit comments

Comments
 (0)