[IMP] web_editor: adjust the dropdowns position in the editor panel

Before this commit, there was an issue with the dropdowns in the editor
panel. When the selector was at the bottom of the panel, the dropdown
opened outside the viewport, requiring the user to scroll the editor
panel to see it.

After this commit, the dropdowns in the editor panel open above the
selector if there is not enough space below for it to be visible without
scrolling.

task-3500768

closes odoo/odoo#135788

Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Benjamin Vray
2023-11-03 07:34:52 +00:00
committed by qsm-odoo
parent fa66d1d458
commit bc3973c424
2 changed files with 79 additions and 1 deletions
@@ -1032,6 +1032,7 @@ const SelectUserValueWidget = BaseSelectionUserValueWidget.extend({
*/
close: function () {
this._super(...arguments);
this.el.classList.remove("o_we_select_dropdown_up");
if (this.menuTogglerEl) {
this.menuTogglerEl.classList.remove('active');
}
@@ -1048,6 +1049,7 @@ const SelectUserValueWidget = BaseSelectionUserValueWidget.extend({
open() {
this._super(...arguments);
this.menuTogglerEl.classList.add('active');
this._adjustDropdownPosition();
},
/**
* @override
@@ -1114,6 +1116,37 @@ const SelectUserValueWidget = BaseSelectionUserValueWidget.extend({
_shouldIgnoreClick(ev) {
return !!ev.target.closest('[role="button"]');
},
/**
* Decides whether the dropdown should be positioned below or above the
* selector based on the available space.
*
* @private
*/
_adjustDropdownPosition() {
const customizePanelEl = this.menuEl.closest(".o_we_customize_panel");
if (!customizePanelEl) {
return;
}
this.el.classList.remove("o_we_select_dropdown_up");
const customizePanelElCoords = customizePanelEl.getBoundingClientRect();
let dropdownMenuElCoords = this.menuEl.getBoundingClientRect();
// Adds a margin to prevent the dropdown from sticking to the edge of
// the customize panel.
const dropdownMenuMargin = 5;
// If after opening, the dropdown list overflows the customization
// panel at the bottom, opens the dropdown above the selector.
if ((dropdownMenuElCoords.bottom + dropdownMenuMargin) > customizePanelElCoords.bottom) {
this.el.classList.add("o_we_select_dropdown_up");
dropdownMenuElCoords = this.menuEl.getBoundingClientRect();
// If there is no available space above it either, then we open
// it below the selector.
if (dropdownMenuElCoords.top < customizePanelElCoords.top) {
this.el.classList.remove("o_we_select_dropdown_up");
}
}
},
//--------------------------------------------------------------------------
// Handlers
@@ -1547,6 +1580,7 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({
selectedColor: this._value,
resetTabCount: ++this.resetTabCount,
});
this._super(...arguments);
} else {
// TODO review in master, this does async stuff. Maybe the open
// method should now be async. This is not really robust as the
@@ -1554,8 +1588,16 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({
// the use of the saved promise where we can should mitigate that
// issue.
this._colorPaletteRenderPromise = this._renderColorPalette();
this._super(...arguments);
this._colorPaletteRenderPromise.then(() => {
// Re-adjust the position of the colorpicker once the
// colorpalette is completely rendered (once that the
// colorpicker has its final height.
// TODO should not be needed once everything will be converted
// to owl.
this._adjustDropdownPosition();
});
}
this._super(...arguments);
},
/**
* @override
@@ -2580,6 +2622,15 @@ const SelectPagerUserValueWidget = SelectUserValueWidget.extend({
// Private
//--------------------------------------------------------------------------
/**
* We never try to adjust the position for selection with pagers as they
* are fullscreen.
*
* @override
*/
_adjustDropdownPosition() {
return;
},
/**
* @override
*/
@@ -1222,6 +1222,33 @@
}
}
// When the dropdown or the colorpicker is displayed above the
// selector.
&.o_we_select_dropdown_up {
we-selection-items {
top: auto !important;
bottom: 100% !important;
margin-bottom: $o-we-sidebar-content-field-dropdown-spacing !important;
}
.o_we_dropdown_caret {
align-self: flex-start !important;
&::before, &::after {
top: auto !important;
bottom: 100% !important;
margin-bottom: $o-we-dropdown-caret-spacing;
transform: rotate(180deg) translateX(-50%) !important;
}
}
&.o_we_so_color_palette .o_we_dropdown_caret {
&::before, &::after {
margin-bottom: $o-we-dropdown-caret-spacing / 2;
}
}
}
we-select-page {
display: grid;
grid-template-columns: repeat(4, 1fr);